Talk:Runit

From Gentoo Wiki
Jump to: navigation, search
Note
This is a talk page. Please add newer comments below older ones, and sign your comments using four tildes (~~~~). When adding a new section (at the bottom of the page), please mark it as "open for discussion" by using {{talk|open}} so it will show up in the list of open discussions.

Article improvements

Talk status
This discussion is done as of 2017-06-24.

The current wiki page is imprecise and out of date. Here is a proposed set of changes to try and improve it.

  • Add general description of what runit is, what it does, and why one may want to use it.
  • Change recommendations (e.g remove /etc/local.d, and rather suggest /etc/runit/1 modification)
  • Add a section for replacing OpenRC and Sysvinit entirely
  • Add general explanation of how runit functions (potential link to socklog information as well?)
  • Add general recommendations on writing service directories
  • Add general recommendations for logging services (svlogd)
  • Fix reboot/shutdown compat. Most systems will use consolekit, which does not use them like so. Thus add information on that, and note that /sbin/runit-init is a thing (for systems without consolekit)
  • Mention http://smarden.org/runit/faq.html#depends (really useful!)

Planning to add examples / sample text for each of those here later; everything obviously open for discussion. SpaceToast (talk) 20:56, 20 October 2015 (UTC)

Sounds good to me. No one has been interested in updating this article in a while. Go for it, buddy! Also, don't forget to sign your comments on discussion pages! --Maffblaster (talk) 16:43, 20 October 2015 (UTC)
I think most if not all of what was proposed here is now either directly in the article, or in the daemontools-encore article and linked from this one. So I'm going to mark this discussion as done. GuillermoDH (talk) 19:06, 6 May 2018 (UTC)

Runit Description/Introduction

Runit is an alternative init (pid 1) and service supervision system. It features a small, simple code base, simple structure for services, easily creatable custom runlevels and transparent functionality which makes it easy to tinker.

Runit may act as PID1 (replacement for SysVinit / the booting part of systemd), global service supervisor (replacement for OpenRC, .service part of systemd) and user service supervision (not handled by anything that I am aware of), and any combination thereof.

One may wish to use runit for its small size, more user-oriented and transparent configuration, or its ability to control user-ran services.

A quick write-up, looks a bit messy, might have to reformat it, but I think it lists all of the basic information a user needs about runit to decide if they would like to use it or not. SpaceToast (talk) 21:07, 20 October 2015 (UTC)

Configuration

As Init and RC (with OpenRC)

Firstly, add init=/sbin/runit-init to your kernel command line. Now runit will handle initialization. After loading up, it will run two files one after the other, here are what they currently look like:

FILE /etc/runit/1
#!/bin/sh
# system one time tasks

PATH=/sbin:/usr/sbin:/bin:/usr/bin

RUNLEVEL=S /sbin/rc sysinit
RUNLEVEL=S /sbin/rc boot

touch /etc/runit/stopit
chmod 0 /etc/runit/stopit

In short, 1 does all the startup tasks. By default, it uses OpenRC to perform sysinit and boot tasks.

FILE /etc/runit/2
#!/bin/sh

PATH=/command:/usr/local/bin:/usr/local/sbin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R6/bin

runsvchdir default >/dev/null

exec env - PATH=$PATH \
runsvdir -P /var/service 'log: ...........................................................................................................................................................................................................................................................................................................................................................................................................'

Note: the ton of dots are used as space for runsvdir itself to log problems. You can view them using something like ps(1).

In short, 2 prepares and runs all user-level (runlevel) services.

In this configuration, you should go through what is defined in rc-status default and write directory structures for those services (or their alternatives, if now desired). On how to write directory structures, see below.

As Init and RC (without OpenRC)

In this configuration, you would fully replace OpenRC as well as SysVinit. To achieve this, follow the instructions above, but remove the two lines starting with RUNLEVEL=S. You should replace them with your own (or, in the future, supplied by a package) scripts that do the same tasks (to see what tasks are being executed by OpenRC one could run rc-status sysinit and rc-status boot).

For this section, someone has supplied a package of runit scripts here, specifically in power-misc/runit-scripts. --Konimex (talk) 23:42, 16 July 2016 (UTC)

PID1 (but not RC)

In this configuration, runit will replace SysVinit, but OpenRC will keep handling all the system services. To achieve this, don't bother creating any service directories, and simply add RUNLEVEL=S /sbin/rc default either after the other such lines into /etc/runit/1, or next to the runsvchdir line in /etc/runit/2.

No other modification should be needed!

As Service Supervisor (but not init)

Fully replacing OpenRC while running SysVinit is not trivial (it involves creating several runlevels (see below) and editing /etc/inittab. As such, this will instead cover how to use runit on top of OpenRC (using OpenRC for booting only). Create directory structures for your desired services in any location (/etc/runit/runsvdir/all is still recommended) and set everything up as if you were using runit as init, and then simply get OpenRC to run runsvdir -P /path/to/service/dir/ in any way you would prefer.

As usual, feel free to edit everything above (it makes sense to me, but I'm not the best at communicating). However this does sum up the general use cases for runit. Next, I'm going to write an overview on how to create service directories and logging. --SpaceToast (talk) 19:34, 21 October 2015 (UTC)

Service Directories and Logging

Typical Structure

The only required file is ./run. This file must be executable (chmod +x ./run). When the service is launched, to launch it, this file is ran. It should set everything up (see logging for potential pointers) and then exec into the daemon.

Beyond this, there are several other files that can be used. Here is a list:

  • ./check - a script that is ran to verify whether or not the service is up (rather than checking the PID). An exit code of 0 means the script is running. Must be executable.
  • ./down - if this file exists, it tells runsv that the service should not be started automatically (and will be started by a call to sv later).
  • ./finish - a script (must be executable) to run after ./run exits or crashes if necessary. After it exits (or if it doesn't exist), ./run is started up again.

Logging

Logging is done through ./log/ (a directory). The structure of this directory is the same as above (see Typical Structure), but behaves a bit differently. Whenever a service starts, it pumps all of its stdout into a pipe. (thus, for daemons that like using stderr, you might want to make exec 2>&1 the first line in your ./run files) Whenever a log service starts, it uses that pipe as its stdin. A simple way of visualizing this is like so (note: this command is a lie, see above for the specific functionality).

user $./run | ./log/run

Runit provides svlogd(8) as a utility for simplifying per-daemon logging. Svlogd takes a directory (or multiple!) where to dump the log files (as current). Without a configuration file, it will dump all output, but you can configure it to selectively parse what should be logged. See svlogd(8) for more details. Here is an example of a functional sshd service directory:

FILE /etc/runit/runsvdir/all/sshd/run
#!/bin/sh
exec 2>&1
exec chpst -Usshd /usr/sbin/sshd -D -e
FILE /etc/runit/runsvdir/all/sshd/log/run
#!/bin/sh
exec chpst -ulog svlogd -tt /var/log/service/sshd

chpst(8) is used here to change the user who is running the commands (to run sshd as the sshd user, and svlogd as the log user).

System Logging

See: socklog

Somewhat dirty, but definitely more informative than the current iteration. Next up: controlling services. If anyone could clean this up to be more readable that'd be great though... --SpaceToast (talk) 00:22, 26 October 2015 (UTC)

Controlling Services

Services can be controlled either directly through the filesystem or using the sv(8) utility. Both will be described here.

File-System

For this whole section, assume that servicedir is the directory of a given service (e.g sshd, or sshd/log).

  • if servicedir/down exists, the service will not be started automatically by runsv until it is explicitly started
  • a binary representation of the status of the service exists in servicedir/supervise/status (to be read by supervise, sv, and similar programs)
  • a human-readable representation of the status of the service exists in servicedir/supervise/stat
  • the pid of the running service is available in servicedir/supervise/pid
  • a named pipe is available in servicedir/supervise/control (see below for controls)

For sending signals to the service / runsv, write one of the following characters to the named pipe:

  • u : start the service if currently down. if it stops, automatically restart it
  • d : send the service a TERM signal, then a CONT signal. if servicedir/run exits, run servicedir/finish if it exists. do not restart the service
  • o : if the service is down, start it. do not automatically restart it
  • p : if service is running, send a STOP signal
  • c : if service is running, send a CONT signal
  • h : if service is running, send a HUP signal
  • a : if service is running, send a ALRM signal
  • i : if service is running, send a INT signal
  • q : if service is running, send a QUIT signal
  • 1 and 2 : if service is running, send a USR1 or USR2 respectively signal
  • t : if service is running, send a TERM signal
  • k : if service is running, send a KILL signal
  • x : if service is running, send a TERM then a CONT signal. do not automatically restart it. if log service exists and is running, close the stdin pipe towards it and wait for it to terminate. once/if the log service is down, exit runsv. (ignored for log service dirs)

sv

Sv automates most of this functionality. If the argument is a directory (absolute, or explicitly relative with ./) it will perform on the specified directory. If it is not, it looks in $SVDIR. If SVDIR is not defined, it defaults to /etc/service. Beyond this, sv supports the same commands as mentioned above, in their full word form, here is a list (see above for meaning):

  • status
  • up
  • down
  • once
  • pause
  • cont
  • hup
  • alarm
  • interrupt
  • quit
  • 1
  • 2
  • term
  • kill
  • exit

Sv also supports a "check" command. This checks whether or not the service is in the currently requested state. Waits up to 7 seconds for it to reach that state. If the requested state is up, it uses servicedir/check to verify whether or not it's running.

Typical usage:

user $sv status sshd

/etc/init.d/

It is possible to symlink sv into /etc/init.d. If this is done, sv will perform on the service matching its calling basename. So, for example, calling sv as /etc/init.d/sshd will run sv with sshd as an argument. In this mode, sv is in LSB compatibility mode, and the following extra commands are available:

  • start : up, but wait 7 seconds for success. Use servicedir/check to verify that the service is up (if it exists).
  • stop : down, but wait 7 seconds before reporting
  • reload : hup, then status
  • restart : term, cont then start.
  • shutdown : exit, wait 7 seconds for runsv to terminate.
  • force-stop : down, wait 7 seconds, kill on timeout
  • force-reload : term, cont, report status. On timeout (7 seconds), kill
  • force-restart : term, cont then up. On timeout (7 seconds), kill. Use servicedir/check to verify if it is up (if it exists).
  • force-shutdown : shutdown, but kill on timeout
  • try-restart : if running, term, cont, wait 7 seconds, then report status or timeout

Sv supports 2 arguments, -v waits 7 seconds for success, and reports, -w changes the default timeout from 7 to argument value (implies -v). Sv also supports two environment variables: SVDIR - where to look for services and SVWAIT - how long to wait (applies to LSB compat and -v), but that is overridden by -w.

Essentially an information dump that's fairly easily achieved by reading the manual pages. Definitely needs reformatting. --SpaceToast (talk) 15:21, 6 November 2015 (UTC)

Shutdown / Reboot Compatibility

Most systems will typically assume that the shutdown script (provided by SysVInit) is available, though some (such as ConsoleKit) have also added detection for systemd. Runit handles shutdown / reboot commands through signals, with a fairly simple interface (0 for shutdown, 6 for reboot).

root #/sbin/runit-init 0
root #/sbin/runit-init 6

Most systems allow you to specify a custom shutdown command (for example, sddm). However, others rely on ConsoleKit. These scripts are located in these two locations, with descriptive names, and could look something like this:

FILE /usr/local/lib/ConsoleKit/scripts/ck-system-stop
/sbin/runit-init 0
FILE /usr/local/lib/ConsoleKit/scripts/ck-system-restart
/sbin/runit-init 6
Probably needs reformatting. Also, the file locations aren't gentoo-specific (I couldn't verify, since I don't have CK on any machines I own anymore, but that's what it should be). --SpaceToast (talk) 02:00, 15 November 2015 (UTC)