From a814e85356a04535278626289345abd5375984a0 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Sun, 16 Aug 2026 12:41:24 +0200 Subject: [PATCH] doc: complete and cross-link the D-Bus documentation dbus.md was orphaned: not in dist_docs_DATA, not linked from the user guide. Wire it into the doc dist and link it from the index features list, features.md, initctl.md, and plugins.md, where the dbus.so plugin entry now disambiguates the external system bus from the built-in org.finit API. Document the 64-peer cap, the supported AddMatch keys, the busconfig policy file, the legacy-parity edge semantics with the deliberate SetRunlevel InvalidArgs divergence, the reload-signal behavior of Service1.Reload, and the reboot family timeout. Refresh the stale initctl.md usage paste, add monitor and the D-Bus transport to initctl(8), add /run/finit/bus to the filesystem layout, and flatten the ChangeLog D-Bus entry to house style. Signed-off-by: Joachim Wiberg --- doc/ChangeLog.md | 55 ++++++++++++++++++++------------------------- doc/Makefile.am | 1 + doc/config/files.md | 1 + doc/dbus.md | 37 +++++++++++++++++++++++++++--- doc/features.md | 4 ++++ doc/index.md | 1 + doc/initctl.md | 21 ++++++++--------- doc/plugins.md | 5 +++++ man/initctl.8 | 8 +++++++ 9 files changed, 89 insertions(+), 44 deletions(-) diff --git a/doc/ChangeLog.md b/doc/ChangeLog.md index d543ae28..e9c9d8d9 100644 --- a/doc/ChangeLog.md +++ b/doc/ChangeLog.md @@ -33,38 +33,31 @@ All relevant changes are documented in this file. private bus at `/run/finit/bus`, and -- opportunistically -- registering `org.finit` on the standard system bus when a `dbus-daemon` is reachable. No external `libdbus`/`sd-bus`/`GIO` - dependency. - - The bus implements the stock `org.freedesktop.DBus`, - `org.freedesktop.DBus.Peer`, `org.freedesktop.DBus.Introspectable`, - and `org.freedesktop.DBus.Properties` interfaces, plus three - Finit-specific ones: - - * `org.finit.Manager1` at `/org/finit/manager` -- - `ListServices`, `GetService`, `Start`/`Stop`/`Restart`/`Reload`, - `SetRunlevel`, `SetDebug`, `Signal`, `Suspend`, and the - `Reboot`/`Halt`/`Poweroff` triplet. Read-only properties - `Runlevel`, `PrevRunlevel`, `Version`. Signals - `ServiceStateChanged (sss)` and `RunlevelChanged (ss)`. - - * `org.finit.Service1` at `/org/finit/service/` -- one - object per loaded service, with `Start`/`Stop`/`Restart`/`Reload` - for working off an object handle rather than passing the - identity string around. - - * `org.finit.Cond1` at `/org/finit/cond` -- `Get`, `Set`, `Clear`, - `List`, `Dump` for [user-defined conditions](conditions.md), - with a `ConditionChanged (ss)` signal. - - Privileged methods accept root and members of the `--with-group` - group; everyone else is refused. On the local bus the caller's uid - and groups come straight from the kernel (`SO_PEERCRED` + - `SO_PEERGROUPS`), so the check never blocks PID 1 on an NSS lookup. - Over the system bus the uid is resolved from the broker - (`GetConnectionUnixUser`) and privileged methods are root-only. - Read-only methods are open. + dependency. The bus implements the stock `org.freedesktop.DBus`, + `Peer`, `Introspectable`, and `Properties` interfaces. See [D-Bus Integration](dbus.md) for the full surface, build flag, - and `dbus-send`/`dbus-monitor` examples. + and `dbus-send`/`dbus-monitor` examples +- New `org.finit.Manager1` interface at `/org/finit/manager`: + `ListServices`, `GetService`, `Start`/`Stop`/`Restart`/`Reload`, + `SetRunlevel`, `SetDebug`, `Signal`, `Suspend`, and the + `Reboot`/`Halt`/`Poweroff` triplet, which take a timeout argument + arming the emergency shutdown bypass like `initctl -t`. Read-only + properties `Runlevel`, `PrevRunlevel`, `Version`; signals + `ServiceStateChanged (sss)` and `RunlevelChanged (ss)` +- New `org.finit.Service1` interface at `/org/finit/service/`, + one object per loaded service, with `Start`/`Stop`/`Restart`/`Reload` + for working off an object handle rather than passing the identity + string around +- New `org.finit.Cond1` interface at `/org/finit/cond`: `Get`, `Set`, + `Clear`, `List`, `Dump` for [user-defined conditions](conditions.md), + with a `ConditionChanged (ss)` signal +- Privileged D-Bus methods accept root and members of the + `--with-group` group; everyone else is refused. On the local bus + the caller's uid and groups come straight from the kernel + (`SO_PEERCRED` + `SO_PEERGROUPS`), so the check never blocks PID 1 + on an NSS lookup. Over the system bus the uid is resolved from the + broker (`GetConnectionUnixUser`) and privileged methods are + root-only. Read-only methods are open - `initctl` now transparently routes through D-Bus when the bus is reachable, with the legacy `INIT_SOCKET` transport as a fallback: diff --git a/doc/Makefile.am b/doc/Makefile.am index dc821c7d..464a4b17 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -3,6 +3,7 @@ EXTRA_DIST = AUTHORS ChangeLog.md docsdir := @docdir@/doc dist_docs_DATA = build.md cmdline.md commands.md conditions.md \ + dbus.md \ distro.md example.md features.md index.md initctl.md \ keventd.md plugins.md requirements.md runlevels.md \ runparts.md service.md signals.md state-machine.md \ diff --git a/doc/config/files.md b/doc/config/files.md index 22b01b1a..bfb86d5a 100644 --- a/doc/config/files.md +++ b/doc/config/files.md @@ -24,6 +24,7 @@ the following layout is recommended: | `- ... `- run/ `- finit/ + |- bus # Finit's own D-Bus socket, see doc/dbus.md `- system/ |- dbus.conf |- keventd.conf diff --git a/doc/dbus.md b/doc/dbus.md index a1a9ac09..505531c4 100644 --- a/doc/dbus.md +++ b/doc/dbus.md @@ -33,6 +33,17 @@ The socket is `0660`, owned by `root` and the group given to does, so restricting one and not the other would leave the door open. Members of that group may use it, see [Authorization](#authorization). +Finit accepts at most 64 concurrent local-bus peers; further +connections are refused until one disconnects. Match rules given to +`AddMatch` support the `type`, `interface`, `member`, and `path` keys; +`arg0` and its variants are not implemented. + +For the system bus a standard busconfig policy ships in +`dbus-1/org.finit.conf`: only root may own `org.finit`, unprivileged +callers reach introspection, properties, and the read-only methods. +Finit also enforces per-method authorization itself, so a permissive +policy installed by mistake does not open state-changing methods. + The **system** bus is best-effort: Finit probes for a running `dbus-daemon` and, when reachable, claims the well-known name `org.finit` so that standard tooling sees Finit just like any other system service: @@ -91,12 +102,20 @@ and the service registry. | `Stop` | `s` | — | yes | Stop the service(s) matching the identity | | `Restart` | `s` | — | yes | Restart (stop + start) the service(s) | | `Reload` | — | — | yes | Re-read all `*.conf` and apply changes | -| `SetRunlevel` | `u` | — | yes | Transition to runlevel `u` (0–6) | +| `SetRunlevel` | `u` | — | yes | Transition to runlevel `u` (0–9) | | `SetDebug` | — | — | yes | Toggle Finit's runtime debug flag | | `Signal` | `su` | — | yes | Send signal `u` (1–31) to services matching identity `s` | | `Suspend` | — | — | yes | `sync()` + suspend-to-RAM | | `Reboot`, `Halt`, `Poweroff` | `u` | — | yes | Trigger the corresponding shutdown sequence; the argument arms the emergency fallback timer (seconds, 0 = none) | +Edge cases follow the legacy `initctl` protocol: `Suspend` and the +reboot family reply `WrongRunlevel` during bootstrap and shutdown, +`SetRunlevel` is a warning + no-op in runlevel 0/6 and records the +level for the end of bootstrap in runlevel S, and `Signal` fails for +stopped services. One deliberate divergence: a `SetRunlevel` argument +outside 0–9 returns `InvalidArgs`, where the legacy protocol +acknowledges silently. + ### Properties All read-only strings; observable via `Properties.Get` and @@ -135,7 +154,7 @@ constructing it by hand. | `Start` | — | — | yes | Equivalent to `Manager1.Start()` for this service | | `Stop` | — | — | yes | … | | `Restart` | — | — | yes | … | -| `Reload` | — | — | yes | Reload (SIGHUP if supported, else restart) | +| `Reload` | — | — | yes | Send the service's `reload-signal`, default `SIGHUP`; restart when set to `"none"` | ### Properties @@ -195,6 +214,18 @@ Lives at **`/org/finit/cond`**. Exposes Finit's Note: non-`usr/*` paths are rejected with `InvalidArgs` -- system conditions belong to Finit's state machine. +A service consuming such a condition: + + service alarm { + description = "Foo alarm" + runlevel = "2345" + conditions = { "usr/data-ready" } + command = "alarm --arg foo" + } + +asserted from any bus client with `Cond1.Set string:"data-ready"`, see +the examples below. + ### Signals | Signal | Body | Fires when | @@ -255,7 +286,7 @@ the following subcommands use the bus first: | `initctl poweroff` | `Manager1.Poweroff(timeout)` | | `initctl suspend` | `Manager1.Suspend()` | | `initctl debug` | `Manager1.SetDebug()` | -| `initctl signal` | `Manager1.Signal(svc, signo)` | +| `initctl signal` (or `kill`) | `Manager1.Signal(svc, signo)` | | `initctl runlevel` | `Properties.Get(Manager1.Runlevel/PrevRunlevel)` | | `initctl cond set/get/clear` | `Cond1.{Set,Get,Clear}`, `clr` is an alias | diff --git a/doc/features.md b/doc/features.md index 5f129b75..c1811010 100644 --- a/doc/features.md +++ b/doc/features.md @@ -275,6 +275,10 @@ initctl top # Interactive resource monitor initctl cond set usr/custom # Set custom condition ``` +`initctl` rides Finit's built-in [D-Bus API](dbus.md) when available, +which is also open to any other bus client, including `dbus-send` and +language bindings. + See the [Commands & Status](initctl.md) section for complete documentation. diff --git a/doc/index.md b/doc/index.md index f58b22ff..7a4624cb 100644 --- a/doc/index.md +++ b/doc/index.md @@ -32,6 +32,7 @@ Features * [Pre/Post script actions](config/service-wrappers.md) * Rudimentary [templating support](config/templating.md) * [Tooling](initctl.md) to enable/disable services + * [D-Bus API](dbus.md), `org.finit` control and signals for bus clients * [Automatic reload](features.md#automatic-reload) of modified configuration files (optional) * [Built-in getty](config/tty.md) * Built-in watchdog, with support for hand-over to [watchdogd][] diff --git a/doc/initctl.md b/doc/initctl.md index de19725c..20380eb9 100644 --- a/doc/initctl.md +++ b/doc/initctl.md @@ -5,6 +5,11 @@ Finit also implements a modern API to query status, and start/stop services, called `initctl`. Unlike `telinit` the `initctl` tool does not return until the given command has fully completed. +Since Finit v5, `initctl` talks to Finit over the built-in +[D-Bus API](dbus.md) when the bus socket is available, falling back +to the legacy `INIT_SOCKET` transport. The `monitor` command streams +the `org.finit` signals until interrupted. + ``` Usage: initctl [OPTIONS] [COMMAND] @@ -14,6 +19,7 @@ Options: -f, --force Ignore missing files and arguments, never prompt -h, --help This help text -j, --json JSON output in 'status' and 'cond' commands + -n, --noerr Ignore error, e.g., already started/enabled/... -1, --once Only one lap in commands like 'top' -p, --plain Use plain table headings, no ctrl chars -q, --quiet Silent, only return status of command @@ -26,15 +32,8 @@ Commands: help This help text version Show program version - ls | list List all .conf in /etc/finit.d - create Create .conf in /etc/finit.d/available - delete Delete .conf in /etc/finit.d/available - show Show .conf in /etc/finit.d/available - edit Edit .conf in /etc/finit.d/available - touch Change .conf in /etc/finit.d/available - enable Enable .conf in /etc/finit.d/available - disable Disable .conf in /etc/finit.d/enabled - reload Reload *.conf in /etc/finit.d (activate changes) + show Show /etc/finit.conf + reload Reload /etc/finit.conf (activate changes) cond set Set (assert) user-defined conditions +usr/COND cond get Get status of user-defined condition, see $? and -v @@ -50,6 +49,7 @@ Commands: Note: Finit .conf file(s) are *not* reloaded! restart [:ID] Restart (stop/start) service by name kill [:ID] Send signal S to service by name, with optional ID + monitor Stream D-Bus signals (service state, conditions) until ^C ident [NAME] Show matching identities for NAME, or all status [:ID] Show service status, by name status Show status of services, default command @@ -65,9 +65,10 @@ Commands: halt Halt system poweroff Halt and power off system suspend Suspend system - switch-root NEWROOT [INIT] Switch to new root filesystem (initramfs only) + switch-root ROOT [INIT] Switch to new root filesystem (initramfs) utmp show Raw dump of UTMP/WTMP db + ``` For services *not* supporting `SIGHUP` the `` notation in the .conf diff --git a/doc/plugins.md b/doc/plugins.md index 458544a7..583db5cc 100644 --- a/doc/plugins.md +++ b/doc/plugins.md @@ -40,6 +40,11 @@ For your convenience a set of *optional* plugins are available: `tmpfiles.d/dbus.conf`, both overridable from `/etc`; the plugin itself only handles what has to inspect the running system. + Not to be confused with Finit's built-in [D-Bus API](dbus.md): the + plugin (`--disable-dbus-plugin`) starts the external system bus + daemon, while the built-in support (`--disable-dbus`) is the + `org.finit` interface served by Finit itself. + * *hook-scripts.so*: Trigger the execution of scripts from plugin hook points (see [Hooks](#hooks)). _Optional plugin._ diff --git a/man/initctl.8 b/man/initctl.8 index 8751b5e4..7508dfed 100644 --- a/man/initctl.8 +++ b/man/initctl.8 @@ -19,6 +19,10 @@ is the official tool for interacting with .Xr finit 8 . It comes with functions for showing status, querying health of services, as well as editing, enabling and disabling services. +Commands are sent over the Finit D-Bus API when available, with the +legacy +.Pa INIT_SOCKET +protocol as fallback. .Sh OPTIONS This program follows the usual UNIX command line syntax, with long options starting with two dashes (`-'). The options are as follows: @@ -205,6 +209,10 @@ restricted Send signal S to service, by name. .Cm S may be a complete signal name such as SIGHUP, or short name such as HUP, or the signal number such as 1 (SIGHUP) +.It Nm Ar monitor +Stream service state, runlevel, and condition change signals from the +Finit D-Bus API until interrupted. Only available when Finit is built +with D-Bus support .It Nm Ar restart Cm NAME[:ID] Restart (stop/start) service by name .It Nm Ar status Cm NAME[:ID]