summaryrefslogtreecommitdiffstats
path: root/sbin
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2010-09-22 19:08:11 +0000
committerpjd <pjd@FreeBSD.org>2010-09-22 19:08:11 +0000
commit67279d16ee319cb5904e06282acb094216407755 (patch)
treebacc321cf8b67b3b710a5e41960ab926cee818ab /sbin
parent2eee4ca70d37cd47c54a9641d8bd574f33579200 (diff)
downloadFreeBSD-src-67279d16ee319cb5904e06282acb094216407755.zip
FreeBSD-src-67279d16ee319cb5904e06282acb094216407755.tar.gz
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@gmail.com> MFC after: 3 days
Diffstat (limited to 'sbin')
-rw-r--r--sbin/hastd/hastd.c84
-rw-r--r--sbin/hastd/hastd.h2
-rw-r--r--sbin/hastd/primary.c13
-rw-r--r--sbin/hastd/secondary.c6
4 files changed, 44 insertions, 61 deletions
diff --git a/sbin/hastd/hastd.c b/sbin/hastd/hastd.c
index 651730d..e47b19d 100644
--- a/sbin/hastd/hastd.c
+++ b/sbin/hastd/hastd.c
@@ -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) {
diff --git a/sbin/hastd/hastd.h b/sbin/hastd/hastd.h
index a32e512..0186e81 100644
--- a/sbin/hastd/hastd.h
+++ b/sbin/hastd/hastd.h
@@ -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);
diff --git a/sbin/hastd/primary.c b/sbin/hastd/primary.c
index 5d6896e..d99bfd7 100644
--- a/sbin/hastd/primary.c
+++ b/sbin/hastd/primary.c
@@ -313,7 +313,6 @@ init_environment(struct hast_resource *res __unused)
{
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 *res __unused)
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);
diff --git a/sbin/hastd/secondary.c b/sbin/hastd/secondary.c
index 9e1e537..403c5b2 100644
--- a/sbin/hastd/secondary.c
+++ b/sbin/hastd/secondary.c
@@ -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, struct nv *nvin)
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 *res, struct nv *nvin)
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);
OpenPOWER on IntegriCloud