[arch-projects] [PATCH 1/2 mkinitcpio] shutdown: add a shutdown hook
Enabling the shutdown hook and using systemd v31 (which is yet to be released), means that on shutdown the root will be pivoted to /run/initramfs, from where the rootfs and all its submonuts (such as /usr) are unmounted cleanly. The same functionality will be supported in a future release of initscript. A natural next step is to add an "/usr"-hook, which mounts the /usr partition (if it exists) in the initramfs, so initscripts (and systemd) can always rely on it being mounted, and we no longer need to move some binaries/libraries to /bin, /sbin and /lib (as this does not work well at the moment). One might argue that this functionality does not beling in mkinitrd. The reason I propose it for inclusion here is: - it is independent of initscripts, so does not really belong there either. - in the future one might imagine extending this to integrate more tightly with the rest of the initramfs (e.g. store state/logs in /run/initramfs to ease debugging, or add shutdown-hooks, to go with the boot-hooks, to gracefully tear down things such as dm or nfs mounts at shutdown). - by behaving like dracut, integrating with systemd became trivial, and IMHO there is no point in systemd/initscripts/dracut/mkinitrd differing at the interface level. Signed-off-by: Tom Gundersen <teg@jklm.no> --- v2: copy the needed libraries to the new ramfs v3: support for 32-bit, and cleanup v4: fix Makefile++ v5: include all the needed libraries (typo) Makefile | 2 +- hooks/shutdown | 17 +++++++++++++++++ install/shutdown | 16 ++++++++++++++++ shutdown | 12 ++++++++++++ 4 files changed, 46 insertions(+), 1 deletions(-) create mode 100644 hooks/shutdown create mode 100644 install/shutdown create mode 100644 shutdown diff --git a/Makefile b/Makefile index 18df47f..56783bb 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ install: all chmod 755 ${DESTDIR}/bin/lsinitcpio ${DESTDIR}/sbin/mkinitcpio install -m644 mkinitcpio.conf ${DESTDIR}/etc/mkinitcpio.conf - install -m755 -t ${DESTDIR}/lib/initcpio init + install -m755 -t ${DESTDIR}/lib/initcpio init shutdown install -m644 -t ${DESTDIR}/lib/initcpio init_functions functions install -m644 01-memdisk.rules ${DESTDIR}/lib/initcpio/udev/01-memdisk.rules diff --git a/hooks/shutdown b/hooks/shutdown new file mode 100644 index 0000000..505d2d6 --- /dev/null +++ b/hooks/shutdown @@ -0,0 +1,17 @@ +# vim: set ft=sh: +run_hook () +{ + msg -n ":: Creating shutdown ramfs..." + mkdir -p /run/initramfs/usr/bin + mkdir /run/initramfs/usr/sbin + mkdir /run/initramfs/bin + mkdir /run/initramfs/sbin + mkdir /run/initramfs/lib + cp /bin/busybox /run/initramfs/bin/ + cp -P /lib/ld-* /run/initramfs/lib/ + cp -P /lib/libc* /run/initramfs/lib/ + + chroot /run/initramfs /bin/busybox --install + cp /shutdown /run/initramfs/ + msg "done." +} diff --git a/install/shutdown b/install/shutdown new file mode 100644 index 0000000..3e37326 --- /dev/null +++ b/install/shutdown @@ -0,0 +1,16 @@ +#!/bin/bash + +build() { + SCRIPT="shutdown" + add_binary /lib/initcpio/shutdown /shutdown +} + +help () { + cat <<HELPEOF +This hook will create a shutdown initrd in /run/initramfs +that we can pivot to on shutdown in order to unmount / +(and any submounts such as /usr) cleanly. +HELPEOF +} + +# vim: set ft=sh ts=4 sw=4 et: diff --git a/shutdown b/shutdown new file mode 100644 index 0000000..db2d394 --- /dev/null +++ b/shutdown @@ -0,0 +1,12 @@ +#!/bin/sh +# shutdown + +# unmount everything that was mounted on the old root +umount `mount | awk '{ print $3 }' | grep "^/oldroot" | sort -r` + +# reboot / poweroff / halt, depending on the argument passed by init +# if something invalid is passed, we halt +case "$1" in + reboot|poweroff|halt) "$1" -f ;; + *) halt -f;; +esac -- 1.7.6
This follows the same protocol as between dracut and systemd. With this patch allows us to do some basic profiling of our initrd: % systemd-analyze Startup finished in 710ms (kernel) + 2445ms (initrd) + 21214ms (userspace) = 24370ms To get the timestamp as accurate as possible, a few things are shuffled around to do the measurement as early in init as we can. A patch to systemd is also required, which I will submit if this is accepted. Signed-off-by: Tom Gundersen <teg@jklm.no> --- init | 10 +++++++--- 1 files changed, 7 insertions(+), 3 deletions(-) diff --git a/init b/init index 8c8709c..9bcc21a 100644 --- a/init +++ b/init @@ -4,10 +4,12 @@ PATH=/usr/sbin:/usr/bin:/sbin:/bin busybox --install -s +mount -t proc proc /proc -o nosuid,noexec,nodev + +RD_TIMESTAMP=$(/bin/cat /proc/uptime) + . /init_functions -mkdir -p /new_root -mount -t proc proc /proc -o nosuid,noexec,nodev mount -t sysfs sys /sys -o nosuid,noexec,nodev if grep -q devtmpfs /proc/filesystems 2>/dev/null; then mount -n -t devtmpfs udev /dev -o mode=0755,size=10M,nosuid @@ -80,6 +82,7 @@ if [ "${break}" = "y" ]; then fi # Mount root at /new_root +mkdir -p /new_root ${mount_handler:-default_mount_handler} /new_root init=${init:-/sbin/init} @@ -113,6 +116,7 @@ for d in proc sys dev run; do umount /${d} fi done -exec env -i TERM=$TERM /sbin/switch_root -c /dev/console /new_root ${init} "$@" + +exec env -i TERM="$TERM" RD_TIMESTAMP="$RD_TIMESTAMP" /sbin/switch_root -c /dev/console /new_root ${init} "$@" # vim: set ft=sh ts=4 sw=4 et: -- 1.7.6
participants (1)
-
Tom Gundersen