Provided by: manpages-ja-dev_0.5.0.0.20210215+dfsg-1_all
名前
unshare - プロセス実行コンテキストの一部を分離する
書式
#include <sched.h> int unshare(int flags); glibc 向けの機能検査マクロの要件 (feature_test_macros(7) 参照): unshare(): glibc 2.14 以降: _GNU_SOURCE glibc 2.14 より前: _BSD_SOURCE || _SVID_SOURCE /* _GNU_SOURCE も定義される */
説明
unshare() を使うと、プロセスは他のプロセスと現在共有している 実行コンテキストの一部を分離 することができる。 実行コンテキストの一部、たとえばマウント名前空間 (mount namespace) な どは、新しいプロセスを fork(2) または vfork(2) を使って生成したときに、暗黙のうちに共有 される。 一方、仮想メモリーなどは、 clone(2) を使ってプロセスを生成するときに、明示的に共 有することを要求できる。 unshare() の主な利用法は、プロセスが新しいプロセスを生成することなく、 共有実行コンテキス トを制御することである。 flags 引き数はビットマスクであり、 実行コンテキストのどの部分の共有を解除するかを表す。 こ の引き数は、以下の定数の 0 個以上の OR で指定する: CLONE_FILES clone(2) CLONE_FILES フラグの効果を取り消す。 ファイルディスクリプターテーブルを共 有させず、 呼び出し元プロセスは他のプロセスとファイルディスクリプターを共有しなくな る。 CLONE_FS clone(2) CLONE_FS フラグの効果を取り消す。ファイルシステム属性を共有させず、呼び出 し元プロセスは、ルートディレクトリ (chroot(2))、カレントディレクトリ (chdir(2))、 umask (umask(2)) を他のプロセスと共有しなくなる。 CLONE_NEWIPC (Linux 2.6.19 以降) このフラグは clone(2) CLONE_NEWIPC フラグと同じ効果を持つ。 System V IPC 名前空間を 共有せず、呼び出し元プロセスは 他のプロセスとは 共有しない固有の System V IPC 名前 空間のコピーを持つ。 このフラグを指定 すると、 CLONE_SYSVSEM も暗黙のうちに指定され る。 CLONE_NEWIPC を 使用するには CAP_SYS_ADMIN ケーパビリティが必要である。 CLONE_NEWNET (Linux 2.6.24 以降) このフラグは clone(2) CLONE_NEWNET フラグと同じ効果を持つ。ネット ワーク名前空間を 共有せず、呼び出し元プロセスは他のプロセスとは共有しな い固有のネットワーク名前空間 のコピーを持つ。CLONE_NEWNET を使用する には CAP_SYS_ADMIN ケーパビリティが必要であ る。 CLONE_NEWNS このフラグは clone(2) CLONE_NEWNS フラグと同じ効果を持つ。 マウン ト名前空間を共有 せず、呼び出し元プロセスは 他のプロセスとは共有しない固 有の名前空間のコピーを持 つ。 このフラグを指定すると、 CLONE_FS も暗 黙のうちに指定される。 CLONE_NEWNS を使 用するには CAP_SYS_ADMIN ケーパビリティが必要である。 CLONE_NEWPID (Linux 3.8 以降) このフラグは clone(2) CLONE_NEWPID フラグと同じ効果を持つ。 PID 名前空間を共有しな い。 呼び出し元プロセスは、 すでに存在するどのプロセスとも共有されない新しい PID 名 前空間を、 自身の子プロセス用に持つことになる。 このプロセスにより作成される最初の 子プロセスはプロセス ID 1 を持ち、 この新しい名前空間において init(1) の役割を持つ とみなされる。 CLONE_NEWPID を指定すると、自動的に CLONE_THREAD も指定されたものと みなされる。 CLONE_NEWPID を使用するには CAP_SYS_ADMIN ケーパビリティが必要である。 詳細な情報は pid_namespaces(7) を参照。 CLONE_NEWUSER (Linux 3.8 以降) このフラグは clone(2) CLONE_NEWUSER フラグと同じ効果を持つ。 ユーザー名前空間を共有 せず、 呼び出し元プロセスはすでに存在するどのプロセスとも共有されない新しいユーザー 名前空間に移動される。 CLONE_NEWUSER フラグを指定して clone(2) で作成された子プロセ スと同様に、 呼び出し元は新しい名前空間ですべてのケーパビリティを獲得する。 CLONE_NEWUSER を使うには、呼び出し元プロセスがスレッド化されていないことが必要であ る。 CLONE_NEWUSER を指定すると、自動的に CLONE_THREAD が指定されたものとみなされ る。 Linux 3.9 以降では、 CLONE_NEWUSER が指定された場合 CLONE_FS も指定されたとみ なされる。 CLONE_NEWUSER を使うには、呼び出し元プロセスのユーザー ID とグループ ID が、 呼び出した時点で、 呼び出し元プロセスのユーザー名前空間のユーザー ID とグルー プ ID にマッピングされている必要がある。 ユーザー名前空間の詳細は user_namespaces(7) を参照。 CLONE_NEWUTS (Linux 2.6.19 以降) このフラグは clone(2) CLONE_NEWUTS フラグと同じ効果を持つ。 UTS IPC 名前空間を共有 せず、呼び出し元プロセスは他のプロセスとは共有しない 固有の UTS IPC 名前空間のコ ピーを持つ。 このフラグを指定すると、 CLONE_FS も暗黙のうちに指定され る。CLONE_NEWUTS を使用するには CAP_SYS_ADMIN ケーパビリティが必要である。 CLONE_SYSVSEM (Linux 2.6.26 以降) このフラグは clone(2) CLONE_SYSVSEM フラグの効果を逆転させる。 System V セマフォの 調整値 (semadj) を共有せず、 呼び出し元プロセスは他のプロセスとは共有されない新しい 空の semadj リストを持つ。 そのプロセスが、自分の現在の semadj リストへの参照を持つ 最後のプロセスであれば、 このリストの調整値は対応するセマフォに適用される (semop(2) に説明がある通り)。 上記に加えて、 呼び出し元がシングルスレッドの場合 (すなわち別のプロセスやスレッドとアドレ ス空間を共有していない場合)、 CLONE_THREAD, CLONE_SIGHAND, CLONE_VM を指定することができ る。 この場合、 これらのフラグは効果を持たない。 (CLONE_THREAD を指定すると自動的に CLONE_VM が指定されたとみなされ、 CLONE_VM を指定すると自動的に CLONE_SIGHAND が指定された とみなされる点に注意してほしい。) プロセスがマルチスレッドの場合、 これらのフラグを使用す るとエラーとなる。 flags に 0 が指定された場合、 unshare() は何も行わないので、 呼び出し元プロセスの実行コン テキストは、何も変更されない。
返り値
成功した場合は 0 が返される。 失敗した場合は -1 が返されて、 errno にはエラーを示す値が設 定される。
エラー
EINVAL flags に不正なビットが指定された。 EINVAL CLONE_THREAD, CLONE_SIGHAND, CLONE_VM が flags に指定されたが、 呼び出したプロセス はマルチスレッドである。 ENOMEM 呼び出し元のコンテキストのうち共有を解除する必要がある部分をコピーするために、 十分 なメモリーが確保できなかった。 EPERM 呼び出し元プロセスはこの操作を行うのに必要な特権を持っていなかった。 EPERM CLONE_NEWUSER が flags に指定されたが、 呼び出し元の実効ユーザー ID もしくは実効グ ループ ID が親名前空間にマッピングがない (user_namespaces(7) 参照)。 EPERM (Linux 3.9 以降) CLONE_NEWUSER が flags に指定され、 呼び出し元が chroot された環境にいる (すなわ ち、呼び出し元の root ディレクトリが呼び出し元が属するマウント名前空間の root ディ レクトリに一致しない)。 EUSERS (Linux 3.11 以降) CLONE_NEWUSER が flags に指定されており、 この呼び出しによりネストされたユーザー名 前空間数の上限を超えてしまう。 user_namespaces(7) を参照。
バージョン
unshare() システムコールは Linux カーネル 2.6.16 で追加された。
準拠
unshare() システムコールは Linux 固有である。
注意
clone(2) で新しいプロセスを生成したときに共有される全てのプロセス属性を、 unshare() に よって共有の解除ができるわけではない。 特に、カーネル 3.8 時点では、 unshare() に CLONE_SIGHAND, CLONE_THREAD, CLONE_VM の効果を取り消すためのフラグが実装されていない。 こ れらの機能は、必要であれば将来追加されるかもしれない。
例
以下のプログラムは unshare(1) コマンドの簡単な実装である。 このコマンドは、1 つ以上の名前 空間の unshare を行ってから、 コマンドライン引き数で指定されたコマンドを実行する。 以下は このプログラムの使用例である。 新しいマウント名前空間でシェルを実行し、 元のシェルと新しい シェルが別のマウント名前空間にいることを確認している。 $ readlink /proc/$$/ns/mnt mnt:[4026531840] $ sudo ./unshare -m /bin/bash [sudo] password for cecilia: # readlink /proc/$$/ns/mnt mnt:[4026532325] 2 つの readlink(1) コマンドの出力が違うことから、 2 つのシェルは異なるマウント名前空間にい ることが分かる。 プログラムのソース /* unshare.c A simple implementation of the unshare(1) command: unshare namespaces and execute a command. */ #define _GNU_SOURCE #include <sched.h> #include <unistd.h> #include <stdlib.h> #include <stdio.h> /* A simple error-handling function: print an error message based on the value in 'errno' and terminate the calling process */ #define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \ } while (0) static void usage(char *pname) { fprintf(stderr, "Usage: %s [options] program [arg...]\n", pname); fprintf(stderr, "Options can be:\n"); fprintf(stderr, " -i unshare IPC namespace\n"); fprintf(stderr, " -m unshare mount namespace\n"); fprintf(stderr, " -n unshare network namespace\n"); fprintf(stderr, " -p unshare PID namespace\n"); fprintf(stderr, " -u unshare UTS namespace\n"); fprintf(stderr, " -U unshare user namespace\n"); exit(EXIT_FAILURE); } int main(int argc, char *argv[]) { int flags, opt; flags = 0; while ((opt = getopt(argc, argv, "imnpuU")) != -1) { switch (opt) { case 'i': flags |= CLONE_NEWIPC; break; case 'm': flags |= CLONE_NEWNS; break; case 'n': flags |= CLONE_NEWNET; break; case 'p': flags |= CLONE_NEWPID; break; case 'u': flags |= CLONE_NEWUTS; break; case 'U': flags |= CLONE_NEWUSER; break; default: usage(argv[0]); } } if (optind >= argc) usage(argv[0]); if (unshare(flags) == -1) errExit("unshare"); execvp(argv[optind], &argv[optind]); errExit("execvp"); }
関連項目
unshare(1), clone(2), fork(2), kcmp(2), setns(2), vfork(2), namespaces(7) Linux カーネルソース内の Documentation/unshare.txt
この文書について
この man ページは Linux man-pages プロジェクトのリリース 3.79 の一部 である。プロジェクト の説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。