Search code examples
linuxarchlinuxsystemdsystem-shutdown

Arch Linux / systemd - prevent any kind of shutdown/rebboot


I'm running Arch-based Manjaro Linux and wrote myself a little update program, that starts every 7 hours and runs completely in the background. This update program is started by systemd.

What I wanna know is: How can I prevent any system shutdown/reboot during the time this program runs no matter if the user just wants to turn it off or any program wants to do so.

The best would be, if any shutdown/reboot action wouldn't be cancelled but delayed instead, so when the update program has finished its run, the shutdown/reboot continues.

My systemd parts are:

uupgrades.timer

[Unit]
Description=UU Upgrades Timer

[Timer]
OnBootSec=23min
OnUnitActiveSec=7h
Unit=uupgrades.target

[Install]
WantedBy=basic.target

uupgrades.target

[Unit]
Description=UU Upgrades Timer Target
StopWhenUnneeded=yes

and in the folder uupgrades.target.wants

uupgrades.service

[Unit]
Description=UU Update Program

[Service]
Nice=19
IOSchedulingClass=2
IOSchedulingPriority=7
ExecStart=/usr/bin/uupgrades

How can I achieve this?


Solution

  • When I want to block myself from rebooting or shutdown, I alias my usual shutdown and reboot aliases to beep;beep;beep;.

    In multiuser environments you could move the reboot, shutdown etc. binaries and move them back, when shutdown should be allowed again. You could also temporarily move an executable shell script outputting information about the postponed shutdown possibility in place of the corresponding binaries. This script could set a flag, if a shutdown was requested.

    Q&D example script:

    #!/usr/bin/env bash
    echo "preventing reboot"
    BACKUPBINARY_REBOOT=$(mktemp);
    mv /bin/reboot $BACKUPBINARY_REBOOT;
    FLAGFILE=$(mktemp);
    echo '#!/usr/bin/env bash' > /bin/reboot;
    echo '# original reboot binary was moved to'"$BACKUPBINARY_REBOOT" >> /bin/reboot;
    echo 'echo request-reboot > '"$FLAGFILE" >> /bin/reboot;
    echo 'echo reboot is prevented, your request will trigger later' >> /bin/reboot;
    chmod 666 "$FLAGFILE";
    chmod +x /bin/reboot;
    echo "postponed reboot - press enter to allow it again and make up for requested reboot";
    read;
    mv "$BACKUPBINARY_REBOOT" /bin/reboot;
    if grep -q request-reboot "$FLAGFILE"; then
      rm $FLAGFILE;
      /bin/reboot;
    fi