Block systemd-initiated poweroff/reboot/halt until configurable condition checks pass
- Python 2.7
- systemd
- Can be launched from a simple systemd service or run manually
-
Download and execute
rguardwithout any condition checks to confirm it really can block shutdown.[root]# cd /usr/sbin [root]# curl -kO https://raw.githubusercontent.com/ryran/reboot-guard/master/rguard % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 16575 100 16575 0 0 54536 0 --:--:-- --:--:-- --:--:-- 54702 [root]# ll rguard -rwxr-xr-x. 1 root root 16575 Sep 1 02:46 rguard [root]# rguard -1 WARNING: ☹ Blocked poweroff.target WARNING: ☹ Blocked reboot.target WARNING: ☹ Blocked halt.target [root]# -
Try to reboot/shutdown/halt and fail. Note that the old legacy commands (
halt,shutdown,reboot) trigger wall messages regardless.[root]# systemctl reboot Failed to issue method call: Operation refused, unit reboot.target may be requested by dependency only. [root]# shutdown -h now Failed to issue method call: Operation refused, unit poweroff.target may be requested by dependency only. Broadcast message from root@localhost on pts/0 (Mon 2015-08-31 02:28:05 EDT): The system is going down for power-off NOW! [root]# -
Disable the blocks.
[root]# rguard -0 WARNING: ☻ Unblocked poweroff.target WARNING: ☻ Unblocked reboot.target WARNING: ☻ Unblocked halt.target [root]#
-
Execute
rguardwith a tiny sleep-interval and 2 simple checks.[root]# rguard --interval 15 --unit atd --require-file /run/.require & [1] 23317 WARNING: ☹ Failed a condition-check WARNING: ☹ Blocked poweroff.target WARNING: ☹ Blocked reboot.target WARNING: ☹ Blocked halt.target [root]# -
The conditions we set meant shutdown will be blocked while atd is active and while
/run/.requiredoes not exist, so fix that andrguardwill immediately unblock shutdown.[root]# systemctl is-active atd active [root]# systemctl stop atd [root]# touch /run/.require WARNING: ☻ Passed all condition-checks WARNING: ☻ Unblocked poweroff.target WARNING: ☻ Unblocked reboot.target WARNING: ☻ Unblocked halt.target [root]# fg rguard --interval 15 --unit atd --require-file /run/.require ^C WARNING: Gracefully exiting due to receipt of signal 2
- Install the latest rpm from Releases or setup yum repo:
yum/dnf install http://people.redhat.com/rsawhill/rpms/latest-rsawaroha-release.rpmyum/dnf install reboot-guard
- If you want the service to always block reboot/shutdown, requiring the service to be manually stopped or killed, simply run
systemctl daemon-reload; systemctl enable rguard --nowand you are done; otherwise, continue to next step - Play with the options until you get them how you want them (see help page:
rguard --help) - Copy
/usr/lib/systemd/system/rguard.serviceto/etc/systemd/systemand set theExecStart=directive to your liking - Run:
systemctl daemon-reload; systemctl enable rguard --now - Check
systemctl status rguard -n50or usejournalctl -fu rguardto keep an eye on logs (turn up the--loglevelif necesary) - Tweak
rguard.serviceas required, and then re-runsystemctl daemon-reload; systemctl restart rguard - Give feedback by posting to the Issue Tracker
usage: rguard [-1 | -0] [-f FILE] [-F FILE] [-u UNIT] [-c CMD] [-a ARGS] [-r COMMAND] [-h] [-i SEC] [-n] [-x] [-v {debug,info,warning,error}] [-t] Block systemd-initiated shutdown until configurable condition checks pass SET AND QUIT: Execute a single action with no condition checks. -1, --install-guard Install reboot-guard and immediately exit -0, --remove-guard Remove reboot-guard (if present) and immediately exit CONFIGURE CONDITIONS: Establish what condition checks must pass to allow shutdown. Each option may be specified multiple times. -f, --forbid-file FILE Prevent shutdown while FILE exists -F, --require-file FILE Prevent shutdown until FILE exists -u, --unit UNIT Prevent shutdown while systemd UNIT is active -c, --cmd CMD Prevent shutdown while CMD exactly matches at least 1 running process -a, --args ARGS Prevent shutdown while ARGS exactly matches the full cmd+args of at least 1 running process -r, --run COMMAND Prevent shutdown while execution of COMMAND fails; prefix COMMAND with '!' to prevent shutdown while execution succeeds (MORE: Prefix COMMAND with '@' to execute it as a shell command, e.g., to use pipes '|' or other logic; examples: '@cmd|cmd' or '!@cmd|cmd') GENERAL OPTIONS: -h, --help Show this help message and exit -i, --interval SEC Modify the sleep interval between condition checks (default: 60 seconds) -n, --ignore-signals Ignore the most common signals (HUP, INT, QUIT, USR1, USR2, TERM), in which case a graceful exit requires the next option or else SIGKILL -x, --exit-on-pass Exit (and remove reboot-guard) the first time all condition checks pass -v, --loglevel {debug,info,warning,error} Specify minimum message type to print (default: warning) -t, --timestamps Enable timestamps in message output (not necessary if running as systemd service) EXAMPLES: As mentioned above, all of the condition-checking options can be used multiple times. All specified checks must pass to allow shutdown. rguard --forbid-file /shutdown/prevented/if/this/file/exists rguard --require-file /shutdown/prevented/until/this/file/exists rguard --cmd some-cmd-name-which-when-running-prevents-shutdown * e.g., 'bash' or 'firefox' rguard --args 'syndaemon -i 1.0 -t -K -R' * Prevent shutdown if this exact cmd + args are found running rguard --run 'ping -c2 -w1 -W1 10.0.0.1' * Allow shutdown only if single command (ping in this case) succeeds rguard --run '!ping -c2 -w1 -W1 10.0.0.1' * Allow shutdown only if single command FAILS rguard --run '!findmnt /mnt' * Allow shutdown if nothing mounted at mountpoint rguard --run '@some_cmd | some_other_cmd; another_cmd' * Allow shutdown only if last cmd in shell succeeds * When using '@', full shell syntax is supported * e.g.: '|', '&&', '||', ';', '>', '>>', '<', etc rguard --run '!@lsof -i:ssh | grep -q ESTABLISHED' * Allow shutdown only if shell commands FAIL * In this example, only if there are no established ssh connections