名 前
clone, __clone2 − 子 プ ロ セ ス を 作 成 す る
書 式
/* glibc ラ ッ パ ー 関 数 の プ ロ ト タ イ プ */
#include <sched.h>
int
clone(int (*fn)(void *), void
*child_stack,
int flags, void *arg, ...
/* pid_t *ptid, struct user_desc
*tls, pid_t *ctid */ );
/* 素 の シ ス テ ム コ ー ル の プ ロ ト タ イ プ */
long
clone(unsigned long flags, void
*child_stack,
void *ptid, void *ctid,
struct pt_regs *regs);
glibc ラ ッ パ ー 関 数 の 機 能 検 査 マ ク ロ の 要 件 (feature_test_macros(7) 参 照 ):
clone():
glibc 2.14 以 降 :
_GNU_SOURCE
glibc 2.14 よ り 前 :
_BSD_SOURCE || _SVID_SOURCE
/* _GNU_SOURCE も 定 義 さ れ
る */
説 明
clone() は 、 fork(2) と 似 た 方 法 で 新 し い プ ロ セ ス を 作 成 す る 。 こ の ペ ー ジ で は 、 glibc の clone() ラ ッ パ ー 関 数 と そ の 裏 で 呼 ば れ る シ ス テ ム コ ー ル の 両 方 に つ い て 説 明 し て い る 。 メ イ ン の 説 明 は ラ ッ パ ー 関 数 に 関 す る も の で あ る 。 素 の シ ス テ ム コ ー ル に お け る 差 分 は こ の ペ ー ジ の 最 後 の 方 で 説 明 す る 。
fork(2) と は 異 な り 、 clone() で は 、 子 プ ロ セ ス (child process) と 呼 び 出 し 元 の プ ロ セ ス と が 、 メ モ リ ー 空 間 、 フ ァ イ ル デ ィ ス ク リ プ タ ー の テ ー ブ ル 、 シ グ ナ ル ハ ン ド ラ ー の テ ー ブ ル な ど の 実 行 コ ン テ キ ス ト の 一 部 を 共 有 で き る 。 (こ の マ ニ ュ ア ル に お け る 「 呼 び 出 し 元 の プ ロ セ ス 」 は 、 通 常 は 「 親 プ ロ セ ス 」 と 一 致 す る 。 但 し 、 後 述 の CLONE_PARENT の 項 も 参 照 の こ と )
clone() の 主 要 な 使 用 法 は ス レ ッ ド (threads) を 実 装 す る こ と で あ る : 一 つ の プ ロ グ ラ ム の 中 の 複 数 の ス レ ッ ド は 共 有 さ れ た メ モ リ ー 空 間 で 同 時 に 実 行 さ れ る 。
clone() で 子 プ ロ セ ス が 作 成 さ れ た 時 に 、 作 成 さ れ た 子 プ ロ セ ス は 関 数 fn(arg) を 実 行 す る 。 (こ の 点 が fork(2) と は 異 な る 。 fork(2) の 場 合 、 子 プ ロ セ ス は fork(2) が 呼 び 出 さ れ た 場 所 か ら 実 行 を 続 け る 。 ) fn 引 き 数 は 、 子 プ ロ セ ス が 実 行 を 始 め る 時 に 子 プ ロ セ ス が 呼 び 出 す 関 数 へ の ポ イ ン タ ー で あ る 。 arg 引 き 数 は そ の ま ま fn 関 数 へ と 渡 さ れ る 。
fn(arg) 関 数 が 終 了 す る と 、 子 プ ロ セ ス は 終 了 す る 。 fn に よ っ て 返 さ れ た 整 数 が 子 プ ロ セ ス の 終 了 コ ー ド と な る 。 子 プ ロ セ ス は 、 exit(2) を 呼 ん で 明 示 的 に 終 了 す る こ と も あ る し 、 致 命 的 な シ グ ナ ル を 受 信 し た 場 合 に 終 了 す る こ と も あ る 。
child_stack 引 き 数 は 、 子 プ ロ セ ス に よ っ て 使 用 さ れ る ス タ ッ ク の 位 置 を 指 定 す る 。 子 プ ロ セ ス と 呼 び 出 し 元 の プ ロ セ ス は メ モ リ ー を 共 有 す る こ と が あ る た め 、 子 プ ロ セ ス は 呼 び 出 し 元 の プ ロ セ ス と 同 じ ス タ ッ ク で 実 行 す る こ と が で き な い 。 こ の た め 、 呼 び 出 し 元 の プ ロ セ ス は 子 プ ロ セ ス の ス タ ッ ク の た め の メ モ リ ー 空 間 を 用 意 し て 、 こ の 空 間 へ の ポ イ ン タ ー を clone() へ 渡 さ な け れ ば な ら な い 。 (HP PA プ ロ セ ッ サ 以 外 の ) Linux が 動 作 す る 全 て の プ ロ セ ッ サ で は 、 ス タ ッ ク は 下 方 (ア ド レ ス が 小 さ い 方 向 ) へ と 伸 び る 。 こ の た め 、 普 通 は child_stack は 子 プ ロ セ ス の ス タ ッ ク の た め に 用 意 し た メ モ リ ー 空 間 の 一 番 大 き い ア ド レ ス を 指 す よ う に す る 。
flags の 下 位 1 バ イ ト は 子 プ ロ セ ス が 死 ん だ 場 合 に 親 プ ロ セ ス へ と 送 ら れ る 終 了 シ グ ナ ル (termination signal) の 番 号 を 指 定 す る 。 こ の シ グ ナ ル と し て SIGCHLD 以 外 が 指 定 さ れ た 場 合 、 親 プ ロ セ ス は 、 wait(2) で 子 プ ロ セ ス を 待 つ 際 に 、 オ プ シ ョ ン と し て __WALL ま た は __WCLONE を 指 定 し な け れ ば な ら な い 。 ど の シ グ ナ ル も 指 定 さ れ な か っ た 場 合 、 子 プ ロ セ ス が 終 了 し た 時 に 親 プ ロ セ ス に シ グ ナ ル は 送 ら れ な い 。
flags
に は 、 以 下 の
定 数 の う ち 0個
以 上 を ビ ッ ト
毎 の 論 理 和
(bitwise−or) を と っ た
も の を 指 定 で
き る 。 こ れ ら
の 定 数 は 呼 び
出 し 元 の プ ロ
セ ス と 子 プ ロ
セ ス の 間 で 何
を 共 有 す る か
を 指 定 す る :
CLONE_CHILD_CLEARTID (Linux 2.5.49 以 降 )
子 プ ロ セ ス が
終 了 し た と き
に 子 プ ロ セ ス
の メ モ リ ー 内
の ctid が 指 す 場
所 に あ る 子 プ
ロ セ ス の ス レ
ッ ド ID を 消 去 し
、 そ の ア ド レ
ス で futex を wake (起 床 )
さ せ る 。 こ の
ア ド レ ス は
set_tid_address(2) シ ス テ
ム コ ー ル で 変
更 す る こ と が
で き る 。 こ の
機 能 は ス レ ッ
ド ラ イ ブ ラ リ
で 使 用 さ れ る
。
CLONE_CHILD_SETTID (Linux 2.5.49 以 降 )
子 プ ロ セ ス の
メ モ リ ー 内 の
ctid が 指 す 場 所
に 子 プ ロ セ ス
の ス レ ッ ド ID を
格 納 す る 。
CLONE_FILES (Linux 2.0 以 降 )
CLONE_FILES が 設 定 さ れ た 場 合 、 呼 び 出 し 元 の プ ロ セ ス と 子 プ ロ セ ス は フ ァ イ ル デ ィ ス ク リ プ タ ー の テ ー ブ ル を 共 有 す る 。 呼 び 出 し 元 プ ロ セ ス と そ の 子 プ ロ セ ス の 一 方 が 作 成 し た フ ァ イ ル デ ィ ス ク リ プ タ ー は 、 も う 一 方 に お い て も 有 効 で あ る 。 同 じ よ う に 、 一 方 の プ ロ セ ス が フ ァ イ ル デ ィ ス ク リ プ タ ー を 閉 じ た り 、 (fcntl(2) F_SETFD 操 作 を 使 っ て ) デ ィ ス ク リ プ タ ー に 関 連 す る フ ラ グ を 変 更 し た り す る と 、 も う 一 方 の プ ロ セ ス に も 影 響 す る 。
CLONE_FILES が 設 定 さ れ て い な い 場 合 、 子 プ ロ セ ス は 、 clone() が 実 行 さ れ た 時 点 で 、 呼 び 出 し 元 の プ ロ セ ス が オ ー プ ン し て い る 全 て の フ ァ イ ル デ ィ ス ク リ プ タ ー の コ ピ ー を 継 承 す る (子 プ ロ セ ス の 複 製 さ れ た フ ァ イ ル デ ィ ス ク リ プ タ ー は 、 対 応 す る 呼 び 出 し 元 の プ ロ セ ス の フ ァ イ ル デ ィ ス ク リ プ タ ー と 同 じ フ ァ イ ル 記 述 (open(2) 参 照 ) を 参 照 す る )。 こ れ 以 降 に 、 呼 び 出 し 元 の プ ロ セ ス と 子 プ ロ セ ス の 一 方 が フ ァ イ ル デ ィ ス ク リ プ タ ー の 操 作 (フ ァ イ ル デ ィ ス ク リ プ タ ー の オ ー プ ン ・ ク ロ ー ズ や 、 フ ァ イ ル デ ィ ス ク リ プ タ ー フ ラ グ の 変 更 ) を 行 っ て も 、 も う 一 方 の プ ロ セ ス に は 影 響 を 与 え な い 。
CLONE_FS (Linux 2.0 以 降 )
CLONE_FS が 設 定 さ れ た 場 合 、 呼 び 出 し 元 の プ ロ セ ス と 子 プ ロ セ ス が 同 じ フ ァ イ ル シ ス テ ム 情 報 を 共 有 す る 。 フ ァ イ ル シ ス テ ム 情 報 は 、 フ ァ イ ル シ ス テ ム の ル ー ト (root)、 カ レ ン ト ワ ー キ ン グ デ ィ レ ク ト リ (current working directory) や umask な ど で あ る 。 呼 び 出 し 元 の プ ロ セ ス や 子 プ ロ セ ス の ど ち ら か 一 方 に よ っ て chroot(2), chdir(2), umask(2) が 呼 び 出 さ れ る と 、 も う 一 方 の プ ロ セ ス に も 影 響 が 及 ぶ 。
CLONE_FS が 設 定 さ れ て い な い 場 合 、 子 プ ロ セ ス は 、 clone() が 実 行 さ れ た 時 点 で の 、 呼 び 出 し 元 の プ ロ セ ス の フ ァ イ ル シ ス テ ム 情 報 の コ ピ ー を 使 用 す る 。 こ れ 以 降 は 、 呼 び 出 し 元 の プ ロ セ ス と 子 プ ロ セ ス の 一 方 が chroot(2), chdir(2), umask(2) を 呼 び 出 し て も 、 も う 一 方 の プ ロ セ ス に は 影 響 を 与 え な い 。
CLONE_IO (Linux 2.6.25 以 降 )
CLONE_IO が 設 定 さ れ た 場 合 、 新 し い プ ロ セ ス は 呼 び 出 し 元 の プ ロ セ ス と I/O コ ン テ キ ス ト を 共 有 す る 。 こ の フ ラ グ が 設 定 さ れ て い な い 場 合 に は 、 (fork(2) の 場 合 と 同 様 ) 新 し い プ ロ セ ス は 自 分 専 用 の I/O コ ン テ キ ス ト を 持 つ 。
I/O コ ン テ キ ス ト は 、 デ ィ ス ク ス ケ ジ ュ ー ル の I/O ス コ ー プ で あ る (言 い 換 え る と 、 I/O コ ン テ キ ス ト は I/O ス ケ ジ ュ ー ラ が プ ロ セ ス I/O の ス ケ ジ ュ ー リ ン グ を モ デ ル 化 す る の に 使 用 さ れ る )。 複 数 の プ ロ セ ス が 同 じ I/O コ ン テ キ ス ト を 共 有 す る 場 合 、 こ れ ら の プ ロ セ ス は I/O ス ケ ジ ュ ー ラ か ら は 一 つ と し て 扱 わ れ る 。 結 果 と し て 、 こ れ ら の プ ロ セ ス は デ ィ ス ク ア ク セ ス の 時 間 を 共 有 す る よ う に な る 。 い く つ か の I/O ス ケ ジ ュ ー ラ で は 、 二 つ の プ ロ セ ス が I/O コ ン テ キ ス ト を 共 有 し て い る 場 合 、 こ れ ら の プ ロ セ ス は デ ィ ス ク ア ク セ ス を 交 互 に 行 う こ と が で き る 。 同 じ プ ロ セ ス の 複 数 の ス レ ッ ド が I/O を 実 行 し て い る 場 合 (例 え ば aio_read(3))、 CLONE_IO を 利 用 す る こ と で I/O 性 能 を 良 く す る こ と が で き る 。 カ ー ネ ル の 設 定 が CONFIG_BLOCK オ プ シ ョ ン 付 き で な い 場 合 、 こ の フ ラ グ は 何 の 意 味 も 持 た な い 。
CLONE_NEWIPC (Linux 2.6.19 以 降 )
CLONE_NEWIPC が 設 定 さ れ た 場 合 、 新 し い IPC 名 前 空 間 (namespace) で プ ロ セ ス を 作 成 す る 。 こ の フ ラ グ が 設 定 さ れ て い な い 場 合 、 (fork(2) の 場 合 と 同 様 ) 呼 び 出 し 元 の プ ロ セ ス と 同 じ IPC 名 前 空 間 で プ ロ セ ス が 作 成 さ れ る 。 こ の フ ラ グ は 、 コ ン テ ナ の 実 装 で の 使 用 を 意 図 し て 用 意 さ れ た も の で あ る 。
IPC 名 前 空 間 は 、 独 立 の System V IPC オ ブ ジ ェ ク ト 空 間 (svipc(7) 参 照 ) を 提 供 す る 。 (Linux 2.6.30 以 降 で は ) 独 立 し た POSIX メ ッ セ ー ジ キ ュ ー 空 間 (mq_overview(7) 参 照 ) も 提 供 さ れ る 。 こ れ ら の IPC 機 構 に 共 通 の 特 徴 と し て 、 IPC オ ブ ジ ェ ク ト は フ ァ イ ル シ ス テ ム の パ ス 名 と は 違 っ た 仕 組 み で 識 別 さ れ る と い う 点 が あ る 。 あ る IPC 名 前 空 間 に 作 成 さ れ た オ ブ ジ ェ ク ト は 、 そ の 名 前 空 間 の メ ン バ ー で あ る 他 の す べ て の プ ロ セ ス か ら も 見 え る が 、 違 う IPC 名 前 空 間 の プ ロ セ ス か ら は 見 え な い 。
IPC 名 前 空 間 が 破 棄 さ れ る 時 (す な わ ち 、 そ の 名 前 空 間 の メ ン バ ー の 最 後 の プ ロ セ ス が 終 了 す る 時 )、 そ の 名 前 空 間 の 全 て の IPC オ ブ ジ ェ ク ト は 自 動 的 に 破 棄 さ れ る 。 特 権 プ ロ セ ス (CAP_SYS_ADMIN) だ け が CLONE_NEWIPC を 使 用 で き る 。 こ の フ ラ グ は CLONE_SYSVSEM と 組 み 合 わ せ て 指 定 す る こ と は で き な い 。
IPC 名 前 空 間 の 詳 細 は namespaces(7) を 参 照 。
CLONE_NEWNET (Linux 2.6.24 以 降 )
(こ の フ ラ グ の 実 装 は 、 Linux 2.6.29 あ た り ま で に は 完 成 し た 。 )
CLONE_NEWNET が 設 定 さ れ た 場 合 、 新 し い ネ ッ ト ワ ー ク 名 前 空 間 (network namaspace) で プ ロ セ ス を 作 成 す る 。 こ の フ ラ グ が 設 定 さ れ て い な い 場 合 、 (fork(2) の 場 合 と 同 様 ) 呼 び 出 し 元 の プ ロ セ ス と 同 じ ネ ッ ト ワ ー ク 名 前 空 間 で プ ロ セ ス が 作 成 さ れ る 。 こ の フ ラ グ は 、 コ ン テ ナ の 実 装 で の 使 用 を 意 図 し て 用 意 さ れ た も の で あ る 。 ネ ッ ト ワ ー ク 名 前 空 間 は 、 分 離 さ れ た ネ ッ ト ワ ー ク ス タ ッ ク を 提 供 す る も の で あ る (ネ ッ ト ワ ー ク ス タ ッ ク と は 、 ネ ッ ト ワ ー ク デ バ イ ス イ ン タ ー フ ェ ー ス 、 IPv4 や IPv6 プ ロ ト コ ル ス タ ッ ク 、 /proc/net、 /sys/class/net デ ィ レ ク ト リ ツ リ ー 、 ソ ケ ッ ト な ど で あ る )。 物 理 ネ ッ ト ワ ー ク デ バ イ ス が 所 属 で き る ネ ッ ト ワ ー ク 名 前 空 間 は 一 つ だ け で あ る 。 仮 想 ネ ッ ト ワ ー ク デ バ イ ス ("veth") の ペ ア に よ り パ イ プ 風 の 抽 象 化 (abstraction) が 実 現 さ れ て お り 、 こ れ を 使 う こ と で 、 ネ ッ ト ワ ー ク 名 前 空 間 間 の ト ン ネ ル を 作 成 し た り 、 別 の 名 前 空 間 の 物 理 ネ ッ ト ワ ー ク デ バ イ ス へ の ブ リ ッ ジ を 作 成 し た り す る こ と が で き る 。 ネ ッ ト ワ ー ク 名 前 空 間 が 解 放 さ れ る 時 (す な わ ち 、 そ の 名 前 空 間 の 最 後 の プ ロ セ ス が 終 了 す る 時 )、 物 理 ネ ッ ト ワ ー ク デ バ イ ス は 初 期 ネ ッ ト ワ ー ク 名 前 空 間 (initial network namespace) に 戻 さ れ る (親 プ ロ セ ス の ネ ッ ト ワ ー ク 名 前 空 間 に 戻 さ れ る 訳 で は な い )。 ネ ッ ト ワ ー ク 名 前 空 間 の さ ら な る 情 報 は namespaces(7) を 参 照 。 特 権 プ ロ セ ス (CAP_SYS_ADMIN) だ け が CLONE_NEWNET を 使 用 で き る 。
CLONE_NEWNS (Linux 2.4.19 以 降 )
CLONE_NEWNS が セ ッ ト さ れ て い る 場 合 、 clone で 作 成 さ れ た 子 プ ロ セ ス は 新 し い マ ウ ン ト 名 前 空 間 で 開 始 さ れ 、 新 し い 名 前 空 間 は 親 プ ロ セ ス の 名 前 空 間 の コ ピ ー で 初 期 化 さ れ る 。 CLONE_NEWNS が セ ッ ト さ れ て い な い 場 合 、 子 プ ロ セ ス は 親 プ ロ セ ス と 同 じ マ ウ ン ト 名 前 空 間 と な る 。 マ ウ ン ト 名 前 空 間 の 詳 細 は namespaces(7) を 参 照 。 特 権 プ ロ セ ス (CAP_SYS_ADMIN) の み が CLONE_NEWNS を 指 定 す る こ と が で き る 。 一 つ の clone() 呼 び 出 し で 、 CLONE_NEWNS と CLONE_FS の 両 方 を 指 定 す る こ と は で き な い 。
CLONE_NEWPID (Linux 2.6.24 以 降 )
CLONE_NEWPID が 設 定 さ れ た 場 合 、 新 し い PID 名 前 空 間 で プ ロ セ ス を 作 成 す る 。 こ の フ ラ グ が 設 定 さ れ て い な い 場 合 、 (fork(2) の 場 合 と 同 様 ) 呼 び 出 し 元 の プ ロ セ ス と 同 じ PID 名 前 空 間 で プ ロ セ ス が 作 成 さ れ る 。 こ の フ ラ グ は 、 コ ン テ ナ の 実 装 で の 使 用 を 意 図 し て 用 意 さ れ た も の で あ る 。
PID 名 前 空 間 の 詳 細 は namespaces(7) と pid_namespaces(7) を 参 照 。 特 権 プ ロ セ ス (CAP_SYS_ADMIN) だ け が CLONE_NEWPID を 使 用 で き る 。 こ の フ ラ グ は CLONE_THREAD や CLONE_PARENT と 組 み 合 わ せ て 指 定 す る こ と は で き な い 。
CLONE_NEWUSER
(こ の フ ラ グ が clone() で 意 味 を 持 つ よ う に な っ た の は Linux 2.6.23 で あ る 。 現 在 の clone() の 動 作 が 取 り 込 ま れ た の は Linux 3.5 で あ り 、 ユ ー ザ ー 名 前 空 間 が 完 全 に 機 能 す る よ う に す る 最 後 の 機 能 が 取 り 込 ま れ た の は Linux 3.8 で あ る 。 )
CLONE_NEWUSER が セ ッ ト さ れ て い る 場 合 、 新 し い ユ ー ザ ー 名 前 空 間 で プ ロ セ ス を 作 成 す る 。 こ の フ ラ グ が セ ッ ト さ れ て い な い 場 合 、 (fork(2) の 場 合 と 同 様 に ) 呼 び 出 し 元 の プ ロ セ ス と 同 じ ユ ー ザ ー 名 前 空 間 で プ ロ セ ス が 作 成 さ れ る 。 ユ ー ザ ー 名 前 空 間 の 詳 細 は namespaces(7) と user_namespaces(7) を 参 照 。
Linux 3.8 よ り 前 で は 、 CLONE_NEWUSER を 使 用 す る に は 、 呼 び 出 し 元 は CAP_SYS_ADMIN, CAP_SETUID, CAP_SETGID の 3 つ の ケ ー パ リ ビ テ ィ を 持 っ て い る 必 要 が あ っ た 。 Linux 3.8 以 降 で は 、 ユ ー ザ ー 名 前 空 間 を 作 成 す る の に 特 権 は 必 要 な く な っ た 。 こ の フ ラ グ は CLONE_THREAD や CLONE_PARENT と 組 み 合 わ せ て 指 定 す る こ と は で き な い 。 セ キ ュ リ テ ィ 上 の 理 由 か ら 、 CLONE_NEWUSER は CLONE_FS と 組 み 合 わ せ て 指 定 す る こ と は で き な い 。 ユ ー ザ ー 名 前 空 間 の 詳 細 は user_namespaces(7) を 参 照 。
CLONE_NEWUTS (Linux 2.6.19 以 降 )
CLONE_NEWUTS が 設 定 さ れ た 場 合 、 新 し い UTS 名 前 空 間 で プ ロ セ ス を 作 成 す る 。 新 し い UTS 名 前 空 間 の 識 別 子 の 初 期 値 は 、 呼 び 出 し 元 の プ ロ セ ス の UTS 名 前 空 間 の 識 別 子 を 複 製 し た も の と な る 。 こ の フ ラ グ が 設 定 さ れ て い な い 場 合 、 (fork(2) の 場 合 と 同 様 ) 呼 び 出 し 元 の プ ロ セ ス と 同 じ UTS 名 前 空 間 で プ ロ セ ス が 作 成 さ れ る 。 こ の フ ラ グ は 、 コ ン テ ナ の 実 装 で の 使 用 を 意 図 し て 用 意 さ れ た も の で あ る 。
UTS 名 前 空 間 は 、 uname(2) が 返 す 識 別 子 の 集 合 で あ る 。 識 別 子 と し て は ド メ イ ン 名 と ホ ス ト 名 が あ り 、 そ れ ぞ れ setdomainname(2), sethostname(2) で 修 正 す る こ と が で き る 。 あ る UTS 名 前 空 間 に お け る 識 別 子 の 変 更 は 同 じ 名 前 空 間 の 他 の す べ て の プ ロ セ ス に 見 え る が 、 別 の UTS 名 前 空 間 の プ ロ セ ス に は 見 え な い 。 特 権 プ ロ セ ス (CAP_SYS_ADMIN) だ け が CLONE_NEWUTS を 使 用 で き る 。
UTS 名 前 空 間 の 詳 細 は namespaces(7) を 参 照 。
CLONE_PARENT (Linux 2.3.12 以 降 )
CLONE_PARENT が 設 定 さ れ た 場 合 、 新 し い 子 供 の (getppid(2) で 返 さ れ る ) 親 プ ロ セ ス は 呼 び 出 し 元 の プ ロ セ ス の 親 プ ロ セ ス と 同 じ に な る 。
CLONE_PARENT が 設 定 さ れ て い な い 場 合 、 (fork(2) と 同 様 に ) 呼 び 出 し 元 の プ ロ セ ス が そ の 子 供 の 親 に な る 。 子 供 が 終 了 し た 時 に シ グ ナ ル が 送 ら れ る の は getppid(2) が 返 す 親 プ ロ セ ス で あ る 点 に 注 意 す る こ と 。 こ の た め CLONE_PARENT が 設 定 さ れ た 場 合 、 呼 び 出 し 元 の プ ロ セ ス で は な く 呼 び 出 し 元 の プ ロ セ ス の 親 プ ロ セ ス に シ グ ナ ル が 送 ら れ る 。
CLONE_PARENT_SETTID
(Linux 2.5.49 以 降 ) 親 プ ロ
セ ス と 子 プ ロ
セ ス の メ モ リ
ー 内 の ptid が 指
す 領 域 に 子 プ
ロ セ ス の ス レ
ッ ド ID を 格 納 す
る 。 (Linux 2.5.32−2.5.48 で
は 、 同 じ こ と
を す る CLONE_SETTID と
い う フ ラ グ が
存 在 し た 。 )
CLONE_PID (廃 止 予 定 )
CLONE_PID が 設 定 さ れ た 場 合 、 子 プ ロ セ ス は 呼 び 出 し 元 の プ ロ セ ス と 同 じ プ ロ セ ス ID で 作 成 さ れ る 。 こ れ は シ ス テ ム を ハ ッ キ ン グ す る の に は 便 利 だ が 、 そ れ 以 外 に は あ ま り 使 わ れ な い 。 Linux 2.3.21 以 降 で は 、 シ ス テ ム の ブ ー ト プ ロ セ ス (PID 0) だ け が こ の フ ラ グ を 指 定 で き る 。 Linux 2.5.16 で 削 除 さ れ た 。
CLONE_PTRACE (Linux 2.2 以 降 )
CLONE_PTRACE が 指 定 さ れ 、 か つ 呼 び 出 し 元 の プ ロ セ ス が 追 跡 (trace) さ れ て い た 場 合 、 子 プ ロ セ ス も 同 様 に 追 跡 さ れ る 。 (ptrace(2) を 参 照 の こ と )
CLONE_SETTLS (Linux 2.5.32 以 降 )
newtls 引 き 数 は 、 新 し い TLS (Thread Local Storage) デ ィ ス ク リ プ タ ー で あ る 。 (set_thread_area(2) を 参 照 の こ と )
CLONE_SIGHAND (Linux 2.0 以 降 )
CLONE_SIGHAND が 設 定 さ れ た 場 合 、 呼 び 出 し 元 の プ ロ セ ス と 子 プ ロ セ ス は 同 じ シ グ ナ ル ハ ン ド ラ の テ ー ブ ル を 共 有 す る 。 呼 び 出 し 元 の プ ロ セ ス ま た は 子 プ ロ セ ス の ど ち ら か が sigaction(2) を 呼 び 出 し て シ グ ナ ル に 対 応 す る 動 作 を 変 更 し た 場 合 、 も う 一 方 の プ ロ セ ス の シ グ ナ ル 動 作 も 変 更 さ れ る 。 但 し 、 呼 び 出 し 元 の プ ロ セ ス と 子 プ ロ セ ス は 、 プ ロ セ ス 毎 に 、 シ グ ナ ル マ ス ク (signal mask) と 処 理 待 ち シ グ ナ ル の 集 合 を 持 っ て い る 。 こ の た め 、 あ る プ ロ セ ス は 、 sigprocmask(2) を 使 用 し て 、 も う 一 方 の プ ロ セ ス に 影 響 を 与 え ず に シ グ ナ ル を 禁 止 (block) し た り 許 可 (unblock) し た り で き る 。
CLONE_SIGHAND が 設 定 さ れ て い な い 場 合 、 子 プ ロ セ ス は clone() が 実 行 さ れ た 時 点 で の 、 呼 び 出 し 元 の プ ロ セ ス の シ グ ナ ル ハ ン ド ラ ー の コ ピ ー を 継 承 す る 。 こ れ 以 降 は 、 一 方 の プ ロ セ ス が sigaction(2) を 呼 び 出 し て も 、 も う 一 方 の プ ロ セ ス に は 影 響 を 与 え な い 。
Linux 2.6.0−test6 以 降 で は 、 CLONE_SIGHAND を 指 定 す る 場 合 、 CLONE_VM も flags に 含 め な け れ ば な ら な い 。
CLONE_STOPPED (Linux 2.6.0−test2 以 降 )
CLONE_STOPPED が 設 定 さ れ る と 、 子 プ ロ セ ス は 最 初 (SIGSTOP シ グ ナ ル を 送 ら れ た か の よ う に ) 停 止 し た 状 態 と な る 。 子 プ ロ セ ス を 再 開 さ せ る に は SIGCONT シ グ ナ ル を 送 信 し な け れ ば な ら な い 。 こ の フ ラ グ は Linux 2.6.25 以 降 で は 非 推 奨 で あ り 、 Linux 2.6.38 で 完 全 に 削 除 さ れ た 。
CLONE_SYSVSEM (Linux 2.5.10 以 降 )
CLONE_SYSVSEM が セ ッ ト さ れ る と 、 子 プ ロ セ ス と 呼 び 出 し 元 プ ロ セ ス は 一 つ の System V セ マ フ ォ の 調 整 値 (semadj) (semop(2) 参 照 ) を 共 有 す る 。 こ の 場 合 、 共 有 さ れ た リ ス ト は こ の リ ス ト を 共 有 す る 全 プ ロ セ ス の semadj 値 を 積 算 し 、 セ マ フ ォ 調 整 は こ の リ ス ト を 共 有 し て い る 最 後 の プ ロ セ ス が 終 了 し た 際 (ま た は unshare(2) を 使 っ て リ ス ト の 共 有 が 中 止 さ れ た 際 ) に 実 行 さ れ る 。 こ の フ ラ グ が セ ッ ト さ れ て い な け れ ば 、 子 プ ロ セ ス は 独 自 の セ マ フ ォ semadj リ ス ト を 持 つ (リ ス ト の 初 期 値 は 空 で あ る )。
CLONE_THREAD (Linux 2.4.0−test8以 降 )
CLONE_THREAD が 設 定 さ れ た 場 合 、 子 プ ロ セ ス は 呼 び 出 し 元 の プ ロ セ ス と 同 じ ス レ ッ ド グ ル ー プ に 置 か れ る 。 CLONE_THREAD に つ い て の 以 降 の 議 論 を 読 み や す く す る た め 、 「 ス レ ッ ド 」 と い う 用 語 は ス レ ッ ド グ ル ー プ の 中 の プ ロ セ ス を 参 照 す る の に 使 う こ と と す る 。 ス レ ッ ド グ ル ー プ は 、 ス レ ッ ド 集 合 で 一 つ の PID を 共 有 す る と い う POSIX ス レ ッ ド の 概 念 を サ ポ ー ト す る た め に Linux 2.4 に 加 え ら れ た 機 能 で あ っ た 。 内 部 的 に は 、 こ の 共 有 PID は い わ ゆ る そ の ス レ ッ ド グ ル ー プ の ス レ ッ ド グ ル ー プ 識 別 子 (TGID) で あ る 。 Linux 2.4 以 降 で は 、 getpid(2) の 呼 び 出 し で は そ の プ ロ セ ス の ス レ ッ ド グ ル ー プ ID を 返 す 。 あ る グ ル ー プ に 属 す る ス レ ッ ド は (シ ス テ ム 全 体 で ) 一 意 な ス レ ッ ド ID (TID) で 区 別 で き る 。 新 し い ス レ ッ ド の TID は clone() の 呼 び 出 し 元 へ 関 数 の 結 果 と し て 返 さ れ 、 ス レ ッ ド は 自 分 自 身 の TID を gettid(2) で 取 得 で き る 。
CLONE_THREAD を 指 定 せ ず に clone() の 呼 び 出 し が 行 わ れ る と 、 生 成 さ れ た ス レ ッ ド は そ の ス レ ッ ド の TID と 同 じ 値 の TGID を 持 つ 新 し い ス レ ッ ド グ ル ー プ に 置 か れ る 。 こ の ス レ ッ ド は 新 し い ス レ ッ ド グ ル ー プ の 「 リ ー ダ ー 」 で あ る 。
CLONE_THREAD を 指 定 し て 作 成 さ れ た 新 し い ス レ ッ ド は 、 (CLONE_PARENT の 場 合 と 同 様 に ) clone() を 呼 び 出 し 元 と 同 じ 親 プ ロ セ ス を 持 つ 。 そ の た め 、 getppid(2) を 呼 ぶ と 、 一 つ の ス レ ッ ド グ ル ー プ に 属 す ス レ ッ ド は 全 て 同 じ 値 を 返 す 。 CLONE_THREAD で 作 ら れ た ス レ ッ ド が 終 了 し た 際 に 、 そ の ス レ ッ ド を clone() を 使 っ て 生 成 し た ス レ ッ ド に は SIGCHLD (も し く は 他 の 終 了 シ グ ナ ル ) は 送 信 さ れ な い 。 ま た 、 wait(2) を 使 っ て 終 了 し た ス レ ッ ド の 状 態 を 取 得 す る こ と も で き な い (そ の よ う な ス レ ッ ド は detached (分 離 さ れ た ) と い わ れ る )。 ス レ ッ ド グ ル ー プ に 属 す 全 て の ス レ ッ ド が 終 了 し た 後 、 そ の ス レ ッ ド グ ル ー プ の 親 プ ロ セ ス に SIGCHLD (も し く は 他 の 終 了 シ グ ナ ル ) が 送 ら れ る 。 ス レ ッ ド グ ル ー プ に 属 す い ず れ か の ス レ ッ ド が execve(2) を 実 行 す る と 、 ス レ ッ ド グ ル ー プ リ ー ダ ー 以 外 の 全 て の ス レ ッ ド は 終 了 さ れ 、 新 し い プ ロ セ ス が そ の ス レ ッ ド グ ル ー プ リ ー ダ ー の 下 で 実 行 さ れ る 。 ス レ ッ ド グ ル ー プ に 属 す ス レ ッ ド の 一 つ が fork(2) を 使 っ て 子 プ ロ セ ス を 作 成 し た 場 合 、 ス レ ッ ド グ ル ー プ の ど の ス レ ッ ド で あ っ て も そ の 子 供 を wait(2) で き る 。
Linux 2.5.35 以 降 で は 、 CLONE_THREAD を 指 定 す る 場 合 、 flags に CLONE_SIGHAND も 含 ま れ て い な け れ ば な ら な い (Linux 2.6.0−test6 以 降 で は 、 CLONE_SIGHAND を 指 定 す る 場 合 CLONE_VM も 指 定 す る 必 要 が あ る 点 に 注 意 す る こ と )。
kill(2) を 使 っ て ス レ ッ ド グ ル ー プ 全 体 (つ ま り TGID) に シ グ ナ ル を 送 る こ と も で き れ ば 、 tgkill(2) を 使 っ て 特 定 の ス レ ッ ド (つ ま り TID) に シ グ ナ ル を 送 る こ と も で き る 。 シ グ ナ ル の 配 送 と 処 理 は プ ロ セ ス 全 体 に 影 響 す る : ハ ン ド ラ ー を 設 定 し て い な い シ グ ナ ル が あ る ス レ ッ ド に 配 送 さ れ る と 、 そ の シ グ ナ ル は ス レ ッ ド グ ル ー プ の 全 メ ン バ ー に 影 響 を 及 ぼ す (終 了 し た り 、 停 止 し た り 、 動 作 を 継 続 し た り 、 無 視 さ れ た り す る )。 各 々 の ス レ ッ ド は 独 自 の シ グ ナ ル マ ス ク を 持 っ て お り 、 sigprocmask(2) で 設 定 で き る 。 だ が 、 処 理 待 ち の シ グ ナ ル に は 、 kill(2) で 送 信 さ れ る プ ロ セ ス 全 体 に 対 す る も の (つ ま り 、 ス レ ッ ド グ ル ー プ の ど の メ ン バ ー に も 配 送 で き る も の ) と 、 tgkill(2) で 送 信 さ れ る 個 々 の ス レ ッ ド に 対 す る も の が あ り え る 。 sigpending(2) を 呼 び 出 す と 、 プ ロ セ ス 全 体 に 対 す る 処 理 待 ち シ グ ナ ル と 呼 び 出 し 元 の ス レ ッ ド に 対 す る 処 理 待 ち シ グ ナ ル を 結 合 し た シ グ ナ ル 集 合 が 返 さ れ る 。
kill(2) を 使 っ て ス レ ッ ド グ ル ー プ に シ グ ナ ル が 送 ら れ た 場 合 で 、 そ の ス レ ッ ド グ ル ー プ が そ の シ グ ナ ル に 対 す る シ グ ナ ル ハ ン ド ラ ー が 登 録 さ れ て い た と き に は 、 シ グ ナ ル ハ ン ド ラ ー は ス レ ッ ド グ ル ー プ の メ ン バ ー の う ち 、 た だ 一 つ の ス レ ッ ド で だ け 起 動 さ れ る 。 ハ ン ド ラ ー が 起 動 さ れ る ス レ ッ ド は 、 そ の シ グ ナ ル を 禁 止 (block) し て い な い メ ン バ ー の 中 か ら 一 つ だ け が 勝 手 に (arbitrarily) 選 ば れ る 。 ス レ ッ ド グ ル ー プ に 属 す 複 数 の ス レ ッ ド が sigwaitinfo(2) を 使 っ て 同 じ シ グ ナ ル を 待 っ て い る 場 合 、 こ れ ら の ス レ ッ ド の 中 か ら 一 つ を カ ー ネ ル が 勝 手 に 選 択 し 、 そ の ス レ ッ ド が kill (2) を 使 っ て 送 信 さ れ た シ グ ナ ル を 受 信 す る 。
CLONE_UNTRACED (Linux 2.5.46 以 降 )
CLONE_UNTRACED が 指 定 さ れ る と 、 trace を 行 っ て い る プ ロ セ ス は こ の 子 プ ロ セ ス に CLONE_PTRACE を 適 用 す る こ と が で き な い 。
CLONE_VFORK (Linux 2.2 以 降 )
CLONE_VFORK が 設 定 さ れ た 場 合 、 (vfork(2) と 同 様 に ) 子 プ ロ セ ス が execve(2) ま た は _exit(2) に よ っ て 仮 想 メ モ リ ー を 解 放 す る ま で 、 呼 び 出 し 元 の プ ロ セ ス の 実 行 は 停 止 さ れ る 。
CLONE_VFORK が 設 定 さ れ て い な い 場 合 、 clone() 呼 び 出 し 後 は 、 呼 び 出 し 元 の プ ロ セ ス と 子 プ ロ セ ス の 両 方 が ス ケ ジ ュ ー ル 対 象 と な り 、 ア プ リ ケ ー シ ョ ン は こ れ ら の プ ロ セ ス の 実 行 順 序 に 依 存 し な い よ う に す べ き で あ る 。
CLONE_VM (Linux 2.0 以 降 )
CLONE_VM が 設 定 さ れ た 場 合 、 呼 び 出 し 元 の プ ロ セ ス と 子 プ ロ セ ス は 同 じ メ モ リ ー 空 間 で 実 行 さ れ る 。 特 に 、 呼 び 出 し 元 の プ ロ セ ス や 子 プ ロ セ ス の 一 方 が メ モ リ ー に 書 き 込 ん だ 内 容 は も う 一 方 の プ ロ セ ス か ら も 見 る こ と が で き る 。 さ ら に 、 子 プ ロ セ ス や 呼 び 出 し 元 の プ ロ セ ス の 一 方 が mmap(2) や munmap(2) を 使 っ て メ モ リ ー を マ ッ プ し た り ア ン マ ッ プ し た 場 合 、 も う 一 方 の プ ロ セ ス に も 影 響 が 及 ぶ 。
CLONE_VM が 設 定 さ れ て い な い 場 合 、 子 プ ロ セ ス は clone() が 実 行 さ れ た 時 点 で の 、 親 プ ロ セ ス の メ モ リ ー 空 間 を コ ピ ー し た 別 の メ モ リ ー 空 間 で 実 行 さ れ る 。 一 方 の プ ロ セ ス が 行 っ た メ モ リ ー へ の 書 き 込 み や フ ァ イ ル の マ ッ プ /ア ン マ ッ プ は 、 fork(2) の 場 合 と 同 様 、 も う 一 方 の プ ロ セ ス に は 影 響 し な い 。
C ラ イ ブ ラ リ と カ ー ネ ル ABI の 違 い 素 の clone シ ス テ ム コ ー ル は 、 よ り fork(2) に 近 い か た ち に な っ て お り 、 子 プ ロ セ ス の 実 行 が 呼 び 出 し が 行 わ れ た 場 所 か ら 続 け ら れ る 。 そ の た め 、 clone() ラ ッ パ ー 関 数 の 引 き 数 fn と arg は 省 略 さ れ る 。 ま た 、 引 き 数 の 順 序 も 違 っ て い る 。 x86 と 他 の 多 く の ア ー キ テ ク チ ャ ー に お け る 、 素 の シ ス テ ム コ ー ル の イ ン タ ー フ ェ ー ス は 、 お お ま か に は 次 の よ う に な っ て い る 。
long
clone(unsigned long flags, void
*child_stack,
void *ptid, void *ctid,
struct pt_regs *regs); 生 の
シ ス テ ム コ ー
ル の も う 一 つ
の 違 い は 、
child_stack 引 き 数 が
ゼ ロ で も 良 い
こ と で あ る 。
こ の 場 合 に は
、 ど ち ら か の
プ ロ セ ス が ス
タ ッ ク を 変 更
し た 時 に 、 書
き 込 み 時 コ ピ
ー (copy−on−write) 方 式
に よ り 子 プ ロ
セ ス が ス タ ッ
ク ペ ー ジ の 独
立 し た コ ピ ー
を 得 ら れ る こ
と が 保 証 さ れ
る 。 こ の 場 合
、 正 常 に 動 作
さ せ る た め に
は 、 CLONE_VM オ プ シ
ョ ン を 指 定 し
て は な ら な い
。 い く つ か の
ア ー キ テ ク チ
ャ ー で は 、 シ
ス テ ム コ ー ル
の 引 き 数 の 順
序 は 上 記 と は
異 な っ て い る
。 microblaze, ARM, ARM 64, PA−RISC, arc, Power
PC, xtensa, MIPS ア ー キ テ
ク チ ャ ー で は
、 4 番 目 と 5 番 目
の 引 き 数 の 順
番 が 逆 で あ る
。 cris と s390 ア ー キ
テ ク チ ャ ー で
は 、 最 初 と 2 番
目 の 引 き 数 の
順 番 が 逆 で あ
る 。
blackfin,
m68k, sparc
blackfin, m68k, sparc で は 引 き
数 渡 し の 規 約
が 上 記 の 説 明
と は 異 な る 。
詳 細 は 、 カ ー
ネ ル (と glibc) の ソ
ー ス を 参 照 の
こ と 。
ia64
ia64 で は 、 別 の イ
ン タ ー フ ェ ー
ス が 使 用 さ れ
る :
int
__clone2(int (*fn)(void *),
void *child_stack_base, size_t
stack_size,
int flags, void *arg, ...
/* pid_t *ptid, struct user_desc
*tls, pid_t *ctid */ );
上 記 の プ ロ ト
タ イ プ は glibc ラ ッ
パ ー 関 数 用 の
も の で あ る 。
素 の シ ス テ ム
コ ー ル の イ ン
タ ー フ ェ ー ス
に は 引 き 数 fn
と arg が な い 。
ま た 、 引 き 数
の 順 序 が 変 わ
り 、 flags が 最 初
の 引 き 数 で 、
tls が 最 後 の 引
き 数 で あ る 。
__clone2() は clone() と 同 じ よ う に 動 作 す る が 、 以 下 の 点 が 異 な る : child_stack_base は 子 プ ロ セ ス の ス タ ッ ク エ リ ア の 最 小 の ア ド レ ス を 指 し 、 stack_size は child_stack_base が 指 し 示 す ス タ ッ ク エ リ ア の 大 き さ を 示 す 。
Linux 2.4
以 前
Linux 2.4 以 前 で は 、
clone() は 引 き 数
ptid, tls, ctid を 取
ら な い 。
返 り 値
成 功 し た 場 合 、 呼 び 出 し 元 の 実 行 ス レ ッ ド に は 子 プ ロ セ ス の ス レ ッ ド ID が 返 さ れ る 。 失 敗 し た 場 合 、 呼 び 出 し 元 の コ ン テ キ ス ト に は −1 が 返 さ れ 、 子 プ ロ セ ス は 作 成 さ れ ず 、 errno が 適 切 に 設 定 さ れ る 。
エ ラ ー
EAGAIN す で に 実 行 中 の プ ロ セ ス が 多 す ぎ る 。 |
fork(2) 参 照 。 |
|||
EINVAL |
CLONE_SIGHAND が 指 定 さ れ て い た が 、 CLONE_VM が 指 定 さ れ て い な か っ た 。 (Linux 2.6.0−test6 以 降 )
EINVAL |
CLONE_THREAD が 指 定 さ れ て い た が 、 CLONE_SIGHAND が 指 定 さ れ て い な か っ た 。 (Linux 2.5.35 以 降 ) | ||
EINVAL |
CLONE_FS と CLONE_NEWNS の 両 方 が flags に 指 定 さ れ た 。 |
EINVAL (Linux 3.9 以 降 )
CLONE_NEWUSER と CLONE_FS の 両 方 が flags に 指 定 さ れ た 。
EINVAL |
CLONE_NEWIPC と CLONE_SYSVSEM の 両 方 が flags に 指 定 さ れ た 。 | ||
EINVAL |
CLONE_NEWPID と CLONE_NEWUSER の 一 方 (も し く は 両 方 ) と 、 CLONE_THREAD と CLONE_PARENT の 一 方 (も し く は 両 方 ) が 、 flags に 指 定 さ れ た 。 | ||
EINVAL |
child_stack に ゼ ロ を 指 定 し た 場 合 に clone() が 返 す 。 | ||
EINVAL |
flags に CLONE_NEWIPC が 指 定 さ れ た が 、 カ ー ネ ル で オ プ シ ョ ン CONFIG_SYSVIPC と CONFIG_IPC_NS が 有 効 に な っ て い な か っ た 。 | ||
EINVAL |
flags に CLONE_NEWNET が 指 定 さ れ た が 、 カ ー ネ ル で オ プ シ ョ ン CONFIG_NET_NS が 有 効 に な っ て い な か っ た 。 | ||
EINVAL |
flags に CLONE_NEWPID が 指 定 さ れ た が 、 カ ー ネ ル で オ プ シ ョ ン CONFIG_PID_NS が 有 効 に な っ て い な か っ た 。 | ||
EINVAL |
flags に CLONE_NEWUTS が 指 定 さ れ た が 、 カ ー ネ ル で オ プ シ ョ ン CONFIG_UTS が 有 効 に な っ て い な か っ た 。 | ||
ENOMEM |
子 プ ロ セ ス の た め に 確 保 す べ き タ ス ク 構 造 体 や 、 呼 び 出 し 元 の コ ン テ キ ス ト の 一 部 を コ ピ ー す る の に 必 要 な メ モ リ ー を 十 分 に 割 り 当 て る こ と が で き な い 。
EPERM 非 特 権 プ ロ セ ス |
(CAP_SYS_ADMIN を 持 た な い プ ロ セ ス ) が |
CLONE_NEWIPC, CLONE_NEWNET, CLONE_NEWNS, CLONE_NEWPID, CLONE_NEWUTS を 指 定 し た 。
EPERM |
PID が 0 以 外 の プ ロ セ ス に よ っ て CLONE_PID が 指 定 さ れ た 。 | ||
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) を 参 照 。
バ ー ジ ョ ン
libc5 に は clone() は な い 。 glibc2 で は clone() が 提 供 さ れ て お り 、 こ の マ ニ ュ ア ル ペ ー ジ に 記 載 の 通 り で あ る 。
準 拠
clone() は Linux 特 有 で あ り 、 移 植 を 考 慮 し た プ ロ グ ラ ム で は 使 用 す べ き で は な い 。
注 意
カ ー ネ ル 2.4.x 系 列 で は 、 一 般 的 に は CLONE_THREAD フ ラ グ を 指 定 し て も 新 し い ス レ ッ ド の 親 を 呼 び 出 し 元 プ ロ セ ス の 親 と 同 じ に は し な い 。 し か し 、 バ ー ジ ョ ン 2.4.7〜 2.4.18 の カ ー ネ ル で は 、 (カ ー ネ ル 2.6 と 同 じ よ う に ) CLONE_THREAD フ ラ グ を 指 定 す る と 、 暗 黙 の う ち に CLONE_PARENT フ ラ グ を 指 定 し た こ と に な る 。
CLONE_DETACHED と い う フ ラ グ が 、 2.5.32 で 導 入 さ れ て 以 来 し ば ら く の 間 存 在 し た 。 こ の フ ラ グ は 親 プ ロ セ ス が 子 プ ロ セ ス 終 了 の シ グ ナ ル を 必 要 と し な い こ と を 表 す も の で あ る 。 2.6.2 で 、 CLONE_DETATCHED を CLONE_THREAD と 一 緒 に 指 定 す る 必 要 は な く な っ た 。 こ の フ ラ グ は ま だ 定 義 さ れ て い る が 、 何 の 効 果 も な い 。
i386 上 で は 、 clone() は vsyscall 経 由 で は な く 、 直 接 int $0x80 経 由 で 呼 び 出 す べ き で あ る 。
バ グ
NPTL ス レ ッ ド ラ イ ブ ラ リ を 含 ん で い る GNU C ラ イ ブ ラ リ の い く つ か の バ ー ジ ョ ン に は 、 getpid(2) の ラ ッ パ ー 関 数 が 含 ま れ て お り 、 こ の ラ ッ パ ー 関 数 は PID を キ ャ ッ シ ュ す る 。 こ の キ ャ ッ シ ュ 処 理 が 正 し く 動 作 す る た め に は glibc の clone() の ラ ッ パ ー 関 数 で の 助 け が 必 要 だ が 、 現 状 の 実 装 で は 、 あ る 状 況 下 に お い て キ ャ ッ シ ュ が 最 新 と な ら な い 可 能 性 が あ る 。 特 に 、 clone() の 呼 び 出 し 直 後 に シ グ ナ ル が 子 プ ロ セ ス に 配 送 さ れ た 場 合 に 、 そ の シ グ ナ ル に 対 す る ハ ン ド ラ ー 内 で getpid(2) を 呼 び 出 す と 、 そ れ ま で に clone の ラ ッ パ ー 関 数 が 子 プ ロ セ ス の PID キ ャ ッ シ ュ を 更 新 す る 機 会 が 得 ら れ て い な け れ ば 、 呼 び 出 し 元 プ ロ セ ス ("親 プ ロ セ ス ") の PID が 返 さ れ る 可 能 性 が あ る 。 (こ の 議 論 で は 、 子 プ ロ セ ス が CLONE_THREAD を 使 っ て 作 成 さ れ た 場 合 の こ と は 無 視 し て い る 。 子 プ ロ セ ス が CLONE_THREAD を 作 っ て 作 成 さ れ た 場 合 に は 、 呼 び 出 し 元 と 子 プ ロ セ ス は 同 じ ス レ ッ ド グ ル ー プ に 属 す の で 、 getpid(2) は 子 プ ロ セ ス と clone() を 呼 び 出 し た プ ロ セ ス で 同 じ 値 を 返 す の が 「 正 し い 」 。 キ ャ ッ シ ュ が 最 新 と な ら な い 問 題 (stale−cache problem) は 、 flags に CLONE_VM が 含 ま れ て い る 場 合 に も 発 生 し な い 。 ) 本 当 の 値 を 得 る た め に は 、 次 の よ う な コ ー ド を 使 う 必 要 が あ る か も し れ な い 。
#include <syscall.h>
pid_t mypid;
mypid = syscall(SYS_getpid);
例
以 下 の プ ロ グ ラ ム は 、 別 の UTS 名 前 空 間 で 動 作 す る 子 プ ロ セ ス を clone() を 使 っ て 作 成 す る 例 で あ る 。 子 プ ロ セ ス は 、 自 分 の UTS 名 前 空 間 に お い て ホ ス ト 名 を 変 更 す る 。 そ れ か ら 、 親 プ ロ セ ス と 子 プ ロ セ ス の 両 方 で シ ス テ ム の ホ ス ト 名 を 表 示 し 、 親 プ ロ セ ス と 子 プ ロ セ ス の UTS 名 前 空 間 で ホ ス ト 名 が 異 な る こ と を 確 認 す る 。 こ の プ ロ グ ラ ム の 使 用 方 法 に つ い て は setns(2) を 参 照 。 プ ロ グ ラ ム の ソ ー ス
#define _GNU_SOURCE
#include <sys/wait.h>
#include <sys/utsname.h>
#include <sched.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define
errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \ }
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\n",
uts.nodename);
/* sleep
を 使 っ て し ば
ら く 名 前 空 間
を オ ー プ ン さ
れ た ま ま に す
る 。 こ れ に よ
り 実 験 を 行 う
こ と が で き る
−− 例 え ば 、 別
の プ ロ セ ス が
こ の 名 前 空 間
に 参 加 す る な
ど 。
*/
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
<child−hostname>\n", 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\n", (long) pid);
/* 親 プ ロ セ ス の 実 行 は こ こ に 来 る */
sleep(1); /* 子 プ ロ セ ス が ホ ス ト 名 を 変 更 す る 時 間 を 与 え る */
/* 親
プ ロ セ ス の UTS 名
前 空 間 で の ホ
ス ト 名 を 表 示
す る ; こ れ は 子
プ ロ セ ス の
UTS 名 前 空 間 で の
ホ ス ト 名 と は
異 な る */
if
(uname(&uts) == −1)
errExit("uname");
printf("uts.nodename in parent: %s\n",
uts.nodename);
if
(waitpid(pid, NULL, 0) == −1) /* 子 プ
ロ セ ス を 待 つ */
errExit("waitpid");
printf("child has terminated\n");
exit(EXIT_SUCCESS); }
関 連 項 目
fork(2), futex(2), getpid(2), gettid(2), kcmp(2), set_thread_area(2), set_tid_address(2), setns(2), tkill(2), unshare(2), wait(2), capabilities(7), namespaces(7), pthreads(7)
こ の 文 書 に つ い て
こ の man ペ ー ジ は Linux man−pages プ ロ ジ ェ ク ト の リ リ ー ス 3.79 の 一 部 で あ る 。 プ ロ ジ ェ ク ト の 説 明 と バ グ 報 告 に 関 す る 情 報 は http://www.kernel.org/doc/man−pages/ に 書 か れ て い る 。