diff options
| author | Laurent Bercot <ska-skaware@skarnet.org> | 2026-01-13 04:16:54 +0000 |
|---|---|---|
| committer | Laurent Bercot <ska-skaware@skarnet.org> | 2026-01-13 04:16:54 +0000 |
| commit | 625252d2e88c9a6cb84ecb8731c14d85dd699aa9 (patch) | |
| tree | 9d40d9a83d5fe3b0699b5974b6515349319c8464 | |
| parent | 12868f261b1e822ae7f132216c2a5a380a163102 (diff) | |
| download | s6-frontend-625252d2e88c9a6cb84ecb8731c14d85dd699aa9.tar.gz | |
Better live_status and live_stop_everything, more doc
| -rw-r--r-- | doc/s6_live.html | 30 | ||||
| -rw-r--r-- | doc/s6_repository.html | 187 | ||||
| -rw-r--r-- | doc/s6_system.html | 147 | ||||
| -rw-r--r-- | src/s6-frontend/live_status.c | 45 | ||||
| -rw-r--r-- | src/s6-frontend/live_stop_everything.c | 5 |
5 files changed, 394 insertions, 20 deletions
diff --git a/doc/s6_live.html b/doc/s6_live.html index b35ba30..cd6aeac 100644 --- a/doc/s6_live.html +++ b/doc/s6_live.html @@ -61,7 +61,7 @@ and usage of the <tt>s6 live</tt> command. It is not as detailed as this page. <h4> Interface </h4> <pre> - s6 live status [ <em>servicenames...</em> ] + s6 live status [ -e | -E ] [ <em>servicenames...</em> ] </pre> <ul> @@ -75,9 +75,20 @@ then <tt>up</tt> or <tt>down</tt> depending on the current state of the service. in the generic s6 options, and s6-frontend is built with util-linux support, then the output is pretty-printed instead of having a slash separate the name of the service from its state. </li> - <li> No options are defined. </li> </ul> +<h4> Options </h4> + +<dl> +<dt> -e, --without-essentials </dt> +<dd> Do not list essential services, which can clutter the display with +irrelevant information and are all supposed to always be up anyway. +This is the default. </dd> + +<dt> -E, --with-essentials </dt> +<dd> List all services, including essential ones. </dd> +</dl> + <div id="start"> <h3> start </h3> </div> @@ -213,7 +224,7 @@ The default is <tt>default</tt>, possibly overridden by the <h4> Interface </h4> <pre> - s6 live stop_everything [ -n ] [ -t <em>timeout</em> ] + s6 live stop_everything [ -n ] [ -e | -E ] [ -t <em>timeout</em> ] </pre> <ul> @@ -228,6 +239,19 @@ reboot a machine; for that, check <a href="s6_system.html"><tt>s6 system</tt></a <dt> -n, --dry-run </dt> <dd> Only print what would be done; do not actually stop services. </dd> +<dt> -e, --without-essentials </dt> +<dd> Do not stop essential services; keep the machine in a state where +it can more or less run and be interacted with, even if in a completely +bare state. This is the default. </dd> + +<dt> -E, --with-essentials </dt> +<dd> Also stop essential services. After this command, the machine +isn't good for much except a reboot. <code>s6 live stop_everything -E</code> +is the command that should be run right before a shutdown when the +system is not using s6-linux-init. To that end, the line +<code>::shutdown:/usr/bin/s6 live stop_everything -E</code> should be +added to <tt>/etc/inittab</tt>, if that is what the init uses. </dd> + <dt> -t <em>timeout</em>, --timeout=<em>timeout</em> </dt> <dd> If the whole change still hasn't completed after <em>timeout</em> milliseconds, stop waiting and don't attempt to perform the remaining diff --git a/doc/s6_repository.html b/doc/s6_repository.html new file mode 100644 index 0000000..377344f --- /dev/null +++ b/doc/s6_repository.html @@ -0,0 +1,187 @@ +<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 repository command</title> + <meta name="Description" content="s6-frontend: the s6 repository command" /> + <meta name="Keywords" content="s6 ecosystem supervision service manager user interface init skarnet.org skarnet software repository repo 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 repository</tt> command </h1> + +<p> + <tt>s6 repository</tt> regroups actions that target the repository of source +definition directories for services managed by the +<a href="//skarnet.org/software/s6-rc/repodefs.html">repo commands</a> of the +s6-rc service manager. The repository is hosted in the +<a href="s6-frontend.conf.html">configured</a> <em>repodir</em>. +</p> + +<p> + This set of commands is not intended for day-to-day use, since they involve +serious actions on the repository which is supposed to be stable. Rather, +they are likely to be a part of automated procedures written by the distribution +and triggered by specific events like installation or package updates. +</p> + +<div id="interface"> +<h2> Interface </h2> +</div> + +<pre> + s6 repository <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 repository help</tt> prints a short help message summarizing the options +and usage of the <tt>s6 repository</tt> command. It is not as detailed as this page. +</p> + +<div id="init"> +<h3> init </h3> +</div> + +<h4> Interface </h4> + +<pre> + s6 repository init [ -f ] [ -U ] [ -h <em>fdhuser</em> ] +</pre> + +<ul> + <li> <tt>s6 repository init</tt> creates the repository at the configured +location. </li> + <li> It links all the stores defined in the configured store list. </li> + <li> It syncs the repository with the stores, importing all the services +and making its reference database. </li> + <li> It creates a service set named <tt>current</tt>, which will be the +working set for all <a href="s6_set.html"><tt>s6 set</tt></a> commands. </li> +</ul> + +<h4> Options </h4> + +<dl> +<dt> -f, --force </dt> +<dd> If the repository already exists, overwrite it with a new one. +This is a dangerous option and should only be used as a last resort +if the repository seems hopelessly broken. </dd> + +<dt> -U, --update-stores </dt> +<dd> Do not recreate the repository from scratch, but update the list +of stores. This commands needs to be run when the storelist variable +has changed. </dd> + +<dt> -h <em>fdhuser</em>, --fdholder-user=<em>fdhuser</em> </dt> +<dd> Specify the fdholder user for the reference database. This has +no impact whatsoever and this option can safely be ignored. </dd> +</dl> + +<div id="list"> +<h3> list </h3> +</div> + +<h4> Interface </h4> + +<pre> + s6 repository list +</pre> + +<ul> + <li> <tt>s6 repository list</tt> lists all the saved sets in the repository, +printing their names on stdout, one per line. It does not list <tt>current</tt>, +the current working set, which always exists. </li> + <li> No options are defined. </li> +</ul> + +<div id="check"> +<h3> check </h3> +</div> + +<h4> Interface </h4> + +<pre> + s6 repository check [ -f ] [ -d | -u ] [ -E | -e ] +</pre> + +<ul> + <li> <tt>s6 repository check</tt> checks all the services in the 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 a 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 a 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 sets 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 sets 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="sync"> +<h3> sync </h3> +</div> + +<h4> Interface </h4> + +<pre> + s6 repository sync [ -h <em>fdhuser</em> ] +</pre> + +<ul> + <li> <tt>s6 repository sync</tt> synchronizes the repository's view of services +with the contents of the stores. </li> + <li> This command must be run every time the stores change, typically +when the package manager of the distribution adds or removes a package +that defines a service. Ideally it should be added to a hook defined by +the package manager. </li> +</ul> + +<h4> Options </h4> + +<dl> +<dt> -h <em>fdhuser</em>, --fdholder-user=<em>fdhuser</em> </dt> +<dd> Specify the fdholder user for the reference database. This has +no impact whatsoever and this option can safely be ignored. </dd> +</dl> + +</body> +</html> diff --git a/doc/s6_system.html b/doc/s6_system.html new file mode 100644 index 0000000..10d52d7 --- /dev/null +++ b/doc/s6_system.html @@ -0,0 +1,147 @@ +<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 system command</title> + <meta name="Description" content="s6-frontend: the s6 system command" /> + <meta name="Keywords" content="s6 ecosystem supervision service manager user interface init skarnet.org skarnet software boot shutdown system reboot poweroff" /> + <!-- <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 system</tt> command </h1> + +<p> + <tt>s6 system</tt> regroups actions related to booting or shutting down +the system. +</p> + +<div id="interface"> +<h2> Interface </h2> +</div> + +<pre> + s6 system <em>subcommand</em> +</pre> + +<ul> + <li> No subcommand takes any options. </li> +</ul> + +<div id="subcommands"> +<h2> Subcommands </h2> +</div> + +<div id="help"> +<h3> help </h3> +</div> + +<p> + <tt>s6 system help</tt> prints a short help message summarizing the options +and usage of the <tt>s6 system</tt> command. It is not as detailed as this page. +</p> + +<div id="boot"> +<h3> boot </h3> +</div> + +<h4> Interface </h4> + +<pre> + s6 system boot +</pre> + +<ul> + <li> <tt>s6 system boot</tt> initializes the live directory for s6-rc +then starts all the services defined in the default bundle. In other +words, it brings the system from a state where nothing is running to +a state where everything the user wants is running. </li> + <li> This is the command that should be called as soon as the init +program hands off duties. + <ul> + <li> On a system making use of +<a href="//skarnet.org/software/s6-linux-init/">s6-linux-init/a>, +<tt>s6 system boot</tt> should be the sole command defined in the +<tt>/etc/rc.init</tt> script. </li> + <li> On a system using <tt>/etc/inittab</tt>, the first line +of the inittab should be: <tt>::wait:/usr/bin/s6 system boot</tt> </li> + </ul> </li> +</ul> + +<p> + The rest of the subcommands are shutdown subcommands, and they +only work if the machine makes use of +<a href="//skarnet.org/software/s6-linux-init/">s6-linux-init/a> and +s6-frontend has been configured to support it. On a machine that +does not boot via s6-linux-init, a shutdown should be executed via +the shutdown commands provided by your init system. In order for +the shutdown to be clean, the <code>s6 live stop_everything -E</code> +should be run before the init system performs a hard shutdown. For +instance, if the system uses <tt>/etc/inittab</tt>, then the +following line should appear in <tt>/etc/inittab</tt>: +<code>::shutdown:/usr/bin/s6 live stop_everything -E</code> +</p> + +<div id="reboot"> +<h3> reboot </h3> +</div> + +<h4> Interface </h4> + +<pre> + s6 system reboot +</pre> + +<ul> + <li> <tt>s6 system reboot</tt> reboots the machine. + <li> This only works if the machine makes use of +<a href="//skarnet.org/software/s6-linux-init/">s6-linux-init/a> and +s6-frontend has been configured to support it. </li> +</ul> + +<div id="poweroff"> +<h3> poweroff </h3> +</div> + +<h4> Interface </h4> + +<pre> + s6 system poweroff +</pre> + +<ul> + <li> <tt>s6 system poweroff</tt> halts the system and turns the +power off. </li> + <li> This only works if the machine makes use of +<a href="//skarnet.org/software/s6-linux-init/">s6-linux-init/a> and +s6-frontend has been configured to support it. </li> +</ul> + +<div id="halt"> +<h3> halt </h3> +</div> + +<h4> Interface </h4> + +<pre> + s6 system halt +</pre> + +<ul> + <li> <tt>s6 system halt</tt> halts the system without turning +the power off. </li> + <li> This only works if the machine makes use of +<a href="//skarnet.org/software/s6-linux-init/">s6-linux-init/a> and +s6-frontend has been configured to support it. </li> +</ul> + +</body> +</html> diff --git a/src/s6-frontend/live_status.c b/src/s6-frontend/live_status.c index a68d99f..dbf9aa6 100644 --- a/src/s6-frontend/live_status.c +++ b/src/s6-frontend/live_status.c @@ -17,12 +17,12 @@ #include <s6-frontend/config.h> #include "s6-frontend-internal.h" -#define USAGE "s6 live status services..." +#define USAGE "s6 live status [ -e | -E ] services..." #define dieusage() strerr_dieusage(100, USAGE) #define dienomem() strerr_diefu1sys(111, "stralloc_catb") -static void live_status_all (void) gccattr_noreturn ; -static void live_status_all (void) +static void live_status_all (int withe) gccattr_noreturn ; +static void live_status_all (int withe) { char const *argv[23] ; unsigned int m = 0 ; @@ -40,7 +40,7 @@ static void live_status_all (void) argv[m++] = EXECLINE_EXTBINPREFIX "if" ; argv[m++] = " " EXECLINE_EXTBINPREFIX "pipeline" ; argv[m++] = " " S6RC_EXTBINPREFIX "s6-rc" ; - argv[m++] = " -ua" ; + argv[m++] = withe ? " -buaE" : " -buae" ; argv[m++] = " list" ; argv[m++] = " " ; argv[m++] = " sed" ; @@ -48,7 +48,7 @@ static void live_status_all (void) argv[m++] = "" ; argv[m++] = EXECLINE_EXTBINPREFIX "pipeline" ; argv[m++] = " " S6RC_EXTBINPREFIX "s6-rc" ; - argv[m++] = " -da" ; + argv[m++] = withe ? " -bdaE" : " -bdae" ; argv[m++] = " list" ; argv[m++] = "" ; argv[m++] = "sed" ; @@ -57,13 +57,13 @@ static void live_status_all (void) xmexec_n(argv, cleanup_modif.s, cleanup_modif.len, cleanup_modif.n) ; } -static int get_list_of_up (stralloc *storage) +static int get_list_of_up (stralloc *storage, int withe) { int swasnull = !storage->s ; size_t sabase = storage->len ; int fd ; int wstat ; - char const *argv[7] = { S6RC_EXTBINPREFIX "s6-rc", "-l", g->dirs.live, "-ba", "--", "list", 0 } ; + char const *argv[7] = { S6RC_EXTBINPREFIX "s6-rc", "-l", g->dirs.live, withe ? "-baE" : "-bae", "--", "list", 0 } ; pid_t pid = child_spawn1_pipe(argv[0], argv, (char const *const *)environ, &fd, 1) ; if (!pid) { strerr_warnfu2sys("spawn ", argv[0]) ; return 111 ; } if (!slurpn(fd, storage, 0)) { strerr_warnfu2sys("read output from ", argv[0]) ; return 111 ; } @@ -88,7 +88,7 @@ static int get_list_of_up (stralloc *storage) return 111 ; } -static int get_atomics (char const *const *services, unsigned int n, stralloc *storage) +static int get_atomics (char const *const *services, unsigned int n, stralloc *storage, int withe) { int swasnull = !storage->s ; size_t sabase = storage->len ; @@ -100,7 +100,7 @@ static int get_atomics (char const *const *services, unsigned int n, stralloc *s argv[m++] = S6RC_EXTBINPREFIX "s6-rc-db" ; argv[m++] = "-l"; argv[m++] = g->dirs.live ; - argv[m++] = "-b" ; + argv[m++] = withe ? "-bE" : "-be" ; argv[m++] = "--" ; argv[m++] = "atomics" ; for (unsigned int i = 0 ; i < n ; i++) argv[m++] = services[i] ; @@ -129,8 +129,8 @@ static int get_atomics (char const *const *services, unsigned int n, stralloc *s return 111 ; } -static void live_status_some (char const *const *services) gccattr_noreturn ; -static void live_status_some (char const *const *services) +static void live_status_some (char const *const *services, int withe) gccattr_noreturn ; +static void live_status_some (char const *const *services, int withe) { stralloc sa = STRALLOC_ZERO ; unsigned int m = 0 ; @@ -138,11 +138,11 @@ static void live_status_some (char const *const *services) int e ; char const *argv[59] ; if (!stralloc_catb(&sa, " ", 1)) dienomem() ; - e = get_atomics(services, env_len(services), &sa) ; + e = get_atomics(services, env_len(services), &sa, withe) ; if (e) _exit(e) ; if (!stralloc_catb(&sa, "\0 ", 3)) dienomem() ; uplistpos = sa.len ; - e = get_list_of_up(&sa) ; + e = get_list_of_up(&sa, withe) ; if (e) _exit(e) ; if (!stralloc_0(&sa)) dienomem() ; @@ -213,10 +213,23 @@ static void live_status_some (char const *const *services) xmexec_n(argv, cleanup_modif.s, cleanup_modif.len, cleanup_modif.n) ; } +enum golb_e +{ + GOLB_INCLUDE_ESSENTIALS = 0x01, +} ; + + void live_status (char const *const *argv) { - argv += gol_argv(argv, 0, 0, 0, 0, 0, 0) ; - if (!argv) live_status_all() ; - else live_status_some(argv) ; + static gol_bool const rgolb[] = + { + { .so = 'e', .lo = "without-essentials", .clear = GOLB_INCLUDE_ESSENTIALS, .set = 0 }, + { .so = 'E', .lo = "with-essentials", .clear = 0, .set = GOLB_INCLUDE_ESSENTIALS }, + } ; + uint64_t wgolb = 0 ; + + argv += gol_argv(argv, rgolb, 2, 0, 0, &wgolb, 0) ; + if (!argv) live_status_all(wgolb & GOLB_INCLUDE_ESSENTIALS) ; + else live_status_some(argv, wgolb & GOLB_INCLUDE_ESSENTIALS) ; _exit(0) ; } diff --git a/src/s6-frontend/live_stop_everything.c b/src/s6-frontend/live_stop_everything.c index 7d98c70..be9a40a 100644 --- a/src/s6-frontend/live_stop_everything.c +++ b/src/s6-frontend/live_stop_everything.c @@ -9,6 +9,7 @@ enum golb_e { GOLB_DRYRUN = 0x01, + GOLB_INCLUDE_ESSENTIALS = 0x02, } ; enum gola_e @@ -22,6 +23,8 @@ void live_stop_everything (char const *const *argv) static gol_bool const rgolb[] = { { .so = 'n', .lo = "dry-run", .clear = 0, .set = GOLB_DRYRUN }, + { .so = 'e', .lo = "without-essentials", .clear = GOLB_INCLUDE_ESSENTIALS, .set = 0 }, + { .so = 'E', .lo = "with-essentials", .clear = 0, .set = GOLB_INCLUDE_ESSENTIALS }, } ; static gol_arg const rgola[] = { @@ -56,7 +59,7 @@ void live_stop_everything (char const *const *argv) if (wgolb & GOLB_DRYRUN) newargv[m++] = "-n1" ; newargv[m++] = "-l" ; newargv[m++] = g->dirs.live ; - newargv[m++] = "-bda" ; + newargv[m++] = wgolb & GOLB_INCLUDE_ESSENTIALS ? "-bDa" : "-bda" ; newargv[m++] = "--" ; newargv[m++] = "change" ; newargv[m++] = 0 ; |
