diff options
| author | Laurent Bercot <ska-skaware@skarnet.org> | 2026-10-05 18:03:35 +0000 |
|---|---|---|
| committer | Laurent Bercot <ska-skaware@skarnet.org> | 2026-10-05 18:03:35 +0000 |
| commit | f706ab3b309a4c9a0425ac23d5ffff7ead48fcb2 (patch) | |
| tree | 741b3d5367b083a53b9cde74d6a6427eb310f307 | |
| parent | 9f4ba23454acf1d3925ffb7ea2123c9b19c2bf24 (diff) | |
| download | s6-rc-f706ab3b309a4c9a0425ac23d5ffff7ead48fcb2.tar.gz | |
Add -L catchall to s6-rc-compile and s6-rc-fdholder-filler
| -rw-r--r-- | NEWS | 3 | ||||
| -rw-r--r-- | doc/s6-rc-compile.html | 7 | ||||
| -rw-r--r-- | doc/s6-rc-fdholder-filler.html | 4 | ||||
| -rw-r--r-- | src/s6-rc/s6-rc-compile.c | 25 | ||||
| -rw-r--r-- | src/s6-rc/s6-rc-fdholder-filler.c | 142 |
5 files changed, 123 insertions, 58 deletions
@@ -4,7 +4,8 @@ In 0.7.1.0 ---------- - Bugfixes. - - Databases now embed the major version they were built with + - Databases now embed the major version they were built with. + - New -L option to s6-rc-compile. (and s6-rc-fdholder-filler) In 0.7.0.0 diff --git a/doc/s6-rc-compile.html b/doc/s6-rc-compile.html index fc4a9c6..09e71d6 100644 --- a/doc/s6-rc-compile.html +++ b/doc/s6-rc-compile.html @@ -37,7 +37,7 @@ the current service database via <h2> Interface </h2> <pre> - s6-rc-compile [ -v <em>verbosity</em> ] [ -h <em>fdhuser</em> ] [ -b ] <em>compiled</em> <em>source...</em> + s6-rc-compile [ -v <em>verbosity</em> ] [ -h <em>fdhuser</em> ] [ -L <em>catchall</em> ] [ -b ] <em>compiled</em> <em>source...</em> </pre> <ul> @@ -70,6 +70,11 @@ what s6-rc-compile is doing. 3 or more is heavy debug output. </li> program, which maintains the pipes for the longrun pipelines, to run as user <em>fdhuser</em>. By default, it runs as the user owning the supervision tree, i.e. most likely <tt>root</tt>. </li> + <li> <tt>-L <em>catchall</em></tt> : assume that a catch-all +logger service will be running on <em>catchall</em> and ensure that its +fifo is properly held in the fdholder (which avoids services getting killed +by SIGPIPE if they're writing uncaught logs while the catch-all logger is +restarting). </li> <li> <tt>-b</tt> : make <a href="s6-rc-oneshot-run.html">s6-rc-oneshot-run</a> invocations wait instead of fail on lock contention. This diff --git a/doc/s6-rc-fdholder-filler.html b/doc/s6-rc-fdholder-filler.html index 5f47ec4..b160573 100644 --- a/doc/s6-rc-fdholder-filler.html +++ b/doc/s6-rc-fdholder-filler.html @@ -35,7 +35,7 @@ in internal scripts created by <h2> Interface </h2> <pre> - s6-rc-fdholder-filler [ -1 ] [ -t <em>timeout</em> ] < <em>longrunnamesfile</em> + s6-rc-fdholder-filler [ -1 ] [ -t <em>timeout</em> ] [ -L <em>catchall</em> ] < <em>longrunnamesfile</em> </pre> <ul> @@ -63,6 +63,8 @@ successful operation. This is used as a notification mechanism. </li> <li> <tt>-t <em>timeout</em></tt> : if the operation cannot be achieved in <em>timeout</em> milliseconds, abort and report failure. By default, <em>timeout</em> is 0, meaning infinite. </li> + <li> <tt>-L <em>catchall</em></tt> : also store the fifo for +the catch-all logger whose service directory is <em>catchall</em>. </li> </ul> <h2> Exit codes </h2> diff --git a/src/s6-rc/s6-rc-compile.c b/src/s6-rc/s6-rc-compile.c index 83e751c..0bfe4d7 100644 --- a/src/s6-rc/s6-rc-compile.c +++ b/src/s6-rc/s6-rc-compile.c @@ -21,7 +21,7 @@ #include <s6-rc/config.h> #include <s6-rc/s6rc.h> -#define USAGE "s6-rc-compile [ -v verbosity ] [ -h fdholder_user ] [ -b ] destdir sources..." +#define USAGE "s6-rc-compile [ -v verbosity ] [ -h fdholder-user ] [ -L catchall-logger ] [ -b ] destdir sources..." #define dieusage() strerr_dieusage(100, USAGE) #define dienomem() strerr_dief(111, "out of memory") ; @@ -36,6 +36,7 @@ enum gola_e { GOLA_VERBOSITY, GOLA_FDHUSER, + GOLA_CATCHALL, GOLA_N } ; @@ -1122,7 +1123,7 @@ static inline void write_oneshot_runner (char const *compiled, int blocking) auto_rights(compiled, "servicedirs/" S6RC_ONESHOT_RUNNER "/run", 0755) ; } -static inline void write_fdholder (char const *compiled, s6rc_db_t const *db, char const *fdhuser) +static inline void write_fdholder (char const *compiled, s6rc_db_t const *db, char const *fdhuser, char const *catchall) { unsigned int nfds = 0 ; size_t base = satmp.len ; @@ -1163,7 +1164,14 @@ static inline void write_fdholder (char const *compiled, s6rc_db_t const *db, ch EXECLINE_EXTBINPREFIX "if -nt --\n {\n " EXECLINE_EXTBINPREFIX "redirfd -r 0 ./data/autofilled\n " S6_EXTBINPREFIX "s6-ipcclient -l0 -- s\n " - S6RC_EXTLIBEXECPREFIX "s6-rc-fdholder-filler -1 --\n }\n " + S6RC_EXTLIBEXECPREFIX "s6-rc-fdholder-filler -1 ")) goto err ; + if (catchall) + { + if (!stralloc_cats(&satmp, "-L ") + || !string_quote(&satmp, catchall, strlen(catchall)) + || !stralloc_catb(&satmp, " ", 1)) goto err ; + } + if (!stralloc_cats(&satmp, "--\n }\n " S6_EXTBINPREFIX "s6-svc -t .\n}\n")) goto err ; if (fdhuser) { @@ -1619,6 +1627,7 @@ static inline void write_compiled ( unsigned int nbundles, uint32_t const *bdeps, char const *fdhuser, + char const *catchall, int blocking) { if (verbosity >= 2) strerr_warni("writing compiled information to ", compiled) ; @@ -1629,7 +1638,7 @@ static inline void write_compiled ( stralloc_free(&data) ; write_db(compiled, db) ; write_oneshot_runner(compiled, blocking) ; - write_fdholder(compiled, db, fdhuser) ; + write_fdholder(compiled, db, fdhuser, catchall) ; write_servicedirs(compiled, db, srcdirs) ; } @@ -1643,6 +1652,7 @@ int main (int argc, char const *const *argv) { { .so = 'v', .lo = "verbosity", .i = GOLA_VERBOSITY }, { .so = 'h', .lo = "fdholder-user", .i = GOLA_FDHUSER }, + { .so = 'L', .lo = "catchall-logger", .i = GOLA_CATCHALL }, } ; before_t before = BEFORE_ZERO ; uint64_t wgolb = 0 ; @@ -1659,6 +1669,11 @@ int main (int argc, char const *const *argv) if (!uint0_scan(wgola[GOLA_VERBOSITY], &verbosity)) strerr_dief(100, "verbosity must be an unsigned integer") ; } + if (wgola[GOLA_CATCHALL]) + { + if (wgola[GOLA_CATCHALL][0] != '/') + strerr_dief(100, "catchall-logger must be an absolute path") ; + } compiled = *argv++ ; before.specialdeps[0] = add_internal_longrun(&before, S6RC_ONESHOT_RUNNER) ; @@ -1707,7 +1722,7 @@ int main (int argc, char const *const *argv) db.deps = deps ; flatlist_services(&db, sarray) ; propagate_bundle_flags(&db, bundles, nbundles, bdeps) ; - write_compiled(compiled, &db, srcdirs, bundles, nbundles, bdeps, wgola[GOLA_FDHUSER], wgolb & GOLB_BLOCK) ; + write_compiled(compiled, &db, srcdirs, bundles, nbundles, bdeps, wgola[GOLA_FDHUSER], wgola[GOLA_CATCHALL], wgolb & GOLB_BLOCK) ; } } diff --git a/src/s6-rc/s6-rc-fdholder-filler.c b/src/s6-rc/s6-rc-fdholder-filler.c index a64a7f1..37d1945 100644 --- a/src/s6-rc/s6-rc-fdholder-filler.c +++ b/src/s6-rc/s6-rc-fdholder-filler.c @@ -6,20 +6,36 @@ #include <errno.h> #include <skalibs/types.h> -#include <skalibs/sgetopt.h> +#include <skalibs/gol.h> +#include <skalibs/prog.h> #include <skalibs/strerr.h> #include <skalibs/allreadwrite.h> #include <skalibs/tai.h> #include <skalibs/buffer.h> +#include <skalibs/djbunix.h> #include <skalibs/stralloc.h> #include <skalibs/genalloc.h> #include <s6/fdholder.h> -#define USAGE "s6-rc-fdholder-filler [ -1 ] [ -t timeout ] < autofilled-filename" +#include <s6-rc/config.h> + +#define USAGE "s6-rc-fdholder-filler [ -1 ] [ -t timeout ] [ -L catchall-logger ] < autofilled-filename" #define dieusage() strerr_dieusage(100, USAGE) #define dienomem() strerr_diefu1sys(111, "stralloc_catb") +enum golb_e +{ + GOLB_1 = 0x1, +} ; + +enum gola_e +{ + GOLA_TIMEOUT, + GOLA_CATCHALL, + GOLA_N, +} ; + static inline uint8_t cclass (char c) { switch (c) @@ -64,71 +80,97 @@ static inline void parse_servicenames (stralloc *sa, genalloc *g) int main (int argc, char const *const *argv) { + static gol_bool const rgolb[1] = + { + { .so = '1', .lo = "notify-stdout", .clear = 0, .set = GOLB_1 }, + } ; + static gol_arg const rgola[GOLA_N] = + { + { .so = 't', .lo = "timeout", .i = GOLA_TIMEOUT }, + { .so = 'L', .lo = "catchall-logger", .i = GOLA_CATCHALL }, + } ; s6_fdholder_t a = S6_FDHOLDER_ZERO ; stralloc sa = STRALLOC_ZERO ; genalloc ga = GENALLOC_ZERO ; /* size_t */ size_t n ; size_t const *indices ; - tain deadline ; - int notif = 0 ; + tain deadline = TAIN_INFINITE_RELATIVE ; + uint64_t wgolb = 0 ; + char const *wgola[GOLA_N] = { 0 } ; + tain offset = { .sec = TAI_ZERO } ; + int p[2] ; + size_t m = 0 ; PROG = "s6-rc-fdholder-filler" ; + + { + unsigned int golc = GOL_main(argc, argv, rgolb, rgola, &wgolb, wgola) ; + argc -= golc ; argv += golc ; + } + if (wgola[GOLA_TIMEOUT]) { unsigned int t = 0 ; - subgetopt l = SUBGETOPT_ZERO ; - for (;;) - { - int opt = subgetopt_r(argc, argv, "1t:", &l) ; - if (opt == -1) break ; - switch (opt) - { - case '1': notif = 1 ; break ; - case 't': if (!uint0_scan(l.arg, &t)) dieusage() ; break ; - default : dieusage() ; - } - } - argc -= l.ind ; argv += l.ind ; + if (!uint0_scan(wgola[GOLA_TIMEOUT], &t)) + strerr_dief(100, "timeout must be an unsigned integer") ; if (t) tain_from_millisecs(&deadline, t) ; - else deadline = tain_infinite_relative ; + } + if (wgola[GOLA_CATCHALL]) + { + if (wgola[GOLA_CATCHALL][0] != '/') + strerr_dief(100, "catchall-logger must be an absolute path") ; } parse_servicenames(&sa, &ga) ; n = genalloc_len(size_t, &ga) ; indices = genalloc_s(size_t, &ga) ; - if (n) + + s6_fdholder_fd_t dump[1 + (n<<1)] ; + + close(0) ; + s6_fdholder_init(&a, 6) ; + tain_now_set_stopwatch_g() ; + tain_add_g(&deadline, &deadline) ; + + if (wgola[GOLA_CATCHALL]) { - tain offset = { .sec = TAI_ZERO } ; - int p[2] ; - size_t i = 0 ; - s6_fdholder_fd_t dump[n<<1] ; - close(0) ; - s6_fdholder_init(&a, 6) ; - tain_now_set_stopwatch_g() ; - tain_add_g(&deadline, &deadline) ; - for (; i < n ; i++) + size_t len = strlen(wgola[GOLA_CATCHALL]) ; + char fn[len + 6] ; + memcpy(fn, wgola[GOLA_CATCHALL], len) ; + memcpy(fn + len, "/fifo", 6) ; + dump[m].fd = open_read(fn) ; + if (dump[m].fd >= 0) { - size_t len = strlen(sa.s + indices[i]) ; - if (len + 12 > S6_FDHOLDER_ID_SIZE) - { - errno = ENAMETOOLONG ; - strerr_diefu2sys(111, "create identifier for ", sa.s + indices[i]) ; - } - if (pipe(p) < 0) - strerr_diefu1sys(111, "create pipe") ; - dump[i<<1].fd = p[0] ; - tain_add_g(&dump[i<<1].limit, &tain_infinite_relative) ; - offset.nano = i << 1 ; - tain_add(&dump[i<<1].limit, &dump[i<<1].limit, &offset) ; - memcpy(dump[i<<1].id, "pipe:s6rc-r-", 12) ; - memcpy(dump[i<<1].id + 12, sa.s + indices[i], len + 1) ; - dump[(i<<1)+1].fd = p[1] ; - offset.nano = 1 ; - tain_add(&dump[(i<<1)+1].limit, &dump[i<<1].limit, &offset) ; - memcpy(dump[(i<<1)+1].id, dump[i<<1].id, 13 + len) ; - dump[(i<<1)+1].id[10] = 'w' ; + tain_add_g(&dump[m].limit, &tain_infinite_relative) ; + memcpy(dump[m].id, "pipe:s6-rc-r/s6-svscan-log", 27) ; + m++ ; } - if (!s6_fdholder_setdump_g(&a, dump, n << 1, &deadline)) - strerr_diefu1sys(111, "transfer pipes") ; } - if (notif) write(1, "\n", 1) ; + for (size_t i = 0 ; i < n ; i++) + { + size_t len = strlen(sa.s + indices[i]) ; + if (len + 12 > S6_FDHOLDER_ID_SIZE) + { + errno = ENAMETOOLONG ; + strerr_diefusys(111, "create identifier for ", sa.s + indices[i]) ; + } + if (pipe(p) == -1) strerr_diefu1sys(111, "create pipe") ; + dump[m].fd = p[0] ; + tain_add_g(&dump[m].limit, &tain_infinite_relative) ; + offset.nano = m ; + tain_add(&dump[m].limit, &dump[m].limit, &offset) ; + memcpy(dump[m].id, "pipe:s6rc-r-", 12) ; + memcpy(dump[m].id + 12, sa.s + indices[i], len + 1) ; + m++ ; + dump[m].fd = p[1] ; + offset.nano = 1 ; + tain_add(&dump[m].limit, &dump[m-1].limit, &offset) ; + memcpy(dump[m].id, dump[m-1].id, 13 + len) ; + dump[m].id[10] = 'w' ; + m++ ; + } + + if (!s6_fdholder_setdump_g(&a, dump, m, &deadline)) + strerr_diefusys(111, "transfer pipes") ; + + if (wgolb & GOLB_1) write(1, "\n", 1) ; return 0 ; } |
