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"