How to restart C daemon program on Linux after receiving a SIGHUP signal

Someone can send some sample code on how I can re-read the configuration file and restart my daemon after the daemon receives a SIGHUP signal. A daemon is a user space program written in C on Linux and not run by inetd.

+7
c linux daemon
source share
4 answers

Depending on how much your program is written, there are (at least) three ways to do this:

  • When a signal is received, return to the beginning of the program before the initialization phase (possibly, but not necessarily) using the setjmp () / longjmp () or sigsetjmp () / siglongjmp ()) pair., Thus reloading and re-reading the configuration file.

  • When a signal is received, the signal handler again executes the original program. It makes sense to lose all state and reset all global variables and static variables back to their original state. This has the disadvantage of losing the entire previous state.

  • The third option is less violent, perhaps; he would have noticed that the signal was received and at the next convenient point in the main processing cycle he would return and re-read the configuration file.

This partly depends on what your demon should do. If he spends time talking with his clients, you may not want to use either option 1 or 2 - you would prefer to use option 3. If you make one-time answers to simple questions, cruel approaches can be (and probably easier for programming). Please note that in option 1, careful WIP processing (incomplete work) and such things as open files are required - if you are not careful, you will lose resources and the daemon will fail (from memory, from file descriptors - most likely, one of these two).

+5
source share

I found this page because I myself was looking for an example to make sure that I am doing this correctly. Since there is no example for this, I will post my attempt and let others comment on this:

volatile sig_atomic_t g_eflag = 0; volatile sig_atomic_t g_hupflag = 1; static void signal_handler(int sig) { switch(sig) { case SIGHUP: g_hupflag = 1; break; case SIGINT: case SIGTERM: g_eflag = 1; break; } } int main(int argc, char **argv) { signal(SIGINT, signal_handler); signal(SIGTERM, signal_handler); signal(SIGHUP, signal_handler); signal(SIGPIPE, SIG_IGN); while(!g_eflag) { if(g_hupflag) { g_hupflag = 0; load_config(); } // ... do daemon work ... } return 0; } 
+1
source share
+1
source share

Depends on how you structure it; if you process several connections in one thread / process, then you must somehow notify them of the exit (if you can, it depends on the protocol) before reloading the configuration (or exec itself).

If the protocol allows you to say "leave and return later", then it is clear that this is a good victory. If clients must remain connected, you can apply configuration changes to already connected clients, if it is a daemon of one process and one thread, if that makes sense.

If it's a multiprocessor, things get more complicated. You will need to notify the processes of the new configuration, or make sure that they continue with the old configuration, or that they can select the new configuration when their client shuts down.

If it is a multi-threaded thread, the threads would have to safely read the new configuration in the middle of what they were doing, which might require locking, or you could allocate memory for the new configuration and perform the switch somehow,

0
source share

All Articles