diff options
author | Laurent Bercot <ska-skaware@skarnet.org> | 2015-07-04 01:40:10 +0000 |
---|---|---|
committer | Laurent Bercot <ska-skaware@skarnet.org> | 2015-07-04 01:40:10 +0000 |
commit | 96fbd74d6d70b562f45e327eeb0f625b54899bcc (patch) | |
tree | 9ea39925915206e3f40ef2ed4c1298f92dff5858 | |
parent | 53e51768c75662a66a8b5656ee557640376d252b (diff) | |
download | s6-rc-96fbd74d6d70b562f45e327eeb0f625b54899bcc.tar.xz |
Start of doc
-rw-r--r-- | doc/index.html | 142 | ||||
-rw-r--r-- | doc/overview.html | 220 | ||||
-rw-r--r-- | doc/s6-rc-compile.html | 163 | ||||
-rw-r--r-- | doc/s6-rc-db.html | 134 | ||||
-rw-r--r-- | doc/s6-rc-dryrun.html | 64 | ||||
-rw-r--r-- | doc/s6-rc-init.html | 168 | ||||
-rw-r--r-- | doc/s6-rc-upgrade.html | 174 | ||||
-rw-r--r-- | doc/s6-rc.html | 2 | ||||
-rw-r--r-- | doc/upgrade.html | 28 | ||||
-rw-r--r-- | doc/why.html | 278 |
10 files changed, 1372 insertions, 1 deletions
diff --git a/doc/index.html b/doc/index.html new file mode 100644 index 0000000..543b4ca --- /dev/null +++ b/doc/index.html @@ -0,0 +1,142 @@ +<html> + <head> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6-rc - a service manager for s6</title> + <meta name="Description" content="s6-rc - a service manager for s6" /> + <meta name="Keywords" content="s6 rc unix s6-rc init service management rc.d scripts administration root laurent bercot ska skarnet" /> + <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="http://skarnet.org/software/">Software</a><br /> +<a href="http://skarnet.org/">skarnet.org</a> +</p> + +<h1> s6-rc </h1> + +<h2> What is it ? </h2> + +<p> + s6-rc is a service manager for +<a href="http://skarnet.org/software/s6/">s6</a>-based +systems, i.e. a suite of programs that can start and stop +services, both long-running daemons and one-time +initialization scripts, in the proper order according to a +dependency tree. It ensures that long-running daemons are +supervised by the s6 infrastructure, and that one-time +scripts are also run in a controlled environment. +</p> + +<hr /> + +<ul> + <li> <a href="why.html">Why</a> such a program ? </li> + <li> A <a href="overview.html">high-level overview</a> of s6-rc </li> +</ul> + +<hr /> + +<h2> Installation </h2> + +<h3> Requirements </h3> + +<ul> + <li> A POSIX-compliant system with a standard C development environment </li> + <li> GNU make, version 4.0 or later </li> + <li> <a href="http://skarnet.org/software/skalibs/">skalibs</a> version +2.3.5.1 or later </li> + <li> <a href="http://skarnet.org/software/execline/">execline</a> version +2.1.2.2 or later </li> + <li> <a href="http://skarnet.org/software/s6/">s6</a> version +2.1.6.0 or later </li> +</ul> + +<h3> Licensing </h3> + +<p> + s6-rc is free software. It is available under the +<a href="http://opensource.org/licenses/ISC">ISC license</a>. +</p> + +<h3> Download </h3> + +<ul> + <li> The current released version of s6-rc is +<a href="s6-rc-0.0.1.0.tar.gz">0.0.1.0</a>. </li> + <li> Alternatively, you can checkout a copy of the s6-rc git repository: +<pre> git clone git://git.skarnet.org/s6-rc </pre> </li> + <li> There's also a +<a href="https://github.com/skarnet/s6-rc">GitHub mirror</a> +of the s6 git repository. </li> +</ul> + +<h3> Compilation </h3> + +<ul> + <li> See the enclosed INSTALL file for installation details. </li> +</ul> + +<h3> Upgrade notes </h3> + +<ul> + <li> <a href="upgrade.html">This page</a> lists the differences to be aware of between +the previous versions of s6-rc and the current one. </li> +</ul> + +<hr /> + +<h2> Reference </h2> + +<h3> Commands </h3> + +<p> + All these commands exit 111 if they encounter a temporary error, and +100 if they encounter a permanent error - such as a misuse. +</p> + +<h4> Offline tools: creating and managing a compiled service database </h4> + +<ul> + <li> <a href="s6-rc-compile.html">The <tt>s6-rc-compile</tt> program</a> </li> + <li> <a href="s6-rc-db.html">The <tt>s6-rc-db</tt> program</a> </li> +</ul> + +<h4> Online tools: managing your live services </h4> + +<ul> + <li> <a href="s6-rc-init.html">The <tt>s6-rc-init</tt> program</a> </li> + <li> <a href="s6-rc.html">The <tt>s6-rc</tt> program</a> </li> + <li> <a href="s6-rc-dryrun.html">The <tt>s6-rc-dryrun</tt> internal program</a> </li> + <li> <a href="s6-rc-upgrade.html">The <tt>s6-rc-upgrade</tt> program</a> </li> +</ul> + +<h2> Related resources </h2> + +<h3> Discussion </h3> + +<ul> + <li> <tt>s6-rc</tt> is discussed on the +<a href="http://skarnet.org/lists.html#skaware">skaware</a> mailing-list. </li> +</ul> + +<h3> Similar work </h3> + +<ul> + <li> <a href="http://jjacky.com/anopa/">anopa</a> is another service manager +for s6, with a similar design (but no compilation phase). </li> + <li> <a href="http://homepage.ntlworld.com/jonathan.deboynepollard/Softwares/nosh.html">nosh</a> +is a complete init system and service manager for Unix. </li> +</ul> + +<h3> Discussion </h3> + +<ul> + <li> <tt>s6-rc</tt> is discussed on the +<a href="http://skarnet.org/lists.html#skaware">skaware</a> mailing-list. </li> +</ul> + +</body> +</html> diff --git a/doc/overview.html b/doc/overview.html new file mode 100644 index 0000000..fd544a7 --- /dev/null +++ b/doc/overview.html @@ -0,0 +1,220 @@ +<html> + <head> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6-rc: an overview</title> + <meta name="Description" content="s6-rc: an overview" /> + <meta name="Keywords" content="s6-rc overview" /> + <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">s6-rc</a><br /> +<a href="http://skarnet.org/software/">Software</a><br /> +<a href="http://skarnet.org/">skarnet.org</a> +</p> + +<h1> An overview of s6-rc </h1> + +<h2> A manager for <em>services</em> </h2> + +<p> + s6-rc is a service manager, or, in other words, a +<em>machine state manager</em>: given a database of services, +with dependencies between them, it can safely bring the +<em>global machine state</em>, or <em>live state</em>, to +the desired point, making sure dependencies are never +broken. +</p> + +<h3> The live state </h3> + +<p> + The <em>live state</em>, by definition, is the tuple of +all service states on the machine. Changing the live state +means bringing services up, or bringing services down. +</p> + +<h3> 2.5 kinds of services </h3> + +<p> + Supervision suites manage <em>long-lived processes</em>, a.k.a +<em>daemons</em>, and sometimes call them <em>services</em>. +With s6-rc, those things are different: a long-lived process is +also called a <em>longrun</em> and is a service, but a service +does not have to be a longrun. There is a second kind of service, +which is called a <em>oneshot</em>, and which represents a change +of system state that is not embodied by the presence of a +long-lived process. For instance, "mounting a filesystem" is a +system state change, but in most cases there is no process hanging +around while the filesystem is mounted. +</p> + +<p> + s6-rc handles both oneshots and longruns. +</p> + +<ul> + <li> A <em>longrun</em> is the exact equivalent of a <em>service</em> +in the supervision sense. It is defined by a +<a href="http://skarnet.org/software/s6/servicedir.html">service +directory</a>, with a run script and optional other data. The +service is considered <em>up</em> as long as the long-lived +process is alive and, for daemons that support it, has +<a href="http://skarnet.org/software/s6/notifywhenup.html">notified +its readiness</a>. It is considered <em>down</em> otherwise. </li> + <li> A <em>oneshot</em>, on the other hand, is totally unknown +from supervision suites, because there is no daemon to manage. +A oneshot is represented by two short-lived scripts, <em>up</em> +and <em>down</em>, used to bring the service respectively up and +down. The service is considered up when the <em>up</em> +program has exited successfully, and until the <em>down</em> +program has exited successfully. </li> +</ul> + +<p> + Services can depend on one another. +If service <em>A</em> has been declared as +depending on service <em>B</em>, then s6-rc will make sure to +never start <em>A</em> until it knows that <em>B</em> is up, +and will make sure to never stop <em>B</em> until it knows that +<em>A</em> is down. This works whether <em>A</em> and <em>B</em> +are both oneshots, both longruns, or a oneshot and a longrun. +</p> + +<p> + s6-rc also handles an additional kind of service: a <em>bundle</em>. +A bundle is just a collection of oneshots or longruns, described +under a single name. A bundle definition can even contain other +bundles, but ultimately a bundle will always represent a set of one +or more oneshots or longruns. A oneshot or longrun is called an +<em>atomic service</em>. +Bundle names can be used anywhere with the s6-rc user +interface, and they will internally be converted to a set of +atomic services. An atomic service can depend on a bundle: it will +simply depend on all the atomic services represented by the bundle. +A bundle, however, cannot have dependencies. +</p> + +<h2> A two-part operation </h2> + +<p> + Unlike other service managers such as +<a href="http://jjacky.com/anopa/">anopa</a>, s6-rc separates the +work of analyzing a set of service definitions, resolving +dependencies, and so on, from the work of actually applying the +dependency graph to perform live state changes. The former is +the <em>compilation</em> phase, and is done offline; the latter is +the <em>live</em> phase, and is of course done online - it impacts +the actual state of the machine. +</p> + +<h3> The compilation phase </h3> + +<ul> + <li> Users are expected to write their service definitions - be it +oneshots, longruns or bundles - in one ore more +<em>source directories</em>, in the s6-rc +<a href="s6-rc-compile.html#source">source format</a>. +The source format is simple to parse automatically - which is +one of the main reasons why it has been designed that way - and +it is also simple to generate automatically: it is easy to write +converters from a given service definition format to the s6-rc +source format. </li> + <li> Users then run the +<a href="s6-rc-compile.html">s6-rc-compile</a> program, that takes +a set of service definitions in one or more source directories +and makes a <em>compiled service database</em>, abbreviated as +<em>compiled</em>. This <em>compiled</em> should be stored by the +administrator on the root filesystem. </li> + <li> The <a href="s6-rc-db.html">s6-rc-db</a> tool can be used +to examine compiled service databases and extract information from +them in a human-friendly format. </li> +</ul> + +<h3> The live phase </h3> + +<p> + When the machine boots up: +</p> + +<ul> + <li> First, the chosen init should make sure that a +<a href="http://skarnet.org/software/s6/">s6</a> +supervision tree is up and running. s6-rc will only work +if there is an active +<a href="http://skarnet.org/software/s6/s6-svscan.html">s6-svscan</a> +process monitoring a +<a href="http://skarnet.org/software/s6/scandir.html">scan</a> +directory. On Linux, for instance, it is possible to achieve such a state +by using an init created by the +<a href="http://skarnet.org/software/s6-linux-init/s6-linux-init-maker.html">s6-linux-init-maker</a> +tool: when control reaches stage 2, s6-svscan is guaranteed to run, +so using s6-rc in the stage 2 script is the way to go. </li> + <li> The boot process, let's name it <em>stage2</em>, should then call the +<a href="s6-rc-init.html">s6-rc-init</a> program. This program +will set up an area for s6-rc in a writable directory (which can +be on a RAM filesystem such as tmpfs) to host its live information +such as the machine state, a working copy of all service directories +for longruns, and a link to the current compiled state database. +<a href="s6-rc-init.html">s6-rc-init</a> initializes the machine state +as "every declared service is down". </li> + <li> <em>stage2</em> should then invoke the +<a href="s6-rc.html">s6-rc</a> program with the names of the services that +should be brought up given as arguments. Of course, bundles can be used +for shortcuts. </li> + <li> That's it, the services are up and the initialization should be +over. If the service database has been properly written, a <em>stage2</em> +script can actually be really short: an invocation of +<a href="s6-rc-init.html">s6-rc-init</a> and an invocation of +<a href="s6-rc.html">s6-rc</a>. </li> +</ul> + +<h3> Other state changes and shutdown </h3> + +<p> + The administrator can make changes to the live state of the machine +by manually calling <a href="s6-rc.html">s6-rc</a> again with the +proper arguments. This is more powerful than the old +<a href="http://www.tldp.org/LDP/sag/html/run-levels-intro.html">runlevels</a>: +it is possible to change the live state to <em>any</em> set of +services, not only predefined ones. The only thing that s6-rc will +not allow is a state that would break service dependencies; it +will always respect the dependency graph. +</p> + +<p> + The s6-rc command is the central for machine state changes, and it is +also true for shutdown. When shutting a machine down, all the services +managed by s6-rc should be brought down in the proper order (via the +<tt>s6-rc -da change</tt> command). Once all those services have been +brought down successfully, the final shutdown procedure can take place; +for instance, if s6-svscan is running as process 1 with the +<a href="http://skarnet.org/software/s6-linux-init/">s6-linux-init</a> +defaults, <tt>s6-svscanctl -t /run/service</tt> will kill the +supervision tree and call <tt>/etc/rc.shutdown reboot</tt>, which should +reboot the machine. +</p> + +<h2> Live updates to the service database </h2> + +<p> +The s6-rc command is a one-stop shop for service management as long as +the compiled database doesn't change. If an administrator wishes to +make a new compiled database the current live one, without rebooting +the machine, a bit more work is needed, and that's the job of the +<a href="s6-rc-update.html">s6-rc-update</a> command. This command +has been specifically written with Unix distributions in mind: when +new packages ship, they come with new service definitions, or upgraded +ones, and it is necessary to compile a new service database and update +the live state so it matches; if source definitions for s6-rc are +provided in the packages, an invocation of +<a href="s6-rc-compile.html">s6-rc-compile</a> followed by an invocation of +<a href="s6-rc-update.html">s6-rc-update</a> should be all it takes to +keep the live state up to date. +</p> + +</body> +</html> diff --git a/doc/s6-rc-compile.html b/doc/s6-rc-compile.html new file mode 100644 index 0000000..33d8bcd --- /dev/null +++ b/doc/s6-rc-compile.html @@ -0,0 +1,163 @@ +<html> + <head> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6-rc: the s6-rc-compile program</title> + <meta name="Description" content="s6-rc: the s6-rc-compile program" /> + <meta name="Keywords" content="s6-rc offline database compilation command rc init dependency state management services" /> + <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">s6-rc</a><br /> +<a href="http://skarnet.org/software/">Software</a><br /> +<a href="http://skarnet.org/">skarnet.org</a> +</p> + +<h1> The s6-rc-compile program </h1> + +<p> + s6-rc is a <em>machine state manager</em>: it brings the machine to a +desired state, by starting or stopping services as needed. +</p> + +<h2> Interface </h2> + +<pre> + s6-rc [ -v <em>verbosity</em> ] [ <em>servicenames...</em> ] +</pre> + +<ul> + <li> s6-rc expects to find a <em>compiled service database</em> +in <tt>/etc/s6-rc/compiled</tt> and a <em>live state</em> in +<tt>/s6/s6-rc</tt>. If it cannot find that data, it complains and +exits. + <ul> + <li> The <em>compiled service database</em> is built offline +via the <a href="s6-rc-compile.html">s6-rc-compile</a> tool. </li> + <li> The <em>live state</em> should be initialized at boot time +via the <a href="s6-rc-init.html">s6-rc-init</a> tool. It is then +maintained by s6-rc itself. </li> + </ul> </li> + <li> The command line arguments <em>servicenames...</em> define a set +of selected services the user wants to act on. </li> + <li> s6-rc computes the necessary transitions to bring the machine +to the desired state - by default a state where all the +services listed on the command line are up. If asked to, it performs +those transitions. </li> + <li> s6-rc processes services as soon as they can be processed. It +will wait until a service is up to start a dependent service, but it +will start two independent services in parallel. </li> + <li> If every state transition completes successfully, s6-rc exits 0. </li> + <li> If a state transition fails, s6-rc will not perform the transitions +that depend on it. It will wait until all the other independent transitions +are done, then exit 1. </li> +</ul> + +<h2> Options </h2> + +<h3> s6-rc control </h3> + +<ul> + <li> <tt>-v <em>verbosity</em></tt> : be more or less +verbose. Default is 1: warning and error messages will be printed to +stderr. 0 silences warnings. 2 writes information messages whenever +s6-rc performs a transition. 3 or more is debug info. </li> + <li> <tt>-n <em>dryruntimeout</em></tt> : dry run. +s6-rc will pretend to perform transitions, but will replace all its +program invocations by a call to +<a href="s6-rc-dryrun">s6-rc-dryrun</a>, which will do nothing but +print the command line s6-rc would have executed, then sleep for +<em>dryruntimeout</em> milliseconds before reporting success. </li> + <li> <tt>-t <em>timeout</em></tt> : timeout. If s6-rc +isn't done after <em>timeout</em> milliseconds, it will exit, leaving +the live state as it is at exit time. It does not kill its children, so +a child may successfully complete afterwards and the live state will +not be updated; in that case, subsequent s6-rc invocations will notice +and correctly update it. </li> + <li> <tt>-c <em>compiled</em></tt> : look for the +compiled service database in <em>compiled</em>. Default is +<tt>/etc/s6-rc/compiled</tt> </li> + <li> <tt>-l <em>live</em></tt> : look for the +live state in <em>live</em>. Default is +<tt>/s6/s6-rc</tt> </li> +</ul> + +<h3> Up or down </h3> + +<ul> + <li> <tt>-u</tt> : selected services are interpreted +as to be brought <em>up</em>. This is the default. </li> + <li> <tt>-d</tt> : selected services are interpreted +as to be brought <em>down</em>. </li> +</ul> + +<h3> Service selection </h3> + +<ul> + <li> <tt>-p</tt> : prune. The state will be brought to +<em>exactly</em> <em>servicenames...</em>, plus their dependencies, and +the other services will be brought down. With the <tt>-d</tt> option, +the meaning is reversed: the state will be brought to the maximum +possible set that does not include <em>servicenames...</em>. </li> + <li> <tt>-a</tt> : all. Add the current set of active services to +the selected set. This is useful to ensure consistency of the machine +state, for instance, and also at shutdown time: <tt>s6-rc -da</tt> +will stop all the currently active services. </li> +</ul> + +<h3> Actions </h3> + +<ul> + <li> <tt>-C</tt> : check. s6-rc will check the consistency of the +database, and exit with an error message if it finds errors. </li> + <li> <tt>-L</tt> : list. s6-rc will resolve the given names, then +print the list of corresponding atomic services to stdout, without taking their +dependencies into account. It will print an empty line afterwards. </li> + <li> <tt>-A</tt> : list all. s6-rc will print the list of selected +atomic services to stdout, after computing dependencies. Note that with +the <tt>-d</tt> option, it computes reverse dependencies instead. </li> + <li> <tt>-S</tt> : state change. A state change will be performed +for the selected services. +This is the default if no other action option has been given. </li> +</ul> + +<h2> Usage examples </h2> + +<pre> s6-rc <em>myservicebundle</em> </pre> +<p> + Brings up all the services represented by <em>myservicebundle</em>, +dependencies first. +</p> + +<pre> s6-rc -Sad </pre> +<p> + Brings down all the services in an orderly manner. This is typically +run at shutdown time. +</p> + +<pre> s6-rc -Au <em>myservicebundle</em> </pre> +<p> + Prints the names of all atomic services represented by +<em>myservicebundle</em>, as well as everything they depend on. +</p> + +<pre> s6-rc -Ad <em>myservicebundle</em> </pre> +<p> + Prints the names of all atomic services represented by +<em>myservicebundle</em>, as well as everything that depends on them. +</p> + +<pre> s6-rc -pun0 <em>myservicebundle</em> </pre> +<p> + Prints what s6-rc would do to bring the state to just +<em>myservicebundle</em> and its dependencies. +</p> + + +<h2> Internals </h2> + +</body> +</html> diff --git a/doc/s6-rc-db.html b/doc/s6-rc-db.html new file mode 100644 index 0000000..9a1cf3b --- /dev/null +++ b/doc/s6-rc-db.html @@ -0,0 +1,134 @@ +<html> + <head> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6-rc: the s6-rc-db program</title> + <meta name="Description" content="s6-rc: the s6-rc-db program" /> + <meta name="Keywords" content="s6-rc offline database dump command rc init dependency state management services" /> + <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">s6-rc</a><br /> +<a href="http://skarnet.org/software/">Software</a><br /> +<a href="http://skarnet.org/">skarnet.org</a> +</p> + +<h1> The s6-rc-db program </h1> + +<p> + s6-rc-db is a tool to analyze a compiled service database +and extract information from it, and print it in a user-friendly +format. +</p> + +<p> + It is an <em>offline tool</em>, i.e. you can run it on any +compiled service database without actually having a live set +of services managed by s6-rc. However, if you do have a live +set, you can still run s6-rc-db on the current database (and +it is the default); it won't interfere with your normal service +operation. +</p> + +<h2> Interface </h2> + +<pre> + s6-rc-db help + s6-rc-db [ -l <em>live</em> ] [ -c <em>compiled</em> ] check + s6-rc-db [ -l <em>live</em> ] [ -c <em>compiled</em> ] list all|services|oneshots|longruns|bundles + s6-rc-db [ -l <em>live</em> ] [ -c <em>compiled</em> ] type <em>servicename</em> + s6-rc-db [ -l <em>live</em> ] [ -c <em>compiled</em> ] [ -u | -d ] timeout <em>atomicname</em> + s6-rc-db [ -l <em>live</em> ] [ -c <em>compiled</em> ] contents <em>bundlename</em> + s6-rc-db [ -l <em>live</em> ] [ -c <em>compiled</em> ] [ -u | -d ] dependencies <em>servicename</em> + s6-rc-db [ -l <em>live</em> ] [ -c <em>compiled</em> ] servicedir <em>longrunname</em> + s6-rc-db [ -l <em>live</em> ] [ -c <em>compiled</em> ] [ -u | -d ] script <em>oneshotname</em> + s6-rc-db [ -l <em>live</em> ] [ -c <em>compiled</em> ] flags <em>atomicname</em> + s6-rc-db [ -l <em>live</em> ] [ -c <em>compiled</em> ] atomics <em>servicename...</em> + s6-rc-db [ -l <em>live</em> ] [ -c <em>compiled</em> ] [ -u | -d ] all-dependencies <em>servicename...</em> +</pre> + +<ul> + <li> s6-rc-db expects to find a <em>compiled service database</em> +in <em>compiled</em>; by default it uses the service database +used by the live state in <em>live</em>. +It reads and parses the compiled database it finds. If the +database is invalid, it exits 4. </li> + <li> Depending on the arguments given, it prints the requested +information to stdout, then exits 0. </li> +</ul> + +<h2> Options </h2> + +<ul> + <li> <tt>-c <em>compiled</em></tt> : examine a +compiled service database in <em>compiled</em> instead of +the current live one. </li> + <li> <tt>-l <em>live</em></tt> : assume the live +state is in <em>live</em>. Default is +<tt>/run/s6-rc</tt>. This option is ignored if the +<tt>-c</tt> option has been given. </li> + <li> <tt>-u</tt> : for commands that use different data +depending on whether it's about bringing the service up or down, +select the "up" data. This option is ignored when it is irrelevant. </li> + <li> <tt>-d</tt> : for commands that use different data +depending on whether it's about bringing the service up or down, +select the "down" data. This option is ignored when it is irrelevant. </li> +</ul> + +<h2> Subcommands </h2> + +<h3> s6-rc-db help </h3> + +<p> + Prints a help message on stdout. +</p> + +<h3> s6-rc-db check </h3> + +<p> + Checks the database consistency. Exits 4 with an error message if +it finds a problem, such as a mismatch in the direct and reverse +dependency tables, or a dependency cycle. +</p> + + +<h2> Usage examples </h2> + +<pre> s6-rc <em>myservicebundle</em> </pre> +<p> + Brings up all the services represented by <em>myservicebundle</em>, +dependencies first. +</p> + +<pre> s6-rc -Sad </pre> +<p> + Brings down all the services in an orderly manner. This is typically +run at shutdown time. +</p> + +<pre> s6-rc -Au <em>myservicebundle</em> </pre> +<p> + Prints the names of all atomic services represented by +<em>myservicebundle</em>, as well as everything they depend on. +</p> + +<pre> s6-rc -Ad <em>myservicebundle</em> </pre> +<p> + Prints the names of all atomic services represented by +<em>myservicebundle</em>, as well as everything that depends on them. +</p> + +<pre> s6-rc -pun0 <em>myservicebundle</em> </pre> +<p> + Prints what s6-rc would do to bring the state to just +<em>myservicebundle</em> and its dependencies. +</p> + + +<h2> Internals </h2> + +</body> +</html> diff --git a/doc/s6-rc-dryrun.html b/doc/s6-rc-dryrun.html new file mode 100644 index 0000000..0a55fa6 --- /dev/null +++ b/doc/s6-rc-dryrun.html @@ -0,0 +1,64 @@ +<html> + <head> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6-rc: the s6-rc-dryrun program</title> + <meta name="Description" content="s6-rc: the s6-rc-dryrun program" /> + <meta name="Keywords" content="s6-rc dry run s6-rc-dryrun command rc init dependency state management services" /> + <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">s6-rc</a><br /> +<a href="http://skarnet.org/software/">Software</a><br /> +<a href="http://skarnet.org/">skarnet.org</a> +</p> + +<h1> The s6-rc-dryrun internal program </h1> + +<p> + s6-rc-dryrun is a command wrapper and nullifier, roughly +equivalent to the Unix <tt>echo</tt> command. When run, it +simply prints its arguments to stdout. +</p> + +<p> + s6-rc-dryrun is not meant to be used directly; it is +internally called by +<a href="s6-rc.html">s6-rc</a> when given the <tt>-n</tt> +option. When a dry-running s6-rc instance wants to change the +system state by spawning a command <tt><em>cmd</em></tt>, it spawns +<tt>s6-rc-dryrun <em>cmd</em></tt> instead, which allows the user +to see what would have been done without actually running the +command. +</p> + +<h2> Interface </h2> + +<pre> + s6-rc-dryrun [ -v <em>verbosity</em> ] [ -t <em>timeout</em> ] <em>cmd...</em> +</pre> + +<ul> + <li> s6-rc-dryrun prints its name, a colon, a space, and +the space-separated list of its arguments to stdout. </li> + <li> It then waits for <em>timeout</em> milliseconds, then +exits 0. </li> +</ul> + +<h2> Options </h2> + +<ul> + <li> <tt>-v <em>verbosity</em></tt> : if <em>verbosity</em> +is 0, s6-rc-dryrun will not print anything to stdout. Default is 1. </li> + <li> <tt>-t <em>timeout</em></tt> : sleep for <em>timeout</em> +milliseconds before exiting. Default is 1000, but when invoked by +<a href="s6-rc.html">s6-rc</a>, it will be the value of the +<em>dryruntimeout</em> argument to the <tt>-n</tt> option. This is +used to simulate a non-immediate startup or shutdown script. </li> +</ul> + +</body> +</html> diff --git a/doc/s6-rc-init.html b/doc/s6-rc-init.html new file mode 100644 index 0000000..143a0f4 --- /dev/null +++ b/doc/s6-rc-init.html @@ -0,0 +1,168 @@ +<html> + <head> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6-rc: the s6-rc-init program</title> + <meta name="Description" content="s6-rc: the s6-rc-init program" /> + <meta name="Keywords" content="s6-rc command s6-rc-init rc init dependency state management services" /> + <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">s6-rc</a><br /> +<a href="http://skarnet.org/software/">Software</a><br /> +<a href="http://skarnet.org/">skarnet.org</a> +</p> + +<h1> The s6-rc-init program </h1> + +<p> + s6-rc-init is an initialization tool for the s6-rc +system. It must be run at boot time, prior to any +invocation of the +<a href="s6-rc.html">s6-rc</a> binary. +</p> + +<h2> Requirements </h2> + + +<h2> Interface </h2> + +<pre> + s6-rc-init [ -v <em>verbosity</em> ] [ <em>servicenames...</em> ] +</pre> + +<ul> + <li> s6-rc expects to find a <em>compiled service database</em> +in <tt>/etc/s6-rc/compiled</tt> and a <em>live state</em> in +<tt>/s6/s6-rc</tt>. If it cannot find that data, it complains and +exits. + <ul> + <li> The <em>compiled service database</em> is built offline +via the <a href="s6-rc-compile.html">s6-rc-compile</a> tool. </li> + <li> The <em>live state</em> should be initialized at boot time +via the <a href="s6-rc-init.html">s6-rc-init</a> tool. It is then +maintained by s6-rc itself. </li> + </ul> </li> + <li> The command line arguments <em>servicenames...</em> define a set +of selected services the user wants to act on. </li> + <li> s6-rc computes the necessary transitions to bring the machine +to the desired state - by default a state where all the +services listed on the command line are up. If asked to, it performs +those transitions. </li> + <li> s6-rc processes services as soon as they can be processed. It +will wait until a service is up to start a dependent service, but it +will start two independent services in parallel. </li> + <li> If every state transition completes successfully, s6-rc exits 0. </li> + <li> If a state transition fails, s6-rc will not perform the transitions +that depend on it. It will wait until all the other independent transitions +are done, then exit 1. </li> +</ul> + +<h2> Options </h2> + +<h3> s6-rc control </h3> + +<ul> + <li> <tt>-v <em>verbosity</em></tt> : be more or less +verbose. Default is 1: warning and error messages will be printed to +stderr. 0 silences warnings. 2 writes information messages whenever +s6-rc performs a transition. 3 or more is debug info. </li> + <li> <tt>-n <em>dryruntimeout</em></tt> : dry run. +s6-rc will pretend to perform transitions, but will replace all its +program invocations by a call to +<a href="s6-rc-dryrun">s6-rc-dryrun</a>, which will do nothing but +print the command line s6-rc would have executed, then sleep for +<em>dryruntimeout</em> milliseconds before reporting success. </li> + <li> <tt>-t <em>timeout</em></tt> : timeout. If s6-rc +isn't done after <em>timeout</em> milliseconds, it will exit, leaving +the live state as it is at exit time. It does not kill its children, so +a child may successfully complete afterwards and the live state will +not be updated; in that case, subsequent s6-rc invocations will notice +and correctly update it. </li> + <li> <tt>-c <em>compiled</em></tt> : look for the +compiled service database in <em>compiled</em>. Default is +<tt>/etc/s6-rc/compiled</tt> </li> + <li> <tt>-l <em>live</em></tt> : look for the +live state in <em>live</em>. Default is +<tt>/s6/s6-rc</tt> </li> +</ul> + +<h3> Up or down </h3> + +<ul> + <li> <tt>-u</tt> : selected services are interpreted +as to be brought <em>up</em>. This is the default. </li> + <li> <tt>-d</tt> : selected services are interpreted +as to be brought <em>down</em>. </li> +</ul> + +<h3> Service selection </h3> + +<ul> + <li> <tt>-p</tt> : prune. The state will be brought to +<em>exactly</em> <em>servicenames...</em>, plus their dependencies, and +the other services will be brought down. With the <tt>-d</tt> option, +the meaning is reversed: the state will be brought to the maximum +possible set that does not include <em>servicenames...</em>. </li> + <li> <tt>-a</tt> : all. Add the current set of active services to +the selected set. This is useful to ensure consistency of the machine +state, for instance, and also at shutdown time: <tt>s6-rc -da</tt> +will stop all the currently active services. </li> +</ul> + +<h3> Actions </h3> + +<ul> + <li> <tt>-C</tt> : check. s6-rc will check the consistency of the +database, and exit with an error message if it finds errors. </li> + <li> <tt>-L</tt> : list. s6-rc will resolve the given names, then +print the list of corresponding atomic services to stdout, without taking their +dependencies into account. It will print an empty line afterwards. </li> + <li> <tt>-A</tt> : list all. s6-rc will print the list of selected +atomic services to stdout, after computing dependencies. Note that with +the <tt>-d</tt> option, it computes reverse dependencies instead. </li> + <li> <tt>-S</tt> : state change. A state change will be performed +for the selected services. +This is the default if no other action option has been given. </li> +</ul> + +<h2> Usage examples </h2> + +<pre> s6-rc <em>myservicebundle</em> </pre> +<p> + Brings up all the services represented by <em>myservicebundle</em>, +dependencies first. +</p> + +<pre> s6-rc -Sad </pre> +<p> + Brings down all the services in an orderly manner. This is typically +run at shutdown time. +</p> + +<pre> s6-rc -Au <em>myservicebundle</em> </pre> +<p> + Prints the names of all atomic services represented by +<em>myservicebundle</em>, as well as everything they depend on. +</p> + +<pre> s6-rc -Ad <em>myservicebundle</em> </pre> +<p> + Prints the names of all atomic services represented by +<em>myservicebundle</em>, as well as everything that depends on them. +</p> + +<pre> s6-rc -pun0 <em>myservicebundle</em> </pre> +<p> + Prints what s6-rc would do to bring the state to just +<em>myservicebundle</em> and its dependencies. +</p> + + +<h2> Internals </h2> + +</body> +</html> diff --git a/doc/s6-rc-upgrade.html b/doc/s6-rc-upgrade.html new file mode 100644 index 0000000..bdaa090 --- /dev/null +++ b/doc/s6-rc-upgrade.html @@ -0,0 +1,174 @@ +<html> + <head> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6-rc: the s6-rc-update program</title> + <meta name="Description" content="s6-rc: the s6-rc-update program" /> + <meta name="Keywords" content="s6-rc command rc update s6-rc-update init dependency state management services" /> + <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">s6-rc</a><br /> +<a href="http://skarnet.org/software/">Software</a><br /> +<a href="http://skarnet.org/">skarnet.org</a> +</p> + +<h1> The s6-rc-update program </h1> + +<p> + s6-rc-update is an <em>online service database switcher</em>: +it will replace your compiled service database with another +one, and adjust the live state accordingly. +</p> + +<p> + Live upgrading a service database is no small feat, and no +fully automated system can get it right in all cases. +s6-rc-update will do its best on its own, but it lets you +give it instructions to handle +difficult cases; and rather than implement doubtful +heuristics, it will fail with an error message in +situations it really cannot solve. +</p> + +<h2> Interface </h2> + +<pre> + s6-rc [ -v <em>verbosity</em> ] [ <em>servicenames...</em> ] +</pre> + +<ul> + <li> s6-rc expects to find a <em>compiled service database</em> +in <tt>/etc/s6-rc/compiled</tt> and a <em>live state</em> in +<tt>/s6/s6-rc</tt>. If it cannot find that data, it complains and +exits. + <ul> + <li> The <em>compiled service database</em> is built offline +via the <a href="s6-rc-compile.html">s6-rc-compile</a> tool. </li> + <li> The <em>live state</em> should be initialized at boot time +via the <a href="s6-rc-init.html">s6-rc-init</a> tool. It is then +maintained by s6-rc itself. </li> + </ul> </li> + <li> The command line arguments <em>servicenames...</em> define a set +of selected services the user wants to act on. </li> + <li> s6-rc computes the necessary transitions to bring the machine +to the desired state - by default a state where all the +services listed on the command line are up. If asked to, it performs +those transitions. </li> + <li> s6-rc processes services as soon as they can be processed. It +will wait until a service is up to start a dependent service, but it +will start two independent services in parallel. </li> + <li> If every state transition completes successfully, s6-rc exits 0. </li> + <li> If a state transition fails, s6-rc will not perform the transitions +that depend on it. It will wait until all the other independent transitions +are done, then exit 1. </li> +</ul> + +<h2> Options </h2> + +<h3> s6-rc control </h3> + +<ul> + <li> <tt>-v <em>verbosity</em></tt> : be more or less +verbose. Default is 1: warning and error messages will be printed to +stderr. 0 silences warnings. 2 writes information messages whenever +s6-rc performs a transition. 3 or more is debug info. </li> + <li> <tt>-n <em>dryruntimeout</em></tt> : dry run. +s6-rc will pretend to perform transitions, but will replace all its +program invocations by a call to +<a href="s6-rc-dryrun">s6-rc-dryrun</a>, which will do nothing but +print the command line s6-rc would have executed, then sleep for +<em>dryruntimeout</em> milliseconds before reporting success. </li> + <li> <tt>-t <em>timeout</em></tt> : timeout. If s6-rc +isn't done after <em>timeout</em> milliseconds, it will exit, leaving +the live state as it is at exit time. It does not kill its children, so +a child may successfully complete afterwards and the live state will +not be updated; in that case, subsequent s6-rc invocations will notice +and correctly update it. </li> + <li> <tt>-c <em>compiled</em></tt> : look for the +compiled service database in <em>compiled</em>. Default is +<tt>/etc/s6-rc/compiled</tt> </li> + <li> <tt>-l <em>live</em></tt> : look for the +live state in <em>live</em>. Default is +<tt>/s6/s6-rc</tt> </li> +</ul> + +<h3> Up or down </h3> + +<ul> + <li> <tt>-u</tt> : selected services are interpreted +as to be brought <em>up</em>. This is the default. </li> + <li> <tt>-d</tt> : selected services are interpreted +as to be brought <em>down</em>. </li> +</ul> + +<h3> Service selection </h3> + +<ul> + <li> <tt>-p</tt> : prune. The state will be brought to +<em>exactly</em> <em>servicenames...</em>, plus their dependencies, and +the other services will be brought down. With the <tt>-d</tt> option, +the meaning is reversed: the state will be brought to the maximum +possible set that does not include <em>servicenames...</em>. </li> + <li> <tt>-a</tt> : all. Add the current set of active services to +the selected set. This is useful to ensure consistency of the machine +state, for instance, and also at shutdown time: <tt>s6-rc -da</tt> +will stop all the currently active services. </li> +</ul> + +<h3> Actions </h3> + +<ul> + <li> <tt>-C</tt> : check. s6-rc will check the consistency of the +database, and exit with an error message if it finds errors. </li> + <li> <tt>-L</tt> : list. s6-rc will resolve the given names, then +print the list of corresponding atomic services to stdout, without taking their +dependencies into account. It will print an empty line afterwards. </li> + <li> <tt>-A</tt> : list all. s6-rc will print the list of selected +atomic services to stdout, after computing dependencies. Note that with +the <tt>-d</tt> option, it computes reverse dependencies instead. </li> + <li> <tt>-S</tt> : state change. A state change will be performed +for the selected services. +This is the default if no other action option has been given. </li> +</ul> + +<h2> Usage examples </h2> + +<pre> s6-rc <em>myservicebundle</em> </pre> +<p> + Brings up all the services represented by <em>myservicebundle</em>, +dependencies first. +</p> + +<pre> s6-rc -Sad </pre> +<p> + Brings down all the services in an orderly manner. This is typically +run at shutdown time. +</p> + +<pre> s6-rc -Au <em>myservicebundle</em> </pre> +<p> + Prints the names of all atomic services represented by +<em>myservicebundle</em>, as well as everything they depend on. +</p> + +<pre> s6-rc -Ad <em>myservicebundle</em> </pre> +<p> + Prints the names of all atomic services represented by +<em>myservicebundle</em>, as well as everything that depends on them. +</p> + +<pre> s6-rc -pun0 <em>myservicebundle</em> </pre> +<p> + Prints what s6-rc would do to bring the state to just +<em>myservicebundle</em> and its dependencies. +</p> + + +<h2> Internals </h2> + +</body> +</html> diff --git a/doc/s6-rc.html b/doc/s6-rc.html index eeefe7a..34dfc59 100644 --- a/doc/s6-rc.html +++ b/doc/s6-rc.html @@ -26,7 +26,7 @@ desired state, by starting or stopping services as needed. <h2> Interface </h2> <pre> - s6-rc [ -v <em>verbosity</em> ] [<em>servicenames...</em> + s6-rc [ -v <em>verbosity</em> ] [ <em>servicenames...</em> ] </pre> <ul> diff --git a/doc/upgrade.html b/doc/upgrade.html new file mode 100644 index 0000000..9536af8 --- /dev/null +++ b/doc/upgrade.html @@ -0,0 +1,28 @@ +<html> + <head> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6-rc: how to upgrade</title> + <meta name="Description" content="s6-rc: how to upgrade" /> + <meta name="Keywords" content="s6-rc installation upgrade" /> + <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">s6-rc</a><br /> +<a href="http://skarnet.org/software/">Software</a><br /> +<a href="http://skarnet.org/">skarnet.org</a> +</p> + +<h1> What has changed in s6-rc </h1> + +<h2> in 0.0.1.0 </h2> + +<ul> + <li> Initial release. </li> +</ul> + +</body> +</html> diff --git a/doc/why.html b/doc/why.html new file mode 100644 index 0000000..f544e08 --- /dev/null +++ b/doc/why.html @@ -0,0 +1,278 @@ +<html> + <head> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6-rc: why?</title> + <meta name="Description" content="s6-rc: why?" /> + <meta name="Keywords" content="s6-rc why reason rationale" /> + <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">s6-rc</a><br /> +<a href="http://skarnet.org/software/">Software</a><br /> +<a href="http://skarnet.org/">skarnet.org</a> +</p> + +<h1> Why s6-rc ? </h1> + +<h2> The limits of supervision suites </h2> + +<p> + Supervision suites such as +<a href="http://skarnet.org/software/s6/">s6</a>, +<a href="http://smarden.org/runit/">runit</a>, +<a href="http://b0llix.net/perp/">perp</a> or +<a href="http://cr.yp.to/daemontools.html">daemontools</a> +define a <em>service</em> as a long-lived process, a.k.a a +daemon. They provide tools to run the daemon in a reproducible +way in a controlled environment and keep it alive if it dies; +they also provide daemon management tools to, among others, +send signals to the daemon without knowing its PID. They can +control individual long-lived process perfectly well, and +<a href="http://skarnet.org/software/s6/">s6</a> also provides +tools to manage a whole supervision tree. +</p> + +<p> + However, a supervision suite is not a service manager. +</p> + +<p> + Relying on a supervision suite to handle all the service +management is doable on simple systems, where there aren't +many dependencies, and where most of the one-time initialization +can take place in stage 1, before any daemons are launched. +On embedded systems, for instance, this is perfectly reasonable. +</p> + +<p> + On bigger systems, though, it is more problematic. Here are a few +issues encountered: +</p> + +<ul> + <li> With a pure supervision tree, all daemons are launched in +parallel; if their dependencies are not met, daemons just die, and +are restarted by the supervisors, and so on; so eventually everything +is brought up. This is okay with lightweight daemons that do not take +up too many resources when starting; but with heavyweight daemons, +bringing them up at the wrong time can significantly expend CPU and +increase the total booting time. </li> + <li> The <a href="http://smarden.org/runit/">runit</a> model of +separating one-time initialization (stage 1) and daemon management +(stage 2) does not always work: some one-time initialization may +depend on a daemon being up. Example: udevd on Linux. Such daemons +then need to be run in stage 1, unsupervised - which defeats the +purpose of having a supervision suite. </li> + <li> More generally, supervision suites do not perform +<em>dependency management</em>. Their job is to maintain daemons +alive and ease their administration; dependency across those +daemons is not their concern, and one-time initialization scripts +are entirely foreign to them. So a situation like <tt>udevd</tt> +where it is necessary to interleave daemons and one-time scripts +is very badly handled by them. </li> +</ul> + +<p> + To manage complex systems, pure supervision suites are insufficient, +and real <em>service managers</em>, starting and stopping services +in the proper order and handling both <em>oneshots</em> (one-time +initialization scripts) and <em>longruns</em> (daemons), are needed. +</p> + +<h2> Previous alternatives </h2> + +<p> + Unix distributions usually come with their own init systems and +service managers; all of those have flaws one way or another. No +widely spread init system gets things right, which is the main +reason for the recent "init wars" - there are strong, valid reasons +to support such or such init system, but <em>also</em> strong, valid +reason to dislike it. +</p> + +<p> + Non-supervision init systems usually fall in one of two categories, +both with pros and cons. +</p> + +<h3> Traditional, sequential starters </h3> + +<p> + Those are either the historical Unix init systems, or newer systems +that still favor simplicity. Among them, for instance: +</p> + +<ul> + <li> <a href="http://savannah.nongnu.org/projects/sysvinit">sysvinit</a>, +the historical GNU/Linux init system, and its companion set of +<tt>/etc/rc.d</tt> init scripts that some distributions like to +call <tt>sysv-rc</tt>. Note that sysvinit <em>does</em> have +supervision capabilities, but nobody ever bothered to use them +for anything else than <tt>getty</tt>s, and all the machine +initialization, including longruns, is done by the <tt>sysv-rc</tt> +scripts, in a less than elegant way. </li> + <li> <a href="https://www.freebsd.org/cgi/man.cgi?query=init(8)">BSD +init</a>, which is very similar to sysvinit - including the +supervision abilities that are only ever used for <tt>getty</tt>s. +The <tt>/etc/rc</tt> script takes care of all the initialization. </li> + <li> <a href="https://wiki.gentoo.org/wiki/Project:OpenRC">OpenRC</a>, +an alternative, dependency-based rc system. </li> +</ul> + +<p> + All these systems run sequentially: they will start services, either +oneshots or longruns, one by one, even when the dependency graph says +that some services could be started in parallel. Also, the daemons +they start are always unsupervised, even when the underlying init +system provides supervision features. There usually is no +<a href="http://skarnet.org/software/s6/notifywhenup.html">readiness +notification</a> support on daemons either, daemons are fire-and-forget +(but that's more on the +scripts themselves than on the frameworks). Another common criticism +of those systems is that the amount of shell scripting is so huge +that it has a significant performance impact. +</p> + +<p> + Another, less obvious, but important drawback is that service-launching +scripts run as scions of the shell that invoked the command, and so +they may exhibit different behaviours when they're run automatically at +boot time and when they're run manually by an admin, because the +environment is different. Scripts usually try to run in a clean +environment, but it's hard to think of everything (open file +descriptors!) and every script must protect itself with a gigantic +boilerplate, which adds to the inefficiency problem. +</p> + +<h3> Monolithic init behemoths </h3> + +<p> + The other category of service managers is made of attempts to cover +the flaws of traditional service starters, and provide supervision, +dependency management and sometimes readiness notification, while +reducing the amount of scripting needed. +Unfortunately, the results were tightly integrated, monolithic init +systems straying very far away from Unix core principles, with +design flaws that make the historical inits' design flaws look like +a joke. +</p> + +<ul> + <li> <a href="http://upstart.ubuntu.com/">Upstart</a> was the first +one. On the front page, in the "feature highlights" section: +"Tasks and Services are started and stopped +by events. Events are generated as tasks and services are started +and stopped." Do you understand what that means? I don't. </li> + <li> <a href="https://en.wikipedia.org/wiki/Launchd">launchd</a>, +Darwin's init and service manager. The wikipedia page (linked here +because Apple doesn't see fit to provide a documentation page for +launchd) is very clear: it replaces init, rc, init.d/rc.d, +SystemStarter, inetd, crontd, atd and watchdogd. It does all of this +in process 1. And it uses XML for daemon configuration, so process 1 +has to link in a XML parsing library. </li> + <li> <a href="http://www.freedesktop.org/wiki/Software/systemd/">systemd</a>, +the main protagonist (or antagonist) in the "init wars". It has the same +problems as launchd, up by an order of magnitude; +<a href="http://skarnet.org/software/s6/systemd.html">here is why</a>. +systemd avowedly aims to replace the whole low-level user-space of +Linux systems, but its design is horrendous. It doesn't even +<a href="http://ewontfix.com/15/">get readiness notification right</a>. </li> +</ul> + +<p> + The problem of integrated init systems is that: +</p> + +<ul> + <li> They have been developed by companies and associations, not +individuals, and despite the licensing, they are for all intents and +purposes closer to proprietary software than free software; they also +suffer from many of the technical flaws of enterprise software +design. </li> + <li> As a result, and despite being backed by tremendous manpower, +they have been very poorly thought out. The manpower goes into the +coding of features, not into architecture conception; and the +architects were obviously not Unix experts, which is a shame when +it's about creating a process 1 for Unix. This is apparent because: </li> + <li> They have been designed like <em>application software</em>, not +<em>system software</em>, which requires a fairly different set of +skills, and careful attention to details - such as minimal software +dependencies and shortness of code paths - that are not as important +in application software. </li> +</ul> + +<p> + Pages and pages could be written about the shortcomings of integrated +init systems; one fact remains - they are not a satisfying solution +to the problem of service management under Unix. +</p> + +<h2> The best of both worlds </h2> + +<p> + s6-rc aims to be such a solution: it is small and modular, but offers +full functionality. Parallel service startup and shutdown with +correct dependency management (none of the systemd nonsense where +services are started before their dependencies are met), correct +readiness notification support, reproducible script execution, and +<em>short code paths</em>. +</p> + +<ul> + <li> s6-rc is a <em>service manager</em>, i.e. the equivalent of +<tt>sysv-rc</tt> or OpenRC. It is <em>not</em> an init system. +<strong>You can run s6-rc with any init system of your choosing.</strong> +Of course, s6-rc requires a s6 supervision tree to be running on +the system, since it delegates the management of longrun services +to that supervision tree, but it does not require that s6 be the +init system itself. s6-rc will work +<a href="http://skarnet.org/software/s6/s6-svscan-1.html">when s6-svscan +runs as process 1</a> (on Linux, such a setup can be easily achieved +via the help of the +<a href="http://skarnet.org/software/s6-linux-init/">s6-linux-init</a> +package), and it will also work +<a href="http://skarnet.org/software/s6/s6-svscan-not-1.html">when +s6-svscan runs under another init process</a>. </li> + <li> The service manager runs <em>on top of</em> a supervision +suite. It does not try to make it perform boot/shutdown operations or +dependency management itself; and it does not substitute itself to it. +s6-rc uses the functionality provided by s6, but it is still possible +to run s6 without s6-rc for systems that do not need a service manager. +It would also be theoretically possible to run s6-rc on top of another +supervision suite, if said supervision suite provided the hooks that +s6-rc needs. </li> + <li> A significantly time-consuming part of a service manager is +the analysis of a set of services and computation of a dependency graph +for that set. At the time of writing this document, s6-rc is the only +service manager that performs that work <em>offline</em>, eliminating +the dependency analysis overhead from boot time, shutdown time, or +any other time where the machine state changes. </li> + <li> The <em>source</em> format for the +<a href="s6-rc-compile.html">s6-rc-compile</a> tool is purposefully +simple, in order to allow external tools to automatically write +service definitions for s6-rc - for instance for conversions between +service manager formats. </li> + <li> Like every +<a href="http://skarnet.org/software/">skarnet.org tool</a>, s6-rc +is made of very little code, that does its job and nothing else. +The binaries are small, it is very light in memory usage, and the +code paths are extremely short. </li> +</ul> + + +<p> + The combination of s6 and s6-rc makes a complete, full-featured and +performant init system and service manager, with probably the lowest +total memory footprint of any service manager out there, and all the +reliability and ease of administration that a supervision suite can +provide. It is a real, viable alternative to integrated init +behemoths, providing equivalent functionality while being much +smaller and much, much more maintainable. +</p> + +</body> +</html> |