conf: generate runtime .conf files in the block format

Finit's own generated services -- watchdogd, keventd, runparts, and
the dbus plugin -- still went through conf_save_service() as legacy
one-liners, so `initctl show keventd` taught the old format on a
system otherwise converted to the new one.

conf_save_service() now takes the block title and a printf-style body
and writes the file itself:

    # Generated by finit:conf_save_service()
    service keventd {
            description = "Finit kernel event daemon"
            runlevel    = "S12345789"
            notify      = "none"
            cgroup init {}
            command     = "/libexec/finit/keventd"
    }

vfprintf() into the file also removes the fixed-size staging buffers
in the callers, where a long dbus pidfile path could truncate inside
a quoted string and take the whole generated file with it.

Semantics preserved: watch-only pid:! maps to pidfile without
pidfile-create, the watchdog keeps its watchdog:finit identity, and
log:console becomes log { file = "/dev/console" }.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
Joachim Wiberg
2026-08-01 11:25:39 +02:00
parent 5aa7daf708
commit 9360c8e9b9
3 changed files with 45 additions and 21 deletions
+12 -8
View File
@@ -100,7 +100,7 @@ static void setup(void *arg)
{
char *group = DBUS_DAEMONGROUP;
char *user = DBUS_DAEMONUSER;
char line[256];
char pid[300];
char *pidfn;
mode_t prev;
char *cmd;
@@ -151,15 +151,19 @@ static void setup(void *arg)
* Register service with Finit
* Note: dbus drops privs after starting up.
*/
pid[0] = 0;
if (pidfn) {
snprintf(line, sizeof(line), "[S123456789] cgroup.system notify:none name:dbus pid:!%s %s %s -- %s",
pidfn, cmd, DBUS_ARGS, DBUS_DESC);
snprintf(pid, sizeof(pid), "\tpidfile = \"%s\"\n", pidfn);
free(pidfn);
} else
snprintf(line, sizeof(line), "[S123456789] cgroup.system notify:none name:dbus %s %s -- %s",
cmd, DBUS_ARGS, DBUS_DESC);
conf_save_service(SVC_TYPE_SERVICE, line, "dbus.conf");
}
conf_save_service(SVC_TYPE_SERVICE, "dbus", "dbus.conf",
"\tdescription = \"" DBUS_DESC "\"\n"
"\trunlevel = \"S123456789\"\n"
"\tnotify = \"none\"\n"
"\tcgroup system {}\n"
"%s"
"\tcommand = \"%s " DBUS_ARGS "\"\n",
pid, cmd);
free(cmd);
}
+31 -12
View File
@@ -43,6 +43,7 @@
#include "config.h" /* Generated by configure script */
#include <stdarg.h>
#include <string.h>
#include <sys/inotify.h>
#include <sys/resource.h>
@@ -664,11 +665,14 @@ done:
}
/*
* Called by plugins and similar that dynamically generate system services
* Called by plugins and similar that dynamically generate system
* services. @body holds the block contents, one indented line per
* setting.
*/
void conf_save_service(int type, char *cfg, char *file)
void conf_save_service(int type, const char *name, char *file, const char *fmt, ...)
{
char fn[256];
va_list ap;
svc_t foo;
FILE *fp;
@@ -684,7 +688,11 @@ void conf_save_service(int type, char *cfg, char *file)
foo.type = type;
fprintf(fp, "# Generated by finit:%s()\n", __func__);
fprintf(fp, "%s %s\n", svc_typestr(&foo), cfg);
fprintf(fp, "%s %s {\n", svc_typestr(&foo), name);
va_start(ap, fmt);
vfprintf(fp, fmt, ap);
va_end(ap);
fprintf(fp, "}\n");
fclose(fp);
}
@@ -2520,16 +2528,24 @@ 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 notify:none name:watchdog :finit "
FINIT_EXECPATH_ "/watchdogd -- Finit watchdog daemon", "watchdogd.conf");
conf_save_service(SVC_TYPE_SERVICE, "watchdog:finit", "watchdogd.conf",
"\tdescription = \"Finit watchdog daemon\"\n"
"\trunlevel = \"S0123456789\"\n"
"\tnotify = \"none\"\n"
"\tcgroup init {}\n"
"\tcommand = \"" FINIT_EXECPATH_ "/watchdogd\"\n");
}
#endif
/*
* Start kernel event daemon as soon as possible, if enabled
*/
if (whichp(FINIT_EXECPATH_ "/keventd"))
conf_save_service(SVC_TYPE_SERVICE, "[S12345789] cgroup.init notify:none "
FINIT_EXECPATH_ "/keventd -- Finit kernel event daemon", "keventd.conf");
conf_save_service(SVC_TYPE_SERVICE, "keventd", "keventd.conf",
"\tdescription = \"Finit kernel event daemon\"\n"
"\trunlevel = \"S12345789\"\n"
"\tnotify = \"none\"\n"
"\tcgroup init {}\n"
"\tcommand = \"" FINIT_EXECPATH_ "/keventd\"\n");
dbg("Allow plugins to register early runlevel 1 run/task/services ...");
plugin_run_hooks(HOOK_SVC_PLUGIN);
@@ -2552,7 +2568,6 @@ int conf_init(uev_ctx_t *ctx)
* Background startup scripts in the runparts directory, if any.
*/
if (runparts && fisdir(runparts) && !rescue) {
char conf[sizeof(_PATH_RUNPARTS) + strlen(runparts) + 100];
char args[10] = { 0 };
if (debug)
@@ -2562,10 +2577,14 @@ int conf_init(uev_ctx_t *ctx)
if (runparts_sysv)
strlcat(args, "-s ", sizeof(args));
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");
conf_save_service(SVC_TYPE_TASK, "runparts", "runparts.conf",
"\tdescription = \"Calling runparts %s in the background\"\n"
"\trunlevel = \"S\"\n"
"\tconditions = { \"int/bootstrap\" }\n"
"\tnotify = \"none\"\n"
"\tlog { file = \"/dev/console\" }\n"
"\tcommand = \"%s %s%s\"\n",
runparts, _PATH_RUNPARTS, args, runparts);
}
return 0;
+2 -1
View File
@@ -71,7 +71,8 @@ int conf_monitor (void);
void conf_saverc (void);
void conf_save_exec_order (svc_t *svc, char *cmdline, int result);
void conf_save_service (int type, char *cfg, char *file);
void conf_save_service (int type, const char *name, char *file, const char *fmt, ...)
__attribute__ ((format (printf, 4, 5)));
void conf_parse_cmdline (int argc, char *argv[]);
void conf_reset_env (void);