Provided by: manpages-ja-dev_0.5.0.0.20161015+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/ に書かれている。