How to detect pending system shutdown on Linux?

前端 未结 9 979
死守一世寂寞
死守一世寂寞 2020-12-05 14:37

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 o

相关标签:
9条回答
  • 2020-12-05 15:22

    The practical answer to do what you originally wanted is that you check for the shutdown process (e.g ps aux | grep "shutdown -h" ) and then, if you want to be sure you check it's command line arguments and time it was started (e.g. "shutdown -h +240" started at 14:51 will shutdown at 18:51).

    In the general case there is from the point of view of the entire system there is no way to do this. There are many different ways a "shutdown" can happen. For example someone can decide to pull the plug in order to hard stop a program that they now has bad/dangerous behaviour at shutdown time or a UPS could first send a SIGHUP and then simply fail. Since such a shutdown can happen suddenly and with no warning anywhere in a system there is no way to be sure that it's okay to keep running after a SIGHUP.

    If a process receives SIGHUP you should basically assume that something nastier will follow soon. If you want to do something special and partially ignore SIGHUP then a) you need to coordinate that with whatever program will do the shutdown and b) you need to be ready that if some other system does the shutdown and kills you dead soon after a SIGHUP your software and data will survive. Write out any data you have and only continue writing to append-only files with safe atomic updates.

    For your case I'm almost sure your current solution (treat all SIGHUPs as a shutdown) is the correct way to go. If you want to improve things, you should probably add a feature to the shutdown program which does a notify via DBUS or something similar.

    0 讨论(0)
  • 2020-12-05 15:23

    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.

    0 讨论(0)
  • 2020-12-05 15:26

    I think I got it.

    Source = https://github.com/mozilla-b2g/busybox/blob/master/miscutils/runlevel.c

    I copy part of the code here, just in case the reference disappears.

    #include "libbb.h"
    ...
    struct utmp *ut;
    char prev;
    
    if (argv[1]) utmpname(argv[1]);
    
    setutent();
    while ((ut = getutent()) != NULL) {
        if (ut->ut_type == RUN_LVL) {
            prev = ut->ut_pid / 256;
            if (prev == 0) prev = 'N';
            printf("Runlevel: prev=%c current=%c\n", prev, ut->ut_pid % 256);
            endutent();
            return 0;
        }
    }
    puts("unknown");
    
    0 讨论(0)
提交回复
热议问题