TGViewer
Linux - Reddit Linux - Reddit @r_linux · 1.08K subscribers
Post #43341 41
Project I wrote a 450KB static PID 1 micro-supervisor in Rust to replace systemd

Hey r/rust!

Over the past few months, I've been building an open-source project called **Kurogane (黒鉄)**: https://github.com/devpryan7792/kurogane

It's an engine that compiles single-purpose desktop and kiosk workloads into read-only EROFS appliances with sub-2s cold boots.

Instead of running a general-purpose init system like systemd (with hundreds of background units, D-Bus, and mutable state drift), I wrote a minimal, single-threaded micro-supervisor in Rust (`kurogane-init`) that runs directly as PID 1:

👉 **GitHub**: https://github.com/devpryan7792/kurogane

\### What I learned building a Rust PID 1:

1. **POSIX Async-Signal Safety in `pre_exec`:**Between `fork` and `execve`, taking allocator locks or doing dynamic allocations (`format!`, `Vec`, `CString`) introduces unrecoverable allocator deadlock hazards post-fork. I refactored all child sandboxing (Landlock LSM and Seccomp-BPF) to use pre-allocated static null-terminated buffers and stack-only raw syscalls before dropping privileges (`setgroups`, `setgid`, `setuid`).
2. **Fail-Closed Privilege Invariants:**If a container or kernel restricts `setuid(1000)` mapping, ignoring the return value leaves child processes running with root EUID. I enforced strict fail-closed exit codes (122–127) via `libc::_exit` directly in `pre_exec`.
3. **Zero-Poll Event-Driven Reactor:**PID 1 does not poll in a loop. It blocks indefinitely in an `epoll(7)` reactor sleeping on `signalfd(2)`. When any child exits, `SIGCHLD` wakes `epoll`, and I drain `waitpid(-1, WNOHANG)` non-blockingly to handle POSIX signal coalescing. Idle CPU utilization is 0.00%.
4. **Bijective Wayland `SCM_RIGHTS` Descriptor Demuxing:**Wayland passes file descriptors out-of-band without length tags in the 8-byte framing header. In the decoupled proxy helper, I track schema interface states to route descriptors cleanly to `wl_keyboard.keymap` and `wl_shm.create_pool` while dynamically draining unmodeled protocol extensions to prevent queue phase-shifts.

\### Footprint & Benchmarks:

* Binary Size: \~453 KB stripped static binary

* Idle RAM: 57.6 MB (Alpine/musl) to 85.4 MB (Arch)

* Cold-boot to active terminal: \~1.8s (QEMU KVM direct kernel)

* Storage: Compressed read-only EROFS + ext4 journaled persistence on `/data`

\### Looking for Community Feedback:

* Are there safer abstractions for handling raw `signalfd` and `epoll` in Rust without relying heavily on `nix`?

* Any edge cases I might encounter with POSIX signal coalescing under heavy process churning?

Repo & Architecture Docs: https://github.com/devpryan7792/kurogane

https://redd.it/1x8gimv
@r_linux
GitHub GitHub - devpryan7792/kurogane: Game Boy cartridges for operating systems. Instant-on (<1.8s), declarative, immutable appliances… Game Boy cartridges for operating systems. Instant-on (<1.8s), declarative, immutable appliances on pure EROFS. - devpryan7792/kurogane
More from @r_linux
  1. Oct 18, 2026Glowbuffer - drag 'n drop & pasting fix for Hyprland /r/hyprland/comments/1x6602a/glowbuff…
  2. Oct 18, 2026SonicDE is a fork of KDE that aims to preserve and improve the X11 https://redd.it/1x6v65a…
  3. Oct 18, 2026PSA: "Beginner" distros aren't just for beginners. These days it's not quite as rampant as…
  4. Oct 18, 2026I made a tool to use OpenCore as a macOS like bootloader on Linux https://redd.it/1x8ykrm…
  5. Oct 18, 2026Recordings of the October 10 2026 GNUstep meeting are online The recordings of the October…
  6. Oct 18, 2026Anyone want to work with me on this or on this? Or maybe even spend the 60$ in Ai to do th…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →