Clean shutdown with systemd

Warning, technical post, for advanced users and developers only :) (and for me, because I will surely forget this soon)

If you were used to access files in /mnt/live/* in Slax, then you will have to change your habits (and scripts) because that is now available in a different path: /run/initramfs/* ... Explanation why this change was necessary follows.

When Slax was based on Slackware, I had to manually patch the rc scripts for shutdown, to return control back to initramfs which could safely unmount all devices and reboot. But after changing to Debian base, there are no such rc scripts (due to systemd). Systemd has some hardcoded logic on what it tries to unmount. I had to digg into systemd source codes to find out what it actually does during reboot, and I was happy to find a solution.

Previous Slax puts the initramfs-root-filesystem in /mnt/live/ by calling pivot_root. But systemd has no idea this directory is special, and it tries to unmount it (including all submounts) on shutdown, making Debian report lots of red warnings. As it shows up, there is no possibility to exclude certain mountpoints from unmounting when the system is ending, however systemd has several exclude-paths hardcoded. It is / (root directory, obviously), /run/initramfs and /usr. So, instead of pivoting the root to /mnt/live, I had to modify linux-live-kit to pivot into /run/initramfs, in order for all systemd-based distros to ignore unmounting of initrd-based mounts, resulting in shutdown without errors. In order to unmount those properly, systemd executes /run/initramfs/shutdown.

One problem appeared immediately - Debian overmounts /run on boot with tmpfs, which made the /run/initramfs inaccessible (even mount --bind /run /somewhere couldn't help). So I had to make a little change in the initial startup - mount the 'run/' directory first with tmpfs, then create run/initramfs/, and then pivot root. Debian recognizes that /run is areadly mounted and doesn't overmount it again, leaving /run/initramfs accessible. Bingo.

User comments
neko 2017-11-12 15:23

I will study your initramfs of new "Slax based on Debian".
I expect that it will make me happy.

My try is as follow. (not yet finished)


Tomas M 2017-11-13 11:44

Basically what you need is the following:
1) if you run some processes in initrd (initramfs) which should stay not killed after the distro ends, you have to rename those processes to start with @. So for example I have to use @mount.httpfs2 ... this way systemd knows to ignore such process when killing all processes, thus such processes stay. Your shutdown script in initrd should then handle them properly.
2) systemd returns back to initrd (initramfs) if it finds /run/initramfs/shutdown and executes this script after it switched back. So as long as you live startup scripts use /run/initramfs for pivot_root, everything is handled by systemd properly, and such shutdown script can then unmount the rest of devices (eg. the boot device).

I've made the changes to linux-live-kit (www.linux-live.org) including a new shutdown script, so basically if you use newest liveKit you should not need to care about anything, the system will be prepared for you.

neko 2017-11-17 03:47

New version, Congraturation !!
The ISO size is surprise small !!

I am studying the initrfs of new "slax".

Now, I understand as follow.
1. It uses "init" command same as old version instead of "systemd" command.
But new "init" is symbolic linkaged to "systemd".

2. "pivot_root" space is assigned with "run/initramfs" instead of "mnt/live".
diff -r initrfs-7.0.8-x86_64/lib/livekitlib initrfs-64bit-9.2.1/lib/livekitlib
< mkdir -p mnt/live
> mkdir -p run
> mount -t tmpfs tmpfs run
> mkdir -p run/initramfs
< pivot_root . mnt/live
> pivot_root . run/initramfs

3. "Shutdown" script is changed to "shutdown" from "cleanup".
Only in initrfs-7.0.8-x86_64/lib: cleanup
Only in initrfs-64bit-9.2.1: shutdown

I will study more.
I expect that next version "slax" will employ "systemd" as start command instead of "init".


Tomas M 2017-11-18 16:33

Your observations are all correct.
But there is no more systemd integration needed. Slax (and LiveKit scripts in general) will continue to call "init". Because Linux is calling /sbin/init.