svn commit: r213009 - head/sbin/hastd

Pawel Jakub Dawidek pjd at FreeBSD.org
Wed Sep 22 19:08:11 UTC 2010


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.trociny at 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);


More information about the svn-src-all mailing list