Author: pjd
Date: Wed Sep 22 19:08:11 2010
New Revision: 213009
URL: http://svn.freebsd.org/changeset/base/213009

Log:
  Switch to sigprocmask(2) API also in the main process and secondary process.
  This way the primary process inherits signal mask from the main process,
  which fixes a race where signal is delivered to the primary process before
  configuring signal mask.
  
  Reported by:  Mikolaj Golub <to.my.troc...@gmail.com>
  MFC after:    3 days

Modified:
  head/sbin/hastd/hastd.c
  head/sbin/hastd/hastd.h
  head/sbin/hastd/primary.c
  head/sbin/hastd/secondary.c

Modified: head/sbin/hastd/hastd.c
==============================================================================
--- head/sbin/hastd/hastd.c     Wed Sep 22 19:05:54 2010        (r213008)
+++ head/sbin/hastd/hastd.c     Wed Sep 22 19:08:11 2010        (r213009)
@@ -63,10 +63,6 @@ __FBSDID("$FreeBSD$");
 const char *cfgpath = HAST_CONFIG;
 /* Hastd configuration. */
 static struct hastd_config *cfg;
-/* Was SIGCHLD signal received? */
-bool sigchld_received = false;
-/* Was SIGHUP signal received? */
-bool sighup_received = false;
 /* Was SIGINT or SIGTERM signal received? */
 bool sigexit_received = false;
 /* PID file handle. */
@@ -83,26 +79,6 @@ usage(void)
 }
 
 static void
-sighandler(int sig)
-{
-
-       switch (sig) {
-       case SIGINT:
-       case SIGTERM:
-               sigexit_received = true;
-               break;
-       case SIGCHLD:
-               sigchld_received = true;
-               break;
-       case SIGHUP:
-               sighup_received = true;
-               break;
-       default:
-               assert(!"invalid condition");
-       }
-}
-
-static void
 g_gate_load(void)
 {
 
@@ -625,26 +601,41 @@ static void
 main_loop(void)
 {
        struct hast_resource *res;
-       struct timeval timeout;
-       int fd, maxfd, ret;
+       struct timeval seltimeout;
+       struct timespec sigtimeout;
+       int fd, maxfd, ret, signo;
+       sigset_t mask;
        fd_set rfds;
 
-       timeout.tv_sec = REPORT_INTERVAL;
-       timeout.tv_usec = 0;
+       seltimeout.tv_sec = REPORT_INTERVAL;
+       seltimeout.tv_usec = 0;
+       sigtimeout.tv_sec = 0;
+       sigtimeout.tv_nsec = 0;
+
+       PJDLOG_VERIFY(sigemptyset(&mask) == 0);
+       PJDLOG_VERIFY(sigaddset(&mask, SIGHUP) == 0);
+       PJDLOG_VERIFY(sigaddset(&mask, SIGINT) == 0);
+       PJDLOG_VERIFY(sigaddset(&mask, SIGTERM) == 0);
+       PJDLOG_VERIFY(sigaddset(&mask, SIGCHLD) == 0);
 
        for (;;) {
-               if (sigexit_received) {
-                       sigexit_received = false;
-                       terminate_workers();
-                       exit(EX_OK);
-               }
-               if (sigchld_received) {
-                       sigchld_received = false;
-                       child_exit();
-               }
-               if (sighup_received) {
-                       sighup_received = false;
-                       hastd_reload();
+               while ((signo = sigtimedwait(&mask, NULL, &sigtimeout)) != -1) {
+                       switch (signo) {
+                       case SIGINT:
+                       case SIGTERM:
+                               sigexit_received = true;
+                               terminate_workers();
+                               exit(EX_OK);
+                               break;
+                       case SIGCHLD:
+                               child_exit();
+                               break;
+                       case SIGHUP:
+                               hastd_reload();
+                               break;
+                       default:
+                               assert(!"invalid condition");
+                       }
                }
 
                /* Setup descriptors for select(2). */
@@ -666,7 +657,7 @@ main_loop(void)
                }
 
                assert(maxfd + 1 <= (int)FD_SETSIZE);
-               ret = select(maxfd + 1, &rfds, NULL, NULL, &timeout);
+               ret = select(maxfd + 1, &rfds, NULL, NULL, &seltimeout);
                if (ret == 0)
                        hook_check(false);
                else if (ret == -1) {
@@ -701,6 +692,7 @@ main(int argc, char *argv[])
        pid_t otherpid;
        bool foreground;
        int debuglevel;
+       sigset_t mask;
 
        g_gate_load();
 
@@ -751,10 +743,12 @@ main(int argc, char *argv[])
        cfg = yy_config_parse(cfgpath, true);
        assert(cfg != NULL);
 
-       signal(SIGINT, sighandler);
-       signal(SIGTERM, sighandler);
-       signal(SIGHUP, sighandler);
-       signal(SIGCHLD, sighandler);
+       PJDLOG_VERIFY(sigemptyset(&mask) == 0);
+       PJDLOG_VERIFY(sigaddset(&mask, SIGHUP) == 0);
+       PJDLOG_VERIFY(sigaddset(&mask, SIGINT) == 0);
+       PJDLOG_VERIFY(sigaddset(&mask, SIGTERM) == 0);
+       PJDLOG_VERIFY(sigaddset(&mask, SIGCHLD) == 0);
+       PJDLOG_VERIFY(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
 
        /* Listen on control address. */
        if (proto_server(cfg->hc_controladdr, &cfg->hc_controlconn) < 0) {

Modified: head/sbin/hastd/hastd.h
==============================================================================
--- head/sbin/hastd/hastd.h     Wed Sep 22 19:05:54 2010        (r213008)
+++ head/sbin/hastd/hastd.h     Wed Sep 22 19:08:11 2010        (r213009)
@@ -40,7 +40,7 @@
 #include "hast.h"
 
 extern const char *cfgpath;
-extern bool sigchld_received, sigexit_received, sighup_received;
+extern bool sigexit_received;
 extern struct pidfh *pfh;
 
 void hastd_primary(struct hast_resource *res);

Modified: head/sbin/hastd/primary.c
==============================================================================
--- head/sbin/hastd/primary.c   Wed Sep 22 19:05:54 2010        (r213008)
+++ head/sbin/hastd/primary.c   Wed Sep 22 19:08:11 2010        (r213009)
@@ -313,7 +313,6 @@ init_environment(struct hast_resource *r
 {
        struct hio *hio;
        unsigned int ii, ncomps;
-       sigset_t mask;
 
        /*
         * In the future it might be per-resource value.
@@ -420,15 +419,6 @@ init_environment(struct hast_resource *r
                hio->hio_ggio.gctl_error = 0;
                TAILQ_INSERT_HEAD(&hio_free_list, hio, hio_free_next);
        }
-
-       /*
-        * Turn on signals handling.
-        */
-       PJDLOG_VERIFY(sigemptyset(&mask) == 0);
-       PJDLOG_VERIFY(sigaddset(&mask, SIGHUP) == 0);
-       PJDLOG_VERIFY(sigaddset(&mask, SIGINT) == 0);
-       PJDLOG_VERIFY(sigaddset(&mask, SIGTERM) == 0);
-       PJDLOG_VERIFY(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
 }
 
 static void
@@ -800,9 +790,6 @@ hastd_primary(struct hast_resource *res)
 
        setproctitle("%s (primary)", res->hr_name);
 
-       signal(SIGHUP, SIG_DFL);
-       signal(SIGCHLD, SIG_DFL);
-
        /* Declare that we are sender. */
        proto_send(res->hr_event, NULL, 0);
 

Modified: head/sbin/hastd/secondary.c
==============================================================================
--- head/sbin/hastd/secondary.c Wed Sep 22 19:05:54 2010        (r213008)
+++ head/sbin/hastd/secondary.c Wed Sep 22 19:08:11 2010        (r213009)
@@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$");
 #include <fcntl.h>
 #include <libgeom.h>
 #include <pthread.h>
+#include <signal.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <string.h>
@@ -334,6 +335,7 @@ init_remote(struct hast_resource *res, s
 void
 hastd_secondary(struct hast_resource *res, struct nv *nvin)
 {
+       sigset_t mask;
        pthread_t td;
        pid_t pid;
        int error;
@@ -380,8 +382,8 @@ hastd_secondary(struct hast_resource *re
 
        setproctitle("%s (secondary)", res->hr_name);
 
-       signal(SIGHUP, SIG_DFL);
-       signal(SIGCHLD, SIG_DFL);
+       PJDLOG_VERIFY(sigemptyset(&mask) == 0);
+       PJDLOG_VERIFY(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
 
        /* Declare that we are sender. */
        proto_send(res->hr_event, NULL, 0);
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to