Finit Features¶
This page highlights some of Finit's key features with examples and usage scenarios. For complete documentation, configuration syntax, and advanced options, see the Configuration section.
Process Supervision
Start, monitor and restart services should they fail.
Getty
Finit supports external getty but also comes with a limited built-in
Getty, useful for really small systems. A getty sets up the TTY and
waits for user input before handing over to /bin/login, which is
responsible for handling the actual authentication.
tty [12345] /dev/tty1 nowait linux
tty [12345] /dev/ttyAMA0 noclear vt100
tty [12345] /sbin/getty -L /dev/ttyAMA0 vt100
Users of embedded systems may want to enable automatic serial console
with the special @console device. This works regardless whether the
system uses ttyS0, ttyAMA0, ttyMXC0, or anything else. Finit
figures it out by querying sysfs: /sys/class/tty/console/active.
Notice the optional noclear, nowait, and nologin flags. The
latter is for skipping the login process entirely. For more information,
see the TTY and Consoles section.
Runlevels
Support for SysV init-style runlevels is available, in the same
minimal style as everything else in Finit. The [2345] syntax can be
applied to service, task, run, and TTY stanzas.
Reserved runlevels are 0 and 6, halt and reboot, respectively just like
SysV init. Runlevel 1 can be configured freely, but is recommended to
be kept as the system single-user runlevel since Finit will not start
networking here. The configured runlevel NUM from /etc/finit.conf
is what Finit changes to after bootstrap, unless 'single' (or 'S') is
given on the kernel cmdline, in which case runlevel 1 is started.
All services in runlevel S) are started first, followed by the desired
run-time runlevel. Run tasks in runlevel S can be started in sequence
by using run [S] cmd. Changing runlevels at runtime is done like any
other init, e.g. init 4, but also using the more advanced
initctl tool.
Conditions
As mentioned previously, Finit has an advanced dependency system to handle synchronization, called conditions. It can be used in many ways; depend on another service, network availability, etc.
One really cool example useful for embedded systems is to run certain
scripts if a board has a certain feature encoded in its device tree. At
bootstrap we run the following ident script:
#!/bin/sh
conddir=/var/run/finit/cond/hw/model
dtmodel=/sys/firmware/devicetree/base/model
if ! test -e $dtmodel; then
exit 0
fi
model=$(cat $dtmodel | tr "[A-Z] " "[a-z]-")
mkdir -p $conddir && ln -s ../../reconf $conddir/$model
Provided the device tree node exists, and is a string, we can then use
the condition <hw/model/foo> when starting other scripts. Here is an
example:
Tip
Notice the trick with an empty description to hide the call to ident
in the Finit progress output.
Plugins
Plugins can extend the functionality of Finit and hook into the
different stages of the boot process and at runtime. Plugins are
written in C and compiled into a dynamic library loaded automatically by
finit at boot. A basic set of plugins are bundled in the plugins/
directory.
Capabilities:
- Hooks
Hook into the boot at predefined points to extend Finit - I/O
Listen to external events and control Finit behavior/services
Extensions and functionality not purely related to what an /sbin/init
needs to start a system are available as a set of plugins that either
hook into the boot process or respond to various I/O.
For more information, see the Plugins section.
Automatic Reload
By default, Finit monitors /etc/finit.d/ and /etc/finit.d/enabled/
registering any changes to .conf files. To activate a change the user
must call initctl reload, which reloads all modified files, stops any
removed services, starts new ones, and restarts any modified ones. If the
command line arguments of a service have changed, the process will be
terminated and then started again with the updated arguments. If the arguments
have not been modified and the process supports SIGHUP, the process will
receive a SIGHUP rather than being terminated and started.
For some use-cases the extra step of calling initctl reload creates an
unnecessary overhead, which can be removed at build-time using:
configure --enable-auto-reload
Linux Capabilities
Finit supports Linux capabilities, allowing services to run with minimal required privileges instead of running as root. This improves security by following the principle of least privilege.
service [2345] name:nginx \
www-data:www-data \
caps:^cap_net_bind_service \
/usr/sbin/nginx -g 'daemon off;'
In this example, nginx runs as the unprivileged www-data user but retains
the ability to bind to privileged ports (80, 443) through the
cap_net_bind_service capability.
The caps: directive uses the IAB (Inheritable, Ambient, Bounding) format:
- ^ = Ambient (recommended) - capabilities survive exec()
- % = Inheritable only - requires file capabilities
- ! = Bounding - block from acquiring capability
Multiple capabilities can be specified as comma-separated:
See the Linux Capabilities section for detailed information, examples, and security best practices.
Supplementary Groups
Finit supports supplementary groups for services, allowing them to access resources owned by multiple groups without running as root. This complements capabilities for fine-grained privilege control.
In this example, the Caddy web server runs as user caddy with primary group
caddy, but also has access to resources owned by the ssl-cert group (such
as TLS certificates).
Finit automatically reads the user's supplementary group membership from
/etc/group. Additional groups can be specified explicitly using the syntax
@user:group,sup1,sup2,....
See the Non-privileged Services section for more information.
Cgroups
Finit supports cgroups v2 and comes with the following default groups in which services and user sessions are placed in:
/sys/fs/cgroup
|-- init/ # cpu.weight:100
|-- system/ # cpu.weight:9800
`-- user/ # cpu.weight:100
Finit itself and its helper scripts and services are placed in the
top-level leaf-node group init/, which also is reserved.
All run/task/service/sysv processes are placed in their own sub-group
in system/. The name of each sub-group is taken from the respective
.conf file from /etc/finit.d.
All getty/tty processes are placed in their own sub-group in user/.
The name of each sub-group is taken from the username.
A fourth group also exists, the root group. It is also reserved and
primarily intended for RT tasks. If you have RT tasks they need to be
declared as such in their service stanza like this:
service [...] <...> cgroup.root /path/to/foo args -- description
or
cgroup.root
service [...] <...> /path/to/foo args -- description
service [...] <...> /path/to/bar args -- description
See the Cgroups section for more information, e.g., how to configure per-group limits.
The initctl tool has three commands to help debug and optimize the
setup and monitoring of cgroups. See the ps, top, and cgroup
commands for details.
Note
Systems that do not support cgroups, specifically version 2, are automatically detected. On such systems the above functionality is disabled early at boot.
Service Management
Finit includes the initctl tool for managing services and system state at
runtime. Key capabilities include:
- Enable/Disable services: Manage which services start at boot by moving
configuration files between
/etc/finit.d/availableand/etc/finit.d/enabled - Start/Stop/Restart: Control individual services without requiring a full system reboot
- Status monitoring: View service state, PID, uptime, and resource usage
- Condition management: Set and clear user-defined conditions to control service dependencies
- Cgroup monitoring: Real-time process and resource monitoring with
initctl top, similar to the traditionaltopcommand but cgroup-aware
Example commands:
initctl enable myservice # Enable service for next boot
initctl start myservice # Start service now
initctl status # Show all services
initctl top # Interactive resource monitor
initctl cond set usr/custom # Set custom condition
See the Commands & Status section for complete documentation.
Rescue Mode
Finit provides a built-in rescue mode for system recovery and maintenance.
When booting with the rescue kernel parameter, the system enters a
protected maintenance shell.
If the bundled sulogin program is available (from Finit, util-linux, or
BusyBox), you'll be prompted for the root password before accessing the
maintenance shell. This provides secure access for system recovery.
If sulogin is not available, Finit falls back to reading
/lib/finit/rescue.conf and boots the system in a limited maintenance mode.
In rescue mode, initctl will not work. After fixing the problem, use
reboot -f to force reboot.
Rescue mode can be disabled at build time with configure --without-rescue.
See the Rescue Mode section for more information.
Switch Root
Finit supports switching from an initramfs to a real root filesystem using
the built-in initctl switch-root command. This allows Finit to serve as
the init system in an initramfs for early boot tasks (LUKS unlock, LVM
activation, network boot) before transitioning to the real root.
The switch-root operation:
- Runs the
HOOK_SWITCH_ROOThook for cleanup - Stops all services gracefully
- Moves virtual filesystems (
/dev,/proc,/sys,/run) to the new root - Deletes initramfs contents to free memory
- Pivots to the new root and execs the new init
See the Switch Root section for complete documentation.