From e0d3aa8e062ad7ce39fe979d4c583a34edd1764f Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Wed, 24 Feb 2021 12:27:46 +0100 Subject: [PATCH 1/5] iwatch: handle watching paths for same inode Signed-off-by: Joachim Wiberg --- src/iwatch.c | 4 ++-- src/iwatch.h | 11 +++++++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/iwatch.c b/src/iwatch.c index 48bedea1..ee241a66 100644 --- a/src/iwatch.c +++ b/src/iwatch.c @@ -48,7 +48,7 @@ int iwatch_init(struct iwatch *iw) iw->fd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC); if (iw->fd < 0) { - _pe("inotify_init()"); + _pe("Failed creating inotify descriptor"); return -1; } initialized = 1; @@ -90,7 +90,7 @@ int iwatch_add(struct iwatch *iw, char *file, uint32_t mask) wd = inotify_add_watch(iw->fd, path, IWATCH_MASK | mask); if (wd < 0) { - _pe("inotify_add_watch(%s)", path); + _pe("Failed adding watcher for %s", path); free(path); return -1; } diff --git a/src/iwatch.h b/src/iwatch.h index b59c3fb9..adff92a3 100644 --- a/src/iwatch.h +++ b/src/iwatch.h @@ -29,9 +29,16 @@ #include #include +#ifndef IN_MASK_CREATE +#define IN_MASK_CREATE 0x10000000 /* since Linux 4.18 */ +#endif -/* Monitors changes to both directories and files by default */ -#define IWATCH_MASK (IN_CREATE | IN_DELETE | IN_MODIFY | IN_ATTRIB | IN_MOVE) +/* + * Monitors changes to both directories and files by default, but only + * add watcher once (IN_MASK_CREATE) to avoid clobbering any already + * monitored paths. + */ +#define IWATCH_MASK (IN_CREATE | IN_DELETE | IN_MODIFY | IN_ATTRIB | IN_MOVE | IN_MASK_CREATE) struct iwatch_path { TAILQ_ENTRY(iwatch_path) link; From f906bb357a243ee297cf0c42c11b5704cd2e334e Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Wed, 24 Feb 2021 12:28:45 +0100 Subject: [PATCH 2/5] plugins: pidfile: only scan directory if watch added successfully Also, update condition example in comment. Signed-off-by: Joachim Wiberg --- plugins/pidfile.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/pidfile.c b/plugins/pidfile.c index e2a55023..b525952f 100644 --- a/plugins/pidfile.c +++ b/plugins/pidfile.c @@ -138,8 +138,8 @@ static void pidfile_handle_dir(struct iwatch *iw, char *dir, char *name, int mas if (mask & IN_CREATE) { if (!iwp) { - pidfile_add_path(iw, path); - pidfile_scandir(iw, path, sizeof(path)); + if (!pidfile_add_path(iw, path)) + pidfile_scandir(iw, path, sizeof(path)); } } else if (mask & IN_DELETE) { if (iwp) @@ -265,9 +265,9 @@ static void pidfile_init(void *arg) * * service /sbin/dropbear ... * - * Which provides the condition, will not be - * set by pidfile.so during `initctl reload` because dropbear is - * still SIGSTP:ed waiting for . + * Which provides the condition, will not be set by + * pidfile.so during `initctl reload` because dropbear is still + * SIGSTP:ed waiting for . */ static plugin_t plugin = { .name = __FILE__, From d27b3948aff9720d08f9348a0b9ac46820358afc Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Wed, 24 Feb 2021 22:00:41 +0100 Subject: [PATCH 3/5] Drop unnecessary and confusing debug message in mkcond() Signed-off-by: Joachim Wiberg --- src/cond-w.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/cond-w.c b/src/cond-w.c index d748e10a..d450c49a 100644 --- a/src/cond-w.c +++ b/src/cond-w.c @@ -71,7 +71,6 @@ char *mkcond(svc_t *svc, char *buf, size_t len) char ident[sizeof(svc->name) + sizeof(svc->id) + 2]; snprintf(buf, len, "pid/%s", svc_ident(svc, ident, sizeof(ident))); - _d("Created condition => %s", buf); return buf; } From 81d8f3cccc36fe90e4b4bacef39cc749a5e2b178 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Wed, 24 Feb 2021 22:02:27 +0100 Subject: [PATCH 4/5] Drop unnecessary service_step() in cond_reload() The cond_reload() fn is called on `initctl reload`, thus we don't need to call service_step(), since we call service_step_all() later in that cycle. So we can drop cond_update(NULL), which calls service_step(). Signed-off-by: Joachim Wiberg --- src/cond-w.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/cond-w.c b/src/cond-w.c index d450c49a..e5f7456e 100644 --- a/src/cond-w.c +++ b/src/cond-w.c @@ -242,7 +242,6 @@ void cond_reload(void) _d(""); cond_bump_reconf(); - cond_update(NULL); } static int reassert(const char *fpath, const struct stat *sb, int tflg, struct FTW *ftw) From 14f0443bd7e08720d16ccd92814fe200eb0770ea Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Wed, 24 Feb 2021 22:04:46 +0100 Subject: [PATCH 5/5] Allow services to be added *and removed* from /etc/finit.conf This patch fixes a long standing issue where removing a service from /etc/finit.conf does not stop and unregister it. The issue was caused by the Finit support for "protected" services, e.g. services created by plugins like hotplug.so To reproduce issue before this fix: cat /etc/finit.d/available/ntpd.conf >> /etc/finit.conf initctl reload The NTP service now runs smoothly, as expected. Later on, we decide to drop it from our system: sed -i 1,2d /etc/finit.conf initctl reload ... and the NTP service continues to run unaffected. Not what most sane users expect. Signed-off-by: Joachim Wiberg --- src/conf.c | 2 +- src/service.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/conf.c b/src/conf.c index 0b68aa7f..8cec98d7 100644 --- a/src/conf.c +++ b/src/conf.c @@ -626,7 +626,7 @@ static int parse_conf(char *file) _d("%s", line); parse_static(line); - parse_dynamic(line, global_rlimit, NULL); + parse_dynamic(line, global_rlimit, file); } fclose(fp); diff --git a/src/service.c b/src/service.c index 25452d60..eaa3d551 100644 --- a/src/service.c +++ b/src/service.c @@ -1107,6 +1107,7 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file) else svc_mark_clean(svc); + /* for finit native services only, e.g. plugins/hotplug.c */ if (!file) svc->protect = 1;