6

Is there a way to run a script on shutdown, after the file system is remounted as read-only?

I've a raspberry pi connected to a wireless socket, which I can control via a sender and a script. I want to power off that socket (powering off the raspberry) on shutdown, after the file system is mounted read-only.

I've tried this:

[Unit]
Description=Test
DefaultDependencies=no
Requires=shutdown.target umount.target final.target
After=shutdown.target umount.target final.target

[Service]
Type=oneshot
ExecStart=/test
KillMode=none

[Install]
WantedBy=halt.target

The script /test does output the current mounts. When it's run on shutdown, it states read/write for the root file system and not read-only as expected.

Edit:

Content of /test:

#!/bin/bash

echo -n 'Debug-Mount: ' > /dev/tty1
cat /proc/mounts | grep /dev/sda > /dev/tty1

Screen output on shutdown:

enter image description here

casper
  • 221
  • You don't show the contents of your test script. My guess is that if you're using the "mount" command to determine the state of the mount points, you will get a stale result (the contents of /etc/mtab, which is now on a read only filesystem). What you should do is look at the contents of /proc/mounts. – izak Nov 06 '15 at 08:25
  • I've added the missing information. I see no difference in using /proc/mounts instead of "mount" command. Tried both. – casper Nov 07 '15 at 12:03
  • Okay, it looks like you are right. I have to admit, I came on your question because I also wanted to run a command after root was mounted ro, because we're building something on a Raspberry Pi and it has to tell you when you can unplug. systemd is some kind of black magic and until further notice I officially hate its guts and I want sysv back :-P I ended up with After=umount.target and Before=shutdown.target and nothing else. – izak Nov 09 '15 at 07:55
  • If it's just to poweroff the device, can you start it late in the shutdown sequence and have it fork and sleep for (say) 60 seconds? Or does it just get shot down by systemd anyway? – Chris Davies Jul 27 '16 at 22:38

2 Answers2

6

I found a reliable solution: Just put the script in /usr/lib/systemd/system-shutdown/.

See also: https://www.freedesktop.org/software/systemd/man/systemd-halt.service.html

Immediately before executing the actual system halt/poweroff/reboot/kexec systemd-shutdown will run all executables in /usr/lib/systemd/system-shutdown/ and pass one arguments to them: either "halt", "poweroff", "reboot" or "kexec", depending on the chosen action. All executables in this directory are executed in parallel, and execution of the action is not continued before all executables finished.

casper
  • 221
  • Please avoid posting only the link, since there is no guarantee that the link remain alive in future . It is always better to post the answer and give the link for reference or more information. – Mostafa Ahangarha Mar 24 '16 at 18:35
1

Regarding your original script, it's usually ran before halt.target (note you didn't order it before halt.target) - and filesystems are never remounted ro at that point. systemd-shutdown (to which systemd execs at the very end - after reaching halt.target), kills stuff (possibly along with your not-ordered script =) ), runs final umount/swapoff/losetup, remounts ro what couldn't be umounted, then runs in parallel stuff from system-shutdown directory, then tries to pivot_root() into /run/initrams if shutdown exists there (and if it doesn't or pivot fails, proceeds with halt).