1 A distro which already uses runit
3 I installed Void Linux, in order to see what do they have.
4 Xfce desktop looks fairly okay, network is up.
5 ps tells me they did put X, dbus, NM and udev into runsvdir-supervised tree:
8 623 ? 00:00:00 runsvdir
10 650 tty1 00:00:00 agetty
12 644 ? 00:00:09 NetworkManager
13 1737 ? 00:00:00 dhclient
15 639 tty4 00:00:00 agetty
19 1809 pts/3 00:00:00 sh
20 1818 pts/3 00:00:00 ps
22 637 tty5 00:00:00 agetty
24 796 ? 00:00:00 dhclient
30 652 ? 00:00:00 console-kit-dae
32 651 tty6 00:00:00 agetty
34 660 tty2 00:00:00 agetty
36 657 ? 00:00:02 dbus-daemon
38 658 ? 00:00:00 cgmanager
40 656 tty3 00:00:00 agetty
42 655 ? 00:00:00 lxdm-binary
43 698 tty7 00:00:14 Xorg
44 729 ? 00:00:00 lxdm-session
46 982 ? 00:00:00 xfce4-session
47 1006 ? 00:00:04 nm-applet
51 Here is a link to Void Linux's wiki:
53 https://wiki.voidlinux.eu/Runit
55 Void Linux packages install their services as subdirectories of /etc/rc,
56 such as /etc/sv/sshd, with a script file, "run", and a link
57 "supervise" -> /run/runit/supervise.sshd
59 For sshd, "run" contains:
62 ssh-keygen -A >/dev/null 2>&1 # generate host keys if they don't exist
63 [ -r conf ] && . ./conf
64 exec /usr/bin/sshd -D $OPTS
66 That's it from the POV of the packager.
68 This is pretty minimalistic, and yet, it is already distro-specific:
69 the link to /run/runit/* is conceptually wrong, it requires packagers
70 to know that /etc/rc should not be mutable and thus they need to use
71 a different location in filesystem for supervise/ directory.
73 I think a good thing would be to require just one file: the "run" script.
74 The rest should be handled by distro tooling, not by packager.
76 A similar issue is arising with logging. It would be ideal if packagers
77 would not need to know how a particular distro manages logs.
78 Whatever their daemons print to stdout/stderr, should be automagically logged
79 in a way distro prefers.
83 Proposed "standard" on how distros should use runit
85 The original idea of services-as-directories belongs to D.J.Bernstein (djb),
86 and his project to implement it is daemontools: https://cr.yp.to/daemontools.html
88 There are several reimplementations of daemontools:
89 - runit: by Gerrit Pape, http://smarden.org/runit/
90 (busybox has it included)
91 - s6: by Laurent Bercot, http://skarnet.org/software/s6/
93 It is not required that a specific clone should be used. Let evolution work.
98 daemon: any long running background program. Common examples are sshd, getty,
101 service: daemon controlled by a service monitor.
103 service directory: a directory with an executable file (script) named "run"
104 which (usually) execs some daemon, possibly after some preparatory steps.
105 It should start it not as a child or daemonized process, but by exec'ing it
106 (inheriting the same PID and the place in the process tree).
108 service monitor: a tool which watches a set of service directories.
109 In daemontools package, it is called "svscan". In runit, it is called
110 "runsvdir". In s6, it is called "s6-svscan".
111 Service monitor starts a supervisor for each service directory.
112 If it dies, it restarts it. If service directory disappears,
113 service monitor will not be restarted if it dies.
114 runit's service monitor (runsvdir) sends SIGTERM to supervisors
115 whose directories disappeared.
117 supervisor: a tool which monitors one service directory.
118 It runs "run" script as its child. It restarts it if it dies.
119 It can be instructed to start/stop/signal its child.
120 In daemontools package, it is called "supervise". In runit, it is called
121 "runsv". In s6, it is called "s6-supervise".
123 Conceptually, a daemontools clone can be designed such that it does not *have*
124 the supervisor component: service monitor can directly monitor all its daemons
125 (for example, this may be a good idea for memory-constrained systems).
126 However all three existing projects (daemontools/runit/s6) do have a per-service
129 log service: a service which is exclusively tasked with logging
130 the output of another service. It is implemented as log/ subdirectory
131 in a service directory. It has the same structure as "normal"
132 service dirs: it has a "run" script which starts a logging tool.
134 If log service exists, stdout of its "main" service is piped
135 to log service. Stops/restarts of either of them do not sever the pipe
138 If log service exists, daemontools and s6 run a pair of supervisors
139 (one for the daemon, one for the logger); runit runs only one supervisor
140 per service, which is handling both of them (presumably this is done
141 to use fewer processes and thus, fewer resources).
146 "Users" of service monitoring are authors of software which has daemons.
147 They need to package their daemons to be installed as services at package
148 install time. And they need to do this for many distros.
149 The less distros diverge, the easier users' lives are.
151 System-wide service dirs reside in a distro-specific location.
152 The recommended location is /var/service. (However, since it is not
153 a mandatory location, avoid depending on it in your run scripts.
154 Void Linux wanted to have it somewhere in /run/*, and they solved this
155 by making /var/service a symlink).
157 The install location for service dirs is /etc/rc:
158 when e.g. ntpd daemon is installed, it creates the /etc/rc/ntpd
159 directory with (minimally) one executable file (script) named "run"
160 which starts ntpd daemon. It can have other files there.
162 At boot, distro should copy /etc/rc/* to a suitable writable
163 directory (common choice are /var/service, /run/service etc).
164 It should create log/ directories in each subdirectory
165 and create "run" files in them with suitable (for this particular distro)
166 logging tool invocation, unless this directory chose to channel
167 all logging from all daemons through service monitor process
168 and log all of them into one file/database/whatever,
169 in which case log/ directories should not be created.
171 It is allowable for a distro to directly use /etc/rc/ as the only
172 location of its service directories. (For example,
173 /var/service may be a symlink to /etc/rc).
174 However, it poses some problems:
176 (1) Supervision tools will need to write to subdirectories:
177 the control of running daemons is implemented via some files and fifos
178 in automatically created supervise/ subdirectory in each /etc/rc/DIR.
180 (2) Creation of a new service can race with the rescanning of /etc/rc/
181 by service monitor: service monitor may see a directory with only some files
182 present. If it attempts to start the service in this state, all sorts
183 of bad things may happen. This may be worked around by various
184 heuristics in service monitor which give new service a few seconds
185 of "grace time" to be fully populated; but this is not yet
186 implemented in any of three packages.
187 This also may be worked around by creating a .dotdir (a directory
188 whose name starts with a dot), populating it, and then renaming;
189 but packaging tools usually do not have an option to do this
190 automatically - additional install scripting in packages will be needed.
192 Daemons' output file descriptors are handled somewhat awkwardly
193 by various daemontools implementations. For example, for runit tools,
194 daemons' stdout goes to wherever runsvdir's stdout was directed;
195 stderr goes to runsvdir, which in turn "rotates" it on its command line
196 (which is visible in ps output).
198 Hopefully this get changed/standardized; while it is not, the "run" file
203 command, making stderr equivalent to stdout.
204 An especially primitive service which does not want its output to be logged
205 with standard tools can do
213 To prevent creation of distro-specific log/ directory, a service directory
214 in /etc/rc can contain an empty "log" file.
219 The "svc" tool is available for admins and scripts to control services.
220 In particular, often one service needs to control another:
221 e.g. ifplugd can detect that the network cable was just plugged in,
222 and it needs to (re)start DHCP service for this network device.
224 The name of this tool is not standard either, which is an obvious problem.
225 I propose to fix this by implementing a tool with fixed name and API by all
226 daemontools clones. Lets use original daemontools name and API. Thus:
228 The following form must work:
232 Options map to up/down/once/STOP/CONT/HUP/ALRM/INT/TERM/KILL/exit
233 commands to the daemon being controlled.
235 The form with one option letter must work. If multiple-option form
236 is supported, there is no guarantee in which order they take effect:
237 svc -it DIR can deliver TERM and INT in any order.
239 If more than one DIR can be specified (which is not a requirement),
240 there is no guarantee in which order commands are sent to them.
242 If DIR has no slash and is not "." or "..", it is assumed to be
243 relative to the system-wide service directory.
245 [Currently, "svc" exists only in daemontools and in busybox.
246 This proposal asks developers of other daemontools implementations
247 to add "svc" command to their projects]
249 The "svok DIR" tool exits 0 if service is running, and nonzero if not.
251 Other tools with different names and APIs may exist; however
252 for portability scripts should use the above tools.
254 Creation of a new service on a running system should be done atomically.
255 To this end, first create and populate a new /etc/rc/DIR.
257 Then "activate" it by running ??????? - this copies (or symlinks,
258 depending on the distro) its files to the "live" service directory,
259 wherever it is located on this distro.
261 Removal of the service should be done as follows:
262 svc -d DIR [DIR/log], then remove the service directory:
263 this makes service monitor SIGTERM per-directory supervisors
264 (if they exist in the implementation).
267 Implementation details
269 Top-level service monitor program name is not standardized
270 [svscan, runsvdir, s6-svscan ...] - it does not need to be,
271 as far as daemon packagers are concerned.
273 It may run one per-directory supervisor, or two supervisors
274 (one for DIR/ and one for DIR/log/); for memory-constrained systems
275 an implementation is possible which itself controls all services, without
276 intermediate supervisors.
277 [runsvdir runs one "runsv DIR" per DIR, runsv handles DIR/log/ if that exists]
278 [svscan runs a pair of "supervise DIR" and "supervise DIR/log"]
280 Directories are remembered by device+inode numbers, not names. Renaming a directory
281 does not affect the running service (unless it is renamed to a .dotdir).
283 Removal (or .dotdiring) of a directory sends SIGTERM to any running services.
285 Standard output of non-logged services goes to standard output of service monitor.
286 Standard output of logger services goes to standard output of service monitor.
287 Standard error of them always goes to standard error of service monitor.
289 If you want to log standard error of your logged service along with its stdout, use
290 "exec 2>&1" in the beginning of your "run" script.
292 Whether stdout/stderr of service monitor is discarded (>/dev/null)
293 or logged in some way is system-dependent.
298 [What do containers need?]