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

Dave Reisner d at falconindy.com
Fri Jul 22 19:43:47 EDT 2011


On Sat, Jul 23, 2011 at 01:23:41AM +0200, Tom Gundersen wrote:
> 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.
> 
> v2: copy the needed libraries to the new ramfs
> 
> Signed-off-by: Tom Gundersen <teg at jklm.no>
> ---
>  Makefile         |    1 +
>  hooks/shutdown   |   16 ++++++++++++++++
>  install/shutdown |   19 +++++++++++++++++++
>  shutdown         |   10 ++++++++++
>  4 files changed, 46 insertions(+), 0 deletions(-)
>  create mode 100644 hooks/shutdown
>  create mode 100644 install/shutdown
>  create mode 100644 shutdown
> 
> diff --git a/Makefile b/Makefile
> index 18df47f..d4bb4e1 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -35,6 +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/shutdown shutdown

You never added /lib/initcpio/shutdown to the DIRS declare in the
Makefile. install(1) doesn't make the directory structure for you here.

>  	install -m755 -t ${DESTDIR}/lib/initcpio init
>  	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..6291a30
> --- /dev/null
> +++ b/hooks/shutdown
> @@ -0,0 +1,16 @@
> +# vim: set ft=sh:
> +run_hook ()
> +{
> +    msg -n ":: Creating shutdown ramfs..."

Skip the -n if you aren't going to add a 'done' msg at the end.

> +    mkdir -p /run/initramfs/usr/bin
> +    mkdir -p /run/initramfs/usr/sbin
> +    mkdir -p /run/initramfs/bin
> +    mkdir -p /run/initramfs/sbin
> +    mkdir -p /run/initramfs/lib

Such repetition... -p is only necessary on the first call.

> +    cp /bin/busybox /run/initramfs/bin/
> +    cp /lib/ld-linux-x86-64.so.2 /run/initramfs/lib/

You can't hardcode this -- it totally precludes 32 bit. Since we're
running this from the initramfs anyways, I suggest we just copy over
/lib/ld-* to /run/initramfs/bin.

> +    cp /lib/libc.so.6 /run/initramfs/lib/

Same here. cp /lib/libc.* /run/initramfs/lib/

> +
> +    chroot /run/initramfs /bin/busybox --install
> +    cp /shutdown /run/initramfs/
> +}
> diff --git a/install/shutdown b/install/shutdown
> new file mode 100644
> index 0000000..9f8076b
> --- /dev/null
> +++ b/install/shutdown
> @@ -0,0 +1,19 @@
> +# vim:set ft=sh:
> +
> +build()
> +{
> +    MODULES=""
> +    BINARIES=""
> +    FILES=""
> +    SCRIPT="shutdown"
> +    add_binary /lib/initcpio/shutdown /shutdown
> +}
> +
> +help ()
> +{
> +cat <<HELPEOF
> +  This hook will create a shutdown initrd in /run/mkinitramfs
> +  that we can pivot to on shutdown in order to unmount /
> +  (and any submounts such as /usr) cleanly.
> +HELPEOF
> +}

This is all bash, and I spent a fair bit of time cleaning things up in
the install directory. Can I pedantic and ask for the same style?

#!/bin/bash

build() {
  foo
  bar
}

help() {
  cat <<HELPEOF
i halp you.
EOF
}

# vim: set ft=sh ts=4 sw=4 et:

If a var isn't defined, just leave it out. It's all unset prior to the
hook being run anyways.

> diff --git a/shutdown b/shutdown
> new file mode 100644

Doesn't this need to be executable? Or are we sourcing this?

> index 0000000..a55975f
> --- /dev/null
> +++ b/shutdown
> @@ -0,0 +1,10 @@
> +#!/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
> +[ "$1" = "reboot" ] && reboot -f
> +[ "$1" = "poweroff" ] && poweroff -f
> +[ "$1" = "halt" ] && halt -f

Would probably make sense to throw this into a case statement:

case "$1" in
  reboot|poweroff|halt) "$1" -f ;;
  *) defaultaction ;;
esac

Not sure what that default action should be, but I suggest we do
_something_.

d



More information about the arch-projects mailing list