From 047befef9b8ef074d34b05e294d753f6c2751987 Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Wed, 23 Sep 2015 19:13:22 +0000 Subject: No need for -a in s6-rc -u invocation; remove -X from dryrun print --- doc/faq.html | 129 +++++++++++++++++++++++++++++++++++++++------ doc/index.html | 5 ++ doc/overview.html | 7 +-- doc/s6-rc-bundle.html | 4 +- doc/s6-rc-compile.html | 25 +++++---- doc/s6-rc-dryrun.html | 3 +- doc/s6-rc-init.html | 24 +++++++-- doc/s6-rc-oneshot-run.html | 4 +- doc/s6-rc-update.html | 26 +++++---- doc/s6-rc.html | 21 +++----- doc/why.html | 42 +++++++++------ src/s6-rc/s6-rc-update.c | 10 ++-- 12 files changed, 215 insertions(+), 85 deletions(-) diff --git a/doc/faq.html b/doc/faq.html index 692c7f7..608c5e2 100644 --- a/doc/faq.html +++ b/doc/faq.html @@ -16,13 +16,62 @@ skarnet.org

-

s6-rc: FAQ

+

s6-rc: Frequently Asked Questions

+ +

Quick recipes

+ +

How do I...

+ +

list every active service ?

+ +
s6-rc -a list 
+ +

list every service in the current live database, active or not ?

+ +
s6-rc -d list 
+

or

+
s6-rc-db list services
+ +

bring up service foo ?

+ +
s6-rc -u change foo
+ +

bring down everything ?

+ +
s6-rc -da change
+ +

print the "up" script for oneshot service foo ?

+ +
s6-rc-db -u script foo | xargs -0 printf "%s "
+ +

see what pipeline longrun service foo is a part of ?

+ +
s6-rc-db pipeline foo
+ +

see the list of all services that depend on foo, +directly or indirectly ?

+ +
s6-rc-db -d all-dependencies foo
+ +

see what services will restart if I update my live service database to +newcompiled ?

+ +
s6-rc-update -n newcompiled
+ +

+ The first line is the s6-rc invocation that +will bring the old services down. The services that will stop are listed +after -- change. + The second line is the s6-rc invocation that +will bring the new services up. The services that will start are listed +after -- change. +

The s6-rc-compile source format

The source format for s6-rc-compile is not very convenient. -Why not put all the information for a service in a single file?

+Why not put all the information for a service in a single file ?

Because parsing sucks. Writing parsers is an annoying, ungrateful task, @@ -37,16 +86,17 @@ file.

Using the filesystem as a key-value store is a good technique to avoid parsing, and skarnet.org packages do it -everywhere: for instance, look at -s6-envdir. +everywhere: for instance, +s6-envdir +uses the file name as a key and the file contents as a value. The s6-rc-compile source format is just another instance of this technique.

- This format generally plays well with automated tools, be it for + The source format generally plays well with automated tools, be it for reading, as s6-rc-compile does, as for writing. -I fully expect the s6-rc-compile source format +I fully expect it to be used as the input (resp. the output) of some automated tools that would convert service definitions to (resp. from) another format, such as systemd @@ -55,17 +105,19 @@ s6-rc source format will make it easy on those tools.

- And if you love configuration files, don't mind writing a parser (which is + And if you love configuration files, are ok with writing a parser (which is indubitably easier to do in other languages than C), and want to write a program that takes a text file, parses it and outputs a service -definition directory, it should also be rather easy. +definition directory in the s6-rc-compile source format, it should also be +rather easy - please, feel free!

There are no "Provides:", no virtual services. What do I do -if I have several implementations for a service?

+if I have several implementations for a service ?

- Use bundles. Bundles are awesome. + Use bundles. Bundles are the solution to most of the questions in +the same vein.

@@ -84,7 +136,7 @@ will resolve to opensshd, and the compiled service database will consider opensshd to be the "real" service; but users will still be able to run s6-rc commands involving sshd. -And if users want to change the default to dropbear, just +And if you want to change the default to dropbear, just change the sshd/contents file to dropbear, recompile the database, and run s6-rc-update. @@ -113,7 +165,7 @@ one of them.

I have a collection of init scripts in another format, but don't want to wait until the whole collection is converted -before switching to s6-rc. Is there a smooth way in?

+before switching to s6-rc. Is there a smooth way in ?

Yes. @@ -163,7 +215,7 @@ you fix it.

There are no runlevels in s6-rc. I like runlevels.

- You have better than runlevels. You have bundles. + You have better than runlevels. You have bundles.

@@ -209,11 +261,57 @@ for. When in doubt, use bundles.

+

There are no intermediate states in s6-rc. There's just "up" +and "down", no "starting", no "failed", etc. Why ?

+ +

+ Because those intermediate states are unnecessary. +

+ +

+ From the machine's point of view, things are simple: a service is +either up or it's not. If a service fails to start, then it's still +down. Note that it is recommended to write atomic oneshots +for this very reason. +

+ +

+ Service managers that use intermediate states do so in order to keep +track of what they're doing and what they have done. But this +introduces needless complexity: the reality is that the service is +either up or down, it's either in the state you wanted it to be or +not. A model should not be more complex than the reality. +

+ +

+ s6-rc does not keep track of "failed" states: a service that fails +to start simply remains down, and +s6-rc exits 1 to report that something +went wrong. To know what services failed to start, compare the +result of s6-rc -a list against your expected machine state. +

+ +

+ The reason for this design is simple: if the +s6-rc process is killed in the middle of a transition +while a service state is "starting", what should the next invocation do? +This is unclear, and the intermediate state introduces ambiguity where +there should not be. Also, +if there is a "failed" service, what should the next invocation do? Try +and restart it, or not? This depends on what the user wants; this is +policy, not mechanism. Simply reporting the error while keeping the +state as "down" allows users to apply their chosen policies - see below. +

+ +

+ Keep it simple, stupid. +

+

Mechanism vs. policy

s6-rc feels bare: there are tools, but no wrappers, no pre-packaged scripts to boot my machines, no default runlevels. By comparison, OpenRC -provides a complete default set of scripts!

+provides a complete default set of scripts !

In the world of software development, it is important to distinguish @@ -248,7 +346,8 @@ distributors' job! for a Linux distribution, so with that in mind, the OpenRC developers did not have to think much about separating mechanism from policy. It works very well for Gentoo and Gentoo-derived distributions; but it -requires more work to use OpenRC outside of that frame. +requires adaptation and more work for the admin to use OpenRC outside of +that frame.

diff --git a/doc/index.html b/doc/index.html index 58e60e3..ecb1fe4 100644 --- a/doc/index.html +++ b/doc/index.html @@ -107,6 +107,11 @@ the previous versions of s6-rc and the current one.
  • The s6-rc-init program
  • The s6-rc program
  • The s6-rc-update program
  • + + +

    Programs used internally

    + + diff --git a/doc/overview.html b/doc/overview.html index 0d8dce0..4209f42 100644 --- a/doc/overview.html +++ b/doc/overview.html @@ -116,7 +116,7 @@ the actual state of the machine. @@ -124,7 +124,7 @@ deleted from the database.
  • One argument that is the name of the bundle to add
  • One block listing the services contained in the new bundle. The names in the block are resolved before any addition -is made to the database.
  • +or deletion is made to the database. diff --git a/doc/s6-rc-compile.html b/doc/s6-rc-compile.html index 8e4b279..51396b3 100644 --- a/doc/s6-rc-compile.html +++ b/doc/s6-rc-compile.html @@ -90,8 +90,9 @@ to operate the database. If neither option is used, then root It is important to only use the -u or -g options when the user owning the supervision tree is not root. The internal s6-rc mechanisms allow uids and gids specified by those -options to run any program as the user owning the supervision tree; -if that user is root, this becomes an easy avenue for unwanted +options to run any oneshot in the compiled service database as the +user owning the supervision tree; +if that user is root, this becomes an avenue for unwanted privilege gain. Only specify users that have the right to operate the supervision tree!

    @@ -201,7 +202,8 @@ compiled database in an internal form. up will be run when the service is started, and down will be executed when the service is stopped. up is mandatory, but down is optional; if no down file is provided in the source definition directory, -then s6-rc will consider that the down transition for this service +then it is treated as the empty script. If a script is empty, +then s6-rc will consider that the corresponding transition for this service does nothing and always succeeds. @@ -302,10 +304,14 @@ use relative paths, not absolute ones.

    - Note that you cannot create a down file in a generated service + Note that you cannot create a ./down file for +s6-supervise +in a generated service directory. Even if such a file exists in the definition directory, it will -be ignored. This is intentional: -s6-rc internally uses down files to mark longrun +be ignored - it will not be replicated in the service directory. +This is intentional: +s6-rc internally uses ./down files in +the service directories it manages, to mark longrun services that are down.

    @@ -338,9 +344,7 @@ indefinite number of longrun services this way.
  • The first producer may declare a name for the whole pipeline, in its pipeline-name file. If it does so, then a bundle is automatically created with -the given name, and it contains all the services in the pipeline (plus the -automatically generated supporting services that open and store the -pipes).
  • +the given name, and it contains all the services in the pipeline.

    @@ -357,7 +361,8 @@ detect and reject cycles as well as collisions.

    - The pipe linking a producer and a consumer is created and stored at run-time in a + The pipe linking a producer with a consumer is created and stored at +run-time in a s6-fdholder-daemon instance managed by an automatically generated longrun service named s6rc-fdholder. diff --git a/doc/s6-rc-dryrun.html b/doc/s6-rc-dryrun.html index 0a55fa6..ee23d3b 100644 --- a/doc/s6-rc-dryrun.html +++ b/doc/s6-rc-dryrun.html @@ -57,7 +57,8 @@ is 0, s6-rc-dryrun will not print anything to stdout. Default is 1. milliseconds before exiting. Default is 1000, but when invoked by s6-rc, it will be the value of the dryruntimeout argument to the -n option. This is -used to simulate a non-immediate startup or shutdown script. +used to simulate a start or stop script that does not complete +immediately. diff --git a/doc/s6-rc-init.html b/doc/s6-rc-init.html index 3334525..e5ae884 100644 --- a/doc/s6-rc-init.html +++ b/doc/s6-rc-init.html @@ -36,7 +36,7 @@ invocation of the absolute paths.

  • s6-rc-init expects to find a compiled service database in compiled. It expects to be able to create a directory -at live. It also expects that an instance of +named live. It also expects that an instance of s6-svscan is running on scandir.
  • s6-rc-init initializes the live state in live. It @@ -44,13 +44,13 @@ declares compiled as the current service database and sets the state as "all services down".
  • It then copies verbatim all the service directories declared by compiled into a -subdirectory of live, adds down files to the live copies -and links them into scandir. It then triggers +subdirectory of live, adds ./down files to the live copies +and links those live copies into scandir. It then triggers s6-svscan, which will pick up the new service directories and start s6-supervise processes on them - but the service themselves will not be started -right away, because of the down files.
  • +right away, because of the ./down files.
  • s6-rc-init waits for all s6-supervise processes to be operational, then exits 0.
  • @@ -95,5 +95,21 @@ invocation of the s6-rc change command.) stage2 (by default /etc/rc.init) script.

    +

    Notes

    + + + diff --git a/doc/s6-rc-oneshot-run.html b/doc/s6-rc-oneshot-run.html index c2b422f..351e9e1 100644 --- a/doc/s6-rc-oneshot-run.html +++ b/doc/s6-rc-oneshot-run.html @@ -37,8 +37,8 @@ in internal scripts created by diff --git a/doc/s6-rc-update.html b/doc/s6-rc-update.html index 1e56ba2..e9ab43c 100644 --- a/doc/s6-rc-update.html +++ b/doc/s6-rc-update.html @@ -43,7 +43,8 @@ situations it cannot solve.

    - Pages and pages could be written about the shortcomings of integrated -init systems; one fact remains - they are not a satisfying solution + Pages and pages could be - and have been - written about the shortcomings +of integrated +init systems, but one fact remains: they are not a satisfying solution to the problem of service management under Unix.

    diff --git a/src/s6-rc/s6-rc-update.c b/src/s6-rc/s6-rc-update.c index 6704e93..66c956f 100644 --- a/src/s6-rc/s6-rc-update.c +++ b/src/s6-rc/s6-rc-update.c @@ -753,7 +753,7 @@ int main (int argc, char const *const *argv, char const *const *envp) /* Down transition */ { - char const *newargv[11 + (dryrun * 5) + want_count(oldstate, oldn)] ; + char const *newargv[12 + (dryrun * 4) + want_count(oldstate, oldn)] ; unsigned int m = 0, i = oldn ; int wstat ; char vfmt[UINT_FMT] ; @@ -775,7 +775,8 @@ int main (int argc, char const *const *argv, char const *const *envp) newargv[m++] = tfmt ; newargv[m++] = "-l" ; newargv[m++] = live ; - newargv[m++] = "-Xd" ; + if (!dryrun) newargv[m++] = "-X" ; + newargv[m++] = "-d" ; newargv[m++] = "--" ; newargv[m++] = "change" ; while (i--) if (oldstate[i] & 2) @@ -818,7 +819,7 @@ int main (int argc, char const *const *argv, char const *const *envp) /* Up transition */ { - char const *newargv[11 + (dryrun * 5) + want_count(newstate, newn)] ; + char const *newargv[12 + (dryrun * 4) + want_count(newstate, newn)] ; unsigned int m = 0, i = newn ; char vfmt[UINT_FMT] ; char tfmt[UINT_FMT] ; @@ -839,7 +840,8 @@ int main (int argc, char const *const *argv, char const *const *envp) newargv[m++] = tfmt ; newargv[m++] = "-l" ; newargv[m++] = live ; - newargv[m++] = "-Xua" ; + if (!dryrun) newargv[m++] = "-X" ; + newargv[m++] = "-u" ; newargv[m++] = "--" ; newargv[m++] = "change" ; while (i--) if (newstate[i] & 2) -- cgit v1.2.3