From a491c627e09aa1149196dd40cb377d181db0580a Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Tue, 7 Jul 2015 14:39:16 +0000 Subject: - Minor fixes to s6-rc - More doc --- doc/s6-rc-db.html | 151 +++++++++++++++++++++++--- doc/s6-rc-init.html | 168 ++++++++--------------------- doc/s6-rc.html | 304 +++++++++++++++++++++++++++++++++++++++------------- src/s6-rc/s6-rc.c | 19 ++-- 4 files changed, 417 insertions(+), 225 deletions(-) diff --git a/doc/s6-rc-db.html b/doc/s6-rc-db.html index 9a1cf3b..280f98a 100644 --- a/doc/s6-rc-db.html +++ b/doc/s6-rc-db.html @@ -94,41 +94,158 @@ it finds a problem, such as a mismatch in the direct and reverse dependency tables, or a dependency cycle.

+

s6-rc-db list

-

Usage examples

+

+ Lists all services of a given type. This subcommand takes a second subcommand: +

+ +

s6-rc-db list all

+ +

+ Lists everything - atomic services and bundles - contained in the database. +

+ +

s6-rc-db list services

+ +

+ Lists all atomic services. +

+ +

s6-rc-db list oneshots

+ +

+ Lists oneshots. +

+ +

s6-rc-db list longruns

+ +

+ Lists longruns. +

+ +

s6-rc-db list bundles

+ +

+ Lists all bundles. +

+ +

s6-rc-db type servicename

+ +

+ Prints the type of servicename: oneshot, longrun +or bundle. Exits 1 if +servicename is not a valid identifier in the database. +

+ +

s6-rc-db timeout atomicname

+ +

+ Prints the timeout value, in milliseconds, after which bringing +atomicname up or down is considered a failure if the +called script still has not succeeded. Exits 1 if atomicname +isn't a valid atomic service. By default, or if the -u +option has been given to s6-rc-db, the timeout for up is +printed; the timeout for down is printed instead if the +-d option has been given. +

+ +

s6-rc-db contents bundlename

+ +

+ Lists the atomic services represented by bundle bundlename. +Exits 1 if bundlename is not a valid bundle. +

+ +

s6-rc-db dependencies servicename

+ +

+ Prints the list of direct dependencies for servicename. +Exits 1 if servicename isn't a valid identifier. If +servicename is a bundle, its set of direct dependencies +is the union of the direct dependencies of all the atomic services +contained in the bundle. +

+ +

+ If the -d option has been given to s6-rc-db, the +reverse dependencies are given instead: services that directly +depend on servicename, or on one of its components if it +is a bundle. +

+ +

s6-rc-db servicedir longrunname

-
 s6-rc myservicebundle 

- Brings up all the services represented by myservicebundle, -dependencies first. + Prints the service directory for longrun service longrunname; +this value is relative to the scandir. Exits 1 if +longrunname is not a valid longrun.

-
 s6-rc -Sad 
+

s6-rc-db script oneshotname

+ +

+ Prints the up script for oneshotname, which is +an argv, i.e. a Unix command line. Each component of this +command line is +terminated by a null character, so to print it in +a human-readable format, pipe the output into something like +xargs -0 echo. The command exits 1 if oneshotname +is not a valid oneshot. +

+ +

+ If the -d option has been given to s6-rc-db, the +down script is printed instead. +

+ +

s6-rc-db flags atomicname

+

- Brings down all the services in an orderly manner. This is typically -run at shutdown time. + Prints a hexadecimal number that is the list of all binary flags +for atomic service atomicname. Exits 1 if atomicname +is not a valid atomic service.

-
 s6-rc -Au myservicebundle 

- Prints the names of all atomic services represented by -myservicebundle, as well as everything they depend on. + Those binary flags are currently unused, but this may change in a +future version of s6-rc.

-
 s6-rc -Ad myservicebundle 
+

s6-rc-db atomics servicename...

+

- Prints the names of all atomic services represented by -myservicebundle, as well as everything that depends on them. + Prints the fully resolved list of services represented by the +servicename... arguments, i.e. the union of all +atomic services contained in servicename.... Each +argument in servicename... can be an atomic service or +a bundle. If an argument isn't a valid identifier, the command +exits 1.

-
 s6-rc -pun0 myservicebundle 
+

s6-rc-db all-dependencies servicename...

+

- Prints what s6-rc would do to bring the state to just -myservicebundle and its dependencies. + Prints the list of all atomic services needed to bring up +all of the servicename... arguments, with all their +dependencies, recursively. In other words: for +servicename... to be up, every single service listed +in the output will need to be up. The output includes the +atomic services represented by the +servicename... arguments themselves. If one of those +arguments isn't a valid identifier, the command exits 1.

+

+ The list is not topologically sorted. +

-

Internals

+

+ If the -d option has been given to s6-rc-db, the +recursive list of reverse dependencies is printed: for +servicename... to be down, every single service listed +in the output will need to be down. +

diff --git a/doc/s6-rc-init.html b/doc/s6-rc-init.html index 143a0f4..f2bd8e1 100644 --- a/doc/s6-rc-init.html +++ b/doc/s6-rc-init.html @@ -20,149 +20,75 @@

s6-rc-init is an initialization tool for the s6-rc -system. It must be run at boot time, prior to any +system. It must be run as root, at boot time, prior to any invocation of the s6-rc binary.

-

Requirements

- -

Interface

-     s6-rc-init [ -v verbosity ] [ servicenames... ]
+     s6-rc-init [ -c compiled ] [ -l live ] [ -t timeout ] scandir
 
+
  • compiled, live and scandir must be +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 +s6-svscan +is running on scandir.
  • +
  • s6-rc-init initializes the live state in live. It +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 +s6-svscan, +which will pick up the new service directories and start +http://skarnet.org/software/s6/s6-supervise.html">s6-supervise +processes on them - but the service themselves will not be started +right away, because of the down files.
  • +
  • s6-rc-init waits for all s6-supervise processes to be +operational, then exits 0.
  • Options

    -

    s6-rc control

    - - - -

    Up or down

    - -

    Service selection

    - - +

    Typical usage

    -

    Actions

    - - - -

    Usage examples

    - -
     s6-rc myservicebundle 

    - Brings up all the services represented by myservicebundle, -dependencies first. + Administrators should invoke s6-rc-init once, in their +early boot scripts, after s6-svscan is functional but before any +other initialization. (The rest of the initialization can be +written as a set of s6-rc services, and performed by just one +invocation of the s6-rc change command.)

    -
     s6-rc -Sad 

    - Brings down all the services in an orderly manner. This is typically -run at shutdown time. + For instance, when using an init created by +s6-linux-init, +s6-rc-init should be the first command in the +stage2 (by default /etc/rc.init) script.

    -
     s6-rc -Au myservicebundle 
    -

    - Prints the names of all atomic services represented by -myservicebundle, as well as everything they depend on. -

    - -
     s6-rc -Ad myservicebundle 
    -

    - Prints the names of all atomic services represented by -myservicebundle, as well as everything that depends on them. -

    - -
     s6-rc -pun0 myservicebundle 
    -

    - Prints what s6-rc would do to bring the state to just -myservicebundle and its dependencies. -

    - - -

    Internals

    - diff --git a/doc/s6-rc.html b/doc/s6-rc.html index 34dfc59..ff18362 100644 --- a/doc/s6-rc.html +++ b/doc/s6-rc.html @@ -19,46 +19,85 @@

    The s6-rc program

    - s6-rc is a machine state manager: it brings the machine to a -desired state, by starting or stopping services as needed. + s6-rc is a service manager, a.k.a machine state manager: +a program to manage the live state of a machine - +what services are currently up and what services are currently down. It +can list active services, or change the live state. +

    + +

    + s6-rc is meant to be the one-stop shop of service management: once +service definitions have been made into a compiled service database +via s6-rc-compile, and the machine +state has been initialized via s6-rc-init, +any state change - be it initial startup, shutdown, or anything else - +should be achieved by a single s6-rc change invocation. +

    + +

    + s6-rc should only be run as root, especially when asking for a state +change.

    Interface

    -     s6-rc [ -v verbosity ] [ servicenames... ]
    +     s6-rc help
    +     s6-rc [ -l live ] [ -a ] list servicenames...
    +     s6-rc [ -l live ] [ -a ] [ -u | -d ] listall servicenames...
    +     s6-rc [ -l live ] [ -a ] [ -u | -d ] [ -p ] [ -v verbosity ] [ -n dryrunthrottle ] [ -t timeout ] change [ servicenames... ]
     
    +

    Service selection

    + +

    +The arguments servicenames... may be atomic services or +bundles; they are resolved into a set of atomic services, which is +called the selection. If the -a option is present, +the current set of up services is added to the selection. +The s6-rc command operates on the selection. +

    +

    Options

    -

    s6-rc control

    +

    General options

    + + + +

    Up or down

    + +

    + These options control what is to be done: bring selected services +up or down (for s6-rc change) or whether to use the +forward or reverse dependency graph (for s6-rc listall). +Default is up. +

    + + + +

    s6-rc change control

    -

    Up or down

    +

    Subcommands

    + +

    s6-rc help

    + +

    + Prints a short help message. +

    + +

    s6-rc list servicenames...

    + +

    + Prints the selection. +

    + +

    + This is mostly useful as s6-rc -a list, which simply prints +the list of currently active services. +

    + +

    s6-rc listall servicenames...

    -

    Service selection

    +

    s6-rc change

    + +

    + s6-rc change is the service state engine. It will bring the +machine to a state where: +

    -

    Actions

    +

    + To do so: +

    +

    Longrun transitions

    + +

    + Transitions for longrun services are simple: s6-rc removes or create +a down file, then sends a command +to the supervision tree to start or stop the service. (A service that +is considered down by s6-rc will have a down file in its live service +directory; a service that is considered up by s6-rc will not.) The +transition is considered successful as soon as the daemon dies (for +down transitions), or becomes up and +ready +(for up transitions). If a longrun service does not support +readiness notification, the +s6-svc +command that is invoked by s6-rc will print a warning message, and +the transition will be considered successful as soon as the daemon +is up. +

    + +

    + Transitions are supposed to be idempotent, but it is a general +rule of supervision that run and finish scripts +must be idempotent, so a properly designed service directory +should work with s6-rc with no additional effort. +

    + +

    Oneshot transitions

    + +

    + Transitions for oneshot services involve running the up +or down script for the service; those scripts are stored +in the compiled service database that is linked from the live state. +The transition is considered successful if the script exits zero, +and unsuccessful otherwise. +

    + +

    + s6-rc performs some black magic so that up and down +scripts are always run in a reproducible way, no matter when or how +s6-rc change is invoked. That black magic involves a special +longrun service, s6rc-oneshot-runner, that every oneshot +service automatically depends on, and that is actually used to fork +the up or down scripts as scions of the s6 supervision +tree, instead of children of the s6-rc process. +

    + +

    + Transitions should be ideally transactional, or at the very least +idempotent. If a +transition fails, it should leave the machine in the same state as +before the transition was attempted; at the very least, it should not +prevent a subsequent run of the same transition from completing +successfully. If an s6-rc change invocation fails because +some transition experienced a temporary failure, it should be possible +to run the exact same s6-rc change invocation later, and be +met with success. +

    + +

    + This is important: it means that oneshot scripts should be treated +as atoms, and that some care should be taken when writing them. +

    + +

    Dry runs

    + +

    + For any manual change, is it recommended to perform a dry run before +the state change itself: add the -n dryrunthrottle +option to the s6-rc command line. s6-rc will then simulate all the +transitions, but not actually perform them or change the real live +state. + The command lines that s6-rc would have run will be printed to stdout +instead, and +each simulated transition will take dryrunthrottle +milliseconds to complete successfully. +

    +

    Usage examples

    -
     s6-rc myservicebundle 
    +
     s6-rc change myservicebundle 

    Brings up all the services represented by myservicebundle, -dependencies first. +bringing up all its dependencies first (recursively).

    -
     s6-rc -Sad 
    +
     s6-rc -ad change 

    - Brings down all the services in an orderly manner. This is typically -run at shutdown time. + Brings down all the currently running services in an orderly manner. +This is typically run at shutdown time.

    -
     s6-rc -Au myservicebundle 
    +
     s6-rc -l /zork -ua listall myservicebundle 

    Prints the names of all atomic services represented by -myservicebundle, as well as everything they depend on. +myservicebundle plus the current live services, as well as +everything they depend on, recursively. Assumes the live state is +stored in the /zork directory instead of /run/s6-rc.

    -
     s6-rc -Ad myservicebundle 
    +
     s6-rc -d listall myservicebundle 

    Prints the names of all atomic services represented by myservicebundle, as well as everything that depends on them. @@ -152,12 +305,11 @@ run at shutdown time.

     s6-rc -pun0 myservicebundle 

    - Prints what s6-rc would do to bring the state to just -myservicebundle and its dependencies. + Prints what s6-rc would do to bring the state to exactly +the contents of myservicebundle as well as its recursive +dependencies, and pruning all the rest. Do not wait any extra time +between simulated transitions.

    - -

    Internals

    - diff --git a/src/s6-rc/s6-rc.c b/src/s6-rc/s6-rc.c index eb01789..377a7d4 100644 --- a/src/s6-rc/s6-rc.c +++ b/src/s6-rc/s6-rc.c @@ -67,6 +67,8 @@ static void print_services (void) buffer_puts(buffer_1, db->string + db->services[i].name) ; buffer_put(buffer_1, "\n", 1) ; } + if (!buffer_flush(buffer_1)) + strerr_diefu1sys(111, "write to stdout") ; } static pid_t start_oneshot (unsigned int i, int h) @@ -111,7 +113,7 @@ static pid_t start_longrun (unsigned int i, int h) char fmt[UINT32_FMT] ; char vfmt[UINT_FMT] ; char servicefn[livelen + svdlen + 19] ; - char const *newargv[11 + !!dryrun[0] * 6] ; + char const *newargv[7 + !!dryrun[0] * 6] ; byte_copy(servicefn, livelen, live) ; byte_copy(servicefn + livelen, 13, "/servicedirs/") ; byte_copy(servicefn + livelen + 13, svdlen, db->string + db->services[i].x.longrun.servicedir) ; @@ -127,16 +129,12 @@ static pid_t start_longrun (unsigned int i, int h) newargv[m++] = dryrun ; newargv[m++] = "--" ; } - newargv[m++] = S6_EXTBINPREFIX "s6-svlisten1" ; - newargv[m++] = h ? "-U" : "-d" ; + newargv[m++] = S6_EXTBINPREFIX "s6-svc" ; + newargv[m++] = h ? "-Uu" : "-Dd" ; newargv[m++] = "-t" ; newargv[m++] = fmt ; newargv[m++] = "--" ; newargv[m++] = servicefn ; - newargv[m++] = S6_EXTBINPREFIX "s6-svc" ; - newargv[m++] = h ? "-u" : "-d" ; - newargv[m++] = "--" ; - newargv[m++] = servicefn ; newargv[m++] = 0 ; if (!dryrun[0]) @@ -292,7 +290,6 @@ static int doit (int spfd, int h) for (;;) { register int r ; - buffer_flush(buffer_1) ; if (!npids) break ; r = iopause_g(&x, 1, &deadline) ; if (r < 0) strerr_diefu1sys(111, "iopause") ; @@ -334,9 +331,9 @@ static inline void print_help (void) { static char const *help = "s6-rc help\n" -"s6-rc [ -l live ] [ -u | -d ] [ -a ] list [ servicenames... ]\n" -"s6-rc [ -l live ] [ -u | -d ] [ -a ] listall [ servicenames... ]\n" -"s6-rc [ -l live ] [ -u | -d ] [ -a ] [ -p ] [ -v verbosity ] [ -t timeout ] [ -n dryrunthrottle ] change [ servicenames... ]\n" ; +"s6-rc [ -l live ] [ -a ] list [ servicenames... ]\n" +"s6-rc [ -l live ] [ -a ] [ -u | -d ] listall [ servicenames... ]\n" +"s6-rc [ -l live ] [ -a ] [ -u | -d ] [ -p ] [ -v verbosity ] [ -t timeout ] [ -n dryrunthrottle ] change [ servicenames... ]\n" ; if (buffer_putsflush(buffer_1, help) < 0) strerr_diefu1sys(111, "write to stdout") ; } -- cgit v1.2.3