Finit speaks D-Bus itself now and claims org.finit on the system bus
when it finds one, but nothing in a default build ever brings that bus
up. The plugin that does was opt-in, so the built-in support sat idle
unless the integrator knew to ask for both halves.
Defaulting it on is only reasonable if the result stays the admin's to
change, and a service registered from C through conf_save_service() is
not: it lands in the run path where it cannot be overridden or emptied
out. So the daemon moves to 20-dbus.conf and its directories to
tmpfiles.d/dbus.conf, the same way hotplug and every other daemon we
ship them for. The plugin keeps only what has to look at the running
system, the stale pidfile and the machine UUID.
Those directories are no longer chowned to messagebus. tmpfiles.d
skips a line whose user does not exist rather than falling back, so
the plugin's messagebus/dbus/root ladder has no equivalent there, and
dbus-daemon binds its socket before dropping privileges anyway.
The plugin already bows out where there is no dbus-daemon installed,
so systems that never wanted a bus are unaffected, and
--disable-dbus-plugin is there for those that have one and would still
rather init left it alone.
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>
The runparts directory and the dbus pidfile and daemon paths are
embedded in double-quoted values of the generated block files. A
literal quote in either ends the value early and libconfuse rejects
the whole file, and a backslash is read as an escape sequence,
silently mangling the path. The legacy one-liners had no quoting, so
neither failure existed before the block conversion.
conf_escape() doubles backslashes and escapes quotes; verified by
round-tripping hostile paths through cfg_parse_buf().
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Finit's own generated services -- watchdogd, keventd, runparts, and
the dbus plugin -- still went through conf_save_service() as legacy
one-liners, so `initctl show keventd` taught the old format on a
system otherwise converted to the new one.
conf_save_service() now takes the block title and a printf-style body
and writes the file itself:
# Generated by finit:conf_save_service()
service keventd {
description = "Finit kernel event daemon"
runlevel = "S12345789"
notify = "none"
cgroup init {}
command = "/libexec/finit/keventd"
}
vfprintf() into the file also removes the fixed-size staging buffers
in the callers, where a long dbus pidfile path could truncate inside
a quoted string and take the whole generated file with it.
Semantics preserved: watch-only pid:! maps to pidfile without
pidfile-create, the watchdog keeps its watchdog:finit identity, and
log:console becomes log { file = "/dev/console" }.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
When 'initctl reload' is called after marking a service in a dependency
chain dirty, Finit fails to restart (unfreeze) affected services.
This patch updates the pidfile plugin to watch for IN_ATTRIB changes,
e.g. when a process uses utimensat() to update its pidfile, and adds
service_step_all() at end of reload cycle to guarantee convergence
after conditions are reasserted.
Issue #476
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The netlink plugin only receives RTM_NEWLINK events for interfaces that
appear after the plugin starts. Interfaces that already exist at boot
(e.g., virtio-net in QEMU) never generate events, so their conditions
like net/eth0/exist were never set.
Moving enumeration to PLUGIN_INIT doesn't work because it runs before
cond_init(), so the condition filesystem isn't ready yet.
Fix by registering an HOOK_SVC_PLUGIN callback that queries existing
interfaces and routes. This hook runs during conf_init(), after the
condition system is initialized.
The container monitor that podman forks off when starting a container
instance creates subgroups in the cgroup v2 hieararchy that we want to
reuse. This patch adds cgroup_move_svc() which we call from the pidfile
plugins to relocate the conmon process.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
There are some invalid condition checks in rtc.c, when rtc_file is
missing, it should not consider that as a error and return, otherwise,
it can lead to the case that time_set wont be called at all.
With this fix, when both RTC and file restore fail, it will fall back
to call time_set(NULL) and restore time from rtc_timestamp, this
ensures the OS has a valid time at the very first boot.
Signed-off-by: Ming Liu <liu.ming50@gmail.com>
These variables really belong in conf.c. Relocate and move external
decls. from finit.h -> conf.h to simplify linking of other programs.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
With the relocation of several functions, including inline functions,
from helpers to util, we no longer need to include log.h. Which is a
good thing, since any subsystem that needs logging should explicitly
include log.h
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Prevent name clash with upcoming refactor and any confusion with
src/plugin.c functions with the same name.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The tmpfiles.d spec has proven useful in systemd, enough so that some developers
are starting to ship tmpfiles.d configuration files with their software.
By splitting the tmpfiles functionality in finit out into a separate executable
we are providing a useful piece of software that package managers can hook into.
An svc_t (service/sysv) that is in setup, teardown, or cleanup state
must be ignored by the pidfile plugin for any events regarding PID
files. E.g., a setup script for a sysv service may create a PID file
to alert the system that a setup process for the service is running.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Introduced to work-around systems with broken RTCs, it also introduced a
dormant bug in Finit, triggered at shutdown on some systems. The call
to dlclose() removed the memory to the rtc_timer which libuev later then
referenced.
Fixes#429
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Enhance fallback entropy generation by mixing in multiple sources:
runtime statistics, PID, and high-resolution timestamps.
This provides better initialization for the PRNG when neither saved
entropy nor hardware RNG are available during early boot.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
These plugins signal success and failure directly to the console, the
user should inspect syslog for more information.
This change is a follow-up to 340cae4, where kernel logs of LOG_ERR and
higher are allowed to log directly to the console. Since syslogd has
not been started before these plugins, the log messages would otherwise
leak to the console.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
In 42ef3d3c, for v4.4-rc1, support for setting a custom RTC restore date
was introduced. Unfortunately the configure script was wrong and caused
config.h to contain
#define RTC_TIMESTAMP_CUSTOM "$rtc_date"
instead of
#define RTC_TIMESTAMP_CUSTOM "2023-04-10 14:35:42"
Furthermore, the error handling for strptime() was wrong, so the restore
date was always reverted to the default.
This patch fixes both issues and extends the DATE of --with-rtc-date to
also include seconds.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch introduces a new configure option --with-rtc-file=FILE. When
enabled the RTC plugin detects missing RTC device and falls back to save
and restore system time from a file instead. When --with-rtc-file is
used without an argument the default file is /var/lib/misc/rtc, but the
feature itself is disabled by default.
The usefulness of this feature may not be obvious at first, but some
systems are equipped with an RTC that resets to a random date at power
on. This can be really bad in the case the date is far in the future,
because an NTP sync would then cause time skips backwards, which shows
up in logs and causes a whole lot of pain in alarm systems.
The solution is to disable the RTC driver or device tree node, and when
Finit starts up, the RTC plugin detects a the device node and instead
restores time from the last save game. Meaning time will always only
move forwards.
NOTE: when Finit is built --with-rtc-file we always save to disk, but
only restore from the "save game" if restoring from RTC fails.
If the system has no RTC we always restore from disk.
As an added bonus, this change also makes sure to periodically
sync also the RTC with the system clock. Useful for systems
that do not run an NTP client.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
A service with notify:pid is 'ready' when the pidfile has been created,
the converse also holds true -- when a pidfile is removed the service is
no longer 'ready'.
The state transition for the service has probably already been done, in
svc_set_state(), clearing all <service/foo/*> conditions when the PID
was collected. The pidfile event may arrive later, so for completeness
we make sure the 'ready' condition is not recreated at least.
Problem introduced in 912a281 with the original supoport for service
readiness notification.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
There exist two possible basename functions, a xpg compliant one in libgen.h
and a GLIBC exclusive one declared in string.h, that was previously also declared by musl libc.
Both implementations are expecting different parameter types (`const char *` for GLIBC and `char *` for xpg)
With the removal of the basename function from string.h in musl libc, we could only rely on the xpg implementation.
Unfortunately, the xpg implementation of basename does modify the contents of whatever you put in it,
even though that there really is no need for it.
This is an issue in some cases, where we might want to get the basename of a read-only variable, e.g. a `const char *`,
as trying to modify something read-only is undefined behavior.
So in order to keep things consistent for us, we implement our own version of basename called `basenm`,
that does not modify the passed argument.
Premise, a service declaring itself 'notify:none' should never assert a
pid condition. However, forking services still need to be supported and
the only way to do that is if they create a pid file. Hence, instead of
skipping pidfile_update_conds() completely we need to filter the type.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This change expands the readiness notification system in Finit with the
native 'pid' style, which will remain the default readiness in Finit 4.x
For systems that want to transition to Finit 5.x early, a global option
to set 'readiness none' in /etc/finit.conf, has been added. This change
the service default notification mode to 'notify:none', which can also
be set by Finit 4.x ('readiness pid') for select services.
Fixes#386.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This adds a new function conf_save_service() replacing service_register() for
plugins and bundled services like watchdogd, keventd, runparts, etc.
The benefits to this change are several:
- Plugin/Bundled services no longer risk starting before udev or other
critical services/task have started
- Definitions can be overridden by an administrator (see docs)
- Increases visibility (user: where are all these services coming from?)
Previously the origin (file the service was loaded from) was NULL.
- Adds another level of extensibility to Finit
The most notable change is that dbus is no longer started before udevd.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This patch extens the SysV compatibility support in Finit by adding
support for limiting `runparts` to run only SNNfoo, or KNNfoo, style
scripts from a directory.
Additionally, by default `runparts` now runs entirely in the background
without any progress. To enable progress, an optional argument has been
added to the runparts command line.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
With non-standard paths, e.g., when running `make distcheck`, the
absolute path to some commands become ridiculously long. However,
this has been a recurring issue for some users in the past, so it
is time to increase the capabilibieies of Finit to cover this.
Yes, a better way is probably to allocate all these strings when they
are used, but that would require a redesign of the initctl API and
likely cause a lot of regressions before everything has stabilized.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>