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