LINUX.ORG.RU
решено ФорумAdmin

bash/sh из initrd

 


0

1

Доброго времени, коллеги!

В initrd можно вывалится в консоль вызвав, например, /bin/bash.

Да! У меня в стандартном initrd присутствует bash.

Все нормально. Можно вручную монтировать и вообще изголяться в командной строке. Однако… Есть бочка дегтя в ложке меда: при выходе из bash продолжается отработка последующих команд из /init (initrd), но в процессе дальнейшей загрузки получаю:

Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000100
CPU: 3 PID: 1 Comm:switch_root Tained: G

Если я правильно его полнимаю, то после вызова /bin/bash и последующего выхода из него (initrd), /sbin/init в рабочей системе не может получить PID 1 и это происходит из-за вызова /bin/bash внутри скрипта /init (initrd).

Как правильно вызвать bash из /init (initrd), что бы после выхода из него продолжилась нормальная загрузка и /sbin/init в полноценной системе смог получить PID 1?


Думаю дело не в баше. Попробуй его там закомментировать и проверить что будет.

/sbin/init в рабочей системе не может получить PID 1

Он его не может не получить, его ядро с таким запускает до всего остального.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 1)
Ответ на: комментарий от anonymous

exec /sbin/init

Это вы о чем? О запуске /sbin/init полноценной системы из initrd?

Ну так там это делается совсем не так.

echo "ROOTFS"
/tmp/root_part

exec runas /sbin/init /bin/environ -cf /.initrd/kernelenv /sbin/swich_root $ROOTFS /sbin/init
HighMan
() автор топика

/sbin/init в рабочей системе не может получить PID 1

Ну, дак вы перед вызовом вашего странного ″exec runas ... switch_root″ вставье ″echo $$″, чтобы было видно с каким PID будет exec. Или вобще выведите список процессов, /proc же должен быть смонтирован.

Да и проверку сделайте, что это $ROOTFS/sbin/init существует и исполняемый.

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

Ну, дак вы перед вызовом вашего странного ″exec runas … switch_root″ вставье ″echo $$″, чтобы было видно с каким PID будет exec. Или вобще выведите список процессов, /proc же должен быть смонтирован.

Да и проверку сделайте, что это $ROOTFS/sbin/init существует и исполняемый.

exec runas … Это конструкция в стандартном /init (initrd) Altlinux. И она работает

Перед «прыжком» в полноценную систему я проверял $$. Если вызывался /bin/bash то PID != 1, если не вызывался, то PID = 1. Мне нужно как-то сделать, что бы вызов /bin/bash не менял PID /init

$ROOTFS/sbin/init существует и он исполняемый. С ним все в порядке. Он из стандартной полноценной системы. К тому же я сейчас издеваюсь лишь над initrd

HighMan
() автор топика
Ответ на: комментарий от HighMan

Вы сделайте вывод процессов, в древовидной форме и будет понятно, что происходит при вызове bash. Походу, вы из него не выходите. PID запущенного процесса поменяться не может. Если исходно скрипт-init был PID=1, то после вызова bash, у скрипта так PID=1 и остаётся.

$ROOTFS/sbin/init существует и он исполняемый.

Может, /sbin/init и существует, но я про то, что передаётся команде switch_root. Может содержимое $ROOTFS не туда показывает, а может туда не смонтирована ФС. За время пока тут висит этот топик, можно насовать отладочной печати в init-скрипт и понять что происходит с PID'ами, переменными и пр.

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

Может, /sbin/init и существует, но я про то, что передаётся команде switch_root. Может содержимое $ROOTFS не туда показывает, а может туда не смонтирована ФС. За время пока тут висит этот топик, можно насовать отладочной печати в init-скрипт и понять что происходит с PID’ами, переменными и пр.

Добрый день!

Извините, что надолго пропал. Тем не менее вернулся и с уточнениями.

  1. я что-то сам намудрил с PID процессов. В действительности /init имеет PID 1, как и должно быть. PID не меняется если вызывать bash. Тем не менее, в старых скриптах попытка вызвать bash и вернуться в /init приводила к kernel panic. Так и не разобрался с причиной.

  2. переделал скрипты. Теперь можно вывалится в bash, что-то там сделать, вернутся в /init и дальше идет загрузка.

Идет… Да не везде.

Сгенерировал intrd на другой машине и при запуске снова kernel panic. При этом я проверил все что можно и все в порядке! Основная система смонтирована в /rootfs, есть файл, точнее ссылка /rootfs/sbin/init. Ведет она куда следует /lib/systemd/systemd. /init имеет PID 1 и все равно kernel panic!

Я перестал что либо понимать.

Посоветуйте, что можно посмотреть? Kernel panic не изменился и как в заглавном посте

HighMan
() автор топика
Ответ на: комментарий от HighMan

ИМХО, из initrd только печать всё и вся. Снимать процесс загрузки на телефон, если рассмотреть не получается, вставлять крошечные паузы между echo, если слишком быстро для видео.

Лучше добавить в скрипт обработку своего параметра из коммандной строки ядра, которая передаётся ядру загрузчиком (grub) и доступна через /proc/cmdline. Там может быть что угодно и все игнорируют неизвестные парметры. Поэтому добавление уникального параметра, типа dbg469q ничего другое не сломает. Сделать, чтобы скрипт выводил кучу всего, если есть параметр dbg469q в /proc/cmdline. Ну, чтобы скрипт был один, не было отладочного и рабочего вариантов.

Ещё можно в командную строку ядра добавить ″debug″ и ″systemd.log_level=debug″, может понятнее будет.

А дальше, не знаю, может начинать вставлять отладочную печать в swich_root и пр. бинарники, то есть править исходники и перекомпилять. Так как не понято на каком этапе падает, там у вас 4 бинарника: runas, environ, swich_root, systemd и каждый, если завершается, а не превращается в другой через exec(), то это ″kill init!″...

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

А дальше, не знаю, может начинать вставлять отладочную печать в swich_root и пр. бинарники, то есть править исходники и перекомпилять. Так как не понято на каком этапе падает, там у вас 4 бинарника: runas, environ, swich_root, systemd и каждый, если завершается, а не превращается в другой через exec(), то это ″kill init!″…

Строка выпадения в основную систему взята из родного init скрипта.

Что интересно все работает нормально, если не вызывать: exec setsid bash -c ‘exec bash </dev/tty1 >/dev/tty1 2>&1’ Если же вызвать, посмотреть наличие смонтированного root раздела, то при выходе из bash все падает

UPD странная история…

После выхода из bash я добавил еще несколько строк, включая echo и, блин, они не срабатывают! Получается, что как только завершается сеанс вызванного bash, то он завершает и bash в котором крутится вызвавший его /init.

Еще: в порожденном процессе bash я посмотрел его PID и он 1. Т.е. это не породился новый процесс, а как-то он продолжает работать в основном! Его завершение приводит к завершению всго init процесса.

Что-то начало проясняться…

HighMan
() автор топика
Последнее исправление: HighMan (всего исправлений: 3)
Ответ на: комментарий от HighMan

как только завершается сеанс вызванного bash, то он завершает и bash в котором крутится вызвавший его /init.

Разумется, раз вы додумались делать ″exec bash″, именно так и происходит. Вы за столько времени скриптописания так и не поняли, что делает в шелле команда exec?

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

Разумется, раз вы додумались делать ″exec bash″, именно так и происходит. Вы за столько времени скриптописания так и не поняли, что делает в шелле команда exec?

Если честно, то я этим exec ни разу не пользовался

HighMan
() автор топика