multipathd: Ensure that SIGINT, SIGTERM, SIGHUP and SIGUSR1 are delivered to the...
authorBart Van Assche <bart.vanassche@sandisk.com>
Wed, 27 Jul 2016 21:14:08 +0000 (14:14 -0700)
committerChristophe Varoqui <christophe.varoqui@opensvc.com>
Sun, 31 Jul 2016 09:01:55 +0000 (11:01 +0200)
The POSIX standard mentions that the only way to guarantee that signals
are delivered to a specific thread is:
* Block all signals before the first pthread_create() call.
* Unblock signals from the thread that should receive signals.

Implement that approach in multipathd. And since ppoll() can return 0
if interrupted, also call handle_signals() if ppoll() returns 0.

Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
multipathd/main.c
multipathd/uxlsnr.c

index 7d6d9b5..20589a7 100644 (file)
@@ -2124,11 +2124,8 @@ signal_init(void)
        sigset_t set;
 
        sigemptyset(&set);
-       sigaddset(&set, SIGHUP);
-       sigaddset(&set, SIGUSR1);
-       sigaddset(&set, SIGUSR2);
-       sigaddset(&set, SIGALRM);
-       pthread_sigmask(SIG_BLOCK, &set, NULL);
+       sigaddset(&set, SIGPIPE);
+       pthread_sigmask(SIG_SETMASK, &set, NULL);
 
        signal_set(SIGHUP, sighup);
        signal_set(SIGUSR1, sigusr1);
index d2ef0b8..f114e59 100644 (file)
@@ -150,9 +150,11 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, void * trigger_data)
                condlog(0, "uxsock: failed to allocate poll fds");
                return NULL;
        }
-       pthread_sigmask(SIG_SETMASK, NULL, &mask);
-       sigdelset(&mask, SIGHUP);
-       sigdelset(&mask, SIGUSR1);
+       sigemptyset(&mask);
+       sigaddset(&mask, SIGINT);
+       sigaddset(&mask, SIGTERM);
+       sigaddset(&mask, SIGHUP);
+       sigaddset(&mask, SIGUSR1);
        while (1) {
                struct client *c, *tmp;
                int i, poll_count, num_clients;
@@ -208,8 +210,10 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, void * trigger_data)
                        break;
                }
 
-               if (poll_count == 0)
+               if (poll_count == 0) {
+                       handle_signals();
                        continue;
+               }
 
                /* see if a client wants to speak to us */
                for (i = 1; i < num_clients + 1; i++) {