[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