1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118
|
.\" 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.
|