How to detect pending system shutdown on Linux?
Solution 1
There is no way to determine if a SIGTERM
is a part of a shutdown sequence. To detect a shutdown sequence you can either use use rc.d
scripts like ereOn and Eric Sepanson suggested or use mechanisms like DBus.
However, from a design point of view it makes no sense to ignore SIGTERM
even if it is not part of a shutdown. SIGTERM
's primary purpose is to politely ask apps to exit cleanly and it is not likely that someone with enough privileges will issue a SIGTERM
if he/she does not want the app to exit.
Solution 2
Maybe a little bit late. Yes, you can determine if a SIGTERM is in a shutting down process by invoking the runlevel command. Example:
#!/bin/bash
trap "runlevel >$HOME/run-level; exit 1" term
read line
echo "Input: $line"
save it as, say, term.sh
and run it. By executing killall term.sh
, you should able to see and investigate the run-level
file in your home directory. By executing any of the following:
sudo reboot
sudo halt -p
sudo shutdown -P
and compare the difference in the file. Then you should have the idea on how to do it.
Solution 3
From man shutdown:
If the time argument is used, 5 minutes before the system goes down the
/etc/nologin
file is created to ensure that further logins shall not be allowed.
So you can test existence of /etc/nologin
. It is not optimal, but probably best you can get.
Solution 4
Its a little bit of a hack but if the server is running systemd if you can run
/bin/systemctl list-jobs shutdown.target
... it will report ...
JOB UNIT TYPE STATE
755 shutdown.target start waiting <---- existence means shutting down
1 jobs listed.
... if the server is shutting down or rebooting ( hint: there's a reboot.target if you want to look specifically for that )
You will get No jobs running.
if its not being shutdown.
You have to parse the output which is a bit messy as the systemctl doesnt return a different exit code for the two results. But it does seem reasonably reliable. You will need to watch out for a format change in the messages if you update the system however.
Solution 5
see man systemctl
, you can determine if the system is shutting down like this:
if [ "`systemctl is-system-running`" = "stopping" ]; then
# Do what you need
fi
this is in bash, but you can do it with 'system' in C
341008
Updated on August 06, 2022Comments
-
341008 almost 2 years
I am working on an application where I need to detect a system shutdown. However, I have not found any reliable way get a notification on this event.
I know that on shutdown, my app will receive a
SIGTERM
signal followed by aSIGKILL
. I want to know if there is any way to query if aSIGTERM
is part of a shutdown sequence?Does any one know if there is a way to query that programmatically (C API)?
As far as I know, the system does not provide any other method to query for an impending shutdown. If it does, that would solve my problem as well. I have been trying out
runlevels
as well, but change inrunlevels
seem to be instantaneous and without any prior warnings.