Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Phase 208 — systemd userspace contract

At a glance

FieldValue
Phase familyPhase 2 — bootable image
Run commandmake phase 208
Underlying make target/scriptvm/phase2/verify-systemd-userspace-plan.sh
Runs onhost
Main proof/artifactVerifies the systemd userspace ownership and PID 1 contract.

Phase 208 is also a contract phase.

Phase 208 does not build systemd. It does not copy host systemd. It does not copy Nix systemd. It does not mount the image. It does not boot QEMU.

This phase exists because the Phase 206 boot entry already says:

init=/usr/lib/systemd/systemd
systemd.unit=multi-user.target

That means the future kernel/initramfs handoff expects the real root filesystem to contain:

/usr/lib/systemd/systemd

Before we build or import that file, we need to say what owns it and what minimum userspace shape must exist around it.

What PID 1 means

When Linux starts userspace, the first normal process gets process ID 1:

PID 1

PID 1 is special. It becomes the init system for the machine.

It is responsible for starting and supervising the rest of userspace:

mounts
device management
services
login
shutdown
reboot
cleanup of orphaned processes

For ONIX, the planned PID 1 path is:

/usr/lib/systemd/systemd

That is why Phase 206 put this on the kernel command line:

init=/usr/lib/systemd/systemd

Why not copy host systemd

The Phase 208 decision is:

do not copy host systemd
do not copy Nix systemd

The host systemd belongs to the developer machine. The Nix systemd belongs to the Nix toolbox environment.

ONIX is meant to be a musl-based OS. A random host or Nix systemd may be built for a different libc, with a different layout, with different assumptions about paths, users, groups, services, and dependencies.

So the future package must be ONIX-owned:

onix-systemd

That package name is the contract for now. It may eventually be split into smaller packages, but the ownership rule is clear: ONIX must provide its own systemd userspace rather than smuggling in the host one.

What systemd userspace must include

The minimum future onix-systemd package needs more than one binary.

At minimum, the contract needs:

/usr/lib/systemd/systemd
/usr/lib/systemd/systemd-udevd
/usr/bin/systemctl
/usr/bin/journalctl
/usr/lib/systemd/system/multi-user.target

systemd-udevd matters because device nodes and device events are part of turning early boot into a usable machine.

multi-user.target matters because the Phase 206 boot entry already asks for:

systemd.unit=multi-user.target

So the target file must exist at:

/usr/lib/systemd/system/multi-user.target

Runtime filesystems systemd expects

Some paths are not normal package payload. They are runtime filesystems mounted by the kernel, initramfs, or early userspace:

/run
/dev
/proc
/sys

ONIX packages can create the mount-point directories, but they should not ship host contents for those paths.

That matches the earlier root-tree rule:

/dev   runtime devices
/proc  kernel process/info view
/sys   kernel device/info view
/run   runtime state

Machine identity and defaults

systemd also expects some machine-local state and policy.

Important early files include:

/etc/machine-id
/etc/fstab

/etc/machine-id is the unique machine identity. It should not be a baked-in shared ID copied into every image forever. The first real boot path needs a policy for creating or seeding it safely.

/etc/fstab already comes from the ONIX filesystem package defaults and is materialized by image assembly.

tmpfiles and sysusers

Two common systemd mechanisms matter for package integration:

tmpfiles
sysusers

tmpfiles describes runtime directories, files, permissions, and cleanup rules.

sysusers describes system users and groups that packages need.

ONIX should eventually support package-owned defaults such as:

/usr/lib/tmpfiles.d/*.conf
/usr/lib/sysusers.d/*.conf

This lets packages declare system integration without editing live /etc directly.

Future file contract

The future root filesystem must provide:

/usr/lib/systemd/systemd
/usr/lib/systemd/systemd-udevd
/usr/lib/systemd/system/multi-user.target

The future image or first-boot policy must handle:

/etc/machine-id
/run
/dev
/proc
/sys

The future package name for this responsibility is:

onix-systemd

Again: ONIX should build or package this intentionally for its musl base.

What Phase 208 verifies

make phase 208 verifies:

  • this Phase 208 section exists
  • the planned PID 1 path is /usr/lib/systemd/systemd
  • the boot entry still asks for systemd.unit=multi-user.target
  • the target path is /usr/lib/systemd/system/multi-user.target
  • the plan names onix-systemd
  • the plan says musl
  • the plan says do not copy host systemd
  • the plan says do not copy Nix systemd
  • the plan mentions systemd-udevd
  • the plan mentions /etc/machine-id
  • the plan mentions /run, /dev, /proc, and /sys
  • the plan mentions tmpfiles
  • the plan mentions sysusers
  • the Phase 206 image script still points at /usr/lib/systemd/systemd

This makes Phase 208 a checkpoint between “the boot entry names systemd” and “ONIX actually provides systemd userspace”.

What Phase 208 does not prove

Phase 208 does not prove:

systemd builds on musl
systemd starts as PID 1
udev works
services start
the image boots

Those are later phases. This phase only protects the ownership boundary.