差分
このページの2つのバージョン間の差分を表示します。
両方とも前のリビジョン 前のリビジョン 次のリビジョン | 前のリビジョン | ||
linux:kernel:namespace:the_namespaces_api [2013/07/22 08:39] – [/proc/PID/ns ファイル] tenforward | linux:kernel:namespace:the_namespaces_api [2016/07/12 18:23] (現在) – [名前空間の操作,その 2: 名前空間 API] tenforward | ||
---|---|---|---|
行 3: | 行 3: | ||
名前空間はグローバルなシステムリソースを抽象的なものの中に包みこむ.隔離されたリソースのインスタンスを持つ名前空間内にプロセスを出現させるということである.名前空間は様々な目的に使われる.最も有名なのは軽量の仮想化テクニックであるコンテナの実装である.これは名前空間と名前空間 API の詳細を見ていく記事のシリーズの第 2 部である.この記事では名前空間 API を少し詳細に見ていく.そして多数のサンプルプログラムで実際の API を説明する. | 名前空間はグローバルなシステムリソースを抽象的なものの中に包みこむ.隔離されたリソースのインスタンスを持つ名前空間内にプロセスを出現させるということである.名前空間は様々な目的に使われる.最も有名なのは軽量の仮想化テクニックであるコンテナの実装である.これは名前空間と名前空間 API の詳細を見ていく記事のシリーズの第 2 部である.この記事では名前空間 API を少し詳細に見ていく.そして多数のサンプルプログラムで実際の API を説明する. | ||
- | 名前空間の API は 3 つのシステムコール,clone(), | + | 名前空間の API は 3 つのシステムコール,clone(), |
===== 新しい名前空間内で子プロセスを生成する: | ===== 新しい名前空間内で子プロセスを生成する: | ||
行 153: | 行 153: | ||
以前までのバージョンのカーネルでは,setns() を使って mount, PID, ユーザ名前空間に参加する事はできなかった.しかし 3.8 以降で,全ての名前空間に参加が可能になった. | 以前までのバージョンのカーネルでは,setns() を使って mount, PID, ユーザ名前空間に参加する事はできなかった.しかし 3.8 以降で,全ての名前空間に参加が可能になった. | ||
+ | |||
+ | ===== 名前空間から抜ける: | ||
+ | |||
+ | 名前空間 API の最後のシステムコールは unshare() である. | ||
+ | |||
+ | <code c> | ||
+ | int unshare(int flags); | ||
+ | </ | ||
+ | |||
+ | unshare() システムコールは clone() と同様の機能を提供する.しかし,呼び出したプロセス上での操作となる.つまり,CLONE_NEW* ビットを引数として取り新しい名前空間を作成し,呼び出し元を名前空間のメンバーにする (clone() と同様に,我々がここでは扱わない名前空間の操作以外の機能を提供する).unshare() の主な目的は,(clone() が行うような) 新しいプロセスやスレッドを作る必要なしに名前空間 (や他) の副次的な効果を隔離することである. | ||
+ | |||
+ | clone() システムコールの他の効果はひとまず置いといて, | ||
+ | |||
+ | <code c> | ||
+ | |||
+ | という形式での呼び出しと,名前空間という点で,大体同じとなるのは以下のようなものである. | ||
+ | |||
+ | <code c> | ||
+ | if (fork() == 0) | ||
+ | unshare(CLONE_NEWXXX); | ||
+ | </ | ||
+ | |||
+ | unshare() システムコールの使い方の一つは,unshare コマンドの実装にある.このコマンドは,シェルとは別の名前空間内でコマンドを実行できるというものである.おおまかなコマンドの実行方法は | ||
+ | |||
+ | < | ||
+ | unshare [options] program [arguments] | ||
+ | </ | ||
+ | |||
+ | options は arguments を引数として program を実行する前に unshare する名前空間を指定するコマンドラインのオプションである. | ||
+ | |||
+ | unshare コマンドの実装のキーとなる部分はわかりやすい. | ||
+ | |||
+ | <code c> | ||
+ | /* Code to initialize ' | ||
+ | omitted */ | ||
+ | |||
+ | | ||
+ | |||
+ | /* Now execute ' | ||
+ | of the next command-line argument after options */ | ||
+ | |||
+ | | ||
+ | </ | ||
+ | |||
+ | unshare コマンドのシンプルな実装 (unshare.c) は [[http:// | ||
+ | |||
+ | 以下のシェルのセッションでは,unshare.c を使い,別のマウント名前空間でシェルを実行している.先週の記事で注意したようにマウント名前空間は,プロセスのグループから見えるファイルシステムのマウントポイントの組を隔離するものであり,異なるマウント名前空間内のプロセスは異なったファイルシステム構造が持てるというものである. | ||
+ | |||
+ | < | ||
+ | # echo $$ # シェルの PID を見る | ||
+ | 8490 | ||
+ | # cat / | ||
+ | mqueue /dev/mqueue mqueue rw, | ||
+ | # readlink / | ||
+ | mnt: | ||
+ | # ./unshare -m / | ||
+ | # readlink / | ||
+ | mnt: | ||
+ | </ | ||
+ | |||
+ | 2 度実行した readlink コマンドの出力を比べると,2 つのシェルは別のマウント名前空間にいることが示されている.片方の名前空間のマウントポイントの組を変化させ,他の名前空間で変化が見えるかどうかをチェックすることで,2 つのプログラムが別の名前空間内にいることを別の方法でデモする. | ||
+ | |||
+ | < | ||
+ | # umount / | ||
+ | # cat / | ||
+ | # cat / | ||
+ | mqueue /dev/mqueue mqueue rw, | ||
+ | </ | ||
+ | |||
+ | 最後の 2 つのコマンドの出力から分かるように,/ | ||
+ | |||
+ | ===== 最後に ===== | ||
+ | |||
+ | この記事では,名前空間API の基本的な部分を見て,それをどのように組み合わせて使うかを示した.後に続く記事では,他のいくつかの名前空間でより深い部分を見ていく.特に PID とユーザ名前空間を見る.ユーザ名前空間は,アプリケーションが,従来は特権アプリに限られていたカーネルインターフェースの使用するための新しい可能性を広げるものである. | ||