[make-initrd] [PATCH 2/3] Rewrite console locking

Alexey Gladkov gladkov.alexey at gmail.com
Wed May 17 19:04:41 MSK 2023


We have migrated from a directory as a locking mechanism to use the
flock utility. This allows you to get rid of active polling.

Signed-off-by: Alexey Gladkov <gladkov.alexey at gmail.com>
---
 data/bin/rdshell                              | 12 --------
 data/bin/rdshell-locked                       |  1 -
 data/bin/rdshell-sh-functions                 | 29 -------------------
 data/etc/rc.d/init.d/cmdline                  |  2 --
 data/etc/rc.d/rc                              | 15 +++++-----
 data/lib/initrd/boot/scripts/console-inactive |  7 ++---
 data/lib/initrd/spawn-shell                   |  7 +++--
 data/lib/uevent/each/pre/.gitignore           |  0
 data/lib/uevent/each/pre/console              | 25 ----------------
 data/lib/uevent/handlers/poll/400-rootdelay   | 21 ++++++++------
 .../lib/initrd/boot/method/bootloader/action  | 18 ++++++------
 .../data/lib/uevent/handlers/040-mountdev     | 13 ++++-----
 .../luks/data/lib/uevent/handlers/085-luks    | 11 +++----
 .../network/data/etc/rc.d/init.d/network-up   | 10 +++++++
 .../data/lib/uevent/handlers/040-sshfsroot    | 13 ++++-----
 .../zfs/data/lib/uevent/extenders/200-zfs     | 12 ++++----
 testing/sh-functions                          |  4 +--
 .../units/sort-services/ts0007/data00-cmdline |  2 --
 .../units/sort-services/ts0008/data00-cmdline |  2 --
 19 files changed, 69 insertions(+), 135 deletions(-)
 delete mode 120000 data/bin/rdshell-locked
 delete mode 100644 data/bin/rdshell-sh-functions
 create mode 100644 data/lib/uevent/each/pre/.gitignore
 delete mode 100755 data/lib/uevent/each/pre/console

diff --git a/data/bin/rdshell b/data/bin/rdshell
index 59c3e6c1..bb040f15 100755
--- a/data/bin/rdshell
+++ b/data/bin/rdshell
@@ -2,7 +2,6 @@
 
 . shell-error
 . shell-source
-. rdshell-sh-functions
 
 source_if_exists /.initrd/initenv
 
@@ -27,14 +26,6 @@ esac
 
 exec </dev/console >/dev/console 2>&1
 
-console_locked=
-if [ -n "$0" ] && [ -z "${0##*-locked}" ]; then
-	while ! console_lock; do
-		sleep 0.1
-	done
-	console_locked=1
-fi
-
 for f in /lib/shell/*; do
 	[ -x "$f" ] || break
 	"$f" ||:
@@ -44,6 +35,3 @@ done
 	printf '%s: %s\n' "${0##*/}" "$1"
 
 setsid -c $shcmd
-
-[ -z "$console_locked" ] ||
-	console_unlock
diff --git a/data/bin/rdshell-locked b/data/bin/rdshell-locked
deleted file mode 120000
index ee18ff81..00000000
--- a/data/bin/rdshell-locked
+++ /dev/null
@@ -1 +0,0 @@
-rdshell
\ No newline at end of file
diff --git a/data/bin/rdshell-sh-functions b/data/bin/rdshell-sh-functions
deleted file mode 100644
index b2b7b2aa..00000000
--- a/data/bin/rdshell-sh-functions
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/bash -eu
-
-if [ -z "${__rdshell_sh_functions-}" ]; then
-__rdshell_sh_functions=1
-
-_console_lock=/.initrd/rdshell.lock
-
-console_lock()
-{
-	mkdir "$_console_lock" >/dev/null 2>&1 ||
-		return 1
-}
-
-console_unlock()
-{
-	rmdir "$_console_lock"
-}
-
-console_inactive()
-{
-	[ ! -d "$_console_lock" ]
-}
-
-console_open()
-{
-	rdshell-locked "$@" &
-}
-
-fi
diff --git a/data/etc/rc.d/init.d/cmdline b/data/etc/rc.d/init.d/cmdline
index 7199c4aa..4d2af343 100755
--- a/data/etc/rc.d/init.d/cmdline
+++ b/data/etc/rc.d/init.d/cmdline
@@ -15,8 +15,6 @@
 
 . /etc/init.d/functions
 
-. rdshell-sh-functions
-
 . shell-error
 . shell-var
 . shell-cmdline
diff --git a/data/etc/rc.d/rc b/data/etc/rc.d/rc
index 9e261958..02f85ae5 100755
--- a/data/etc/rc.d/rc
+++ b/data/etc/rc.d/rc
@@ -8,7 +8,7 @@
 #
 
 . /etc/init.d/functions
-. rdshell-sh-functions
+. shell-locks
 
 # Get first argument. Set new runlevel to this argument.
 [ $# -eq 0 ] ||
@@ -21,14 +21,13 @@ rcd="/etc/rc.d/rc$runlevel.d"
 [ -d "$rcd" ] ||
 	exit 0
 
+exec </dev/console 2>&1
+fd_lock 90 /dev/console
+
 msg "INIT: Entering runlevel: $runlevel"
 
 export INITLOG_FILE='/var/log/boot.log'
 
-while ! console_lock; do
-	sleep 0.5
-done
-
 run_scripts() {
 	local s n="$1"
 	shift
@@ -59,7 +58,7 @@ for i in "$rcd"/K*; do
 	rc="$?"
 
 	run_scripts "post/$subsys" stop "$subsys" "$rc"
-done
+done 90<&-
 
 # Now run the START scripts.
 for i in "$rcd"/S*; do
@@ -111,6 +110,6 @@ for i in "$rcd"/S*; do
 	rc="$?"
 
 	run_scripts "post/$subsys" start "$subsys" "$rc"
-done
+done 90<&-
 
-console_unlock
+fd_unlock 90
diff --git a/data/lib/initrd/boot/scripts/console-inactive b/data/lib/initrd/boot/scripts/console-inactive
index b40bdde9..ab41ef21 100755
--- a/data/lib/initrd/boot/scripts/console-inactive
+++ b/data/lib/initrd/boot/scripts/console-inactive
@@ -1,6 +1,5 @@
-#!/bin/bash
+#!/bin/bash -e
 
-. rdshell-sh-functions
+. shell-locks
 
-console_inactive ||
-	exit
+fd_trylock 90 /dev/console
diff --git a/data/lib/initrd/spawn-shell b/data/lib/initrd/spawn-shell
index 55dbdbfe..ed8df4a3 100755
--- a/data/lib/initrd/spawn-shell
+++ b/data/lib/initrd/spawn-shell
@@ -1,6 +1,7 @@
 #!/bin/bash -efu
 
-. rdshell-sh-functions
+. shell-locks
 
-console_inactive &&
-	console_open "Emergency shell" ||:
+if fd_trylock 90 /dev/console; then
+	rdshell "Emergency shell" &
+fi
diff --git a/data/lib/uevent/each/pre/.gitignore b/data/lib/uevent/each/pre/.gitignore
new file mode 100644
index 00000000..e69de29b
diff --git a/data/lib/uevent/each/pre/console b/data/lib/uevent/each/pre/console
deleted file mode 100755
index dbf16cbb..00000000
--- a/data/lib/uevent/each/pre/console
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/bash -efu
-
-. rdshell-sh-functions
-
-QUEUE="$1"
-
-[ "$QUEUE" = udev ] ||
-	exit 0
-
-. shell-error
-
-PROG="${QUEUE:--}: session=${SESSION:-0}: $PROG"
-message_time=1
-
-show_msg=
-while ! console_inactive; do
-	if [ -z "$show_msg" ]; then
-		message "waiting for console to be unlocked."
-		show_msg=1
-	fi
-	sleep 0.1
-done
-
-[ -z "$show_msg" ] ||
-	message "console is unlocked."
diff --git a/data/lib/uevent/handlers/poll/400-rootdelay b/data/lib/uevent/handlers/poll/400-rootdelay
index cac86622..50173947 100755
--- a/data/lib/uevent/handlers/poll/400-rootdelay
+++ b/data/lib/uevent/handlers/poll/400-rootdelay
@@ -1,12 +1,11 @@
 #!/bin/bash -efu
 
-. rdshell-sh-functions
-
 # Waiting for cmdline service
 [ -f /.initrd/initenv ] ||
 	exit 0
 
 . /.initrd/initenv
+. shell-locks
 
 disabled="/.initrd/rootdelay/disabled"
 
@@ -15,7 +14,10 @@ disabled="/.initrd/rootdelay/disabled"
 
 if [ -n "${RDSHELL-}" ]; then
 	mkdir -p -- "$disabled"
-	console_open "Emergency shell"
+
+	fd_lock 90 /dev/console
+	rdshell "Emergency shell" &
+
 	exit
 fi
 
@@ -58,23 +60,24 @@ if [ "$delay" -le 0 ]; then
 		msg="$(cat "$consmsg")"
 
 	mkdir -p -- "$disabled"
-	console_open "${msg:-The waiting time expired!}"
+
+	fd_lock 90 /dev/console
+	rdshell "${msg:-The waiting time expired!}" &
+
 	exit 0
 fi
 
 if [ -z "${QUIET-}" ] && [ -z "$first_iter" ] && [ $(( $delay % 15 )) -eq 0 ]; then
 	. shell-error
 
-	while ! console_lock; do
-		sleep 0.2
-	done
+	fd_lock 90 /dev/console
 
 	resume_checked &&
 		msg="Waiting for root ${ROOT:+($ROOT) }..." ||
 		msg="Waiting for resume device ${RESUME:+($RESUME) }..."
 
 	PROG=initramfs \
-	message "$msg" >/dev/console 2>&1 ||:
+	message "$msg" >/dev/console 2>&1 90<&- ||:
 
-	console_unlock
+	fd_unlock 90
 fi
diff --git a/features/bootloader/data/lib/initrd/boot/method/bootloader/action b/features/bootloader/data/lib/initrd/boot/method/bootloader/action
index b11b98d7..20fd15e9 100755
--- a/features/bootloader/data/lib/initrd/boot/method/bootloader/action
+++ b/features/bootloader/data/lib/initrd/boot/method/bootloader/action
@@ -1,22 +1,22 @@
 #!/bin/bash -efu
 
-. shell-error
 . /.initrd/initenv
 
+. shell-error
+. shell-locks
+
 [ -n "${BOOT_CONFIG-}" ] ||
 	fatal "config file not found"
 
-. rdshell-sh-functions
-
-console_lock
 exec < /dev/console >/dev/console 2>&1
+fd_lock 90 /dev/console
 
 export NEWT_COLORS_FILE="/home/root/.newtrc"
 
 mkdir -p /tmp/bootmenu
 cd /tmp/bootmenu
 
-setsid -c /bin/bootmenu "$BOOT_CONFIG" .
+setsid -c /bin/bootmenu "$BOOT_CONFIG" . 90<&-
 
 # shellcheck disable=SC2094,SC2162
 read kernel < kernel
@@ -32,9 +32,9 @@ ln -sf -- "${BOOT_CONFIG%/*}" /boot
 kexec \
 	--load "/boot/$kernel" \
 	${initrd:+--initrd="/boot/$initrd"} \
-	${append:+--append="$append"}
-kexec -x -e
+	${append:+--append="$append"} 90<&-
+kexec -x -e 90<&-
 
-setsid /bin/sh -l
+setsid /bin/sh -l 90<&-
 
-console_unlock
+fd_unlock 90
diff --git a/features/fsck/data/lib/uevent/handlers/040-mountdev b/features/fsck/data/lib/uevent/handlers/040-mountdev
index 8ca70ded..fab73b4b 100755
--- a/features/fsck/data/lib/uevent/handlers/040-mountdev
+++ b/features/fsck/data/lib/uevent/handlers/040-mountdev
@@ -1,9 +1,11 @@
 #!/bin/bash
 
 . /.initrd/initenv
+
+. shell-locks
+
 . /etc/init.d/functions
 . uevent-sh-functions
-. rdshell-sh-functions
 . initrd-sh-functions
 . state-sh-functions
 
@@ -50,15 +52,12 @@ handler()
 	reboot
 }
 
-while ! console_lock; do
-	sleep 0.5
-done
-
 exec 0</dev/console >/dev/console 2>&1
+fd_lock 90 /dev/console
 
 for e in "$eventdir"/mountdev.*; do
 	[ -e "$e" ] || break
 	( . "$e"; handler; ) ||:
-done
+done 90<&-
 
-console_unlock
+fd_unlock 90
diff --git a/features/luks/data/lib/uevent/handlers/085-luks b/features/luks/data/lib/uevent/handlers/085-luks
index 5dd038e1..d2025a50 100755
--- a/features/luks/data/lib/uevent/handlers/085-luks
+++ b/features/luks/data/lib/uevent/handlers/085-luks
@@ -4,10 +4,10 @@
 
 . shell-error
 . shell-var
+. shell-locks
 
 . uevent-sh-functions
 . initrd-sh-functions
-. rdshell-sh-functions
 . crypttab-sh-functions
 
 PROG="${QUEUE:--}: session=${SESSION:-0}: $PROG"
@@ -407,11 +407,8 @@ handler() {
 	fi
 }
 
-while ! console_lock; do
-	sleep 0.5
-done
-
 exec 0</dev/console >/dev/console 2>&1
+fd_lock 90 /dev/console
 
 rc=0
 for e in "$eventdir"/luks.*; do
@@ -423,7 +420,7 @@ for e in "$eventdir"/luks.*; do
 		1) rc=1 ;;
 		0) done_event "$e" ;;
 	esac
-done
+done 90<&-
 
-console_unlock
+fd_unlock 90
 exit $rc
diff --git a/features/network/data/etc/rc.d/init.d/network-up b/features/network/data/etc/rc.d/init.d/network-up
index 684d5a3d..9ec3b978 100755
--- a/features/network/data/etc/rc.d/init.d/network-up
+++ b/features/network/data/etc/rc.d/init.d/network-up
@@ -13,11 +13,14 @@
 
 msg="Network up"
 
+. shell-locks
 . network-sh-functions
 
 # wait for network modules
 udevadm settle --timeout=3
 
+fd_rlock 90 /dev/console
+
 ifaces=' '
 while :; do
 	set -- /sys/class/net/*
@@ -46,3 +49,10 @@ while :; do
 
 	sleep 0.1
 done
+
+if [ "${RDLOG-}" = 'console' ]; then
+	msg="all interfaces are up ($ifaces):"
+
+	echo_msg "$msg"
+	success "$msg"
+fi
diff --git a/features/sshfsroot/data/lib/uevent/handlers/040-sshfsroot b/features/sshfsroot/data/lib/uevent/handlers/040-sshfsroot
index 99d1416c..3a4b0ef4 100755
--- a/features/sshfsroot/data/lib/uevent/handlers/040-sshfsroot
+++ b/features/sshfsroot/data/lib/uevent/handlers/040-sshfsroot
@@ -1,10 +1,12 @@
 #!/bin/bash
 
 . /.initrd/initenv
+
+. shell-locks
+
 . initrd-sh-functions
 . uevent-sh-functions
 . network-sh-functions
-. rdshell-sh-functions
 
 PROG="${QUEUE:--}: session=${SESSION:-0}: $PROG"
 message_time=1
@@ -38,11 +40,8 @@ handler() {
 	done
 }
 
-while ! console_lock; do
-        sleep 0.5
-done
-
 exec 0</dev/console >/dev/console 2>&1
+fd_lock 90 /dev/console
 
 rc=0
 for e in "$eventdir"/sshfsroot.*; do
@@ -50,7 +49,7 @@ for e in "$eventdir"/sshfsroot.*; do
 	( . "$e"; handler; ) ||
 		rc=1
 	done_event "$e"
-done
+done 90<&-
 
-console_unlock
+fd_unlock 90
 exit $rc
diff --git a/features/zfs/data/lib/uevent/extenders/200-zfs b/features/zfs/data/lib/uevent/extenders/200-zfs
index ec626234..723ac827 100755
--- a/features/zfs/data/lib/uevent/extenders/200-zfs
+++ b/features/zfs/data/lib/uevent/extenders/200-zfs
@@ -7,8 +7,9 @@
 . /.initrd/initenv
 
 . shell-error
+. shell-locks
+
 . initrd-sh-functions
-. rdshell-sh-functions
 . uevent-sh-functions
 
 message_time=1
@@ -90,13 +91,12 @@ mount_zfs()
 resume_checked ||
 	exit 0
 
-while ! console_lock; do
-	sleep 0.5
-done
+exec 0</dev/console >/dev/console 2>&1
+fd_lock 90 /dev/console
 
 findmnt -sno TARGET -t zfs | sort -d -k1,1 |
 while read -r mnt; do
-	mount_zfs "$mnt" </dev/null ||:
+	mount_zfs "$mnt" </dev/null 90<&- ||:
 done
 
-console_unlock
+fd_unlock 90
diff --git a/testing/sh-functions b/testing/sh-functions
index da515ee9..18a8c8c2 100644
--- a/testing/sh-functions
+++ b/testing/sh-functions
@@ -360,8 +360,8 @@ qemu_watchdog()
 		for err in \
 			"(or press Control-D to continue):" \
 			"/.initrd/uevent/queues/udev.startup: No such file or directory" \
-			"rdshell-locked: The waiting time expired!" \
-			"rdshell-locked: The init program \`/sbin/init' not found in the root directory." \
+			"rdshell: The waiting time expired!" \
+			"rdshell: The init program \`/sbin/init' not found in the root directory." \
 		;
 		do
 			if grep -qsF -e "$err" "$logfile"; then
diff --git a/testing/units/sort-services/ts0007/data00-cmdline b/testing/units/sort-services/ts0007/data00-cmdline
index 95ea8e05..f68ba8a2 100755
--- a/testing/units/sort-services/ts0007/data00-cmdline
+++ b/testing/units/sort-services/ts0007/data00-cmdline
@@ -15,8 +15,6 @@
 
 . /etc/init.d/functions
 
-. rdshell-sh-functions
-
 . shell-error
 . shell-var
 . shell-cmdline
diff --git a/testing/units/sort-services/ts0008/data00-cmdline b/testing/units/sort-services/ts0008/data00-cmdline
index 95ea8e05..f68ba8a2 100755
--- a/testing/units/sort-services/ts0008/data00-cmdline
+++ b/testing/units/sort-services/ts0008/data00-cmdline
@@ -15,8 +15,6 @@
 
 . /etc/init.d/functions
 
-. rdshell-sh-functions
-
 . shell-error
 . shell-var
 . shell-cmdline
-- 
2.33.8



More information about the Make-initrd mailing list