[make-initrd] polld и проверка наличия /root/sbin/init
Leonid Krivoshein
klark.devel at gmail.com
Fri Apr 7 01:27:13 MSK 2023
On 4/6/23 09:00, Leonid Krivoshein wrote:
>> Отсюда выводы:
>> 1. Факт монтирования корня недостаточное условие, существует
>> переходный процесс монтирования
>
> Насколько я понимаю, у каждой группы процессов может быть собственное
> пространство имён монтирования, но описываемое поведение говорит о
> том, что polld и chaind находятся в разных пространствах имён и ещё
> что-то заставляет перемещать структуры в ядре от одной из групп к
> другой. В общем странно и невероятно, потому что по идее, если
> пространства разные, они изолированы, а если одинаковые, все процессы
> должны увидеть изменения мгновенно. Тем не менее, мы наблюдаем именно
> такое поведение, описанное Антоном. Весьма похоже на ядерный рейс,
> поскольку на начальном этапе загрузка работой сильная и "мгновенности"
> не случается.
Сказанное выше больше похоже на тонкую шутку. На самом деле всё может
быть проще...
Если какой-то внешний процесс по отношению bootchain среагировал на
событие, увидев /root/sbin/init или что-то ещё, он же может вызвать
telinit 2? Но на шаге squahfs это ещё не было финальным монтированием. В
тот же момент bootchain продолжает процесс загрузки в шаге overlayfs, но
polld, получив сигнал, уже начинает проверку финального условия.
bootchain выполняет telinit 2 только на последнем шаге rootfs, и раз
polld начинает обработку раньше, сигнал посылает кто-то ещё и это
следует из журнала chaind.log. Возможно, остановка polld на время работы
bootchain поможет, я просто не знаю, можно ли это делать. Но я
сталкивался с двойной обработкой события на финальном этапе в другом
коде при использовании как раз метода загрузки.
При написании прототипа отдельной фичи overlayroot (вложил), закрывающей
обычный корень на запись, приходится проверять повторный вход в
/lib/initrd/boot/scripts/overlayroot. Без это оверлеи монтируются
неправильно и система просто не грузится. А откуда возникает второе
событие при срабатывании события "корень найден -- пора в stage2"?
Раньше я полагал, что его создаёт монтирование overlay.
Драка между bootchain и polld может быть не результатом "гонки" в ядре
или сторонним вызовом telinit 2, а результатом обработки этого второго
события. Но я не так хорошо знаю архитектуру make-initrd.
--
WBR, Leonid Krivoshein.
-------------- next part --------------
#!/bin/sh -efu
. shell-error
OVERLAY="${1:-tmpfs}"
BASE=/usr/share/make-initrd/data
case "$OVERLAY" in
-i|--install)
OVERLAY="${2:-tmpfs}"
;;
-u|--uninstall)
[ -d "$BASE/lib/initrd/boot/scripts" ] ||
fatal "make-initrd is not installed."
[ -x "$BASE/lib/initrd/boot/scripts/$PROG" ] ||
fatal "The $PROG feature is not installed."
sed -i -E "/\.\/$PROG/d" "$BASE"/lib/initrd/boot/method/localdev/check
sed -i -E "/register_parameter string OVERLAYROOT/d" \
"$BASE"/etc/initrd/cmdline.d/base
sed -i -E "/MODULES_TRY_ADD \+= overlay/d" /etc/initrd.mk
sed -i -E "/PUT_FILES \+= \/etc\/$PROG\.conf/d" /etc/initrd.mk
rm -f -- "/etc/$PROG.conf" "$BASE/lib/initrd/boot/scripts/$PROG"
echo "The $PROG feature was uninstalled!"
exit 0
;;
-h|--help)
cat <<-EOF
Usage $PROG [<command> | UUID=... | LABEL=... | <device>]
Commands:
-i, --install Install $PROG feature.
-u, --uninstall Uninstall $PROG feature.
-h, --help Show this help message and exit.
UUID=, LABEL= and /dev/device specified a device with the R/W layer.
By default R/W layer will be created on the TMPFS at the install time.
After install or uninstall don't forget to run make-initrd [<args>]...
EOF
exit 0
;;
esac
# Install feature
[ -d "$BASE/lib/initrd/boot/scripts" ] ||
fatal "make-initrd is not installed."
[ ! -f "$BASE/lib/initrd/boot/scripts/$PROG" ] ||
fatal "The $PROG feature already installed."
grep -qw "./$PROG" "$BASE"/lib/initrd/boot/method/localdev/check ||
echo "./$PROG" >> "$BASE"/lib/initrd/boot/method/localdev/check
grep -qw "OVERLAYROOT" "$BASE"/etc/initrd/cmdline.d/base ||
echo "register_parameter string OVERLAYROOT" \
>> "$BASE"/etc/initrd/cmdline.d/base
echo "$PROG=$OVERLAY" > "/etc/$PROG.conf"
grep -qw "/etc/$PROG.conf" /etc/initrd.mk ||
echo "PUT_FILES += /etc/$PROG.conf" >> /etc/initrd.mk
grep -w "MODULES_TRY_ADD" /etc/initrd.mk |grep -qw overlay ||
echo "MODULES_TRY_ADD += overlay" >> /etc/initrd.mk
cat > "$BASE/lib/initrd/boot/scripts/$PROG" <<EOF
#!/bin/bash -efu
. shell-error
. /.initrd/initenv
# Handle first event only
[ ! -f /.initrd/$PROG ] ||
exit 0
[ -n "\${$PROG-}" ] || [ ! -s /etc/$PROG.conf ] ||
. /etc/$PROG.conf
:> /.initrd/$PROG
case "\${$PROG-}" in
"") # Silent use default boot
exit 0
;;
disabled)
echo "rootfs has return back to the read/write mode" >&2
exit 0
;;
tmpfs)
echo "rootfs switched to the read-only mode, using tmpfs as overlay" >&2
device=
;;
UUID=?*)
device="/dev/disk/by-uuid/\${$PROG##UUID=}"
;;
LABEL=?*)
device="/dev/disk/by-label/\${$PROG##LABEL=}"
;;
/dev/?*)
device="\$$PROG"
;;
*)
fatal "\$$PROG: invalid $PROG"
;;
esac
# Wait the device
if [ -n "\$device" ]; then
i=10
while [ "\$i" != 0 ]; do
dev="\$(readlink-e "\$device" 2>/dev/null ||:)"
[ -z "\$dev" ] || [ ! -b "\$dev" ] ||
break
i="\$((\$i - 1))"
sleep .5
done
[ -n "\$dev" ] && [ -b "\$dev" ] ||
fatal "\$$PROG: invalid device specification"
echo "rootfs switched to the read-only mode, using \$dev as overlay" >&2
device="\$dev"
fi
echo "remounting / with overlayfs" >&2
mkdir -p -- "\$rootmnt.rw" "\$rootmnt.ro"
if [ -n "\$device" ]; then
mount -- "\$device" "\$rootmnt.rw"
else
mount -t tmpfs -o mode=755 -- none "\$rootmnt.rw"
fi
opts="lowerdir=\$rootmnt.ro"
opts="\$opts,upperdir=\$rootmnt.rw/rw"
opts="\$opts,workdir=\$rootmnt.rw/wk"
mkdir -p -- "\$rootmnt.rw/rw" "\$rootmnt.rw/wk"
mount --move -- "\$rootmnt" "\$rootmnt.ro"
mount -t overlay -o "\$opts" -- overlay "\$rootmnt"
mkdir -p -- "\$rootmnt/.ro" "\$rootmnt/.rw"
mount --move -- "\$rootmnt.ro" "\$rootmnt/.ro"
mount --move -- "\$rootmnt.rw" "\$rootmnt/.rw"
rmdir -- "\$rootmnt.rw" "\$rootmnt.ro"
echo "rootfs overlayed with overlayfs" >&2
EOF
chmod +x "$BASE/lib/initrd/boot/scripts/$PROG"
echo "The $PROG feature was installed!"
More information about the Make-initrd
mailing list