mirror of
https://github.com/troglobit/finit.git
synced 2026-09-30 13:02:37 +07:00
1119 lines
32 KiB
Plaintext
1119 lines
32 KiB
Plaintext
.\" Hey, EMACS: -*- nroff -*-
|
|
.\" First parameter, NAME, should be all caps
|
|
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
|
|
.\" other parameters are allowed: see man(7), man(1)
|
|
.Dd July 10, 2025
|
|
.Dt FINIT.CONF 5 SMM
|
|
.Os Linux
|
|
.Sh NAME
|
|
.Nm finit.conf
|
|
.Nd Finit configuration file format
|
|
.Sh SYNOPSIS
|
|
.Nm /etc/finit.conf
|
|
.Nm /etc/finit.d/*.conf
|
|
.Nm /etc/finit.d/available/*.conf
|
|
.Nm /etc/finit.d/enabled/*.conf
|
|
.Sh DESCRIPTION
|
|
.Nm Finit
|
|
based systems can be set up with a single file:
|
|
.Pa /etc/finit.conf .
|
|
This is the traditional way of doing it which can be ideal for some
|
|
setups since it gives a great overview of the system configuration.
|
|
.Pp
|
|
More comprehensive setups, however, require more careful planning.
|
|
The recommendation is per-package
|
|
.Cm *.conf
|
|
files in
|
|
.Pa /etc/finit.d/available/ .
|
|
This allows end users to enable and disable parts of the system
|
|
configuration at runtime. Finit tracks which tasks and services belong
|
|
to a given file, so that when the user calls
|
|
.Cm initctl reload
|
|
to activate the changes they have made, only the affected tasks and
|
|
services are stopped, started, or restarted. Hence, this approach is
|
|
useful for modern package-based Linux distributions.
|
|
.Pp
|
|
The following sections describe the more of this in detail, starting
|
|
with files, the file format, and available directives. Remember to
|
|
also visit the other manual pages (references at the bottom).
|
|
.Sh FILES
|
|
.Bl -tag -width /etc/finit.d/available/*.conf -compact
|
|
.It Pa /etc/finit.conf
|
|
Main configuration file, optional
|
|
.It Pa /etc/finit.d/*.conf
|
|
Static (system) service definitions
|
|
.It Pa /etc/finit.d/available/*.conf
|
|
Available (installed) services
|
|
.It Pa /etc/finit.d/enabled/*.conf
|
|
Enabled services (symlink back)
|
|
.El
|
|
.Pp
|
|
Static services,
|
|
.Cm .conf
|
|
files in
|
|
.Pa /etc/finit.d/ ,
|
|
cannot be enabled or disabled using
|
|
.Cm initctl [enable | disable] service[.conf] .
|
|
An enabled service is a symlink back to the corresponding
|
|
.Cm ../available/
|
|
service
|
|
.Cm .conf
|
|
file. Please use the
|
|
.Cm initctl
|
|
tool to manage these symlinks to ensure proper operation.
|
|
.Pp
|
|
.Sy NOTE:
|
|
Previous versions of
|
|
.Nm Finit
|
|
created symlinks in
|
|
.Pa /etc/finit.d/
|
|
if
|
|
.Pa /etc/finit.d/enabled/
|
|
was missing, this is as of v4.4 not supported.
|
|
.Sh FILE FORMAT
|
|
The file format is line based, empty lines and comments, lines starting
|
|
with `#', are ignored. A configuration directive starts with a keyword
|
|
followed by a space and the rest of the line is treated as the value.
|
|
.Pp
|
|
As of Finit v4.4, configuration directives can be broken up in multiple
|
|
lines using the continuation character `\\', and trailing comments are
|
|
also allowed. Example:
|
|
.Bd -unfilled -offset indent
|
|
# Escape \\# chars if you want them literal in, e.g., descriptions
|
|
service name:sysklogd [S123456789] \\
|
|
env:-/etc/default/sysklogd \\
|
|
syslogd -F $SYSLOGD_ARGS \\
|
|
-- System log daemon \\# 1 # Comments allowed now
|
|
.Ed
|
|
.Sh DIRECTIVES
|
|
This section lists all supported configuration directives. There also exist
|
|
deprecated directives, see the Markdown documentation for details on these.
|
|
.Pp
|
|
.Bl -tag -width 1n
|
|
.It Cm rlimit Oo hard|soft Oc Ar RESOURCE Aq LIMIT | unlimited
|
|
.Pp
|
|
Set the hard or soft limit for a resource, or both if that argument is
|
|
omitted.
|
|
.Ar RESOURCE
|
|
is the lower-case
|
|
.Cm RLIMIT_
|
|
string constants from
|
|
.Xr setrlimit 2 ,
|
|
without prefix. E.g. to set
|
|
.Cm RLIMIT_CPU ,
|
|
use
|
|
.Cm cpu .
|
|
.Pp
|
|
.Ar LIMIT
|
|
is an integer that depends on the resource being modified, see
|
|
the man page, or the kernel
|
|
.Pa /proc/PID/limits
|
|
file, for details.
|
|
Finit versions before v3.1 used
|
|
.Cm infinity
|
|
for
|
|
.Cm unlimited ,
|
|
which is still supported, albeit deprecated.
|
|
.Bd -unfilled -offset indent
|
|
# No process is allowed more than 8MB of address space
|
|
rlimit hard as 8388608
|
|
|
|
# Core dumps may be arbitrarily large
|
|
rlimit soft core infinity
|
|
|
|
# CPU limit for all services, soft & hard = 10 sec
|
|
rlimit cpu 10
|
|
.Ed
|
|
.Pp
|
|
.Cm rlimit
|
|
can be set globally, in
|
|
.Pa /etc/finit.conf ,
|
|
or locally per each
|
|
.Pa /etc/finit.d/*.conf
|
|
read. I.e., a set of task/run/service stanzas can share the same
|
|
rlimits if they are in the same .conf.
|
|
.It Cm runlevel Aq N
|
|
The system runlevel to go to after bootstrap (S) has completed.
|
|
.Cm N
|
|
is the runlevel number 0-9, where 6 is reserved for reboot and 0 for
|
|
halt. All other can be used by operating system administrators.
|
|
Default: 2
|
|
.Pp
|
|
It s recommended to keep runlevel 1 as single-user mode, because
|
|
.Nm
|
|
disables networking in this mode.
|
|
.Pp
|
|
.Sy Note:
|
|
only read and executed in runlevel S (bootstrap).
|
|
.It Cm run Oo LVLS Oc Ao COND Ac Ar /path/to/cmd ARGS Op -- Optional description
|
|
One-shot command to run in sequence when entering a runlevel, with
|
|
optional arguments and description.
|
|
.Pp
|
|
.Cm run
|
|
commands are guaranteed to be completed before running the next
|
|
command. Highly useful if true serialization is needed. Usually
|
|
only used in the bootstrap (S) runlevel.
|
|
.Pp
|
|
.Cm Aq COND
|
|
conditions are described in
|
|
.Xr finit 8 ,
|
|
see also the
|
|
.Sx Examples
|
|
section below.
|
|
.It Cm task Oo LVLS Oc Ao COND Ac Ar /path/to/cmd ARGS Op -- Optional description
|
|
One-shot like
|
|
.Cm run ,
|
|
but starts in parallel with the next command.
|
|
.Pp
|
|
Both
|
|
.Cm run
|
|
and
|
|
.Cm task
|
|
commands are run in a shell, so pipes and redirects can be freely used:
|
|
.Bd -unfilled -offset indent
|
|
task [s] echo "foo" | cat >/tmp/bar
|
|
.Ed
|
|
.It Cm sysv Oo LVLS Oc Ao COND Ac Ar /path/to/script ARGS Op -- Optional description
|
|
Similar to
|
|
.Cm service
|
|
is the
|
|
.Cm sysv
|
|
directive, which can be used to call SysV style start/stop scripts. The
|
|
primary intention for this command is to be able to re-use traditional
|
|
SysV init scripts in Linux distributions.
|
|
.Pp
|
|
When entering an allowed runlevel, Finit calls
|
|
.Cm init-script start ,
|
|
when entering a disallowed runlevel, Finit calls
|
|
.Cm init-script stop ,
|
|
and if the Finit .conf, where the
|
|
.Cm sysv
|
|
stanza is declared, is modified, Finit calls
|
|
.Cm init-script restart
|
|
on
|
|
.Cm initctl reload .
|
|
Similar to how
|
|
.Cm service
|
|
directives work.
|
|
.Pp
|
|
Forking services started with
|
|
.Cm sysv
|
|
scripts can be monitored by Finit by declaring the PID file to look for:
|
|
.Bd -unfilled -offset indent
|
|
sysv pid:!/path/to/pidfile.pid /path/to/script ...
|
|
.Ed
|
|
.Pp
|
|
The leading '!' is to prevent Finit from managing the PID file, which is
|
|
the default behavior for the
|
|
.Cm pid:
|
|
command modifier.
|
|
.It Cm service Oo LVLS Oc Ao COND Ac Ar /path/to/daemon ARGS Op -- Optional description
|
|
Service, or daemon, to be monitored and automatically restarted if it
|
|
exits prematurely. Finit tries to restart services that die, by
|
|
default 10 times, before giving up and marking them as
|
|
.Em crashed .
|
|
After which they have to be restarted manually using
|
|
.Cm initctl restart NAME .
|
|
The number of restarts, the delay between each restart, and more is
|
|
configurable, see the options below.
|
|
.Pp
|
|
.Bd -filled -offset indent
|
|
.Sy Tip:
|
|
to allow endless restarts, see below option
|
|
.Cm respawn
|
|
.Ed
|
|
.Pp
|
|
For daemons that support it, we recommend appending
|
|
.Cm --foreground , --no-background , -n , -F ,
|
|
or similar command line argument to prevent them from forking off a
|
|
sub-process in the background. This is the most reliable way to monitor
|
|
a service.
|
|
.Pp
|
|
However, not all daemons support running in the foreground, or they may
|
|
start logging to the foreground as well, these are called forking
|
|
services and are supported using the same syntax as forking
|
|
.Cm sysv
|
|
services, using the
|
|
.Cm pid:!/path/to/pidfile.pid
|
|
command modifier syntax. There is an alternative syntax that may be
|
|
more intuitive, where Finit can also guess the PID file based on the
|
|
daemon's command name:
|
|
.Bd -unfilled -offset indent
|
|
service type:forking ntpd -- NTP daemon
|
|
.Ed
|
|
.Pp
|
|
Here we let BusyBox
|
|
.Nm ntpd
|
|
daemonize itself. Finit uses the basename of the binary to guess the
|
|
PID file to watch for the PID:
|
|
.Pa /var/run/ntpd.pid .
|
|
If Finit guesses wrong, you have to submit the full
|
|
.Cm pid:!/path/to/file.pid
|
|
option to your service stanza.
|
|
.Pp
|
|
.Sy Example: in the case of
|
|
.Cm ospfd
|
|
(below), we omit the
|
|
.Cm -d
|
|
flag (daemonize) to prevent it from forking to the background:
|
|
.Bd -unfilled -offset indent
|
|
service [2345] <pid/zebra> /sbin/ospfd -- OSPF daemon
|
|
.Ed
|
|
.Pp
|
|
.Cm [2345]
|
|
denote the runlevels
|
|
.Cm ospfd
|
|
is allowed to run in, they are optional and default to runlevel 2-5 if
|
|
omitted.
|
|
.Pp
|
|
.Cm <pid/zebra>
|
|
is the condition for starting
|
|
.Cm ospfd .
|
|
In this example Finit waits for another service,
|
|
.Cm zebra ,
|
|
to have created its PID file in
|
|
.Pa /var/run/quagga/zebra.pid
|
|
before starting
|
|
.Cm ospfd .
|
|
Finit watches *all* files in
|
|
.Pa /var/run ,
|
|
for each file named
|
|
.Cm *.pid ,
|
|
.Cm */pid ,
|
|
Finit opens it and find the matching
|
|
.Cm NAME:ID
|
|
using the PID.
|
|
.Pp
|
|
Some services do not maintain a PID file and rather than patching each
|
|
application Finit provides a workaround. A
|
|
.Cm pid
|
|
modifier keyword can be set to have Finit automatically create (when
|
|
starting) and later remove (when stopping) the PID file. The file is
|
|
created in the
|
|
.Pa /var/run
|
|
directory using the
|
|
.Xr basename 3
|
|
of the service. The full syntax of the
|
|
.Cm pid
|
|
modifier is:
|
|
.Bd -unfilled -offset indent
|
|
pid[:[!][/path/to/]filename[.pid]]
|
|
.Ed
|
|
.Pp
|
|
For example, by adding
|
|
.Cm pid:/run/foo.pid
|
|
to the service
|
|
.Cm /sbin/bar ,
|
|
that PID file will, not only be created and removed automatically, but
|
|
also be used by the Finit condition subsystem. So a service/run/task
|
|
can depend on the
|
|
.Cm <pid/bar>
|
|
condition.
|
|
.Pp
|
|
As an alternative "readiness" notification, Finit supports both systemd
|
|
and s6 style notification. This can be enabled by using the `notify`
|
|
option:
|
|
.Bl -tag -width 1n
|
|
.It Cm notify:systemd
|
|
tells Finit the service uses the
|
|
.Cm sd_notify()
|
|
API to signal PID 1 when it has completed its startup and is ready
|
|
to service events. This API expects
|
|
the environment variable
|
|
.Cm NOTIFY_SOCKET
|
|
to be set to the socket where the application can send
|
|
.Cm "READY=1\n"
|
|
when it is starting up or has processed a
|
|
.Cm SIGHUP .
|
|
For details, see:
|
|
.Pp
|
|
.Lk https://www.freedesktop.org/software/systemd/man/sd_notify.html
|
|
.It Cm notify:s6
|
|
puts Finit in s6 compatibility mode. Compared to the systemd
|
|
notification, s6 expect compliant daemons to send
|
|
.Cm "\\n"
|
|
and then close their socket. For details, see:
|
|
.Pp
|
|
.Lk https://skarnet.org/software/s6/notifywhenup.html
|
|
.Pp
|
|
Finit takes care of "hard-wiring" the READY state as long as the
|
|
application is running, events across any `SIGHUP`. Since s6 can give
|
|
its applications the descriptor number (must be >3) on then command
|
|
line, Finit provides the following syntax (
|
|
.Cm %n
|
|
is replaced by Finit with then descriptor number):
|
|
.Bd -unfilled -offset indent
|
|
service notify:s6 mdevd -C -O 4 -D %n
|
|
.Ed
|
|
.Pp
|
|
When a service is ready, either by Finit detecting its PID file, or
|
|
their respective readiness mechanism has been triggered, Finit creates
|
|
then service's ready condition which other services can depend on:
|
|
.Bd -unfilled -offset indent
|
|
$ initctl -v cond get service/mdevd/ready
|
|
on
|
|
.Ed
|
|
.El
|
|
.Pp
|
|
If a service should not be automatically started, it can be configured
|
|
as manual with the
|
|
.Cm manual:yes
|
|
command modifier. The service can then be started at any time by
|
|
running
|
|
.Cm initctl start NAME
|
|
.Pp
|
|
The name of a service, shown by the
|
|
.Cm initctl
|
|
tool, defaults to the basename of the service executable. It can be
|
|
changed with the
|
|
.Cm name:foo
|
|
command modifier.
|
|
.Pp
|
|
As mentioned previously, services are automatically restarted should
|
|
they crash, this is configurable with the following options:
|
|
.Bl -tag -width 1n
|
|
.It Cm restart:NUM
|
|
number of times Finit tries to restart a crashing
|
|
service, default: 10. When this limit is reached the service is
|
|
marked
|
|
.Em crashed
|
|
and must be restarted manually with
|
|
.Xr initctl 8 .
|
|
.It Cm restart_sec:SEC
|
|
number of seconds before Finit tries to restart
|
|
a crashing service, default: 2 seconds for the first five retries,
|
|
then back-off to 5 seconds. The maximum of this configured value
|
|
and the above (2 and 5) will be used
|
|
.It Cm restart:always
|
|
no upper limit on the number of times Finit tries to restart a crashing
|
|
service. Same as
|
|
.Cm restart:-1
|
|
.It Cm norestart
|
|
dont restart on failures, same as
|
|
.Cm restart:0
|
|
.It Cm respawn
|
|
bypasses the
|
|
.Cm restart
|
|
mechanism completely, allows endless restarts. Useful in many
|
|
use-cases, but not what
|
|
.Cm service
|
|
was originally designed for so not the default behavior.
|
|
.It Cm oncrash:reboot
|
|
when all retries have failed, and the service
|
|
has
|
|
.Em crashed ,
|
|
if this option is set the system is rebooted.
|
|
.It Cm oncrash:script
|
|
Similar to
|
|
.Cm oncrash:reboot ,
|
|
but instead of rebooting this action calls the
|
|
.Cm post:script
|
|
(see below) to let the operator decide the best course of action. If
|
|
the post:script option is not set, this is a no-op.
|
|
.Pp
|
|
The post:script is called with the same environment variables
|
|
.Sy except
|
|
for the
|
|
.Cm EXIT_CODE
|
|
variable which is set to
|
|
.Cm "crashed"
|
|
.It Cm reload:'script [args]'
|
|
some services do not support SIGHUP but may have other ways to update
|
|
the configuration of a running daemon. When
|
|
.Cm reload:script
|
|
is defined it is preferred over SIGHUP. Like systemd,
|
|
.Nm finit
|
|
sets
|
|
.Cm $MAINPID
|
|
as a convenience to scripts, which in effect also allow
|
|
.Cm reload:'kill -HUP $MAINPID'
|
|
.It Cm stop:'script [args]'
|
|
Some services may require alternate methods to be stopped. When
|
|
.Cm stop:script
|
|
is defined it is preferred over SIGTERM and stop, for
|
|
.Cm service
|
|
and
|
|
.Cm sysv
|
|
directives, respectively.
|
|
Similar to
|
|
.Cm reload:script ,
|
|
.Nm finit
|
|
sets
|
|
.Cm $MAINPID .
|
|
.El
|
|
.Pp
|
|
When stopping a service (run/task/sysv/service), either manually or when
|
|
moving to another runlevel, Finit starts by sending SIGTERM, to allow
|
|
the process to shut down gracefully. If the process has not been
|
|
collected within 3 seconds, Finit sends SIGKILL. To halt the process
|
|
using a different signal, use the command modifier
|
|
.Cm halt:SIGNAL ,
|
|
e.g.,
|
|
.Cm halt:SIGPWR .
|
|
To change the delay between your halt signal and KILL, use the command
|
|
modifier
|
|
.Cm kill:SEC ,
|
|
e.g.,
|
|
.Cm kill:10
|
|
to wait 10 seconds before sending SIGKILL.
|
|
.Pp
|
|
Services, including the
|
|
.Cm sysv
|
|
variant, support pre/post/ready and cleanup scripts:
|
|
.Bl -tag -width 1n
|
|
.It Cm pre:[0-3600,]script
|
|
called before the sysv/service is stated
|
|
.It Cm post:[0-3600,]script
|
|
called after the sysv/service has stopped
|
|
.It Cm ready:[0-3600,]script
|
|
called when the sysv/service is ready
|
|
.It Cm cleanup:[0-3600,]script
|
|
called when run/task/sysv/service is removed
|
|
.El
|
|
.Pp
|
|
The optional number (0-3600) is the timeout before Finit kills the
|
|
script, it defaults to the kill delay value and can be disabled by
|
|
setting it to zero. These scripts run as the same
|
|
.Cm @USER:GROUP
|
|
as the service itself, with any
|
|
.Cm env:file
|
|
sourced. The scripts must use an absolute path, but are executed from
|
|
the
|
|
.Cm $HOME
|
|
of the given user. The scripts are not called with any argument, but
|
|
both get a set of environment variables:
|
|
.Pp
|
|
.Bl -tag -width 1n -compact
|
|
.It Cm SERVICE_IDENT=foo:1
|
|
.It Cm SERVICE_NAME=foo
|
|
.It Cm SERVICE_ID=1
|
|
.El
|
|
.Pp
|
|
The
|
|
.Cm post:script
|
|
is called with an additional set of environment variables, and yes the
|
|
naming looks like it should be swapped:
|
|
.Bl -tag -offset indent -width 1n
|
|
.It Cm EXIT_CODE=[exited,signal,crashed]
|
|
set to one of
|
|
.Cm exited ,
|
|
.Cm signal ,
|
|
or
|
|
.Cm crashed
|
|
(see above).
|
|
.It Cm EXIT_STATUS=[num,SIGNAME]
|
|
set to one of exit status code from the program, if it exited normally,
|
|
or the signal name (HUP, TERM, etc.) if it exited due to signal
|
|
.El
|
|
.Pp
|
|
When a run/task/sys/service is removed (disable + reload) it is first
|
|
stopped and then removed from the runlevel. The
|
|
.Cm post:script
|
|
always runs when the process has stopped, and the
|
|
.Cm cleanup:script
|
|
runs when the the stanza has been removed from the runlevel.
|
|
.It Cm runparts Aq DIR
|
|
Call
|
|
.Xr run-parts 8
|
|
on
|
|
.Cm DIR
|
|
to run start scripts. All executable files, or scripts, in the
|
|
directory are called, in alphabetic order. The scripts in this
|
|
directory are executed at the very end of bootstrap, runlevel S.
|
|
.Pp
|
|
It can be beneficial to use
|
|
.Cm S01name ,
|
|
.Cm S02othername ,
|
|
etc. if there is a dependency order between the scripts. Symlinks to
|
|
existing daemons can talso be used, but make sure they daemonize by
|
|
default.
|
|
.Pp
|
|
Similar to the
|
|
.Pa /etc/rc.local
|
|
shell script, make sure that all your services and programs either
|
|
terminate or start in the background or you will block Finit.
|
|
.Sy Note:
|
|
only read and executed in runlevel S (bootstrap).
|
|
.It Cm include Aq CONF
|
|
Include another configuration file. Absolute path required.
|
|
.It Cm log size:BYTES count:NUM
|
|
Log rotation for run/task/services using the
|
|
.Cm log
|
|
command modifier with redirection to a log file. Global setting,
|
|
applies to all services.
|
|
.Pp
|
|
The size can be given as bytes, without a specifier, or in `k`, `M`,
|
|
or `G`, e.g.
|
|
.Cm size:10M ,
|
|
or
|
|
.Cm size:3G .
|
|
A value of
|
|
.Cm size:0
|
|
disables log rotation. The default is
|
|
.Cm size:200k .
|
|
.Pp
|
|
The count value is recommended to be between 1-5, with a default 5.
|
|
Setting count to 0 means the logfile will be truncated when the MAX
|
|
size limit is reached.
|
|
.It Cm tty Oo LVLS Oc Ao COND Ac Ar DEV Oo BAUD Oc Oo noclear Oc Oo nowait Oc Oo nologin Oc Oo TERM Oc
|
|
This form of the
|
|
.Cm tty
|
|
directive uses the built-in getty on the given TTY device
|
|
.Ar DEV ,
|
|
in the given runlevels.
|
|
.Ar DEV may be the special keyword
|
|
.Cm @console ,
|
|
or `console`, which is expanded from `/sys/class/tty/console/active`,
|
|
useful on embedded systems.
|
|
.Pp
|
|
The default baud rate is 0, i.e., keep kernel default.
|
|
.Pp
|
|
The `tty` directive inherits runlevel, condition (and other feature)
|
|
parsing from the `service` directive. So TTYs can run in one or many
|
|
runlevels and depend on any condition supported by Finit. This is
|
|
useful e.g. to depend on `<pid/elogind>` before starting a TTY.
|
|
.Bd -unfilled -offset indent
|
|
tty [12345] /dev/ttyAMA0 115200 noclear vt220
|
|
.Ed
|
|
.It Cm tty Oo LVLS Oc Ao COND Ac Ar CMD DEV Oo noclear Oc Oo nowait Oc
|
|
This form of the
|
|
.Cm tty
|
|
directive is for using an external getty, like agetty or the BusyBox getty.
|
|
.Pp
|
|
By default, these first two syntax variants
|
|
.Em clear
|
|
the TTY and
|
|
.Em wait
|
|
for the user to press enter before starting getty.
|
|
.Bd -unfilled -offset indent
|
|
tty [12345] /sbin/getty -L 115200 /dev/ttyAMA0 vt100
|
|
tty [12345] /sbin/agetty -L ttyAMA0 115200 vt100 nowait
|
|
.Ed
|
|
.Pp
|
|
The
|
|
.Cm noclear
|
|
option disables clearing the TTY after each session. Clearing the TTY
|
|
when a user logs out is usually preferable.
|
|
.Pp
|
|
The
|
|
.Cm nowait
|
|
option disables the
|
|
.Cm Please press Enter to activate console
|
|
message before actually starting the getty program. On small and
|
|
embedded systems running multiple unused getty wastes both memory and
|
|
CPU cycles, so `wait` is the preferred default.
|
|
.Pp
|
|
The
|
|
.Cm nologin
|
|
option disables getty and
|
|
.Pa /bin/login ,
|
|
and gives the user a root (login) shell on the given TTY
|
|
.Cm DEV
|
|
immediately. Needless to say, this is a rather insecure option, but can
|
|
be very useful for developer builds, during board bringup, or similar.
|
|
.Pp
|
|
Notice the ordering, the
|
|
.Cm TERM
|
|
option to the built-in getty must be the last argument.
|
|
.Pp
|
|
Embedded systems may want to enable automatic `DEV` by supplying the
|
|
special
|
|
.Cm @console
|
|
device. This works regardless weather the system uses
|
|
.Cm ttyS0 , ttyAMA0 , ttyMXC0 ,
|
|
or anything else. Finit figures it out by querying sysfs:
|
|
.Pa /sys/class/tty/console/active .
|
|
The speed can be omitted to keep the kernel default.
|
|
.Pp
|
|
Most systems get by fine by just using `console`, which will evaluate
|
|
to
|
|
.Pa /dev/console .
|
|
If you have to use
|
|
.Cm @console
|
|
to get any output, you may have some issue with your kernel config.
|
|
.Bd -unfilled -offset indent
|
|
tty [12345] @console noclear vt220
|
|
.Ed
|
|
.Pp
|
|
On really bare bones systems, or for board bringup, Finit can give you a
|
|
shell prompt as soon as bootstrap is done, without opening any device
|
|
node:
|
|
.Bd -unfilled -offset indent
|
|
tty [12345789] notty
|
|
.Ed
|
|
.Pp
|
|
This should of course not be enabled on production systems. Because it
|
|
may give a user root access without having to log in. However, for
|
|
board bringup and system debugging it can come in handy.
|
|
.Pp
|
|
One can also use the
|
|
.Cm service
|
|
directive to start a stand-alone shell:
|
|
.Bd -unfilled -offset indent
|
|
service [12345] /bin/sh -l
|
|
.Ed
|
|
.Pp
|
|
.It Cm tty Oo LVLS Oc Ao COND Ac Oo notty Oc Oo rescue Oc
|
|
The third
|
|
.Cm tty
|
|
form is for board bringup and the
|
|
.Cm rescue
|
|
boot mode. No device node is required in this variant, the same output
|
|
that the kernel uses is reused for stdio. If the
|
|
.Cm rescue
|
|
option is omitted, a shell is started. The flags
|
|
.Cm nologin , noclear ,
|
|
and
|
|
.Cm nowait
|
|
are implied. If the
|
|
.Cm rescue
|
|
option is set the bundled
|
|
.Pa /libexec/finit/sulogin
|
|
is started to present a bare-bones root login prompt. If the root
|
|
(uid:0, gid:0) user does not have a password set, no rescue is possible.
|
|
.El
|
|
.Sh COMMAND MODIFIERS
|
|
The run/task/tty/service/sysv directives take modifiers, or options, to
|
|
control their behavior. This section lists them with their limitations.
|
|
All modifiers must be placed between the directive and its command.
|
|
.Bl -tag -width 1n
|
|
.It Cm @user:group
|
|
Every
|
|
.Cm run , task ,
|
|
or
|
|
.Cm service
|
|
can also list the privileges the
|
|
.Cm /path/to/cmd
|
|
should be executed with. Prefix the command with
|
|
.Cm @USR[:GRP] ,
|
|
group is optional, like this:
|
|
.Bd -unfilled -offset indent
|
|
run [2345] @joe:users logger "Hello world"
|
|
.Ed
|
|
.Pp
|
|
For multiple instances of the same command, e.g. a DHCP client or
|
|
multiple web servers, add
|
|
.Cm :ID
|
|
somewhere between the
|
|
.Cm run , task , service
|
|
keyword and the command, like this:
|
|
.Bd -unfilled -offset indent
|
|
service :80 [2345] httpd -f -h /http -p 80 -- Web server
|
|
service :8080[2345] httpd -f -h /http -p 8080 -- Old web server
|
|
.Ed
|
|
.Pp
|
|
Without the
|
|
.Cm :ID
|
|
to the service the latter will overwrite the former and only the old web
|
|
server would be started and supervised.
|
|
.It Cm log:/path/to/file
|
|
Redirect stdout/stderr of a command to the given log file. See the
|
|
global log directive, above, for details on log rotation.
|
|
.It Cm log:console
|
|
Redirect stdout/stderr of a command to
|
|
.Pa /dev/console ,
|
|
only use this for debugging or bringup.
|
|
.It Cm log:null
|
|
Redirect stdout/stderr of a command to
|
|
.Pa /dev/null .
|
|
.It Cm log:prio:facility.level,tag:ident
|
|
Redirect stdout/stderr of a command to syslog using the given priority
|
|
and tag identity.
|
|
.Bd -unfilled -offset indent
|
|
service log:prio:user.warn,tag:ntpd /sbin/ntpd pool.ntp.org -- NTP daemon
|
|
.Ed
|
|
.It Cm log
|
|
Default
|
|
.Cm prio
|
|
is
|
|
.Cm daemon.info
|
|
and the default
|
|
.Cm tag
|
|
identity is the basename of the service or run/task command.
|
|
.El
|
|
.Sh RESCUE MODE
|
|
Finit supports a rescue mode which is activated by the
|
|
.Cm rescue
|
|
option on the kernel command line. The rescue mode comes in two
|
|
flavors:
|
|
.Em traditional
|
|
and
|
|
.Em fallback .
|
|
.Ss Traditional
|
|
This is what most users expect. A very early maintenance login prompt,
|
|
served by the bundled
|
|
.Pa /libexec/finit/sulogin
|
|
program, or the standard
|
|
.Cm sulogin
|
|
from util-linux or BusyBox is searched for in the UNIX default
|
|
.Cm $PATH .
|
|
If a successful login is made, or the user exits (Ctrl-D), the rescue
|
|
mode is ended and the system boots up normally.
|
|
.Pp
|
|
.Sy Note:
|
|
if the user (UID 0 and GID 0) does not have a password, or
|
|
.Em the account is locked ,
|
|
the user is presented with a password-less prompt:
|
|
.Cm "Press enter to enter maintenance mode." ,
|
|
which opens up a root shell.
|
|
.Ss Fallback
|
|
If no
|
|
.Cm sulogin
|
|
program is found, Finit tries to bring up as much of its own
|
|
functionality as possible, yet limiting many aspects, meaning; no
|
|
network, no`fsck` of file systems in
|
|
.Pa /etc/fstab ,
|
|
no
|
|
.Pa /etc/rc.local ,
|
|
no
|
|
.Cm runparts ,
|
|
and most plugins are skipped (except those that provide functionality
|
|
for the condition subsystem).
|
|
.Pp
|
|
Instead of reading
|
|
.Pa /etc/finit.conf
|
|
et al, system configuration is read from
|
|
.Pa /lib/finit/rescue.conf ,
|
|
which can be freely modified by the system administrator.
|
|
.Pp
|
|
The bundled default `rescue.conf` contains nothing more than:
|
|
.Bd -unfilled -offset indent
|
|
runlevel 1
|
|
tty [12345] rescue
|
|
.Ed
|
|
.Pp
|
|
The
|
|
.Cm tty
|
|
has the
|
|
.Cm rescue
|
|
option set, which works similar to the board bring-up tty option
|
|
.Cm notty .
|
|
The major difference being that `sulogin` is started to query for
|
|
root/admin password. If
|
|
.Cm sulogin
|
|
is not found,
|
|
.Cm rescue
|
|
behaves like
|
|
.Cm notty
|
|
and gives a plain root shell prompt.
|
|
.Pp
|
|
If Finit cannot find
|
|
.Pa /lib/finit/rescue.conf
|
|
it defaults to:
|
|
.Bd -unfilled -offset indent
|
|
tty [12345] rescue
|
|
.Ed
|
|
.Pp
|
|
There is no way to exit the
|
|
.Em fallback
|
|
rescue mode.
|
|
.Sh SERVICE ENVIRONMENT
|
|
Finit supports sourcing environment variables from
|
|
.Pa /etc/default/* ,
|
|
or similar. This is a common pattern from SysV init scripts, where the
|
|
start/stop script is a generic script for the given service,
|
|
.Cm foo ,
|
|
and the options for the service are sourced from the file
|
|
.Pa /etc/default/foo .
|
|
Like this:
|
|
.Bd -unfilled -offset indent
|
|
/etc/default/foo:
|
|
|
|
FOO_OPTIONS=--extra-arg="bar" -s -x
|
|
|
|
/etc/finit.conf:
|
|
|
|
service [2345] env:-/etc/default/foo foo -n $FOO_OPTIONS -- Example foo daemon
|
|
.Ed
|
|
.Pp
|
|
Here the service
|
|
.Cm foo
|
|
is started with
|
|
.Op Fl -n ,
|
|
to make sure it runs in the foreground, and the with the options found
|
|
in the environment file. With the
|
|
.Cm ps
|
|
command we can see that the process is started with:
|
|
.Bd -unfilled -offset indent
|
|
foo -n --extra-arg=bar -s -x
|
|
.Ed
|
|
.Pp
|
|
.Sy Note:
|
|
the leading `-` determines if Finit should treat a missing environment
|
|
file as blocking the start of the service or not. When `-` is used, a
|
|
missing environment file does
|
|
.Em not
|
|
block the start.
|
|
.Sh SERVICE WRAPPER SCRIPTS
|
|
If your service requires to run additional commands, executed before the
|
|
service is actually started, like the systemd `ExecStartPre`, you can
|
|
use a wrapper shell script to start your service.
|
|
.Pp
|
|
The Finit service
|
|
.Cm .conf
|
|
file can be put into
|
|
.Pa /etc/finit.d/available ,
|
|
so you can control the service using
|
|
.Cm initctl .
|
|
Then use the path to the wrapper script in the Finit
|
|
.Cm .conf
|
|
service stanza. The following example employs a wrapper script in
|
|
.Pa /etc/start.d .
|
|
.Bd -unfilled
|
|
/etc/finit.d/available/program.conf:
|
|
|
|
service [235] <!> /etc/start.d/program -- Example Program
|
|
|
|
/etc/start.d/program:
|
|
|
|
#!/bin/sh
|
|
# Prepare the command line options
|
|
OPTIONS="-u $(cat /etc/username)"
|
|
|
|
# Execute the program
|
|
exec /usr/bin/program $OPTIONS
|
|
.Ed
|
|
.Pp
|
|
.Sy Note:
|
|
the example sets
|
|
.Cm <!>
|
|
to denote that it doesn't support SIGHUP. That way Finit will
|
|
stop/start the service instead of sending SIGHUP at restart/reload
|
|
events.
|
|
.Sh TEMPLATING
|
|
Finit comes with rudimentary support for templating, similar to that of
|
|
systemd. Best illustrated with an example:
|
|
.Bd -unfilled -offset indent
|
|
$ initctl show avahi-autoipd@
|
|
service :%i avahi-autoipd --syslog %i -- ZeroConf for %i
|
|
.Ed
|
|
.Pp
|
|
To enable ZeroConf for, e.g.,
|
|
.Cm eth0 ,
|
|
use
|
|
.Bd -unfilled -offset indent
|
|
$ initctl enable avahi-autoipd@eth0.conf
|
|
.Ed
|
|
.Pp
|
|
The enabled symlink will be set up to
|
|
.Cm avahi-autoipd@.conf
|
|
and every instance of
|
|
.Cm %i
|
|
will in the instantiated directive be replaced with
|
|
.Cm eth0 .
|
|
Inspect the result with:
|
|
.Bd -unfilled -offset indent
|
|
$ initctl status avahi-autoipd:eth0
|
|
.Ed
|
|
.Sh CGROUPS
|
|
There are three major cgroup configuration directives:
|
|
.Pp
|
|
.Bl -enum -offset indent -compact
|
|
.It
|
|
Global top-level group: init, system, user, or a custom group
|
|
.It
|
|
Selecting a top-level group for a set of run/task/services
|
|
.It
|
|
Per run/task/service limits
|
|
.El
|
|
.Pp
|
|
Top-level group configuration.
|
|
.Bd -unfilled -offset indent
|
|
# Top-level cgroups and their default settings. All groups mandatory
|
|
# but more can be added, max 8 groups in total currently. The cgroup
|
|
# 'root' is also available, reserved for RT processes. Settings are
|
|
# as-is, only one shorthand 'mem.' exists, other than that it's the
|
|
# cgroup v2 controller default names.
|
|
cgroup init cpu.weight:100
|
|
cgroup user cpu.weight:100
|
|
cgroup system cpu.weight:9800
|
|
.Ed
|
|
.Pp
|
|
Adding an extra cgroup
|
|
.Cm maint/
|
|
will require you to adjust the weight of the above three. We leave
|
|
.Cm init/
|
|
and
|
|
.Cm user/
|
|
as-is reducing weight of
|
|
.Cm system/
|
|
to 9700.
|
|
.Bd -unfilled -offset indent
|
|
cgroup system cpu.weight:9700
|
|
|
|
# Example extra cgroup 'maint'
|
|
cgroup maint cpu.weight:100
|
|
.Ed
|
|
.Pp
|
|
By default, the
|
|
.Cm system/
|
|
cgroup is selected for almost everything. The
|
|
.Cm init/
|
|
cgroup is reserved for PID 1 itself and its closest relatives. The
|
|
.Cm user/
|
|
cgroup is for local TTY logins spawned by getty.
|
|
.Pp
|
|
To select a different top-level cgroup, e.g.
|
|
.Cm maint/ ,
|
|
one can either define it for a group of run/task/service directives in a
|
|
.Cm .conf
|
|
or per each stanza:
|
|
.Bd -unfilled -offset indent
|
|
cgroup.maint
|
|
service [...] <...> /path/to/foo args -- description
|
|
service [...] <...> /path/to/bar args -- description
|
|
.Ed
|
|
.Pp
|
|
or
|
|
.Bd -unfilled -offset indent
|
|
service [...] <...> cgroup.maint /path/to/foo args -- description
|
|
.Ed
|
|
.Pp
|
|
The latter form also allows per-stanza limits on the form (notice the
|
|
single quotes for arguments that contain spaces):
|
|
.Bd -unfilled -offset indent
|
|
service [...] <...> cgroup.maint:cpu.max:'200000 100000',mem.max:655360 /path/to/foo args -- description
|
|
.Ed
|
|
.Pp
|
|
Notice the comma separation and the
|
|
.Cm mem.
|
|
exception to the rule: every cgroup setting maps directly to cgroup v2
|
|
syntax. I.e.,
|
|
.Cm cpu.max
|
|
maps to the file
|
|
.Pm /sys/fs/cgroup/maint/foo/cpu.max .
|
|
There is no filtering, except for expanding the shorthand
|
|
.Cm mem.
|
|
to
|
|
.Cm memory. ,
|
|
if the file is not available, either the cgroup controller is not
|
|
available in your Linux kernel, or the name is misspelled.
|
|
.Pp
|
|
Linux cgroups and details surrounding values are not explained in the
|
|
Finit documentation. The Linux admin-guide cover this well:
|
|
.Lk https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html
|
|
.Sh CONDITIONAL LOADING
|
|
Finit support conditional loading of stanzas. The following example is
|
|
take from the
|
|
.Pa system/hotplug.conf
|
|
file in the Finit distribution. Here we only show a simplified subset.
|
|
.Pp
|
|
Starting with the
|
|
.Cm nowarn
|
|
option.
|
|
.Bd -unfilled -offset indent
|
|
service nowarn name:udevd pid:udevd /lib/systemd/systemd-udevd
|
|
service nowarn name:udevd pid:udevd udevd
|
|
.Ed
|
|
.Pp
|
|
When loading the .conf file Finit looks for
|
|
.Pa /lib/systemd/systemd-udevd
|
|
if that is not found Finit automatically logs a warning. The
|
|
.Cm nowarn
|
|
option disables this warning so that the second line can be evaluated,
|
|
which also provides a service named
|
|
.Cm udevd .
|
|
.Bd -unfilled -offset indent
|
|
run nowarn if:udevd <pid/udevd> :1 udevadm settle -t 0
|
|
.Ed
|
|
.Pp
|
|
This line is only loaded if we know of a service named
|
|
.Cm udevd .
|
|
Again, we do not warn if
|
|
.Cm udevadm
|
|
is not found, execution will also stop here until the PID condition is
|
|
asserted, i.e., Finit detecting udevd has started.
|
|
.Bd -unfilled -offset indent
|
|
run nowarn conflict:udevd [S] mdev -s -- Populating device tree
|
|
.Ed
|
|
.Pp
|
|
If
|
|
.Cm udevd
|
|
is not available, we try to run
|
|
.Cm mdev ,
|
|
but if that is not found, again we do not warn.
|
|
.Pp
|
|
Conditional loading statements can also be negated, so the previous stanza
|
|
can also be written as:
|
|
.Bd -unfilled -offset indent
|
|
run nowarn if:!udevd [S] mdev -s -- Populating device tree
|
|
.Ed
|
|
.Pp
|
|
The reason for using
|
|
.Cm conflict
|
|
in this example is that a conflict can be resolved. Stanzas marked with
|
|
.C, conflict:foo
|
|
are rechecked at runtime.
|
|
.Sh CONDITIONAL EXECUTION
|
|
Similar to conditional loading of stanzas there is conditional runtime
|
|
execution. This can be confusing at first, since Finit already has a
|
|
condition subsystem, but this is more akin to the qualification to a
|
|
runlevel. E.g., a
|
|
.Cm task [123]
|
|
is qualified to run only in runlevel 1, 2, and 3. It is not considered
|
|
for other runlevels.
|
|
.Pp
|
|
Conditional execution qualify a run/task/service based on a condition.
|
|
Consider this (simplified) example from the Infix operating system:
|
|
.Bd -unfilled -offset indent
|
|
run [S] name:startup <pid/sysrepo> confd -b --load startup-config
|
|
run [S] if:<usr/fail-startup> name:failure <pid/sysrepo> confd --load failure-config
|
|
.Ed
|
|
.Pp
|
|
The two run statements reside in the same .conf file so Finit runs them
|
|
in true sequence. If loading the file
|
|
.Cm startup-config
|
|
fails
|
|
.Cm confd
|
|
sets the condition
|
|
.Cm usr/fail-startup ,
|
|
thus allowing the next run statement to load
|
|
.Cm failure-config .
|
|
.Pp
|
|
Notice the critical difference between the
|
|
.Cm <pid/sysrepo>
|
|
condition and
|
|
.Cm if:<usr/fail-startup> .
|
|
The former is a condition for starting and the latter is a condition to
|
|
check if a run/task/service is qualified to even be considered.
|
|
.Pp
|
|
Conditional execution statements can also be negated, so provided the
|
|
file loaded did the opposite, i.e., set a condition on success, the
|
|
previous stanza can also be written as:
|
|
.Bd -unfilled -offset indent
|
|
run [S] if:<!usr/startup-ok> name:failure <pid/sysrepo> confd ...
|
|
.Ed
|
|
.Sh LIMITATIONS
|
|
As of Finit v4 there are no limitations to where
|
|
.Cm .conf
|
|
settings can be placed. Except for the system/global
|
|
.Cm rlimit
|
|
and
|
|
.Cm cgroup
|
|
top-level group declarations, which can only be set from
|
|
.Pa /etc/finit.conf ,
|
|
since it is the first
|
|
.Cm .conf
|
|
file Finit reads.
|
|
.Pp
|
|
Originally,
|
|
.Pp /etc/finit.conf
|
|
was the only way to set up a Finit system. Today it is mainly used for
|
|
bootstrap settings like system hostname, early module loading for
|
|
watchdogd, network bringup and system shutdown. These can now also be
|
|
set in any
|
|
.Cm .conf
|
|
file in
|
|
.Pa /etc/finit.d .
|
|
.Pp
|
|
There is, however, nothing preventing you from having all configuration
|
|
settings in
|
|
.Pa /etc/finit.conf .
|
|
.Sh SEE ALSO
|
|
.Xr finit 8 ,
|
|
.Xr initctl 8
|
|
.Sh AUTHORS
|
|
.Nm Finit
|
|
was conceived and reverse engineered by Claudio Matsuoka. Since v1.0,
|
|
maintained by Joachim Wiberg, with contributions by many others.
|