Skip to main content

In Nitrux, we utilize OpenRC as the init-system; it differs from the more widely used systemd software suite (which includes an init) in using scripts instead of “units” to start services. So, in today’s tutorial, we’ll check how to create service files (scripts) for use with OpenRC.

This tutorial is part one of two, with the second dealing with “user” services, as OpenRC does not use the concept of “user services.”

Difficulty: ★☆☆☆☆


Structure

Let’s start with an example.

#!/usr/bin/openrc-run
# Copyright 2022 Nitrux Latinoamericana S.C.
# Distributed under the terms of the 3-Clause BSD License

PIDFILE=/run/mybinary.pid
BIN=/path/to/mybinary

start() {
    ebegin "Starting mybinary"
    start-stop-daemon --start --exec $BIN --pidfile $PIDFILE
    eend $?
}

stop() {
    ebegin "Stopping mybinary"
    start-stop-daemon --stop --exec $BIN --pidfile $PIDFILE
    eend $?
}

The structure is straightforward to understand. First, we need to add the correct shebang; the shebang has to be ‘#!/usr/bin/openrc-run‘; otherwise, the script won’t run, and we can add a License header optionally. Then, we set two variables, ‘PIDFILE’ and ‘BIN’; these are variables where we specify the path of the PID file and the binary we want to run as a service.

  • 🔰 Information: A PID file is a file that contains the PID (PID is the operating system’s unique identifier for active programs that are running) of the executable that generated it. The PID file must be in ‘/run/’ and use the same name as the binary.

Next, we have two shell functions, start and stop; these contain the command ‘start-stop-daemon,’ which we use to do just that, starting and stopping the binary we want as a daemon.

An additional function is called depend. The OpenRC user guide states, “A depend function declares the dependencies of this service script. All scripts must have start/stop/status functions, but defaults are provided and should be used unless you have a very strong reason not to use them.”

#!/usr/bin/openrc-run
# Copyright 2022 Nitrux Latinoamericana S.C.
# Distributed under the terms of the 3-Clause BSD License

PIDFILE=/run/mybinary.pid
BIN=/path/to/mybinary

depend() {
    after service1 service2
}

start() {
    ebegin "Starting mybinary"
    start-stop-daemon --start --exec $BIN --pidfile $PIDFILE
    eend $?
}

stop() {
    ebegin "Stopping mybinary"
    start-stop-daemon --stop --exec $BIN --pidfile $PIDFILE
    eend $?
}

Usage

Service scripts are in ‘/etc/init.d’; we must add them to a runlevel to use them. As described in the OpenRC user guide, “OpenRC has a concept of runlevels, similar to what sysvinit historically offered. A runlevel is a collection of services that needs to be started. Instead of random numbers, they are named, and users can create their own if needed. This allows, for example, to have a default runlevel with “everything” enabled and a “power-saving” runlevel where some services are disabled.”

  • 🔰 Information: All runlevels are folders in ‘/etc/runlevels/’ with symlinks to ‘/etc/init.d‘ with the actual service scripts files. By default, there are seven runlevels in Nitrux; however, users can create custom runlevels.
❯ ll /etc/runlevels
total 0
drwxr-xr-x 2 root root   3 abr  2  2021 boot
drwxr-xr-x 2 root root 489 jul  6 17:06 default
drwxr-xr-x 2 root root  28 jul  6 17:06 nonetwork
drwxr-xr-x 2 root root 102 jul  6 17:06 off
drwxr-xr-x 2 root root  62 jul  6 17:06 recovery
drwxr-xr-x 2 root root   3 abr  2  2021 shutdown
drwxr-xr-x 2 root root 499 jul  6 17:06 sysinit

The ‘rc-status helper will print all currently active runlevels and the state of services in them.

Output of rc-status.

To start and stop services anytime, we use the command ‘rc-service.’

sudo rc-service someservice start
sudo rc-service someservice stop

To manage services in runlevels, we use the command ‘rc-update.’

  • 🔰 Information: The option add will add the service to the specified run level; for example, default and option del will remove the service from the specified run level.
sudo rc-update add service default
sudo rc-update del service default

If we run ‘rc-update‘ and press Enter, we will get a visualization of all the runlevels and all the services in them (but not the state).

Output of rc-update.

Finally, to update the services list, do the following.

sudo rc-update -u

Troubleshooting

If a service we added is not working, we can check the log file created by OpenRC to find out why. To do so, run the following command.

tail -n +1 /var/log/rc.log

That’s it; this concludes today’s tutorial. Stay put for the second part, where we’ll check the equivalent of “user services.”