[arch-projects] [PATCH] 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. v2: copy the needed libraries to the new ramfs Signed-off-by: Tom Gundersen <teg@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 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..." + 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 + cp /bin/busybox /run/initramfs/bin/ + cp /lib/ld-linux-x86-64.so.2 /run/initramfs/lib/ + cp /lib/libc.so.6 /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 +} diff --git a/shutdown b/shutdown new file mode 100644 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 -- 1.7.6
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@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
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 v3: support for 32-bit, and cleanup Signed-off-by: Tom Gundersen <teg@jklm.no> --- Makefile | 1 + hooks/shutdown | 17 +++++++++++++++++ install/shutdown | 16 ++++++++++++++++ shutdown | 12 ++++++++++++ 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 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..f22a0f0 --- /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 /lib/ld-* /run/initramfs/lib/ + cp /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..019a6a5 --- /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/mkinitramfs +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
On Fri, Jul 22, 2011 at 7:13 PM, Tom Gundersen <teg@jklm.no> 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 v3: support for 32-bit, and cleanup If you put these below the --- (three dashes), they won't show up when you commit to git. (Use git format-patch then edit the results before send-email).
Signed-off-by: Tom Gundersen <teg@jklm.no> --- Makefile | 1 + hooks/shutdown | 17 +++++++++++++++++ install/shutdown | 16 ++++++++++++++++ shutdown | 12 ++++++++++++ 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 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..f22a0f0 --- /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
One liner: mkdir -p /run/initramfs/{usr/bin,usr/sbin,bin,sbin,lib}
+ cp /bin/busybox /run/initramfs/bin/ + cp /lib/ld-* /run/initramfs/lib/ + cp /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..019a6a5 --- /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/mkinitramfs +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
On Sat, Jul 23, 2011 at 7:26 AM, Dan McGee <dpmcgee@gmail.com> wrote:
On Fri, Jul 22, 2011 at 7:13 PM, Tom Gundersen <teg@jklm.no> wrote:
v2: copy the needed libraries to the new ramfs v3: support for 32-bit, and cleanup If you put these below the --- (three dashes), they won't show up when you commit to git. (Use git format-patch then edit the results before send-email).
Good point. I'll do that (there will, sadly, be a v4).
diff --git a/hooks/shutdown b/hooks/shutdown new file mode 100644 index 0000000..f22a0f0 --- /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 One liner: mkdir -p /run/initramfs/{usr/bin,usr/sbin,bin,sbin,lib}
This is not bash, so that would not work.
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++ 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 @@ +#!/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
participants (3)
-
Dan McGee
-
Dave Reisner
-
Tom Gundersen