Когда бы вы использовали pivot_root вместо switch_root?

19

Я хочу лучше понять процесс инициализации Linux, чтобы система загружалась через ceph, а не через nfs.

В процессе я столкнулся с двумя формами переключения root. Один называется switch_root, а другой называется pivot_root. Эти сценарии запускаются из файловой системы в памяти (initramfs), полученной через tftp с помощью процесса загрузки pxe.

Когда бы вы использовали один поверх другого? Я видел оба, использованные в каком-то скрипте инициализации, помещенном в root.

Мэтт Н
источник

Ответы:

16

Я нашел замечательное объяснение здесь . Тем не менее, позвольте мне попытаться изложить в более коротком формате то, что я понял в ответе.

Более короткая версия

  1. Пока система загружается, ей нужно раннее пространство пользователя. Это может быть достигнуто с помощью initramfs или initrd.
  2. initrd загружается в ramdisk, который является актуальной ФАЙЛОВОЙ СИСТЕМОЙ .
  3. initramfs это не файловая система .
  4. Для initrd pivot_root используется и для initramfs switch_root используется.

Более длинная версия

Теперь к подробному объяснению того, что я изложил выше.

Хотя и initramfs, и initrd служат одной и той же цели, есть 2 различия. Наиболее очевидное отличие состоит в том, что initrd загружается в виртуальный диск. Он состоит из реальной файловой системы (обычно ext2), которая монтируется на виртуальном диске. С другой стороны, initramfs не является файловой системой. Это просто (сжатый) архив cpio (типа newc), который распаковывается в tmpfs. Это имеет побочный эффект, делая initramfs немного более оптимизированным и способным загружаться немного раньше в процессе загрузки ядра, чем initrd. Кроме того, размер initramfs в памяти меньше, так как ядро ​​может адаптировать размер tmpfs к тому, что фактически загружено, вместо того, чтобы полагаться на предопределенные размеры виртуального диска,

Есть и другое отличие от побочных эффектов: как обрабатывается корневое устройство (и переключается на него). Поскольку initrd - это действительная файловая система, распакованная в ram, корневым устройством должен быть виртуальный диск. Для initramfs существует ядро ​​«rootfs», которое становится tmpfs, в который распаковываются initramfs (если ядро ​​загружает initramfs; если нет, то rootfs - это просто файловая система, указанная в параметре загрузки root = kernel), но этот временный rootfs не следует указывать в качестве параметра root = boot (и не было бы способа сделать это, поскольку к нему не подключено никакое устройство). Это означает, что вы все равно можете передать свое настоящее корневое устройство ядру при использовании initramfs. С помощью initrd вы должны сами обработать то, чем является настоящее корневое устройство. Кроме того, так как "настоящий" корневое устройство с initrd - это ramdisk, ядро ​​должно действительно переключать корневые устройства с одного реального устройства (ramdisk) на другое (ваш настоящий root). В случае initramfs пространство initramfs (tmpfs) не является реальным устройством, поэтому ядро ​​не переключает реальные устройства. Таким образом, хотя команда pivot_root используется с initrd, для initramfs должна использоваться другая команда. Busybox предоставляет switch_root для этого, а klibc предлагает new_root. другая команда должна быть использована для initramfs. Busybox предоставляет switch_root для этого, а klibc предлагает new_root. другая команда должна быть использована для initramfs. Busybox предоставляет switch_root для этого, а klibc предлагает new_root.

Рамеш
источник
2
Я использовал pivot_rootв прошлом для initramfs, switch_rootне существовал в то время. switch_rootКажется, это удобный метод, pivot_rootкоторый делает больше очистки, а также перемещает /proc /sysи /devт. д., а не только сам корень
Даниэль Алдер
2
Вы не можете использовать pivot_root для initramfs rootfs, вы получите неверный аргумент. Вы можете вращать только реальные файловые системы.
TiCPU
@TiCPU Тогда как Linux выйдет из раннего пространства пользователя?
Мелаб
Представленное решение кажется неправильным. Сам Линус говорит, что pivot_root () или chroot () просто изменят ссылку на текущий процесс /. Так что, насколько я понимаю, это может быть любой путь, который не имеет ничего общего с реальными «дисками».
erikbwork