Previously, all processes would shutdown on receiving SIGINT or SIGTERM.
When going down, the parent process would kill all the other process and
waitpid() them.
Now, only the parent process handles SIGTERM and SIGINT, other processes
ignore them. Upon receiving one of these signals, the parent process all
imsg sockets and waitpid() for the children. It fatal()s if one of the
imsg sockets is closed unexpectedly.
Other processes exit() "normally" when one of their imsg socket is closed
(except for client connection on the control socket of course). That's how
they are supposed to stop now. When doing so, they log as "debug" instead
of "info" because useless logs are useless.
This makes the shutdown sequence much saner.
Eric.
Index: ca.c
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/ca.c,v
retrieving revision 1.24
diff -u -p -r1.24 ca.c
--- ca.c 4 Sep 2016 16:10:31 -0000 1.24
+++ ca.c 6 Sep 2016 19:33:45 -0000
@@ -66,29 +66,14 @@ static uint64_t rsae_reqid = 0;
static void
ca_shutdown(void)
{
- log_info("info: ca agent exiting");
+ log_debug("debug: ca agent exiting");
_exit(0);
}
-static void
-ca_sig_handler(int sig, short event, void *p)
-{
- switch (sig) {
- case SIGINT:
- case SIGTERM:
- ca_shutdown();
- break;
- default:
- fatalx("ca_sig_handler: unexpected signal");
- }
-}
-
int
ca(void)
{
struct passwd *pw;
- struct event ev_sigint;
- struct event ev_sigterm;
purge_config(PURGE_LISTENERS|PURGE_TABLES|PURGE_RULES);
@@ -110,10 +95,8 @@ ca(void)
imsg_callback = ca_imsg;
event_init();
- signal_set(&ev_sigint, SIGINT, ca_sig_handler, NULL);
- signal_set(&ev_sigterm, SIGTERM, ca_sig_handler, NULL);
- signal_add(&ev_sigint, NULL);
- signal_add(&ev_sigterm, NULL);
+ signal(SIGINT, SIG_IGN);
+ signal(SIGTERM, SIG_IGN);
signal(SIGPIPE, SIG_IGN);
signal(SIGHUP, SIG_IGN);
@@ -242,6 +225,9 @@ ca_imsg(struct mproc *p, struct imsg *im
int ret = 0;
uint64_t id;
int v;
+
+ if (imsg == NULL)
+ ca_shutdown();
if (p->proc == PROC_PARENT) {
switch (imsg->hdr.type) {
Index: control.c
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/control.c,v
retrieving revision 1.116
diff -u -p -r1.116 control.c
--- control.c 4 Sep 2016 16:10:31 -0000 1.116
+++ control.c 6 Sep 2016 19:33:45 -0000
@@ -63,7 +63,6 @@ static void control_shutdown(void);
static void control_listen(void);
static void control_accept(int, short, void *);
static void control_close(struct ctl_conn *);
-static void control_sig_handler(int, short, void *);
static void control_dispatch_ext(struct mproc *, struct imsg *);
static void control_digest_update(const char *, size_t, int);
static void control_broadcast_verbose(int, int);
@@ -89,6 +88,12 @@ control_imsg(struct mproc *p, struct ims
const void *data;
size_t sz;
+ if (imsg == NULL) {
+ if (p->proc != PROC_CLIENT)
+ control_shutdown();
+ return;
+ }
+
if (p->proc == PROC_PONY) {
switch (imsg->hdr.type) {
case IMSG_CTL_SMTP_SESSION:
@@ -186,19 +191,6 @@ control_imsg(struct mproc *p, struct ims
imsg_to_str(imsg->hdr.type));
}
-static void
-control_sig_handler(int sig, short event, void *p)
-{
- switch (sig) {
- case SIGINT:
- case SIGTERM:
- control_shutdown();
- break;
- default:
- fatalx("control_sig_handler: unexpected signal");
- }
-}
-
int
control_create_socket(void)
{
@@ -245,8 +237,6 @@ int
control(void)
{
struct passwd *pw;
- struct event ev_sigint;
- struct event ev_sigterm;
purge_config(PURGE_EVERYTHING);
@@ -271,10 +261,8 @@ control(void)
imsg_callback = control_imsg;
event_init();
- signal_set(&ev_sigint, SIGINT, control_sig_handler, NULL);
- signal_set(&ev_sigterm, SIGTERM, control_sig_handler, NULL);
- signal_add(&ev_sigint, NULL);
- signal_add(&ev_sigterm, NULL);
+ signal(SIGINT, SIG_IGN);
+ signal(SIGTERM, SIG_IGN);
signal(SIGPIPE, SIG_IGN);
signal(SIGHUP, SIG_IGN);
@@ -305,7 +293,7 @@ control(void)
static void
control_shutdown(void)
{
- log_info("info: control process exiting");
+ log_debug("debug: control agent exiting");
_exit(0);
}
Index: lka.c
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/lka.c,v
retrieving revision 1.196
diff -u -p -r1.196 lka.c
--- lka.c 4 Sep 2016 16:10:31 -0000 1.196
+++ lka.c 6 Sep 2016 19:33:46 -0000
@@ -83,6 +83,9 @@ lka_imsg(struct mproc *p, struct imsg *i
uint64_t reqid;
int v;
+ if (imsg == NULL)
+ lka_shutdown();
+
if (imsg->hdr.type == IMSG_MTA_DNS_HOST ||
imsg->hdr.type == IMSG_MTA_DNS_PTR ||
imsg->hdr.type == IMSG_SMTP_DNS_PTR ||
@@ -383,10 +386,6 @@ lka_sig_handler(int sig, short event, vo
pid_t pid;
switch (sig) {
- case SIGINT:
- case SIGTERM:
- lka_shutdown();
- break;
case SIGCHLD:
do {
pid = waitpid(-1, &status, WNOHANG);
@@ -400,7 +399,7 @@ lka_sig_handler(int sig, short event, vo
void
lka_shutdown(void)
{
- log_info("info: lookup agent exiting");
+ log_debug("debug: lookup agent exiting");
_exit(0);
}
@@ -408,8 +407,6 @@ int
lka(void)
{
struct passwd *pw;
- struct event ev_sigint;
- struct event ev_sigterm;
struct event ev_sigchld;
purge_config(PURGE_LISTENERS);
@@ -427,12 +424,10 @@ lka(void)
imsg_callback = lka_imsg;
event_init();
- signal_set(&ev_sigint, SIGINT, lka_sig_handler, NULL);
- signal_set(&ev_sigterm, SIGTERM, lka_sig_handler, NULL);
signal_set(&ev_sigchld, SIGCHLD, lka_sig_handler, NULL);
- signal_add(&ev_sigint, NULL);
- signal_add(&ev_sigterm, NULL);
signal_add(&ev_sigchld, NULL);
+ signal(SIGINT, SIG_IGN);
+ signal(SIGTERM, SIG_IGN);
signal(SIGPIPE, SIG_IGN);
signal(SIGHUP, SIG_IGN);
Index: mproc.c
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/mproc.c,v
retrieving revision 1.26
diff -u -p -r1.26 mproc.c
--- mproc.c 3 Sep 2016 16:06:26 -0000 1.26
+++ mproc.c 6 Sep 2016 19:33:46 -0000
@@ -88,6 +88,8 @@ mproc_init(struct mproc *p, int fd)
void
mproc_clear(struct mproc *p)
{
+ log_debug("debug: clearing p=%s, fd=%d, pid=%d", p->name,
p->imsgbuf.fd, p->pid);
+
event_del(&p->ev);
close(p->imsgbuf.fd);
imsg_clear(&p->imsgbuf);
@@ -166,10 +168,8 @@ mproc_dispatch(int fd, short event, void
/* NOTREACHED */
case 0:
/* this pipe is dead, so remove the event handler */
- if (smtpd_process != PROC_CONTROL ||
- p->proc != PROC_CLIENT)
- log_warnx("warn: %s -> %s: pipe closed",
- proc_name(smtpd_process), p->name);
+ log_debug("debug: %s -> %s: pipe closed",
+ proc_name(smtpd_process), p->name);
p->handler(p, NULL);
return;
default:
@@ -181,10 +181,8 @@ mproc_dispatch(int fd, short event, void
n = msgbuf_write(&p->imsgbuf.w);
if (n == 0 || (n == -1 && errno != EAGAIN)) {
/* this pipe is dead, so remove the event handler */
- if (smtpd_process != PROC_CONTROL ||
- p->proc != PROC_CLIENT)
- log_warnx("warn: %s -> %s: pipe closed",
- proc_name(smtpd_process), p->name);
+ log_debug("debug: %s -> %s: pipe closed",
+ proc_name(smtpd_process), p->name);
p->handler(p, NULL);
return;
}
Index: pony.c
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/pony.c,v
retrieving revision 1.15
diff -u -p -r1.15 pony.c
--- pony.c 4 Sep 2016 16:10:31 -0000 1.15
+++ pony.c 6 Sep 2016 19:33:46 -0000
@@ -46,7 +46,6 @@ void mta_imsg(struct mproc *, struct ims
void smtp_imsg(struct mproc *, struct imsg *);
static void pony_shutdown(void);
-static void pony_sig_handler(int, short, void *);
void
pony_imsg(struct mproc *p, struct imsg *imsg)
@@ -54,6 +53,9 @@ pony_imsg(struct mproc *p, struct imsg *
struct msg m;
int v;
+ if (imsg == NULL)
+ pony_shutdown();
+
switch (imsg->hdr.type) {
case IMSG_CONF_START:
return;
@@ -132,22 +134,9 @@ pony_imsg(struct mproc *p, struct imsg *
}
static void
-pony_sig_handler(int sig, short event, void *p)
-{
- switch (sig) {
- case SIGINT:
- case SIGTERM:
- pony_shutdown();
- break;
- default:
- fatalx("pony_sig_handler: unexpected signal");
- }
-}
-
-static void
pony_shutdown(void)
{
- log_info("info: pony agent exiting");
+ log_debug("debug: pony agent exiting");
_exit(0);
}
@@ -155,8 +144,6 @@ int
pony(void)
{
struct passwd *pw;
- struct event ev_sigint;
- struct event ev_sigterm;
mda_postfork();
mta_postfork();
@@ -191,10 +178,8 @@ pony(void)
mta_postprivdrop();
smtp_postprivdrop();
- signal_set(&ev_sigint, SIGINT, pony_sig_handler, NULL);
- signal_set(&ev_sigterm, SIGTERM, pony_sig_handler, NULL);
- signal_add(&ev_sigint, NULL);
- signal_add(&ev_sigterm, NULL);
+ signal(SIGINT, SIG_IGN);
+ signal(SIGTERM, SIG_IGN);
signal(SIGPIPE, SIG_IGN);
signal(SIGHUP, SIG_IGN);
Index: queue.c
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/queue.c,v
retrieving revision 1.181
diff -u -p -r1.181 queue.c
--- queue.c 4 Sep 2016 16:10:31 -0000 1.181
+++ queue.c 6 Sep 2016 19:33:47 -0000
@@ -45,7 +45,6 @@ static void queue_imsg(struct mproc *, s
static void queue_timeout(int, short, void *);
static void queue_bounce(struct envelope *, struct delivery_bounce *);
static void queue_shutdown(void);
-static void queue_sig_handler(int, short, void *);
static void queue_log(const struct envelope *, const char *, const char *);
static void queue_msgid_walk(int, short, void *);
@@ -66,6 +65,9 @@ queue_imsg(struct mproc *p, struct imsg
size_t n_evp;
int fd, mta_ext, ret, v, flags, code;
+ if (imsg == NULL)
+ queue_shutdown();
+
memset(&bounce, 0, sizeof(struct delivery_bounce));
if (p->proc == PROC_PONY) {
@@ -636,22 +638,9 @@ queue_bounce(struct envelope *e, struct
}
static void
-queue_sig_handler(int sig, short event, void *p)
-{
- switch (sig) {
- case SIGINT:
- case SIGTERM:
- queue_shutdown();
- break;
- default:
- fatalx("queue_sig_handler: unexpected signal");
- }
-}
-
-static void
queue_shutdown(void)
{
- log_info("info: queue handler exiting");
+ log_debug("debug: queue agent exiting");
queue_close();
_exit(0);
}
@@ -662,8 +651,6 @@ queue(void)
struct passwd *pw;
struct timeval tv;
struct event ev_qload;
- struct event ev_sigint;
- struct event ev_sigterm;
purge_config(PURGE_EVERYTHING);
@@ -698,10 +685,8 @@ queue(void)
imsg_callback = queue_imsg;
event_init();
- signal_set(&ev_sigint, SIGINT, queue_sig_handler, NULL);
- signal_set(&ev_sigterm, SIGTERM, queue_sig_handler, NULL);
- signal_add(&ev_sigint, NULL);
- signal_add(&ev_sigterm, NULL);
+ signal(SIGINT, SIG_IGN);
+ signal(SIGTERM, SIG_IGN);
signal(SIGPIPE, SIG_IGN);
signal(SIGHUP, SIG_IGN);
Index: scheduler.c
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/scheduler.c,v
retrieving revision 1.54
diff -u -p -r1.54 scheduler.c
--- scheduler.c 4 Sep 2016 16:10:31 -0000 1.54
+++ scheduler.c 6 Sep 2016 19:33:47 -0000
@@ -47,7 +47,6 @@
static void scheduler_imsg(struct mproc *, struct imsg *);
static void scheduler_shutdown(void);
-static void scheduler_sig_handler(int, short, void *);
static void scheduler_reset_events(void);
static void scheduler_timeout(int, short, void *);
@@ -75,6 +74,9 @@ scheduler_imsg(struct mproc *p, struct i
time_t timestamp;
int v, r, type;
+ if (imsg == NULL)
+ scheduler_shutdown();
+
switch (imsg->hdr.type) {
case IMSG_QUEUE_ENVELOPE_SUBMIT:
@@ -404,22 +406,9 @@ scheduler_imsg(struct mproc *p, struct i
}
static void
-scheduler_sig_handler(int sig, short event, void *p)
-{
- switch (sig) {
- case SIGINT:
- case SIGTERM:
- scheduler_shutdown();
- break;
- default:
- fatalx("scheduler_sig_handler: unexpected signal");
- }
-}
-
-static void
scheduler_shutdown(void)
{
- log_info("info: scheduler handler exiting");
+ log_debug("debug: scheduler agent exiting");
_exit(0);
}
@@ -438,8 +427,6 @@ int
scheduler(void)
{
struct passwd *pw;
- struct event ev_sigint;
- struct event ev_sigterm;
backend = scheduler_backend_lookup(backend_scheduler);
if (backend == NULL)
@@ -473,10 +460,8 @@ scheduler(void)
imsg_callback = scheduler_imsg;
event_init();
- signal_set(&ev_sigint, SIGINT, scheduler_sig_handler, NULL);
- signal_set(&ev_sigterm, SIGTERM, scheduler_sig_handler, NULL);
- signal_add(&ev_sigint, NULL);
- signal_add(&ev_sigterm, NULL);
+ signal(SIGINT, SIG_IGN);
+ signal(SIGTERM, SIG_IGN);
signal(SIGPIPE, SIG_IGN);
signal(SIGHUP, SIG_IGN);
Index: smtpd.c
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/smtpd.c,v
retrieving revision 1.285
diff -u -p -r1.285 smtpd.c
--- smtpd.c 6 Sep 2016 16:34:29 -0000 1.285
+++ smtpd.c 6 Sep 2016 19:33:48 -0000
@@ -60,7 +60,7 @@
static void parent_imsg(struct mproc *, struct imsg *);
static void usage(void);
static int smtpd(void);
-static void parent_shutdown(int);
+static void parent_shutdown(void);
static void parent_send_config(int, short, void *);
static void parent_send_config_lka(void);
static void parent_send_config_pony(void);
@@ -162,8 +162,8 @@ parent_imsg(struct mproc *p, struct imsg
int fd, n, v, ret;
if (imsg == NULL)
- exit(1);
-
+ fatalx("process %s socket closed", p->name);
+
if (p->proc == PROC_LKA) {
switch (imsg->hdr.type) {
case IMSG_LKA_OPEN_FORWARD:
@@ -275,16 +275,16 @@ usage(void)
}
static void
-parent_shutdown(int ret)
+parent_shutdown(void)
{
- void *iter;
- struct child *child;
- pid_t pid;
+ pid_t pid;
- iter = NULL;
- while (tree_iter(&children, &iter, NULL, (void**)&child))
- if (child->type == CHILD_DAEMON)
- kill(child->pid, SIGTERM);
+ mproc_clear(p_ca);
+ mproc_clear(p_pony);
+ mproc_clear(p_control);
+ mproc_clear(p_lka);
+ mproc_clear(p_scheduler);
+ mproc_clear(p_queue);
do {
pid = waitpid(WAIT_MYPGRP, NULL, 0);
@@ -292,8 +292,8 @@ parent_shutdown(int ret)
unlink(SMTPD_SOCKET);
- log_warnx("warn: parent terminating");
- exit(ret);
+ log_info("Exiting");
+ exit(0);
}
static void
@@ -333,16 +333,17 @@ static void
parent_sig_handler(int sig, short event, void *p)
{
struct child *child;
- int die = 0, die_gracefully = 0, status, fail;
+ int status, fail;
pid_t pid;
char *cause;
switch (sig) {
case SIGTERM:
case SIGINT:
- log_info("info: %s, shutting down", strsignal(sig));
- die_gracefully = 1;
- /* FALLTHROUGH */
+ log_debug("debug: got signal %d", sig);
+ parent_shutdown();
+ /* NOT REACHED */
+
case SIGCHLD:
do {
int len;
@@ -379,7 +380,6 @@ parent_sig_handler(int sig, short event,
switch (child->type) {
case CHILD_DAEMON:
- die = 1;
if (fail)
log_warnx("warn: lost child: %s %s",
child->title, cause);
@@ -434,10 +434,6 @@ parent_sig_handler(int sig, short event,
free(cause);
} while (pid > 0 || (pid == -1 && errno == EINTR));
- if (die)
- parent_shutdown(1);
- else if (die_gracefully)
- parent_shutdown(0);
break;
default:
fatalx("smtpd: unexpected signal");
@@ -1597,7 +1593,7 @@ imsg_dispatch(struct mproc *p, struct im
int msg;
if (imsg == NULL) {
- exit(1);
+ imsg_callback(p, imsg);
return;
}