an init system
  • C++ 72.2%
  • Python 27.8%
Find a file
2026-08-27 19:08:08 +01:00
etc add stuff 2026-08-27 19:08:08 +01:00
src add stuff 2026-08-27 19:08:08 +01:00
tools add stuff 2026-08-27 19:08:08 +01:00
.gitignore add stuff 2026-08-27 19:08:08 +01:00
configure.py add stuff 2026-08-27 19:08:08 +01:00
LICENSE Initial commit 2026-08-28 01:52:19 +09:00
README.md add stuff 2026-08-27 19:08:08 +01:00

bajia

an init system (PID 1) for embedded / VM targets, written in C++20 and configured with a small declarative language inspired by Android's init .rc format.

Status

  • .rc config parser (services + on-trigger action blocks)
  • Supervisor event loop built on signalfd + epoll
  • service spawn / reap / respawn (per-service restart policy)
  • action commands: start, stop, restart, exec, mkdir, chmod, chown, setenv, write, symlink, mount, log
  • logger with a ring buffer that flushes to the console once available

roadmap:

  • user/group privilege drop (user, group, supplementary groups)
  • dependency ordering between services
  • SIGCHLD crash-window limiting (rate-limited restarts)
  • property triggers (property:<k>=<v>) and setprop/getprop
  • per-service logging to files
  • reboot/poweroff path with ordered unmount
  • SIGHUP config reload
  • SELinux

building

requires a C++20 compiler and Ninja

python3 configure.py     # generates build/build.ninja
ninja -C build           # produces build/bajia

configure.py also writes a thin Makefile convenience wrapper (make, make clean, make format, --asan, --debug).

running

As a real init, the kernel must launch it as PID 1:

init=/path/to/bajia

Or by hand against a config (useful for development, may not behave like a real boot). bajia normally refuses to start unless it is PID 1; pass --run-as-user to override:

./build/bajia --run-as-user etc/init.rc

If no files are given it looks for /etc/bajia/init.rc.

configuration language

See etc/init.rc for a complete example.

services

service NAME /path/to/exe [args...]
    user root|other          # privilege level (drop, planned)
    group GROUP [GROUP...]
    oneshot                  # run once and exit, never respawn
    disabled                 # not started by the boot sequence
    console                  # bind stdio to /dev/console
    class NAME               # grouping (default "default")
    respawn never|on-failure|always   # restart policy (default always)
    crash-threshold N        # restarts allowed per window
    crash-window SECS
    setenv K=V               # extra environment (repeatable)
    cwd /path

actions

on TRIGGER
    start NAME | stop NAME | restart NAME
    exec /cmd args...
    mkdir PATH [mode]
    chmod PATH mode
    chown PATH uid gid
    setenv K V
    write PATH CONTENT
    symlink TARGET LINK
    mount SOURCE TARGET FSTYPE
    log message

boot triggers fire in order: early-init, init, boot. shutdown is reserved (planned wiring to the signal path). property/service-* triggers are on the roadmap.