diff options
| author | Laurent Bercot <ska-skaware@skarnet.org> | 2026-06-09 05:27:48 +0000 |
|---|---|---|
| committer | Laurent Bercot <ska-skaware@skarnet.org> | 2026-06-09 05:27:48 +0000 |
| commit | 958958d74337a6ddaf649968d188e768984100e0 (patch) | |
| tree | 7f32dfc1bea9c4d010a344e130707e638620a0fc | |
| parent | 241d2079a25d77e090beb0b767984928dbbc8cd6 (diff) | |
| download | s6-rc-958958d74337a6ddaf649968d188e768984100e0.tar.gz | |
Prepare for 0.6.2.0; implement s6-rc reload
Also support reload-signal in the service definition directory.
| -rw-r--r-- | INSTALL | 2 | ||||
| -rw-r--r-- | NEWS | 5 | ||||
| -rw-r--r-- | doc/index.html | 6 | ||||
| -rw-r--r-- | doc/s6-rc-oneshot-run.html | 4 | ||||
| -rw-r--r-- | doc/s6-rc.html | 21 | ||||
| -rw-r--r-- | doc/upgrade.html | 3 | ||||
| -rw-r--r-- | package/deps-build | 2 | ||||
| -rw-r--r-- | package/info | 2 | ||||
| -rw-r--r-- | src/libs6rc/s6rc_servicedir_internal.c | 1 | ||||
| -rw-r--r-- | src/s6-rc/s6-rc-oneshot-run.c | 7 | ||||
| -rw-r--r-- | src/s6-rc/s6-rc.c | 66 |
11 files changed, 97 insertions, 22 deletions
@@ -8,7 +8,7 @@ Build Instructions - GNU make version 3.81 or later - skalibs version 2.15.0.1 or later: https://skarnet.org/software/skalibs/ - execline version 2.9.9.2 or later: https://skarnet.org/software/execline/ - - s6 version 2.15.0.1 or later: https://skarnet.org/software/s6/ + - s6 version 2.15.1.0 or later: https://skarnet.org/software/s6/ This software will run on any operating system that implements POSIX.1-2024, available at: @@ -1,10 +1,11 @@ Changelog for s6-rc. -In 0.6.1.2 +In 0.6.2.0 ---------- - Bugfixes. - - s6-rc-init is now idempotent and behaves better in pathological situations + - s6-rc-init is now idempotent and behaves better in pathological situations. + - New "s6-rc reload" command. In 0.6.1.1 diff --git a/doc/index.html b/doc/index.html index ed486bf..426bdb5 100644 --- a/doc/index.html +++ b/doc/index.html @@ -55,7 +55,7 @@ requirement if you link against the shared version of the skalibs library. </li> <li> <a href="//skarnet.org/software/execline/">execline</a> version 2.9.9.2 or later. It's a build-time <em>and</em> run-time requirement. </li> <li> <a href="//skarnet.org/software/s6/">s6</a> version -2.15.0.1 or later. It's a build-time <em>and</em> run-time requirement. </li> +2.15.1.0 or later. It's a build-time <em>and</em> run-time requirement. </li> </ul> <h3> Licensing </h3> @@ -69,8 +69,8 @@ requirement if you link against the shared version of the skalibs library. </li> <ul> <li> The current released version of s6-rc is -<a href="s6-rc-0.6.1.2.tar.gz">0.6.1.2</a>. -You can access its checksum <a href="s6-rc-0.6.1.2.tar.gz.sha256">here</a>. </li> +<a href="s6-rc-0.6.2.0.tar.gz">0.6.2.0</a>. +You can access its checksum <a href="s6-rc-0.6.2.0.tar.gz.sha256">here</a>. </li> <li> Alternatively, you can checkout a copy of the <a href="//git.skarnet.org/cgi-bin/cgit.cgi/s6-rc/">s6-rc git repository</a>: diff --git a/doc/s6-rc-oneshot-run.html b/doc/s6-rc-oneshot-run.html index ee454ae..15f10aa 100644 --- a/doc/s6-rc-oneshot-run.html +++ b/doc/s6-rc-oneshot-run.html @@ -34,7 +34,7 @@ in internal scripts created by <h2 id="interface"> Interface </h2> <pre> - s6-rc-oneshot-run [ -l <em>live</em> ] [ -b ] up|down <em>n</em> + s6-rc-oneshot-run [ -l <em>live</em> ] [ -b ] up|down|reload <em>n</em> </pre> <ul> @@ -44,6 +44,8 @@ in the current compiled service database (i.e. the compiled linked from the live directory). </li> <li> <tt>up</tt> or <tt>down</tt> are run with the <tt>RC_NAME</tt> environment variable set to the name of the service. </li> + <li> A <tt>reload</tt> command causes the <tt>up</tt> script to be run, with +an additional <tt>RC_RELOAD</tt> environment variable containing 1. </li> </ul> <h2 id="options"> Options </h2> diff --git a/doc/s6-rc.html b/doc/s6-rc.html index a7eb9d9..bb16113 100644 --- a/doc/s6-rc.html +++ b/doc/s6-rc.html @@ -244,6 +244,27 @@ below. It will run the engine to start a set of services. below. It will run the engine to stop a set of services. </p> +<h3> s6-rc reload </h3> + +<p> + <tt>s6-rc reload</tt> sends a "reload" command to the list of services +given on the command line, which must all be up. For a longrun, +<tt>s6-rc reload</tt> sends an <a href="//skarnet.org/software/s6/s6-svc.html">s6-svc -l</a> +command to the service, which causes it to receive a SIGHUP, or any +overriding signal configured in the <tt>reload-signal</tt> file. +For a oneshot, the service's <tt>up</tt> script is executed, with +an additional <tt>RC_RELOAD</tt> environment variable containing 1. +</p> + +<p> + <tt>s6-rc reload</tt> is special in that it does not use the live state +at all (except to verify that the services the user wants to reload are +indeed up) and does not involve the dependency engine. It only operates on +the services given as arguments on the command line. It is implemented at +the s6-rc level because it is sometimes useful to ask for a <em>oneshot</em> +to be reloaded. +</p> + <h3> s6-rc change </h3> <p> diff --git a/doc/upgrade.html b/doc/upgrade.html index d63dc34..0aac5cf 100644 --- a/doc/upgrade.html +++ b/doc/upgrade.html @@ -31,7 +31,7 @@ minor and bugfix version changes. <h1> What has changed in s6-rc </h1> -<h2> in 0.6.1.2 </h2> +<h2> in 0.6.2.0 </h2> <ul> <li> <a href="//skarnet.org/software/skalibs/">skalibs</a> @@ -40,6 +40,7 @@ dependency bumped to 2.15.0.1. </li> dependency bumped to 2.9.9.2. </li> <li> <a href="//skarnet.org/software/s6/">s6</a> dependency bumped to 2.15.0.1. </li> + <li> New <a href="s6-rc.html">s6-rc reload</a> command. </li> </ul> <h2> in 0.6.1.1 </h2> diff --git a/package/deps-build b/package/deps-build index 842d3a2..c270804 100644 --- a/package/deps-build +++ b/package/deps-build @@ -1,3 +1,3 @@ true true /package/prog/skalibs 2.15.0.1 libskarnet true false /package/admin/execline 2.9.9.2 libexecline -true true /package/admin/s6 2.15.0.1 libs6 +true true /package/admin/s6 2.15.1.0 libs6 diff --git a/package/info b/package/info index bc728bb..0b55290 100644 --- a/package/info +++ b/package/info @@ -1,4 +1,4 @@ package=s6-rc -version=0.6.1.2 +version=0.6.2.0 category=admin package_macro_name=S6RC diff --git a/src/libs6rc/s6rc_servicedir_internal.c b/src/libs6rc/s6rc_servicedir_internal.c index 419fd88..e81f378 100644 --- a/src/libs6rc/s6rc_servicedir_internal.c +++ b/src/libs6rc/s6rc_servicedir_internal.c @@ -25,6 +25,7 @@ static s6_servicedir_desc const svdir_file_list[] = { .name = "timeout-finish", .type = S6_FILETYPE_UINT, .options = 0 }, { .name = "max-death-tally", .type = S6_FILETYPE_UINT, .options = 0 }, { .name = "down-signal", .type = S6_FILETYPE_NORMAL, .options = 0 }, + { .name = "reload-signal", .type = S6_FILETYPE_NORMAL, .options = 0 }, { .name = "flag-newpidns", .type = S6_FILETYPE_EMPTY, .options = 0 }, { .name = "template", .type = S6_FILETYPE_DIR, .options = 0 }, { .name = "data", .type = S6_FILETYPE_DIR, .options = 0 }, diff --git a/src/s6-rc/s6-rc-oneshot-run.c b/src/s6-rc/s6-rc-oneshot-run.c index dbaa38d..dc7bf06 100644 --- a/src/s6-rc/s6-rc-oneshot-run.c +++ b/src/s6-rc/s6-rc-oneshot-run.c @@ -21,6 +21,7 @@ enum golb_e { GOLB_UP = 0x01, GOLB_BLOCK = 0x02, + GOLB_RELOAD = 0x04, } ; enum gola_e @@ -51,6 +52,7 @@ int main (int argc, char const *const *argv) if (!strcasecmp(argv[0], "up")) wgolb |= GOLB_UP ; else if (!strcasecmp(argv[0], "down")) wgolb &= ~GOLB_UP ; + else if (!strcasecmp(argv[0], "reload")) wgolb |= GOLB_UP | GOLB_RELOAD ; else dieusage() ; if (!uint0_scan(argv[1], &number)) dieusage() ; @@ -112,12 +114,13 @@ int main (int argc, char const *const *argv) char const *const *sargv = db.argvs + sv->x.oneshot.argv[!!(wgolb & GOLB_UP)] ; char const *newargv[sargc + 1] ; char const **p = newargv ; - char modif[namelen + 9] ; + char modif[namelen + 21] ; memcpy(modif, "RC_NAME=", 8) ; memcpy(modif + 8, db.string + sv->name, namelen + 1) ; + if (wgolb & GOLB_RELOAD) memcpy(modif + 9 + namelen, "RC_RELOAD=1", 12) ; while (sargc--) *p++ = *sargv++ ; *p = 0 ; - xmexec0_n(newargv, modif, namelen + 9, 1) ; + xmexec0_n(newargv, modif, namelen + (wgolb & GOLB_RELOAD ? 21 : 9), 1 + !!(wgolb & GOLB_RELOAD)) ; } } } diff --git a/src/s6-rc/s6-rc.c b/src/s6-rc/s6-rc.c index 74d48c5..b74b902 100644 --- a/src/s6-rc/s6-rc.c +++ b/src/s6-rc/s6-rc.c @@ -38,6 +38,7 @@ enum what_e WHAT_CHANGE, WHAT_START, WHAT_STOP, + WHAT_RELOAD, } ; struct what_s @@ -182,7 +183,7 @@ static inline pid_t start_oneshot (unsigned int i, int h) newargv[m++] = tfmt ; newargv[m++] = "--" ; newargv[m++] = socketfn ; - newargv[m++] = h ? "up" : "down" ; + newargv[m++] = h == 3 ? "reload" : h ? "up" : "down" ; newargv[m++] = ifmt ; if (dryrun[0]) { @@ -227,7 +228,7 @@ static inline pid_t start_longrun (unsigned int i, int h) newargv[m++] = "--" ; } newargv[m++] = S6_EXTBINPREFIX "s6-svc" ; - newargv[m++] = h ? h == 2 ? "-uwu" : "-uwU" : "-dwD" ; + newargv[m++] = h == 3 ? "-l" : h ? h == 2 ? "-uwu" : "-uwU" : "-dwD" ; newargv[m++] = "-T" ; newargv[m++] = fmt ; newargv[m++] = "--" ; @@ -266,7 +267,7 @@ static inline void success_longrun (unsigned int i, int h) static inline void failure_longrun (unsigned int i, int h) { - if (h && !dryrun[0]) + if (!dryrun[0]) { size_t svdlen = strlen(db->string + db->services[i].name) ; char fn[livelen + svdlen + 14] ; @@ -333,22 +334,25 @@ static void broadcast_success (unsigned int i, int h) static inline void on_success (unsigned int i, int h) { - if (i < db->nlong) success_longrun(i, h) ; - if (h) state[i] |= 1 ; else state[i] &= 254 ; - announce() ; + if (h != 3) + { + if (i < db->nlong) success_longrun(i, h) ; + if (h) state[i] |= 1 ; else state[i] &= 254 ; + announce() ; + } if (verbosity >= 2) - strerr_warni5x(dryrun[0] ? "dry run: " : "", "service ", db->string + db->services[i].name, " successfully st", h ? "arted" : "opped") ; - if (!lameduck) broadcast_success(i, h) ; + strerr_warni5x(dryrun[0] ? "dry run: " : "", "service ", db->string + db->services[i].name, " successfully ", h == 3 ? "reloaded" : h ? "started" : "stopped") ; + if (!lameduck && h != 3) broadcast_success(i, h) ; } static inline void on_failure (unsigned int i, int h, int crashed, unsigned int code) { - if (i < db->nlong) failure_longrun(i, h) ; + if (h != 3 && i < db->nlong) failure_longrun(i, h) ; if (verbosity) { char fmt[UINT_FMT] ; fmt[uint_fmt(fmt, code)] = 0 ; - strerr_warnwu7x(dryrun[0] ? "(dry run) " : "", h ? "start" : "stop", " service ", db->string + db->services[i].name, ": command ", crashed ? "crashed with signal " : "exited ", fmt) ; + strerr_warnwu7x(dryrun[0] ? "(dry run) " : "", h == 3 ? "reload" : h ? "start" : "stop", " service ", db->string + db->services[i].name, ": command ", crashed ? "crashed with signal " : "exited ", fmt) ; } } @@ -457,6 +461,38 @@ static void invert_selection (void) while (i--) state[i] ^= 2 ; } +static int reload (void) +{ + iopause_fd x = { .fd = selfpipe_fd(), .events = IOPAUSE_READ } ; + int exitcode = 0 ; + unsigned int i = n ; + pidindex_t pidindexblob[n] ; + pidindex = pidindexblob ; + + while (i--) if (state[i] & 2) + { + pid_t pid ; + if (!(state[i] & 1)) + { + if (verbosity) strerr_warnw("service ", db->string + db->services[i].name, " is down - not reloading") ; + continue ; + } + pid = i < db->nlong ? start_longrun(i, 3) : start_oneshot(i, 3) ; + if (!pid) strerr_diefusys(111, "send reload command to service ", db->string + db->services[i].name) ; + pidindex[npids].pid = pid ; + pidindex[npids++].i = i ; + } + + while (npids) + { + int r = iopause_g(&x, 1, &deadline) ; + if (r < 0) strerr_diefu1sys(111, "iopause") ; + if (!r) strerr_dief(2, "timed out") ; + if (!handle_signals(3)) exitcode = 1 ; + } + return exitcode ; +} + static inline enum what_e parse_command (char const *command) { static struct what_s const command_table[] = @@ -466,6 +502,7 @@ static inline enum what_e parse_command (char const *command) { .s = "help", .e = WHAT_HELP }, { .s = "list", .e = WHAT_LIST }, { .s = "listall", .e = WHAT_LISTALL }, + { .s = "reload", .e = WHAT_RELOAD }, { .s = "start", .e = WHAT_START }, { .s = "stop", .e = WHAT_STOP }, } ; @@ -660,6 +697,15 @@ int main (int argc, char const *const *argv) close(fdcompiled) ; + /* s6-rc reload */ + + if (what == WHAT_RELOAD) + { + if (!argc) strerr_dief(100, "reload: too few arguments") ; + _exit(reload()) ; + } + + /* Add live state to selection */ if (wgolb & GOLB_SELECTLIVE) |
