C API で「unshare」が期待どおりに動作しない 質問する

C API で「unshare」が期待どおりに動作しない 質問する

このコマンドシーケンスは機能します:

unshare --fork --pid --mount 
umount /proc
mount -t proc proc /proc
umount /dev/pts
mount -t devpts devpts /dev/pts

ただし、対応する C プログラムは期待どおりに動作しません (以前の /proc をアンマウントしていないようで、devpts をアンマウントしようとすると EBUSY が発生します)。

unshare(CLONE_NEWPID | CLONE_NEWNS );
int pid = fork();
if (pid != 0) {
    int status;
    waitpid(-1, &status, 0);
    return status;
}

printf("My pid: %i\n", getpid()); // It prints 1 as expected

umount("/proc"); // Returns 0

system("mount"); // Should print error on mtab, but it prints the previous mounted filesystems

mount("proc", "/proc", "proc",
      MS_MGC_VAL | MS_NOSUID | MS_NOEXEC | MS_NODEV,
      NULL));  // Returns 0

umount("/dev/pts");  // Returns -1 errno = 0 (??)

mount("devpts", "/dev/pts", "devpts", 
      MS_MGC_VAL | MS_NOSUID | MS_NOEXEC | MS_NODEV,
      NULL) ); // Returns -1 errno = EBUSY

読みやすさを考慮してエラーチェックは省略しました

unshare または unmount は期待どおりに動作しないと思います。ゼロを返しても、/proc はアンマウントされないようです (system("mount")その後に exec a を実行しようとすると、マウントされたファイルシステムが出力されます)。

ベストアンサー1

あなたのコメントにもかかわらず

「時々」はumount0を返し、「時々」は-1を返しますが、結局は/procまったくアンマウントされません

あなたのペーストビンのコードを10000回試したところ、umount() いつも私の場合、 は失敗し、 を返して-1アンマウントしませんでした。 が要求されたアンマウントの実行に失敗したにもかかわらずを返す/procとは信じがたいのですが、もし が返るとしたら、それは のバグになります。実際にそのようなバグを実証できる場合は、コミュニティー志向の対応としては、glibc に対してバグ レポートを提出することでしょう。umount()0umount()


すると、スクリプトの動作がなぜ、どのように異なるのかという疑問が生じますbash。しかし、実際には、そうはならないようです。

まず、unshare(1)コマンドに対する期待が間違っています。unshare(2)関数とは異なり、unshareコマンドは実行されるシェルには影響しません。代わりに、別のプロセス指定された名前空間の独自のプライベート コピーを持つプロセスです。通常は、コマンド ラインでそのプロセスを起動するコマンドを指定しますunshareが、実際、プログラムのマニュアル ページには、そうすることが必須であることが示されています。

経験的に、このようなコマンドを指定しなかった場合(あなたのように)、unshareターゲットプロセスとして新しいシェルが起動するunshareことがわかりました。特に、スクリプトを実行すると( を使用するのに十分な権限で)、すぐに新しいプロンプトが表示されますが、それはフォアグラウンドで実行されている新しいシェルのプロンプトです。プロンプトが異なるため、これはすぐにわかります(ただし、そのような状況ではプロンプトは変わらない可能性があります)。umountその時点ではエラーメッセージなどが表示されません。まだ実行されていません. umount( unshared) サブシェルで手動で proc を実行しようとすると、「デバイスがビジーです」というエラーで失敗します。これは、C プログラムが実行しようとしていることと類似しています。

サブシェルを終了すると、スクリプトの残りの部分が実行され、両方umountの と両方mountの が失敗します。メイン スクリプトはマウント名前空間を共有しているため、これは予想どおりの結果です。


/procが本当にビジー状態であり、マウント名前空間のプライベートコピーを持つプロセスであっても、アンマウントできないということは十分にあり得る。そのようなプロセスは、マウントのプライベートコピーを使用している可能性が高い/proc。対照的に、私はできる/dev/pts共有されていないマウント名前空間を持つプロセスでは正常にアンマウントされますが、その名前空間のシステムのコピーを共有するプロセスでは正常にアンマウントされません。

おすすめ記事