Nfsではなくcephを介してシステムをネットブートするために、Linuxの初期化プロセスをよりよく理解したいと考えています。
その過程で、ルートを切り替える2つの形式に遭遇しました。 1つはswitch_rootと呼ばれ、もう1つはpivot_rootと呼ばれます。これらのスクリプトは、pxeブートプロセスを使用してtftp経由で取得したメモリ内ファイルシステム(initramfs)から実行されます。
いつどちらを使用しますか?ルートに配置されたいくつかのinitスクリプトで両方が使用されるのを見ました。
私は素晴らしい説明を見つけました ここ 。しかし、私が答えで理解したことをより短い形式にしてみます。
短いバージョン
pivot_root
が使用され、initramfsの場合はswitch_root
が使用されます。長いバージョン
さて、私が上に置いたものの詳細な説明に。
Initramfsとinitrdの両方が同じ目的を果たしますが、2つの違いがあります。最も明らかな違いは、initrdがRAMディスクにロードされることです。 RAMディスクにマウントされている実際のファイルシステム(通常はext2)で構成されています。一方、initramfsはファイルシステムではありません。これは単にtmpfsに解凍された(圧縮された)cpioアーカイブ(newcタイプ)です。これには、initramfsを少し最適化し、カーネルブートプロセスでinitrdより少し早くロードできるようにするという副作用があります。また、カーネルは、事前定義されたramdiskサイズに依存するのではなく、カーネルがtmpfsのサイズを実際にロードされるサイズに適応できるため、メモリ内のinitramfsのサイズが小さくなり、使用されたramをクリーンアップできます。 (pivot_root実装の詳細により)引き続き使用されます。
また、別の副作用の違いがあります。ルートデバイス(およびルートデバイスへの切り替え)の処理方法です。 initrdはramに展開された実際のファイルシステムなので、ルートデバイスは実際にはramdiskでなければなりません。 initramfsの場合、initramfsが展開されるtmpfsになるカーネル「rootfs」があります(カーネルがinitramfsをロードする場合、そうでない場合、rootfsは単にroot =カーネルブートパラメータで指定されたファイルシステムです)。この暫定rootfsは、root =ブートパラメータとして指定しないでください(接続されているデバイスがないため、これを行う方法はありません)。つまり、initramfsを使用する場合でも、実際のルートデバイスをカーネルに渡すことができます。 initrdを使用すると、実際のルートデバイスが自分のものであることを処理する必要があります。また、initrdを備えた「実際の」ルートデバイスはramdiskであるため、カーネルは1つの実際のデバイス(ramdisk)からもう1つ(実際のルート)に本当にルートデバイスを切り替える必要があります。 initramfsの場合、initramfsスペース(tmpfs)は実際のデバイスではないため、カーネルは実際のデバイスを切り替えません。したがって、pivot_rootコマンドはinitrdで使用されますが、initramfsには別のコマンドを使用する必要があります。 Busyboxはこれを実現するためのswitch_rootを提供し、klibcはnew_rootを提供します。