Major change, rename <svc/...> conditions to <pid/...> conditions

The <svc/foo> condition was created to synchronize starting services,
hence the abbreviation.  Example: the Quagga ripd needs to start after
the zebra daemon to ensure its UNIX domain socket is active, otherwise
events may be lost.

However, considering that synchronization was implemented with UNIX PID
files, e.g. waiting for /var/run/quagga/zebra.pid to be created, the
condition abbreviation name <svc/foo> was hard to understand by most
newcomers to Finit.  To make matters worse, a new feature to track or
even create PID files for services that don't create one themselves,
using the syntax 'pid:/path/to/foo.pid' was added.

Connecting the dots between these wasn't obvious.

This patch renames service conditions pid conditions and also adds
a compatibility wrapper to the Finit .conf parser.  Any condition
given in old .conf files with 'svc/' prefix are internally renamed
'pid/', along with a LOG_INFO notice in syslog.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
Joachim Wiberg committed 2021-02-09 22:07:03 +01:00
1 parent ff41868b59
commit a8b113185d
15 files changed
+43 -36

No files matched your search

+2 -2
View File
@@ -140,7 +140,7 @@ Here is another example where we instruct Finit to not start BusyBox
`ntpd` until `syslogd` has started properly. Finit waits for `syslogd` `ntpd` until `syslogd` has started properly. Finit waits for `syslogd`
to create its PID file, by default `/var/run/syslogd.pid`. to create its PID file, by default `/var/run/syslogd.pid`.
service [2345] log <svc/sbin/syslogd> /usr/sbin/ntpd -n -N -p pool.ntp.org service [2345] log <pid/sbin/syslogd> /usr/sbin/ntpd -n -N -p pool.ntp.org
service [S12345] /sbin/syslogd -n -- Syslog daemon service [S12345] /sbin/syslogd -n -- Syslog daemon
Notice the `log` keyword, BusyBox `ntpd` uses `stderr` for logging when Notice the `log` keyword, BusyBox `ntpd` uses `stderr` for logging when
@@ -150,7 +150,7 @@ to the system log daemon using the command line `logger(1)` tool.
A service, or task, can have multiple dependencies listed. Here we wait A service, or task, can have multiple dependencies listed. Here we wait
for *both* `syslogd` to have started and basic networking to be up: for *both* `syslogd` to have started and basic networking to be up:
service [2345] log <svc/sbin/syslogd,net/route/default> /usr/sbin/ntpd -n -N -p pool.ntp.org service [2345] log <pid/sbin/syslogd,net/route/default> /usr/sbin/ntpd -n -N -p pool.ntp.org
If either condition fails, e.g. loss of networking, `ntpd` is stopped If either condition fails, e.g. loss of networking, `ntpd` is stopped
and as soon as it comes back up again `ntpd` is restarted automatically. and as soon as it comes back up again `ntpd` is restarted automatically.
+1 -1
View File
@@ -1,3 +1,3 @@
# Handle PWR button to shutdown/reboot -- useful in Qemu (virt-manager) # Handle PWR button to shutdown/reboot -- useful in Qemu (virt-manager)
# Depends on syslogd having started. Redirect any output to log. # Depends on syslogd having started. Redirect any output to log.
service [2345] log <svc/syslogd> acpid -f -- ACPI daemon service [2345] log <pid/syslogd> acpid -f -- ACPI daemon
+1 -1
View File
@@ -1 +1 @@
service [2345] <svc/syslogd> crond -f -S -c /etc/crontabs -- Cron daemon service [2345] <pid/syslogd> crond -f -S -c /etc/crontabs -- Cron daemon
+1 -1
View File
@@ -1,2 +1,2 @@
# Start klogd as soon as possible, after syslogd, should always run # Start klogd as soon as possible, after syslogd, should always run
service [S12345] <svc/syslogd> klogd -n -- Kernel log daemon service [S12345] <pid/syslogd> klogd -n -- Kernel log daemon
+1 -1
View File
@@ -1,2 +1,2 @@
# Silly Busybox ntpd has no option to use syslog when running in foreground # Silly Busybox ntpd has no option to use syslog when running in foreground
service [2345] log <svc/syslogd> ntpd -n -N -p pool.ntp.org -- NTP daemon service [2345] log <pid/syslogd> ntpd -n -N -p pool.ntp.org -- NTP daemon
+1 -1
View File
@@ -1,3 +1,3 @@
# Handle PWR button to shutdown/reboot -- useful in Qemu (virt-manager) # Handle PWR button to shutdown/reboot -- useful in Qemu (virt-manager)
# Depends on rsyslogd having started. Redirect any output to log. # Depends on rsyslogd having started. Redirect any output to log.
service [2345] <svc/rsyslogd> log acpid -f -- ACPI daemon service [2345] <pid/rsyslogd> log acpid -f -- ACPI daemon
+1 -1
View File
@@ -1 +1 @@
service [2345] <svc/sbin/syslogd> /usr/sbin/crond -f -S -c /etc/crontabs -- Cron daemon service [2345] <pid/sbin/syslogd> /usr/sbin/crond -f -S -c /etc/crontabs -- Cron daemon
+1 -1
View File
@@ -1,2 +1,2 @@
# Start klogd as soon as possible, should always run # Start klogd as soon as possible, should always run
service [S12345] <svc/syslogd> klogd -n -- Kernel log daemon service [S12345] <pid/syslogd> klogd -n -- Kernel log daemon
+1 -1
View File
@@ -1,2 +1,2 @@
# Silly Busybox ntpd has no option to use syslog when running in foreground # Silly Busybox ntpd has no option to use syslog when running in foreground
service [2345] log <svc/syslogd> ntpd -n -N -p pool.ntp.org -- NTP daemon service [2345] log <pid/syslogd> ntpd -n -N -p pool.ntp.org -- NTP daemon
+10 -10
View File
@@ -31,11 +31,11 @@ service to run.
### Example ### Example
```shell ```shell
service [2345] <svc/sbin/setupd,svc/sbin/zebra> /sbin/netd -- Network monitor service [2345] <pid/sbin/setupd,pid/sbin/zebra> /sbin/netd -- Network monitor
``` ```
In this example the Network monitor daemon `netd` is not started until In this example the Network monitor daemon `netd` is not started until
both the `svc/sbin/setupd` *and* `svc/sbin/zebra` conditions are both the `pid/sbin/setupd` *and* `pid/sbin/zebra` conditions are
satisfied. An `svc` condition is satisfied by the corresponding satisfied. An `svc` condition is satisfied by the corresponding
service's PID file being created. service's PID file being created.
@@ -62,7 +62,7 @@ Built-in Conditions
Finit is distributed with a `pidfile` and `netlink` plugin. If enabled, Finit is distributed with a `pidfile` and `netlink` plugin. If enabled,
the `pidfile` plugin watches `/var/run/` for PID files created by the the `pidfile` plugin watches `/var/run/` for PID files created by the
monitored services, and sets a corresponding condition in the `svc/` monitored services, and sets a corresponding condition in the `pid/`
namespace. Similarily, the `netlink` plugin provides basic conditions namespace. Similarily, the `netlink` plugin provides basic conditions
for when an interface is brought up/down and when a default route for when an interface is brought up/down and when a default route
(gateway) is set, in the `net/` namespace. (gateway) is set, in the `net/` namespace.
@@ -81,7 +81,7 @@ file touched (re-created).
Built-in conditions: Built-in conditions:
- `svc/<PATH>` - `pid/<PATH>`
- `net/route/default` - `net/route/default`
- `net/<IFNAME>/exist` - `net/<IFNAME>/exist`
- `net/<IFNAME>/up` - `net/<IFNAME>/up`
@@ -95,16 +95,16 @@ Built-in conditions:
Composition Composition
----------- -----------
The `svc/` conditions can be quite tricky to understand. They are The `pid/` conditions can be quite tricky to understand. They are
generated by the Finit `pidfile.so` plugin and are composed from the generated by the Finit `pidfile.so` plugin and are composed from the
daemon's path and the pidfile name (and path). daemon's path and the pidfile name (and path).
| **service** | **pid:** | **pidfile path** | **svc condition** | | **service** | **pid:** | **pidfile path** | **svc condition** |
|--------------------------------------|-----------------|------------------|-------------------| |--------------------------------------|-----------------|------------------|-------------------|
| /sbin/foo | | /run/foo.pid | svc/sbin/foo | | /sbin/foo | | /run/foo.pid | pid/sbin/foo |
| /sbin/bar -p /run/baz.pid | pid:baz | /run/bas.pid | svc/sbin/baz | | /sbin/bar -p /run/baz.pid | pid:baz | /run/bas.pid | pid/sbin/baz |
| lxc-start -n foo -p /run/lxc/foo.pid | pid:lxc/foo.pid | /run/lxc/foo.pid | svc/lxc/foo | | lxc-start -n foo -p /run/lxc/foo.pid | pid:lxc/foo.pid | /run/lxc/foo.pid | pid/lxc/foo |
| /usr/bin/dbus-daemon | pid:dbus/pid | /run/dbus/pid | svc/usr/bin/dbus | | /usr/bin/dbus-daemon | pid:dbus/pid | /run/dbus/pid | pid/usr/bin/dbus |
Omitting the `pid:` to run/task/service/sysv stanza means Finit will Omitting the `pid:` to run/task/service/sysv stanza means Finit will
guess the pidfile path based on `/run/` and the basename(1) of the guess the pidfile path based on `/run/` and the basename(1) of the
@@ -128,7 +128,7 @@ conditions that are not satisfied. Listed as `off` below.
~ # initctl cond show ~ # initctl cond show
PID Service Status Condition (+ on, ~ flux, - off) PID Service Status Condition (+ on, ~ flux, - off)
=============================================================================== ===============================================================================
1419 /sbin/netd on <+svc/sbin/setupd,+svc/sbin/zebra> 1419 /sbin/netd on <+pid/sbin/setupd,+pid/sbin/zebra>
0 /sbin/udhcpc off <-net/vlan1/exist> 0 /sbin/udhcpc off <-net/vlan1/exist>
``` ```
+2 -2
View File
@@ -184,7 +184,7 @@ Syntax
from forking (daemonizing): from forking (daemonizing):
```shell ```shell
service [2345] <svc/sbin/zebra> /sbin/ospfd -- OSPF daemon service [2345] <pid/sbin/zebra> /sbin/ospfd -- OSPF daemon
``` ```
The `[2345]` is the runlevels `ospfd` is allowed to run in, they are The `[2345]` is the runlevels `ospfd` is allowed to run in, they are
@@ -206,7 +206,7 @@ Syntax
For example, by adding `pid:/run/foo.pid` to the service `/sbin/bar` For example, by adding `pid:/run/foo.pid` to the service `/sbin/bar`
that PID file will, not only be created and removed automatically, but that PID file will, not only be created and removed automatically, but
also be used by the Finit condition subsystem. So a service/run/task also be used by the Finit condition subsystem. So a service/run/task
can depend on `<svc/sbin/foo>`, notice the composition of conditions. can depend on `<pid/sbin/foo>`, notice the composition of conditions.
However, if a service `bar` *does* create a PID file, using `foo.pid`, However, if a service `bar` *does* create a PID file, using `foo.pid`,
we can inform Finit of this by prepending an `!`: we can inform Finit of this by prepending an `!`:
+1 -1
View File
@@ -323,7 +323,7 @@ static struct context pidfile_ctx;
* *
* service <net/iface/lo> /sbin/dropbear ... * service <net/iface/lo> /sbin/dropbear ...
* *
* Which provides the <svc/sbin/dropbear> condition, will not be * Which provides the <pid/sbin/dropbear> condition, will not be
* set by pidfile.so during `initctl reload` because dropbear is * set by pidfile.so during `initctl reload` because dropbear is
* still SIGSTP:ed waiting for <net/iface/lo>. * still SIGSTP:ed waiting for <net/iface/lo>.
*/ */
+14 -11
View File
@@ -32,28 +32,31 @@
#include "service.h" #include "service.h"
/* /*
* The service condition name is constructed from the 'svc/' prefix, the * The service condition name is constructed from the 'pid/' prefix,
* dirname of the svc->cmd, e.g., '/usr/bin/teamd' => 'usr/bin', and the * the dirname of the svc->cmd, e.g., '/usr/bin/teamd' => 'usr/bin', and
* service's pid:filename, including an optional subdirectory, without * the service's pid:filename, including an optional subdirectory,
* the .pid extension. * without the .pid extension.
* *
* The following example uses the team (aggregate) service: * The following example uses the team (aggregate) service:
* *
* service pid:!/run/teamd/a1.pid /usr/bin/teamd -f /etc/teamd/a1.conf * service pid:!/run/teamd/a1.pid /usr/bin/teamd -f /etc/teamd/a1.conf
* *
* => 'svc/' + 'usr/bin' + 'teamd/a1' => svc/usr/bin/teamd/a1 * => 'pid/' + 'usr/bin' + 'teamd/a1' => pid/usr/bin/teamd/a1
* *
* The next example uses the dbus-daemon: * The next example uses the dbus-daemon:
* *
* service pid:!/run/dbus/pid /usr/bin/dbus-daemon * service pid:!/run/dbus/pid /usr/bin/dbus-daemon
* *
* => 'svc/' + 'usr/bin' + 'dbus' => svc/usr/bin/dbus * => 'pid/' + 'usr/bin' + 'dbus' => pid/usr/bin/dbus
* *
* The last example uses lxc-start to start container foo: * The last example uses lxc-start to start container foo:
* *
* service pid:!/run/lxc/foo.pid lxc-start -n foo -F -p /run/lxc/foo.pid -- Container foo * service pid:!/run/lxc/foo.pid lxc-start -n foo -F -p /run/lxc/foo.pid -- Container foo
* *
* => 'svc/' + '' + 'lxc/foo' => svc/lxc/foo * => 'pid/' + '' + 'lxc/foo' => pid/lxc/foo
*
* Note: previously the condition ws called 'svc/..', the conf.c parser
* automatically translates to the 'pid/..' prefix and warns.
*/ */
char *mkcond(svc_t *svc, char *buf, size_t len) char *mkcond(svc_t *svc, char *buf, size_t len)
{ {
@@ -81,12 +84,12 @@ char *mkcond(svc_t *svc, char *buf, size_t len)
else else
ptr = rindex(pidfile, '/'); ptr = rindex(pidfile, '/');
/* Custom name:foo declaration found => svc/foo instead of /svc/bin/path/pidfile-.pid */ /* Custom name:foo declaration found => pid/foo instead of /pid/bin/path/pidfile-.pid */
if (strcmp(nm, svc->name)) { if (strcmp(nm, svc->name)) {
snprintf(buf, len, "svc/%s", svc->name); snprintf(buf, len, "pid/%s", svc->name);
_d("Composed condition from svc->name %s => %s", svc->name, buf); _d("Composed condition from svc->name %s => %s", svc->name, buf);
} else { } else {
snprintf(buf, len, "svc%s%s%s", path[0] != 0 && path[0] != '/' ? "/" : "", path, ptr); snprintf(buf, len, "pid%s%s%s", path[0] != 0 && path[0] != '/' ? "/" : "", path, ptr);
_d("Composed condition from cmd %s (path %s) and pidfile %s => %s", svc->cmd, path, ptr, buf); _d("Composed condition from cmd %s (path %s) and pidfile %s => %s", svc->cmd, path, ptr, buf);
} }
@@ -306,7 +309,7 @@ static int reassert(const char *fpath, const struct stat *sb, int tflg, struct F
/* /*
* Used only by netlink plugin atm. * Used only by netlink plugin atm.
* type: is a one of svc/, net/, etc. * type: is a one of pid/, net/, etc.
*/ */
void cond_reassert(const char *type) void cond_reassert(const char *type)
{ {
+5 -1
View File
@@ -236,7 +236,11 @@ void conf_parse_cond(svc_t *svc, char *cond)
return; return;
} }
strlcpy(svc->cond, ptr, sizeof(svc->cond)); if (!strncmp(ptr, "svc/", 4)) {
snprintf(svc->cond, sizeof(svc->cond), "pid/%s", &ptr[4]);
logit(LOG_INFO, "Migrating cond syntax of %s: %s -> %s", svc->cmd, ptr, svc->cond);
} else
strlcpy(svc->cond, ptr, sizeof(svc->cond));
} }
struct rlimit_name { struct rlimit_name {
+1 -1
View File
@@ -825,7 +825,7 @@ static void parse_cmdline_args(svc_t *svc, char *cmd)
* special case when a service is declared with <!> means it does not * special case when a service is declared with <!> means it does not
* support SIGHUP but must be STOP/START'ed at system reconfiguration. * support SIGHUP but must be STOP/START'ed at system reconfiguration.
* *
* Service conditions can be: svc/<PATH> for PID files, net/<IFNAME>/up * Service conditions can be: pid/<PATH> for PID files, net/<IFNAME>/up
* and net/<IFNAME>/exists. The condition handling is further described * and net/<IFNAME>/exists. The condition handling is further described
* in doc/conditions.md, but worth mentioning here is that the condition * in doc/conditions.md, but worth mentioning here is that the condition
* name itself can be modified using the :ID and name:foo syntax. * name itself can be modified using the :ID and name:foo syntax.