aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/s6_repository.html6
-rw-r--r--doc/s6_set.html347
-rw-r--r--src/s6-frontend/live.help.txt6
-rw-r--r--src/s6-frontend/repository_check.c2
-rw-r--r--src/s6-frontend/s6-frontend-internal.h1
-rw-r--r--src/s6-frontend/set.c1
-rw-r--r--src/s6-frontend/set.help.txt2
-rw-r--r--src/s6-frontend/set_change.c8
-rw-r--r--src/s6-frontend/set_check.c2
-rw-r--r--src/s6-frontend/set_list.c25
-rw-r--r--src/s6-frontend/set_status.c9
11 files changed, 386 insertions, 23 deletions
diff --git a/doc/s6_repository.html b/doc/s6_repository.html
index 377344f..d992a1b 100644
--- a/doc/s6_repository.html
+++ b/doc/s6_repository.html
@@ -117,18 +117,18 @@ the current working set, which always exists. </li>
<h4> Interface </h4>
<pre>
- s6 repository check [ -f ] [ -d | -u ] [ -E | -e ]
+ s6 repository check [ -F ] [ -d | -u ] [ -E | -e ]
</pre>
<ul>
- <li> <tt>s6 repository check</tt> checks all the services in the set for
+ <li> <tt>s6 repository check</tt> checks all the sets in the repository for
inconsistencies, and prints anything it finds to stdout. </li>
</ul>
<h4> Options </h4>
<dl>
-<dt> -f, --fix </dt>
+<dt> -F, --fix </dt>
<dd> Also attempt to fix the inconsistencies. </dd>
<dt> -E, --no-force-essential </dt>
diff --git a/doc/s6_set.html b/doc/s6_set.html
new file mode 100644
index 0000000..83cf9f7
--- /dev/null
+++ b/doc/s6_set.html
@@ -0,0 +1,347 @@
+<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-frontend: the s6 set command</title>
+ <meta name="Description" content="s6-frontend: the s6 set command" />
+ <meta name="Keywords" content="s6 ecosystem supervision service manager user interface init skarnet.org skarnet software repository repo working set load save s6-rc" />
+ <!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> -->
+ </head>
+<body>
+
+<p>
+<a href="s6.html">The s6 command</a><br />
+<a href="index.html">s6-frontend</a><br />
+<a href="//skarnet.org/software/">Software</a><br />
+<a href="//skarnet.org/">skarnet.org</a>
+</p>
+
+<h1> The <tt>s6 set</tt> command </h1>
+
+<p>
+ <tt>s6 set</tt> regroups actions on
+<a href="//skarnet.org/software/s6-rc/repodefs.html#set>service sets</a>,
+telling the service manager what service should be enabled or disabled
+at boot time, or even should be masked, i.e. should not even appear in
+the list of services available at next boot.
+</p>
+
+<p>
+ Unlike <tt>s6 live</tt>, which deals with starting and stopping services
+that are currently running, <tt>s6 set</tt> is an <em>offline</em> tool,
+setting services in a state that remains theoretical until the user
+<em>commits</em> to it and <em>installs</em> the set, making it live.
+</p>
+
+<p>
+ <tt>s6 set</tt> commands always operate on a "working set" of services,
+which is internally named <tt>current</tt>. It is not the set that is
+currently live; it is the set that is currently worked on.
+</p>
+
+<div id="interface">
+<h2> Interface </h2>
+</div>
+
+<pre>
+ s6 set <em>subcommand</em> [ <em>subcommand_options...</em> ] [ <em>args...</em> ]
+</pre>
+
+<div id="subcommands">
+<h2> Subcommands </h2>
+</div>
+
+<div id="help">
+<h3> help </h3>
+</div>
+
+<p>
+ <tt>s6 set help</tt> prints a short help message summarizing the options
+and usage of the <tt>s6 set</tt> command. It is not as detailed as this page.
+</p>
+
+<div id="save">
+<h3> save </h3>
+</div>
+
+<h4> Interface </h4>
+
+<pre>
+ s6 set save [ -f ] <em>name</em>
+</pre>
+
+<ul>
+ <li> <tt>s6 set save</tt> saves a copy of the current working set into a
+set named <em>name</em>. </li>
+ <li> <em>name</em> can be loaded by <a href="#load"><tt>s6 set load <em>name</em></a>. </li>
+</ul>
+
+<h4> Options </h4>
+
+<dl>
+<dt> -f, --force </dt>
+<dd> If a set named <em>name</em> already exists, overwrite it with a copy
+of the current working set. By default, the command exits with an error
+instead of overwriting. </dd>
+
+<div id="load">
+<h3> load </h3>
+</div>
+
+<h4> Interface </h4>
+
+<pre>
+ s6 set load <em>name</em>
+</pre>
+
+<ul>
+ <li> <tt>s6 set load</tt> replaces the current working set with the set stored
+as <em>name</em>. </li>
+ <li> No options are defined. </li>
+</ul>
+
+<div id="list">
+<h3> list </h3>
+</div>
+
+<h4> Interface </h4>
+
+<pre>
+ s6 set list [ -E | -e ]
+</pre>
+
+<ul>
+ <li> <tt>s6 set list</tt> lists all the services in the current set,
+printing their names on stdout, one per line.
+the current working set, which always exists. </li>
+</ul>
+
+<h4> Options </h4>
+
+<dl>
+<dt> -E, --with-essentials </dt>
+<dd> List all the services, including the essential ones. This is the
+default. </dd>
+
+<dt> -e, --without-essentials </dt>
+<dd> Do not list essential services. </dd>
+</dl>
+
+<div id="status">
+<h3> list </h3>
+</div>
+
+<h4> Interface </h4>
+
+<pre>
+ s6 set status [ -E | -e ] [ <em>names...</em> ]
+</pre>
+
+<ul>
+ <li> <tt>s6 set status</tt> lists the services named <em>names...</em>
+in the working set with their current
+<a href="//skarnet.org/software/s6-rc/repodefs.html#sub">sub</a>, i.e.
+the state that they should be in at boot time: masked, disabled (listed
+as <tt>usable</tt>), enabled (listed as <tt>active</tt>), or essential
+(listed as <tt>always</tt>).
+ <ul>
+ <li> <tt>masked</tt> means that the service will not even appear
+in the live service database, it will be entirely omitted. If a
+service depends on a masked service, it should be masked too, else
+the set is said to be <em>inconsistent</em>. </li>
+ <li> <tt>usable</tt> means that the service will be listed in the
+live service database, but will not be brought up by default at boot
+time. It can later be brought up manually via the
+<a href="s6_live.html#start"><tt>s6 live start</tt></a> command. </li>
+ <li> <tt>active</tt> means that the service will be brought up by
+default at boot time. It can later be brought down manually via the
+<a href="s6_live.html#stop"><tt>s6 live stop</tt></a> command. </li>
+ <li> <tt>always</tt> means that the service is considered essential:
+it will always be brought up at boot time, and it cannot be brought down
+without special options to force it down; it normally stays up until
+the machine is shut down. Essential services are marked as such in the
+stores, and should generally not be tampered with via <tt>s6 set</tt>
+commands. </li>
+ </ul> </li>
+ <li> The service name is normally followed by a slash (<tt>/</tt>)
+followed by the name of the sub the service is in. On a terminal,
+with util-linux support, every line is pretty-printed into columns
+instead. </li>
+ <li> If <em>names...</em> is empty, all the services in the set
+are printed, along with their subs. </li>
+</ul>
+
+<h4> Options </h4>
+
+<dl>
+<dt> -E, --with-essentials </dt>
+<dd> Prints all the listed services, including the essential ones. This is the
+default. </dd>
+
+<dt> -e, --without-essentials </dt>
+<dd> Do not print essential services. </dd>
+</dl>
+
+<div id="enable">
+<div id="disable">
+<div id="mask">
+<div id="unmask">
+<div id="make-essential">
+<h3> enable, disable, mask, unmask, make-essential </h3>
+</div></div></div></div></div>
+
+<h4> Interface </h4>
+
+<pre>
+ s6 set enable|disable|mask|unmask|make-essential [ -f ] [ -n ] [ -I fail|warn|pull ] [ <em>services...</em> ]
+</pre>
+
+<ul>
+ <li> These subcommands are build with the same model and do the same
+thing: they move the services listed in <em>services...</em> from their
+current subs to another.
+ <ul>
+ <li> <tt>mask</tt> masks the services. </li>
+ <li> <tt>unmask</tt> and <tt>disable</tt> put the services in the <tt>usable</tt> sub, i.e. unmasked and disabled. </li>
+ <li> <tt>enable</tt> enables the services. </li>
+ <li> <tt>make-essential</tt> enables the services and marks them as essential. This command should normally not
+be used: essential services are marked as such in the stores and should not be touched. The command exists for
+troubleshooting purposes. </li>
+ </ul> </li>
+ <li> Dependencies across services are computed, and the command will print a message if the change would
+make the set inconsistent. </li>
+</ul>
+
+<h4> Options </h4>
+
+<dl>
+<dt> -f, --ignore-dependencies </dt>
+<dd> Only change the services listed in <em>services</em>, don't compute dependencies </dd>
+
+<dt> -n, --dry-run </dt>
+<dd> Do not perform the change; only show what would be done and check whether the set
+would be made inconsistent. </dd>
+
+<dt> -I <em>what</tt>, --if-dependencies-found=<em>what</em> </dt>
+<dd> What to do when services have dependencies, or reverse dependencies, that are not
+listed in <em>services...</em>. <em>what</em> can be <tt>fail</tt>, <tt>warn</tt>,
+or <tt>pull</tt>.
+ <ul>
+ <li> <tt>fail</tt>: abort the operation with an error message. </li>
+ <li> <tt>warn</tt>: perform the operation with a warning message. The set might
+be inconsistent afterwards, that can be changed by manually changing the dependencies
+or by fixing the set (see below). </li>
+ <li> <tt>pull</tt>: pull the dependencies into the
+same sub as the listed service, so there is no inconsistency. For <tt>enable</tt>,
+service dependencies are made <em>active</em> as well. For <tt>disable</tt>, reverse
+dependencies are disabled as well. For <tt>mask</tt>, reverse dependencies are
+masked as well. </li>
+ </ul>
+</dl>
+
+<h4> Notes </h4>
+
+<p>
+ These subcommands are the bread and butter of the <tt>s6 set</tt> commands. They
+allow the user to tailor the boot sequence to their needs without touching the
+currently running database.
+</p>
+
+<div id="check">
+<h3> check </h3>
+</div>
+
+<h4> Interface </h4>
+
+<pre>
+ s6 set check [ -F ] [ -d | -u ] [ -E | -e ]
+</pre>
+
+<ul>
+ <li> <tt>s6 set check</tt> checks the current working set for
+inconsistencies, and prints anything it finds to stdout. </li>
+</ul>
+
+<h4> Options </h4>
+
+<dl>
+<dt> -F, --fix </dt>
+<dd> Also attempt to fix the inconsistencies. </dd>
+
+<dt> -E, --no-force-essential </dt>
+<dd> If fixing the set involves changing a service flagged as essential
+to a sub that is <em>not</em> <tt>always</tt>, or a service <em>not</em>
+flagged as essential to the <tt>always</tt> sub, print an error message
+and exit. This is the default. </dd>
+
+<dt> -e, --force-essential </dt>
+<dd> If fixing the set involves changing a service flagged as essential
+to a sub that is <em>not</em> <tt>always</tt>, or a service <em>not</em>
+flagged as essential to the <tt>always</tt> sub, perform the change
+and continue. This is normally not necessary with a list of stores
+providing consistent services. </dd>
+
+<dt> -d, --down </dt>
+<dd> Fix the set by disabling or masking services. If service <tt>A</tt>
+depends on service <tt>B</tt> and <tt>B</tt> is masked or disabled,
+change <tt>A</tt> to be masked or disabled as well. This is the
+default. </dd>
+
+<dt> -u, --up </dt>
+<dd> Fix the set by enabling or unmasking services. If service <tt>A</tt>
+depends on service <tt>B</tt> and <tt>A</tt> is unmasked or enabled,
+change <tt>B</tt> to be unmasked or enabled as well. </dd>
+</dl>
+
+<div id="commit">
+<h3> commit </h3>
+</div>
+
+<h4> Interface </h4>
+
+<pre>
+ s6 set commit [ -f ] [ -K ] [ -D <em>defaultbundle</em> [ -h <em>fdhuser</em> ]
+</pre>
+
+<ul>
+ <li> <tt>s6 set commit</tt>
+<a href="//skarnet.org/software/s6-rc/repodefs.html#commit">commits</a>
+the current set: it attempts to
+<a href="//skarnet.org/software/s6-rc/s6-rc-compile.html">compile</a> a
+service database out of the set. </li>
+ <li> This command must be run once all desired modifications have been
+done to the set and that its consistency has been ensured, for instance
+by a <a href="#check"><tt>s6 set check -F</tt></a> command. </li>
+ <li> Once the set has been committed, in order to actually be used, it must
+be installed via the <a href="s6_live.html#install"><tt>s6 live install</tt></a>
+command. </li>
+</ul>
+
+<h4> Options </h4>
+
+<dl>
+<dt> -f, --force </dt>
+<dd> Compile the database even if no change has been performed since the
+last time the set was committed. </dd>
+
+<dt> -K, --keep-old </dt>
+<dd> If an old compiled database exists for the set, do not delete it,
+but print its path to stdout. By default, the old database is deleted
+when the set is successfully committed. </dd>
+
+<dt> -D <em>defaultbundle</em>, --default-bundle=<em>defaultbundle</em> </dt>
+<dd> The name of the bundle that will hold all <tt>active</tt> and <tt>always</tt>
+services, and that will be started at boot time. There is generally no reason
+to change the default, which depends on the distribution and is probably called
+<tt>default</tt>. </dd>
+
+<dt> -h <em>fdhuser</em>, --fdholder-user=<em>fdhuser</em> </dt>
+<dd> Specify the fdholder user for the compiled database built from
+the set. This must be a user name defined in the <tt>/etc/passwd</tt>
+file or whatever user database the system uses. The default is <tt>root</tt>
+and that is fine. </dd>
+</dl>
+
+</body>
+</html>
diff --git a/src/s6-frontend/live.help.txt b/src/s6-frontend/live.help.txt
index acb383b..88d51ca 100644
--- a/src/s6-frontend/live.help.txt
+++ b/src/s6-frontend/live.help.txt
@@ -10,14 +10,16 @@ Subcommands:
start-everything start all the services enabled at boot
stop-everything stop all the non-essential services
-s6 live status options: none
+s6 live status options:
+ -e --without-essentials ignore essential services (default)
+ -E --with-essentials also list essential services
s6 live start, s6 live stop, s6 live restart, s6 live stop-everything options:
-n --dry-run only show what would be done, don't do it
-t TIMEOUT --timeout=TIMEOUT if not done after TIMEOUT milliseconds, abort
s6 live install options:
- -b --block wait rather than fail on contention
+ -b --block on contention, wait rather than fail
-K --keep-old keep the old db and write its path to stdout
-f FILE --conversion-file=FILE use a conversion file from current to new set
diff --git a/src/s6-frontend/repository_check.c b/src/s6-frontend/repository_check.c
index a0e7737..a2c2cb8 100644
--- a/src/s6-frontend/repository_check.c
+++ b/src/s6-frontend/repository_check.c
@@ -26,7 +26,7 @@ void repository_check (char const *const *argv)
{ .so = 'e', .lo = "force-essential", .clear = 0, .set = GOLB_FORCE_ESSENTIAL },
{ .so = 'd', .lo = "down", .clear = GOLB_FIXUP, .set = 0 },
{ .so = 'u', .lo = "up", .clear = 0, .set = GOLB_FIXUP },
- { .so = 'f', .lo = "fix", .clear = 0, .set = GOLB_FIX },
+ { .so = 'F', .lo = "fix", .clear = 0, .set = GOLB_FIX },
} ;
uint64_t wgolb = 0 ;
unsigned int m = 0 ;
diff --git a/src/s6-frontend/s6-frontend-internal.h b/src/s6-frontend/s6-frontend-internal.h
index fdacb2b..253303d 100644
--- a/src/s6-frontend/s6-frontend-internal.h
+++ b/src/s6-frontend/s6-frontend-internal.h
@@ -81,6 +81,7 @@ extern void set_mask (char const *const *) gccattr_noreturn ;
extern void set_unmask (char const *const *) gccattr_noreturn ;
extern void set_enable (char const *const *) gccattr_noreturn ;
extern void set_disable (char const *const *) gccattr_noreturn ;
+extern void set_make_essential (char const *const *) gccattr_noreturn ;
extern void set_check (char const *const *) gccattr_noreturn ;
extern void set_commit (char const *const *) gccattr_noreturn ;
diff --git a/src/s6-frontend/set.c b/src/s6-frontend/set.c
index 8774aa5..b013c35 100644
--- a/src/s6-frontend/set.c
+++ b/src/s6-frontend/set.c
@@ -30,6 +30,7 @@ void set (char const *const *argv)
{ .s = "help", .f = &set_help },
{ .s = "list", .f = &set_list },
{ .s = "load", .f = &set_load },
+ { .s = "make-essential", .f = &set_make_essential },
{ .s = "mask", .f = &set_mask },
{ .s = "save", .f = &set_save },
{ .s = "status", .f = &set_status },
diff --git a/src/s6-frontend/set.help.txt b/src/s6-frontend/set.help.txt
index e998852..20deb73 100644
--- a/src/s6-frontend/set.help.txt
+++ b/src/s6-frontend/set.help.txt
@@ -33,7 +33,7 @@ s6 set enable|disable|mask|unmask options:
s6 set check options:
-E --no-force-essential do not allow manual changes to essential services (default)
-e --force-essential allow manual changes to essential services
- -f --fix try to fix inconsistencies automatically
+ -F --fix try to fix inconsistencies automatically
-d --down fix by disabling or masking services if necessary (default)
-u --up fix by enabling services if necessary
diff --git a/src/s6-frontend/set_change.c b/src/s6-frontend/set_change.c
index 5353422..b74d6ae 100644
--- a/src/s6-frontend/set_change.c
+++ b/src/s6-frontend/set_change.c
@@ -49,7 +49,7 @@ static void set_change (char const *const *argv, char const *newsub, char const
}
char fmtv[UINT_FMT] ;
- char const *newargv[13 + argc] ;
+ char const *newargv[14 + argc] ;
newargv[m++] = S6RC_EXTBINPREFIX "s6-rc-set-change" ;
if (g->verbosity != 1)
{
@@ -68,6 +68,7 @@ static void set_change (char const *const *argv, char const *newsub, char const
newargv[m++] = "-I" ;
newargv[m++] = wgola[GOLA_FORCELEVEL] ;
}
+ if (!strcmp(newsub, "always")) newargv[m++] = "-e" ;
newargv[m++] = "--" ;
newargv[m++] = "current" ;
newargv[m++] = newsub ;
@@ -96,3 +97,8 @@ void set_unmask (char const *const *argv)
{
set_change(argv, "usable", "unmask") ;
}
+
+void set_make_essential (char const *const *argv)
+{
+ set_change(argv, "always", "make-essential") ;
+}
diff --git a/src/s6-frontend/set_check.c b/src/s6-frontend/set_check.c
index 4abda87..b6f4924 100644
--- a/src/s6-frontend/set_check.c
+++ b/src/s6-frontend/set_check.c
@@ -26,7 +26,7 @@ void set_check (char const *const *argv)
{ .so = 'e', .lo = "force-essential", .clear = 0, .set = GOLB_FORCE_ESSENTIAL },
{ .so = 'd', .lo = "down", .clear = GOLB_FIXUP, .set = 0 },
{ .so = 'u', .lo = "up", .clear = 0, .set = GOLB_FIXUP },
- { .so = 'f', .lo = "fix", .clear = 0, .set = GOLB_FIX },
+ { .so = 'F', .lo = "fix", .clear = 0, .set = GOLB_FIX },
} ;
uint64_t wgolb = 0 ;
unsigned int m = 0 ;
diff --git a/src/s6-frontend/set_list.c b/src/s6-frontend/set_list.c
index 6c98137..f01ef47 100644
--- a/src/s6-frontend/set_list.c
+++ b/src/s6-frontend/set_list.c
@@ -9,23 +9,32 @@
#include "s6-frontend-internal.h"
+enum golb_e
+{
+ GOLB_IGNORE_ESSENTIALS = 0x01,
+} ;
+
void set_list (char const *const *argv)
{
+ static gol_bool const rgolb[] =
+ {
+ { .so = 'E', .lo = "with-essentials", .clear = GOLB_IGNORE_ESSENTIALS, .set = 0 },
+ { .so = 'e', .lo = "without-essentials", .clear = 0, .set = GOLB_IGNORE_ESSENTIALS },
+ } ;
+ uint64_t wgolb = 0 ;
unsigned int m = 0 ;
- char const *newargv[9] ;
+ char const *newargv[10] ;
char fmtv[UINT_FMT] ;
- argv += gol_argv(argv, 0, 0, 0, 0, 0, 0) ;
+ argv += gol_argv(argv, rgolb, 2, 0, 0, &wgolb, 0) ;
newargv[m++] = S6RC_EXTBINPREFIX "s6-rc-set-status" ;
- if (g->verbosity != 1)
- {
- fmtv[uint_fmt(fmtv, g->verbosity)] = 0 ;
- newargv[m++] = "-v" ;
- newargv[m++] = fmtv ;
- }
+ fmtv[uint_fmt(fmtv, g->verbosity)] = 0 ;
+ newargv[m++] = "-v" ;
+ newargv[m++] = fmtv ;
newargv[m++] = "-r" ;
newargv[m++] = g->dirs.repo ;
newargv[m++] = "-L" ;
+ newargv[m++] = wgolb & GOLB_IGNORE_ESSENTIALS ? "--without-essentials" : "--with-essentials" ;
newargv[m++] = "--" ;
newargv[m++] = "current" ;
newargv[m++] = 0 ;
diff --git a/src/s6-frontend/set_status.c b/src/s6-frontend/set_status.c
index 4cb04d3..baead01 100644
--- a/src/s6-frontend/set_status.c
+++ b/src/s6-frontend/set_status.c
@@ -47,12 +47,9 @@ void set_status (char const *const *argv)
}
#endif
newargv[m++] = S6RC_EXTBINPREFIX "s6-rc-set-status" ;
- if (g->verbosity != 1)
- {
- fmtv[uint_fmt(fmtv, g->verbosity)] = 0 ;
- newargv[m++] = "-v" ;
- newargv[m++] = fmtv ;
- }
+ fmtv[uint_fmt(fmtv, g->verbosity)] = 0 ;
+ newargv[m++] = "-v" ;
+ newargv[m++] = fmtv ;
newargv[m++] = "-r" ;
newargv[m++] = g->dirs.repo ;
newargv[m++] = wgolb & GOLB_IGNORE_ESSENTIALS ? "--without-essentials" : "--with-essentials" ;