Changeset 2e99039


Ignore:
Timestamp:
2015-10-30T10:31:09Z (4 years ago)
Author:
dequis <dx@…>
Branches:
master
Children:
9516bb6
Parents:
ad8a810
git-author:
dequis <dx@…> (27-10-15 06:07:02)
git-committer:
dequis <dx@…> (30-10-15 10:31:09)
Message:

Avoid propagating shutdown signal to all subprocesses

This was a sort-of-regression with 7233f68

While this behavior might seem desirable in some cases, multi-user
installs like public servers would rather not kill children while
upgrading.

Turns out that pipes are inherited by forks, and writing in one side
means there might be more than one listener that calls
bitlbee_shutdown(). If the parent gets it, the children will get it
too. If a child gets it, the parent and the other children get it too.

This adds a sighandler_shutdown_setup() function that closes any
previously existing pipes and disconnects the events from them, to
create a new one. This is called again after forking each child process.

While I'm sure this fixes the issue, I still don't understand why it
*didn't* kill the forked processes in some cases. Worrying.

Files:
3 edited

Legend:

Unmodified
Added
Removed
  • bitlbee.c

    rad8a810 r2e99039  
    311311                        b_event_remove(global.listen_watch_source_id);
    312312
     313                        /* Make a new pipe for the shutdown signal handler */
     314                        sighandler_shutdown_setup();
     315
    313316                        /* Make the connection. */
    314317                        irc = irc_new(new_socket);
  • bitlbee.h

    rad8a810 r2e99039  
    158158} global_t;
    159159
     160void sighandler_shutdown_setup(void);
     161
    160162int bitlbee_daemon_init(void);
    161163int bitlbee_inetd_init(void);
  • unix.c

    rad8a810 r2e99039  
    4848global_t global;        /* Against global namespace pollution */
    4949
    50 static int signal_shutdown_pipe[2] = { -1, -1 };
     50static struct {
     51        int fd[2];
     52        int tag;
     53} shutdown_pipe = {{-1 , -1}, 0};
     54
    5155static void sighandler_shutdown(int signal);
    5256static void sighandler_crash(int signal);
     
    156160        sigaction(SIGSEGV, &sig, &old);
    157161
    158         /* Use a pipe for SIGTERM/SIGINT so the actual signal handler doesn't do anything unsafe */
    159         if (pipe(signal_shutdown_pipe) == 0) {
    160                 b_input_add(signal_shutdown_pipe[0], B_EV_IO_READ, bitlbee_shutdown, NULL);
    161                 sig.sa_handler = sighandler_shutdown;
    162                 sigaction(SIGINT, &sig, &old);
    163                 sigaction(SIGTERM, &sig, &old);
    164         }
     162        sighandler_shutdown_setup();
     163
     164        sig.sa_handler = sighandler_shutdown;
     165        sigaction(SIGINT, &sig, &old);
     166        sigaction(SIGTERM, &sig, &old);
    165167
    166168        if (!getuid() || !geteuid()) {
     
    256258}
    257259
     260/* Set up a pipe for SIGTERM/SIGINT so the actual signal handler doesn't do anything unsafe */
     261void sighandler_shutdown_setup()
     262{
     263        if (shutdown_pipe.fd[0] != -1) {
     264                /* called again from a forked process, clean up to avoid propagating the signal */
     265                b_event_remove(shutdown_pipe.tag);
     266                close(shutdown_pipe.fd[0]);
     267                close(shutdown_pipe.fd[1]);
     268        }
     269
     270        if (pipe(shutdown_pipe.fd) == 0) {
     271                shutdown_pipe.tag = b_input_add(shutdown_pipe.fd[0], B_EV_IO_READ, bitlbee_shutdown, NULL);
     272        }
     273}
     274
    258275/* Signal handler for SIGTERM and SIGINT */
    259276static void sighandler_shutdown(int signal)
     
    261278        /* Write a single null byte to the pipe, just to send a message to the main loop.
    262279         * This gets handled by bitlbee_shutdown (the b_input_add callback for this pipe) */
    263         write(signal_shutdown_pipe[1], "", 1);
     280        write(shutdown_pipe.fd[1], "", 1);
    264281}
    265282
Note: See TracChangeset for help on using the changeset viewer.