The accepted standard in Unix is to report successful executions with
exitcode 0. Therefore, map a "initctl cond get" of a condition to the
following exitcodes:
- On: 0
- Off: 1
- Flux: 255
Fixes: c3c662fe64 ("initctl: ensure 'cond get' support flux state")
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
As it turns out, not all buses in Linux will add `modalias` attributes
to their devices in sysfs. One notable exception are MDIO buses. The
plugin's scan routine would thus not pick them up.
Fortunately, the information is always available in the device's
`uevent` attribute.
Therefore, default to looking for modaliases in the device's `uevent`
attribute instead, falling back to `modalias` only if `uevent` is not
availble (this should never happen).
Since the modprobe plugin (unsurpricingly) may cause new modules to be
loaded, it makes sense to to delay the initial device node scan until
we know that no mode nodes will show up within the next few
microseconds.
Add a plugin that will allow the user to trigger the execution of
scripts from plugin hook points. This is particularly useful for early
boot debugging that needs to take place before regular services are
available.
For example, let's say that you want to enable some kernel tracing
before modules are loaded. With hook-scripts, you can just drop in a
shell script in /libexec/finit/hook/mount/all/ that will poke the
right control files in tracefs.
The contents of /etc/finit.conf and friends could potentially change
after mounting /etc/fstab. If, for example, /etc was to be re-mounted
from ro to rw using an overlay filesystem, we want any user changes to
the configuration to take effect.
Instead of heuristically trying to determine the correct hotplug
daemon to use (mdev/udev), defer to the user to specify it in the
configuration. Same goes for the built-in watchdog.
Traditionally, Finit has setup _some_ filesystems that are Nice To
Have (tm), using options that do the Right Thing (tm).
On the one hand, this is very convenient for users that don't
necessarily know what a reasonable mode= value is for /tmp etc. (pun
intended). It also means that mountpoints can be created if they
don't exist.
On the other hand it means that all users are forced to submit to the
choices made by Finit. Also, different filesystems where spread out
at many different points in `main()`, meaning that the fact that
`/proc` was available at a given hook point did not imply that `/sys`
was, for example.
Instead, defer _all_ filesystem setup to the user by simply calling
`mount -a`. We then ship an example `fstab` that shows how to
re-create the old behavior.
As a precaution, services who are being stopped are automatically sent
a SIGKILL after 3 seconds if they refuse to go away willingly.
Unfortunately this backup mechanism was also enabled for inetd
services which are not backed by a real process. When the service was
freed the timer was not stopped, since it was not expected to be
armed. The timer would then trigger, causing a use-after-free on the
timer watcher containing a bogus callback pointer.
TIL, using mtimes for tracking event orderings is a monumentally bad
idea (queue the nodding UNIX-beards). Mtimes are in wallclock time which
is not necessarily monotonically increasing. A user may adjust the time,
an NTP daemon will continously tune the clock and so on.
Instead, store an explicit generation number in each condition file,
which will be monotonically increased by finit on each reconf.
Add support for registering callbacks to be called after a given
timeout.
Use this to implement forceful termination of services that refuse to
terminate upon receiving a SIGTERM. If the service PID is not collected
within 3 seconds, send a SIGKILL to it.
Also, rework restarting of crashing services. When a service crashes for
the first time, try to restart it immediately. If it crashes again, wait
a few seconds before trying again. Just as before, if it continues to
crash, block the service.
Add support for changing the initial hard and soft resource limits for
finit and any processes it launches.
See /etc/finit.conf section in README.md for more information.
Flush any existing filter rules when a configuration file is
updated. Otherwise filters are simply appended to the old
configuration which can cause finit to accept connections on
interfaces that are blocked in the new configuration.
When a service's condition transitions to `flux`, put it in the
waiting state, even if it does not support SIGHUP. That way, if the
condition returns to `on` we can simply SIGCONT it. If it goes to
`off` it will still be stop/started as before.
When reloading dynamic services, inetd services deleted marker was not
being cleaned. This caused finit to stop and start all inetd services
at every other reload.
This patch introduces a new service type called SVC_TYPE_INETD_CONN,
which represents a running inetd connection. These are handled in much
the same way as tasks. I.e. they are considered one-time jobs, with
the difference that they are removed upon completion.
When cleaning up removed services, the assumption was made that if a
service was not 'removed', it was 'clean'. In reality, it could also
be 'updated', which was then overwritten, causing services not being
restarted. Don't do that.
As a future precaution, make the dirty field const, only allowing
updates from accessor methods.
During documentation of the state machine, some theoretical problems
where discovered that could have lead finit to spawn a new instance of
a daemon before the previous one had been collected.
Now a service will always go through the STOPPING state when leaving
RUNNING. This ensures that the PID has been collected before any calls
to service_start.
...documenting your work is, apparently, not a bad idea. :)
Old event system has been replaced with a more generic condition
concept. The idea is that finit plugins may provide arbitrary
conditions that services may specify as dependencies that they require
to run.
In order to accomodate this, the service management has been
redesigned to use a state machine.
Parser would erroneously interpret an event specification containing
slashes as an inet service/proto specification.
E.g. "<net/gw>" was interpreted as port "<net" using protocol "gw>".
After forking off a new child, all signals that are blocked by finit
should be unblocked before exec-ing the final binary. Also, finit now
blocks SIGHUP, so add it to the set of signals that should be
unblocked.
Check return code from `mount -na`, if there where any errors give
plugins a chance to do something about it.
Signed-off-by: Tobias Waldekranz <tobias@waldekranz.com>
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>