summaryrefslogtreecommitdiff
path: root/examples/var_service/README_distro_proposal.txt (plain)
blob: 9b3fe04bad5702e32f9d4fefed03d6d694c0b799
1 A distro which already uses runit
2
3I installed Void Linux, in order to see what do they have.
4Xfce desktop looks fairly okay, network is up.
5ps tells me they did put X, dbus, NM and udev into runsvdir-supervised tree:
6
7 1 ? 00:00:01 runit
8 623 ? 00:00:00 runsvdir
9 629 ? 00:00:00 runsv
10 650 tty1 00:00:00 agetty
11 630 ? 00:00:00 runsv
12 644 ? 00:00:09 NetworkManager
13 1737 ? 00:00:00 dhclient
14 631 ? 00:00:00 runsv
15 639 tty4 00:00:00 agetty
16 632 ? 00:00:00 runsv
17 640 ? 00:00:00 sshd
18 1804 ? 00:00:00 sshd
19 1809 pts/3 00:00:00 sh
20 1818 pts/3 00:00:00 ps
21 633 ? 00:00:00 runsv
22 637 tty5 00:00:00 agetty
23 634 ? 00:00:00 runsv
24 796 ? 00:00:00 dhclient
25 635 ? 00:00:00 runsv
26 649 ? 00:00:00 uuidd
27 636 ? 00:00:00 runsv
28 647 ? 00:00:00 acpid
29 638 ? 00:00:00 runsv
30 652 ? 00:00:00 console-kit-dae
31 641 ? 00:00:00 runsv
32 651 tty6 00:00:00 agetty
33 642 ? 00:00:00 runsv
34 660 tty2 00:00:00 agetty
35 643 ? 00:00:00 runsv
36 657 ? 00:00:02 dbus-daemon
37 645 ? 00:00:00 runsv
38 658 ? 00:00:00 cgmanager
39 648 ? 00:00:00 runsv
40 656 tty3 00:00:00 agetty
41 653 ? 00:00:00 runsv
42 655 ? 00:00:00 lxdm-binary
43 698 tty7 00:00:14 Xorg
44 729 ? 00:00:00 lxdm-session
45 956 ? 00:00:00 sh
46 982 ? 00:00:00 xfce4-session
47 1006 ? 00:00:04 nm-applet
48 654 ? 00:00:00 runsv
49 659 ? 00:00:00 udevd
50
51Here is a link to Vod Linux's wiki:
52
53 https://wiki.voidlinux.eu/Runit
54
55Void Linux packages install their services as subdirectories of /etc/rc,
56such as /etc/sv/sshd, with a script file, "run", and a link
57"supervise" -> /run/runit/supervise.sshd
58
59For sshd, "run" contains:
60
61 #!/bin/sh
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
65
66That's it from the POV of the packager.
67
68This is pretty minimalistic, and yet, it is already distro-specific:
69the link to /run/runit/* is conceptually wrong, it requires packagers
70to know that /etc/rc should not be mutable and thus they need to use
71a different location in filesystem for supervise/ directory.
72
73I think a good thing would be to require just one file: the "run" script.
74The rest should be handled by distro tooling, not by packager.
75
76A similar issue is arising with logging. It would be ideal if packagers
77would not need to know how a particular distro manages logs.
78Whatever their daemons print to stdout/stderr, should be automagically logged
79in a way distro prefers.
80
81* * * * * * * *
82
83 Proposed "standard" on how distros should use runit
84
85The original idea of services-as-directories belongs to D.J.Bernstein (djb),
86and his project to implement it is daemontools: https://cr.yp.to/daemontools.html
87
88There 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/
92
93
94It is not required that a specific clone should be used. Let evolution work.
95
96 Terminology
97
98daemon: any long running background program. Common examples are sshd, getty,
99ntpd, dhcp client...
100
101service: same as "daemon"
102
103service directory: a directory with an executable file (script) named "run"
104which (usually) execs daemon (possibly after some preparatory steps).
105It 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).
107
108service monitor: a tool which watches a set of service directories.
109In daemontools package, it is called "svscan". In runit, it is called
110"runsvdir". In s6, it is called "s6-svscan".
111Service monitor starts a supervisor for each service directory.
112If it dies, it restarts it. If service directory disappears,
113service monitor will not be restarted if it dies.
114runit's service monitor (runsvdir) sends SIGTERM to supervisors
115whose directories disappeared.
116
117supervisor: a tool which monitors one service directory.
118It runs "run" script as its child. It restarts it if it dies.
119It can be instructed to start/top/signal its child.
120In daemontools package, it is called "supervise". In runit, it is called
121"runsv". In s6, it is called "s6-supervise".
122
123Conceptually, a daemontools clone can be designed such that it does not *have*
124the supervisor component: service monitor can directly monitor all its daemons
125(for example, this may be a good idea for memory-constrained systems).
126However all three existing projects (daemontools/runit/s6) do have a per-service
127supervisor process.
128
129log service: a service which is exclusively tasked with logging
130the output of another service. It is implemented as log/ subdirectory
131in a service directory. It has the same structure as "normal"
132service dirs: it has a "run" script which starts a logging tool.
133
134If log service exists, stdout of its "main" service is piped
135to log service. Stops/restarts of either of them do not sever the pipe
136between them.
137
138If 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
140per service, which is handling both of them (presumably this is done
141to use fewer processes and thus, fewer resources).
142
143
144 User API
145
146"Users" of service monitoring are authors of software which has daemons.
147They need to package their daemons to be installed as services at package
148install time. And they need to do this for many distros.
149The less distros diverge, the easier users' lives are.
150
151System-wide service dirs reside in a distro-specific location.
152The recommended location is /var/service. (However, since it is not
153a mandatory location, avoid depending on it in your run scripts).
154
155The install location for service dirs is /etc/rc:
156when e.g. ntpd daemon is installed, it creates the /etc/rc/ntpd
157directory with (minimally) one executable file (script) named "run"
158which starts ntpd daemon. It can have other files there.
159
160At boot, distro should copy /etc/rc/* to a suitable writable
161directory (common choice are /var/service, /run/service etc).
162It should create log/ directories in each subdirectory
163and create "run" files in them with suitable (for this particular distro)
164logging tool invocation, unless this directory chose to channel
165all logging from all daemons through service monitor process
166and log all of them into one file/database/whatever,
167in which case log/ directories should not be created.
168
169It is allowable for a distro to directly use /etc/rc/ as the only
170location of its service directories. (For example,
171/var/service may be a symlink to /etc/rc).
172However, it poses some problems:
173
174(1) Supervision tools will need to write to subdirectories:
175the control of running daemons is implemented via some files and fifos
176in automatically created supervise/ subdirectory in each /etc/rc/DIR.
177
178(2) Creation of a new service can race with the rescanning of /etc/rc/
179by service monitor: service monitor may see a directory with only some files
180present. If it attempts to start the service in this state, all sorts
181of bad things may happen. This may be worked around by various
182heuristics in service monitor which give new service a few seconds
183of "grace time" to be fully populated; but this is not yet
184implemented in any of three packages.
185
186Daemons' output file descriptors are handled somewhat awkwardly
187by various daemontools implementations. For example, for runit tools,
188daemons' stdout goes to wherever runsdir's stdout was directied;
189stderr goes to runsvdir, which in turn "rotates" it on its command line
190(which is visible in ps output).
191
192Hopefully this get changed/standardized; while it is not, the "run" file
193should start with a
194
195 exec 2>&1
196
197command, making stderr equivalent to stdout.
198An especially primitive service which does not want its output to be logged
199with standard tools can do
200
201 exec >LOGFILE 2>&1
202
203or even
204
205 exec >/dev/null 2>&1
206
207To prevent creation of distro-specific log/ directory, a service directory
208in /etc/rc can contain an empty "log" file.
209
210
211 Controlling daemons
212
213The "svc" tool is available for admins and scripts to control services.
214In particular, often one service needs to control another:
215e.g. ifplugd can detect that the network cable was just plugged in,
216and it needs to (re)start DHCP service for this network device.
217
218The name of this tool is not standard either, which is an obvious problem.
219I propose to fix this by implementing a tool with fixed name and API by all
220daemontools clones. Lets use original daemontools name and API. Thus:
221
222The following form must work:
223
224 svc -udopchaitkx DIR
225
226Options map to up/down/once/STOP/CONT/HUP/ALRM/INT/TERM/KILL/exit
227commands to the daemon being controlled.
228
229The form with one option letter must work. If multiple-option form
230is supported, there is no guarantee in which order they take effect:
231svc -it DIR can deliver TERM and INT in any order.
232
233If more than one DIR can be specified (which is not a requirement),
234there is no guarantee in which order commands are sent to them.
235
236If DIR has no slash and is not "." or "..", it is assumed to be
237relative to the system-wide service directory.
238
239The "svok DIR" tool exits 0 if service is running, and nonzero if not.
240
241The "svstat DIR1 DIR2..." prints one human-readable line for each directory,
242saying whether supervise is successfully running in that directory,
243and reporting the status information maintained by supervise.
244
245Other tools with different names and APIs may exist; however
246for portability scripts should use the above tools.
247
248Creation of a new service on a running system should be done atomically.
249To this end, first create and populate a new /etc/rc/DIR.
250
251Then "activate" it by running ??????? - this copies (or symlinks,
252depending on the distro) its files to the "live" service directory,
253whereever it is located on this distro.
254
255Removal of the service should be done as follows:
256svc -d DIR [DIR/log], then remove the service directory
257(this makes service monitor SIGTERM per-directory supervisors
258(if they exist in the implementation))
259
260
261 Implementation details
262
263Top-level service monitor program name is not standardized.
264[svscan, runsvdir, s6-svscan ...]
265
266It may run one per-directory supervisor, or two supervisors
267(one for DIR/ and one for DIR/log/); for memory-constrained systems
268an implementation is possible which itself controls all services, without
269intermediate supervisors.
270[runsvdir runs one "runsv DIR" per DIR, runsv handles DIR/log/ if that exists]
271[svscan runs a pair of "superwise DIR" and "superwise DIR/log"]
272
273Directores are remembered by device+inode numbers, not names. Renaming a directory
274does not affect the running service (unless it is renamed to a .dotdir).
275
276Removal (or .dotdiring) of a directory sends SIGTERM to any running services.
277
278Standard output of non-logged services goes to standard output of service monitor.
279Standard output of logger services goes to standard output of service monitor.
280Standard error of them always goes to standard error of service monitor.
281
282If you want to log standard error of your logged service along with its stdout, use
283"exec 2>&1" in the beginning of your "run" script.
284
285Whether stdout/stderr of service monitor is discarded (>/dev/null)
286or logged in some way is system-dependent.
287
288
289 Containers
290
291[What do containers need?]
292