[make-initrd] polld и проверка наличия /root/sbin/init
Alexey Gladkov
gladkov.alexey at gmail.com
Fri Apr 7 16:05:22 MSK 2023
On Fri, Apr 07, 2023 at 01:27:13AM +0300, Leonid Krivoshein wrote:
>
> On 4/6/23 09:00, Leonid Krivoshein wrote:
> >> Отсюда выводы:
> >> 1. Факт монтирования корня недостаточное условие, существует
> >> переходный процесс монтирования
> >
> > Насколько я понимаю, у каждой группы процессов может быть собственное
> > пространство имён монтирования, но описываемое поведение говорит о
> > том, что polld и chaind находятся в разных пространствах имён
Это называется mount namespace. Для использования другого mountns нужно
сделать unshare/clone т.е. определённые действия. Просто так это не
случается. polld не меняет свой mountns. В make-initrd вообще никто не
использует namespaces поскольку это необязательная фича ядра и для задачи
не требуется.
> > и ещё
> > что-то заставляет перемещать структуры в ядре от одной из групп к
> > другой. В общем странно и невероятно, потому что по идее, если
> > пространства разные, они изолированы, а если одинаковые, все процессы
> > должны увидеть изменения мгновенно. Тем не менее, мы наблюдаем именно
> > такое поведение, описанное Антоном. Весьма похоже на ядерный рейс,
> > поскольку на начальном этапе загрузка работой сильная и "мгновенности"
> > не случается.
>
> Сказанное выше больше похоже на тонкую шутку. На самом деле всё может
> быть проще...
>
> Если какой-то внешний процесс по отношению bootchain среагировал на
> событие, увидев /root/sbin/init или что-то ещё, он же может вызвать
> telinit 2?
Такой процесс есть - polld. Я же про это уже говорил.
> Но на шаге 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.
> #!/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!"
> _______________________________________________
> Make-initrd mailing list
> Make-initrd at lists.altlinux.org
> https://lists.altlinux.org/mailman/listinfo/make-initrd
--
Rgrds, legion
More information about the Make-initrd
mailing list