Add DESIGN overview.
[oweals/dinit.git] / doc / DESIGN
1 Dinit Design Overview
2 =====================
3
4 Dinit's overall function is fairly straightforward but there are some considerations that cause
5 its design to be more complicated than it might otherwise be.  The heart of the issue is that
6 Dinit should not stall on I/O and its essential operation should never fail, which means that many
7 code paths cannot perform memory allocation for example, and that log message all go through a
8 buffer.
9
10 The design is based around an event loop: events include process termination, signal reception,
11 and I/O coming in from control sockets (used to issue service start/stop commands etc via
12 dinitctl). The Dasynq library provides the backend event loop functionality; it is included
13 with the Dinit source, but has a separate web page and documentation:
14
15     http://davmac.org/projects/dasynq/ 
16
17 In Dinit, service actions are often performed by setting "propagation" flags, inserting the
18 service in a queue, and then processing the queues. Thus a lot of service actions are performed
19 by first calling a function on a service and then draining the propagation queues. More
20 information can be found in comments at the beginning of the includes/service.h header.
21
22 The logging subsystem is designed to log to two different sinks - typically, one is the console
23 and one is the syslog facility, but other arrangements are possible. It uses a circular buffer
24 for each output sink, and if the buffer becomes full it discards additional messages to avoid
25 blocking (though it flags that this has occurred and later outputs a message to the sink).
26 Services may acquire the console and in this case output is discarded (though it will of
27 course continue to be logged to the other sink).
28
29 Control protocol handling uses a circular receive buffer, but allocates storage for outgoing
30 packets dynamically. If allocation files an "out of memory" flag is set and the connection is
31 closed after writing an "out of memory" information packet.
32
33
34 Services
35 --------
36
37 There are presently four service types: internal, process, bgprocess and scripted. The latter
38 three share the fact that they execute external processes and so naturally share some
39 implementation. Specifically, the base service class is "service_record" - this directly
40 supports "internal" services. The "base_process_service" class serves as a base class for
41 the other three service types and provides common functionality.
42
43 Various functions in the service_record / base_process_service classes are virtual, so that
44 they can be overridden by the subclasses.
45
46 All execution of child processes related to services currently goes through
47 service_record::run_child_proc() (after forking).
48
49
50 Source code organisation
51 ------------------------
52
53 Most function comments and general documentation can be found in header files rather than in the
54 corresponding source files.
55
56 dinit.cc - main event loop handling, command line parsing, general initialisation
57
58 service.cc, proc-service.cc, baseproc-service.cc -
59     service logic (see service.h, proc-service.h)
60     
61 run-child-proc.cc - contains service_record::run_child_proc(), used to run child processes.
62
63 load-service.cc - service loading
64
65 control.cc - control protocol handling
66
67 dinit-log.cc - logging subsystem
68
69
70 The utility sources are:
71
72 dinitctl.cc - the control/status utility
73 shutdown.cc - shutdown/halt/reboot utility