web-dev-qa-db-ja.com

initramfsから新しいルートへのpivot_root-エラー「無効な引数」

initramfs rootfsでピボットルートを使用することはできません。無効な引数が返されます。ピボットできるのは実際のファイルシステムのみです。

確かに:

  1. Fedora Linux 28-dracut initramfsを使用します。
  2. カーネルコマンドラインのオプションとしてrd.breakを追加して、initramfsシェルを起動します。
  3. cd /sysroot
  4. usr/bin/pivot_root . mnt

-> pivot_rootは、errnoEINVALに対応する「無効な引数」で失敗します。

man 2 pivot_rootには、これに関する説明はありません。

EINVAL put_old 下にありません new_root

なぜ失敗するのですか?そして、次のコメンターが答えたように、「それでは、Linuxはどのように初期のユーザー空間を終了するのですか?」

4
sourcejedi

initrdとは異なり、Linuxではinitramfsをアンマウントできません。どうやらこれはカーネルコードをシンプルに保つのに役立ちました。

pivot_rootの代わりに、switch_rootコマンドを使用できます。以下の手順を実装しています。 switch_rootは古いルート上のすべてのファイルを削除してinitramfsメモリを解放するため、このコマンドを実行する場所には注意が必要です。

initramfsはrootfsです。pivot_rootrootfsもアンマウントもできません。代わりに、rootfsからすべてを削除して領域を解放し(find -xdev/-exec rm '{}' ';')、rootfsを新しいルートでオーバーマウントします(cd/newmount; mount --move。/; chroot。)、 stdin/stdout/stderrを新しい/ dev/consoleにアタッチし、新しいinitを実行します。

提案されているシェルコマンドは、Cコードとほぼ同じであることに注意してください。最初のコマンドはすべてのプログラムと他のファイルをinitramfsから削除するため、コマンドはすべてシェルに組み込まれていないと機能しません:-)。


Rootfsはramfs(または有効になっている場合はtmpfs)の特別なインスタンスであり、2.6システムには常に存在します。 initプロセスを終了できないのとほぼ同じ理由で、rootfsをマウント解除することはできません。空のリストをチェックして処理する特別なコードを用意するのではなく、特定のリストが空にならないようにするだけの方がカーネルにとっては小さくて簡単です。

https://github.com/torvalds/linux/blob/v4.17/Documentation/filesystems/ramfs-rootfs-initramfs.txt

7
sourcejedi

fs/namespace.cのpivot_root syscallのコメントから

また、現在のルートを「rootfs」(初期ramfs)ファイルシステム上に置くことはできません。この状況での代替策については、 Documentation/filesystems/ramfs-rootfs-initramfs.txt を参照してください。

私は これに関するman-pagesプロジェクトへのパッチ を提出したので、将来のリリースではman 2 pivot_rootはこのケースについて言及します。