Files
finit/doc/config/service-sync.md
T
Joachim Wiberg b9ad9bcb21 doc: convert the documentation to the block format
The syntax overview no longer describes a line-based format, since that
is not what the rest of the documentation shows.  It now covers the
grammar, the two naming conventions, the nine aliases, and the leading
'-' on a path, and it says plainly that both formats are still read and
told apart per file by content.  Without that, a reader with an
existing configuration is left wondering what happened to it.

service-opts.md was a list of modifiers to place between a directive
and its command, so it needed rewriting rather than translating: there
are no positions left to describe.  It is now grouped by what the
settings do.

conditions.md needed correcting.  It presented '!' as a condition
prefix alongside '~'.  It is neither a condition nor a negation, it is
a flag on the block that means one thing on a service and another on a
run or task, so it is spelled reload-signal and required here, and the
page maps the old form to both.

Two things the pages claimed are not true.  The kill delay range is
1-300, not 1-60, and stop and reload scripts are no longer run without
a timeout.

ChangeLog.md keeps its line-based examples.  Those sit in historical
release entries, and rewriting them in a syntax that did not exist at
the time would misdate the format.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2026-07-30 15:21:31 +02:00

3.3 KiB

Service Synchronization

Finit was created for fast booting systems. Faster than a regular SysV Init based system at the time. Early on the need for a guaranteed start order of services (daemons) arose. I.e., service A must be guaranteed to have started (and be ready!) before B. The model that was chosen to determine this was very simple: PID files.

Early on in UNIX daemons were controlled with basic IPC like signals, and the way for a user to know that a daemon was ready to respond to signals (minimally having set up its signal handler), was to tell the user;

"Hey, you can send signals to me using the PID in this file: /var/run/daemon.pid".

Since most systems run fairly unchanged after boot, Finit could rely on the PID file for A being created before launching B. This method has worked well for a long time, and for systems based on Open Source it was easy to either add PID file support to a daemon without support for it, or fix ordering issues (PID file created before signal handler is set up) in existing daemons.

However, with the advent of other Init systems (Finit is rather old), most notably systemd and s6, other methods for signaling "readiness" arrived and daemons were adapted to these new schemes to a larger extent.

As of Finit v4.4 partial support for systemd and s6 style readiness notification is available, and the native PID file mode of operation is, as of Finit v4.6 optional, by default it is still enabled, but this can be changed in finit.conf:

readiness none

This will be made the default in Finit 5.0. In this mode of operation, every service needs to explicitly declare their readiness notification, like this:

service watchdogd { notify = "pid"      command = "watchdogd" }
service foo       { notify = "systemd"  command = "foo"       }
service bar       { notify = "s6"       command = "bar"       }
service qux       { notify = "none"     command = "qux"       }

The notify:none syntax is for completeness in systems which run in readiness pid mode (default). Services declared with notify:none will transition to ready as soon as Finit has started them, e.g., service/qux/ready.

To synchronize two services the following condition can be used:

service watchdogd {
    notify  = "pid"
    command = "watchdogd"
}

service stress-ng {
    conditions = { "service/watchdogd/ready" }
    command    = "stress-ng --cpu 8"
}

For details on the syntax and options, see below.

Note

On initctl reload conditions are set in "flux", while figuring out which services to stop, start or restart. Services that need to be restarted have their ready condition removed before Finit issue a SIGHUP (if they support that), or stop-starting them. A daemon is expected to reassert its readiness, e.g. systemd style daemons to write READY=1\n.

However, the s6 notify mode does not support this because in s6 you are expected to close your notify descriptor after having written \n. This means s6 style daemons currently must be stop-started. (Declare the service with <!> in its condition statement.)

For default, PID file style readiness notification, daemons are expected to either create their PID files, or touch it using utimensat() to reassert readiness. Triggering both the <pid/> and <.../ready> conditions.