about summary refs log tree commit diff
path: root/doc/why.html
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2014-12-05 22:26:11 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2014-12-05 22:26:11 +0000
commit90b12bd71bb9fc79a4640b9112c13ef529d0196a (patch)
tree523b3f4ee2969e7a729bab2ba749c4b924ae62af /doc/why.html
downloads6-90b12bd71bb9fc79a4640b9112c13ef529d0196a.tar.gz
s6-90b12bd71bb9fc79a4640b9112c13ef529d0196a.tar.xz
s6-90b12bd71bb9fc79a4640b9112c13ef529d0196a.zip
Initial commit
Diffstat (limited to 'doc/why.html')
-rw-r--r--doc/why.html203
1 files changed, 203 insertions, 0 deletions
diff --git a/doc/why.html b/doc/why.html
new file mode 100644
index 0000000..1901259
--- /dev/null
+++ b/doc/why.html
@@ -0,0 +1,203 @@
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta http-equiv="Content-Language" content="en" />
+    <title>s6: why another supervision suite</title>
+    <meta name="Description" content="s6: why another supervision suite" />
+    <meta name="Keywords" content="s6 supervision daemontools runit perp service svscan supervise" />
+    <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> -->
+  </head>
+<body>
+
+<p>
+<a href="index.html">s6</a><br />
+<a href="http://skarnet.org/software/">Software</a><br />
+<a href="http://skarnet.org/">skarnet.org</a>
+</p>
+
+<h1> Why another supervision suite ? </h1>
+
+<p>
+ Supervision suites are becoming quite common. Today, we already have:
+</p>
+
+<ul>
+ <li> Good (?) old System V init, which can be made to supervise services if you perform <tt>/etc/inittab</tt> voodoo.
+BSD init can also be used the same way with the <tt>/etc/ttys</tt> file, but for some reason, nobody among BSD
+developers is using <tt>/etc/ttys</tt> to this purpose, so I won't consider BSD init here. </li>
+ <li> <a href="http://cr.yp.to/daemontools.html">daemontools</a>, the pioneer </li>
+ <li> <a href="http://untroubled.org/daemontools-encore/">daemontools-encore</a>, Bruce Guenter's upgrade to daemontools </li>
+ <li> <a href="http://smarden.org/runit/">runit</a>, Gerrit Pape's suite, well-integrated with Debian </li>
+ <li> <a href="http://b0llix.net/perp/">perp</a>, Wayne Marshall's take on supervision </li>
+ <li> Integrated init systems providing a lot of features, process supervision being one of them.
+For instance, <a href="http://upstart.ubuntu.com/">Upstart</a>, MacOS X's 
+<a href="http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man8/launchd.8.html">launchd</a>,
+and Fedora's <a href="http://freedesktop.org/wiki/Software/systemd">systemd</a>. </li>
+</ul>
+
+<p>
+ Why is s6 needed ? What does it do differently ? Here are the criteria I used.
+</p>
+
+
+<h2> Supervision suites should not wake up unless notified. </h2>
+
+<ul>
+ <li> System V init fails the test: it wakes up every 5 seconds, for the reason that
+<tt>/dev/initctl</tt> might have changed.
+<a href="http://demotivate.me/mediafiles/full/4162010103911AM_picard-no-facepalm.jpg"><tt>m(</tt></a> </li>
+ <li> daemontools fails the test: it wakes up every 5 seconds to check for new services. </li>
+ <li> daemontools-encore does the same. </li>
+ <li> the current version of runit fails the test: it wakes up every 14 seconds. But this is a workaround for a bug in some Linux kernels;
+there is no design flaw in runit that prevents it from passing the test. </li>
+ <li> perp works. </li>
+ <li> Upstart works. I have no idea what other integrated init systems do: it's much too difficult to strace them
+to see exactly where they're spending their time, and when it is possible, the trace output is so big that it's
+hard to extract any valuable information from it. </li>
+ <li> s6 works. By default, s6-svscan wakes up every 5 seconds, to emulate
+<a href="http://cr.yp.to/daemontools/svscan.html">svscan</a> behaviour; but it
+can be told not to do so. (<tt>s6-svscan -t0</tt>) </li>
+</ul>
+
+
+<h2> Supervision suites should provide a program that can run as process 1. </h2>
+
+<ul>
+ <li> System V init <em>is</em> process 1, so no problem here. </li>
+ <li> Integrated init systems, by definition, provide a process 1. </li>
+ <li> daemontools was not designed to take over init, although
+<a href="http://code.dogmap.org./svscan-1/">it can be made to work</a> with
+enough hacking skills. Same thing with daemontools-encore. </li>
+ <li> runit provides an <em>init</em> functionality, but the mechanism is
+separate from the supervision itself; the <tt>runit</tt> process, not the
+<tt>runsvdir</tt> process, runs as process 1. This lengthens the supervision
+chain. </li>
+ <li> perp was not designed to run as process 1. It probably could be made to work too
+without too much trouble. </li>
+ <li> s6-svscan was designed from the start to be run as process 1, although it
+does not have to. </li>
+</ul>
+
+
+<h2> Supervision suites should be bug-free, lightweight and easy to understand. </h2>
+
+<ul>
+ <li> daemontools, daemontools-encore, runit and perp all qualify. All of this is excellent quality
+code, <a href="http://skarnet.org/software/skalibs/djblegacy.html">unsurprisingly</a>. </li>
+ <li> System V init is understandable, and reasonably lightweight; but it is still
+too big for what it does - poorly. The <tt>/etc/inittab</tt> file needs to be parsed;
+that parser has to be in process 1. There is support in process 1 for the whole
+"runlevel" concept, which is a primitive form of service management. The same
+executable handles all 3 stages of the machine's lifetime and does not separate
+them properly. All in all, System V init does its job, but is showing its age
+and nowadays we know much better designs. </li>
+ <li> This is where integrated init systems fail, hard. By wanting to organize
+the way a the machine is operated - so, machine state management - in the
+<em>same package</em> as the init and process supervision system, they add
+incredible complexity where it does not belong.
+ <ul>
+  <li> Upstart uses <tt>ptrace</tt> to watch its children fork(), and links
+process 1 against libdbus. This is insane.
+Process 1 should be <em>absolutely stable</em>, it should be guaranteed
+to never crash, so the whole of its source code should be under control. At
+Upstart's level of complexity, those goals are outright impossible to achieve,
+so this approach is flawed by design. </li>
+ <li> launchd suffers from the same kind of problem. Regardless of how
+things are actually implemented inside (which I have no idea about), services
+running under launchd must be configured
+<a href="https://developer.apple.com/library/mac/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingLaunchdJobs.html">using
+XML</a>. That means there is an XML parser in process 1.
+<a href="https://software.intel.com/sites/default/files/race.jpg">What
+could possibly go wrong&nbsp;?</a> </li>
+ <li> systemd is much, much worse than the other ones, and a real danger
+for the future of GNU/Linux. I have a <a href="systemd.html">special page</a>
+dedicated to it. </li>
+ </ul>
+ What those systems fail to recognize is that process supervision, rooted in
+process 1, is a good thing, and machine management is also a good thing, but
+<strong>those are two different functions</strong>, and a good init system
+needs, and <strong>should</strong>, only provide process supervision, in
+order to keep such a crucial piece of code as easy to maintain as possible.
+Machine management can be added <em>on top of</em> a process supervision
+suite, in a different package, and it has nothing to do with process 1. </li>
+ <li> s6, which has been designed with embedded environments in mind, tries
+harder than anyone to pass this. It tries so hard that <tt>s6-svscan</tt>
+and <tt>s6-supervise</tt>, the two long-running programs that make the
+supervision chain, <em>do not even allocate heap memory</em>, and their main
+program source files are less than 500 lines long. </li>
+</ul>
+
+
+<h2> Supervision suites should provide a basis for high-level service management. </h2>
+
+<ul>
+ <li> Neither System V init, daemontools, runit or perp
+provides any hooks to wait for a service to go up or down. runit provides a
+waiting mechanism, but it's based on polling, and the <tt>./check</tt> script
+has to be manually written for every service. </li>
+ <li> daemontools-encore qualifies: the <em>notify script</em> can be used for
+inter-service communication. But it's just a hook: all the real notification
+work has to be done by the notify script itself, no notification framework is
+provided. </li>
+ <li> Integrated init systems provide high-level service management
+themselves. Again, this is not good design: service management has nothing
+to do with init or process supervision, and should be implemented on top
+of it, not as a part of it. </li>
+ <li> s6 comes with <a href="libftrig.html">libftrig</a>, an event notification
+library, and command-line tools based on this library, thus providing a simple
+API for future service management tools to build upon. </li>
+</ul>
+
+
+<h2> Artistic considerations </h2>
+
+<ul>
+ <li> <tt>s6-svscan</tt> and <tt>s6-supervise</tt> are <em>entirely asynchronous</em>.
+Even during trouble (full process table, for instance), they'll remain reactive
+and instantly respond to commands they may receive. <tt>s6-supervise</tt> has
+even been implemented as a full deterministic finite automaton, to ensure it
+always does the right thing under any circumstance. Other supervision suites
+do not achieve that for now. </li>
+ <li> daemontools' <a href="http://cr.yp.to/daemontools/svscan.html">svscan</a>
+maintains an open pipe between a daemon and its logger, so even if the daemon,
+the logger, <em>and</em> both
+<a href="http://cr.yp.to/daemontools/supervise.html">supervise</a> processes
+die, the pipe is still the same so <em>no logs are lost, ever</em>, unless
+svscan itself dies. </li>
+ <li> runit has only one supervisor, <a href="http://smarden.org/runit/runsv.8.html">runsv</a>,
+for both a daemon and its logger. The pipe is maintained by <tt>runsv</tt>.
+If the <tt>runsv</tt> process dies, the pipe disappears and logs are lost.
+So, runit does not offer as strong a guarantee as daemontools. </li>
+ <li> perp has only one process, <a href="http://b0llix.net/perp/site.cgi?page=perpd.8">perpd</a>,
+acting both as a "daemon and logger supervisor" (like <tt>runsv</tt>) and as a
+"service directory scanner" (like <tt>runsvdir</tt>). It maintains the pipes
+between the daemons and their respective loggers. If perpd dies, everything
+is lost. Since perpd cannot be run as process 1, this is a possible SPOF for
+a perp installation; however, perpd is well-written and has virtually no risk of
+dying, especially compared to process 1 behemoths provided by integrated
+init systems. </li>
+ <li> Besides, the <tt>runsv</tt> model, which has to handle both a daemon
+and its logger, is more complex than the <tt>supervise</tt> model (which
+only has to handle a daemon). Consequently, the <tt>runsvdir</tt> model is
+simpler than the <tt>svscan</tt> model, but there is only one <tt>svscan</tt>
+instance when there are several <tt>runsv</tt>s and <tt>supervise</tt>s.
+The <tt>perpd</tt> model is obviously the most complex; while very understandable,
+<tt>perpd</tt> is unarguably harder to maintain than the other two. </li>
+ <li> So, to achieve maximum simplicity and code reuse, and minimal memory
+footprint, s6's design is close to daemontools' one.
+And when <a href="s6-svscan-1.html">s6-svscan is run as process 1</a>,
+pipes between daemons and loggers are never lost. </li>
+</ul>
+
+
+<h2> Conclusion </h2>
+
+<p>
+ All in all, I believe that s6 offers the best overall implementation of a
+supervision suite <em>as it should be designed</em>. At worst, it's just another
+take on daemontools with a <a href="http://skarnet.org/software/skalibs/">reliable
+base library</a> and a few nifty features.
+</p>
+
+</body>
+</html>