diff --git a/configure.ac b/configure.ac index 6a1c7f85..c664e77e 100644 --- a/configure.ac +++ b/configure.ac @@ -109,6 +109,10 @@ AC_ARG_WITH(rc-local, AS_HELP_STRING([--with-rc-local=FILE], [SysV init /etc/rc.local file, default /etc/rc.local]), [rclocal=$withval], [rclocal=$sysconfdir/rc.local]) +AC_ARG_WITH(sysconfig, + AS_HELP_STRING([--with-sysconfig=DIR], [Enviroment config directory, default /etc/default]), + [sysconfig=$withval], [sysconfig=yes]) + AC_ARG_WITH(hostname, AS_HELP_STRING([--with-hostname=NAME], [If /etc/hostname is missing, default: noname]), [hostname=$withval], [hostname=noname]) @@ -165,6 +169,13 @@ AS_IF([test "x$with_rc_local" != "xno"], [ AC_EXPAND_DIR(rclocal_path, "$rclocal") AC_DEFINE_UNQUOTED(FINIT_RC_LOCAL, "$rclocal_path", [Compat SysV /etc/rc.local file to run last at boot.]) +AS_IF([test "x$with_sysconfig" != "xno"], [ + AS_IF([test "x$sysconfig" = "xyes"], [ + sysconfig=$sysconfdir/default + AC_EXPAND_DIR(sysconfig_path, "$sysconfig") + AC_DEFINE_UNQUOTED(FINIT_SYSCONFIG, "$sysconfig_path", + [System environment, default /etc/default])])]) + AS_IF([test "x$with_heading" != "xno"], [ AS_IF([test "x$heading" = "xyes"], [ heading="$PACKAGE_NAME v$PACKAGE_VERSION"])]) @@ -221,6 +232,7 @@ cat < examples in the `contrib/` directory, which can be used as a base. +Service Environment +------------------- + +Finit supports sourcing environment variables from `/etc/default/*`, or +similar `--with-sysconfig=DIR`. This is a common pattern from SysV init +scripts, where the start-stop script is a generic script for the given +service, `foo`, and the options for the service are sourced from the +file `/etc/default/foo`. Like this: + +* `/etc/default/foo`: + + FOO_OPTIONS=--extra-arg="bar" -s -x + +* `/etc/finit.conf`: + + service [2345] env:-/etc/default/foo foo -n $FOO_OPTIONS -- Example foo daemon + +Here the service `foo` is started with `-n`, to make sure it runs in the +foreground, and the with the options found in the environment file. With +the `ps` command we can see that the process is started with: + + foo -n --extra-arg=bar -s -x + +> **Note:** the leading `-` determines if Finit should treat a missing +> environment file as blocking the start of the service or not. When +> `-` is used, a missing environment file does *not* block the start. + + Service Wrapper Scripts ----------------------- diff --git a/src/conf.c b/src/conf.c index e866db7e..32c6b612 100644 --- a/src/conf.c +++ b/src/conf.c @@ -772,13 +772,13 @@ static void drop_changes(void) static int do_change(char *dir, char *name, uint32_t mask) { - char path[strlen(dir) + strlen(name) + 2]; + char fn[strlen(dir) + strlen(name) + 2]; struct conf_change *node; - snprintf(path, sizeof(path), "%s%s", dir, name); - _d("path: %s", path); + snprintf(fn, sizeof(fn), "%s%s%s", dir, fisslashdir(dir) ? "" : "/", name); + _d("path: %s mask: %08x", fn, mask); - node = conf_find(path); + node = conf_find(fn); if (mask & (IN_DELETE | IN_MOVED_FROM)) { drop_change(node); return 0; @@ -793,13 +793,13 @@ static int do_change(char *dir, char *name, uint32_t mask) if (!node) return 1; - node->name = strdup(path); + node->name = strdup(fn); if (!node->name) { free(node); return 1; } - _d("Event registered for %s, mask 0x%x", path, mask); + _d("Event registered for %s, mask 0x%x", fn, mask); TAILQ_INSERT_HEAD(&conf_change_list, node, link); return 0; @@ -881,6 +881,14 @@ int conf_monitor(void) rc += iwatch_add(&iw_conf, FINIT_RCSD "/enabled/", IN_ONLYDIR | IN_DONT_FOLLOW); rc += iwatch_add(&iw_conf, FINIT_CONF, 0); + /* + * Systems with /etc/default, or similar, can also monitor changes + * in env files sourced by .conf files (above) + */ +#ifdef FINIT_SYSCONFIG + rc += iwatch_add(&iw_conf, FINIT_SYSCONFIG, IN_ONLYDIR); +#endif + return rc + conf_reload(); } diff --git a/src/service.c b/src/service.c index 7ba261e4..116f1528 100644 --- a/src/service.c +++ b/src/service.c @@ -1116,7 +1116,7 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file) memcpy(svc->rlimit, rlimit, sizeof(svc->rlimit)); /* New, recently modified or unchanged ... used on reload. */ - if (file && conf_changed(file)) + if ((file && conf_changed(file)) || conf_changed(svc_getenv(svc))) svc_mark_dirty(svc); else svc_mark_clean(svc);