2

With init one could point the ctrlaltdel action in inittab to any command, such as doing a delayed shutdown command. How can this be done with Systemd?

I sometimes work form the console and being forced on Windows at work I got used to hitting CTRL-ALT-DEL first thing when my monitor is blank - this does not have the desired effect on the linux console! Disabling it is easy but I'd still like the key to perform a graceful shutdown if something really bad happens and I cannot login.

1 Answer 1

1

In systemd, the CTRL-ALT-DEL key sequence triggers the ctrl-alt-del.target (which by default lives in the system path, /lib/systemd/system/ctrl-alt-del.target on Debian) and starts the systemd-reboot.service. It can be overridden by creating a local version, /etc/systemd/system/ctrl-alt-del.target. Creating it as an empty file effectively disables the key sequence.

One way to schedule the reboot in the future would be to have this target require a service (ex local-delayed-reboot.service - create the file in the same directory) and have this service configured as oneshot with ExecStart=shutdown -r <delay>.

What bugs me in this method is that we're going all over the place, ctrl-alt-del trigger a systemd service which calls a binary which send a dbus message back to systemd to schedule the shutdown (logind handles it...). I though it might be cleaner to actually keep starting the same target but only after executing a systemd timer. This is how I implemented it:

Create a warning service - this is to warn (using wall + tee console in case no one is logged in) that the reboot is going to happen. adjust the message - esp. the delay - as desired:

/etc/systemd/system/local-delay-reboot-warn.service

[Unit]
Description=Reboot Warning

[Service]
Type=oneshot
ExecStart=/bin/sh -c '/bin/echo -e "\aCTRL-ALT-DEL has been hit! Reboot in 60 seconds...\n\nTo abort:\n  systemctl stop ctrl-alt-del.target"|tee /dev/console|/usr/bin/wall'

Create a timer that starts the shutdown unit after specified time - the timer depends on the warning service so warning message is fired first (likewise, update the delay as desired):

/etc/systemd/system/local-delay-reboot.timer

[Unit]
Description=Reboot delay
DefaultDependencies=no
# Warn first...
Requires=local-delay-reboot-warn.service
After=local-delay-reboot-warn.service
# Make this timer stop if ctrl-alt-del.target is stopped
PartOf=ctrl-alt-del.target

[Timer]
OnActiveSec=60s
RemainAfterElapse=no
Unit=systemd-reboot.service
# Disable systemd's timer optimisations
AccuracySec=1us

[Install]
WantedBy=ctrl-alt-del.target

Finally override ctrl-alt-del.target with this:

/etc/systemd/system/ctrl-alt-del.target

# Custom reboot action 

[Unit]
Description=Reboot (delayed)
DefaultDependencies=no
Requires=local-delay-reboot-warn.service local-delay-reboot.timer
After=systemd-reboot.service
AllowIsolate=yes
JobTimeoutSec=30min
JobTimeoutAction=reboot-force

[Install]
Alias=ctrl-alt-del.target

After all I'm not sure it was really worth it but it was definitively educational in understanding how to use timers.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .