2017-06-21 15 views
3

私はLinuxネームスペースを試しています。特にpid名前空間。unshare --pid/bin/bash-forkはメモリを割り当てることができません

私はbashので何かアウトをテストしたが、この問題に遭遇しようと思いました。そこから

unshare -p /bin/bash 
bash: fork: Cannot allocate memory 

実行lsがコアダンプを与えました。可能なのは出口だけです。

これはなぜですか?

答えて

3

エラーが新しい名前空間にPID 1プロセスが終了によって引き起こされます。

bashの実行が開始されると、bashはいくつかの新しいサブプロセスをforkして何かを実行します。 -fなしでunshareを実行すると、bashは現在の "unshare"プロセスと同じpidを持ちます。現在の "unshare"プロセスはunshare systemcallを呼び出し、新しいpid名前空間を作成しますが、現在の "unshare"プロセスは新しいpid名前空間にありません。これはLinuxカーネルの望ましい動作です。プロセスAは新しい名前空間を作成し、プロセスA自体は新しい名前空間に入れられず、プロセスAのサブプロセスだけが新しい名前空間に入れられます。あなたが実行したときので:いくつかのサブプロセスの共有を解除プロセスは、/ binに/ bashのをexecします

 
unshare -p /bin/bash 

を、および/ binに/ bashのフォークは、bashの最初のサブプロセスは、新しい名前空間のPID 1となり、サブプロセスはジョブの完了後に終了します。したがって、新しい名前空間のPID 1は終了します。

PID 1プロセスには特別な機能があります。すべての孤立したプロセスの親プロセスになるはずです。ルート名前空間のPID 1プロセスが終了すると、カーネルはパニックに陥ります。サブネームスペースのPID 1プロセスが終了すると、linuxカーネルはdisable_pid_allocation関数を呼び出し、その名前空間のPIDNS_HASH_ADDINGフラグをクリアします。 Linuxカーネルが新しいプロセスを作成すると、カーネルはalloc_pid関数を呼び出して名前空間にPIDを割り当て、PIDNS_HASH_ADDINGフラグが設定されていない場合、alloc_pid関数は-ENOMEMエラーを返します。そのため、「メモリを割り当てられません」というエラーが表示されます。

あなたはオプション「-F」を使用することで、この問題を解決することができます:あなたは「-f」オプションと共有解除を実行した場合、それは新しいPID名前空間を作成した後、共有解除は、新しいプロセスをforkします

 
unshare -fp /bin/bash 

。そして、新しいプロセスで/ bin/bashを実行してください。新しいプロセスは、新しいpid名前空間のpid 1になります。次に、bashはいくつかのサブプロセスをforkしていくつかのジョブを実行します。 bash自体は新しいpid名前空間のpid 1であるため、そのサブプロセスは問題なく終了できます。

+0

この非常に参考になる回答をいくつかのmanページの参考文献に戻すには、['man 2 unshare'](http://man7.org/linux/man-pages/man2/unshare.2.html)では' CLONE_NEWPID ':_UnshareはPID名前空間を共有するので、呼び出しプロセスには、既存のプロセスと共有されていない子プロセスのための新しいPID名前空間があります。呼び出し元のプロセスは新しい名前空間に移動されません。 **呼び出したプロセスによって作成された最初の子は、プロセスID 1 **を持ち、新しい名前空間でinit(1)の役割を担います。 – nh2

1

この問題が発生したが、正しく新しいPID名前空間でシェルを起動する方法を示していますこれはなぜを説明していません:

unshareからシェルをオフフォークする-fフラグを使用します。

unshare -fp /bin/bash 

--mount-procオプションも渡して、新しく作成された名前空間でシェルがPID 1を取得するようにする必要があります。

psを実行します。

# ps 
    PID TTY   TIME CMD 
1 pts/1 00:00:00 bash 
11 pts/1 00:00:00 ps 
関連する問題