[arch-projects] [mkinitramfs] add a shutdown hook
The following patch adds a shutdown hook, which allows us to unmount root and all its submounts cleanly.
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> --- Makefile | 1 + hooks/shutdown | 11 +++++++++++ install/shutdown | 19 +++++++++++++++++++ shutdown | 10 ++++++++++ 4 files changed, 41 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..ea52796 --- /dev/null +++ b/hooks/shutdown @@ -0,0 +1,11 @@ +# vim: set ft=sh: +run_hook () +{ + msg -n ":: Creating shutdown ramfs..." + mkdir -p /run/initramfs/bin + cp /bin/busybox /run/initramfs/bin + cp /shutdown /run/initramfs + cd /run/initramfs/bin + ./busybox --install -s . + 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..5fb6e46 --- /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 | tr '\n' ' '` + +# 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 Fri, Jul 22, 2011 at 1:45 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.
Looks like I made a mistake. This only works with busybox from [community], not with mkinitcpio-busybox from [core]. It looks like there are two problematic differences: our busybox does not come with "tr", and the --install function creates symlinkes to /bin/busybox, rather than to the calling binary (/run/initramfs/bin/busybox, in this case). I'll post a new patch once I have sorted this out. Cheers, Tom
On Fri, Jul 22, 2011 at 2:58 PM, Tom Gundersen <teg@jklm.no> wrote:
On Fri, Jul 22, 2011 at 1:45 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.
Looks like I made a mistake. This only works with busybox from [community], not with mkinitcpio-busybox from [core].
It looks like there are two problematic differences: our busybox does not come with "tr", and the --install function creates symlinkes to /bin/busybox, rather than to the calling binary (/run/initramfs/bin/busybox, in this case).
Looks easy to fix. Any objections to changing the mkinitrd-busybox config from: CONFIG_BUSYBOX_EXEC_PATH="/bin/busybox" # CONFIG_TR is not set to: CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe" CONFIG_TR=y When busybox is installed in the initramfs, we have /proc/self/exe -> /bin/busybox, so it should not make a difference (though, I have not actually tried, will do later). Cheers, Tom
Am 22.07.2011 15:10, schrieb Tom Gundersen:
Looks easy to fix. Any objections to changing the mkinitrd-busybox config from: CONFIG_BUSYBOX_EXEC_PATH="/bin/busybox" # CONFIG_TR is not set to: CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe" CONFIG_TR=y
When busybox is installed in the initramfs, we have /proc/self/exe -> /bin/busybox, so it should not make a difference (though, I have not actually tried, will do later).
There was some reason I didn't do this, but I don't remember. For the busybox install in [1], I called chroot "${DEINITRAMFS_PATH}" /bin/busybox --install -s [1] http://projects.archlinux.org/users/thomas/deinitramfs.git/tree/deinitramfs#...
On Fri, Jul 22, 2011 at 03:10:58PM +0200, Tom Gundersen wrote:
On Fri, Jul 22, 2011 at 2:58 PM, Tom Gundersen <teg@jklm.no> wrote:
On Fri, Jul 22, 2011 at 1:45 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.
Looks like I made a mistake. This only works with busybox from [community], not with mkinitcpio-busybox from [core].
It looks like there are two problematic differences: our busybox does not come with "tr", and the --install function creates symlinkes to /bin/busybox, rather than to the calling binary (/run/initramfs/bin/busybox, in this case).
Looks easy to fix. Any objections to changing the mkinitrd-busybox config from: CONFIG_BUSYBOX_EXEC_PATH="/bin/busybox" # CONFIG_TR is not set to: CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe" CONFIG_TR=y
When busybox is installed in the initramfs, we have /proc/self/exe -> /bin/busybox, so it should not make a difference (though, I have not actually tried, will do later).
Cheers,
Tom
I object. The usage of tr isn't necessary in your pipeline. You can remove it and everything will still just work. Furthermore.... umount $(mount | awk ' $3 ~ /^\/oldroot/ { umount[NR] = $3; } END { for (i = NR; i >= 0; i--) { if (umount[i]) { umount[i] } }') How does busybox behave with the exec path as /proc/self/exe prior to /proc being mounted? d
On Fri, Jul 22, 2011 at 09:31:23AM -0400, Dave Reisner wrote:
On Fri, Jul 22, 2011 at 03:10:58PM +0200, Tom Gundersen wrote:
On Fri, Jul 22, 2011 at 2:58 PM, Tom Gundersen <teg@jklm.no> wrote:
On Fri, Jul 22, 2011 at 1:45 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.
Looks like I made a mistake. This only works with busybox from [community], not with mkinitcpio-busybox from [core].
It looks like there are two problematic differences: our busybox does not come with "tr", and the --install function creates symlinkes to /bin/busybox, rather than to the calling binary (/run/initramfs/bin/busybox, in this case).
Looks easy to fix. Any objections to changing the mkinitrd-busybox config from: CONFIG_BUSYBOX_EXEC_PATH="/bin/busybox" # CONFIG_TR is not set to: CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe" CONFIG_TR=y
When busybox is installed in the initramfs, we have /proc/self/exe -> /bin/busybox, so it should not make a difference (though, I have not actually tried, will do later).
Cheers,
Tom
I object. The usage of tr isn't necessary in your pipeline. You can remove it and everything will still just work. Furthermore....
umount $(mount | awk ' $3 ~ /^\/oldroot/ { umount[NR] = $3; } END { for (i = NR; i >= 0; i--) { if (umount[i]) { umount[i]
Of course i meant 'print umount[i]' here.
} }')
How does busybox behave with the exec path as /proc/self/exe prior to /proc being mounted?
d
On Fri, Jul 22, 2011 at 4:04 PM, Dave Reisner <d@falconindy.com> wrote:
On Fri, Jul 22, 2011 at 09:31:23AM -0400, Dave Reisner wrote:
On Fri, Jul 22, 2011 at 03:10:58PM +0200, Tom Gundersen wrote:
On Fri, Jul 22, 2011 at 2:58 PM, Tom Gundersen <teg@jklm.no> wrote:
On Fri, Jul 22, 2011 at 1:45 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.
Looks like I made a mistake. This only works with busybox from [community], not with mkinitcpio-busybox from [core].
It looks like there are two problematic differences: our busybox does not come with "tr", and the --install function creates symlinkes to /bin/busybox, rather than to the calling binary (/run/initramfs/bin/busybox, in this case).
Looks easy to fix. Any objections to changing the mkinitrd-busybox config from: CONFIG_BUSYBOX_EXEC_PATH="/bin/busybox" # CONFIG_TR is not set to: CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe" CONFIG_TR=y
When busybox is installed in the initramfs, we have /proc/self/exe -> /bin/busybox, so it should not make a difference (though, I have not actually tried, will do later).
Cheers,
Tom
I object. The usage of tr isn't necessary in your pipeline. You can remove it and everything will still just work. Furthermore....
umount $(mount | awk ' $3 ~ /^\/oldroot/ { umount[NR] = $3; } END { for (i = NR; i >= 0; i--) { if (umount[i]) { umount[i]
Of course i meant 'print umount[i]' here.
} }')
How does busybox behave with the exec path as /proc/self/exe prior to /proc being mounted?
d
Dave, Thomas, Good points. I'll send a new patch soon. -t
Am 22.07.2011 15:31, schrieb Dave Reisner:
How does busybox behave with the exec path as /proc/self/exe prior to /proc being mounted?
As soon as one applet wants to call another, busybox forks and re-execs itself. This behaviour can also be enabled for shell commands, but this is disabled in our config. If /proc is not mounted and the path is set to /proc/self/exe, the command will fail. The first command we execute is busybox --install -s, which IIRC re-execs itself to run the 'ln' applet.
On Fri, Jul 22, 2011 at 3:31 PM, Dave Reisner <d@falconindy.com> wrote:
How does busybox behave with the exec path as /proc/self/exe prior to /proc being mounted?
Very good point. Is there any reason busybox is not installed when the initrd is created, rather than at boot (in the same way Thomas installed it in his deinitramfs)? Also, is there any reason not to use hardlinks in stead of symlinks? -t
participants (3)
-
Dave Reisner
-
Thomas Bächler
-
Tom Gundersen