Why IronForge uses dinit

IronForge uses dinit because its desktop and network services need an explicit startup order, and because dinit can restart userspace without restarting the kernel.

Why SysV init stopped fitting

Early versions of IronForge used SysV init and /etc/inittab. That was adequate while boot mostly meant starting long-running programs that could be treated as independent processes. It became fragile as the desktop stack grew.

D-Bus, PipeWire, WirePlumber, Wi-Fi association, and DHCP do not merely need to be launched. Each service must start only after its prerequisites are running or ready. A flat list of commands does not express those relationships. Keeping the ordering in shell scripts would instead spread polling, retries, and process supervision across the boot sequence.

Dinit keeps the init system small while making the service relationships explicit.

The startup graph

The current service definitions encode the important paths through boot:

Area Ordered services Why the order matters
Hardware early-setupudevdudev-coldplug The device manager must be running before devices are triggered and allowed to settle.
Network udev-coldplugwpa_supplicantwifi-readydhcpcd The wireless device must exist, Wi-Fi must associate, and only then can DHCP request an address.
Audio dbuspipewirepipewire-pulse and wireplumber PipeWire starts after D-Bus and waits for seat management; its compatibility server and session manager start after PipeWire.
Desktop D-Bus, seatd, PipeWire, and device coldplug → desktop session The graphical session starts only after the services it uses have completed startup.

Hard depends-on relationships keep required services running. Softer waits-for relationships provide ordering where a failed prerequisite does not have to block the rest of the system. Independent branches can still start in parallel.

Long-running services such as D-Bus, PipeWire, WirePlumber, wpa_supplicant, and dhcpcd are also configured for automatic restart. Ordering, failure handling, and supervision therefore live beside each service definition rather than in one growing startup script.

Soft reboot

Dinit can perform a soft reboot: it stops user-space services, runs the IronForge shutdown hook, and starts dinit again with the original boot-time arguments. The kernel remains running.

IronForge uses that shutdown window to replace the mounted /usr with the selected SquashFS image. forge soft-reboot first checks that the image, shutdown hook, cleanup service, and static helper tools are available, then hands control to dinit. After /usr has been replaced, dinit starts the service graph again against the new userspace.

This is what makes the IronForge goal of avoiding reboots except for kernel upgrades practical. A soft reboot refreshes /usr, but not /opt; a release that changes /opt, or a kernel update, still requires a normal reboot. See Release layout and updates for the release-level rules.

The trade-off

Dinit needs more service definitions than the old /etc/inittab, but those files document the real boot contract. The extra structure replaces implicit timing assumptions with dependencies that can be inspected, restarted, and tested independently.