From 5340e47e8135f6213fca9fb4fb9de4d7dc790518 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Sun, 19 Mar 2023 08:49:10 +0100 Subject: [PATCH] Flush .conf event queue before leaving boostrap Signed-off-by: Joachim Wiberg --- src/conf.c | 40 +++++++++++++++++++++++++++------------- src/finit.c | 3 +++ src/private.h | 1 + 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/conf.c b/src/conf.c index 5d9711c0..011eaf69 100644 --- a/src/conf.c +++ b/src/conf.c @@ -73,6 +73,7 @@ struct conf_change { }; static struct iwatch iw_conf; +static int iwatch_fd; static uev_t etcw; static TAILQ_HEAD(, conf_change) conf_change_list = TAILQ_HEAD_INITIALIZER(conf_change_list); @@ -1193,18 +1194,16 @@ int conf_changed(char *file) return rc; } -static void conf_cb(uev_t *w, void *arg, int events) +static int conf_iwatch_read(int fd) { static char ev_buf[8 *(sizeof(struct inotify_event) + NAME_MAX + 1) + 1]; struct inotify_event *ev; ssize_t sz; size_t off; - sz = read(w->fd, ev_buf, sizeof(ev_buf) - 1); - if (sz <= 0) { - err(1, "invalid inotify event"); - return; - } + sz = read(fd, ev_buf, sizeof(ev_buf) - 1); + if (sz <= 0) + return -1; ev_buf[sz] = 0; for (off = 0; off < (size_t)sz; off += sizeof(*ev) + ev->len) { @@ -1227,18 +1226,35 @@ static void conf_cb(uev_t *w, void *arg, int events) if (!iwp) continue; - if (do_change(iwp->path, ev->name, ev->mask)) { + if (conf_change_act(iwp->path, ev->name, ev->mask)) { err(1, " Out of memory"); break; } } + return 0; +} + +static void conf_cb(uev_t *w, void *arg, int events) +{ + if (conf_iwatch_read(w->fd)) { + err(1, "invalid inotify event"); + return; + } + + #ifdef AUTO_RELOAD if (conf_any_change()) service_reload_dynamic(); #endif } +void conf_flush_events(void) +{ + while (!conf_iwatch_read(iwatch_fd)) + dbg("emptying inotify queue ..."); +} + /* * Set up inotify watcher and load all *.conf in /etc/finit.d/ */ @@ -1279,8 +1295,6 @@ int conf_monitor(void) */ int conf_init(uev_ctx_t *ctx) { - int fd; - /* default hostname */ hostname = strdup(DEFHOST); @@ -1320,13 +1334,13 @@ int conf_init(uev_ctx_t *ctx) parse_conf(finit_conf, 0); /* prepare /etc watcher */ - fd = iwatch_init(&iw_conf); - if (fd < 0) + iwatch_fd = iwatch_init(&iw_conf); + if (iwatch_fd < 0) return 1; - if (uev_io_init(ctx, &etcw, conf_cb, NULL, fd, UEV_READ)) { + if (uev_io_init(ctx, &etcw, conf_cb, NULL, iwatch_fd, UEV_READ)) { err(1, "Failed setting up I/O callback for /etc watcher"); - close(fd); + close(iwatch_fd); return 1; } diff --git a/src/finit.c b/src/finit.c index 73b297e2..d9d881ed 100644 --- a/src/finit.c +++ b/src/finit.c @@ -612,6 +612,9 @@ static void bootstrap_worker(void *work) run_parts(runparts, NULL, NULL, 1); + dbg("Flushing pending .conf file events ..."); + conf_flush_events(); + /* * Start all tasks/services in the configured runlevel, or jump * into the runlevel selected from the command line. diff --git a/src/private.h b/src/private.h index 53a347c1..cfba4260 100644 --- a/src/private.h +++ b/src/private.h @@ -41,6 +41,7 @@ extern char *fsck_repair; int api_init (uev_ctx_t *ctx); int api_exit (void); +void conf_flush_events(void); void service_monitor (pid_t lost, int status); void service_notify_cb(uev_t *w, void *arg, int events);