The bus method called sm_runlevel() unconditionally. In runlevel 0
and 6 that aborts an in-flight shutdown, which INIT_CMD_RUNLVL
refuses with a warning, and during bootstrap it switches immediately
where the legacy path defers via cfglevel to the end of runlevel S.
Port both. A bad runlevel argument still returns InvalidArgs, where
the legacy protocol acks silently: a typed interface rejects garbage.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Finit had no way to answer the question every service manager gets
asked: what is running, and change it. D-Bus is how the rest of
userspace asks, but linking libdbus, sd-bus or GIO into PID 1 buys a
dependency, an allocator and a main loop we do not control.
So libink: the wire format, an object tree, and a bus of Finit's own
at /run/finit/bus, gated like INIT_SOCKET. It speaks the standard
org.freedesktop.DBus, .Peer, .Introspectable interfaces, and Finit's
own Manager1, Service1 and Cond1 on top. Methods that change
something are marked privileged and answered only for a caller the
kernel vouched for, via SO_PEERCRED.
Server and client both, since initctl is the first thing that needs
to talk to it, and its Start/Stop/Restart/Reload now go over the bus
rather than the legacy socket.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
A service's condition was computed with mkcond() at each of the six
sites that assert or clear it, and svc_find_by_cond() reimplemented
the reverse lookup a seventh time. maybe_clear_cond() had its own
scan for another service supplying the same condition.
svc_cond_owner() answers who owns a condition, svc_cond_nth() walks
the conditions a service owns, and svc_cond_set()/svc_cond_clear()
apply to all of them. svc_find_by_cond() becomes a wrapper, and
maybe_clear_cond() keeps its rule per condition rather than for the
one it used to compute.
The provides[] storage lands here unused, since svc_cond_nth() reads
num_provides. Nothing sets it yet, so a service still owns exactly
its own pid/<ident> and there is no functional change.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This fixes a real bug where `initctl reload syslogd` unconditionally
clears syslogd's pid condition, causing all dependent services (dbus,
dnsmasq, etc.) to be stopped even though syslogd handles SIGHUP
gracefully and its PID/pidfile persist.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When reloading a specific service with 'initctl reload foo', the
pid/foo and service/foo/ready conditions were never cleared, so
dependent services were not notified of the reload.
Clear the service's pid condition and, for pid/none notify types,
the ready condition before reloading. The conditions are then
reasserted by the pidfile inotify handler when the service touches
its PID file after processing SIGHUP.
For s6/systemd services the ready condition is left intact since
their readiness notification may not re-trigger on SIGHUP.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The do_ prefix is conventionally reserved for local helper functions.
Move switch_root() declaration to private.h alongside iterate_proc()
and remove the now-empty initramfs.h header.
in an initramfs, then transition to the real root filesystem. Useful
for systems requiring early boot tasks like LUKS unlock, LVM activation,
or network boot before mounting the real root.
Adds INIT_CMD_SWITCH_ROOT API command, `initctl switch-root` subcommand,
and HOOK_SWITCH_ROOT plugin hook point. The implementation gracefully
stops services, moves virtual filesystems (/dev, /proc, /sys, /run) to
the new root, deletes initramfs contents to free memory, then execs the
new init as PID 1.
See GitHub Discussion #292 for background.
Relax the constraints introduced in a39ee0b, for issue #342, a bit on
when start/stop/restart/reload service can be called. Also, allow
'initctl reload', but ignore it when the system is in runlevels S/0/6.
This makes it possible to start manual:yes type services at botostrap,
for example, which has been a common feature request.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This refactor should have been done years ago when we first introduced
the big state machine. The old functions service_runvel() and the oddly
named service_reload_dynamic() are actually state machine control fns,
so let relocate them.
Also in this commit, remove the global variable 'sm' and rename a few of
the critical functions to better names.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch fixes issue #440 which details how systemd readiness
notification has been broken since its inception in Finit.
In addition to now providing a proper abstract socket, the refactor
also drops the reliance on the Finit client API to fetch a socket.
Now an s6 descriptor is the write end of a pipe() and the systemd
socket is instead created before forking off the service.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When building with global CFLAGS=-Wunused-parameter the output from the
build looks terrible. This commit explicitly declares unused variables
to prevent triggering -Wunused-parameter
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This change opens up the runlevel change API from bootstrap. The twist
is that the change is only queued, i.e., the call `initctl runlevel 9`
during bootstrap only changes the configured runlevel to go to after
bootstrap has completed.
Effectively, this change allows overriding the `runlevel` directive in
/etc/finit.conf without having to change the file.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
These changes add a new svc_block_t type: SVC_BLOCK_CONFLICT so a user
can more clearly see why a run/task/service has not been started by
Finit. The reason for the block is by default logged, which can be
escaped by using the `nowarn` flag.
Also, when the conflict is resolved, allow the service to start.
With these changes, the system/hotplug.conf should work better and
cause less questions about "strange" log messages.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Due to an old design decision runlevel S was encoded internally as '0',
meaning it was the same as halt/poweroff. If you want to run scripts at
system shutdown this was less then ideal since it meant your scripts
also ran at bootstrap.
This change is quite invasive. It introduces INIT_LEVEL (10) as the
value for runlevel S, meaning all code that parses and/or evaluates
anything for runlevel 0/S was affected and had to be reworked.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
All services registered in the system rely on conf_init() having been
set up properly, e.g., global_rlimit. Having conf_init() be responsible
also for registering static services is only logical, and also helps us
clean up main() a bit.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Over the years there have been multiple cases of invalid and/or unsafe
uses of signals and initctl commands at bootstrap and shutdown. These
cases cannot be safely supported. This commit locks down finit a bit
to avoid the most common cases.
If you run into this, please open a new discussion at GitHub and we'll
talk about it. Maybe I've been overzealous or you have another use-case
that warrants opening up some or parts of the API.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When a service crashes Finit launches a restart timer that periodically
will try restart the service. If a user calls `initctl stop foo` finit
must cancel this timer callback, otherwise we may end up with a weird
state where Finit thinkgs the service is running, but pid: 0, i.e., not
started.
Note: this fix has been expanded upon from the proof of concept
submitted by Jack Newman.
Bug #313
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch adds service readiness notification to support daemons
employing systemd and s6 notification. Complementing the native
Finit readiness support using PID files that exist already.
The two have slightly different ways of implementing readiness:
- https://www.freedesktop.org/software/systemd/man/sd_notify.html
- https://skarnet.org/software/s6/notifywhenup.html
Finit now provides both a NOTIFY_SOCKET environemnt variable, for
systemd, and a way to start s6 daemons with a descriptor argument.
For details on the syntax, see the `service` documentation.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Move the stop+start from initctl to the state machine by allowing
stopped tasks to restart once it has been collected. This should
prevent finit from blocking, allowing it to handle other requests
while waiting for the service's PID to be collected.
Effectively, this will allow a service to call initctl to restart
itself, as reported in issue #280.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
In some conditions, typically when the same command is used for multiple
services, e.g. the modules-load plugin, the svc_find() function returned
an existing "similar" entry instead of NULL, causing loss of config.
When creating, and searching for, a run/task/service we must follow the
new name:id paradigm to the letter. Always create based on name:id and
always search for matching name:id. The name may be derived from the
command, but they cannot be used interchangably.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Drop the config.h include from helpers.h after a report from a colleague
trying to build an external plugin from the latest GIT sources.
Instead, make sure config.h is included, and properly commented, in all
.c files that have configure #ifdefs and other deps. Also, move more
ot the includes from helpers.h to their respective .c file instead to
reduce the amount of headers an external plugin pulls in.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
- Check all pointers
- Declaratons always at top of func/scope
- Use established variable nomenclature
- Skip useless if() stmt
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
- Comments preferably at beginning of func/sect
- Reorder code slightly, add whitespace for readability
- Drop useless comment
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The implementation looks up the named service by using
`svc_parse_jobstr`. The callbacks for `svc_parse_jobstr` has been
augmented to accept a user data parameter. For this use case,
a carrier for the actual signal was needed. The address of the
signal parameter is taken and passed on as a `void *`. The
callback then simply deferences it as an int - the signal number.
Due to an unfortunate name clash with the DirectFB project LiTE, the
libite (-lite) project had to change its header namespace from
lite/*.h -> libite/*.h
This patch adds support for the new namepace in Finit, triggered by the
define _LIBITE_LITE, from the .pc file read by pkg-config. This should
only be needed on systems that install libite without the compatibility
symlink lite -> libite/ in the staging include directory.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch restores the start of the built-in/bundled watchdogd. It is
tracked in the `wdog` variable and handled as an exception at shutdown.
This is also a follow-up to 7b74c99, ensuring that we only kill/stop the
built-in watchdog, not any external. External ones can register to be
the controlling watchdogd in the system -- Finit is not the arbiter for
singletons, this is up to the system engineer.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
No need to zero out whole buffer for strlcat(), or other string check
ops. Also drop a few completely useless memset() calls.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch corrects a logical glitch, or design flaw, in initctl. The
'restart FOO' command did not stop+start FOO only send SIGHUP (provided
FOO supports SIGHUP). Hence, a new command 'reload FOO' is introduced,
which does exactly that, and 'restart FOO' now stops and restarts FOO.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>