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
This commit is contained in:
parent
2eee4ca70d
commit
67279d16ee
@ -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. */
|
||||
@ -82,26 +78,6 @@ usage(void)
|
||||
errx(EX_USAGE, "[-dFh] [-c config] [-P pidfile]");
|
||||
}
|
||||
|
||||
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) {
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user