Provided by: manpages-ja-dev_0.5.0.0.20221215+dfsg-1_all bug

名前

       unshare - プロセス実行コンテキストの一部を分離する

書式

       #define _GNU_SOURCE
       #include <sched.h>

       int unshare(int flags);

説明

       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_NEWCGROUP (Linux 4.6 以降)
              This  flag  has the same effect as the clone(2)  CLONE_NEWCGROUP flag.  Unshare the
              cgroup namespace.  Use of CLONE_NEWCGROUP requires the CAP_SYS_ADMIN capability.

       CLONE_NEWIPC (Linux 2.6.19 以降)
              このフラグは clone(2) CLONE_NEWIPC  フラグと同じ効果を持つ。  IPC  名前空間を共有せ
              ず、呼び出し元プロセスは  他のプロセスとは共有しない固有の 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 ケーパビリティが必要である。詳細は mount_namespaces(7) を参照。

       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_NEWTIME (Linux 5.6 以降)
              Unshare  the  time  namespace, so that the calling process has a new time namespace
              for its children which is not shared with any  previously  existing  process.   The
              calling process is not moved into the new namespace.  Use of CLONE_NEWTIME requires
              the CAP_SYS_ADMIN capability.  For further information, see time_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_VMflags に指定されたが、  呼び出したプロセス
              はマルチスレッドである。

       EINVAL flagsCLONE_NEWIPC  が指定されたが、カーネルでオプション  CONFIG_SYSVIPCCONFIG_IPC_NS が有効になっていなかった。

       EINVAL flagsCLONE_NEWNET が指定されたが、カーネルでオプション  CONFIG_NET_NS  が有効に
              なっていなかった。

       EINVAL flagsCLONE_NEWPID が指定されたが、カーネルでオプション CONFIG_PID_NS が有効に
              なっていなかった。

       EINVAL flagsCLONE_NEWUSER が指定されたが、カーネルでオプション CONFIG_USER_NS が有効に
              なっていなかった。

       EINVAL flagsCLONE_NEWUTS が指定されたが、カーネルでオプション CONFIG_UTS_NS が有効に
              なっていなかった。

       EINVAL CLONE_NEWPID was  specified  in  flags,  but  the  process  has  previously  called
              unshare()  with the CLONE_NEWPID flag.

       ENOMEM 呼び出し元のコンテキストのうち共有を解除する必要がある部分をコピーするために、 十分
              なメモリーが確保できなかった。

       ENOSPC (Linux 3.7 以降)
              CLONE_NEWPID was specified in flags, but the limit on  the  nesting  depth  of  PID
              namespaces would have been exceeded; see pid_namespaces(7).

       ENOSPC (Linux 4.9 以降; 以前は EUSERS)
              CLONE_NEWUSERflags に指定されており、 この呼び出しによりネストされたユーザー名
              前空間数の上限を超えてしまう。 user_namespaces(7) を参照。

              From Linux 3.11 to Linux 4.8, the error diagnosed in this case was EUSERS.

       ENOSPC (Linux 4.9 以降)
              One of the values in flags specified the creation of  a  new  user  namespace,  but
              doing  so  would  have  caused  the  limit  defined  by  the  corresponding file in
              /proc/sys/user to be exceeded.  For further details, see namespaces(7).

       EPERM  呼び出し元プロセスはこの操作を行うのに必要な特権を持っていなかった。

       EPERM  CLONE_NEWUSERflags に指定されたが、 呼び出し元の実効ユーザー ID  もしくは実効グ
              ループ ID が親名前空間にマッピングがない (user_namespaces(7) 参照)。

       EPERM (Linux 3.9 以降)
              CLONE_NEWUSERflags  に指定され、 呼び出し元が chroot された環境にいる (すなわ
              ち、呼び出し元の root ディレクトリが呼び出し元が属するマウント名前空間の root  ディ
              レクトリに一致しない)。

        EUSERS (from Linux 3.11 to Linux 4.8)
              CLONE_NEWUSER  was  specified  in flags, and the limit on the number of nested user
              namespaces would be exceeded.  See the discussion of the ENOSPC error above.

バージョン

       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
           # 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, "    -C   unshare cgroup namespace\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, "    -t   unshare time 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, "CimnptuU")) != -1) {
               switch (opt) {
               case 'C': flags |= CLONE_NEWCGROUP;      break;
               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 't': flags |= CLONE_NEWTIME;        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/userspace-api/unshare.rst  (Linux 4.12 より前では
       Documentation/unshare.txt)

この文書について

       この man ページは Linux man-pages プロジェクトのリリース 5.10 の一部である。プロジェクトの
       説明とバグ報告に関する情報は https://www.kernel.org/doc/man-pages/ に書かれている。