From 9b1e70ac170b46c640dc9f90bda451b53423ddc1 Mon Sep 17 00:00:00 2001 From: Davin McCall Date: Sat, 23 Jun 2018 15:41:37 +0100 Subject: [PATCH] Add DESIGN overview. --- doc/DESIGN | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 doc/DESIGN diff --git a/doc/DESIGN b/doc/DESIGN new file mode 100644 index 0000000..c776fa5 --- /dev/null +++ b/doc/DESIGN @@ -0,0 +1,73 @@ +Dinit Design Overview +===================== + +Dinit's overall function is fairly straightforward but there are some considerations that cause +its design to be more complicated than it might otherwise be. The heart of the issue is that +Dinit should not stall on I/O and its essential operation should never fail, which means that many +code paths cannot perform memory allocation for example, and that log message all go through a +buffer. + +The design is based around an event loop: events include process termination, signal reception, +and I/O coming in from control sockets (used to issue service start/stop commands etc via +dinitctl). The Dasynq library provides the backend event loop functionality; it is included +with the Dinit source, but has a separate web page and documentation: + + http://davmac.org/projects/dasynq/ + +In Dinit, service actions are often performed by setting "propagation" flags, inserting the +service in a queue, and then processing the queues. Thus a lot of service actions are performed +by first calling a function on a service and then draining the propagation queues. More +information can be found in comments at the beginning of the includes/service.h header. + +The logging subsystem is designed to log to two different sinks - typically, one is the console +and one is the syslog facility, but other arrangements are possible. It uses a circular buffer +for each output sink, and if the buffer becomes full it discards additional messages to avoid +blocking (though it flags that this has occurred and later outputs a message to the sink). +Services may acquire the console and in this case output is discarded (though it will of +course continue to be logged to the other sink). + +Control protocol handling uses a circular receive buffer, but allocates storage for outgoing +packets dynamically. If allocation files an "out of memory" flag is set and the connection is +closed after writing an "out of memory" information packet. + + +Services +-------- + +There are presently four service types: internal, process, bgprocess and scripted. The latter +three share the fact that they execute external processes and so naturally share some +implementation. Specifically, the base service class is "service_record" - this directly +supports "internal" services. The "base_process_service" class serves as a base class for +the other three service types and provides common functionality. + +Various functions in the service_record / base_process_service classes are virtual, so that +they can be overridden by the subclasses. + +All execution of child processes related to services currently goes through +service_record::run_child_proc() (after forking). + + +Source code organisation +------------------------ + +Most function comments and general documentation can be found in header files rather than in the +corresponding source files. + +dinit.cc - main event loop handling, command line parsing, general initialisation + +service.cc, proc-service.cc, baseproc-service.cc - + service logic (see service.h, proc-service.h) + +run-child-proc.cc - contains service_record::run_child_proc(), used to run child processes. + +load-service.cc - service loading + +control.cc - control protocol handling + +dinit-log.cc - logging subsystem + + +The utility sources are: + +dinitctl.cc - the control/status utility +shutdown.cc - shutdown/halt/reboot utility -- 2.25.1