svn commit: r217784 - head/sbin/hastd

Pawel Jakub Dawidek pjd at FreeBSD.org
Mon Jan 24 15:04:16 UTC 2011


Author: pjd
Date: Mon Jan 24 15:04:15 2011
New Revision: 217784
URL: http://svn.freebsd.org/changeset/base/217784

Log:
  Don't open configuration file from worker process. Handle SIGHUP in the
  master process only and pass changes to the worker processes over control
  socket. This removes access to global namespace in preparation for capsicum
  sandboxing.
  
  MFC after:	2 weeks

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

Modified: head/sbin/hastd/control.c
==============================================================================
--- head/sbin/hastd/control.c	Mon Jan 24 14:53:53 2011	(r217783)
+++ head/sbin/hastd/control.c	Mon Jan 24 15:04:15 2011	(r217784)
@@ -411,7 +411,6 @@ ctrl_thread(void *arg)
 			nv_free(nvin);
 			continue;
 		}
-		nv_free(nvin);
 		nvout = nv_alloc();
 		switch (cmd) {
 		case HASTCTL_STATUS:
@@ -433,11 +432,23 @@ ctrl_thread(void *arg)
 				nv_add_uint32(nvout, (uint32_t)0, "keepdirty");
 				nv_add_uint64(nvout, (uint64_t)0, "dirty");
 			}
+			nv_add_int16(nvout, 0, "error");
+			break;
+		case HASTCTL_RELOAD:
+			/*
+			 * When parent receives SIGHUP and discovers that
+			 * something related to us has changes, it sends reload
+			 * message to us.
+			 */
+			assert(res->hr_role == HAST_ROLE_PRIMARY);
+			primary_config_reload(res, nvin);
+			nv_add_int16(nvout, 0, "error");
 			break;
 		default:
 			nv_add_int16(nvout, EINVAL, "error");
 			break;
 		}
+		nv_free(nvin);
 		if (nv_error(nvout) != 0) {
 			pjdlog_error("Unable to create answer on control message.");
 			nv_free(nvout);

Modified: head/sbin/hastd/control.h
==============================================================================
--- head/sbin/hastd/control.h	Mon Jan 24 14:53:53 2011	(r217783)
+++ head/sbin/hastd/control.h	Mon Jan 24 15:04:15 2011	(r217784)
@@ -34,6 +34,7 @@
 
 #define	HASTCTL_SET_ROLE	1
 #define	HASTCTL_STATUS		2
+#define	HASTCTL_RELOAD		3
 
 struct hastd_config;
 struct hast_resource;

Modified: head/sbin/hastd/hastd.c
==============================================================================
--- head/sbin/hastd/hastd.c	Mon Jan 24 14:53:53 2011	(r217783)
+++ head/sbin/hastd/hastd.c	Mon Jan 24 15:04:15 2011	(r217784)
@@ -205,6 +205,45 @@ resource_needs_reload(const struct hast_
 }
 
 static void
+resource_reload(const struct hast_resource *res)
+{
+	struct nv *nvin, *nvout;
+	int error;
+
+	assert(res->hr_role == HAST_ROLE_PRIMARY);
+
+	nvout = nv_alloc();
+	nv_add_uint8(nvout, HASTCTL_RELOAD, "cmd");
+	nv_add_string(nvout, res->hr_remoteaddr, "remoteaddr");
+	nv_add_int32(nvout, (int32_t)res->hr_replication, "replication");
+	nv_add_int32(nvout, (int32_t)res->hr_timeout, "timeout");
+	nv_add_string(nvout, res->hr_exec, "exec");
+	if (nv_error(nvout) != 0) {
+		nv_free(nvout);
+		pjdlog_error("Unable to allocate header for reload message.");
+		return;
+	}
+	if (hast_proto_send(res, res->hr_ctrl, nvout, NULL, 0) < 0) {
+		pjdlog_errno(LOG_ERR, "Unable to send reload message");
+		nv_free(nvout);
+		return;
+	}
+	nv_free(nvout);
+
+	/* Receive response. */
+	if (hast_proto_recv_hdr(res->hr_ctrl, &nvin) < 0) {
+		pjdlog_errno(LOG_ERR, "Unable to receive reload reply");
+		return;
+	}
+	error = nv_get_int16(nvin, "error");
+	nv_free(nvin);
+	if (error != 0) {
+		pjdlog_common(LOG_ERR, 0, error, "Reload failed");
+		return;
+	}
+}
+
+static void
 hastd_reload(void)
 {
 	struct hastd_config *newcfg;
@@ -338,13 +377,8 @@ hastd_reload(void)
 			cres->hr_timeout = nres->hr_timeout;
 			strlcpy(cres->hr_exec, nres->hr_exec,
 			    sizeof(cres->hr_exec));
-			if (cres->hr_workerpid != 0) {
-				if (kill(cres->hr_workerpid, SIGHUP) < 0) {
-					pjdlog_errno(LOG_WARNING,
-					    "Unable to send SIGHUP to worker process %u",
-					    (unsigned int)cres->hr_workerpid);
-				}
-			}
+			if (cres->hr_workerpid != 0)
+				resource_reload(cres);
 		}
 	}
 

Modified: head/sbin/hastd/hastd.h
==============================================================================
--- head/sbin/hastd/hastd.h	Mon Jan 24 14:53:53 2011	(r217783)
+++ head/sbin/hastd/hastd.h	Mon Jan 24 15:04:15 2011	(r217784)
@@ -46,4 +46,6 @@ extern struct pidfh *pfh;
 void hastd_primary(struct hast_resource *res);
 void hastd_secondary(struct hast_resource *res, struct nv *nvin);
 
+void primary_config_reload(struct hast_resource *res, struct nv *nv);
+
 #endif	/* !_HASTD_H_ */

Modified: head/sbin/hastd/primary.c
==============================================================================
--- head/sbin/hastd/primary.c	Mon Jan 24 14:53:53 2011	(r217783)
+++ head/sbin/hastd/primary.c	Mon Jan 24 15:04:15 2011	(r217784)
@@ -836,6 +836,7 @@ hastd_primary(struct hast_resource *res)
 	init_local(res);
 	init_ggate(res);
 	init_environment(res);
+
 	/*
 	 * Create the guard thread first, so we can handle signals from the
 	 * very begining.
@@ -1844,47 +1845,32 @@ free_queue:
 	return (NULL);
 }
 
-static void
-config_reload(void)
+void
+primary_config_reload(struct hast_resource *res, struct nv *nv)
 {
-	struct hastd_config *newcfg;
-	struct hast_resource *res;
 	unsigned int ii, ncomps;
-	int modified;
+	int modified, vint;
+	const char *vstr;
 
 	pjdlog_info("Reloading configuration...");
 
-	ncomps = HAST_NCOMPONENTS;
-
-	newcfg = yy_config_parse(cfgpath, false);
-	if (newcfg == NULL)
-		goto failed;
+	assert(res->hr_role == HAST_ROLE_PRIMARY);
+	assert(gres == res);
+	nv_assert(nv, "remoteaddr");
+	nv_assert(nv, "replication");
+	nv_assert(nv, "timeout");
+	nv_assert(nv, "exec");
 
-	TAILQ_FOREACH(res, &newcfg->hc_resources, hr_next) {
-		if (strcmp(res->hr_name, gres->hr_name) == 0)
-			break;
-	}
-	/*
-	 * If resource was removed from the configuration file, resource
-	 * name, provider name or path to local component was modified we
-	 * shouldn't be here. This means that someone modified configuration
-	 * file and send SIGHUP to us instead of main hastd process.
-	 * Log advice and ignore the signal.
-	 */
-	if (res == NULL || strcmp(gres->hr_name, res->hr_name) != 0 ||
-	    strcmp(gres->hr_provname, res->hr_provname) != 0 ||
-	    strcmp(gres->hr_localpath, res->hr_localpath) != 0) {
-		pjdlog_warning("To reload configuration send SIGHUP to the main hastd process (pid %u).",
-		    (unsigned int)getppid());
-		goto failed;
-	}
+	ncomps = HAST_NCOMPONENTS;
 
 #define MODIFIED_REMOTEADDR	0x1
 #define MODIFIED_REPLICATION	0x2
 #define MODIFIED_TIMEOUT	0x4
 #define MODIFIED_EXEC		0x8
 	modified = 0;
-	if (strcmp(gres->hr_remoteaddr, res->hr_remoteaddr) != 0) {
+
+	vstr = nv_get_string(nv, "remoteaddr");
+	if (strcmp(gres->hr_remoteaddr, vstr) != 0) {
 		/*
 		 * Don't copy res->hr_remoteaddr to gres just yet.
 		 * We want remote_close() to log disconnect from the old
@@ -1892,18 +1878,22 @@ config_reload(void)
 		 */
 		modified |= MODIFIED_REMOTEADDR;
 	}
-	if (gres->hr_replication != res->hr_replication) {
-		gres->hr_replication = res->hr_replication;
+	vint = nv_get_int32(nv, "replication");
+	if (gres->hr_replication != vint) {
+		gres->hr_replication = vint;
 		modified |= MODIFIED_REPLICATION;
 	}
-	if (gres->hr_timeout != res->hr_timeout) {
-		gres->hr_timeout = res->hr_timeout;
+	vint = nv_get_int32(nv, "timeout");
+	if (gres->hr_timeout != vint) {
+		gres->hr_timeout = vint;
 		modified |= MODIFIED_TIMEOUT;
 	}
-	if (strcmp(gres->hr_exec, res->hr_exec) != 0) {
-		strlcpy(gres->hr_exec, res->hr_exec, sizeof(gres->hr_exec));
+	vstr = nv_get_string(nv, "exec");
+	if (strcmp(gres->hr_exec, vstr) != 0) {
+		strlcpy(gres->hr_exec, vstr, sizeof(gres->hr_exec));
 		modified |= MODIFIED_EXEC;
 	}
+
 	/*
 	 * If only timeout was modified we only need to change it without
 	 * reconnecting.
@@ -1937,7 +1927,8 @@ config_reload(void)
 			remote_close(gres, ii);
 		}
 		if (modified & MODIFIED_REMOTEADDR) {
-			strlcpy(gres->hr_remoteaddr, res->hr_remoteaddr,
+			vstr = nv_get_string(nv, "remoteaddr");
+			strlcpy(gres->hr_remoteaddr, vstr,
 			    sizeof(gres->hr_remoteaddr));
 		}
 	}
@@ -1947,16 +1938,6 @@ config_reload(void)
 #undef	MODIFIED_EXEC
 
 	pjdlog_info("Configuration reloaded successfully.");
-	return;
-failed:
-	if (newcfg != NULL) {
-		if (newcfg->hc_controlconn != NULL)
-			proto_close(newcfg->hc_controlconn);
-		if (newcfg->hc_listenconn != NULL)
-			proto_close(newcfg->hc_listenconn);
-		yy_config_free(newcfg);
-	}
-	pjdlog_warning("Configuration not reloaded.");
 }
 
 static void
@@ -2032,7 +2013,6 @@ guard_thread(void *arg)
 	lastcheck = time(NULL);
 
 	PJDLOG_VERIFY(sigemptyset(&mask) == 0);
-	PJDLOG_VERIFY(sigaddset(&mask, SIGHUP) == 0);
 	PJDLOG_VERIFY(sigaddset(&mask, SIGINT) == 0);
 	PJDLOG_VERIFY(sigaddset(&mask, SIGTERM) == 0);
 
@@ -2042,9 +2022,6 @@ guard_thread(void *arg)
 
 	for (;;) {
 		switch (signo) {
-		case SIGHUP:
-			config_reload();
-			break;
 		case SIGINT:
 		case SIGTERM:
 			sigexit_received = true;


More information about the svn-src-all mailing list