Add 'notify:pid' style readiness notifaction and 'readiness none'

This change expands the readiness notification system in Finit with the
native 'pid' style, which will remain the default readiness in Finit 4.x

For systems that want to transition to Finit 5.x early, a global option
to set 'readiness none' in /etc/finit.conf, has been added.  This change
the service default notification mode to 'notify:none', which can also
be set by Finit 4.x ('readiness pid') for select services.

Fixes #386.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
Joachim Wiberg committed 2023-11-12 19:07:12 +01:00
1 parent 6443995fc9
commit 0b5c555c7f
10 files changed
+88 -50

No files matched your search

+15 -3
View File
@@ -958,6 +958,18 @@ static int parse_static(char *line, int is_rcsd)
return 0;
}
/*
* Before Finit 5 the default readiness notification is PID.
* This default can be changed by setting 'readiness none' in
* the file /etc/finit.conf, only read once at bootstrap.
*/
if (BOOTSTRAP && MATCH_CMD(line, "readiness ", x)) {
char *token = strip_line(x);
if (!strcmp(token, "none"))
readiness = SVC_NOTIFY_NONE;
}
if (MATCH_CMD(line, "reboot-delay ", x)) {
syncsec = strtonum(strip_line(x), 0, 60, NULL);
return 0;
@@ -1579,7 +1591,7 @@ int conf_init(uev_ctx_t *ctx)
*/
#ifdef WDT_DEVNODE
if (whichp(FINIT_EXECPATH_ "/watchdogd") && fexist(WDT_DEVNODE)) {
conf_save_service(SVC_TYPE_SERVICE, "[S0123456789] cgroup.init name:watchdog :finit "
conf_save_service(SVC_TYPE_SERVICE, "[S0123456789] cgroup.init notify:none name:watchdog :finit "
FINIT_EXECPATH_ "/watchdogd -- Finit watchdog daemon", "watchdogd.conf");
}
#endif
@@ -1587,7 +1599,7 @@ int conf_init(uev_ctx_t *ctx)
* Start kernel event daemon as soon as possible, if enabled
*/
if (whichp(FINIT_EXECPATH_ "/keventd"))
conf_save_service(SVC_TYPE_SERVICE, "[S0123456789] cgroup.init "
conf_save_service(SVC_TYPE_SERVICE, "[S0123456789] cgroup.init notify:none "
FINIT_EXECPATH_ "/keventd -- Finit kernel event daemon", "keventd.conf");
dbg("Allow plugins to register early runlevel 1 run/task/services ...");
@@ -1621,7 +1633,7 @@ int conf_init(uev_ctx_t *ctx)
if (runparts_sysv)
strlcat(args, "-s ", sizeof(args));
snprintf(conf, sizeof(conf), "[S] <int/bootstrap> log:console %s %s %s"
snprintf(conf, sizeof(conf), "[S] <int/bootstrap> notify:none log:console %s %s %s"
" -- Calling runparts %s in the background",
_PATH_RUNPARTS, args, runparts, runparts);
conf_save_service(SVC_TYPE_TASK, conf, "runparts.conf");
+1
View File
@@ -69,6 +69,7 @@ int single = 0; /* single user mode from kernel cmdline */
int bootstrap = 1; /* set while bootrapping (for TTYs) */
int kerndebug = 0; /* set if /proc/sys/kernel/printk > 7 */
int syncsec = 0; /* reboot delay */
int readiness = SVC_NOTIFY_PID;
char *finit_conf= NULL;
char *finit_rcsd= NULL;
char *fstab = NULL;
+1
View File
@@ -121,6 +121,7 @@ extern int single;
extern int bootstrap;
extern int kerndebug;
extern int syncsec;
extern int readiness;
extern char *fstab;
extern char *sdown;
extern char *network;
+32 -30
View File
@@ -701,11 +701,12 @@ static int service_start(svc_t *svc)
wordexp_t we = { 0 };
int rc;
if (svc->notify) {
if (svc->notify == SVC_NOTIFY_SYSTEMD || svc->notify == SVC_NOTIFY_S6) {
if (client_command(INIT_CMD_NOTIFY_SOCKET)) {
err(1, "%s: failed creating notify socket", svc_ident(svc, NULL, 0));
client_disconnect();
svc->notify = 0; /* does not change parent, restarting may work. */
/* does not change parent, restarting may work. */
svc->notify = SVC_NOTIFY_NONE;
} else {
char val[20];
@@ -730,7 +731,7 @@ static int service_start(svc_t *svc)
if (len == 0)
break;
if (svc->notify) {
if (svc->notify == SVC_NOTIFY_SYSTEMD || svc->notify == SVC_NOTIFY_S6) {
char *ptr = strstr(arg, "%n");
if (ptr) {
@@ -907,6 +908,19 @@ static void service_kill(svc_t *svc)
print(2, NULL);
}
/* Ensure we don't have any notify socket lingering */
static void service_notify_stop(svc_t *svc)
{
if (svc->notify != SVC_NOTIFY_SYSTEMD && svc->notify != SVC_NOTIFY_S6)
return;
uev_io_stop(&svc->notify_watcher);
if (svc->notify_watcher.fd > 0) {
close(svc->notify_watcher.fd);
svc->notify_watcher.fd = 0;
}
}
/*
* Clean up any lingering state from dead/killed services
*/
@@ -922,12 +936,7 @@ static void service_cleanup(svc_t *svc)
logit(LOG_CRIT, "Failed removing service %s pidfile %s",
svc_ident(svc, NULL, 0), fn);
/* Ensure we don't have any notify socket lingering */
if (svc->notify && svc->notify_watcher.fd > 0) {
uev_io_stop(&svc->notify_watcher);
close(svc->notify_watcher.fd);
svc->notify_watcher.fd = 0;
}
service_notify_stop(svc);
/* No longer running, update books. */
if (svc_is_tty(svc) && svc->pid > 1)
@@ -1188,13 +1197,15 @@ static void parse_log(svc_t *svc, char *arg)
}
}
static int parse_notify(char *arg)
static svc_notify_t parse_notify(char *arg)
{
if (!strcmp(arg, "systemd"))
return 1;
return SVC_NOTIFY_SYSTEMD;
if (!strcmp(arg, "s6"))
return 2;
return 0; /* unsupported/disabled */
return SVC_NOTIFY_S6;
if (!strcmp(arg, "pid"))
return SVC_NOTIFY_PID;
return SVC_NOTIFY_NONE; /* unsupported/none */
}
static void parse_env(svc_t *svc, char *env)
@@ -1759,17 +1770,12 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
else
svc->log.enabled = 0;
}
if (notify) {
int type = parse_notify(notify);
if (type <= 0)
goto disable_notify;
svc->notify = type;
} else if (svc->notify) {
disable_notify:
/* XXX: close existing socket */
svc->notify = 0;
}
if (notify)
svc->notify = parse_notify(notify);
else
svc->notify = readiness;
if (desc)
strlcpy(svc->desc, desc, sizeof(svc->desc));
else if (type == SVC_TYPE_TTY)
@@ -2373,11 +2379,7 @@ restart:
char condstr[MAX_COND_LEN];
dbg("%s: stopped, cleaning up timers and conditions ...", svc_ident(svc, NULL, 0));
if (svc->notify && svc->notify_watcher.fd > 0) {
uev_io_stop(&svc->notify_watcher);
close(svc->notify_watcher.fd);
svc->notify_watcher.fd = 0;
}
service_notify_stop(svc);
service_timeout_cancel(svc);
cond_clear(mkcond(svc, condstr, sizeof(condstr)));
@@ -2686,7 +2688,7 @@ void service_notify_reconf(void)
svc_t *svc, *iter = NULL;
for (svc = svc_iterator(&iter, 1); svc; svc = svc_iterator(&iter, 0)) {
if (!svc->notify)
if (svc->notify == SVC_NOTIFY_PID)
continue; /* managed by pidfile plugin */
if (svc->state != SVC_RUNNING_STATE)
@@ -2739,7 +2741,7 @@ void service_notify_cb(uev_t *w, void *arg, int events)
service_ready(svc);
/* s6 applications close their socket after notification */
if (svc->notify == 2) {
if (svc->notify == SVC_NOTIFY_S6) {
uev_io_stop(w);
close(w->fd);
w->fd = 0;
+9 -1
View File
@@ -83,6 +83,14 @@ typedef enum {
SVC_ONCRASH_SCRIPT,
} svc_oncrash_action_t;
/* 0: none, 1: systemd, 2: s6 */
typedef enum {
SVC_NOTIFY_NONE = 0,
SVC_NOTIFY_PID,
SVC_NOTIFY_SYSTEMD,
SVC_NOTIFY_S6,
} svc_notify_t;
#define MAX_ID_LEN 16
#define MAX_ARG_LEN 64
#define MAX_CMD_LEN 256
@@ -202,7 +210,7 @@ typedef struct svc {
/*
* Readiness notification socket: systemd, s6
*/
int notify; /* 0: none, 1: systemd, 2: s6 */
svc_notify_t notify;
uev_t notify_watcher; /* i/o watcher */
/* time at svc_del(), used by gc timer */