From b7432d25cba680c785269509245f394dfa6b9dd0 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Mon, 25 Jul 2011 14:58:57 +0200 Subject: shutdown: pivot into a shutdown ramfs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Assume that a shutdown executable has been created in /run/initramfs by either dracut or mkinitramfs. Setup /run/initramfs to be a new root and pivot into it. Making sure that nothing is using our old root anymore. In particular this means we have to reexec init in the new root and make sure stdio is using the new /dev/console. This is inspired by Harald Hoyers work for systemd as well as Thomas Bächlers deinitramfs. Signed-off-by: Tom Gundersen --- rc.shutdown | 51 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 12 deletions(-) (limited to 'rc.shutdown') diff --git a/rc.shutdown b/rc.shutdown index ebfc22c..72f2edd 100755 --- a/rc.shutdown +++ b/rc.shutdown @@ -78,21 +78,48 @@ fi [[ $USELVM = [Yy][Ee][Ss] && -x $(type -P lvm) && -d /sys/block ]] && status "Deactivating LVM2 groups" vgchange --sysinit -a n &>/dev/null -status "Remounting Root Filesystem Read-only" \ +if [[ -x /run/initramfs/shutdown ]]; then + # make /run/initrafs a mount + mount --bind /run/initramfs /run/initramfs + + # in case someone has shared our mountpoints, unshare them + mount --make-private /run/initramfs + mount --make-private / + + # bind all api mounts + mkdir -p /run/initramfs/{sys,proc,dev,run,oldroot} + mount --bind /sys /run/initramfs/sys + mount --bind /proc /run/initramfs/proc + mount --bind /dev /run/initramfs/dev + mount --bind /run /run/initramfs/run + + # enter shutdownramfs + cd /run/initramfs + pivot_root . oldroot + + #reexec init + cp /oldroot/sbin/init /sbin + /oldroot/sbin/init u + + # run /shutdown in the new root + exec chroot . /shutdown /dev/console 2>&1 +else + status "Remounting Root Filesystem Read-only" \ mount -n -o remount,ro / -run_hook shutdown_poweroff + run_hook shutdown_poweroff -# Power off or reboot -printsep -if [[ $RUNLEVEL = 0 ]]; then - printhl "${C_H2}POWER OFF" - poweroff -d -f -h -i -else - printhl "${C_H2}REBOOTING" - # if kexec is installed and a kernel is loaded, use it - [[ -x $(type -P kexec) ]] && kexec -e &>/dev/null - reboot -d -f -i + # Power off or reboot + printsep + if [[ $RUNLEVEL = 0 ]]; then + printhl "${C_H2}POWER OFF" + poweroff -d -f -h -i + else + printhl "${C_H2}REBOOTING" + # if kexec is installed and a kernel is loaded, use it + [[ -x $(type -P kexec) ]] && kexec -e &>/dev/null + reboot -d -f -i + fi fi # End of file -- cgit v1.2.3