Skip to main content
procd is OpenWrt’s process manager and PID 1. It replaces traditional init systems (like SysVinit or systemd) with a lightweight daemon designed for embedded devices. procd is responsible for:
  • Bootstrapping the system after the kernel hands off control
  • Starting and supervising services defined in /etc/init.d/
  • Restarting crashed services automatically
  • Dispatching hotplug events (USB, network interfaces, etc.)
  • Communicating with other system components over ubus

Init Scripts: /etc/init.d/

Each service on the system has an init script in /etc/init.d/. These scripts use the rc.common framework — sourced via the shebang line #!/bin/sh /etc/rc.common — which provides the standard start, stop, restart, enable, and disable actions.

Anatomy of an Init Script

A minimal procd-style init script looks like this:
#!/bin/sh /etc/rc.common
# Example service init script

START=95          # Boot order priority (lower = earlier)
STOP=10           # Shutdown order priority (lower = stops earlier)
USE_PROCD=1       # Use procd service management

start_service() {
    procd_open_instance
    procd_set_param command /usr/sbin/myservice
    procd_set_param respawn          # Restart if it crashes
    procd_set_param stdout 1         # Log stdout to syslog
    procd_set_param stderr 1         # Log stderr to syslog
    procd_close_instance
}

service_triggers() {
    # Reload this service when the UCI "network" config changes
    procd_add_reload_trigger "network"
}
Key variables and functions:
Variable / FunctionPurpose
START=<n>Boot priority. Services with lower numbers start first.
STOP=<n>Shutdown priority. Lower numbers stop first.
USE_PROCD=1Enables procd-native service management (supervised processes).
start_service()Called by procd to launch the service. Uses procd_open_instance / procd_close_instance.
stop_service()Called when stopping the service (optional; procd handles SIGTERM by default).
service_triggers()Declares which UCI config changes should trigger a service reload.
reload_service()Called on reload (if defined); otherwise falls back to restart.

Boot Script Example: /etc/init.d/boot

The built-in boot script (START=10) runs early in the boot sequence and is responsible for:
  • Mounting filesystems (/proc/mounts check, OverlayFS)
  • Creating runtime directories (/var/lock, /var/run, /tmp/.uci)
  • Loading kernel modules via kmodloader
  • Applying UCI defaults from /etc/uci-defaults/
  • Generating initial network configuration

Boot Order

The enable command creates symlinks in /etc/rc.d/ with S<priority><name> naming. rcS walks these symlinks in alphanumeric order at boot:
/etc/rc.d/S10boot     → ../init.d/boot
/etc/rc.d/S10system   → ../init.d/system
/etc/rc.d/S19dnsmasq  → ../init.d/dnsmasq
/etc/rc.d/S20network  → ../init.d/network
/etc/rc.d/S95done     → ../init.d/done
The inittab triggers this via:
::sysinit:/etc/init.d/rcS S boot
::shutdown:/etc/init.d/rcS K shutdown
::askconsole:/usr/libexec/login.sh

Service Management Commands

Using init scripts directly

/etc/init.d/<service> start
/etc/init.d/<service> stop
/etc/init.d/<service> restart
/etc/init.d/<service> reload
/etc/init.d/<service> status

Enable / disable autostart

# Create /etc/rc.d/ symlinks (persist across reboot)
/etc/init.d/<service> enable

# Remove /etc/rc.d/ symlinks
/etc/init.d/<service> disable

# Check if the service is enabled
/etc/init.d/<service> enabled && echo "enabled"

Using the service command

procd installs a convenience wrapper at /sbin/service:
service <name> start
service <name> stop
service <name> restart
service <name> reload

Inspecting running services via ubus

procd exposes service state over ubus:
# List all registered services
ubus call service list

# Get info on a specific service
ubus call service list '{"name": "network"}'

Hotplug: /etc/hotplug.d/

Hotplug events (such as a network interface coming up or a USB device being inserted) are dispatched by procd to shell scripts in /etc/hotplug.d/. Scripts are organized into subdirectories by event subsystem:
/etc/hotplug.d/
├── leds/    # LED state change events
└── net/     # Network interface up/down events
Each script in these directories is called with the environment variable $ACTION set to the event type (e.g., add, remove, ifup, ifdown) and $INTERFACE or $DEVPATH identifying the affected device.
To trigger a reload of all services that depend on a changed UCI config (without restarting unaffected services), use:
reload_config
This calls procd via ubus and only restarts services that declared a trigger for the changed config file.