An ambient capability only reaches the effective set when euid is
non-zero, so a service that pairs `capabilities = { "^cap_..." }` with a
root user gets none of the restriction it asks for, and keeps the full
root set instead. Finit read the list, applied it, and said nothing. A
build without libcap dropped the list on the floor just as quietly.
Both now warn, naming the service:
nginx: ambient capabilities ('^') have no effect as root, use a
non-root user, or '%' and '!' entries
The ambient entries are read back from the parsed IAB value rather than
matched in the text, so inheritable ('%') and bounding ('!') entries stay
silent -- those work fine as root.
The warning repeats when the .conf files are re-read on runlevel change,
as parse warnings here already do.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The block conversion changed the bodies of the reference sections but
left every "**Syntax:**" header spelling the line-based format, so each
page opened by teaching the format it then stopped using. Six files
were missed entirely: runparts, files, capabilities, requirements,
runlevels, and switchroot.
runparts had no block spelling written down anywhere, though the parser
has read `runparts`, `runparts-progress`, and `runparts-sysv` all along.
tty gains a table per variant. Its three syntax lines carried nine
positional fields between them, which no longer describes anything the
parser accepts.
Fixes#148
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
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>
* src/pid.c: note the stale-pidfile-cleanup exception to the
documented "Finit does not touch pid:! pidfiles" rule.
* doc/config/services.md: add a user-facing paragraph on the same.
* doc/ChangeLog.md: add Unreleased section covering this PR --
stale pidfile cleanup, restart log with signal name and core
dump flag, and the SIGUNKOWN typo fix.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Conditions in Finit are dependencies: if A is asserted, service B is
allowed to run. When A goes through FLUX (e.g., upstream reloads),
dependents are PAUSED and then simply resumed when the condition is
reasserted -- this is the correct behavior for barrier-style deps
like <pid/syslogd>.
However, some setups have tightly coupled services where dependents
must be reloaded/restarted when an upstream service reloads, not just
resumed. E.g., the FRR routing stack on Infix OS:
netd <pid/mgmtd> ← zebra <!pid/netd> ← {staticd,ripd} <!pid/zebra>
When netd reloads (SIGHUP), zebra and its dependents must be restarted
to pick up the new configuration.
The new '~' condition prefix marks a dependency as flux-sensitive:
service <!~pid/netd> name:zebra ...
When the upstream condition goes FLUX and returns to ON, the dependent
is reloaded (SIGHUP) or restarted (noreload '!') instead of merely
resumed. Transitivity follows naturally through the condition chain.
Closes#416Closes#476
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Similar to systemd's RemainAfterExit=yes. Prevents the task from
re-running on runlevel re-entry and ensures the post: script runs
when explicitly stopped or when leaving valid runlevels.
Useful for tasks that set up persistent state like firewall rules:
task [2345] remain:yes \
post:/usr/sbin/teardown-firewall \
/usr/sbin/setup-firewall -- Firewall setup
Not supported for bootstrap-only tasks (runlevel S only) since these
are deleted immediately after completion.
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.
Some 'respawn' type services, like gettys, may hog the CPU in error
states if the service immediately exits. E.g., due to missing dev.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Implement supplementary group support for services, allowing them to
access resources owned by multiple groups. Uses the @user:group,sup1,sup2
syntax to explicitly specify supplementary groups, in addition to now
reading group membership from /etc/group.
Cgroups v2 limits are hierarchical - a process is constrained by the
most restrictive limit in its ancestor chain, not just its immediate
cgroup. This patch updates cg_conf() to walk up the hierarchy and
report effective limits by comparing values at each level.
This fixes incorrect "max" (unlimited) reporting in 'initctl --json
status', 'initctl cgroup', and 'initctl top' when child cgroups have
no explicit limits but parents do.
For memory.max and cpu.max: take minimum (most restrictive)
For memory.min: take maximum (most protection)
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
The PTY approach caused isatty() to return true for services using
the log directive, triggering programs like fprintd (using glib) to
emit ANSI escape codes and other TTY-specific formatting in syslog.
Using a standard pipe ensures isatty() correctly returns false, so
programs produce plain text output suitable for logging.
For services that require line-buffered output, users can wrap the
command with `stdbuf -oL` as documented in doc/config/logging.md.
Fixes#455
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
Implement Linux capability support for services, allowing them to run
with minimal required privileges instead of running as root. This uses
the modern IAB (Inheritable, Ambient, Bounding) API from libcap.