LINUX.ORG.RU

[initramfs]После перехода на основную ФС не повторять того, что уже было сделано на этапе initramfs.

 


0

0

Экспериментирую с созданием initramfs на коленке, так сказать. Встали некоторые вопросы. Вот например, в LFS'ном хинте (http://www.linuxfromscratch.org/hints/downloads/files/initramfs.txt) /proc перемещают из initramfs в основную систему

mount -o move /proc /new-root/proc

, а в Gentoo у меня это не сработало, говорит при загрузке, что /proc уже смонтировано, и дальше грузиться не можу. Нашёл другой пример init-сценария в инете, там просто umount /proc делается в конце. Сейчас у меня так и работает. Чем это чревато? Какую информацию я при этом не передаю из initramfs в основную систему?

Кроме того, в том же хинте параметры ядра, передаваемые загрузчиком извлекают командой:

CMDLINE=`cat /proc/cmdline`

У меня жалуется, что нету такого файла /proc/cmdline (/proc смонтирована). Пришлось все параметры захардкодить. Как передавать в init-сценарий параметры ядра?

Ещё в хинте используется команда fstype из пакета klibc-utils-1.1.1, а я поставил klibc-utils-1.5, там такой нет, пришлось захардкодить FSTYPE (хотя это, наверное, не обязательно, если mount сама определяет файловую систему). Как тут быть? Считать, что оно мне не надо?

Ещё, я хочу создать initramfs, без klibc и статических бинарников; хочу glibc. Но в init-сценарии есть run-init из klibc-utils, который я не знаю чем заменить. В описании сказано что он "nuke-initramfs-then-run-the- final-init" (exec run-init последняя команда в init-сценарии). Что из этого делает pivot_root, а что не делает?

Ещё, я в init-сценарии монтирую будущую корневую файловую систему, а потом, при загрузке основной системы она монтируется заново, причём только для чтения, а потом снова перемонтируется, на этот раз окончательно. Правильно я понимаю, что поведение системы на этом этапе описывается rc-сценариями из директории /etc/init.d моего Gentoo? А если неправильно, где копать?

Вообще, если я сделаю initramfs в котором будет проверяться файловая система, настраиваться сеть и запускаться несколько сервисов, то как потом правильно перейти к основной системе? Чтобы не пришлось лишнего останавливать, перезапускать, передывать то, что уже сделано.

★★★★★

Не читай LFS-хинты. У них политика не удалять никакую информацию, даже заведомо протухшую и в корне неверную.

Неповторение того, что уже было сделано на этапе initramfs - плохая идея, так как такая initramfs будет работать только со специально заточенной под нее системой, и не будет работать с ванильным ядром без всяких initramfs.

CMDLINE=`cat /proc/cmdline`

> У меня жалуется, что нету такого файла /proc/cmdline (/proc смонтирована). Пришлось все параметры захардкодить. Как передавать в init-сценарий параметры ядра?

Именно так. Только соптимизировать: IFS="" ; read -r CMDLINE </proc/cmdline

> Ещё в хинте используется команда fstype из пакета klibc-utils-1.1.1, а я поставил klibc-utils-1.5, там такой нет, пришлось захардкодить FSTYPE (хотя это, наверное, не обязательно, если mount сама определяет файловую систему). Как тут быть? Считать, что оно мне не надо?

Ядро без initramfs просто перебирает все известные ему файловые системы из /proc/filesystems, mount делает то же самое. Т.е. оно тебе не надо.

> Ещё, я хочу создать initramfs, без klibc и статических бинарников; хочу glibc. Но в init-сценарии есть run-init из klibc-utils, который я не знаю чем заменить.

Есть два варианта: 1) собрать run-init против glibc или 2) воспользоваться хакнутой заменой (работает только с bash и если /usr - не отдельный раздел). (1) предпочтительнее.

1) cd usr/kinit/run-init ; gcc -o run-init *.c

2)

rm -rf /everything /except/root

cd /root

init=/sbin/init # actually, parsed from /proc/cmdline, with this default

./lib/ld-linux.so.2 --library-path ./lib ./bin/mount -n --move . /

exec ../lib/ld-linux.so.2 --library-path ./lib ./usr/sbin/chroot . "$init" "$@"

> В описании сказано что он "nuke-initramfs-then-run-the- final-init" (exec run-init последняя команда в init-сценарии). Что из этого делает pivot_root, а что не делает?

Пересечение пусто. run-init - это эквивалент следующих команд в предположении, что они сами себя первой строчкой не удаляют:

rm --one-file-system -rf / # Это единственный способ освободить (а точнее - опустошить) initramfs (в отличие от initrd, где правильный подход - это pivot_root && umount). Впрочем, если 10 МБ мамяти не жалко, то можно и не освобождать.

cd $1

init=$2

shift 2

mount -n --move . / # Это не то же самое, что pivot_root, т.к. pivot_root помещает старый root в новую директорию, а mount --move - нет. Более того, pivot_root на rootfs приводит к краху.

exec chroot . "$init" "$@"

> Ещё, я в init-сценарии монтирую будущую корневую файловую систему, а потом, при загрузке основной системы она монтируется заново, причём только для чтения, а потом снова перемонтируется, на этот раз окончательно. Правильно я понимаю, что поведение системы на этом этапе описывается rc-сценариями из директории /etc/init.d моего Gentoo? А если неправильно, где копать?

Вроде правильно.

> Вообще, если я сделаю initramfs в котором будет проверяться файловая система, настраиваться сеть и запускаться несколько сервисов, то как потом правильно перейти к основной системе? Чтобы не пришлось лишнего останавливать, перезапускать, передывать то, что уже сделано.

Запускать сервисы из основной системы только если они уже не запущены. Однако см. выше - единственный реальный случай, когда это нужно, это сеть для NFS-root.

P.S. Готов вести дальнейшее обсуждение через Jabber или SIP, см. профиль. На форум времени не хватает.

AEP ★★★★★
()
Ответ на: комментарий от AEP

root всему голова

>Не читай LFS-хинты. У них политика не удалять никакую информацию, даже заведомо протухшую и в корне неверную.

Gentoo Wiki лежит (формально подняли уже, но у них бэкапы в недоступном помещении лежат, блин). Сделали бы LFS hints на движке Wiki, но почему-то не делают. Предупреждение понял.

>Неповторение того, что уже было сделано на этапе initramfs - плохая идея, так как такая initramfs будет работать только со специально заточенной под нее системой, и не будет работать с ванильным ядром без всяких initramfs.

Понял. Но таки как правильно быть с proc? umount /proc? В LFS hint'е сказано, что LFS'ные rc-сценарии нормально справляются со смонтированным /proc. Кроме того, в /proc лежит mtab, например. Нам наплевать, что оно потеряется при umount /proc?

>>Как передавать в init-сценарий параметры ядра?

>Именно так. Только соптимизировать: IFS="" ; read -r CMDLINE </proc/cmdline

Попробую.

>Ядро без initramfs просто перебирает все известные ему файловые системы из /proc/filesystems, mount делает то же самое. Т.е. оно тебе не надо.

Я так и предполагал.

>gcc -o run-init *.c

Выдаёт run-init размером 12322, ldd показывает, что он действительно слинкован с libc.so.6, а usr/kinit/run-init/static/run-init весит 10028. Я чего-то не понимаю, или динамические бинарники должны весить меньше чем статические?

>initrd, где правильный подход - это pivot_root && umount >pivot_root на rootfs приводит к краху.

Не понял. Оно, наверное, не важно, если run-init работает и полностью очищает initramfs, но если кто-то готов объяснить, то я слушаю.

И ещё, что делает cd /usr/src/linux && make all_modules ? Собирается ли при этом ядро, или только модули? Собираются все модули, которые выбраны для сборки модулями, или все опции отмеченные для сборки, модулями ли, в ядро ли, соберутся модулями, или вообще всё что может быть собрано модулем (включая драйверы для SCSI-контроллеров, веб-камер, планшетов, телескопов...) соберётся модулем.

Camel ★★★★★
() автор топика
Ответ на: root всему голова от Camel

Jabber — сила, hint — могила.

>>Именно так. Только соптимизировать: IFS="" ; read -r CMDLINE </proc/cmdline

>Попробую.

Проблема оказалась в том, что /lib/ld-linux.so.2, который я копировал в initramfs, в реальной системе был symlink'ом на ld-2.6.1.so. Исправил initramfs-list:

file /lib/ld-2.6.1.so /lib/ld-2.6.1.so 0755 0 0

slink /lib/ld-linux.so.2 /lib/ld-2.6.1.so 0755 0 0

Решение этой проблемы AEP помог найти в jabber-обсуждении.

Camel ★★★★★
() автор топика
Ответ на: root всему голова от Camel

> Но таки как правильно быть с proc? umount /proc? В LFS hint'е сказано, что LFS'ные rc-сценарии нормально справляются со смонтированным /proc.

Да, отмонтировать.

> Кроме того, в /proc лежит mtab, например. Нам наплевать, что оно потеряется при umount /proc?

Он (а точнее, /proc/mounts) не потеряется, а только пропадет с глаз долой, и появится заново с правильным содержимым при повторном монтировании /proc.

> Выдаёт run-init размером 12322, ldd показывает, что он действительно слинкован с libc.so.6, а usr/kinit/run-init/static/run-init весит 10028. Я чего-то не понимаю, или динамические бинарники должны весить меньше чем статические?

strip -s run-init

> И ещё, что делает cd /usr/src/linux && make all_modules ?

Не документировано. Правильный способ собрать модули (т.е. то, что отмечено как модули в текущем конфиге) - make modules.

Кстати, про упоминание в хинте отдельного ядра и запуск gen_init_cpio лучше забыть. В реальных дистрибутивах используется простое копирование модулей от уже установленного ядра (т.е. из /lib/modules), а также обычное ядро (bzImage или vmlinuz), которому предварительно собранный образ initramfs передается загрузчиком по протоколу initrd.

Иными словами:

1) Собираем и устанавливаем ядро как обычно (без initramfs), получаем bzImage в /boot и модули в /lib/modules.

2) mkdir work, копируем в work все, что требуется для initramfs, в том числе некоторые модули.

3) cd work ; find . | cpio -o -H newc | gzip -9 >/boot/initramfs.img

4) Настраиваем grub, чтобы он передавал /boot/initramfs.img ядру по протоколу initrd. От этого, однако, initramfs.img остается initramfs'ом, и опустошать его надо по-прежнему с помощью run-init.

AEP ★★★★★
()
Ответ на: root всему голова от Camel

> Не понял. Оно, наверное, не важно, если run-init работает и полностью очищает initramfs, но если кто-то готов объяснить, то я слушаю.

pivot_root и umount - это для устаревшей технологии initrd (не путать с протоколом initrd), которую мы не применяем (а применяем initramfs). Об этом лучше сейчас не задумываться.

AEP ★★★★★
()
Ответ на: комментарий от AEP

Сначала был init.

>Иными словами:

>1) Собираем и устанавливаем ядро как обычно (без initramfs), получаем bzImage в /boot и модули в /lib/modules.

>2) mkdir work, копируем в work все, что требуется для initramfs, в том числе некоторые модули.

>3) cd work ; find . | cpio -o -H newc | gzip -9 >/boot/initramfs.img

>4) Настраиваем grub, чтобы он передавал /boot/initramfs.img ядру по протоколу initrd. От этого, однако, initramfs.img остается initramfs'ом, и опустошать его надо по-прежнему с помощью run-init.

В это "всё что требуется", как я понимаю, входит init-сценарий, правильно? А в нём уже mount /proc, umount /proc, run-init и другие радости жизни.

Camel ★★★★★
() автор топика
Ответ на: Сначала был init. от Camel

Туда входят все файлы, которые должны попасть в initramfs. Т.е. /init, /bin/sh, /lib/libc.so.6 и все остальное.

AEP ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.