From 8eb000d3d22fcf7850b43f75ed52068693430d3b Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Fri, 19 Jun 2026 02:29:06 +0000 Subject: Add s6 set apply and s6 apply --- doc/overview.html | 5 +- doc/s6.html | 1 + doc/s6_set.html | 57 +++++++++++++ package/deps.mak | 3 +- src/s6-frontend/deps-exe/s6-frontend | 1 + src/s6-frontend/main.help.txt | 8 ++ src/s6-frontend/s6-frontend-internal.h | 2 + src/s6-frontend/s6-frontend.c | 1 + src/s6-frontend/set.c | 1 + src/s6-frontend/set.help.txt | 13 ++- src/s6-frontend/set_apply.c | 143 +++++++++++++++++++++++++++++++++ src/s6-frontend/set_change.c | 6 +- 12 files changed, 233 insertions(+), 8 deletions(-) create mode 100644 src/s6-frontend/set_apply.c diff --git a/doc/overview.html b/doc/overview.html index 84a81e1..f7f2c87 100644 --- a/doc/overview.html +++ b/doc/overview.html @@ -303,8 +303,9 @@ changes effective, the user needs to run s6 set commit then openrc sysinit && openrc boot && openrc default s6 system boot - The existence of the sysinit and boot runlevels are a -historical wart that OpenRC still has to deal with; s6-frontend does not. + The sysinit and boot runlevels in OpenRC are only distinct +for historical reasons. s6-frontend does not make the distinction, all the services it +starts at boot time are in the default bundle. reboot diff --git a/doc/s6.html b/doc/s6.html index 0f6fc39..f148a23 100644 --- a/doc/s6.html +++ b/doc/s6.html @@ -232,6 +232,7 @@ The details are available here.
  • s6 start is a shortcut for s6 live start.
  • s6 stop is a shortcut for s6 live stop.
  • s6 kill is a shortcut for s6 process kill.
  • +
  • s6 apply is a shortcut for s6 set apply.
  • Notes

    diff --git a/doc/s6_set.html b/doc/s6_set.html index bd74233..a38a57d 100644 --- a/doc/s6_set.html +++ b/doc/s6_set.html @@ -343,5 +343,62 @@ and that is fine.
    Commit the set named setname, rather than current.
    +

    apply

    + +

    Interface

    + +
    +     s6 set apply [ -b ]  [ -D defaultbundle ] [ -h fdhuser ] [ -s setname ] [ -t timeout ]
    +
    + + + +

    Options

    + +
    +
    -b, --block
    +
    Block if something is currently holding the lock on the live service +database. The default is to fail with an error message instead.
    + +
    -D defaultbundle, --default-bundle=defaultbundle
    +
    The name of the bundle that holds all active and always +services, which will be the ones running on the machine when the command ends. +The default 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.
    + +
    -f convfile, --conversion-file=convfile
    +
    Use convfile as a conversion file for the underlying +s6-rc-update +invocation. This option should +never be necessary if the services in the stores are properly managed.
    + +
    -s setname, --set=setname
    +
    Apply the set named setname, rather than current.
    + +
    -t timeout, --timeout=timeout
    +
    If installing the set and resetting the state still hasn't completed after timeout +milliseconds, stop waiting and don't attempt to perform the remaining +transitions. By default, timeout is 0, meaning infinite: the +command will wait until the task is complete.
    +
    + diff --git a/package/deps.mak b/package/deps.mak index 923fcfc..e26a563 100644 --- a/package/deps.mak +++ b/package/deps.mak @@ -29,6 +29,7 @@ src/s6-frontend/repository_sync.o src/s6-frontend/repository_sync.lo: src/s6-fro src/s6-frontend/s6-frontend.o src/s6-frontend/s6-frontend.lo: src/s6-frontend/s6-frontend.c src/s6-frontend/s6-frontend-internal.h src/include-local/s6f.h src/s6-frontend/s6.o src/s6-frontend/s6.lo: src/s6-frontend/s6.c src/include/s6-frontend/config.h src/s6-frontend/set.o src/s6-frontend/set.lo: src/s6-frontend/set.c src/s6-frontend/s6-frontend-internal.h +src/s6-frontend/set_apply.o src/s6-frontend/set_apply.lo: src/s6-frontend/set_apply.c src/s6-frontend/s6-frontend-internal.h src/s6-frontend/set_change.o src/s6-frontend/set_change.lo: src/s6-frontend/set_change.c src/s6-frontend/s6-frontend-internal.h src/s6-frontend/set_check.o src/s6-frontend/set_check.lo: src/s6-frontend/set_check.c src/s6-frontend/s6-frontend-internal.h src/include/s6-frontend/config.h src/s6-frontend/set_commit.o src/s6-frontend/set_commit.lo: src/s6-frontend/set_commit.c src/s6-frontend/s6-frontend-internal.h @@ -55,5 +56,5 @@ endif s6: EXTRA_LIBS := s6: src/s6-frontend/s6.o -lskarnet s6-frontend: EXTRA_LIBS := ${MAYBEPTHREAD_LIB} -s6-frontend: src/s6-frontend/s6-frontend.o src/s6-frontend/live.o src/s6-frontend/live_help.o src/s6-frontend/live_install.o src/s6-frontend/live_reload.o src/s6-frontend/live_startstop.o src/s6-frontend/live_status.o src/s6-frontend/live_start_everything.o src/s6-frontend/live_stop_everything.o src/s6-frontend/main_help.o src/s6-frontend/process.o src/s6-frontend/process_help.o src/s6-frontend/process_kill.o src/s6-frontend/process_restart.o src/s6-frontend/process_startstop.o src/s6-frontend/process_status.o src/s6-frontend/repository.o src/s6-frontend/repository_check.o src/s6-frontend/repository_help.o src/s6-frontend/repository_init.o src/s6-frontend/repository_list.o src/s6-frontend/repository_sync.o src/s6-frontend/set.o src/s6-frontend/set_change.o src/s6-frontend/set_check.o src/s6-frontend/set_commit.o src/s6-frontend/set_copy.o src/s6-frontend/set_delete.o src/s6-frontend/set_help.o src/s6-frontend/set_list.o src/s6-frontend/set_status.o src/s6-frontend/system.o src/s6-frontend/system_boot.o src/s6-frontend/system_help.o src/s6-frontend/system_hpr.o src/s6-frontend/version.o src/s6-frontend/version_export.o src/s6-frontend/version_help.o src/s6-frontend/version_show.o libs6f.a.xyzzy ${LIBNSSS} -ls6rc -ls6 -lskarnet +s6-frontend: src/s6-frontend/s6-frontend.o src/s6-frontend/live.o src/s6-frontend/live_help.o src/s6-frontend/live_install.o src/s6-frontend/live_reload.o src/s6-frontend/live_startstop.o src/s6-frontend/live_status.o src/s6-frontend/live_start_everything.o src/s6-frontend/live_stop_everything.o src/s6-frontend/main_help.o src/s6-frontend/process.o src/s6-frontend/process_help.o src/s6-frontend/process_kill.o src/s6-frontend/process_restart.o src/s6-frontend/process_startstop.o src/s6-frontend/process_status.o src/s6-frontend/repository.o src/s6-frontend/repository_check.o src/s6-frontend/repository_help.o src/s6-frontend/repository_init.o src/s6-frontend/repository_list.o src/s6-frontend/repository_sync.o src/s6-frontend/set.o src/s6-frontend/set_apply.o src/s6-frontend/set_change.o src/s6-frontend/set_check.o src/s6-frontend/set_commit.o src/s6-frontend/set_copy.o src/s6-frontend/set_delete.o src/s6-frontend/set_help.o src/s6-frontend/set_list.o src/s6-frontend/set_status.o src/s6-frontend/system.o src/s6-frontend/system_boot.o src/s6-frontend/system_help.o src/s6-frontend/system_hpr.o src/s6-frontend/version.o src/s6-frontend/version_export.o src/s6-frontend/version_help.o src/s6-frontend/version_show.o libs6f.a.xyzzy ${LIBNSSS} -ls6rc -ls6 -lskarnet INTERNAL_LIBS := libs6f.a.xyzzy diff --git a/src/s6-frontend/deps-exe/s6-frontend b/src/s6-frontend/deps-exe/s6-frontend index b6d45c0..1a47be4 100644 --- a/src/s6-frontend/deps-exe/s6-frontend +++ b/src/s6-frontend/deps-exe/s6-frontend @@ -20,6 +20,7 @@ repository_init.o repository_list.o repository_sync.o set.o +set_apply.o set_change.o set_check.o set_commit.o diff --git a/src/s6-frontend/main.help.txt b/src/s6-frontend/main.help.txt index f7c03eb..7837152 100644 --- a/src/s6-frontend/main.help.txt +++ b/src/s6-frontend/main.help.txt @@ -11,6 +11,14 @@ Commands: set manipulate sets of services (offline, to later install them live) repository manipulate the service repository itself +Shortcuts: + enable s6 set enable + disable s6 set disable + start s6 live start + stop s6 live stop + kill s6 process kill + apply s6 set apply + Global options: -h --help equivalent to "s6 help" -u --user override config values with XDG environment diff --git a/src/s6-frontend/s6-frontend-internal.h b/src/s6-frontend/s6-frontend-internal.h index dad191b..587b4e2 100644 --- a/src/s6-frontend/s6-frontend-internal.h +++ b/src/s6-frontend/s6-frontend-internal.h @@ -88,6 +88,8 @@ 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 ; +extern void set_apply (char const *const *) gccattr_noreturn ; + /* system */ diff --git a/src/s6-frontend/s6-frontend.c b/src/s6-frontend/s6-frontend.c index c79464e..9e649a7 100644 --- a/src/s6-frontend/s6-frontend.c +++ b/src/s6-frontend/s6-frontend.c @@ -118,6 +118,7 @@ int main (int argc, char const *const *argv) } ; static struct command_s const commands[] = { + { .s = "apply", .f = &set_apply }, { .s = "disable", .f = &set_disable }, { .s = "enable", .f = &set_enable }, { .s = "help", .f = &main_help }, diff --git a/src/s6-frontend/set.c b/src/s6-frontend/set.c index fe5f165..8ece627 100644 --- a/src/s6-frontend/set.c +++ b/src/s6-frontend/set.c @@ -23,6 +23,7 @@ void set (char const *const *argv) { static struct command_s const commands[] = { + { .s = "apply", .f = &set_apply }, { .s = "check", .f = &set_check }, { .s = "commit", .f = &set_commit }, { .s = "copy", .f = &set_copy }, diff --git a/src/s6-frontend/set.help.txt b/src/s6-frontend/set.help.txt index 62b59ea..9113f34 100644 --- a/src/s6-frontend/set.help.txt +++ b/src/s6-frontend/set.help.txt @@ -12,6 +12,7 @@ Subcommands: unmask unmask services (equivalent to "disable") check check working set and fix inconsistencies commit commit working set (can then be installed) + apply make working set live: commit + live install + live reset s6 set copy options: @@ -37,8 +38,8 @@ s6 set enable|disable|mask|unmask options: -s SET --set=SET change services in set SET (default: current) 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 + -E --no-force-essentials do not allow manual changes to essential services (default) + -e --force-essentials allow manual changes to essential services -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 @@ -51,3 +52,11 @@ s6 set commit options: -h USER --fdholder-user=USER user for the s6-fdholderd process (default: root - it's fine) -s SET --set=SET commit set SET (default: current) +s6 set apply options: + -b --block block if another s6-rc is running (default: fail) + -D BUN --default-bundle=BUN name of the bundle containing enabled+essential services + -h USER --fdholder-user=USER user for the s6-fdholderd process (default: root - it's fine) + -f CONVFILE --conversion-file=CONVFILE use CONVFILE when updating the service db (default: none) + -s SET --set=SET apply set SET (default: current) + -t TIMEOUT --timeout=TIMEOUT fail after TIMEOUT milliseconds (default: 0 (=infinite)) + diff --git a/src/s6-frontend/set_apply.c b/src/s6-frontend/set_apply.c new file mode 100644 index 0000000..b017212 --- /dev/null +++ b/src/s6-frontend/set_apply.c @@ -0,0 +1,143 @@ +/* ISC license. */ + +#include +#include +#include +#include + +#include + +#include "s6-frontend-internal.h" + +enum golb_e +{ + GOLB_BLOCK = 0x01, +} ; + +enum gola_e +{ + GOLA_DEFBUNDLE, + GOLA_FDHUSER, + GOLA_CONVFILE, + GOLA_SET, + GOLA_TIMEOUT, + GOLA_N +} ; + +void set_apply (char const *const *argv) +{ + static gol_bool const rgolb[] = + { + { .so = 'b', .lo = "block", .clear = 0, .set = GOLB_BLOCK }, + } ; + static gol_arg const rgola[] = + { + { .so = 'D', .lo = "default-bundle", .i = GOLA_DEFBUNDLE }, + { .so = 'h', .lo = "fdholder-user", .i = GOLA_FDHUSER }, + { .so = 'f', .lo = "conversion-file", .i = GOLA_CONVFILE }, + { .so = 's', .lo = "set", .i = GOLA_SET }, + { .so = 't', .lo = "timeout", .i = GOLA_TIMEOUT }, + } ; + uint64_t wgolb = 0 ; + unsigned int timeout = 0 ; + unsigned int m = 0 ; + int wstat ; + pid_t pid ; + char const *wgola[GOLA_N] = { 0 } ; + char const *newargv[15] ; + char fmtv[UINT_FMT] ; + char fmtt[UINT_FMT] ; + + wgola[GOLA_DEFBUNDLE] = S6_FRONTEND_DEFBUNDLE ; + wgola[GOLA_SET] = "current" ; + + argv += GOL_argv(argv, rgolb, rgola, &wgolb, wgola) ; + + if (wgola[GOLA_TIMEOUT]) + { + if (!uint0_scan(wgola[GOLA_TIMEOUT], &timeout)) + strerr_dief1x(100, "timeout must be an integer (milliseconds)") ; + } + + /* set commit */ + newargv[m++] = S6RC_EXTBINPREFIX "s6-rc-set-commit" ; + if (g->verbosity != 1) + { + fmtv[uint_fmt(fmtv, g->verbosity)] = 0 ; + newargv[m++] = "-v" ; + newargv[m++] = fmtv ; + } + newargv[m++] = "-r" ; + newargv[m++] = g->dirs.repo ; + newargv[m++] = "-D" ; + newargv[m++] = wgola[GOLA_DEFBUNDLE] ; + if (wgola[GOLA_FDHUSER]) + { + newargv[m++] = "-h" ; + newargv[m++] = wgola[GOLA_FDHUSER] ; + } + newargv[m++] = "--" ; + newargv[m++] = wgola[GOLA_SET] ; + newargv[m++] = 0 ; + + pid = main_spawn(newargv) ; + if (wait_pid(pid, &wstat) == -1) + strerr_diefusys(111, "wait for ", newargv[0]) ; + if (wait_estatus(wstat)) + strerr_dief(wait_estatus(wstat), newargv[0], " failed") ; + + /* live install */ + m = 0 ; + newargv[m++] = S6RC_EXTBINPREFIX "s6-rc-set-install" ; + if (g->verbosity != 1) + { + newargv[m++] = "-v" ; + newargv[m++] = fmtv ; + } + newargv[m++] = "-r" ; + newargv[m++] = g->dirs.repo ; + newargv[m++] = "-c" ; + newargv[m++] = g->dirs.boot ; + newargv[m++] = "-l" ; + newargv[m++] = g->dirs.live ; + + if (wgolb & GOLB_BLOCK) newargv[m++] = "-b" ; + if (wgola[GOLA_CONVFILE]) + { + newargv[m++] = "-f" ; + newargv[m++] = wgola[GOLA_CONVFILE] ; + } + newargv[m++] = "--" ; + newargv[m++] = wgola[GOLA_SET] ; + newargv[m++] = 0 ; + + pid = main_spawn(newargv) ; + if (wait_pid(pid, &wstat) == -1) + strerr_diefusys(111, "wait for ", newargv[0]) ; + if (wait_estatus(wstat)) + strerr_dief(wait_estatus(wstat), newargv[0], " failed") ; + + /* live reset */ + m = 0 ; + newargv[m++] = S6RC_EXTBINPREFIX "s6-rc" ; + if (g->verbosity != 1) + { + newargv[m++] = "-v" ; + newargv[m++] = fmtv ; + } + if (timeout) + { + fmtt[uint_fmt(fmtt, timeout)] = 0 ; + newargv[m++] = "-t" ; + newargv[m++] = fmtt ; + } + newargv[m++] = "-pe" ; + newargv[m++] = "-l" ; + newargv[m++] = g->dirs.live ; + if (wgolb & GOLB_BLOCK) newargv[m++] = "-b" ; + newargv[m++] = "--" ; + newargv[m++] = "change" ; + newargv[m++] = wgola[GOLA_DEFBUNDLE] ; + newargv[m++] = 0 ; + main_exec(argv) ; +} diff --git a/src/s6-frontend/set_change.c b/src/s6-frontend/set_change.c index a0db9b7..deefe5e 100644 --- a/src/s6-frontend/set_change.c +++ b/src/s6-frontend/set_change.c @@ -11,9 +11,9 @@ enum golb_e { - GOLB_DRYRUN = 0x02, - GOLB_FAIL_ON_DEPS = 0x04, - GOLB_PULL_DEPS = 0x08, + GOLB_DRYRUN = 0x01, + GOLB_FAIL_ON_DEPS = 0x02, + GOLB_PULL_DEPS = 0x04, } ; enum gola_e -- cgit v1.3.1