about summary refs log tree commit diff
path: root/doc
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2023-01-09 11:09:14 +0000
committerLaurent Bercot <ska@appnovation.com>2023-01-09 11:09:14 +0000
commit09750ce3525129a676dec4f579aea3ad2eca1b19 (patch)
treeacae6b5f47914d7ed85bbb8fe9780ed34a85cfd0 /doc
parent191b46491407632f2431c46eab97dbf5543fa26d (diff)
downloads6-09750ce3525129a676dec4f579aea3ad2eca1b19.tar.gz
s6-09750ce3525129a676dec4f579aea3ad2eca1b19.tar.xz
s6-09750ce3525129a676dec4f579aea3ad2eca1b19.zip
Add instances implementation (still needs testing)
Signed-off-by: Laurent Bercot <ska@appnovation.com>
Diffstat (limited to 'doc')
-rw-r--r--doc/index.html10
-rw-r--r--doc/instances.html121
-rw-r--r--doc/s6-instance-control.html65
-rw-r--r--doc/s6-instance-create.html92
-rw-r--r--doc/s6-instance-delete.html72
-rw-r--r--doc/s6-instance-maker.html203
-rw-r--r--doc/s6-log.html2
-rw-r--r--doc/s6-svc.html7
-rw-r--r--doc/s6-usertree-maker.html6
-rw-r--r--doc/servicedir.html7
10 files changed, 582 insertions, 3 deletions
diff --git a/doc/index.html b/doc/index.html
index c0c8403..8b87d71 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -271,6 +271,16 @@ synchronization</a>.
 <li><a href="s6-usertree-maker.html">The <tt>s6-usertree-maker</tt> program</a></li>
 </ul>
 
+<h4> Management of dynamic instances </h4>
+
+<ul>
+<li>An <a href="instances.html">overview</a> of dynamic instantiation in s6</li>
+<li><a href="s6-instance-maker.html">The <tt>s6-instance-maker</tt> program</a></li>
+<li><a href="s6-instance-create.html">The <tt>s6-instance-create</tt> program</a></li>
+<li><a href="s6-instance-delete.html">The <tt>s6-instance-delete</tt> program</a></li>
+<li><a href="s6-instance-control.html">The <tt>s6-instance-control</tt> program</a></li>
+</ul>
+
 <h4> Timed lock acquisition </h4>
 
 <ul>
diff --git a/doc/instances.html b/doc/instances.html
new file mode 100644
index 0000000..0586fdb
--- /dev/null
+++ b/doc/instances.html
@@ -0,0 +1,121 @@
+<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: dynamic instantiation</title>
+    <meta name="Description" content="s6: dynamic instantiation" />
+    <meta name="Keywords" content="s6 instances dynamic instantiation" />
+    <!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> -->
+  </head>
+<body>
+
+<p>
+<a href="index.html">s6</a><br />
+<a href="//skarnet.org/software/">Software</a><br />
+<a href="//skarnet.org/">skarnet.org</a>
+</p>
+
+<h1> Dynamic instantiation under s6 </h1>
+
+<p>
+ A <em>instanced service</em> is a parameterized service that you want to
+run several copies of, with only the parameter changing. Each copy of the
+service is called an <em>instance</em>.
+</p>
+
+<p>
+ With s6, a <a href="servicedir.html">service directory</a> can only
+handle one process at a time. So, if we want instanced services, there
+will have to be one service directory per instance, always.
+</p>
+
+<p>
+ <em>Static instantiation</em> means that the set of possible instances
+is finite and known in advance. With s6, it means that all the service
+directories for all possible instances are created, typically by a
+preprocessor, and instances are treated like regular services.
+</p>
+
+<p>
+ <em>Dynamic instantiation</em> means that instances are created
+on demand instead of preallocated. Starting with version 2.11.2.0, s6
+provides a few tools to help users set up and manage dynamically
+instanced services.
+</p>
+
+<h2> How to make a dynamically instanced service under s6 </h2>
+
+<ul>
+ <li> Write a template for a service directory that would run under
+<a href="s6-supervise.html">s6-supervise</a>.
+The <tt>run</tt> script should take the name of the instance as its
+first argument; the <tt>finish</tt> script should take the name of the
+instance as its third argument. </li>
+ <li> Call the <a href="s6-instance-maker.html">s6-instance-maker</a> program
+with this template as first argument, and a path <em>dir</em> as second
+argument. <a href="s6-instance-maker.html">s6-instance-maker</a> will create
+a service directory in <em>dir</em>. This is an offline tool: it does not
+interact with any currently active services or supervision trees. </li>
+ <li> Supervise <em>dir</em> by adding it to your regular
+<a href="scandir.html">scan directory</a>. This will be your instanced
+service, but it's not running any instances yet. It is, instead, a nested
+supervision tree - the instanced service is an
+<a href="s6-svscan.html">s6-svscan</a> process that will supervise all the
+instances. </li>
+ <li> Create and delete instances at will with the
+<a href="s6-instance-create.html">s6-instance-create</a> and
+<a href="s6-instance-delete.html">s6-instance-delete</a> programs. Instances
+are regular supervised processes; you can control them with
+<a href="s6-instance-control.html">s6-instance-control</a>. These tools are
+<em>online</em>: they work with live service directories (i.e. that are
+being supervised by <a href="s6-supervise.html">s6-supervise</a>). They
+are really syntactic sugar around the
+<a href="s6-svlink.html">s6-svlink</a>,
+<a href="s6-svunlink.html">s6-svunlink</a> and
+<a href="s6-svc.html">s6-svc</a> programs; they provide you with the
+same functionality but allow you to address individual instances via the
+instanced service name (the service directory running the nested
+supervision tree) and the instance name. </li>
+</ul>
+
+<h2> Internal workings </h2>
+
+<p>
+This section is not normative; users should not rely on it. It is only
+here for informational purposes.
+</p>
+
+<ul>
+ <li> The service directory created by <a href="s6-instance-maker.html">s6-instance-maker</a>
+has two specifics subdirectories in it: <tt>instance</tt> and <tt>instances</tt>. They
+are initially empty, except that the template service directory is stored in
+<tt>instances/.template</tt>. </li>
+ <li> When the service is active, there is an <a href="s6-svscan.html">s6-svscan</a>
+process running on <tt>instance</tt>. </li>
+ <li> <a href="s6-instance-create.html">s6-instance-create</a> makes a copy of
+<tt>instances/.template</tt> into <tt>instances/<em>name</em>/tt>, and
+<a href="s6-svlink.html">s6-svlink</a>s <tt>instances/<em>name</em>/tt> to
+<tt>instance</tt>. When it returns, there is an <a href="s6-supervise.html">s6-supervise</a>
+process running on <tt>instance/<em>name</em></tt>, and the instance may be up
+or not depending on the given options. </li>
+ <li> <a href="s6-instance-control.html">s6-instance-control</a> is syntactic sugar
+around <a href="s6-svc.html">s6-svc</a> on <tt>instance/<em>name</em></tt>. </li>
+ <li> <a href="s6-instance-delete.html">s6-instance-delete</a> is syntactic sugar
+around <a href="s6-svunlink.html">s6-svunlink</a> on <tt>instance/<em>name</em></tt>. </li>
+</ul>
+
+<h2> Notes </h2>
+
+<ul>
+ <li> This implementation of dynamic instances may seem expensive: it
+creates one <a href="s6-svscan.html">s6-svscan</a> process per
+instanced service, and one <a href="s6-supervise.html">s6-supervise</a>
+process per instance. However, remember that these processes use very
+little private memory, so having additional copies of them is far less
+expensive than it looks. It's really a convenient way to implement the
+feature by reusing existing code. </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/s6-instance-control.html b/doc/s6-instance-control.html
new file mode 100644
index 0000000..cd76688
--- /dev/null
+++ b/doc/s6-instance-control.html
@@ -0,0 +1,65 @@
+<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: the s6-instance-control program</title>
+    <meta name="Description" content="s6: the s6-instance-control program" />
+    <meta name="Keywords" content="s6 command s6-instance-control instance dynamic instantiation instanced services control s6-svc" />
+    <!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> -->
+  </head>
+<body>
+
+<p>
+<a href="index.html">s6</a><br />
+<a href="//skarnet.org/software/">Software</a><br />
+<a href="//skarnet.org/">skarnet.org</a>
+</p>
+
+<h1> The s6-instance-control program </h1>
+
+<p>
+s6-instance-control sends commands to a running instance of an
+<a href="instances.html">instanced service</a>.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+     s6-instance-control [ -wu | -wU | -wd | -wD | -wr | -wR ] [ -T <em>timeout</em> ] [ -abqhkti12pcyoduDUxOr ] <em>servicedir</em> <em>name</em>
+</pre>
+
+<ul>
+ <li> s6-instance-control expects a running, supervised
+<a href="instances.html">instanced service</a> in <em>servicedir</em>,
+as well as an existing instance of this service named <em>name</em>. </li>
+ <li> It sends the given series of commands to the supervisor monitoring
+the <em>name</em> instance. </li>
+ <li> It exits 0. </li>
+</ul>
+
+<h2> Exit codes </h2>
+
+<ul>
+ <li> 0: success </li>
+ <li> 99: with one of the <tt>-w</tt> options, timed out while waiting for the command to complete </li>
+ <li> 100: wrong usage </li>
+ <li> 111: system call failed </li>
+</ul>
+
+<h2> Options </h2>
+
+<p>
+ The options, and the commands they represent, are exactly the same as the ones
+understood by <a href="s6-svc.html">s6-svc</a>.
+</p>
+
+ In fact, s6-instance-control is
+nothing more than a call to <a href="s6-svc.html">s6-svc</a> on the service
+directory representing the <em>name</em> instance. It is syntactic sugar so
+the user does not have to depend on the internal representation of instances
+and the location of instances' service directories.
+</p>
+
+</body>
+</html>
diff --git a/doc/s6-instance-create.html b/doc/s6-instance-create.html
new file mode 100644
index 0000000..c81dfe4
--- /dev/null
+++ b/doc/s6-instance-create.html
@@ -0,0 +1,92 @@
+<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: the s6-instance-create program</title>
+    <meta name="Description" content="s6: the s6-instance-create program" />
+    <meta name="Keywords" content="s6 command s6-instance-create instance dynamic instantiation instanced services creation s6-svlink" />
+    <!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> -->
+  </head>
+<body>
+
+<p>
+<a href="index.html">s6</a><br />
+<a href="//skarnet.org/software/">Software</a><br />
+<a href="//skarnet.org/">skarnet.org</a>
+</p>
+
+<h1> The s6-instance-create program </h1>
+
+<p>
+s6-instance-create creates a new instance of a currently supervised
+<a href="instances.html">instanced service</a>.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+     s6-instance-create [ -d | -D ] [ -P ] [ -f ] [ -t <em>timeout</em> ] <em>servicedir</em> <em>name</em>
+</pre>
+
+<ul>
+ <li> s6-instance-create expects a running, supervised
+<a href="instances.html">instanced service</a> in <em>servicedir</em>.
+This service typically has been created by linking the result of an
+<a href="s6-instance-maker.html">s6-instance-maker</a> invocation into
+an existing <a href="scandir.html">scan directory</a>. </li>
+ <li> s6-instance-create creates a new instance of that service, named
+<em>name</em>. Depending on the given options, it may start it
+immediately, or keep it down until a later
+<a href="s6-instance-control.html">s6-instance-control</a> invocation. </li>
+ <li> It waits for the new instance to be ready to take commands from
+<a href="s6-instance-control.html">s6-instance-control</a>. </li>
+ <li> It exits 0. </li>
+</ul>
+
+<h2> Exit codes </h2>
+
+<ul>
+ <li> 0: success </li>
+ <li> 99: timeout while waiting for the instance supervisor to start </li>
+ <li> 100: wrong usage </li>
+ <li> 111: system call failed </li>
+</ul>
+
+<h2> Options </h2>
+
+<ul>
+ <li> <tt>-d</tt>&nbsp;: down. The instance supervisor will be started, but the instance
+itself will remain down. Any <tt>down</tt> file for the instance will be
+deleted. By default, if neither the <tt>-d</tt> nor <tt>-D</tt> options have
+been given, the supervisor auto-starts the instance as soon as it runs. </li>
+ <li> <tt>-D</tt>&nbsp;: down, and stay down. The instance supervisor will be started,
+but the instance itself will remain down. A <tt>down</tt> file
+will be created for the instance. By default, if neither the <tt>-d</tt> nor <tt>-D</tt> options have
+been given, the supervisor auto-starts the instancece as soon as it runs. </li>
+ <li> <tt>-P</tt>&nbsp;: public. Everyone will be able to subscribe to the
+instance supervisor's notification. By default, only processes running with the same gid
+as the instanced service can subscribe to it. </li>
+ <li> <tt>-f</tt>&nbsp;: force permissions. You should never need to use this
+option, it is only there for testing purposes. </li>
+ <li> <tt>-t&nbsp;<em>timeout</em></tt>&nbsp;: if the instance supervisor has not started
+after <em>timeout</em> milliseconds, s6-instance-create will print a message
+to stderr and exit 99. By default, <em>timeout</em> is 0, which means no time
+limit. </li>
+</ul>
+
+<h2> Notes </h2>
+
+<ul>
+ <li> s6-instance-create is similar to
+<a href="s6-svlink.html">s6-svlink</a>, because it uses the same underlying
+library functions. Under the hood, an instance is a regular service running
+on a supervision tree that is specific to the instanced service, and
+s6-instance-create adds a service directory to that tree and ensures it gets
+supervised. </li>
+ <li> If the template for the service is logged, then s6-instance-create will
+wait until supervisors have been spawned for both the instance and its logger. </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/s6-instance-delete.html b/doc/s6-instance-delete.html
new file mode 100644
index 0000000..28eca9c
--- /dev/null
+++ b/doc/s6-instance-delete.html
@@ -0,0 +1,72 @@
+<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: the s6-instance-delete program</title>
+    <meta name="Description" content="s6: the s6-instance-delete program" />
+    <meta name="Keywords" content="s6 command s6-instance-delete instance dynamic instantiation instanced services deletion s6-svunlink" />
+    <!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> -->
+  </head>
+<body>
+
+<p>
+<a href="index.html">s6</a><br />
+<a href="//skarnet.org/software/">Software</a><br />
+<a href="//skarnet.org/">skarnet.org</a>
+</p>
+
+<h1> The s6-instance-delete program </h1>
+
+<p>
+s6-instance-delete deletes an existing instance of a currently supervised
+<a href="instances.html">instanced service</a>.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+     s6-instance-delete [ -X ] [ -t <em>timeout</em> ] <em>servicedir</em> <em>name</em>
+</pre>
+
+<ul>
+ <li> s6-instance-delete expects a running, supervised
+<a href="instances.html">instanced service</a> in <em>servicedir</em>,
+as well as an existing instance of this service named <em>name</em>
+(it doesn't matter if the instance is up or down). </li>
+ <li> It deletes the <em>name</em> instance. </li>
+ <li> It exits 0. </li>
+</ul>
+
+<h2> Exit codes </h2>
+
+<ul>
+ <li> 0: success </li>
+ <li> 100: wrong usage </li>
+ <li> 111: system call failed </li>
+</ul>
+
+<h2> Options </h2>
+
+<ul>
+ <li> <tt>-X</tt>&nbsp;: don't wait. s6-instance-delete will exit right away,
+without waiting for the instance (and its supervisor) to properly disappear. </li>
+ <li> <tt>-t&nbsp;<em>timeout</em></tt>&nbsp;: if the instance supervisor has not exited
+after <em>timeout</em> milliseconds, s6-instance-delete will still exit.
+By default, <em>timeout</em> is 0, which means no time limit. </li>
+</ul>
+
+<h2> Notes </h2>
+
+<ul>
+ <li> s6-instance-delete is similar to
+<a href="s6-svunlink.html">s6-svunlink</a>, because it uses the same underlying
+library functions. Under the hood, an instance is a regular service running
+on a supervision tree that is specific to the instanced service, and
+s6-instance-delete removes a service directory from that tree. </li>
+ <li> If the template for the service is logged, then s6-instance-delete will
+delete both the instance and its logger. </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/s6-instance-maker.html b/doc/s6-instance-maker.html
new file mode 100644
index 0000000..2eb0f4e
--- /dev/null
+++ b/doc/s6-instance-maker.html
@@ -0,0 +1,203 @@
+<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: the s6-instance-maker program</title>
+    <meta name="Description" content="s6: the s6-instance-maker program" />
+    <meta name="Keywords" content="s6 command s6-instance-maker instance dynamic instantiation instanced services" />
+    <!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> -->
+  </head>
+<body>
+
+<p>
+<a href="index.html">s6</a><br />
+<a href="//skarnet.org/software/">Software</a><br />
+<a href="//skarnet.org/">skarnet.org</a>
+</p>
+
+<h1> The s6-instance-maker program </h1>
+
+<p>
+s6-instance-maker creates a <a href="servicedir.html">service directory</a>
+implementing an <a href="instances.html">instanced service</a>. Give it a
+templated service directory describing how to run an instance of a service,
+and it will create a different service directory that can launch and
+manage several instances; each of these instances will be running a
+copy of the service directory you gave.
+</p>
+
+<p>
+ Alternatively, s6-instance-maker can create source definition directories
+for the <a href="//skarnet.org/software/s6-rc/">s6-rc</a> service manager.
+</p>
+
+<h2> Interface </h2>
+
+<pre>
+     s6-instance-maker \
+       [ -c <em>maxinstances</em> ] \
+       [ -r <em>service</em>[/<em>logger</em>[/<em>pipeline</em>]] ] \
+       [ -u <em>user</em> ] \
+       [ -l <em>loguser</em> ] \
+       [ -L <em>logdir</em> ] \
+       [ -t <em>stamptype</em> ] \
+       [ -n <em>nfiles</em> ] \
+       [ -s <em>filesize</em> ] \
+       [ -S <em>maxsize</em> ] \
+       [ -P <em>prefix</em> ] \
+       template dir
+</pre>
+
+<p>
+s6-instance-maker creates a service directory in <em>dir</em>. The
+created service will be a supervisor for a set of instances (initially empty)
+each running a copy of the service directory given in <em>template</em>.
+</p>
+
+<p>
+s6-instance-maker is an <em>offline</em> tool: it is run before you need
+instances. Once the created service directory is live, i.e. there is a
+supervisor running on it, then you can create, delete, or control
+individual instances via the
+<a href="s6-instance-create.html">s6-instance-create</a>,
+<a href="s6-instance-delete.html">s6-instance-delete</a> and
+<a href="s6-instance-control.html">s6-instance-control</a> <em>online</em>
+tools, that work with active services.
+</p>
+
+<h2> Exit codes </h2>
+
+<ul>
+ <li> 0: success </li>
+ <li> 100: wrong usage </li>
+ <li> 111: system call failed </li>
+</ul>
+
+<h2> Options </h2>
+
+<ul>
+ <li> <tt>-c</tt>&nbsp;<em>max</em>&nbsp;: Plan for a maximum of <em>max</em>
+instances. Default is <strong>500</strong>. You can't set it lower than 2 or
+higher than 90000. If your template service directory is logged, it's unadvisable
+to set this above the default. </li> <br>
+
+ <li> <tt>-r</tt>&nbsp;<em>service</em>[/<em>logger</em>[/<em>pipeline</em>]]&nbsp;:
+create <a href="//skarnet.org/software/s6-rc">s6-rc</a> source definition directories.
+When this option is given, <em>dir</em> is not created as a service directory, but
+as a directory containing at least one service: <em>dir</em>/<em>service</em>.
+<em>dir</em> is suitable as a source argument to
+<a href="//skarnet.org/software/s6-rc/s6-rc-compile.html">s6-rc-compile</a>. If
+a <em>logger</em> part is given, then a second service, <em>dir</em>/<em>logger</em>,
+is also created, as a consumer for <em>dir</em>/<em>service</em>, and the <tt>-L</tt>
+option must also be used, to provide a directory to store the logs into. If the
+<tt>/</tt><em>pipeline</em> part is also given, <em>pipeline</em>
+is used as a name for a bundle containing both <em>service</em> and <em>logger</em>.
+When the <tt>-r</tt> option is not given at all, <em>dir</em> is a regular service
+directory for direct inclusion (or linking) in a host
+<a href="scandir.html">scan directory</a>, and if the <tt>-L</tt> option is given
+then the logger for the instance supervisor and all its instances is declared in
+<em>dir</em><tt>/log</tt>). </li> <br>
+
+ <li> <tt>-u</tt>&nbsp;<em>user</em>&nbsp;: run the instance supervisor, and all
+of the instances, as user <em>user</em>. This option should only be used when the
+supervision tree that will host the instanced service is run as root. The default
+is that the service runs as the same user as the host supervision tree. </li> <br>
+
+ <li> <tt>-l</tt>&nbsp;<em>loguser</em>&nbsp;: run the logger of the instance
+supervisor, if any (see <tt>-L</tt> below) as user <em>loguser</em>. This option
+should only be used when the
+supervision tree that will host the instanced service is run as root. The default
+is that the logger runs as the same user as the host supervision tree. </li> <br>
+
+ <li> <tt>-L</tt>&nbsp;<em>logdir</em>&nbsp;: make the service logged via
+<a href="s6-log.html">s6-log</a>, and ensure its log messages go into <em>logdir</em>.
+Error messages from the instance supervisor as well as from every instance will
+be logged to <em>logdir</em>. If this option is not given, these error messages
+will fall through to the host supervision tree's catch-all logger, if any,
+or standard error otherwise. <br>
+The options listed below are only used to configured the logger and are meaningless
+if <tt>-L</tt> is not given. </li> <br>
+
+ <li> <tt>-t</tt>&nbsp;<em>stamptype</em>&nbsp;: how
+logs are timestamped in <em>logdir</em>. 0 means no timestamp, 1 means
+<a href="https://cr.yp.to/libtai/tai64.html">external TAI64N format</a>,
+2 means
+<a href="https://www.iso.org/iso/home/standards/iso8601.htm">ISO 8601 format</a>,
+and 3 means both. Default is <strong><tt>1</tt></strong>. </li> <br>
+
+  <li> <tt>-n</tt>&nbsp;<em>nfiles</em>&nbsp;: maximum number of archive files
+in <em>logdir</em>. Default is <strong><tt>10</tt></strong>. </li> <br>
+
+  <li> <tt>-s</tt>&nbsp;<em>filesize</em>&nbsp;: maximum size of the <tt>current</tt>
+file (and archive files) in <em>logdir</em>. Default is <strong><tt>1000000</tt></strong>. </li> <br>
+
+  <li> <tt>-S</tt>&nbsp;<em>maxsize</em>&nbsp;: maximum total size of the
+archives in <em>logdir</em>. Default is <strong><tt>0</tt></strong>,
+meaning no limits apart from those enforced by the <tt>-n</tt> and
+<tt>-s</tt> options. </li> <br>
+
+  <li> <tt>-P</tt>&nbsp;<em>prefix</em>&nbsp;: when logging to <em>logdir</em>,
+prefix logged lines with the <em>prefix</em> string. Default is no prefix. </li>
+</ul>
+
+<h2> The templated service directory </h2>
+
+<p>
+ <em>template</em> should be a directory that looks exactly like a service
+directory. It will not be live, i.e. at no point will <em>template</em>
+itself be supervised; instead, a copy of it is stored under <em>dir</em>
+(and a copy of that copy will be used for every instance of the service).
+You can safely move or delete <em>template</em> after running
+s6-instance-maker.
+</p>
+
+<p>
+ To differentiate between instances, the <tt>run</tt> and <tt>finish</tt>
+script in <em>template</em> should take one additional argument (the
+first argument for <tt>run</tt> and the third argument for <tt>finish</tt>).
+This argument will be the name of the instance, as provided by the
+<a href="s6-instance-create.html">s6-instance-create</a> invocation.
+</p>
+
+<h2> Logging </h2>
+
+<p>
+ The service is logged: its stderr and stdout are piped to an
+<a href="s6-log.html">s6-log</a> process running as <em>loguser</em> and
+writing to the <em>logdir</em> directory. This logger is the catch-all logger
+for the supervision tree owned by <em>user</em>; it is recommended to make
+<em>loguser</em> distinct from <em>user</em>, and to have <em>logdir</em>
+in a place that is <strong>not</strong> under the control of <em>user</em>.
+If <em>user</em> wants to keep control of their logs, they can declare a
+logger for each of their services.
+</p>
+
+<p>
+ If <em>template</em> has a <em>log</em> subdirectory, then each instance
+will have its own dedicated logger. The <tt>run</tt> and <tt>finish</tt>
+scripts for the logger of an instance named <em>name</em> will be called
+with an additional argument of <tt><em>name</em>/log</tt>. They should
+make use of this, to ensure loggers are properly differentiated between
+instances: for instance, it is not possible to run several
+<a href="s6-log.html">s6-log</a> processes on the same log directory,
+so an instance logger script containing an invocation of s6-log on a fixed
+logdir will fail as soon as there are 2 instances.
+</p>
+
+<h2> Notes </h2>
+
+<ul>
+ <li> s6-instance-maker makes use of the fact that
+<a href="//skarnet.org/software/execline/">execline</a> scripts are much
+easier to generate programmatically and to harden than shell scripts, so it is only
+built if s6 is built with <a href="//skarnet.org/software/execline/">execline</a>
+support - i.e. the <tt>--disable-execline</tt> switch has <em>not</em> been given
+to configure. </li>
+ <li> If s6-instance-maker encounters failure (and exits 111), it does not clean up
+the directories it created. Make sure to always test s6-usertree-maker's return code
+and clean up after it if needed. </li>
+</ul>
+
+</body>
+</html>
diff --git a/doc/s6-log.html b/doc/s6-log.html
index 4f2b99f..a76f9aa 100644
--- a/doc/s6-log.html
+++ b/doc/s6-log.html
@@ -233,7 +233,7 @@ printed on every output line. For instance, a <tt>pfoobar:</tt> directive means
 that the next action directives should prepend every line with <tt>foobar:</tt>
 (plus a space) before outputting it. Note that a prefix is always printed
 <em>after</em> the timestamps, if any. To remove a prefix for the next action
-directives, use <tt>p</tt>. </li>
+directives, use a standalone <tt>p</tt>. </li>
  <li> <strong>!<em>processor</em></strong>: registers
 <tt>execlineb -Pc <em>processor</em></tt> as a processor for the next logdirs;
 <tt>execlineb</tt> must be found in s6-log's PATH. This directive is only
diff --git a/doc/s6-svc.html b/doc/s6-svc.html
index 62e93f9..b8d3c4d 100644
--- a/doc/s6-svc.html
+++ b/doc/s6-svc.html
@@ -28,7 +28,7 @@ knowing their PIDs, and without using horrible hacks such as .pid files.
 <h2> Interface </h2>
 
 <pre>
-     s6-svc [ -wu | -wU | -wd | -wD | -wr | -wR ] [ -T <em>timeout</em> ] [ -abqhkti12pcyoduxOr ] <em>servicedir</em>
+     s6-svc [ -wu | -wU | -wd | -wD | -wr | -wR ] [ -T <em>timeout</em> ] [ -abqhkti12pcyoduDUxOr ] <em>servicedir</em>
 </pre>
 
 <p>
@@ -59,8 +59,13 @@ a SIGTERM (by default) then a SIGCONT (to make sure even stopped processes
 receive the signal aimed to kill them) and do not restart it.
 The SIGTERM default can be changed by editing the <tt>./down-signal</tt>
 file in the <a href="servicedir.html">service directory</a>. </li>
+ <li> <tt>-D</tt>&nbsp;: down, and create a <tt>./down</tt> file so the
+service does not restart automatically if the supervisor dies. </li>
  <li> <tt>-u</tt>&nbsp;: up. If the supervised process is down, start it.
 Automatically restart it when it dies. </li>
+ <li> <tt>-U</tt>&nbsp;: up, and remove any <tt>./down</tt> file that may
+exist, in order to make sure the service is automatically restarted even
+if the supervisor dies. </li>
  <li> <tt>-x</tt>&nbsp;: exit. When the service is asked to be down and
 the supervised process dies, s6-supervise will exit too. This command should
 normally never be used on a working system. Note that if this command is
diff --git a/doc/s6-usertree-maker.html b/doc/s6-usertree-maker.html
index b62727a..29175d6 100644
--- a/doc/s6-usertree-maker.html
+++ b/doc/s6-usertree-maker.html
@@ -21,7 +21,7 @@
 <p>
 s6-usertree-maker creates a <a href="servicedir.html">service directory</a>
 implementing a service that runs an <a href="s6-svscan.html">s6-svscan</a>
-instance owned by a given user, on a <a href="scandir.html">scan directory</a>
+process owned by a given user, on a <a href="scandir.html">scan directory</a>
 belonging to that user. It is meant to help admins deploy systems where
 each user has their own supervision subtree, rooted in the main supervision
 tree owned by root.
@@ -45,6 +45,7 @@ for the <a href="//skarnet.org/software/s6-rc/">s6-rc</a> service manager.
        [ -n <em>nfiles</em> ] \
        [ -s <em>filesize</em> ] \
        [ -S <em>maxsize</em> ] \
+       [ -P <em>prefix</em> ] \
        user logdir dir
 </pre>
 
@@ -123,6 +124,9 @@ file (and archive files) in <em>logdir</em>. Default is <strong><tt>1000000</tt>
 archives in the <em>logdir</em>. Default is <strong><tt>0</tt></strong>,
 meaning no limits apart from those enforced by the <tt>-n</tt> and
 <tt>-s</tt> options. </li> <br />
+
+  <li> <tt>-P</tt>&nbsp;<em>prefix</em>&nbsp;: when logging to <em>logdir</em>,
+prefix logged lines with the <em>prefix</em> string. </li> <br />
 </ul>
 
 <h2> Operation of the service </h2>
diff --git a/doc/servicedir.html b/doc/servicedir.html
index 4ae06c2..89a272d 100644
--- a/doc/servicedir.html
+++ b/doc/servicedir.html
@@ -209,6 +209,13 @@ created by <a href="s6-supervise.html">s6-supervise</a> if it does not exist.
 is the rendez-vous point for listeners, where <a href="s6-supervise.html">s6-supervise</a>
 will send notifications when the service goes up or down. </li>
 
+ <li style="margin-bottom:1em"> Optional directories named <tt>instance<tt>
+and <tt>instances</tt>. Those are internal subdirectories created by
+<a href="s6-instance-maker.html">s6-instance maker</a> in a templated service
+directory. Outside of instanced services, these directories should never
+appear, and you should never create them manually. </li>
+
+
  <li style="margin-bottom:1em"> An optional service directory named <tt>log</tt>. If it exists and <em>foo</em>
 is in a <a href="scandir.html">scandir</a>, and <a href="s6-svscan.html">s6-svscan</a>
 runs on that scandir, then <em>two</em> services are monitored: <em>foo</em> and