On Tue, Sep 06, 2016 at 11:31:04PM +0200, Eric Faurot wrote: > 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. >
ok > 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; > } > > -- Gilles Chehade https://www.poolp.org @poolpOrg