Jorgen Grahn <
grahn...@snipabacken.se> writes:
[...]
> You mean 'systemd' -- the init which restarts your daemons when they
> crash ...
init would do that as well, except that (almost) nobody uses this
facility (it is only commonly used for gettys). But (I've been doing
'special-purpose system design and implementation' for varying usage
scenarios since 2004) you've accidentally hit a pet peeve of mine so
I'm going to expand a little on that ---
The traditional way to orchestrate a complex system startup
procedured, the SysV run-level system, provides essentially no process
control/ management facilities: init executes a particular script
(/etc/init.d/rc) in case of run-level changes which - in turn -
executes some set of other scripts symlinked (on Linux. At least
Solaris uses or used to use hardlinks instead) into the /etc/rc?.d
directories with specific arguments in order to start or stop
services. Anything beyond that has to be implemented within the
scripts themselves or in application code. This implies that there's a
huge amount of code duplication here and some features, such as
monitoring processes and restarting them in case of unexpected
termination, are usually not provided at all.
'systemd' is one approach for improving this situation. AFAIK, the
idea is roughly to implement a 'huge', monolithic, ad-hoc scriptable
'master control program' which supports every conceivable
process-control feature Linux supports, no matter if it is actually
needed for something, which has to be loaded into memory (at least
partially) all the time despite most of its code is unused most of the
time, which has been written in C 'for performance' (amusingly, the
/etc/init.d/sendmail script on my 'office workstation' can start
sendmail about an order of magnitude faster than the average service
start time systemd is reportedly capable of achieving) and which
provides some other grotty, old performance hacks everyone stopped
using for good years ago (the idea of a super server invoking
special-purpose servers on demand).
As I wrote in he first paragraph, I have had to deal with 'system
startup code' for some time and so far, I've been favoring a very much
different approach:
- I don't want to invent a scripting language if there are
numerous implementation of a standardized one I can just
use (the Bourne-shell language)
- I don't want to implement or even just have support for
features I don't need
- I don't want a 'system super daemon' consuming resources
while hanging around doing nothing
- I'm not interested in solving hypothetical performance
problems in rarely executed code
- I'm not smarter than everyone else and absolutely not more
knowledgable/ experienced. If people have been successfully
'gettting stuff done' in certain ways for several decades,
this looks like 'an approach which works' as opposed to 'the
legacy we need to overcome ASAP' to me. Especially, this
means the concept of solving complex problems with the help
of interacting simple tools.
In practice, this means whenever I need a new process management
feature, I write a small C program which does that and only that which
is supposed to be executed by the shell in 'a suitable way', relying
on the UNIX(*) feature that a program can modify (parts of) the kernel
state of a process and then execute another program in the modified
environment. A practical example of that looks like this
daemon chdir $DIR monitor -n jboss -g $RUNAS chids -u $RUNAS $JBOSS_HOME/bin/run.sh -b 127.0.0.1
Each of these primtives performs a particular action and passes the
remaining parts of its command line to execv in order to execute the
next. So far, I've accumulated the following tools
chdir
Changed the working directory of the process and execute
another program.
check-locks
Walks up through the chain of parent processes and check if a
certain set of fcntl record locks are in effect ATM.
chids
Change the uid and/or gid of the process and execute another
program.
daemon
'Daemonize' and execue another program in the backgrounded
process.
lock
Acquire a set of fcntl record locks in a particular order and
execue another program.
mail-output
Execute a program and mail its stdout (and possibly, stderr)
output to some address.
monitor
Monitor another processes' health, restart it in case of
unexpected termination and provide some process control
features (start/ stop/ restart).
rand-periodic
Run some other program such that it executes 'every n seconds'
on average, using a randomized interval.
run-at
Execute a program at a specific time (passed as UNIX(*)
timestamp).
send_args/ recv_args
Send a set of arguments over an 'argument munging transport'
(aka ssh)/ execute a command with the arguments received from
a send_args invocation.
This grew out of earlier work done for a 'Embedded Linux' OS for a UTM
appliance except that I religiously stuck to the 'one feature per
program' idea for the 2nd iteration. So far, this has worked out very
nicely.