Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
cd7b537
libink: brokerless D-Bus server library, for #396
troglobit May 13, 2026
e6acdf1
libink: binary protocol, dispatch, Manager1.ListServices
troglobit May 14, 2026
8bfacc1
libink: read-side marshaller and Manager1 service-control methods
troglobit May 14, 2026
124a567
libink: fix dispatch race on coalesced BEGIN+request
troglobit May 14, 2026
3be433c
libink: per-method authorization
troglobit May 15, 2026
ed2a12d
libink: Service1 per-service objects, path encoding
troglobit May 15, 2026
12ac7f3
libink: D-Bus signals + AddMatch/RemoveMatch
troglobit May 15, 2026
d2d5eab
libink: org.finit.Cond1 with ConditionChanged signal
troglobit May 15, 2026
7218f8f
initctl: route Start/Stop/Restart/Reload/Reboot via D-Bus
troglobit May 15, 2026
483a202
libink: rename API ink_* -> link_* (and INK_* -> LINK_*)
troglobit May 15, 2026
bfadd90
libink: client + server (was server-only)
troglobit May 15, 2026
161f364
libink: public reader, link_reply_t, varargs call
troglobit May 15, 2026
3af3d4e
libink: link_client_wait + signal-aware reply view
troglobit May 15, 2026
38384d0
test: port dbus-auth-client to libink
troglobit May 15, 2026
caad195
test: split dbus-auth.sh by area
troglobit May 15, 2026
27736dc
initctl: monitor subcommand + cond {get,set,clr} via D-Bus
troglobit May 15, 2026
a5d5101
libink/finit: org.freedesktop.DBus.Properties + Manager1 props
troglobit May 15, 2026
7fd1a46
libink/finit: opportunistic system-bus registration
troglobit May 15, 2026
b761752
libink: array iterator, reply accessors, connect timeout
troglobit May 15, 2026
390e278
initctl: SetDebug, Signal, Suspend, per-svc Reload via D-Bus
troglobit May 16, 2026
dbf6a88
doc: D-Bus integration reference + ChangeLog
troglobit May 16, 2026
7e771b8
.github: point ld at /tmp/lib for the libink smoke checks
troglobit May 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,16 +63,16 @@ jobs:
tree /tmp || true
- name: Check dependencies
run: |
ldd /tmp/sbin/finit
LD_LIBRARY_PATH=/tmp/lib ldd /tmp/sbin/finit
size /tmp/sbin/finit
ldd /tmp/sbin/initctl
LD_LIBRARY_PATH=/tmp/lib ldd /tmp/sbin/initctl
size /tmp/sbin/initctl
ldd /tmp/sbin/reboot
LD_LIBRARY_PATH=/tmp/lib ldd /tmp/sbin/reboot
size /tmp/sbin/reboot
- name: Verify starting and showing usage text
run: |
sudo /tmp/sbin/finit -h
sudo /tmp/sbin/initctl -h
sudo env LD_LIBRARY_PATH=/tmp/lib /tmp/sbin/finit -h
sudo env LD_LIBRARY_PATH=/tmp/lib /tmp/sbin/initctl -h
- name: Enable unprivileged userns (unshare)
run: |
sudo sysctl kernel.apparmor_restrict_unprivileged_userns=0
Expand Down
13 changes: 12 additions & 1 deletion Makefile.am
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = man plugins src system tmpfiles.d

# libink must precede src in SUBDIRS because finit links against
# libink at build time. Automake recurses subdirs strictly in
# declaration order, so the typical "explicit dependency" pattern
# (foo: bar) doesn't help here — ordering is the only thing that
# does. libsystemd is consumed by test/serv only, so its position
# after src is fine.
SUBDIRS = man plugins
if DBUS
SUBDIRS += libink dbus-1
endif
SUBDIRS += src system tmpfiles.d
dist_doc_DATA = README.md LICENSE contrib/finit.conf

if CONTRIB
Expand Down
11 changes: 11 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ AC_CONFIG_FILES([Makefile
contrib/debian/Makefile contrib/debian/finit.d/Makefile contrib/debian/finit.d/available/Makefile
contrib/void/Makefile contrib/void/finit.d/Makefile contrib/void/finit.d/available/Makefile
doc/Makefile doc/config/Makefile
dbus-1/Makefile
libink/Makefile libink/libink.pc
libsystemd/Makefile libsystemd/libsystemd.pc
man/Makefile
plugins/Makefile
Expand Down Expand Up @@ -88,6 +90,10 @@ AC_ARG_ENABLE(logrotate,
AS_HELP_STRING([--disable-logrotate], [Disable built-in rotation of /var/log/wtmp]),,[
enable_logrotate=yes])

AC_ARG_ENABLE(dbus,
AS_HELP_STRING([--disable-dbus], [Disable D-Bus support (libink + Finit object tree)]),,[
enable_dbus=yes])

AC_ARG_ENABLE(doc,
AS_HELP_STRING([--disable-doc], [Disable build and install of doc/ section]),,[
enable_doc=yes])
Expand Down Expand Up @@ -237,6 +243,10 @@ AS_IF([test "x$enable_rescue" != "xno"], [

AM_CONDITIONAL(LOGROTATE, [test "x$enable_logrotate" = "xyes"])

AS_IF([test "x$enable_dbus" = "xyes"], [
AC_DEFINE(HAVE_DBUS, 1, [Build D-Bus support via libink])])
AM_CONDITIONAL(DBUS, [test "x$enable_dbus" = "xyes"])

### With features ##############################################################################
AS_IF([test "x$bash_dir" = "xyes"], [
PKG_CHECK_MODULES([BASH_COMPLETION], [bash-completion >= 2.0],
Expand Down Expand Up @@ -432,6 +442,7 @@ Optional features:
Built-in sulogin......: $with_sulogin $sulogin
Built-in watchdogd....: $with_watchdog $watchdog
Built-in logrotate....: $enable_logrotate
D-Bus support (libink): $enable_dbus
Replacement libsystemd: $with_libsystemd
Use cgroup v2.........: $enable_cgroup
Use libcap............: $enable_libcap
Expand Down
2 changes: 2 additions & 0 deletions dbus-1/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/Makefile
/Makefile.in
6 changes: 6 additions & 0 deletions dbus-1/Makefile.am
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
EXTRA_DIST = org.finit.conf

if DBUS
dbuspolicydir = $(sysconfdir)/dbus-1/system.d
dist_dbuspolicy_DATA = org.finit.conf
endif
63 changes: 63 additions & 0 deletions dbus-1/org.finit.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE busconfig PUBLIC
"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<!--
System-bus policy for finit.

finit (PID 1, root) owns the `org.finit` well-known name. The
policy below lets unprivileged callers introspect, read
properties, and query service / condition state, but disallows
every state-changing method at the broker. finit *also* enforces
per-method authorisation itself (LINK_METHOD_PRIVILEGED), so
defense-in-depth: even if a permissive policy is installed by
mistake, finit rejects unprivileged state changes via SO_PEERCRED
on the local bus and by treating every system-bus caller as
unprivileged (peer_uid = (uid_t)-1) until a per-sender uid lookup
via GetConnectionUnixUser is implemented.
-->
<busconfig>

<!-- Only finit (root) may own the org.finit bus name. -->
<policy user="root">
<allow own="org.finit"/>
<allow send_destination="org.finit"/>
<allow receive_sender="org.finit"/>
</policy>

<!-- Everyone may introspect, read properties, and call the
read-only Manager1 / Cond1 methods. Signals fan out
unconditionally. -->
<policy context="default">
<allow send_destination="org.finit"
send_interface="org.freedesktop.DBus.Introspectable"/>
<allow send_destination="org.finit"
send_interface="org.freedesktop.DBus.Peer"/>
<allow send_destination="org.finit"
send_interface="org.freedesktop.DBus.Properties"
send_member="Get"/>
<allow send_destination="org.finit"
send_interface="org.freedesktop.DBus.Properties"
send_member="GetAll"/>

<allow send_destination="org.finit"
send_interface="org.finit.Manager1"
send_member="ListServices"/>
<allow send_destination="org.finit"
send_interface="org.finit.Manager1"
send_member="GetService"/>

<allow send_destination="org.finit"
send_interface="org.finit.Cond1"
send_member="Get"/>
<allow send_destination="org.finit"
send_interface="org.finit.Cond1"
send_member="List"/>
<allow send_destination="org.finit"
send_interface="org.finit.Cond1"
send_member="Dump"/>

<allow receive_sender="org.finit"/>
</policy>

</busconfig>
49 changes: 49 additions & 0 deletions doc/ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,55 @@ All relevant changes are documented in this file.

### Changes

- Finit now ships with a built-in brokerless D-Bus implementation,
**libink**, exposing the running init system as a peer on its own
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/<encoded>` -- 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 reject non-root callers based on the kernel-
authenticated peer uid (`SO_PEERCRED`); read-only methods are open.
See [D-Bus Integration](dbus.md) for the full surface, build flag,
and `dbus-send`/`dbus-monitor` examples.

- `initctl` now transparently routes through D-Bus when the bus is
reachable, with the legacy `INIT_SOCKET` transport as a fallback:
`start`, `stop`, `restart`, `reload`, `reload <svc>`, `reboot`,
`halt`, `poweroff`, `suspend`, `debug`, `signal`, `runlevel`, and
`cond {get,set,clr}` all use the new path. Two new subcommands
show up that have no legacy equivalent:

* `initctl monitor` -- streams every signal on the bus to the
terminal, one line per delivery (`HH:MM:SS iface.member(args)`),
until interrupted. Same idea as `dbus-monitor`, but scoped to
Finit and with no address plumbing required.

* Issuing `initctl cond set/clr` over D-Bus also fires the
`Cond1.ConditionChanged` signal, so observers see user-driven
state changes the same way they see service-driven ones.

- Restart log now spells out the signal name and flags core dumps,
e.g. `killed by SIGKILL` or `killed by SIGSEGV, core dumped`, in
place of the bare numeric `by signal: N`. Gives operators a much
Expand Down
Loading
Loading