1 # procd: init system, process supervisor, hotplug daemon and container runtime for OpenWrt 2 3 procd is the Linux init system, service manager, hotplug daemon and OCI 4 container runtime of [OpenWrt](https://openwrt.org/). It is PID 1 on every 5 device running OpenWrt and on the firmwares derived from it, which puts it 6 on a very large installed base of routers, access points, switches and 7 embedded Linux boards. It has been OpenWrt's init since Barrier Breaker 8 (2014), when it replaced BusyBox init. 9 10 procd is written in C against [libubox](https://github.com/openwrt/libubox) 11 and [ubus](https://github.com/openwrt/ubus). Everything it does at run time 12 is exposed and driven over ubus: starting and stopping services, reloading 13 configuration, hotplug events, reboot and system upgrade. There is no 14 private control socket and no bespoke IPC. 15 16 The canonical repository is 17 [git.openwrt.org/project/procd.git](https://git.openwrt.org/project/procd.git), 18 mirrored at [github.com/openwrt/procd](https://github.com/openwrt/procd). 19 User documentation lives in the 20 [OpenWrt wiki](https://openwrt.org/docs/techref/procd), including the 21 [init script reference](https://openwrt.org/docs/guide-developer/procd-init-scripts). 22 23 ## Relation to other init systems 24 25 procd supervises long-running services the way runit and s6 do: each 26 instance is a tracked child, respawned on failure, with its output 27 captured. Service definitions arrive over ubus from shell init scripts, 28 so the service manager, the hotplug daemon and the rest of the system 29 share one IPC mechanism; ubus takes the place that D-Bus and udev hold on 30 a desktop distribution. There are no unit files and no dependency solver. 31 Ordering at boot comes from the `S` numbers of the `/etc/rc.d/` symlinks, 32 and anything after boot is event driven through triggers. 33 34 ## Features 35 36 - **Init and boot.** Early mounts (`/proc`, `/sys`, cgroup2, `/dev`, 37 `/tmp`), console setup, early kernel module loading, a preinit stage 38 with its own hotplug rules for failsafe and flash recovery, then the 39 classic `/etc/inittab` actions (`sysinit`, `respawn`, `askfirst`, 40 `askconsole`, `shutdown` and their late variants). `sysinit` runs the 41 `/etc/rc.d/S*` scripts through a run queue. 42 - **Service supervision.** Services are registered over ubus, usually by 43 their init script through the `procd_*` shell helpers in OpenWrt's 44 `base-files`. Each service has one or more instances with a command 45 line, environment, user and group, nice level, resource limits, stdout 46 and stderr capture to syslog, a pidfile, a reload signal and a 47 termination timeout. Instances are respawned with a configurable 48 threshold, interval and retry limit. An instance can be told to restart 49 when a configuration file or a network device changes. Every instance 50 and every inittab entry runs in a cgroup of its own, so a stop reaches 51 every descendant process. 52 - **Configuration reload without restart.** A service declares triggers 53 on configuration or ubus events. `ubus call service event` and 54 `reload_config` feed those triggers, and procd compares the registered 55 instance against the new one to decide whether a restart is needed. 56 - **Validation.** Init scripts publish a schema for their UCI 57 configuration, and `ubus call service validate` returns it so that 58 frontends can check settings before applying them. 59 - **Hotplug.** procd reads kernel uevents over netlink and matches them 60 against JSON rules (`/etc/hotplug.json`). Rule actions create and 61 remove device nodes, load firmware, run button handlers and dispatch 62 scripts under `/etc/hotplug.d/<subsystem>/`. Each subsystem is also 63 reachable as a `hotplug.<subsystem>` ubus object, and `udevtrigger` 64 replays uevents for coldplug. 65 - **Watchdog.** procd feeds the hardware watchdog from the first moments 66 of boot, hands the open descriptor from `init` to `procd`, and exposes 67 frequency, timeout and magic close over ubus. Per-instance software 68 watchdogs can require a service to check in periodically. 69 - **System control.** The `system` ubus object reports board and system 70 information, reboots, signals processes, validates firmware images and 71 runs `sysupgrade`. During an upgrade PID 1 hands over to `upgraded`, 72 which runs the flash procedure from a ramdisk. 73 - **SELinux.** Built with `SELINUX`, `init` loads the policy before 74 anything else runs, halts if the policy fails to load in enforcing 75 mode, and relabels the filesystem when booting from an initramfs. 76 - **Sandboxing and containers.** `ujail` runs an instance in its own 77 mount namespace with only the files it needs, resolving shared library 78 dependencies from the ELF headers. It optionally adds network, user, 79 cgroup, PID, UTS and IPC namespaces, drops capabilities, applies a 80 seccomp filter, `no_new_privs`, cgroup2 resource limits and an eBPF 81 device filter. The same binary executes OCI runtime bundles, including 82 rootless ones through id-mapped mounts, and wires the container 83 network through netifd. 84 - **Staged seccomp.** A profile written for an application lists the 85 syscalls the application needs, yet the dynamic loader and the libc 86 start-up code need more, so a filter installed before `execve` has to 87 allow them for the lifetime of the process. `ujail` applies the 88 profile through ptrace. It stops the workload after `execve`, 89 before its first userspace instruction, and injects a filter that 90 covers the profile plus what the loader needs. It then runs the 91 process to its ELF entry point and stacks a second filter that denies 92 the loader's file access calls, and finally runs it to `main()`, 93 found through the libc start routine, and stacks a third filter that 94 denies the libc initialisation calls. Seccomp filters only ever get 95 stricter when stacked, so by the time `main()` runs the live filter 96 is exactly the profile. Static binaries get the same treatment in two 97 stages, and since the parent injects the filter from outside, no 98 preload shim is involved and static binaries are covered too. 99 Profiles can be enforced, traced, audited or run in complain mode, and 100 `trace2seccomp` turns a syscall trace into an OCI seccomp profile. 101 - **Containers as a feature of the package manager.** `uxc` manages OCI 102 containers with a `runc`-compatible command set and stores their state 103 as procd service instances, so `apk` packages can ship containers that 104 start at boot, respawn, get data volumes and log to syslog like any 105 other service. 106 - **Small.** procd links against libubox, ubus, json-c and udebug only. 107 `ujail` adds libuci and `init` adds libselinux when built with 108 `SELINUX`. 109 110 ## Components 111 112 | Binary | Role | 113 | --- | --- | 114 | `init` | PID 1 at boot: early mounts, console, kernel modules, preinit, then `exec` of `procd` | 115 | `procd` | PID 1 for the rest of the uptime: inittab, services, hotplug, watchdog, `system` and `service` ubus objects. Also runs as a standalone hotplug daemon (`-h`) and, built with `DISABLE_INIT`, as a plain service manager under another init | 116 | `ujail` | Namespace and capability sandbox for service instances and OCI runtime for containers | 117 | `uxc` | Container management CLI on top of the `container` ubus object | 118 | `uxc-net`, `uxc-stack` | ucode helpers for container networking through netifd and for multi-container stacks | 119 | `trace2seccomp` | Builds an OCI seccomp profile from a `ujail` syscall trace | 120 | `udevtrigger` | Replays kernel uevents for coldplug | 121 | `upgraded` | Replaces PID 1 during `sysupgrade` and runs the flash procedure | 122 | `askfirst` | Waits for Enter on a console before executing the shell given as its argument | 123 | `libsetlbf.so` | `LD_PRELOAD` shim that makes stdout unbuffered so captured service output reaches syslog as it is written | 124 125 ## ubus interface 126 127 | Object | Methods | 128 | --- | --- | 129 | `service` | `set`, `add`, `list`, `delete`, `signal`, `event`, `validate`, `get_data`, `set_data`, `state`, `update_start`, `update_complete`, `watchdog` | 130 | `container` | `set`, `add`, `list`, `delete`, `state`, `respawn_cancel`, `respawn_reset`, `console_set`, `console_attach`, `get_features` | 131 | `system` | `board`, `info`, `reboot`, `watchdog`, `signal`, `validate_firmware_image`, `sysupgrade` | 132 | `hotplug.<subsystem>` | `call` | 133 | `container.<name>` (from `ujail`) | `start`, `state`, `kill`, `delete`, `pause`, `resume`, `reclaim`, `update`, `exec` | 134 135 ## Building 136 137 ``` 138 cmake -B build -DJAIL_SUPPORT=1 -DSECCOMP_SUPPORT=1 -DUTRACE_SUPPORT=1 139 cmake --build build 140 ``` 141 142 Further options: `DISABLE_INIT` builds procd without the PID 1 parts, 143 `SELINUX` builds `init` with policy loading, `EARLY_PATH` sets the `PATH` 144 used during early boot, `DEBUG` enables verbose logging. 145 146 ## Licence 147 148 procd's own sources are under the LGPL-2.1. `udevtrigger` is under the 149 GPL-2.0-only, the seccomp BPF helpers under the BSD-3-Clause and `rcS.c` 150 under the ISC licence, so the package as a whole is distributed under the 151 GPL-2.0-only. See `COPYING` for the per-file breakdown and the full 152 licence texts.
This page was automatically generated by LXR 0.3.1. • OpenWrt