m³OS docs GitHub

Phase 46

System Services

The OS has a service manager, system logging, and scheduled task execution. Services (sshd, telnetd, etc.) are managed by a unified init/service system that handles startup ordering, restart on failure, and clean shutdown. The OS behaves like a real server that can be administered remotely.

Complete

Learning goal

Understand how init systems (SysV init, systemd, runit) manage service lifecycles.

Category

infrastructure

Unlocked by this phase

Why this phase matters

The OS has a service manager, system logging, and scheduled task execution. Services (sshd, telnetd, etc.) are managed by a unified init/service system that handles startup ordering, restart on failure, and clean shutdown. The OS behaves like a real server that can be administered remotely.

How it works in m3OS

Phase 46 transforms m3OS from a system that hardcodes which daemons to run into one that reads service definitions from configuration files, starts them in dependency order, restarts them on failure, logs their output centrally, schedules recurring tasks, and shuts down cleanly. This is the layer that gives the later headless/reference release story a real operator-facing control plane.

How it builds on earlier phases

This phase builds on Ports System and turns that foundation into System Services.

Implementation outline

  • Design the service definition file format (including max_restart) and create /etc/services.d/ entries.
  • Enhance init to parse service definitions and fill bidirectional dependency edges.
  • Implement dependency-ordered startup (topological sort or iterative readiness check).
  • Implement PID table mapping child PIDs to service entries for O(1) SIGCHLD dispatch.
  • Implement ServiceStatus state machine enum (NeverStarted -> Starting -> Running -> Stopping -> Stopped).
  • Implement SIGCHLD-based service exit detection with PID table lookup and automatic restart (capped by max_restart).
  • Write the service command (start, stop, restart, status, list).
  • Write syslogd: bind /dev/log, accept connections, write to log files.
  • Write the logger command.
  • Write crond: parse crontab format, compute next run time, sleep-and-execute loop.
  • Write the crontab command.
  • Implement sys_reboot() syscall and kernel shutdown path.
  • Write shutdown and reboot commands.
  • Write/update hostname, who, w, last utilities.
  • Implement iterative reverse-dependency shutdown (find service with no unstopped dependents, stop it, repeat).
  • Test full lifecycle: boot → services start → cron runs → remote login → shutdown.

Task progress snapshot

0 of 160 tracked tasks are complete.

Documentation targets

  • Documentation deliverables have not been listed yet.

Deferred follow-on work

  • Socket activation (systemd-style, as in rustysd)
  • sd_notify readiness protocol (rustysd supports this; we use timeout-based heuristics)
  • Service sandboxing (cgroups, namespaces)
  • Journal (structured logging)
  • Log rotation
  • Remote syslog
  • NTP time synchronization
  • systemd-compatible unit files
  • Runlevels / targets

Source materials

Important code

Code spotlight cards

Code spotlight

Create service definition files for existing daemons

kernel/initrd/etc/services.d/sshd.conf L4-L7

spawn_sshd() calls in init. Creating them alongside the format design. Why it matters: These files replace the hardcoded spawn_telnetd() and. Focus on `spawn_telnetd` and `spawn_sshd` in `kernel/initrd/etc/services.d/sshd.conf` while you trace the snippet.

restart=always
max_restart=10
depends=syslogd

Code spotlight

Implement service definition parser in init

userspace/init/src/main.rs L406-L429

parse them into structured ServiceDef values. This replaces the hardcoded. Why it matters: Init must read all .conf files from /etc/services.d/ and. Focus on `parse_service_def` and `ServiceDef` in `userspace/init/src/main.rs` while you trace the snippet.

/// Parse a service definition from a buffer of `key=value` lines.
fn parse_service_def(buf: &[u8], len: usize) -> Option<ServiceDef> {
    let mut svc = ServiceDef::empty();
    let mut pos = 0;

    while pos < len {
        // Skip whitespace and blank lines.
        while pos < len && (buf[pos] == b' ' || buf[pos] == b'\t' || buf[pos] == b'\r') {
            pos += 1;
        }
        if pos >= len {
            break;
        }
        // Skip comment lines.
        if buf[pos] == b'#' {
            while pos < len && buf[pos] != b'\n' {
                pos += 1;
            }
            if pos < len {
                pos += 1;
            }
            continue;
        }
        if buf[pos] == b'\n' {

Code spotlight

Create the `service` command binary

userspace/coreutils-rs/src/service.rs L143-L166

for the service manager. It must communicate with init to request operations. Why it matters: The service command is the primary administration interface. Focus on `service` and `main` in `userspace/coreutils-rs/src/service.rs` while you trace the snippet.

fn main(args: &[&str]) -> i32 {
    if args.len() < 2 {
        write_str(
            STDERR_FILENO,
            "usage: service {list|status|start|stop|restart} [name]\n",
        );
        return 1;
    }

    match args[1] {
        "list" => cmd_list(),
        "status" => {
            if args.len() < 3 {
                write_str(STDERR_FILENO, "usage: service status <name>\n");
                return 1;
            }
            cmd_status(args[2])
        }
        "start" => {
            if args.len() < 3 {
                write_str(STDERR_FILENO, "usage: service start <name>\n");
                return 1;
            }
            send_command("start", args[2])

Key files

  • userspace/init/src/main.rs — PID 1 service manager: parser, dep graph, lifecycle, restart, shutdown
  • userspace/syslogd/src/main.rs — System logging daemon: /dev/log socket, log formatting, file output
  • userspace/crond/src/main.rs — Cron daemon: crontab parser, scheduler, job executor
  • userspace/coreutils-rs/src/service.rs — service command: list, status, start, stop, restart
  • userspace/coreutils-rs/src/logger.rs — logger command: send messages to syslog via /dev/log
  • userspace/coreutils-rs/src/dmesg.rs — dmesg command: print kernel ring buffer from /proc/kmsg
  • userspace/coreutils-rs/src/shutdown.rs — shutdown command: halt the system
  • userspace/coreutils-rs/src/reboot_cmd.rs — reboot command: restart the system
  • userspace/coreutils-rs/src/hostname.rs — hostname command: get/set hostname
  • userspace/coreutils-rs/src/who.rs — who command: show logged-in users
  • userspace/coreutils-rs/src/last.rs — last command: show login history
  • userspace/coreutils-rs/src/crontab.rs — crontab command: manage user crontabs
  • kernel/src/arch/x86_64/syscall.rs — sys_reboot syscall + kernel_shutdown helper
  • userspace/syscall-lib/src/lib.rs — reboot() wrapper, signal constants
  • kernel/initrd/etc/services.d/*.conf — Service definition files

How real OSes differ

  • systemd: unit files, socket activation, cgroups, journal, timer units — enormous scope
  • rustysd (MIT, Rust): systemd-compatible unit files, socket activation, sd_notify readiness protocol, thread-per-event model. Our PID table dispatch, service state machine, and reverse-order shutdown patterns are inspired by rustysd's design.
  • runit: simple supervision tree, process 1/2/3 stages
  • OpenRC: dependency-based init with parallel startup
  • launchd (macOS): combines init, cron, inetd, and more
  • Mailto on job output
  • Timezone-aware scheduling
  • Randomized delay
  • Access control (cron.allow, cron.deny)
  • Remote syslog (UDP/TCP to log servers)
  • Facility/priority-based routing to different files
  • Log rotation and compression
  • Structured logging (RFC 5424)

Success criteria

  • Services defined in `/etc/services.d/` start automatically at boot in dependency order.
  • `service status sshd` shows the service is running with its PID.
  • Killing a `restart=always` service causes it to be automatically restarted.
  • A service that crashes more than `max_restart` times is marked permanently stopped.
  • `service stop telnetd` cleanly stops the telnet server.
  • Log messages from services appear in `/var/log/messages`.
  • `logger "test message"` writes to the system log.
  • A cron job scheduled for every minute executes on time.
  • `shutdown` cleanly stops all services and halts the system.
  • `reboot` cleanly restarts the system.
  • `who` shows currently logged-in users.

Related phases

Keep exploring the roadmap