From c89f29692a2442b8ef9b654f4de37fd1c9d892d4 Mon Sep 17 00:00:00 2001 From: claudio Date: Thu, 8 Apr 2021 16:32:42 +0000 Subject: [PATCH] More cleanup of the main function. Use a loop to collect all childs with waitpid() and print if they exited non-zero or by a signal. Also adjust the poll hangup case to exit the poll loop instead of erroring out. This way a crashed child should be reported before exit. OK job@ tb@ --- usr.sbin/rpki-client/main.c | 94 +++++++++++++++++++------------------ 1 file changed, 49 insertions(+), 45 deletions(-) diff --git a/usr.sbin/rpki-client/main.c b/usr.sbin/rpki-client/main.c index d5fb95cad05..89578897de9 100644 --- a/usr.sbin/rpki-client/main.c +++ b/usr.sbin/rpki-client/main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: main.c,v 1.132 2021/04/08 15:31:14 claudio Exp $ */ +/* $OpenBSD: main.c,v 1.133 2021/04/08 16:32:42 claudio Exp $ */ /* * Copyright (c) 2019 Kristaps Dzonsons * @@ -538,7 +538,7 @@ entity_process(int proc, struct stats *st, struct vrp_tree *tree) st->gbrs++; break; default: - abort(); + errx(1, "unknown entity type"); } entity_queue--; @@ -580,7 +580,6 @@ void suicide(int sig __attribute__((unused))) { killme = 1; - } #define NPFD 4 @@ -588,10 +587,10 @@ suicide(int sig __attribute__((unused))) int main(int argc, char *argv[]) { - int rc = 1, c, st, proc, rsync, http, rrdp, ok, - fl = SOCK_STREAM | SOCK_CLOEXEC; + int rc, c, st, proc, rsync, http, rrdp, ok, + hangup = 0, fl = SOCK_STREAM | SOCK_CLOEXEC; size_t i, id, outsz = 0, talsz = 0; - pid_t procpid, rsyncpid, httppid, rrdppid; + pid_t pid, procpid, rsyncpid, httppid, rrdppid; int fd[2]; struct pollfd pfd[NPFD]; struct msgbuf *queues[NPFD]; @@ -599,7 +598,7 @@ main(int argc, char *argv[]) char *rsync_prog = "openrsync"; char *bind_addr = NULL; const char *cachedir = NULL, *outputdir = NULL; - const char *tals[TALSZ_MAX], *errs; + const char *tals[TALSZ_MAX], *errs, *name; struct vrp_tree v = RB_INITIALIZER(&v); struct rusage ru; struct timeval start_time, now_time; @@ -872,10 +871,10 @@ main(int argc, char *argv[]) * parsing process. */ - pfd[0].fd = rsync; - queues[0] = &rsyncq; - pfd[1].fd = proc; - queues[1] = &procq; + pfd[0].fd = proc; + queues[0] = &procq; + pfd[1].fd = rsync; + queues[1] = &rsyncq; pfd[2].fd = http; queues[2] = &httpq; pfd[3].fd = rrdp; @@ -910,8 +909,10 @@ main(int argc, char *argv[]) for (i = 0; i < NPFD; i++) { if (pfd[i].revents & (POLLERR|POLLNVAL)) errx(1, "poll[%zu]: bad fd", i); - if (pfd[i].revents & POLLHUP) - errx(1, "poll[%zu]: hangup", i); + if (pfd[i].revents & POLLHUP) { + warnx("poll[%zu]: hangup", i); + hangup = 1; + } if (pfd[i].revents & POLLOUT) { /* * XXX work around deadlocks because of @@ -930,7 +931,8 @@ main(int argc, char *argv[]) io_socket_blocking(pfd[i].fd); } } - + if (hangup) + break; /* * Check the rsync and http process. @@ -939,7 +941,7 @@ main(int argc, char *argv[]) * the parser process. */ - if ((pfd[0].revents & POLLIN)) { + if ((pfd[1].revents & POLLIN)) { io_simple_read(rsync, &id, sizeof(id)); io_simple_read(rsync, &ok, sizeof(ok)); rsync_finish(id, ok); @@ -1014,7 +1016,7 @@ main(int argc, char *argv[]) * Dequeue these one by one. */ - if ((pfd[1].revents & POLLIN)) { + if ((pfd[0].revents & POLLIN)) { entity_process(proc, &stats, &v); } } @@ -1025,10 +1027,6 @@ main(int argc, char *argv[]) errx(1, "excessive runtime (%d seconds), giving up", timeout); } - assert(entity_queue == 0); - logx("all files parsed: generating output"); - rc = 0; - /* * For clean-up, close the input for the parser and rsync * process. @@ -1040,37 +1038,43 @@ main(int argc, char *argv[]) close(http); close(rrdp); - if (waitpid(procpid, &st, 0) == -1) - err(1, "waitpid"); - if (!WIFEXITED(st) || WEXITSTATUS(st) != 0) { - warnx("parser process exited abnormally"); - rc = 1; - } - if (!noop) { - if (waitpid(rsyncpid, &st, 0) == -1) - err(1, "waitpid"); - if (!WIFEXITED(st) || WEXITSTATUS(st) != 0) { - warnx("rsync process exited abnormally"); - rc = 1; + rc = 0; + for (;;) { + pid = waitpid(WAIT_ANY, &st, 0); + if (pid == -1) { + if (errno == EINTR) + continue; + if (errno != ECHILD) + err(1, "wait"); + break; } - if (waitpid(httppid, &st, 0) == -1) - err(1, "waitpid"); - if (!WIFEXITED(st) || WEXITSTATUS(st) != 0) { - warnx("http process exited abnormally"); - rc = 1; - } + if (pid == procpid) + name = "parser"; + else if (pid == rsyncpid) + name = "rsync"; + else if (pid == httppid) + name = "http"; + else if (pid == rrdppid) + name = "rrdp"; + else + name = "unknown"; - if (rrdpon) { - if (waitpid(rrdppid, &st, 0) == -1) - err(1, "waitpid"); - if (!WIFEXITED(st) || WEXITSTATUS(st) != 0) { - warnx("rrdp process exited abnormally"); - rc = 1; - } + if (WIFSIGNALED(st)) { + warnx("%s terminated signal %d", name, WTERMSIG(st)); + rc = 1; + } else if (!WIFEXITED(st) || WEXITSTATUS(st) != 0) { + warnx("%s process exited abnormally", name); + rc = 1; } } + /* processing did not finish because of error */ + if (entity_queue != 0) + return 1; + + logx("all files parsed: generating output"); + repo_cleanup(&fpt); gettimeofday(&now_time, NULL); -- 2.20.1