2026-08-28 01:52:19 +09:00
|
|
|
# bajia
|
|
|
|
|
|
2026-08-27 19:08:08 +01:00
|
|
|
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](https://ninja-build.org/)
|
|
|
|
|
|
|
|
|
|
```sh
|
|
|
|
|
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:
|
|
|
|
|
|
|
|
|
|
```sh
|
|
|
|
|
./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`](etc/init.rc) for a complete example.
|
|
|
|
|
|
|
|
|
|
### services
|
|
|
|
|
|
|
|
|
|
```rc
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
```rc
|
|
|
|
|
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.
|