-
Notifications
You must be signed in to change notification settings - Fork 9
Runlevels
Runlevels in runit are quite a bit more sophisticated than the sysvinit and similar solutions, which are fixed in nature and are on a sliding scale from 0 to 6, with 0 being stop, 6 being reboot, and the others being an odd mix of single user, no-X11, multiuser/X11, etc. with 5 being the typical runlevel in a sysvinit (Multi-user, X11) based system. One of the takeaways from things here is that you do not need to specify a 0 or a 6. These are taken care of explicitly by the supervision system for all services running and you need only define normal operation and special cases for maintenance, etc. of the system which provide for subsets of what services including a root login TTY for single user modes, etc. This describes how one would set up runlevels other than the default one.
If not yet done, configure your system to use runit as PID 1 by following the instructions for replacing init. Some distributions (e.g. Void Linux/PHA-Linux) will do this for you automatically as they use runit exclusively as the init system.
Once ready, create the following directories and symbolic links if not already provided by the distribution :
# mkdir -p /etc/runit/runsvdir/default
# mkdir -p /etc/runit/runsvdir/single
# ln -s /etc/sv/getty-5 /etc/runit/runsvdir/single/
# ln -s default /etc/runit/runsvdir/current
This will set up a baseline runlevel (default) and a single-user one that can be selected by the runsvdir command later.
Next, if you've had to do the previous step, copy the contents of /service/ to /etc/runit/runsvdir/current/ and replace /service/ with a symbolic link:
# cp -pR /service/* /etc/runit/runsvdir/current/
# mv -f /service /service.old
# ln -s /etc/runit/runsvdir/current /service
At this point, you have now created two runlevels: default and single. The current runlevel is default. It is safe to remove /service.old/ if you don't need it anymore. Finally edit /etc/runit/2 to set the default runlevel when stage 2 starts:
$ cat /etc/runit/2
#!/bin/sh
PATH=/command:/usr/local/bin:/usr/local/sbin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R6/binrunsvchdir default >/dev/null
exec env - PATH=$PATH \
runsvdir /service 'log: -----------------------------------------------------------------'
Switching runlevels with runit is done by switching the directory the runsvdir program is running in. This is done by the runsvchdir program, e.g. to switch to the single user runlevel, do:
# runsvchdir single
To switch back to the default runlevel, do:
# runsvchdir default
See the runsvdir program for a description of what happens when runsvdir sees the directory changed. Note: There is no guarantee that all services from the previous runlevel will have stopped at the time you're dropped into the new runlevel, the runsv processes will have sent the service daemons a SIGTERM and will wait for them to terminate. Typically, they will have all stopped but there may be stragglers due to ill-behaving services. You can check the status of the previous runlevel through /etc/runit/runsvdir/previous/. A kill or force-exit can be issued via the sv command if needed to any services that didn't honor the shutdown for change.
To create a new runlevel, simply create a new directory in /etc/runit/runsvdir/. The name of the directory is the name of the new runlevel. The name must not start with a dot and must not be current, current.new, or previous, e.g.:
# mkdir /etc/runit/runsvdir/maintenance
Add the services you want to run in the runlevel maintenance to the newly created directory, e.g.:
# ln -s /etc/sv/getty-5 /etc/runit/runsvdir/maintenance/
# ln -s /etc/sv/ssh /etc/runit/runsvdir/maintenance/
# ln -s /etc/sv/dnscache /etc/runit/runsvdir/maintenance/
If you want to switch to the runlevel maintenance, do:
# runsvchdir maintenance
About runit:
Benefits
Frequently Asked Questions (FAQ)
Building runit:
Setting up runit:
Replacing Init
Running WITH Init
Runlevels
Service Dependencies
Execution Modifiers
Using runit commands:
runit
runit-init
sv
runsvdir
runsvchdir
runsv
svlogd
chpst
utmpset