From 6203378b6b6731a938eebdd60d99fecb429a849f Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Fri, 16 Jan 2026 05:09:46 +0000 Subject: Minor changes and fixes; doc for s6 set --- doc/s6_repository.html | 6 +- doc/s6_set.html | 347 +++++++++++++++++++++++++++++++++ src/s6-frontend/live.help.txt | 6 +- src/s6-frontend/repository_check.c | 2 +- src/s6-frontend/s6-frontend-internal.h | 1 + src/s6-frontend/set.c | 1 + src/s6-frontend/set.help.txt | 2 +- src/s6-frontend/set_change.c | 8 +- src/s6-frontend/set_check.c | 2 +- src/s6-frontend/set_list.c | 25 ++- src/s6-frontend/set_status.c | 9 +- 11 files changed, 386 insertions(+), 23 deletions(-) create mode 100644 doc/s6_set.html 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.

Interface

-     s6 repository check [ -f ] [ -d | -u ] [ -E | -e ]
+     s6 repository check [ -F ] [ -d | -u ] [ -E | -e ]
 

Options

-
-f, --fix
+
-F, --fix
Also attempt to fix the inconsistencies.
-E, --no-force-essential
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 @@ + + + + + + s6-frontend: the s6 set command + + + + + + +

+The s6 command
+s6-frontend
+Software
+skarnet.org +

+ +

The s6 set command

+ +

+ s6 set regroups actions on +current. It is not the set that is +currently live; it is the set that is currently worked on. +

+ +
+

Interface

+
+ +
+     s6 set subcommand [ subcommand_options... ] [ args... ]
+
+ +
+

Subcommands

+
+ +
+

help

+
+ +

+ s6 set help prints a short help message summarizing the options +and usage of the s6 set command. It is not as detailed as this page. +

+ +
+

save

+
+ +

Interface

+ +
+     s6 set save [ -f ] name
+
+ +
+ +

Options

+ +
+
-f, --force
+
If a set named name already exists, overwrite it with a copy +of the current working set. By default, the command exits with an error +instead of overwriting.
+ +
+

load

+
+ +

Interface

+ +
+     s6 set load name
+
+ +
    +
  • s6 set load replaces the current working set with the set stored +as name.
  • +
  • No options are defined.
  • +
+ +
+

list

+
+ +

Interface

+ +
+     s6 set list [ -E | -e ]
+
+ +
    +
  • s6 set list lists all the services in the current set, +printing their names on stdout, one per line. +the current working set, which always exists.
  • +
+ +

Options

+ +
+
-E, --with-essentials
+
List all the services, including the essential ones. This is the +default.
+ +
-e, --without-essentials
+
Do not list essential services.
+
+ +
+

list

+
+ +

Interface

+ +
+     s6 set status [ -E | -e ] [ names... ]
+
+ +
    +
  • s6 set status lists the services named names... +in the working set with their current +sub, i.e. +the state that they should be in at boot time: masked, disabled (listed +as usable), enabled (listed as active), or essential +(listed as always). +
      +
    • masked 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 inconsistent.
    • +
    • usable 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 +s6 live start command.
    • +
    • active means that the service will be brought up by +default at boot time. It can later be brought down manually via the +s6 live stop command.
    • +
    • always 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 s6 set +commands.
    • +
  • +
  • The service name is normally followed by a slash (/) +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.
  • +
  • If names... is empty, all the services in the set +are printed, along with their subs.
  • +
+ +

Options

+ +
+
-E, --with-essentials
+
Prints all the listed services, including the essential ones. This is the +default.
+ +
-e, --without-essentials
+
Do not print essential services.
+
+ +
+
+
+
+
+

enable, disable, mask, unmask, make-essential

+
+ +

Interface

+ +
+     s6 set enable|disable|mask|unmask|make-essential [ -f ] [ -n ] [ -I fail|warn|pull ] [ services... ]
+
+ +
    +
  • These subcommands are build with the same model and do the same +thing: they move the services listed in services... from their +current subs to another. +
      +
    • mask masks the services.
    • +
    • unmask and disable put the services in the usable sub, i.e. unmasked and disabled.
    • +
    • enable enables the services.
    • +
    • make-essential 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.
    • +
  • +
  • Dependencies across services are computed, and the command will print a message if the change would +make the set inconsistent.
  • +
+ +

Options

+ +
+
-f, --ignore-dependencies
+
Only change the services listed in services, don't compute dependencies
+ +
-n, --dry-run
+
Do not perform the change; only show what would be done and check whether the set +would be made inconsistent.
+ +
-I what, --if-dependencies-found=what
+
What to do when services have dependencies, or reverse dependencies, that are not +listed in services.... what can be fail, warn, +or pull. +
    +
  • fail: abort the operation with an error message.
  • +
  • warn: 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).
  • +
  • pull: pull the dependencies into the +same sub as the listed service, so there is no inconsistency. For enable, +service dependencies are made active as well. For disable, reverse +dependencies are disabled as well. For mask, reverse dependencies are +masked as well.
  • +
+
+ +

Notes

+ +

+ These subcommands are the bread and butter of the s6 set commands. They +allow the user to tailor the boot sequence to their needs without touching the +currently running database. +

+ +
+

check

+
+ +

Interface

+ +
+     s6 set check [ -F ] [ -d | -u ] [ -E | -e ]
+
+ +
    +
  • s6 set check checks the current working set for +inconsistencies, and prints anything it finds to stdout.
  • +
+ +

Options

+ +
+
-F, --fix
+
Also attempt to fix the inconsistencies.
+ +
-E, --no-force-essential
+
If fixing the set involves changing a service flagged as essential +to a sub that is not always, or a service not +flagged as essential to the always sub, print an error message +and exit. This is the default.
+ +
-e, --force-essential
+
If fixing the set involves changing a service flagged as essential +to a sub that is not always, or a service not +flagged as essential to the always sub, perform the change +and continue. This is normally not necessary with a list of stores +providing consistent services.
+ +
-d, --down
+
Fix the set by disabling or masking services. If service A +depends on service B and B is masked or disabled, +change A to be masked or disabled as well. This is the +default.
+ +
-u, --up
+
Fix the set by enabling or unmasking services. If service A +depends on service B and A is unmasked or enabled, +change B to be unmasked or enabled as well.
+
+ +
+

commit

+
+ +

Interface

+ +
+     s6 set commit [ -f ] [ -K ] [ -D defaultbundle [ -h fdhuser ]
+
+ +
    +
  • s6 set commit +commits +the current set: it attempts to +compile a +service database out of the set.
  • +
  • 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 s6 set check -F command.
  • +
  • Once the set has been committed, in order to actually be used, it must +be installed via the s6 live install +command.
  • +
+ +

Options

+ +
+
-f, --force
+
Compile the database even if no change has been performed since the +last time the set was committed.
+ +
-K, --keep-old
+
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.
+ +
-D defaultbundle, --default-bundle=defaultbundle
+
The name of the bundle that will hold all active and always +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 +default.
+ +
-h fdhuser, --fdholder-user=fdhuser
+
Specify the fdholder user for the compiled database built from +the set. This must be a user name defined in the /etc/passwd +file or whatever user database the system uses. The default is root +and that is fine.
+
+ + + 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" ; -- cgit v1.3.1