From 3b9836248ed7f5164140d63e96ece21973fc43f7 Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Tue, 21 Oct 2025 18:03:48 +0000 Subject: add getserviceflags and use it in fillset; add some doc --- src/include/s6-rc/repo.h | 1 + src/libs6rc/deps-lib/s6rc | 2 +- src/libs6rc/s6rc_repo_fillset.c | 28 ++++--------- src/libs6rc/s6rc_repo_getserviceflags.c | 70 +++++++++++++++++++++++++++++++++ src/libs6rc/s6rc_repo_refcompile.c | 9 ----- src/libs6rc/s6rc_repo_sync.c | 17 ++++---- src/repo/s6-rc-repo-init.c | 5 ++- src/repo/s6-rc-repo-sync.c | 5 ++- src/repo/s6-rc-set-change.c | 2 +- src/repo/s6-rc-set-copy.c | 2 +- 10 files changed, 97 insertions(+), 44 deletions(-) create mode 100644 src/libs6rc/s6rc_repo_getserviceflags.c delete mode 100644 src/libs6rc/s6rc_repo_refcompile.c (limited to 'src') diff --git a/src/include/s6-rc/repo.h b/src/include/s6-rc/repo.h index f611059..ca17b4b 100644 --- a/src/include/s6-rc/repo.h +++ b/src/include/s6-rc/repo.h @@ -50,6 +50,7 @@ extern int s6rc_repo_listdeps (char const *, char const *, stralloc *, genalloc extern int s6rc_repo_listalldeps (char const *, char const *const *, uint32_t, stralloc *, genalloc *, int) ; extern int s6rc_repo_listdeps_internal (char const *, char const *const *, uint32_t, stralloc *, genalloc *, uint32_t) ; +extern int s6rc_repo_getserviceflags (char const *, char const *, uint32_t *) ; extern int s6rc_repo_flattenservices (char const *, char const *const *, uint32_t n, stralloc *storage, genalloc *indices) ; extern int s6rc_repo_makesvlist (char const *, char const *, stralloc *, genalloc *, uint32_t *) ; extern int s6rc_repo_makesvlist_byname (char const *, char const *, stralloc *, genalloc *) ; diff --git a/src/libs6rc/deps-lib/s6rc b/src/libs6rc/deps-lib/s6rc index ea3c4fd..ec22808 100644 --- a/src/libs6rc/deps-lib/s6rc +++ b/src/libs6rc/deps-lib/s6rc @@ -22,6 +22,7 @@ s6rc_repo_compile.o s6rc_repo_fillset.o s6rc_repo_fixset.o s6rc_repo_flattenservices.o +s6rc_repo_getserviceflags.o s6rc_repo_list_sets.o s6rc_repo_listalldeps.o s6rc_repo_listcontents.o @@ -35,7 +36,6 @@ s6rc_repo_makestores.o s6rc_repo_makesvlist.o s6rc_repo_makesvlist_byname.o s6rc_repo_moveservices.o -s6rc_repo_refcompile.o s6rc_repo_setcompile.o s6rc_repo_setuptodate.o s6rc_repo_subnames.o diff --git a/src/libs6rc/s6rc_repo_fillset.c b/src/libs6rc/s6rc_repo_fillset.c index 1b2e2b6..15832c3 100644 --- a/src/libs6rc/s6rc_repo_fillset.c +++ b/src/libs6rc/s6rc_repo_fillset.c @@ -1,6 +1,7 @@ /* ISC license. */ #include +#include #include #include #include @@ -33,37 +34,24 @@ int s6rc_repo_fillset (char const *repo, char const *set, char const *const *exi for (;;) { size_t len ; - unsigned int subi = 1 ; + uint32_t flags ; direntry *d ; + uint8_t subi ; errno = 0 ; d = readdir(dir) ; if (!d) break ; if (d->d_name[0] == '.') continue ; len = strlen(d->d_name) ; - char src[len + 30] ; + char src[len + 13] ; char dst[repolen + 18 + setlen + len] ; memcpy(src, "../.atomics/", 12) ; memcpy(src + 12, d->d_name, len+1) ; if (n && bsearch(d->d_name, existing, n, sizeof(char const *), &str_bcmp)) continue ; - memcpy(src + 12 + len, "/flag-essential", 16) ; - if (access(src, F_OK) == 0) subi = 3 ; - else - { - if (errno != ENOENT) - { - strerr_warnfu2sys("access ", src) ; - break ; - } - memcpy(src + 18 + len, "recommended", 12) ; - if (access(src, F_OK) == 0) subi = 2 ; - else if (errno != ENOENT) - { - strerr_warnfu2sys("access ", src) ; - break ; - } - } - src[12 + len] = 0 ; + if (s6rc_repo_getserviceflags(repo, d->d_name, &flags) <= 0) return 0 ; + if (flags & 1) subi = 3 ; + else if (flags & 2) subi = 2 ; + else subi = 1 ; memcpy(dst, setfn, repolen + 10 + setlen) ; memcpy(dst + repolen + 10 + setlen, s6rc_repo_subnames[subi], 6) ; dst[repolen + setlen + 16] = '/' ; diff --git a/src/libs6rc/s6rc_repo_getserviceflags.c b/src/libs6rc/s6rc_repo_getserviceflags.c new file mode 100644 index 0000000..0ad68e7 --- /dev/null +++ b/src/libs6rc/s6rc_repo_getserviceflags.c @@ -0,0 +1,70 @@ +/* ISC license. */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +int s6rc_repo_getserviceflags (char const *repo, char const *name, uint32_t *flags) +{ + size_t repolen = strlen(repo) ; + ssize_t r ; + pid_t pid ; + int fd ; + int wstat ; + char flagstr[10] ; + char refdb[repolen + 15] ; + char const *argv[8] = { S6RC_BINPREFIX "s6-rc-db", "-c", refdb, "-b", "--", "flags", name, 0 } ; + + memcpy(refdb, repo, repolen) ; + memcpy(refdb + repolen, "/compiled/.ref", 15) ; + pid = child_spawn1_pipe(argv[0], argv, (char const *const *)environ, &fd, 1) ; + if (!pid) { strerr_warnfu2sys("spawn ", argv[0]) ; return -1 ; } + r = readnclose(fd, flagstr, 10) ; + if (r != 9) + { + if (r == 10) goto err ; + else if (r >= 0) errno = EPIPE ; + strerr_warnfu2sys("read output from ", argv[0]) ; + return -1 ; + } + if (wait_pid(pid, &wstat) == -1) + { + strerr_warnfu2sys("wait for ", argv[0]) ; + return -1 ; + } + if (WIFSIGNALED(wstat)) + { + char fmt[UINT_FMT] ; + fmt[uint_fmt(fmt, WTERMSIG(wstat))] = 0 ; + strerr_warnf3x(argv[0], " crashed with signal ", fmt) ; + return -1 ; + } + if (WEXITSTATUS(wstat)) + { + char fmt[UINT_FMT] ; + fmt[uint_fmt(fmt, WEXITSTATUS(wstat))] = 0 ; + strerr_warnf3x(argv[0], " exited with code ", fmt) ; + return (WEXITSTATUS(wstat) < 99) - 1 ; + } + flagstr[8] = 0 ; + if (!uint320_xscan(flagstr, flags)) goto err ; + return 1 ; + + err: + strerr_warnf2x("invalid output from ", S6RC_BINPREFIX "s6-rc-db") ; + errno = EPROTO ; + return -1 ; +} diff --git a/src/libs6rc/s6rc_repo_refcompile.c b/src/libs6rc/s6rc_repo_refcompile.c deleted file mode 100644 index baffe87..0000000 --- a/src/libs6rc/s6rc_repo_refcompile.c +++ /dev/null @@ -1,9 +0,0 @@ -/* ISC license. */ - -#include - -int s6rc_repo_refcompile (char const *repo, char *oldc, unsigned int verbosity, char const *fdhuser) -{ - static char const *const subs[2] = { ".atomics", ".bundles" } ; - return s6rc_repo_compile(repo, ".ref", subs, 2, oldc, verbosity, fdhuser) ; -} diff --git a/src/libs6rc/s6rc_repo_sync.c b/src/libs6rc/s6rc_repo_sync.c index 2ec1356..9458dcb 100644 --- a/src/libs6rc/s6rc_repo_sync.c +++ b/src/libs6rc/s6rc_repo_sync.c @@ -53,13 +53,13 @@ int s6rc_repo_sync (char const *repo, unsigned int verbosity, char const *fdhuse { strerr_warnfu2sys("mkdtemp ", ato) ; umask(m) ; - return 0 ; + return -1 ; } if (chmod(ato, 02755) == -1) { strerr_warnfu2sys("chmod ", ato) ; umask(m) ; - return 0 ; + return -1 ; } if (!mkdtemp(bun)) @@ -67,13 +67,13 @@ int s6rc_repo_sync (char const *repo, unsigned int verbosity, char const *fdhuse strerr_warnfu2sys("mkdtemp ", bun) ; rmdir(ato) ; umask(m) ; - return 0 ; + return -1 ; } umask(m) ; if (chmod(bun, 02755) == -1) { strerr_warnfu2sys("chmod ", bun) ; - return 0 ; + return -1 ; } for (uint16_t istore = 0 ;; istore++) @@ -159,7 +159,8 @@ int s6rc_repo_sync (char const *repo, unsigned int verbosity, char const *fdhuse char const *subs[2] = { ato + repolen + 9, bun + repolen + 9 } ; char oldc[repolen + 49] ; int r = s6rc_repo_compile(repo, ".ref", subs, 2, oldc, verbosity, fdhuser) ; - if (r <= 0) goto err ; + if (r < 0) goto err ; + if (!r) { cleanup(ato, bun) ; return 0 ; } if (r == 2) rm_rf(oldc) ; } @@ -201,7 +202,7 @@ int s6rc_repo_sync (char const *repo, unsigned int verbosity, char const *fdhuse if (!dir) { strerr_warnfu2sys("opendir ", ato) ; - return 0 ; + return -1 ; } for (;;) { @@ -218,7 +219,7 @@ int s6rc_repo_sync (char const *repo, unsigned int verbosity, char const *fdhuse if (errno) { strerr_warnfu2sys("readdir ", ato) ; - return 0 ; + return -1 ; } } @@ -226,5 +227,5 @@ int s6rc_repo_sync (char const *repo, unsigned int verbosity, char const *fdhuse err: cleanup(ato, bun) ; - return 0 ; + return -1 ; } diff --git a/src/repo/s6-rc-repo-init.c b/src/repo/s6-rc-repo-init.c index 335d83f..3c353fe 100644 --- a/src/repo/s6-rc-repo-init.c +++ b/src/repo/s6-rc-repo-init.c @@ -189,7 +189,8 @@ int main (int argc, char const *const *argv) if (!(wgolb & GOLB_BARE)) { - if (!s6rc_repo_sync(wgola[GOLA_REPODIR], verbosity, wgola[GOLA_FDHUSER])) + int r = s6rc_repo_sync(wgola[GOLA_REPODIR], verbosity, wgola[GOLA_FDHUSER]) ; + if (r <= 0) { char stores[repolen + 8] ; char snew[repolen + 16] ; @@ -200,7 +201,7 @@ int main (int argc, char const *const *argv) if (!atomic_symlink4(sold + repolen + 1, stores, snew + repolen + 1, 15)) strerr_diefu7sys(111, "atomically switch back stores at ", wgola[GOLA_REPODIR], " - old store is ", sold + repolen + 1, " and new (invalid) store is ", snew + repolen + 1, " - reported error was") ; rm_rf(snew) ; - _exit(111) ; + _exit(r ? 111 : 1) ; } } diff --git a/src/repo/s6-rc-repo-sync.c b/src/repo/s6-rc-repo-sync.c index 474eec5..ce04d7b 100644 --- a/src/repo/s6-rc-repo-sync.c +++ b/src/repo/s6-rc-repo-sync.c @@ -32,7 +32,7 @@ int main (int argc, char const *const *argv) char const *wgola[GOLA_N] = { 0 } ; unsigned int verbosity = 1 ; unsigned int golc ; - int fdlock ; + int fdlock, r ; PROG = "s6-rc-repo-sync" ; wgola[GOLA_REPODIR] = S6RC_REPO_BASE ; @@ -45,7 +45,8 @@ int main (int argc, char const *const *argv) fdlock = s6rc_repo_lock(wgola[GOLA_REPODIR], 1) ; if (fdlock == -1) strerr_diefu2sys(111, "lock ", wgola[GOLA_REPODIR]) ; - if (!s6rc_repo_sync(wgola[GOLA_REPODIR], verbosity, wgola[GOLA_FDHUSER])) _exit(111) ; + r = s6rc_repo_sync(wgola[GOLA_REPODIR], verbosity, wgola[GOLA_FDHUSER]) ; + if (r <= 0) _exit(r ? 111 : 1) ; if (!s6rc_repo_touch(wgola[GOLA_REPODIR])) _exit(111) ; _exit(0) ; diff --git a/src/repo/s6-rc-set-change.c b/src/repo/s6-rc-set-change.c index 188b11c..2758fa6 100644 --- a/src/repo/s6-rc-set-change.c +++ b/src/repo/s6-rc-set-change.c @@ -127,7 +127,7 @@ int main (int argc, char const *const *argv) newsub = bsearch(argv[1], accepted_subs, sizeof(accepted_subs)/sizeof(struct subname_s), sizeof(struct subname_s), &subname_cmp) ; if (!newsub) strerr_dief2x(100, "unrecognized state change directive:", argv[1]) ; if (newsub->sub == 3 && !(wgolb & GOLB_FORCE_ESSENTIAL)) - strerr_dief1x(100, " artificially mark a service as essential without --force-essential") ; + strerr_diefu1x(10, " artificially mark a service as essential without --force-essential") ; fdlock = s6rc_repo_lock(wgola[GOLA_REPODIR], 1) ; if (fdlock == -1) strerr_diefu2sys(111, "lock ", wgola[GOLA_REPODIR]) ; diff --git a/src/repo/s6-rc-set-copy.c b/src/repo/s6-rc-set-copy.c index 372a23c..3093aaf 100644 --- a/src/repo/s6-rc-set-copy.c +++ b/src/repo/s6-rc-set-copy.c @@ -79,7 +79,7 @@ static inline void docopy (char const *repo, char const *srcname, char const *ds if (r == -1) strerr_diefu2sys(111, "readlink ", dst) ; if (r != dstlen + 8) strerr_dief3x(102, "symlink ", dst, "doesn't point to a valid name") ; } - else strerr_dief4x(100, "set ", dstname, " already exists in repository ", repo) ; + else strerr_dief4x(1, "set ", dstname, " already exists in repository ", repo) ; memcpy(realsrc, src, repolen + 9) ; r = readlink(src, realsrc + repolen + 9, srclen + 9) ; -- cgit v1.3.1