[arch-projects] [PATCH] shutdown: add a shutdown hook

Tom Gundersen teg at jklm.no
Sat Jul 23 15:13:39 EDT 2011

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

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 at jklm.no>

v2: copy the needed libraries to the new ramfs
v3: support for 32-bit, and cleanup
v4: fix Makefile++

 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..5241a85
--- /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 @@
+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.
+# 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 @@
+# 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;;

More information about the arch-projects mailing list