diff --git a/doc/cmdline.md b/doc/cmdline.md index bfc30a2c..2732a5cd 100644 --- a/doc/cmdline.md +++ b/doc/cmdline.md @@ -41,7 +41,7 @@ The `bool` setting is one of `on, off, true false, 1, 0`. Useful when starting up in various [rescue mode][rescue], factory, or production test setups. Use the top-level configuration file - directive `rcsd /path/to/finit.d` to override the default rcS.d + setting `rcsd = "/path/to/finit.d"` to override the default rcS.d directory. * `finit.debug[=bool]`: Enable finit debug. This is operated @@ -104,8 +104,9 @@ The `bool` setting is one of `on, off, true false, 1, 0`. * `single`, or `S`: Overrides the configured runlevel (default: 2) to go to after bootstrap by forcing it to runlevel 1, this is also known as single user mode. Useful to debug startup problems. All services - and TTYs in `[1]` will be started, so a `tty [1] @console nologin` - configuration presents you with a root console without login. + and TTYs in runlevel 1 will be started, so a `tty` block with + `runlevel = "1"`, `device = "@console"`, and `nologin = true` + presents you with a root console without login. * `1-9`, except `6`: override the configured `runlevel`. Like the `S` and `rescue`, giving a single number on the kernel command line tells diff --git a/doc/conditions.md b/doc/conditions.md index d16ebaa3..bb425c4e 100644 --- a/doc/conditions.md +++ b/doc/conditions.md @@ -7,12 +7,11 @@ mechanism for common synchronization problems. For example: - *"wait for service A to start before starting service B"*, or - *"wait for basic network access to be available"* -Conditions are similar in syntax to declaring runlevels per service. -They are specified within angle brackets `<>` and can be applied to any -of the `service`, `task`, or `run` stanza. Multiple conditions may be -specified separated by comma. Multiple conditions are logically AND'ed +A condition is named in the `conditions` list of a `service`, `task`, or +`run` block. The list may hold several, and they are logically AND'ed during evaluation, i.e. all conditions must be satisfied in order for a -service to run. +service to run. In running text, and in `initctl` output, a condition +is written inside angle brackets, ``. One prefix can be used on a condition: @@ -188,15 +187,15 @@ The `devmon` (built-in) plugin monitors `/dev` and `/dev/dir` for device nodes being created and removed. It is active only when a run, task, or service has declared a `` or `` condition. -The `pidfile` plugin (recursively) watches `/run/` (recursively) for PID -files created by the monitored services, and sets a corresponding -condition in the `pid/` namespace. +The `pidfile` plugin recursively watches `/run/` for PID files created +by the monitored services, and sets a corresponding condition in the +`pid/` namespace. Similarly, the `netlink` plugin provides basic conditions for when an interface is brought up/down and when a default route (gateway) is set, in the `net/` namespace. -The `sys` and `usr` plugins monitor are passive condition monitors where +The `sys` and `usr` plugins are passive condition monitors where the action is provided by `keventd`, signal handlers, and in the case of `usr`, the end-user via the `initctl` tool. @@ -266,8 +265,8 @@ its conditions are cleared and reasserted, ensuring dependent services are properly updated. Daemons that don't create PID files, or fail to touch them on reload, -can be worked around by using the `pid:/path/to/file.pid` syntax in -the service stanza for the daemon. It is far from optimal since any +can be worked around by setting `pidfile` and `pidfile-create` in the +service block for the daemon. It is far from optimal since any synchronization of depending services may fail due to the daemon not having reinitialized/created their IPC sockets, or similar. diff --git a/doc/config/cgroups.md b/doc/config/cgroups.md index 6e96824f..2e17d061 100644 --- a/doc/config/cgroups.md +++ b/doc/config/cgroups.md @@ -1,19 +1,17 @@ -Finit provides three different cgroup directives for controlling resource allocation: +Finit has two `cgroup` blocks for controlling resource allocation: - 1. **Top-level cgroup definition**: `cgroup NAME settings` - - Defines a top-level cgroup (e.g., `init`, `system`, `user`) with default settings - - Space-separated syntax - - Example: `cgroup system cpu.weight:9700` + 1. **Top-level definition**, at file scope: declares a group such as + `init`, `system`, or `user`, and its default settings. - 2. **Global cgroup selector**: `cgroup.NAME[,options]` (standalone directive) - - Sets the default cgroup for subsequent services in a `.conf` file - - Dot-separated with optional comma-separated options - - Example: `cgroup.maint` or `cgroup.system,delegate` + cgroup system { cpu.weight = 9700 } - 3. **Per-service cgroup option**: `cgroup.NAME[,options]` or `cgroup:options` - - Overrides the cgroup for a specific service - - Part of the service directive line - - Example: `service [...] cgroup.maint,mem.max:1G /path/to/cmd` + 2. **Joining a group**, inside a service block: names the group this + service runs in, and may override settings for itself alone. + + service foo { + cgroup maint { memory.max = 1G } + command = "/path/to/cmd" + } > [!NOTE] > Linux cgroups and details surrounding values are not explained in the @@ -84,11 +82,11 @@ apply to that service alone: > joins a group says so itself, so the group cannot depend on what came > earlier in the file. -Note the `mem.` exception to the rule: every cgroup setting maps directly to -cgroup v2 syntax. I.e., `cpu.max` maps to the file `/sys/fs/cgroup/maint/foo/cpu.max`. -There is no filtering, except for expanding the shorthand `mem.` to `memory.`. -If the file is not available, either the cgroup controller is not available -in your Linux kernel, or the name is misspelled. +Every cgroup setting maps directly to cgroup v2 syntax, so `cpu.max` +maps to the file `/sys/fs/cgroup/maint/foo/cpu.max`. There is no +filtering, the one exception being the shorthand `mem.`, which expands +to `memory.`. If the file is not available, either the controller is +missing from your Linux kernel, or the name is misspelled. ### Overriding Cgroup Leaf Names @@ -229,7 +227,7 @@ Initially, the service process runs directly in the cgroup root: Once the container runtime creates child cgroups (e.g., `libpod-*/`), cgroups v2 enforces the "no internal processes" rule. When Finit detects this (`EBUSY` error), -it automatically creates an `supervisor/` subdirectory and moves service-related +it automatically creates a `supervisor/` subdirectory and moves service-related processes there: /sys/fs/cgroup/system/container@web/ diff --git a/doc/config/files.md b/doc/config/files.md index 9e084d5c..22b01b1a 100644 --- a/doc/config/files.md +++ b/doc/config/files.md @@ -70,12 +70,12 @@ unique group, where files within each group are sorted alphabetically. /etc/finit.d/enabled/1-aaa.conf /etc/finit.d/enabled/1-abc.conf -The resulting combined configuration is read line by line, each `run`, +The resulting combined configuration is read in order, each `run`, `task`, and `service` added to an ordered list that ensures they are started in the same order. This is important because of the blocking -properties of the `run` statement. For an example on the relation of -`service` and `run` statements, and dependency handling between them, -see [Conditional Loading](services.md#conditional-loading), below. +properties of `run`. For an example on the relation of `service` and +`run`, and dependency handling between them, see +[Conditional Loading](services.md#conditional-loading), below. > [!NOTE] > The names `finit.conf` and `finit.d/` are only defaults. They can be @@ -84,7 +84,7 @@ see [Conditional Loading](services.md#conditional-loading), below. > > They can also be overridden from the [kernel command line](../cmdline.md) > using: `-- finit.config=/etc/bar.conf` and in that file use the -> top-level configuration directive `rcsd /path/to/finit.d`. +> top-level setting `rcsd = "/path/to/finit.d"`. Filesystem Layout ----------------- diff --git a/doc/config/logging.md b/doc/config/logging.md index 743fd34d..70959f09 100644 --- a/doc/config/logging.md +++ b/doc/config/logging.md @@ -3,8 +3,8 @@ General Logging **Syntax:** `log { size = 200k count = 5 }` -Log rotation for run/task/services using the `log` sub-option with -redirection to a log file. Global setting, applies to all services. +Log rotation for run/task/services that redirect output to a log file +with their own `log` block. Global setting, applies to all services. The size can be given as bytes, without a specifier, or in `k`, `M`, or `G`, e.g. `size = 10M`, or `size = 3G`. A value of `size = 0` disables @@ -17,22 +17,30 @@ size limit is reached. Redirecting Output ------------------ -The `run`, `task`, and `service` stanzas also allow the keyword `log` to -redirect `stderr` and `stdout` of the application to a file or syslog +The `run`, `task`, and `service` blocks take a `log` block of their own, +redirecting `stderr` and `stdout` of the application to a file or syslog using the native `logit` tool. This is useful for programs that do not support syslog on their own, which is sometimes the case when running in the foreground. -The full syntax is: +An empty block means syslog with the defaults, and three keys adjust it: - log:/path/to/file - log:prio:facility.level,tag:ident - log:console - log:null - log +| Setting | Description | +|---|---| +| `file` | Write to this path instead of syslog | +| `priority` | Syslog `facility.level`, default `daemon.info` | +| `identity` | Syslog tag, default the basename of the command | -Default `prio` is `daemon.info` and default `tag` is the basename of the -service or run/task command. +`/dev/console` and `/dev/null` are spelled as the paths they are: + + service foo { log { } command = "foo" } # syslog + service foo { log { file = "/var/log/foo" } command = "foo" } # a file + service foo { log { file = "/dev/console" } command = "foo" } # console + service foo { log { file = "/dev/null" } command = "foo" } # discard + +> [!NOTE] +> A `log` block at file scope is a different setting -- that one is the +> global rotation above, and it takes only `size` and `count`. Log rotation is controlled using the global `log` setting. diff --git a/doc/config/rescue.md b/doc/config/rescue.md index a690c150..0ce6d683 100644 --- a/doc/config/rescue.md +++ b/doc/config/rescue.md @@ -47,21 +47,22 @@ system administrator. The bundled default `rescue.conf` contains nothing more than: - runlevel 1 + runlevel = 1 tty rescue { runlevel = "12345" rescue = true } -The `tty` has the `rescue` option set, which works similar to the board -bring-up tty option `notty`. The major difference being that `sulogin` +The `tty` block has `rescue` set, which works similar to the board +bring-up setting `notty`. The major difference being that `sulogin` is started to query for root/admin password. If `sulogin` is not found, `rescue` behaves like `notty` and gives a plain root shell prompt. -If Finit cannot find `/lib/finit/rescue.conf` it defaults to: +If Finit cannot find `/lib/finit/rescue.conf` it falls back to a +built-in equivalent, which runs in every runlevel it can: tty rescue { - runlevel = "12345" + runlevel = "12345789" rescue = true } diff --git a/doc/config/runlevels.md b/doc/config/runlevels.md index bb7d97cd..905270ca 100644 --- a/doc/config/runlevels.md +++ b/doc/config/runlevels.md @@ -38,8 +38,8 @@ Example: } When bootstrap has completed, Finit moves to runlevel 2. This can be -changed in `/etc/finit.conf` using the `runlevel N` directive, or by a -script running in runlevel S that calls, e.g., `initctl runlevel 9`. +changed in `/etc/finit.conf` with `runlevel = N`, or by a script running +in runlevel S that calls, e.g., `initctl runlevel 9`. The latter is useful if startup scripts detect problems outside of Finit's control, e.g., critical services/devices missing or hardware problems. @@ -52,7 +52,7 @@ complete before proceeding to 2. Finit first stops everything that is not allowed to run in 2, and then brings up networking. Networking is expected to be available in all runlevels except: S, 1 (single user level), 6, and 0. Networking is -enabled either by the `network script` directive, or if you have an +enabled either by `network = "script"`, or if you have an `/etc/network/interfaces` file, Finit calls `ifup -a` -- at the very least the loopback interface is brought up. @@ -88,7 +88,7 @@ Networking Script or program to bring up networking, with optional arguments. -Deprecated. We recommend using dedicated task/run stanzas per runlevel, +Deprecated. We recommend using dedicated task/run blocks per runlevel, or `/etc/network/interfaces` if you have a system with `ifupdown`, like Debian, Ubuntu, Linux Mint, or an embedded BusyBox system. @@ -156,7 +156,7 @@ albeit deprecated. `rlimit` can be set globally, in `/etc/finit.conf`, or locally per each `/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. +blocks can share the same rlimits if they are in the same .conf. Miscellaneous Settings ---------------------- diff --git a/doc/config/runparts.md b/doc/config/runparts.md index ba97a569..3d57b662 100644 --- a/doc/config/runparts.md +++ b/doc/config/runparts.md @@ -25,7 +25,7 @@ with the debug flag. **Limitations:** Scripts called from `runparts`, or hook scripts (see below), are limited -in their interaction with Finit. Like the standalone `run` stanza and +in their interaction with Finit. Like a standalone `run` block and the `/etc/rc.local` shell script, Finit waits for their completion before continuing. None of them can issue commands to start, stop, or restart other services. Also, ensure all your services and programs @@ -40,13 +40,13 @@ either terminate or start in the background or you will block Finit. It can be beneficial to use `01-name`, `02-othername`, etc., to ensure the scripts are started in that order, e.g., if there is a dependency -order between scripts. Symlinks to existing daemons can talso be used, +order between scripts. Symlinks to existing daemons can also be used, but make sure they daemonize (background) themselves properly, otherwise Finit will lock up. If `S[0-9]foo` and `K[0-9]bar` style naming is used, the executable will be called with an extra argument, `start` and `stop`, respectively. E.g., `S01foo` will be called as `S01foo start`. Of course, `S01foo` -and `K01foo` may be a symlink to to `another/directory/foo`. +and `K01foo` may be a symlink to `another/directory/foo`. [run-parts(8)]: http://manpages.debian.org/cgi-bin/man.cgi?query=run-parts diff --git a/doc/config/service-opts.md b/doc/config/service-opts.md index e5bb5bfd..7c5ef7da 100644 --- a/doc/config/service-opts.md +++ b/doc/config/service-opts.md @@ -58,7 +58,8 @@ Other run/task/service settings are: * `notify` -- see [Service Synchronization](service-sync.md) * `if` -- see [Conditional Execution](services.md#conditional-execution) * `type = "forking"` -- see description of the [service](services.md) block - * a leading `-` on `command` -- see [Conditional Loading](services.md#conditional-loading) + * a leading `-` on `command` -- see + [Conditional Loading](services.md#conditional-loading) Restarting ---------- @@ -68,13 +69,14 @@ on the configuration and conditions. Within the confines of that the following settings are available: * `restart-max = NUM` -- number of times Finit tries to restart a - crashing service, default: 10, max: 255. When this limit is - reached the service is marked *crashed* and must be restarted - manually with `initctl restart NAME` + crashing service, default: 10. When this limit is reached the + service is marked *crashed* and must be restarted manually with + `initctl restart NAME` * `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 + restart a crashing service. The default is 2 seconds for the first + half of `restart-max` attempts, then a back-off to 5 seconds -- with + the default `restart-max` that is the first five retries. The + greater of this configured value and the back-off is used * `restart = "always"` -- no upper limit on the number of times Finit tries to restart a crashing service * `restart = "never"` -- do not restart on failures. `false` is @@ -168,7 +170,7 @@ accident: When a run/task/sysv/service is removed (disable + reload) it is first stopped and then removed from the runlevel. The `exec-stop-post` script always runs when the process has stopped, and `exec-cleanup` -runs when the stanza has been removed from the runlevel. +runs when the block has been removed from the runlevel. > [!IMPORTANT] > These script actions are intended for setup, cleanup, and readiness diff --git a/doc/config/service-sync.md b/doc/config/service-sync.md index 1cf05319..079dc0e2 100644 --- a/doc/config/service-sync.md +++ b/doc/config/service-sync.md @@ -32,7 +32,7 @@ notification is available, and the native PID file mode of operation is, as of Finit v4.6 optional, by default it is still enabled, but this can be changed in `finit.conf`: - readiness none + readiness = "none" This will be made the default in Finit 5.0. In this mode of operation, every service needs to explicitly declare their readiness notification, @@ -43,10 +43,10 @@ like this: service bar { notify = "s6" command = "bar" } service qux { notify = "none" command = "qux" } -The `notify = "none"` setting is for completeness in systems which run in -`readiness pid` mode (default). Services declared with `notify = "none"` -will transition to ready as soon as Finit has started them, e.g., -`service/qux/ready`. +The `notify = "none"` setting is for completeness in systems which run +in `readiness = "pid"` mode (default). Services declared with +`notify = "none"` will transition to ready as soon as Finit has started +them, e.g., `service/qux/ready`. To synchronize two services the following condition can be used: @@ -60,7 +60,7 @@ To synchronize two services the following condition can be used: command = "stress-ng --cpu 8" } -For details on the syntax and options, see below. +For the full list of conditions, see [Finit Conditions](../conditions.md). > [!NOTE] > On `initctl reload` conditions are set in "flux", while figuring out @@ -73,7 +73,7 @@ For details on the syntax and options, see below. > However, the s6 notify mode does not support this because in s6 you > are expected to close your notify descriptor after having written > `\n`. This means s6 style daemons currently must be stop-started. -> (Declare the service with `` in its condition statement.) +> (Declare the service with `reload-signal = "none"`.) > > For default, PID file style readiness notification, daemons are > expected to either create their PID files, or touch it using diff --git a/doc/config/service-wrappers.md b/doc/config/service-wrappers.md index f0d125a8..e4fb9798 100644 --- a/doc/config/service-wrappers.md +++ b/doc/config/service-wrappers.md @@ -7,7 +7,7 @@ use a wrapper shell script to start your service. The Finit service `.conf` file can be put into `/etc/finit.d/available`, so you can control the service using `initctl`. Then use the path to -the wrapper script in the Finit `.conf` service stanza. The following +the wrapper script in the Finit `.conf` service block. The following example employs a wrapper script in `/etc/start.d`. **Example:** @@ -31,6 +31,6 @@ example employs a wrapper script in `/etc/start.d`. exec /usr/bin/program $OPTIONS > [!NOTE] -> The example sets `` to denote that it doesn't support `SIGHUP`. -> That way Finit will stop/start the service instead of sending SIGHUP -> at restart/reload events. +> The example sets `reload-signal = "none"` to say the program does not +> support `SIGHUP`. Finit then stop/starts the service instead of +> signalling it at restart/reload events. diff --git a/doc/config/services.md b/doc/config/services.md index 8070acbd..857a335e 100644 --- a/doc/config/services.md +++ b/doc/config/services.md @@ -7,10 +7,11 @@ 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 *crashed*. After which they have to be manually restarted with `initctl restart NAME`. The -limits controlling this are configurable, see the options below. +limits controlling this are configurable, see +[Service Options](service-opts.md). > [!TIP] -> To allow endless restarts, see the [`respawn` option](service-opts.md) +> To allow endless restarts, see [`respawn`](service-opts.md#restarting) For daemons that support it, we recommend appending `--foreground`, `--no-background`, `-n`, `-F`, or similar command line argument to @@ -59,11 +60,11 @@ prevent it from forking to the background: `runlevel` denotes the runlevels `ospfd` is allowed to run in, it is optional and defaults to level 2-4 if omitted. -`conditions` lists what must be asserted before starting `ospfd`. In this example Finit -waits for another service, `zebra`, to have created its PID file in -`/var/run/quagga/zebra.pid` before starting `ospfd`. Finit watches -*all* files in `/var/run`, for each file named `*.pid`, or `*/pid`, -Finit opens it and find the matching `NAME:ID` using the PID. +`conditions` lists what must be asserted before starting `ospfd`. In +this example Finit waits for another service, `zebra`, to have created +its PID file in `/var/run/quagga/zebra.pid`. Finit watches *all* files +in `/var/run`, for each file named `*.pid`, or `*/pid`, Finit opens it +and finds the matching `NAME:ID` using the PID. A condition may be prefixed with `~` to propagate a reload of the upstream service to this one, rather than merely pausing and resuming @@ -216,8 +217,8 @@ web server would be started and supervised. Conditional Loading ------------------- -Finit support conditional loading of stanzas. The following example is -take from the `system/hotplug.conf` file in the Finit distribution. +Finit supports conditional loading of blocks. The following example is +taken from the `system/10-hotplug.conf` file in the Finit distribution. Here we only show a simplified subset. Starting with the leading `-` on `command`. @@ -235,7 +236,7 @@ Starting with the leading `-` on `command`. When loading the .conf file Finit looks for `/lib/systemd/systemd-udevd`, and if that is not found it logs a warning. The leading `-` says a missing binary is expected here, so -the stanza is skipped quietly and the second block can be evaluated, +the block is skipped quietly and the second one can be evaluated, which also provides a service named `udevd`. run udevadm:1 { @@ -245,7 +246,7 @@ which also provides a service named `udevd`. command = "-udevadm settle -t 0" } -This line is only loaded if we know of a service named `udevd`. Again, +This block is only loaded if we know of a service named `udevd`. Again, we do not warn if `udevadm` is not found, execution will also stop here until the PID condition is asserted, i.e., Finit detecting udevd has started. @@ -260,8 +261,8 @@ started. If `udevd` is not available, we try to run `mdev`, but if that is not found, again we do not warn. -Conditional loading statements can also be negated, so the previous -stanza can also be written as: +Conditional loading can also be negated, so the previous block can be +written as: run mdev { description = "Populating device tree" @@ -270,18 +271,19 @@ stanza can also be written as: command = "-mdev -s" } -The reason for using `conflict` in this example is that a conflict can be -resolved. Stanzas naming a conflict are rechecked at runtime. +The reason for using `conflicts` in this example is that a conflict can +be resolved. Blocks naming a conflict are rechecked at runtime. Conditional Execution --------------------- -Similar to conditional loading of stanzas there is conditional runtime +Similar to conditional loading of blocks 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 `task [123]` is qualified to run only in runlevel 1, -2, and 3. It is not considered for other runlevels. +runlevel. E.g., a task with `runlevel = "123"` is qualified to run +only in runlevel 1, 2, and 3. It is not considered for other +runlevels. Conditional execution qualify a run/task/service based on a condition. Consider this (simplified) example from the Infix operating system: @@ -299,10 +301,10 @@ Consider this (simplified) example from the Infix operating system: command = "confd --load failure-config" } -The two run statements reside in the same .conf file so Finit runs them -in true sequence. If loading the file `startup-config` fails confd sets -the condition `usr/fail-startup`, thus allowing the next run statement -to load `failure-config`. +The two run blocks reside in the same .conf file so Finit runs them in +true sequence. If loading the file `startup-config` fails confd sets +the condition `usr/fail-startup`, thus allowing the next one to load +`failure-config`. Notice the critical difference between the `conditions` list and `if`. The former is a condition for starting; the latter is a condition to @@ -310,9 +312,13 @@ check whether a run/task/service is qualified to even be considered. `if` has a negation of its own, `!`, which is unrelated to anything in the `conditions` list. -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: +What `if` compares against depends on the angle brackets: `if = "udevd"` +asks whether a service by that name is known, decided when the .conf is +read, while `if = ""` tests a condition at runtime. + +Conditional execution can also be negated, so provided the file loaded +did the opposite, i.e., set a condition on success, the previous block +can be written as: run failure { runlevel = "S" diff --git a/doc/config/sysv.md b/doc/config/sysv.md index 2a59a7c8..4f844ed3 100644 --- a/doc/config/sysv.md +++ b/doc/config/sysv.md @@ -11,34 +11,36 @@ SysV Init Scripts **Syntax:** `sysv NAME { command = "/path/to/init-script" }` -> `` is described in the [Services](services.md) section. +> [!NOTE] +> Conditions, runlevels, and the other settings a `sysv` block takes +> are described in [Service Options](service-opts.md). -Similar to `task` is the `sysv` stanza, which can be used to call SysV -style scripts. The primary intention for this command is to be able to -reuse much of existing setup and init scripts in Linux distributions. +A `sysv` block is a supervised daemon, like `service`, but started and +stopped through a SysV style init script instead of a command line. The +intention is to reuse existing setup and init scripts from Linux +distributions. When entering an allowed runlevel, Finit calls `init-script start`, when entering a disallowed runlevel, Finit calls `init-script stop`, and if -the Finit .conf, where `sysv` stanza is declared, is modified, Finit +the Finit .conf, where the `sysv` block is declared, is modified, Finit calls `init-script restart` on `initctl reload`. Similar to how -`service` stanzas work. +`service` blocks work. Forking services started with `sysv` scripts can be monitored by Finit by declaring the PID file to look for: `pidfile = "/path/to/file.pid"`. Finit does not create that file, it watches it for the resulting -forked-off PID, which is the default; `pidfile-create = true` is what -asks Finit to write it instead. This -syntax also works for forking daemons that do not have a command line -option to run it in the foreground, more on this below in `service`. +forked-off PID. That is the default; `pidfile-create = true` asks Finit +to write it instead. The same applies to forking daemons with no way to +run in the foreground, see [Services](services.md). > [!TIP] > See also [SysV Init Compatibility](#sysv-init-compatibility). -`runparts DIRECTORY` --------------------- +Run-parts +--------- For a directory with traditional start/stop scripts that should run, in -order, at bootstrap, Finit provides the `runparts` directive. It runs +order, at bootstrap, Finit provides the `runparts` setting. It runs in runlevel S, at the very end of it (before calling `/etc/rc.local`) making it perfect for most scenarios. @@ -89,6 +91,7 @@ it exists, and is executable. It is called very late in the boot process when the system has left runlevel S, stopped all old and started all new services in the target runlevel (default 2). +> [!NOTE] > In Finit releases before v4.5 this script blocked Finit execution and > made it as good as impossible to call `initctl` during that time. diff --git a/doc/config/task-and-run.md b/doc/config/task-and-run.md index 17f9c7f7..a86d854e 100644 --- a/doc/config/task-and-run.md +++ b/doc/config/task-and-run.md @@ -3,7 +3,8 @@ run (sequence) **Syntax:** `run NAME { command = "/path/to/cmd ARGS" }` -> `` is described in the [Services](services.md) section. +> Conditions, runlevels, and the other settings a `run` block takes are +> described in [Service Options](service-opts.md). One-shot command to run in sequence when entering a runlevel, with optional arguments and description. `run` commands are guaranteed to be @@ -33,7 +34,8 @@ task (parallel) **Syntax:** `task NAME { command = "/path/to/cmd ARGS" }` -> `` is described in the [Services](services.md) section. +> A `task` block takes the same settings as `run`, see +> [Service Options](service-opts.md). One-shot like 'run', but starts in parallel with the next command. @@ -93,7 +95,7 @@ The firewall rules are created once. The `exec-stop-post` script runs when entering runlevel 0 (halt) or 6 (reboot), or on explicit stop. > [!NOTE] -> The `remain-after-exit` option is not supported for bootstrap-only +> The `remain-after-exit` setting is not supported for bootstrap-only > tasks (tasks with only runlevel S). Bootstrap tasks are deleted > immediately after completion, and their `exec-stop-post` scripts never > run. A warning is logged if `remain-after-exit` is used on such tasks. diff --git a/doc/config/templating.md b/doc/config/templating.md index 4faed67f..50a25de5 100644 --- a/doc/config/templating.md +++ b/doc/config/templating.md @@ -17,8 +17,8 @@ To enable ZeroConf for, e.g., `eth0`, use The enabled symlink will be set up to `avahi-autoipd@.conf` and every instance of `%i` will be replaced with `eth0` before the file is parsed, so it works in the block title, in any value, and in the -command line alike. Inspect the resulting instantiated template with `initctl show -avahi-autoipd:eth0` and check the status of a running instance with: +command line alike. Inspect the result with `initctl show +avahi-autoipd:eth0`, and check a running instance with: ``` $ initctl status avahi-autoipd:eth0 diff --git a/doc/config/tty.md b/doc/config/tty.md index 616e504b..945c5f2a 100644 --- a/doc/config/tty.md +++ b/doc/config/tty.md @@ -28,8 +28,8 @@ The `device` variant takes two more: | `baud` | Baud rate, default 0, i.e., keep kernel default | | `term` | `$TERM` value, e.g. `"vt220"` | -> The `tty` stanza inherits runlevel, condition (and other feature) -> parsing from the `service` stanza. So TTYs can run in one or many +> A `tty` block inherits runlevel, condition (and other feature) +> parsing from the `service` block. 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 `` before starting a TTY. @@ -47,13 +47,13 @@ The second `tty` syntax variant is for using an external getty, like agetty or the BusyBox getty. The third variant is for board bringup and the `rescue` boot mode. No -device node is required in this variant, the same output that the kernel -uses is reused for stdio. If the `rescue` option is omitted, a shell is -started (`nologin`, `noclear`, and `nowait` are implied), if the rescue -option is set the bundled `/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. For more information, -see the [Rescue Mode](rescue.md) section. +device node is required, the same output the kernel uses is reused for +stdio. With `notty` a shell is started (`nologin`, `noclear`, and +`nowait` are implied); with `rescue` the bundled +`/libexec/finit/sulogin` presents a bare-bones root login prompt. If +the root (uid:0, gid:0) user does not have a password set, no rescue is +possible. For more information, see the [Rescue Mode](rescue.md) +section. By default, the first two syntax variants *clear* the TTY and *wait* for the user to press enter before starting getty. @@ -71,27 +71,24 @@ the user to press enter before starting getty. nowait = true } -The `noclear` option disables clearing the TTY after each session. +The `noclear` setting disables clearing the TTY after each session. Clearing the TTY when a user logs out is usually preferable. -The `nowait` option disables the `press Enter to activate console` +The `nowait` setting disables the `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. -The `nologin` option disables getty and `/bin/login`, and gives the -user a root (login) shell on the given TTY `` immediately. +The `nologin` setting disables getty and `/bin/login`, and gives the +user a root (login) shell on the given TTY immediately. Needless to say, this is a rather insecure option, but can be very useful for developer builds, during board bringup, or similar. -Notice the ordering, the `TERM` option to the built-in getty must be -the last argument. - Embedded systems may want to enable automatic `DEV` by supplying the -special `@console` device. This works regardless weather the system +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`. The speed -can be omitted to keep the kernel default. +it out by querying sysfs: `/sys/class/tty/console/active`. Leave +`baud` out to keep the kernel default. > Most systems get by fine by just using `console`, which will evaluate > to `/dev/console`. If you have to use `@console` to get any output, @@ -119,7 +116,7 @@ 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. -One can also use the `service` stanza to start a stand-alone shell: +One can also use a `service` block to start a stand-alone shell: service shell { runlevel = "12345" @@ -129,23 +126,23 @@ One can also use the `service` stanza to start a stand-alone shell: Controlling TTY for Services ---------------------------- -The `tty:` option gives a `run`, `task`, or `service` a controlling +The `tty` setting gives a `run`, `task`, or `service` a controlling terminal on the given device. The device is opened, set as the controlling terminal for the session (after `setsid()`), and connected to the process's stdin, stdout, and stderr. A default `TERM` environment variable is set based on the device type: `vt102` for serial lines and `linux` for virtual terminals. -`` may be a device node like `/dev/ttyS0`, or the special keyword -`@console` (see above). Note that `@console` expands only to the -first console, not all. +The value may be a device node like `/dev/ttyS0`, or the special +keyword `@console` (see above). Note that `@console` expands only to +the first console, not all. -When `tty:` is combined with `log:`, stdout and stderr are redirected -to the log sink instead of the TTY, but stdin remains connected to the -TTY device. +When `tty` is combined with a `log` block, stdout and stderr are +redirected to the log sink instead of the TTY, but stdin remains +connected to the TTY device. -> The `tty:` option is for `run`, `task`, and `service` stanzas only. -> The `tty` directive itself (for getty/login) has its own syntax, see +> The `tty` setting is for `run`, `task`, and `service` blocks only. +> A `tty` block (for getty/login) is a different thing entirely, see > above. **Example:** diff --git a/doc/example.md b/doc/example.md index cd47fdb1..597d7208 100644 --- a/doc/example.md +++ b/doc/example.md @@ -132,7 +132,7 @@ tty tty3 { #tty console { runlevel = "12345" device = "@console" noclear = true nologin = true } ``` -The `service` stanza, as well as `task`, `run` and others are described in +The `service` block, as well as `task`, `run` and others are described in full in the [Services Syntax](config/services.md) section. Here's a quick overview of some of the most common components needed to start diff --git a/doc/features.md b/doc/features.md index 564db42a..48220525 100644 --- a/doc/features.md +++ b/doc/features.md @@ -40,21 +40,21 @@ see the [TTY and Consoles](config/tty.md) section. **Runlevels** Support for SysV init-style [runlevels][5] 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. +minimal style as everything else in Finit. The `runlevel` setting +applies to service, task, run, and tty blocks alike. 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` +networking here. The configured `runlevel` 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 +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`](initctl.md) tool. +by using a `run` block with `runlevel = "S"`. Changing runlevels at +runtime is done like any other init, e.g. init 4, but also +using the more advanced [`initctl`](initctl.md) tool. **Conditions** @@ -222,7 +222,7 @@ 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: +declared as such in their service block like this: service foo { cgroup root {} diff --git a/doc/plugins.md b/doc/plugins.md index 5a889677..36b6ddde 100644 --- a/doc/plugins.md +++ b/doc/plugins.md @@ -70,7 +70,7 @@ For your convenience a set of *optional* plugins are available: name of the module to load. Any line starting with the standard UNIX comment character, `#`, or `;`, is skipped. - Modules are by default loaded in runlevel `S` using the `task` stanza. + Modules are by default loaded in runlevel `S` using a `task` block. Each module is named `modprobe.foo`, with an optional `:ID`. The runlevel can be changed per file using: diff --git a/doc/runparts.md b/doc/runparts.md index 94a9daaa..7d0605a5 100644 --- a/doc/runparts.md +++ b/doc/runparts.md @@ -3,18 +3,18 @@ Runparts & `/etc/rc.local` At the end of the boot, when all bootstrap (`S`) tasks and services have started, but not networking, Finit calls its built-in [run-parts(8)][] -command on any configured `runparts ` directory. This happens just +command on any configured `runparts = "DIR"` directory. This happens just before changing to the configured runlevel (default 2). (Networking is enabled just prior to changing from single user mode.) -```shell -runparts /etc/rc.d/ +```aconf +runparts = "/etc/rc.d/" ``` Right after the runlevel change when all services have started properly, `/etc/rc.local` is called. -No configuration stanza in `/etc/finit.conf` is required for `rc.local`. +No setting in `/etc/finit.conf` is required for `rc.local`. If it exists and is an executable shell script Finit calls it at the very end of the boot, before calling the `HOOK_SYSTEM_UP`. See more in the [Hook Scripts](plugins.md#hooks) section. diff --git a/src/rescue.conf b/src/rescue.conf index 69231099..c46f9569 100644 --- a/src/rescue.conf +++ b/src/rescue.conf @@ -1,2 +1,5 @@ -runlevel 1 -tty [12345] rescue +runlevel = 1 +tty rescue { + runlevel = "12345" + rescue = true +}