Fix mistakes in cptest asserts
[oweals/dinit.git] / README.md
1 # Dinit
2 v0.8.2 (development release)
3
4 This is the README for Dinit, the service manager and init system. It is
5 intended to provide an overview; For full documentation please check the manual pages. 
6 The impatient may wish to check out the [getting started guide](doc/getting_started.md).
7
8 ## Contents
9
10 1. [Introduction](#introduction)
11 2. [Configuring services](#configuring-services)
12     1. [Service types](#service-types)
13     2. [Service description files](#service-description-files)
14 3. [Running Dinit](#running-dinit)
15 4. [Controlling services](#controlling-services)
16     1. [Service hierarchy and states](#service-hierarchy-and-states)
17     2. [Using dinitctl](#using-dinitctl)
18
19 ## Introduction
20
21 "Dinit" is a service supervisor with dependency support which can also
22 act as the system "init" program. It was created with the intention of
23 providing a portable init system that could serve as a lighter-weight
24 alternative to the Linux-only Systemd.
25
26 Specifically, Dinit can launch multiple services in parallel, with dependency
27 management (i.e. if one service's operation depends on another, the latter
28 service will be started first). It  can monitor the process corresponding to a
29 service, and re-start it if it dies, and it can do this in an intelligent way,
30 first "rolling back" all dependent services, and restarting them when their
31 dependencies are satisfied. However, the precise nature of dependency
32 relations between services is highly configurable. The "dinitctl" tool can
33 be used to start or stop services and check their state (by issuing commands
34 to the "dinit" daemon).
35
36 Dinit is designed to run as either as a system service manager (runs as root,
37 uses system paths for configuration etc) or a user process (runs as a user,
38 uses paths in the user's home directory by default).
39
40 Dinit is designed to work on POSIXy operating systems such as Linux and
41 OpenBSD. It is written in C++ and uses the [Dasynq](http://davmac.org/projects/dasynq/)
42 event handling library, which was written especially to support Dinit. (Note
43 that a copy of Dasynq is bundled with Dinit, so a separate copy is not
44 required for compilation; however, the bundled copy does not include the
45 documentation or test suite).
46
47 Development goals include clean design, robustness, portability, and
48 avoiding feature bloat (whilst still handling a variety of use cases).
49
50 See [doc/COMPARISON](doc/COMPARISON) for a comparison of Dinit with similar
51 software packages.
52
53 Dinit is licensed under the Apache License, version 2.0. A copy of this
54 license can be found in the LICENSE file.
55
56 Dinit was written by Davin McCall <davmac@davmac.org>.
57
58 See BUILD.txt for information on how to build Dinit.
59
60
61 ## Configuring services
62
63 ### Service types
64
65 A "service" is nominally a persistent process or system state. The two main
66 types of service are a _process_ service (represented by a an actual process)
67 and a _scripted_ service (which is started and stopped by running a process -
68 often a shell script - to completion). There are also _bgprocess_ services
69 and _internal_ services.
70
71 Many programs that you might want to run under Dinit's supervision can run
72 either "in the foreground" or as a daemon ("in the background"), and the
73 choice is dictated by a command line switch (for instance the -D and -F
74 switches to Samba's "smbd"). Although it might seem counterintuitive,
75 the "foreground" mode should be used for programs registered as process
76 services in Dinit; this allows Dinit to monitor the process.
77
78 Process services are attractive due to the ease of monitoring (and
79 restarting) the service, however, they have one inherent problem, which is
80 that Dinit cannot tell when the service is truly started. Once the process
81 has been launched, Dinit assumes that the service has started, but in fact
82 there will be a short delay before the process sets itself up, starts
83 listening on sockets, etc; during this time any other process (including
84 one from a service listed as dependent) which tries to contact it will not
85 be able to do so. In practice, this is not usually a problem (and external
86 solutions, like D-Bus, do exist).
87
88 A _scripted_ service has separate commands for startup and (optional)
89 shutdown. Scripted services can be used for tasks such as mounting file
90 systems that don't need a persistent process, and in some cases can be used
91 for daemon processes (although Dinit will not be able to supervise a
92 process that is registered as a scripted service).
93
94 A _bgprocess_ service is a mix between a process service and a scripted
95 service. A command is used to start the service, and once started, the
96 process ID is expected to be available in a file which Dinit can then
97 read. Many existing daemons can operate in this way. The process can only be
98 supervised if Dinit runs as the system "init" (PID 1), or can otherwise mark
99 itself as a subreaper (which is possible on Linux, FreeBSD and DragonFlyBSD) -
100 otherwise Dinit can not reliably know when the process has terminated.
101
102 (Note, use of bgprocess services type requires care. The file from which the
103 PID is read is trusted; Dinit may send signals to the specified PID. It
104 should not be possible for unauthorised users to modify the file contents!)
105
106 An _internal_ service is just a placeholder service that can be used to
107 describe a set of dependencies. An internal service has no corresponding
108 process.
109
110
111 ### Service description files
112
113 Dinit discovers services by reading _service description files_. These files
114 reside in a directory (/etc/dinit.d is the default "system" location, with
115 "/usr/local/lib/dinit.d" and "/lib/dinit.d" also searched; the default user
116 location is "$HOME/dinit.d") and the name of a service description file
117 matches the name of the service they configure. Service descriptions are
118 loaded lazily, as needed by Dinit.
119
120 (An example of a complete set of system service descriptions can be found in
121 the [doc/linux/services](doc/linux/services) directory).
122
123 A service description file consists of a number of parameter settings.
124 Settings in the SDF are denoted as a parameter name followed by either an
125 equal sign or colon and then the parameter value (all on the same line).
126 Comments begin with a hash mark (#) and extend to the end of the line (they
127 must be separated from setting values by at least one whitespace character).
128
129 Parameter values are interpreted literally, except that:
130  - whitespace is collapsed to a single space
131  - double quotes can be used around all or part(s) of a parameter to prevent
132    whitespace collapse and interpretation of special characters
133  - backslash can be used to 'escape' the next character, preventing any
134    special meaning from being associated with it. It can be used to include
135    non-collapsing whitespace, double-quote marks, and backslashes in the
136    parameter value.
137
138 Some examples of the available parameters are:
139
140     type = process | bgprocess | scripted | internal
141     command = ...
142     stop-command = ...
143     run-as = (user-id)
144     restart = (boolean)
145     smooth-recovery = (boolean)
146     logfile = ...
147     pid-file = ...
148     options = ...
149     depends-on = (service name)
150     depends-ms = (service name)
151     waits-for = (service name)
152     
153 Descriptions of individual parameters follows:
154
155     command = (external script or executable, and arguments)
156
157 For a 'process' service, this is the process to run.
158 For a 'scripted' service, this command is run to start the service.
159
160     stop-command = (external script or executable, and arguments)
161
162 For a 'scripted' service, this command is run to stop the service.
163
164     run-as = (user-id)
165  
166 Specifies which user to run the process(es) for this service as. The group
167 id for the process will also be set to the primary group of the specified
168 user.
169
170     restart = yes | true | no | false
171
172 Specifies whether the service should automatically restart if it becomes
173 stopped (for any reason, including being explicitly requested to stop).
174 Only active services will restart automatically.
175
176     smooth-recovery = yes | true | no | false
177    
178 For process services only. Specifies that, should the process die, it
179 can be restarted without bringing the service itself down. This means that
180 any dependent services do not need to be stopped/restarted. Such recovery
181 happens regardless of the "restart" setting (if smooth-recovery is enabled,
182 the service does not reach the stopped state when the process terminates
183 unexpectedly).
184
185     logfile = (log file path)
186
187 Specifies the log file for the service. Output from the service process
188 will go this file.
189
190     pid-file = (path to file)
191
192 For "bgprocess" type services only; specifies the path of the file where
193 daemon will write its process ID before detaching.
194
195     depends-on = (service name)
196
197 This service depends on the named service. Starting this service will
198 start the named service; the command to start this service will not be
199 executed until the named service has started. If the named service is
200 stopped then this service will also be stopped.
201
202     depends-ms = (service name)
203
204 Indicates a "milestone dependency" on the named service. This service
205 requires the named service to start before it starts itself. Once the
206 named service has started, it remains active due to the dependency, but if
207 it stops for any reason then the dependency link is broken until the next
208 time this service is started.
209
210     waits-for = (service name)
211
212 When this service is started, wait for the named service to finish
213 starting (or to fail starting) before commencing the start procedure
214 for this service. Starting this service will automatically start
215 the named service.
216
217     options = ( runs-on-console | nosigterm | starts-rwfs | starts-log ) ...
218
219 Specifies various options for this service:
220
221 `no-sigterm` : specifies that the TERM signal should not be send to the
222               process to terminate it. (Another signal can be specified using
223               the "termsignal" setting; if no other signal is specified, NO
224               signal will be sent).
225
226 `runs-on-console` : specifies that this service uses the console; its input
227               and output should be directed to the console. A service running
228               on the console prevents other services from running on the
229               console (they will queue for the console).
230               The "interrupt" key (normally control-C) will be active for
231               process / scripted services that run on the console. Handling
232               of an interrupt is determined by the service process, but
233               typically will cause it to terminate.
234               
235 `starts-on-console` : specifies that this service uses the console during
236               service startup. This is implied by runs-on-console, but can
237               be specified separately for services that need the console
238               while they start but not afterwards.
239               This setting is not applicable to regular "process" services,
240               but can be used for "scripted" and "bgprocess" services. It
241               allows for interrupting startup via the "interrupt" key
242               (normally control-C). This is useful to allow filesystem checks
243               to be interrupted/skipped.
244
245 `start-interruptible` : this service can have its startup interrupted
246               (cancelled) if it becomes inactive while still starting.
247               The SIGINT signal will be sent to the signal to cancel its
248               startup. This is meaningful only for scripted and bgprocess
249               services. 
250
251 Please see the manual page for a full list of service parameters and options.
252
253 ## Running Dinit
254
255 Dinit can run as the system "init" - the first process started by the kernel
256 on boot - which is normally done by linking or copying it to `/sbin/init`.
257 This is currently supported only on Linux. It requires having suitable service
258 descriptions in place and should be attempted only by those comfortable
259 with low-level system administration and recovery. See doc/linux directory for
260 more information.
261
262 Dinit can also run as a normal process, and can be started in this case by a
263 regular user.
264
265 By default, regardless of whether it runs as a system or user process, Dinit
266 will look for and start the service named "boot". This service should be
267 configured with dependencies which will cause any other desired services to
268 start. You can specify alternative services to start via the `dinit` command
269 line (consult the man page for more information).
270
271 ## Controlling services
272
273 ### Service hierarchy and states
274
275 Services can depend on other services for operation, and so form a
276 dependency hierarchy. Starting a service which depends on another
277 causes that other service to start (and the first service waits until
278 the latter has started before its process is launched and it is itself
279 considered started).
280
281 Services are considered _active_ when they are not stopped. Services
282 can also be explicitly marked as active (this normally happens when you
283 explicitly start a service). Finally, a service with an active dependent
284 is also considered active.
285
286 If a service stops and becomes inactive (i.e. it is not explicitly marked
287 active and has no active dependents) then any services it depends on will
288 also be marked inactive and stopped unless they have other active
289 dependents, or were explicitly started and marked active.
290
291 What this means is that, in general, starting an (inactive, stopped)
292 service and then stopping it will return the system to its prior state -
293 no dependencies which were started automatically will be left running.
294
295 ### Using dinitctl
296
297 You can use the "dinitctl" utility to start and stop services. Typical invocations
298 are:
299
300     dinitctl start <service-name>
301     dinitctl stop <service-name>
302     dinitctl release <service-name>
303
304 Note that a "start" marks the service active, as well as starting it if it is
305 not already started; the opposite of this is actually "release", which clears
306 the active mark and stops it if it has no active dependent services. The "stop"
307 command by default acts as a "release" that also forces the service to stop
308 (although it may then immediately restart, depending on how it and its
309 dependents are configured).
310
311 If stopping a service would also require a dependent service to stop, a warning
312 will be issued and the `--force` option will be required.
313
314 When run as root, dinitctl (by default) communicates with the system instance of
315 Dinit. Otherwise, it communicates with a user (personal) instance. This can be
316 overridden (using "-u" or "-s" for the user or system instance, respectively), but
317 note that regular users will generally lack the required permission to communicate
318 with the system instance. 
319
320 Here is an example command for starting a service:
321
322     dinitctl start mysql   # start mysql service
323
324 For complete details on the command line, use:
325
326     dinitctl --help
327
328 You can "pin" a service in either the stopped or started state, which prevents
329 it from changing state either due to a dependency/dependent or a direct
330 command:
331
332     dinitctl start --pin mysql  # start mysql service, pin it as "started"
333     dinitctl stop mysql  # issues stop, but doesn't take effect due to pin
334     dinitctl unpin mysql # release pin; service will now stop
335
336 You can pin a service in the stopped state in order to make sure it doesn't
337 get started accidentally (either via a dependency or directly). You can also
338 use it to temporarily keep stopped a service that would otherwise restart
339 immediately when you stopped it (because it, or a dependent, is configured
340 to restart automatically).
341
342 Finally, you can list the state of all loaded services:
343
344     dinitctl list
345
346 This may result in something like the following:
347
348     [{+}     ] boot
349     [{+}     ] tty1 (pid: 300)
350     [{+}     ] tty2 (pid: 301)
351     [{+}     ] tty3 (pid: 302)
352     [{+}     ] tty4 (pid: 303)
353     [{+}     ] loginready (has console)
354     [{+}     ] rcboot
355     [{+}     ] filesystems
356     [{+}     ] udevd (pid: 4)
357     [     {-}] mysql
358
359 The above represents a number of started services and one stopped service
360 (mysql). Services transitioning state (starting or stopping) are displayed
361 with an arrow indicating the transition direction:
362
363     [{ }<<   ] mysql     # starting
364     [   >>{ }] mysql     # stopping
365     
366 The curly brackets indicate the desired state, which may not be the state to
367 which the service is currently transitioning. For example:
368
369     [   <<{ }] mysql     # starting, but will stop after starting
370     [{ }>>   ] mysql     # stopping, but will restart once stopped
371
372 Remember that a "starting" service may be waiting for its dependencies to
373 start, and a "stopping" service may be waiting for its dependencies to stop.