X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=draft%2Fman2%2Fclone.2;h=6b855b2eac6c930ddc8c2b03d3fbd7d595132c03;hb=fe231d72006b46400bc8bf48d8bca24b62994b25;hp=fb23fdd17fd7242a6e3e7c42b011ce63e6339a2c;hpb=c186e43b623c1066b9ff98caf69079f519993ce3;p=linuxjm%2FLDP_man-pages.git diff --git a/draft/man2/clone.2 b/draft/man2/clone.2 index fb23fdd1..6b855b2e 100644 --- a/draft/man2/clone.2 +++ b/draft/man2/clone.2 @@ -1,8 +1,10 @@ -.\" Hey Emacs! This file is -*- nroff -*- source. -.\" .\" Copyright (c) 1992 Drew Eckhardt , March 28, 1992 -.\" and Copyright (c) Michael Kerrisk, 2001, 2002, 2005 +.\" and Copyright (c) Michael Kerrisk, 2001, 2002, 2005, 2013 +.\" +.\" %%%LICENSE_START(GPL_NOVERSION_ONELINE) .\" May be distributed under the GNU General Public License. +.\" %%%LICENSE_END +.\" .\" Modified by Michael Haardt .\" Modified 24 Jul 1993 by Rik Faith .\" Modified 21 Aug 1994 by Michael Chastain : @@ -45,27 +47,72 @@ .\" This file was generated with po4a. Translate the source file. .\" .\"******************************************************************* -.TH CLONE 2 2011\-09\-08 Linux "Linux Programmer's Manual" +.\" +.\" Japanese Version Copyright (c) 2001 HANATAKA Shinya +.\" and Copyright(c) 2002, 2005-2008 Akihiro MOTOKI +.\" Translated 2001-08-17, HANATAKA Shinya +.\" Modified 2002-09-24, Akihiro MOTOKI +.\" Modified 2005-02-02, Akihiro MOTOKI +.\" Updated 2005-04-17, Akihiro MOTOKI +.\" Updated 2005-09-10, Akihiro MOTOKI +.\" Updated 2006-03-05, Akihiro MOTOKI, LDP v2.25 +.\" Updated 2007-01-05, Akihiro MOTOKI, LDP v2.43 +.\" Updated 2007-05-01, Akihiro MOTOKI, LDP v2.46 +.\" Updated 2007-06-13, Akihiro MOTOKI, LDP v2.55 +.\" Updated 2008-08-04, Akihiro MOTOKI, LDP v3.05 +.\" Updated 2008-11-09, Akihiro MOTOKI, LDP v3.10 +.\" Updated 2009-03-02, Akihiro MOTOKI, LDP v3.19 +.\" Updated 2010-04-11, Akihiro MOTOKI, LDP v3.24 +.\" Updated 2012-05-08, Akihiro MOTOKI +.\" Updated 2013-05-06, Akihiro MOTOKI +.\" +.TH CLONE 2 2014\-02\-27 Linux "Linux Programmer's Manual" .SH 名前 clone, __clone2 \- 子プロセスを作成する .SH 書式 .nf -.\" Actually _BSD_SOURCE || _SVID_SOURCE -.\" FIXME See http://sources.redhat.com/bugzilla/show_bug.cgi?id=4749 -\fB#define _GNU_SOURCE\fP /* feature_test_macros(7) 参照 */ +/* glibc ラッパー関数のプロトタイプ */ + \fB#include \fP \fBint clone(int (*\fP\fIfn\fP\fB)(void *), void *\fP\fIchild_stack\fP\fB,\fP \fB int \fP\fIflags\fP\fB, void *\fP\fIarg\fP\fB, ... \fP \fB /* pid_t *\fP\fIptid\fP\fB, struct user_desc *\fP\fItls\fP\fB, pid_t *\fP\fIctid\fP\fB */ );\fP + +/* 素のシステムコールのプロトタイプ */ + +\fBlong clone(unsigned long \fP\fIflags\fP\fB, void *\fP\fIchild_stack\fP\fB,\fP +\fB void *\fP\fIptid\fP\fB, void *\fP\fIctid\fP\fB,\fP +\fB struct pt_regs *\fP\fIregs\fP\fB);\fP .fi +.sp +.in -4n +glibc ラッパー関数の機能検査マクロの要件 (\fBfeature_test_macros\fP(7) 参照): +.in +.sp +\fBclone\fP(): +.ad l +.RS 4 +.PD 0 +.TP 4 +glibc 2.14 以降: +_GNU_SOURCE +.TP 4 +.\" See http://sources.redhat.com/bugzilla/show_bug.cgi?id=4749 +glibc 2.14 より前: +_BSD_SOURCE || _SVID_SOURCE + /* _GNU_SOURCE も定義される */ +.PD +.RE +.ad b .SH 説明 -\fBclone\fP() は \fBfork\fP(2) と同じような方法で新しいプロセスを作成する。 \fBclone\fP() -には、ライブラリ関数とその下層にあたる \fBclone\fP() システムコールが存在する。以下の説明では、システムコールの方を \fBsys_clone\fP -と表すこととする。 \fBsys_clone\fP に関する説明はこのマニュアルの最後の方にある。 +\fBclone\fP() は、 \fBfork\fP(2) と似た方法で新しいプロセスを作成する。 + +このページでは、 glibc の \fBclone\fP() ラッパー関数とその裏で呼ばれるシステムコールの両方について説明している。 +メインの説明はラッパー関数に関するものである。 素のシステムコールにおける差分はこのページの最後の方で説明する。 -\fBfork\fP(2) とは異なり、これらのコールでは、子プロセス (child process) と呼び出し元のプロセスとが、メモリ空間、 -ファイルディスクリプタのテーブル、シグナル・ハンドラのテーブルなどの 実行コンテキストの一部を共有できる。 +\fBfork\fP(2) とは異なり、\fBclone\fP() では、子プロセス (child process) +と呼び出し元のプロセスとが、メモリ空間、ファイルディスクリプタのテーブル、シグナルハンドラのテーブルなどの 実行コンテキストの一部を共有できる。 (このマニュアルにおける「呼び出し元のプロセス」は、通常は 「親プロセス」と一致する。但し、後述の \fBCLONE_PARENT\fP の項も参照のこと) \fBclone\fP() の主要な使用法はスレッド (threads) を実装することである: @@ -101,7 +148,7 @@ wake (起床) させる。 このアドレスは \fBset_tid_address\fP(2) シ \fBCLONE_CHILD_SETTID\fP (Linux 2.5.49 以降) 子プロセスのメモリ内の \fIctid\fP が指す場所に子プロセスのスレッド ID を格納する。 .TP -\fBCLONE_FILES\fP +\fBCLONE_FILES\fP (Linux 2.0 以降) \fBCLONE_FILES\fP が設定された場合、呼び出し元のプロセスと子プロセスはファイルディスクリプタの テーブルを共有する。 呼び出し元プロセスとその子プロセスの一方が作成した ファイルディスクリプタは、もう一方においても有効である。 同じように、一方のプロセスがファイルディスクリプタを閉じたり、 (\fBfcntl\fP(2) \fBF_SETFD\fP 操作を使って) @@ -113,14 +160,14 @@ wake (起床) させる。 このアドレスは \fBset_tid_address\fP(2) シ 参照) を参照する)。 これ以降に、呼び出し元のプロセスと子プロセスの一方が ファイルディスクリプタの操作 (ファイルディスクリプタの オープン・クローズや、ファイルディスクリプタ・フラグの変更) を行っても、もう一方のプロセスには影響を与えない。 .TP -\fBCLONE_FS\fP -\fBCLONE_FS\fP が設定された場合、呼び出し元のプロセスと子プロセスが同じファイル・システム -情報を共有する。ファイル・システム情報は、ファイル・システムのルート (root)、 カレント・ワーキング・ディレクトリ (current -working directory) や umask などである。 呼び出し元のプロセスや子プロセスのどちらか一方によって \fBchroot\fP(2), +\fBCLONE_FS\fP (Linux 2.0 以降) +\fBCLONE_FS\fP が設定された場合、呼び出し元のプロセスと子プロセスが同じファイルシステム +情報を共有する。ファイルシステム情報は、ファイルシステムのルート (root)、 カレントワーキングディレクトリ (current working +directory) や umask などである。 呼び出し元のプロセスや子プロセスのどちらか一方によって \fBchroot\fP(2), \fBchdir\fP(2), \fBumask\fP(2) が呼び出されると、もう一方のプロセスにも影響が及ぶ。 \fBCLONE_FS\fP が設定されていない場合、子プロセスは、 \fBclone\fP() -が実行された時点での、呼び出し元のプロセスのファイル・システム情報のコピーを 使用する。 これ以降は、呼び出し元のプロセスと子プロセスの一方が +が実行された時点での、呼び出し元のプロセスのファイルシステム情報のコピーを 使用する。 これ以降は、呼び出し元のプロセスと子プロセスの一方が \fBchroot\fP(2), \fBchdir\fP(2), \fBumask\fP(2) を呼び出しても、もう一方のプロセスには影響を与えない。 .TP \fBCLONE_IO\fP (Linux 2.6.25 以降) @@ -144,9 +191,14 @@ I/O コンテキストは、ディスクスケジュールの I/O スコープ このフラグが設定されていない場合、 (\fBfork\fP(2) の場合と同様) 呼び出し元のプロセスと同じ IPC 名前空間でプロセスが 作成される。 このフラグは、コンテナの実装での使用を意図して用意されたものである。 -IPC 名前空間は、System V IPC オブジェクト用の識別子 (identifiers) の 集合で構成される (System V IPC -オブジェクトは \fBmsgctl\fP(2), \fBsemctl\fP(2), \fBshmctl\fP(2) を使って作成される)。 ある IPC -名前空間に作成されたオブジェクトは、 その名前空間のメンバーである他のすべてのプロセスからも見えるが、 違う IPC 名前空間のプロセスからは見えない。 +.\" commit 7eafd7c74c3f2e67c27621b987b28397110d643f +.\" https://lwn.net/Articles/312232/ +IPC 名前空間は、独立の System\ V IPC オブジェクト空間 (\fBsvipc\fP(7) 参照) を提供する 。 (Linux 2.6.30 +以降では) 独立した POSIX メッセージキュー空間 (\fBmq_overview\fP(7) 参照) も提供される。 これらの IPC +機構に共通の特徴として、 IPC オブジェクトはファイルシステムのパス名とは違った仕組みで識別されるという点がある。 + +ある IPC 名前空間に作成されたオブジェクトは、 その名前空間のメンバーである他のすべてのプロセスからも見えるが、 違う IPC +名前空間のプロセスからは見えない。 IPC 名前空間が破棄される時 (すなわち、その名前空間のメンバーの最後のプロセスが終了する時)、 その名前空間の全ての IPC オブジェクトは自動的に破棄される。 @@ -157,12 +209,13 @@ IPC 名前空間が破棄される時 (すなわち、その名前空間のメ .TP \fBCLONE_NEWNET\fP (Linux 2.6.24 以降) .\" FIXME Check when the implementation was completed -(このフラグの実装は、Linux 2.6.29 あたりまでに完成した。) +(このフラグの実装は、Linux 2.6.29 あたりまでには完成した。) \fBCLONE_NEWNET\fP が設定された場合、新しいネットワーク名前空間 (network namaspace) でプロセスを作成する。 このフラグが設定されていない場合、 (\fBfork\fP(2) の場合と同様) 呼び出し元のプロセスと同じネットワーク名前空間でプロセスが 作成される。 このフラグは、コンテナの実装での使用を意図して用意されたものである。 +.\" FIXME Add pointer to veth(4) page when it is eventually completed ネットワーク名前空間は、分離されたネットワークスタックを提供するものである (ネットワークスタックとは、 ネットワークデバイスインタフェース、IPv4 や IPv6 プロトコルスタック、 \fI/proc/net\fP、 \fI/sys/class/net\fP ディレクトリツリー、ソケットなどである)。 物理ネットワークデバイスが所属できるネットワーク名前空間は一つだけである。 仮想ネットワークデバイス ("veth") のペアにより パイプ風の抽象化 @@ -258,7 +311,7 @@ UTS 名前空間は、 \fBuname\fP(2) が返す識別子の集合である。 で作成される。これはシステムをハッキングするのには便利だが、 それ以外にはあまり使われない。 Linux 2.3.21 以降では、 システムのブートプロセス (PID 0) だけがこのフラグを指定できる。 Linux 2.5.16 で削除された。 .TP -\fBCLONE_PTRACE\fP +\fBCLONE_PTRACE\fP (Linux 2.2 以降) \fBCLONE_PTRACE\fP が指定され、かつ呼び出し元のプロセスが追跡 (trace) されていた場合、子プロセスも 同様に追跡される。 (\fBptrace\fP(2) を参照のこと) .TP @@ -266,16 +319,16 @@ UTS 名前空間は、 \fBuname\fP(2) が返す識別子の集合である。 \fInewtls\fP 引き数は、新しい TLS (Thread Local Storage) ディスクリプタである。 (\fBset_thread_area\fP(2) を参照のこと) .TP -\fBCLONE_SIGHAND\fP -\fBCLONE_SIGHAND\fP が設定された場合、呼び出し元のプロセスと子プロセスは同じシグナル・ハン +\fBCLONE_SIGHAND\fP (Linux 2.0 以降) +\fBCLONE_SIGHAND\fP が設定された場合、呼び出し元のプロセスと子プロセスは同じシグナルハン ドラのテーブルを共有する。呼び出し元のプロセスまたは子プロセスのどちらかが \fBsigaction\fP(2) を呼び出してシグナルに対応する動作を変更した場合、 もう一方のプロセスのシグナル動作も変更される。 但し、呼び出し元のプロセスと子プロセスは、 -プロセス毎に、シグナル・マスク (signal mask) と処理待ちシグナルの集合 を持っている。このため、あるプロセスは、 +プロセス毎に、シグナルマスク (signal mask) と処理待ちシグナルの集合 を持っている。このため、あるプロセスは、 \fBsigprocmask\fP(2) を使用して、もう一方のプロセスに影響を与えずに シグナルを禁止 (block) したり許可 (unblock) したりできる。 \fBCLONE_SIGHAND\fP が設定されていない場合、子プロセスは \fBclone\fP() -が実行された時点での、呼び出し元のプロセスのシグナル・ハンドラの コピーを継承する。これ以降は、一方のプロセスが \fBsigaction\fP(2) +が実行された時点での、呼び出し元のプロセスのシグナルハンドラの コピーを継承する。これ以降は、一方のプロセスが \fBsigaction\fP(2) を呼び出しても、もう一方のプロセスには影響を与えない。 Linux 2.6.0\-test6 以降では、 \fBCLONE_SIGHAND\fP を指定する場合、 \fBCLONE_VM\fP も \fIflags\fP @@ -290,71 +343,71 @@ Linux 2.6.0\-test6 以降では、 \fBCLONE_SIGHAND\fP を指定する場合、 Linux 2.6.38 で完全に\fI削除\fPされた。 .TP \fBCLONE_SYSVSEM\fP (Linux 2.5.10 以降) -\fBCLONE_SYSVSEM\fP がセットされると、子プロセスと呼び出し元プロセスは一つの System V セマフォのアンドゥ値リスト +\fBCLONE_SYSVSEM\fP がセットされると、子プロセスと呼び出し元プロセスは一つの System\ V セマフォのアンドゥ値リスト (\fBsemop\fP(2) 参照) を共有する。このフラグがセットされていなければ、 子プロセスは独自のアンドゥリストを持つ (リストの初期値は空である)。 .TP \fBCLONE_THREAD\fP (Linux 2.4.0\-test8以降) -\fBCLONE_THREAD\fP が設定された場合、子プロセスは呼び出し元のプロセスと同じスレッド・グループに 置かれる。 \fBCLONE_THREAD\fP -についての以降の議論を読みやすくするため、 「スレッド」という用語はスレッド・グループの中のプロセスを 参照するのに使うこととする。 +\fBCLONE_THREAD\fP が設定された場合、子プロセスは呼び出し元のプロセスと同じスレッドグループに 置かれる。 \fBCLONE_THREAD\fP +についての以降の議論を読みやすくするため、 「スレッド」という用語はスレッドグループの中のプロセスを 参照するのに使うこととする。 -スレッド・グループは、 スレッド集合で一つの PID を共有するという POSIX スレッドの概念をサポートするために Linux 2.4 -に加えられた機能であった。 内部的には、この共有 PID はいわゆるそのスレッドグループの スレッド・グループ識別子 (TGID) である。 Linux -2.4 以降では、 \fBgetpid\fP(2) の呼び出しではそのプロセスのスレッド・グループ ID を返す。 +スレッドグループは、 スレッド集合で一つの PID を共有するという POSIX スレッドの概念をサポートするために Linux 2.4 +に加えられた機能であった。 内部的には、この共有 PID はいわゆるそのスレッドグループの スレッドグループ識別子 (TGID) である。 Linux +2.4 以降では、 \fBgetpid\fP(2) の呼び出しではそのプロセスのスレッドグループ ID を返す。 あるグループに属するスレッドは (システム全体で) 一意なスレッド ID (TID) で区別できる。新しいスレッドの TID は \fBclone\fP() の呼び出し元へ関数の結果として返され、 スレッドは自分自身の TID を \fBgettid\fP(2) で取得できる。 \fBCLONE_THREAD\fP を指定せずに \fBclone\fP() の呼び出しが行われると、 生成されたスレッドはそのスレッドの TID と同じ値の -TGID を持つ 新しいスレッド・グループに置かれる。このスレッドは 新しいスレッド・グループの「リーダー」である。 +TGID を持つ 新しいスレッドグループに置かれる。このスレッドは 新しいスレッドグループの「リーダー」である。 \fBCLONE_THREAD\fP を指定して作成された新しいスレッドは、 (\fBCLONE_PARENT\fP の場合と同様に) \fBclone\fP() -を呼び出し元と同じ親プロセスを持つ。 そのため、 \fBgetppid\fP(2) を呼ぶと、一つのスレッド・グループに属すスレッドは全て同じ値を返す。 +を呼び出し元と同じ親プロセスを持つ。 そのため、 \fBgetppid\fP(2) を呼ぶと、一つのスレッドグループに属すスレッドは全て同じ値を返す。 \fBCLONE_THREAD\fP で作られたスレッドが終了した際に、 そのスレッドを \fBclone\fP() を使って生成したスレッドには \fBSIGCHLD\fP (もしくは他の終了シグナル) は送信されない。 また、 \fBwait\fP(2) を使って終了したスレッドの状態を取得することもできない (そのようなスレッドは \fIdetached\fP (分離された) といわれる)。 -スレッド・グループに属す全てのスレッドが終了した後、 そのスレッド・グループの親プロセスに \fBSIGCHLD\fP (もしくは他の終了シグナル) -が送られる。 +スレッドグループに属す全てのスレッドが終了した後、 そのスレッドグループの親プロセスに \fBSIGCHLD\fP (もしくは他の終了シグナル) が送られる。 -スレッド・グループに属すいずれかのスレッドが \fBexecve\fP(2) を実行すると、スレッド・グループ・リーダー以外の全てのスレッドは -終了され、新しいプロセスがそのスレッド・グループ・リーダーの下で 実行される。 +スレッドグループに属すいずれかのスレッドが \fBexecve\fP(2) を実行すると、スレッドグループリーダー以外の全てのスレッドは +終了され、新しいプロセスがそのスレッドグループリーダーの下で 実行される。 -スレッド・グループに属すスレッドの一つが \fBfork\fP(2) を使って子プロセスを作成した場合、 スレッド・グループのどのスレッドであっても -その子供を \fBwait\fP(2) できる。 +スレッドグループに属すスレッドの一つが \fBfork\fP(2) を使って子プロセスを作成した場合、 スレッドグループのどのスレッドであっても その子供を +\fBwait\fP(2) できる。 Linux 2.5.35 以降では、 \fBCLONE_THREAD\fP を指定する場合、 \fIflags\fP に \fBCLONE_SIGHAND\fP -も含まれていなければならない。 +も含まれていなければならない (Linux 2.6.0\-test6 以降では、 \fBCLONE_SIGHAND\fP を指定する場合 \fBCLONE_VM\fP +も指定する必要がある点に注意すること)。 -\fBkill\fP(2) を使ってスレッド・グループ全体 (つまり TGID) にシグナルを送ることもできれば、 \fBtgkill\fP(2) +\fBkill\fP(2) を使ってスレッドグループ全体 (つまり TGID) にシグナルを送ることもできれば、 \fBtgkill\fP(2) を使って特定のスレッド (つまり TID) にシグナルを送ることもできる。 シグナルの配送と処理はプロセス全体に影響する: ハンドラを設定していないシグナルがあるスレッドに配送されると、 -そのシグナルはスレッド・グループの全メンバーに影響を及ぼす (終了したり、停止したり、動作を継続したり、無視されたりする)。 +そのシグナルはスレッドグループの全メンバーに影響を及ぼす (終了したり、停止したり、動作を継続したり、無視されたりする)。 各々のスレッドは独自のシグナルマスクを持っており、 \fBsigprocmask\fP(2) で設定できる。 だが、処理待ちのシグナルには、 -\fBkill\fP(2) で送信されるプロセス全体に対するもの (つまり、スレッド・グループの どのメンバーにも配送できるもの) と、 +\fBkill\fP(2) で送信されるプロセス全体に対するもの (つまり、スレッドグループの どのメンバーにも配送できるもの) と、 \fBtgkill\fP(2) で送信される個々のスレッドに対するものがありえる。 \fBsigpending\fP(2) を呼び出すと、プロセス全体に対する処理待ちシグナルと呼び出し元の スレッドに対する処理待ちシグナルを結合したシグナル集合が返される。 -\fBkill\fP(2) を使ってスレッド・グループにシグナルが送られた場合で、 そのスレッド・グループがそのシグナルに対するシグナル・ハンドラが -登録されていたときには、シグナル・ハンドラはスレッド・グループの メンバーのうち、ただ一つのスレッドでだけ起動される。ハンドラが +\fBkill\fP(2) を使ってスレッドグループにシグナルが送られた場合で、 そのスレッドグループがそのシグナルに対するシグナルハンドラが +登録されていたときには、シグナルハンドラはスレッドグループの メンバーのうち、ただ一つのスレッドでだけ起動される。ハンドラが 起動されるスレッドは、そのシグナルを禁止 (block) していない メンバーの中から一つだけが勝手に (arbitrarily) 選ばれる。 -スレッド・グループに属す複数のスレッドが \fBsigwaitinfo\fP(2) を使って同じシグナルを待っている場合、 +スレッドグループに属す複数のスレッドが \fBsigwaitinfo\fP(2) を使って同じシグナルを待っている場合、 これらのスレッドの中から一つをカーネルが勝手に選択し、 そのスレッドが \fBkill (2)\fP を使って送信されたシグナルを受信する。 .TP \fBCLONE_UNTRACED\fP (Linux 2.5.46 以降) \fBCLONE_UNTRACED\fP が指定されると、 trace を行っているプロセスは この子プロセスに \fBCLONE_PTRACE\fP を適用することができない。 .TP -\fBCLONE_VFORK\fP +\fBCLONE_VFORK\fP (Linux 2.2 以降) \fBCLONE_VFORK\fP が設定された場合、 (\fBvfork\fP(2) と同様に) 子プロセスが \fBexecve\fP(2) または \fB_exit\fP(2) によって仮想メモリを解放するまで、呼び出し元のプロセスの実行は停止される。 \fBCLONE_VFORK\fP が設定されていない場合、 \fBclone\fP() 呼び出し後は、呼び出し元のプロセスと子プロセスの 両方がスケジュール対象となり、アプリケーションはこれらのプロセスの 実行順序に依存しないようにすべきである。 .TP -\fBCLONE_VM\fP +\fBCLONE_VM\fP (Linux 2.0 以降) \fBCLONE_VM\fP が設定された場合、呼び出し元のプロセスと子プロセスは同じメモリ空間で 実行される。特に、呼び出し元のプロセスや子プロセスの一方がメモリに 書き込んだ内容はもう一方のプロセスからも見ることができる。さらに、 子プロセスや呼び出し元のプロセスの一方が \fBmmap\fP(2) や \fBmunmap\fP(2) を使ってメモリをマップしたりアンマップした場合、 @@ -363,16 +416,47 @@ Linux 2.5.35 以降では、 \fBCLONE_THREAD\fP を指定する場合、 \fIflag \fBCLONE_VM\fP が設定されていない場合、子プロセスは \fBclone\fP() が実行された時点での、親プロセスのメモリ空間をコピーした 別のメモリ空間で実行される。 一方のプロセスが行ったメモリへの書き込みや ファイルのマップ/アンマップは、 \fBfork\fP(2) の場合と同様、もう一方のプロセスには影響しない。 -.SS sys_clone -\fBsys_clone\fP システムコールは、より \fBfork\fP(2) に近いかたちになっており、子プロセスの実行が呼び出しが行われた場所から -続けられる。 そのため、 \fBsys_clone\fP が必要とする引き数は \fIflags\fP と \fIchild_stack\fP だけであり、それらは -\fBclone\fP() と同じ意味を持つ (これらの引き数の順番は \fBclone\fP() とは異なることに注意せよ)。 +.SS 素のシステムコールのインターフェース +素の \fBclone\fP システムコールは、より \fBfork\fP(2) に近いかたちになっており、 +子プロセスの実行が呼び出しが行われた場所から続けられる。 そのため、 \fBclone\fP() ラッパー関数の引き数 \fIfn\fP と \fIarg\fP +は省略される。 また、 引き数の順序も違っている。 x86 と他の多くのアーキテクチャにおける、 素のシステムコールのインターフェースは、 +おおまかには次のようになっている。 +.in +4 +.nf -\fBsys_clone\fP のもう一つの違いは、 \fIchild_stack\fP 引き数がゼロでも良いことである。この場合には、どちらかのプロセスが +\fBlong clone(unsigned long \fP\fIflags\fP\fB, void *\fP\fIchild_stack\fP\fB,\fP +\fB void *\fP\fIptid\fP\fB, void *\fP\fIctid\fP\fB,\fP +\fB struct pt_regs *\fP\fIregs\fP\fB);\fP + +.fi +.in +生のシステムコールのもう一つの違いは、 \fIchild_stack\fP 引き数がゼロでも良いことである。この場合には、どちらかのプロセスが スタックを変更した時に、書き込み時コピー (copy\-on\-write) 方式により -子プロセスがスタック・ページの独立したコピーを得られることが保証される。 この場合、正常に動作させるためには、 \fBCLONE_VM\fP +子プロセスがスタックページの独立したコピーを得られることが保証される。 この場合、正常に動作させるためには、 \fBCLONE_VM\fP オプションを指定してはならない。 +いくつかのアーキテクチャでは、システムコールの引き数の順序は上記とは異なっている。 microblaze, ARM, ARM 64, PA\-RISC, +arc, Power PC, xtensa, MIPS アーキテクチャでは、 4 番目と 5 番目の引き数の順番が逆である。 cris と s390 +アーキテクチャでは、最初と 2 番目の引き数の順番が逆である。 +.SS "blackfin, m68k, sparc" +blackfin, m68k, sparc では引き数渡しの規約が上記の説明とは異なる。 詳細は、カーネル (と glibc) のソースを参照のこと。 +.SS ia64 +ia64 では、別のインターフェースが使用される: +.nf + +\fBint __clone2(int (*\fP\fIfn\fP\fB)(void *), \fP +\fB void *\fP\fIchild_stack_base\fP\fB, size_t \fP\fIstack_size\fP\fB,\fP +\fB int \fP\fIflags\fP\fB, void *\fP\fIarg\fP\fB, ... \fP +\fB /* pid_t *\fP\fIptid\fP\fB, struct user_desc *\fP\fItls\fP\fB, pid_t *\fP\fIctid\fP\fB */ );\fP +.fi +.PP +上記のプロトタイプは glibc ラッパー関数用のものである。 素のシステムコールのインターフェースには引き数 \fIfn\fP と \fIarg\fP がない。 +また、引き数の順序が変わり、 \fIflags\fP が最初の引き数で、 \fItls\fP が最後の引き数である。 +.PP +\fB__clone2\fP() は \fBclone\fP() と同じように動作するが、以下の点が異なる: \fIchild_stack_base\fP +は子プロセスのスタックエリアの最小のアドレスを指し、 \fIstack_size\fP は \fIchild_stack_base\fP +が指し示すスタックエリアの大きさを示す。 +.SS "Linux 2.4 以前" Linux 2.4 以前では、 \fBclone\fP() は引き数 \fIptid\fP, \fItls\fP, \fIctid\fP を取らない。 .SH 返り値 .\" gettid(2) returns current->pid; @@ -435,7 +519,7 @@ PID が 0 以外のプロセスによって \fBCLONE_PID\fP が指定された .SH バージョン libc5 には \fBclone\fP() はない。glibc2 では \fBclone\fP() が提供されており、このマニュアルページに記載の通りである。 .SH 準拠 -\fBclone\fP() と \fBsys_clone\fP コールは Linux 特有であり、移植を考慮したプログラムでは使用すべき ではない。 +\fBclone\fP() は Linux 特有であり、移植を考慮したプログラムでは使用すべき ではない。 .SH 注意 カーネル 2.4.x 系列では、一般的には \fBCLONE_THREAD\fP フラグを指定しても新しいスレッドの親を 呼び出し元プロセスの親と同じにはしない。 しかし、バージョン 2.4.7〜2.4.18 のカーネルでは、 (カーネル 2.6 と同じように) @@ -446,28 +530,15 @@ CLONE_THREAD フラグを指定すると、 暗黙のうちに CLONE_PARENT フ CLONE_THREAD と一緒に指定する必要はなくなった。 このフラグはまだ定義されているが、何の効果もない。 i386 上では、 \fBclone\fP() は vsyscall 経由ではなく、直接 \fIint $0x80\fP 経由で呼び出すべきである。 - -ia64 では、別のシステムコールが使用される: -.nf - -\fBint __clone2(int (*\fP\fIfn\fP\fB)(void *), \fP -\fB void *\fP\fIchild_stack_base\fP\fB, size_t \fP\fIstack_size\fP\fB,\fP -\fB int \fP\fIflags\fP\fB, void *\fP\fIarg\fP\fB, ... \fP -\fB /* pid_t *\fP\fIptid\fP\fB, struct user_desc *\fP\fItls\fP\fB, pid_t *\fP\fIctid\fP\fB */ );\fP -.fi -.PP -\fB__clone2\fP() システムコールは \fBclone\fP() と同じように動作するが、以下の点が異なる: -\fIchild_stack_base\fP は子プロセスのスタックエリアの最小のアドレスを指し、 \fIstack_size\fP は -\fIchild_stack_base\fP が指し示すスタックエリアの大きさを示す。 .SH バグ -NPTL スレッド・ライブラリを含んでいる GNU C ライブラリのいくつかのバージョン には、 \fBgetpid\fP(2) +NPTL スレッドライブラリを含んでいる GNU C ライブラリのいくつかのバージョン には、 \fBgetpid\fP(2) のラッパー関数が含まれており、このラッパー関数は PID をキャッシュする。 このキャッシュ処理が正しく動作するためには glibc の \fBclone\fP() のラッパー関数での助けが必要だが、現状の実装では、 ある状況下においてキャッシュが最新とならない可能性がある。 特に、 \fBclone\fP() の呼び出し直後にシグナルが子プロセスに配送された場合に、 そのシグナルに対するハンドラ内で \fBgetpid\fP(2) を呼び出すと、それまでに clone のラッパー関数が子プロセスの PID キャッシュを 更新する機会が得られていなければ、呼び出し元プロセス ("親プロセス") の PID が 返される可能性がある。 (この議論では、子プロセスが \fBCLONE_THREAD\fP を使って作成された場合のことは無視している。 子プロセスが \fBCLONE_THREAD\fP を作って作成された場合には、 -呼び出し元と子プロセスは同じスレッド・グループに属すので、 \fBgetpid\fP(2) は子プロセスと \fBclone\fP() +呼び出し元と子プロセスは同じスレッドグループに属すので、 \fBgetpid\fP(2) は子プロセスと \fBclone\fP() を呼び出したプロセスで同じ値を返すのが「正しい」。 キャッシュが最新とならない問題 (stale\-cache problem) は、 \fIflags\fP に \fBCLONE_VM\fP が含まれている場合にも発生しない。) 本当の値を得るためには、次のようなコードを使う必要があるかもしれない。 .nf @@ -481,11 +552,102 @@ NPTL スレッド・ライブラリを含んでいる GNU C ライブラリの .\" See also the following bug reports .\" https://bugzilla.redhat.com/show_bug.cgi?id=417521 .\" http://sourceware.org/bugzilla/show_bug.cgi?id=6910 +.SH 例 +以下のプログラムは、 別の UTS 名前空間で動作する子プロセスを \fBclone\fP() を使って作成する例である。 子プロセスは、自分の UTS +名前空間においてホスト名を変更する。 それから、親プロセスと子プロセスの両方でシステムのホスト名を表示し、 親プロセスと子プロセスの UTS +名前空間でホスト名が異なることを確認する。 このプログラムの使用方法については \fBsetns\fP(2) を参照。 +.SS プログラムのソース +.nf +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include + +#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \e + } while (0) + +static int /* clone された子プロセスの開始関数 */ +childFunc(void *arg) +{ + struct utsname uts; + + /* 子プロセスの UTS 名前空間でホスト名を変更する */ + + if (sethostname(arg, strlen(arg)) == \-1) + errExit("sethostname"); + + /* ホスト名を取得し表示する */ + + if (uname(&uts) == \-1) + errExit("uname"); + printf("uts.nodename in child: %s\en", uts.nodename); + + /* sleep を使ってしばらく名前空間をオープンされたままにする。 + これにより実験を行うことができる \-\- 例えば、 + 別のプロセスがこの名前空間に参加するなど。 */ + + sleep(200); + + return 0; /* 子プロセスを終了する */ +} + +#define STACK_SIZE (1024 * 1024) /* clone される子プロセスのスタックサイズ */ + +int +main(int argc, char *argv[]) +{ + char *stack; /* スタックバッファの先頭 */ + char *stackTop; /* スタックバッファの末尾 */ + pid_t pid; + struct utsname uts; + + if (argc < 2) { + fprintf(stderr, "Usage: %s \en", argv[0]); + exit(EXIT_SUCCESS); + } + + /* 子プロセス用のスタックを割り当てる */ + + stack = malloc(STACK_SIZE); + if (stack == NULL) + errExit("malloc"); + stackTop = stack + STACK_SIZE; /* スタックは下方向に伸びるものとする */ + + /* 自分専用の UTS 名前空間を持つ子プロセスを作成する; + 子プロセスは childFunc() の実行を開始する */ + + pid = clone(childFunc, stackTop, CLONE_NEWUTS | SIGCHLD, argv[1]); + if (pid == \-1) + errExit("clone"); + printf("clone() returned %ld\en", (long) pid); + + /* 親プロセスの実行はここに来る */ + + sleep(1); /* 子プロセスがホスト名を変更する時間を与える */ + + /* 親プロセスの UTS 名前空間でのホスト名を表示する; + これは子プロセスの UTS 名前空間でのホスト名とは異なる */ + + if (uname(&uts) == \-1) + errExit("uname"); + printf("uts.nodename in parent: %s\en", uts.nodename); + + if (waitpid(pid, NULL, 0) == \-1) /* 子プロセスを待つ */ + errExit("waitpid"); + printf("child has terminated\en"); + + exit(EXIT_SUCCESS); +} +.fi .SH 関連項目 -\fBfork\fP(2), \fBfutex\fP(2), \fBgetpid\fP(2), \fBgettid\fP(2), \fBset_thread_area\fP(2), -\fBset_tid_address\fP(2), \fBtkill\fP(2), \fBunshare\fP(2), \fBwait\fP(2), -\fBcapabilities\fP(7), \fBpthreads\fP(7) +\fBfork\fP(2), \fBfutex\fP(2), \fBgetpid\fP(2), \fBgettid\fP(2), \fBkcmp\fP(2), +\fBset_thread_area\fP(2), \fBset_tid_address\fP(2), \fBsetns\fP(2), \fBtkill\fP(2), +\fBunshare\fP(2), \fBwait\fP(2), \fBcapabilities\fP(7), \fBpthreads\fP(7) .SH この文書について -この man ページは Linux \fIman\-pages\fP プロジェクトのリリース 3.40 の一部 +この man ページは Linux \fIman\-pages\fP プロジェクトのリリース 3.67 の一部 である。プロジェクトの説明とバグ報告に関する情報は http://www.kernel.org/doc/man\-pages/ に書かれている。