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

名前

       setns - スレッドに名前空間を関連付けしなおす

書式

       #define _GNU_SOURCE             /* feature_test_macros(7) 参照 */
       #include <sched.h>

       int setns(int fd, int nstype);

説明

       名前空間を参照するファイルディスクリプターを指定すると、 呼び出したスレッドにその名前空間を関連付けしなお
       す。

       fd 引き数は、 /proc/[pid]/ns/ ディレクトリ内の名前空間エントリー のいずれかを参照するファイルディスクリプ
       ターである。 /proc/[pid]/ns/ の詳細は namespaces(7) を参照。 nstype 引き数で指定された制限の範囲内で、 呼
       び出したスレッドに fd に対応する名前空間を関連付けしなおす。

       nstype 引き数は、呼び出したスレッドがどのタイプの名前空間を 関連付けしなおすことができるかを指定する。 こ
       の引き数には以下のいずれかの値を指定できる。

       0      どのタイプの名前空間も関連付けることができる。

       CLONE_NEWIPC (Linux 3.0 以降)
              fd は IPC 名前空間を参照していなければならない。

       CLONE_NEWNET (Linux 3.0 以降)
              fd はネットワーク名前空間を参照していなければならない。

       CLONE_NEWNS (Linux 3.8 以降)
              fd はマウント名前空間を参照していなければならない。

       CLONE_NEWPID (Linux 3.8 以降)
              fd は子孫の PID 名前空間を参照していなければならない。

       CLONE_NEWUSER (Linux 3.8 以降)
              fd はユーザー名前空間を参照していなければならない。

       CLONE_NEWUTS (Linux 3.0 以降)
              fd は UTS 名前空間を参照していなければならない。

       呼び出し側が  fd  がどのタイプの名前空間を参照しているかを知っている  (もしくは気にする必要がない) 場合に
       は、 nstype に 0 を指定すれば十分 である。呼び出し側が fd がどのタイプの名前空間を参照しているかを 知って
       おらず、かつ、特定のタイプの名前空間であることを保証したい場合、  nstype  に 0 以外の値を指定するとよい。
       (ファイルディスクリプターが別の  プロセスによりオープンされ、例えば、UNIX  ドメインソケット経由で呼び出し
       側に渡された場合などでは、呼び出し側が   fd  がどのタイプの名前空間を  参照しているかを知らない可能性があ
       る。)

       CLONE_NEWPID は他の nstype 値の場合と少し違った動作をする。 呼び出し元スレッドを PID 名前空間に関連付けし
       直すと、  呼び出し元の子プロセスが作成される PID 名前空間が変更されるだけである。 呼び出し元自身の PID 名
       前空間は変更されない。 PID 名前空間を関連付けし直すことができるのは、 fd で指定された PID  名前空間が呼び
       出し元の   PID   名前空間の子孫   (子プロセス、孫プロセスなど)  の場合だけである。  PID  名前空間の詳細は
       pid_namespaces(7) を参照。

       プロセスが自分自身をユーザー名前空間に再関連付けするには、 そのプロセスは変更後のユーザー名前空間において
       CAP_SYS_ADMIN  ケーパビリティを持っていなければならない。 ユーザー名前空間への参加に成功すると、 そのユー
       ザー ID やグループ ID  に関わらず、  プロセスにはその名前空間におけるすべてのケーパビリティが認められる。
       マルチスレッドのプロセスは  setns() でユーザー名前空間を変更できない。 setns() を使って、呼び出し元が現在
       のユーザー名前空間に再度入ることは認められていない。 これにより、  いくつかのケーパビリティを外した呼び出
       し元が  setns() を呼び出すことでそれらのケーパビリティを再度得ることを防ぐことができる。 セキュリティ上の
       理由から、 ファイルシステム関連の属性 (共有が clone(2) CLONE_FS フラグで制御される属性)  を別のプロセスと
       共有している場合、        プロセスは新しいユーザー名前空間に参加できない。       ユーザー名前空間の詳細は
       user_namespaces(7) を参照。

       プロセスがマルチスレッドの場合、そのプロセスを新しいマウント名前空間に関連付けし直すことは許可されていな
       い。      マウント名前空間を変更するには、呼び出し元のプロセスが、     自分自身のユーザー名前空間において
       CAP_SYS_CHROOTCAP_SYS_ADMIN    の両方のケーパビリティを持っており、    変更後のマウント名前空間で
       CAP_SYS_ADMIN ケーパビリティを持っていなければならない。 ユーザー名前空間とマウント名前空間の関係の詳細は
       user_namespaces(7) を参照。

返り値

       成功すると setns() は 0 を返す。 失敗すると、 -1 が返され、 errno にエラーを示す値が設定される。

エラー

       EBADF  fd が有効なファイルディスクリプターではない。

       EINVAL fdnstype で指定されたタイプと一致しない名前空間を参照している。

       EINVAL スレッドを指定された名前空間に関連付けし直す際に問題が発生した。

       EINVAL 呼び出し元が先祖 (親や親の親など) の PID 名前空間に参加しようとした。

       EINVAL 自分がすでにメンバーとなっているユーザー名前空間に参加しようとした。

       EINVAL 呼び出し元が他のプロセスとファイルシステム状態    (特に    root    ディレクトリ)    を共有していて
              (CLONE_FS)、 新しいユーザー名前空間に参加しようとした。

       EINVAL 呼び出し元プロセスがマルチスレッドで、新しいユーザー名前空間に参加しようとした。

       ENOMEM 指定された名前空間に変更するのに必要なメモリーが割り当てられない。

       EPERM  呼び出し元スレッドはこの操作を行うのに必要なケーパビリティを持っていなかった。

バージョン

       setns()  システムコールはカーネル  3.0  で Linux に初めて登場した。 ライブラリによるサポートは glibc バー
       ジョン 2.14 を追加された。

準拠

       setns() システムコールは Linux 固有である。

注意

       新しいスレッドが clone(2) を使って作成された際に共有できる全ての属性を、 setns() を使って変更できるわけで
       はない。

       以下のプログラムは  2 つ以上の引き数を取る。 最初の引き数には、 既存の /proc/[pid]/ns/ ディレクトリの名前
       空間ファイルのパス名を指定する。 残りの引き数は、コマンドとその引き数を指定する。  このプログラムは名前空
       間ファイルをオープンし、  setns()  を使って名前空間に参加し、  指定されたコマンドをその名前空間内で実行す
       る。

       以下のシェルセッションでは、 このプログラム (ns_exec  という名前のバイナリとしてコンパイルされている)を、
       clone(2) のマニュアルページの CLONE_NEWUTS のサンプルプログラムと組み合わせて使っている。

       まず、 clone(2) のサンプルプログラムをバックグラウンドで実行する。 このプログラムは、 別の UTS 名前空間で
       子プロセスを作成する。 子プロセスは自分の名前空間内でホスト名を変更する。 それから、 親プロセスと子プロセ
       スの両方でそれぞれの UTS 名前空間のホスト名を表示し、 2 つのホスト名が違うことが確認できる。

           $ su                   # 名前空間の操作には特権が必要
           Password:
           # ./newuts bizarro &
           [1] 3549
           clone() returned 3550
           uts.nodename in child:  bizarro
           uts.nodename in parent: antero
           # uname -n             # シェルでホスト名を確認
           antero

       次に、以下のプログラムを使ってシェルを実行する。 このシェルの中では、ホスト名が最初のプログラムで作成され
       た子プロセスが設定したホスト名になっていることを確認できる。

           # ./ns_exec /proc/3550/ns/uts /bin/bash
           # uname -n             #  ns_exec で起動されたシェル内で実行
           bizarro

   プログラムのソース
       #define _GNU_SOURCE
       #include <fcntl.h>
       #include <sched.h>
       #include <unistd.h>
       #include <stdlib.h>
       #include <stdio.h>

       #define errExit(msg)    do { perror(msg); exit(EXIT_FAILURE); \
                               } while (0)

       int
       main(int argc, char *argv[])
       {
           int fd;

           if (argc < 3) {
               fprintf(stderr, "%s /proc/PID/ns/FILE cmd args...\n", argv[0]);
               exit(EXIT_FAILURE);
           }

           fd = open(argv[1], O_RDONLY);  /* 名前空間のディスクリプターを取得 */
           if (fd == -1)
               errExit("open");

           if (setns(fd, 0) == -1)        /* 名前空間に参加 */
               errExit("setns");

           execvp(argv[2], &argv[2]);     /* 名前空間内でコマンドを実行 */
           errExit("execvp");
       }

関連項目

       clone(2), fork(2), unshare(2), vfork(2), namespaces(7), unix(7)

この文書について

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