diff options
author | Laurent Bercot <ska-skaware@skarnet.org> | 2017-10-08 15:39:57 +0000 |
---|---|---|
committer | Laurent Bercot <ska-skaware@skarnet.org> | 2017-10-08 15:39:57 +0000 |
commit | f9940bb7d1a6ce7d7772e8cbdbbd55a321cc5c18 (patch) | |
tree | 352798ff6073e18a467a9ffeab548485070dc568 | |
parent | 8c341bbaca5e89a9620702bc0025641e815e4195 (diff) | |
download | s6-rc-f9940bb7d1a6ce7d7772e8cbdbbd55a321cc5c18.tar.xz |
Add -s to s6-rc-init; prepare for 0.3.0.0
-rw-r--r-- | NEWS | 6 | ||||
-rw-r--r-- | doc/index.html | 2 | ||||
-rw-r--r-- | doc/s6-rc-init.html | 11 | ||||
-rw-r--r-- | doc/upgrade.html | 4 | ||||
-rw-r--r-- | package/deps.mak | 8 | ||||
-rw-r--r-- | package/info | 2 | ||||
-rw-r--r-- | src/include/s6-rc/s6rc-servicedir.h | 6 | ||||
-rw-r--r-- | src/include/s6-rc/s6rc-utils.h | 3 | ||||
-rw-r--r-- | src/libs6rc/deps-lib/s6rc | 2 | ||||
-rw-r--r-- | src/libs6rc/s6rc_livedir_suffix.c | 19 | ||||
-rw-r--r-- | src/libs6rc/s6rc_livedir_suffixsize.c | 24 | ||||
-rw-r--r-- | src/libs6rc/s6rc_read_uint.c | 1 | ||||
-rw-r--r-- | src/libs6rc/s6rc_servicedir_manage.c | 16 | ||||
-rw-r--r-- | src/libs6rc/s6rc_servicedir_unsupervise.c | 10 | ||||
-rw-r--r-- | src/s6-rc/s6-rc-init.c | 34 | ||||
-rw-r--r-- | src/s6-rc/s6-rc-update.c | 82 | ||||
-rw-r--r-- | src/s6-rc/s6-rc.c | 39 |
17 files changed, 192 insertions, 77 deletions
@@ -1,8 +1,12 @@ Changelog for s6-rc. -In 0.2.2.0 +In 0.3.0.0 ---------- + - s6-rc-init now takes a -s option that adds a suffix to the symbolic links +created in the scandir to manage longruns. This allows the user to use the +same scandir for several s6-rc databases and live directories without risking +conflicts, if the suffixes are unique enough. - Bugfixes. diff --git a/doc/index.html b/doc/index.html index 4f501ab..544fa85 100644 --- a/doc/index.html +++ b/doc/index.html @@ -66,7 +66,7 @@ scripts are also run in a controlled environment. <ul> <li> The current released version of s6-rc is -<a href="s6-rc-0.2.2.0.tar.gz">0.2.2.0</a>. </li> +<a href="s6-rc-0.3.0.0.tar.gz">0.3.0.0</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-init.html b/doc/s6-rc-init.html index f3a7bb1..c531ad6 100644 --- a/doc/s6-rc-init.html +++ b/doc/s6-rc-init.html @@ -28,7 +28,7 @@ invocation of the <h2> Interface </h2> <pre> - s6-rc-init [ -c <em>compiled</em> ] [ -l <em>live</em> ] [ -t <em>timeout</em> ] [ -b ] <em>scandir</em> + s6-rc-init [ -c <em>compiled</em> ] [ -l <em>live</em> ] [ -s <em>suffix</em> ] [ -t <em>timeout</em> ] [ -b ] <em>scandir</em> </pre> <ul> @@ -74,6 +74,15 @@ filesystem. Default is <tt>/run/s6-rc</tt>. The default can be changed at compile time by giving the <tt>--livedir=<em>live</em></tt> option to <tt>./configure</tt>. </li> + <li> <tt>-s <em>suffix</em></tt> : when linking all the +service directory into <em>scandir</em>, add <em>suffix</em> to the +names of the symbolic links. This allows several live directories +to be used with a unique scandir without risking conflicts between +longruns that would have the same name. This option is only useful +if you intend to have several sets of services independently managed +by s6-rc, with different live directories, all using the same scandir +to supervise their longruns. The default is no suffix at all, which +is best when you only have one live directory. </li> <li> <tt>-b</tt> : blocking lock. If the database is currently being used by another program, s6-rc-init will wait until that other program has released its lock on the database, then proceed. diff --git a/doc/upgrade.html b/doc/upgrade.html index fb0f3c8..d48cb98 100644 --- a/doc/upgrade.html +++ b/doc/upgrade.html @@ -30,7 +30,7 @@ minor and bugfix version changes. <h1> What has changed in s6-rc </h1> -<h2> in 0.2.2.0 </h2> +<h2> in 0.3.0.0 </h2> <ul> <li> <a href="//skarnet.org/software/skalibs/">skalibs</a> @@ -39,6 +39,8 @@ dependency bumped to 2.6.0.1. </li> dependency bumped to 2.3.0.3. </li> <li> <a href="//skarnet.org/software/s6/">s6</a> dependency bumped to 2.6.1.1. </li> + <li> New <tt>-s</tt> option to <a href="s6-rc-init.html">s6-rc-init</a> +to allow using several live directories with the same scandir. </li> </ul> <h2> in 0.2.1.2 </h2> diff --git a/package/deps.mak b/package/deps.mak index 054d439..ba322f2 100644 --- a/package/deps.mak +++ b/package/deps.mak @@ -11,8 +11,10 @@ src/libs6rc/s6rc_db_read.o src/libs6rc/s6rc_db_read.lo: src/libs6rc/s6rc_db_read src/libs6rc/s6rc_db_read_sizes.o src/libs6rc/s6rc_db_read_sizes.lo: src/libs6rc/s6rc_db_read_sizes.c src/include/s6-rc/s6rc-db.h src/libs6rc/s6rc_db_read_uint32.o src/libs6rc/s6rc_db_read_uint32.lo: src/libs6rc/s6rc_db_read_uint32.c src/include/s6-rc/s6rc-db.h src/libs6rc/s6rc_graph_closure.o src/libs6rc/s6rc_graph_closure.lo: src/libs6rc/s6rc_graph_closure.c src/include/s6-rc/s6rc-db.h src/include/s6-rc/s6rc-utils.h +src/libs6rc/s6rc_livedir_suffix.o src/libs6rc/s6rc_livedir_suffix.lo: src/libs6rc/s6rc_livedir_suffix.c src/include/s6-rc/s6rc-utils.h +src/libs6rc/s6rc_livedir_suffixsize.o src/libs6rc/s6rc_livedir_suffixsize.lo: src/libs6rc/s6rc_livedir_suffixsize.c src/include/s6-rc/s6rc-utils.h src/libs6rc/s6rc_lock.o src/libs6rc/s6rc_lock.lo: src/libs6rc/s6rc_lock.c src/include/s6-rc/s6rc-utils.h -src/libs6rc/s6rc_read_uint.o src/libs6rc/s6rc_read_uint.lo: src/libs6rc/s6rc_read_uint.c +src/libs6rc/s6rc_read_uint.o src/libs6rc/s6rc_read_uint.lo: src/libs6rc/s6rc_read_uint.c src/include/s6-rc/s6rc-utils.h src/libs6rc/s6rc_sanitize_dir.o src/libs6rc/s6rc_sanitize_dir.lo: src/libs6rc/s6rc_sanitize_dir.c src/include/s6-rc/s6rc-utils.h src/libs6rc/s6rc_servicedir_block.o src/libs6rc/s6rc_servicedir_block.lo: src/libs6rc/s6rc_servicedir_block.c src/include/s6-rc/s6rc-servicedir.h src/libs6rc/s6rc_servicedir_copy_offline.o src/libs6rc/s6rc_servicedir_copy_offline.lo: src/libs6rc/s6rc_servicedir_copy_offline.c src/include/s6-rc/s6rc-servicedir.h src/libs6rc/s6rc-servicedir-internal.h @@ -31,9 +33,9 @@ src/s6-rc/s6-rc-oneshot-run.o src/s6-rc/s6-rc-oneshot-run.lo: src/s6-rc/s6-rc-on src/s6-rc/s6-rc-update.o src/s6-rc/s6-rc-update.lo: src/s6-rc/s6-rc-update.c src/include/s6-rc/config.h src/include/s6-rc/s6rc.h src/s6-rc/s6-rc.o src/s6-rc/s6-rc.lo: src/s6-rc/s6-rc.c src/include/s6-rc/config.h src/include/s6-rc/s6rc.h -libs6rc.a.xyzzy: src/libs6rc/s6rc_db_check_depcycles.o src/libs6rc/s6rc_db_check_pipelines.o src/libs6rc/s6rc_db_check_revdeps.o src/libs6rc/s6rc_db_read.o src/libs6rc/s6rc_db_read_sizes.o src/libs6rc/s6rc_db_read_uint32.o src/libs6rc/s6rc_graph_closure.o src/libs6rc/s6rc_lock.o src/libs6rc/s6rc_read_uint.o src/libs6rc/s6rc_sanitize_dir.o src/libs6rc/s6rc_servicedir_internal.o src/libs6rc/s6rc_servicedir_block.o src/libs6rc/s6rc_servicedir_unblock.o src/libs6rc/s6rc_servicedir_copy_offline.o src/libs6rc/s6rc_servicedir_copy_online.o src/libs6rc/s6rc_servicedir_manage.o src/libs6rc/s6rc_servicedir_unsupervise.o +libs6rc.a.xyzzy: src/libs6rc/s6rc_db_check_depcycles.o src/libs6rc/s6rc_db_check_pipelines.o src/libs6rc/s6rc_db_check_revdeps.o src/libs6rc/s6rc_db_read.o src/libs6rc/s6rc_db_read_sizes.o src/libs6rc/s6rc_db_read_uint32.o src/libs6rc/s6rc_graph_closure.o src/libs6rc/s6rc_livedir_suffix.o src/libs6rc/s6rc_livedir_suffixsize.o src/libs6rc/s6rc_lock.o src/libs6rc/s6rc_read_uint.o src/libs6rc/s6rc_sanitize_dir.o src/libs6rc/s6rc_servicedir_internal.o src/libs6rc/s6rc_servicedir_block.o src/libs6rc/s6rc_servicedir_unblock.o src/libs6rc/s6rc_servicedir_copy_offline.o src/libs6rc/s6rc_servicedir_copy_online.o src/libs6rc/s6rc_servicedir_manage.o src/libs6rc/s6rc_servicedir_unsupervise.o libs6rc.so.xyzzy: EXTRA_LIBS := -ls6 -lskarnet -libs6rc.so.xyzzy: src/libs6rc/s6rc_db_check_depcycles.lo src/libs6rc/s6rc_db_check_pipelines.lo src/libs6rc/s6rc_db_check_revdeps.lo src/libs6rc/s6rc_db_read.lo src/libs6rc/s6rc_db_read_sizes.lo src/libs6rc/s6rc_db_read_uint32.lo src/libs6rc/s6rc_graph_closure.lo src/libs6rc/s6rc_lock.lo src/libs6rc/s6rc_read_uint.lo src/libs6rc/s6rc_sanitize_dir.lo src/libs6rc/s6rc_servicedir_internal.lo src/libs6rc/s6rc_servicedir_block.lo src/libs6rc/s6rc_servicedir_unblock.lo src/libs6rc/s6rc_servicedir_copy_offline.lo src/libs6rc/s6rc_servicedir_copy_online.lo src/libs6rc/s6rc_servicedir_manage.lo src/libs6rc/s6rc_servicedir_unsupervise.lo +libs6rc.so.xyzzy: src/libs6rc/s6rc_db_check_depcycles.lo src/libs6rc/s6rc_db_check_pipelines.lo src/libs6rc/s6rc_db_check_revdeps.lo src/libs6rc/s6rc_db_read.lo src/libs6rc/s6rc_db_read_sizes.lo src/libs6rc/s6rc_db_read_uint32.lo src/libs6rc/s6rc_graph_closure.lo src/libs6rc/s6rc_livedir_suffix.lo src/libs6rc/s6rc_livedir_suffixsize.lo src/libs6rc/s6rc_lock.lo src/libs6rc/s6rc_read_uint.lo src/libs6rc/s6rc_sanitize_dir.lo src/libs6rc/s6rc_servicedir_internal.lo src/libs6rc/s6rc_servicedir_block.lo src/libs6rc/s6rc_servicedir_unblock.lo src/libs6rc/s6rc_servicedir_copy_offline.lo src/libs6rc/s6rc_servicedir_copy_online.lo src/libs6rc/s6rc_servicedir_manage.lo src/libs6rc/s6rc_servicedir_unsupervise.lo s6-rc: EXTRA_LIBS := ${TAINNOW_LIB} ${SPAWN_LIB} s6-rc: src/s6-rc/s6-rc.o ${LIBS6RC} -lskarnet s6-rc-bundle: EXTRA_LIBS := diff --git a/package/info b/package/info index 5a92bbe..436da19 100644 --- a/package/info +++ b/package/info @@ -1,4 +1,4 @@ package=s6-rc -version=0.2.2.0 +version=0.3.0.0 category=admin package_macro_name=S6RC diff --git a/src/include/s6-rc/s6rc-servicedir.h b/src/include/s6-rc/s6rc-servicedir.h index ed2f471..1648975 100644 --- a/src/include/s6-rc/s6rc-servicedir.h +++ b/src/include/s6-rc/s6rc-servicedir.h @@ -10,9 +10,9 @@ extern int s6rc_servicedir_unblock (char const *, int) ; extern int s6rc_servicedir_copy_offline (char const *, char const *) ; extern int s6rc_servicedir_copy_online (char const *, char const *) ; #define s6rc_servicedir_copy(src, dst, h) ((h) ? s6rc_servicedir_copy_online(src, dst) : s6rc_servicedir_copy_offline(src, dst)) -extern void s6rc_servicedir_unsupervise (char const *, char const *, int) ; +extern void s6rc_servicedir_unsupervise (char const *, char const *, char const *, int) ; -extern int s6rc_servicedir_manage (char const *, tain_t const *, tain_t *) ; -#define s6rc_servicedir_manage_g(live, deadline) s6rc_servicedir_manage(live, (deadline), &STAMP) +extern int s6rc_servicedir_manage (char const *, char const *, tain_t const *, tain_t *) ; +#define s6rc_servicedir_manage_g(live, suffix, deadline) s6rc_servicedir_manage(live, suffix, (deadline), &STAMP) #endif diff --git a/src/include/s6-rc/s6rc-utils.h b/src/include/s6-rc/s6rc-utils.h index 22d8324..ad1f1ef 100644 --- a/src/include/s6-rc/s6rc-utils.h +++ b/src/include/s6-rc/s6rc-utils.h @@ -12,4 +12,7 @@ extern int s6rc_lock (char const *, int, int *, char const *, int, int *, int) ; extern int s6rc_read_uint (char const *, unsigned int *) ; extern int s6rc_sanitize_dir (stralloc *, char const *, size_t *) ; +extern int s6rc_livedir_suffixsize (char const *, size_t *) ; +extern ssize_t s6rc_livedir_suffix (char const *, char *, size_t) ; + #endif diff --git a/src/libs6rc/deps-lib/s6rc b/src/libs6rc/deps-lib/s6rc index 5e6263d..3768378 100644 --- a/src/libs6rc/deps-lib/s6rc +++ b/src/libs6rc/deps-lib/s6rc @@ -5,6 +5,8 @@ s6rc_db_read.o s6rc_db_read_sizes.o s6rc_db_read_uint32.o s6rc_graph_closure.o +s6rc_livedir_suffix.o +s6rc_livedir_suffixsize.o s6rc_lock.o s6rc_read_uint.o s6rc_sanitize_dir.o diff --git a/src/libs6rc/s6rc_livedir_suffix.c b/src/libs6rc/s6rc_livedir_suffix.c new file mode 100644 index 0000000..98236cd --- /dev/null +++ b/src/libs6rc/s6rc_livedir_suffix.c @@ -0,0 +1,19 @@ +/* ISC license. */ + +#include <string.h> +#include <errno.h> +#include <skalibs/djbunix.h> +#include <s6-rc/s6rc-utils.h> + +ssize_t s6rc_livedir_suffix (char const *live, char *s, size_t n) +{ + size_t llen = strlen(live) ; + size_t r ; + char sfn[llen + 8] ; + memcpy(sfn, live, llen) ; + memcpy(sfn + llen, "/suffix", 8) ; + r = openreadnclose(sfn, s, n) ; + if (r < 0) return r ; + if (memchr(s, '/', r)) return (errno = EINVAL, 0) ; + return r ; +} diff --git a/src/libs6rc/s6rc_livedir_suffixsize.c b/src/libs6rc/s6rc_livedir_suffixsize.c new file mode 100644 index 0000000..b571dad --- /dev/null +++ b/src/libs6rc/s6rc_livedir_suffixsize.c @@ -0,0 +1,24 @@ +/* ISC license. */ + +#include <string.h> +#include <sys/stat.h> +#include <errno.h> +#include <s6-rc/s6rc-utils.h> + +int s6rc_livedir_suffixsize (char const *live, size_t *n) +{ + struct stat st ; + size_t llen = strlen(live) ; + char sfn[llen + 8] ; + memcpy(sfn, live, llen) ; + memcpy(sfn + llen, "/suffix", 8) ; + if (stat(sfn, &st) < 0) + { + if (errno != ENOENT) return 0 ; + *n = 0 ; + return 1 ; + } + if (!S_ISREG(st.st_mode)) return (errno = EINVAL, 0) ; + *n = st.st_size ; + return 1 ; +} diff --git a/src/libs6rc/s6rc_read_uint.c b/src/libs6rc/s6rc_read_uint.c index c9f05be..1f148ac 100644 --- a/src/libs6rc/s6rc_read_uint.c +++ b/src/libs6rc/s6rc_read_uint.c @@ -5,6 +5,7 @@ #include <skalibs/types.h> #include <skalibs/bytestr.h> #include <skalibs/djbunix.h> +#include <s6-rc/s6rc-utils.h> int s6rc_read_uint (char const *file, unsigned int *u) { diff --git a/src/libs6rc/s6rc_servicedir_manage.c b/src/libs6rc/s6rc_servicedir_manage.c index 218c0af..d39d045 100644 --- a/src/libs6rc/s6rc_servicedir_manage.c +++ b/src/libs6rc/s6rc_servicedir_manage.c @@ -13,23 +13,24 @@ #include <s6/ftrigw.h> #include <s6-rc/s6rc-servicedir.h> -static void rollback (char const *live, char const *s, size_t len) +static inline void rollback (char const *live, char const *suffix, char const *s, size_t len) { while (len) { size_t n = strlen(s) + 1 ; - s6rc_servicedir_unsupervise(live, s, 0) ; + s6rc_servicedir_unsupervise(live, suffix, s, 0) ; s += n ; len -= n ; } } -int s6rc_servicedir_manage (char const *live, tain_t const *deadline, tain_t *stamp) +int s6rc_servicedir_manage (char const *live, char const *suffix, tain_t const *deadline, tain_t *stamp) { ftrigr_t a = FTRIGR_ZERO ; stralloc newnames = STRALLOC_ZERO ; genalloc ids = GENALLOC_ZERO ; /* uint16_t */ gid_t gid = getgid() ; size_t livelen = strlen(live) ; + size_t suffixlen = strlen(suffix) ; int ok = 1 ; int e = 0 ; DIR *dir ; @@ -52,7 +53,7 @@ int s6rc_servicedir_manage (char const *live, tain_t const *deadline, tain_t *st int r ; uint16_t id ; char srcfn[livelen + 20 + len] ; - char dstfn[livelen + 10 + len] ; + char dstfn[livelen + 10 + len + suffixlen] ; memcpy(srcfn, dirfn, livelen + 12) ; srcfn[livelen + 12] = '/' ; memcpy(srcfn + livelen + 13, d->d_name, len + 1) ; @@ -75,7 +76,8 @@ int s6rc_servicedir_manage (char const *live, tain_t const *deadline, tain_t *st else s6_svc_lock_release(fdlock) ; memcpy(dstfn, live, livelen) ; memcpy(dstfn + livelen, "/scandir/", 9) ; - memcpy(dstfn + livelen + 9, d->d_name, len + 1) ; + memcpy(dstfn + livelen + 9, d->d_name, len) ; + memcpy(dstfn + livelen + 9 + len, suffix, suffixlen + 1) ; if (symlink(srcfn, dstfn) < 0) { if (!r || errno != EEXIST) goto err ; @@ -85,7 +87,7 @@ int s6rc_servicedir_manage (char const *live, tain_t const *deadline, tain_t *st if (!stralloc_catb(&newnames, d->d_name, len + 1)) { e = errno ; - s6rc_servicedir_unsupervise(live, d->d_name, 0) ; + s6rc_servicedir_unsupervise(live, suffix, d->d_name, 0) ; goto errn ; } } @@ -125,7 +127,7 @@ int s6rc_servicedir_manage (char const *live, tain_t const *deadline, tain_t *st closederrn: ftrigr_end(&a) ; genalloc_free(uint16_t, &ids) ; - rollback(live, newnames.s, newnames.len) ; + rollback(live, suffix, newnames.s, newnames.len) ; stralloc_free(&newnames) ; errno = e ; return 0 ; diff --git a/src/libs6rc/s6rc_servicedir_unsupervise.c b/src/libs6rc/s6rc_servicedir_unsupervise.c index 8b0dbb9..ed95152 100644 --- a/src/libs6rc/s6rc_servicedir_unsupervise.c +++ b/src/libs6rc/s6rc_servicedir_unsupervise.c @@ -5,14 +5,16 @@ #include <s6/s6-supervise.h> #include <s6-rc/s6rc-servicedir.h> -void s6rc_servicedir_unsupervise (char const *live, char const *name, int keepsupervisor) +void s6rc_servicedir_unsupervise (char const *live, char const *suffix, char const *name, int keepsupervisor) { - size_t namelen = strlen(name) ; size_t livelen = strlen(live) ; - char fn[livelen + 14 + namelen] ; + size_t suffixlen = strlen(suffix) ; + size_t namelen = strlen(name) ; + char fn[livelen + 14 + namelen + suffixlen] ; memcpy(fn, live, livelen) ; memcpy(fn + livelen, "/scandir/", 9) ; - memcpy(fn + livelen + 9, name, namelen + 1) ; + memcpy(fn + livelen + 9, name, namelen) ; + memcpy(fn + livelen + 9 + namelen, suffix, suffixlen + 1) ; unlink(fn) ; if (!keepsupervisor) { diff --git a/src/s6-rc/s6-rc-init.c b/src/s6-rc/s6-rc-init.c index 10d3034..b1765c6 100644 --- a/src/s6-rc/s6-rc-init.c +++ b/src/s6-rc/s6-rc-init.c @@ -15,7 +15,7 @@ #include <s6-rc/config.h> #include <s6-rc/s6rc.h> -#define USAGE "s6-rc-init [ -c compiled ] [ -l live ] [ -t timeout ] [ -b ] [ -d ] scandir" +#define USAGE "s6-rc-init [ -c compiled ] [ -l live ] [ -s suffix ] [ -t timeout ] [ -b ] [ -d ] scandir" #define dieusage() strerr_dieusage(100, USAGE) #define dienomem() strerr_diefu1sys(111, "stralloc_catb") @@ -29,7 +29,6 @@ static void cleanup (void) unlink(stmp.s) ; stmp.s[llen] = ':' ; rm_rf_in_tmp(&stmp, 0) ; - stralloc_free(&stmp) ; errno = e ; } @@ -39,6 +38,7 @@ int main (int argc, char const *const *argv) size_t dirlen ; char const *live = S6RC_LIVE_BASE ; char const *compiled = S6RC_COMPILED_BASE ; + char const *suffix = "" ; int blocking = 0, deref = 0 ; PROG = "s6-rc-init" ; { @@ -46,12 +46,13 @@ int main (int argc, char const *const *argv) subgetopt_t l = SUBGETOPT_ZERO ; for (;;) { - int opt = subgetopt_r(argc, argv, "c:l:t:bd", &l) ; + int opt = subgetopt_r(argc, argv, "c:l:s:t:bd", &l) ; if (opt == -1) break ; switch (opt) { case 'c' : compiled = l.arg ; break ; case 'l' : live = l.arg ; break ; + case 's' : suffix = l.arg ; break ; case 't' : if (!uint0_scan(l.arg, &t)) dieusage() ; break ; case 'b' : blocking = 1 ; break ; case 'd' : deref = 1 ; break ; @@ -70,6 +71,8 @@ int main (int argc, char const *const *argv) strerr_dief2x(100, live, " is not an absolute path") ; if (argv[0][0] != '/') strerr_dief2x(100, argv[0], " is not an absolute path") ; + if (strchr(suffix, '/')) + strerr_dief1x(100, "suffix cannot contain a / character") ; tain_now_g() ; tain_add_g(&deadline, &tto) ; @@ -96,21 +99,17 @@ int main (int argc, char const *const *argv) if (mkdir(stmp.s, 0755) < 0) strerr_diefu2sys(111, "mkdir ", stmp.s) ; if (!s6rc_lock(stmp.s, 2, &fdlock, 0, 0, 0, blocking)) { - char tmp[stmp.len] ; - memcpy(tmp, stmp.s, stmp.len) ; cleanup() ; - strerr_diefu2sys(111, "take lock on ", tmp) ; + strerr_diefu2sys(111, "take lock on ", stmp.s) ; } memcpy(lfn, stmp.s, llen) ; lfn[llen] = 0 ; if (symlink(stmp.s + dirlen, lfn) < 0) { - char tmp[stmp.len - dirlen] ; - memcpy(tmp, stmp.s + dirlen, stmp.len - dirlen) ; cleanup() ; - strerr_diefu4sys(111, "symlink ", tmp, " to ", lfn) ; + strerr_diefu4sys(111, "symlink ", stmp.s + dirlen, " to ", lfn) ; } - + /* compiled */ @@ -134,6 +133,19 @@ int main (int argc, char const *const *argv) } + /* suffix */ + + if (suffix[0]) + { + memcpy(lfn + llen + 1, "suffix", 7) ; + if (!openwritenclose_unsafe(lfn, suffix, strlen(suffix))) + { + cleanup() ; + strerr_diefu2sys(111, "write to ", lfn) ; + } + } + + /* scandir */ memcpy(lfn + llen + 1, "scandir", 8) ; @@ -184,7 +196,7 @@ int main (int argc, char const *const *argv) /* start the supervisors */ lfn[llen] = 0 ; - ok = s6rc_servicedir_manage_g(lfn, &deadline) ; + ok = s6rc_servicedir_manage_g(lfn, suffix, &deadline) ; if (!ok) { cleanup() ; diff --git a/src/s6-rc/s6-rc-update.c b/src/s6-rc/s6-rc-update.c index 5dfd0d7..d9dce7c 100644 --- a/src/s6-rc/s6-rc-update.c +++ b/src/s6-rc/s6-rc-update.c @@ -31,7 +31,7 @@ #define USAGE "s6-rc-update [ -n ] [ -v verbosity ] [ -t timeout ] [ -l live ] [ -f conversion_file ] [ -b ] newdb" #define dieusage() strerr_dieusage(100, USAGE) #define dienomem() strerr_diefu1sys(111, "build string") ; -#define SUFFIX ":update:XXXXXX" +#define NEWSUFFIX ":update:XXXXXX" static char const *live = S6RC_LIVE_BASE ; static size_t livelen = sizeof(S6RC_LIVE_BASE) - 1 ; @@ -222,7 +222,6 @@ static inline void stuff_with_newc (int fdnewc, char const *newfn, unsigned char static void compute_transitions (char const *convfile, unsigned char *oldstate, int fdoldc, s6rc_db_t const *olddb, unsigned char *newstate, unsigned int *invimage, int fdnewc, char const *newfn, s6rc_db_t const *newdb, stralloc *sa) { - size_t sabase = sa->len ; unsigned int oldn = olddb->nshort + olddb->nlong ; unsigned int newn = newdb->nshort + newdb->nlong ; unsigned int newm = bitarray_div8(newn) ; @@ -230,8 +229,8 @@ static void compute_transitions (char const *convfile, unsigned char *oldstate, unsigned char conversion_table[oldn * newm] ; memset(conversion_table, 0, oldn * newm) ; stuff_with_oldc(oldstate, fdoldc, olddb, convfile, oldindex, sa) ; - stuff_with_newc(fdnewc, newfn, conversion_table, oldstate, newstate, sa->s + sabase, oldindex, invimage, olddb, newdb) ; - sa->len = sabase ; + stuff_with_newc(fdnewc, newfn, conversion_table, oldstate, newstate, sa->s, oldindex, invimage, olddb, newdb) ; + sa->len = 0 ; for (;;) { @@ -324,10 +323,9 @@ static inline void rollback_servicedirs (char const *newlive, unsigned char cons } } -static inline void make_new_livedir (unsigned char const *oldstate, s6rc_db_t const *olddb, unsigned char const *newstate, s6rc_db_t const *newdb, char const *newcompiled, unsigned int *invimage, stralloc *sa) +static inline void make_new_livedir (unsigned char const *oldstate, s6rc_db_t const *olddb, unsigned char const *newstate, s6rc_db_t const *newdb, char const *newcompiled, unsigned int *invimage, char const *suffix, size_t suffixlen, stralloc *sa) { size_t tmpbase = satmp.len ; - size_t sabase = sa->len ; size_t newclen = strlen(newcompiled) ; size_t dirlen, llen, newlen, sdlen ; int e = 0 ; @@ -335,34 +333,37 @@ static inline void make_new_livedir (unsigned char const *oldstate, s6rc_db_t co if (sareadlink(&satmp, live) < 0) strerr_diefu2sys(111, "readlink ", live) ; if (!s6rc_sanitize_dir(sa, live, &dirlen)) dienomem() ; llen = sa->len ; - if (!stralloc_catb(sa, SUFFIX, sizeof(SUFFIX))) dienomem() ; + if (!stralloc_catb(sa, NEWSUFFIX, sizeof(NEWSUFFIX))) dienomem() ; newlen = --sa->len ; - if (!mkdtemp(sa->s + sabase)) strerr_diefu2sys(111, "mkdtemp ", sa->s + sabase) ; - if (chmod(sa->s + sabase, 0755) < 0) { e = errno ; goto err ; } + if (!mkdtemp(sa->s)) strerr_diefu2sys(111, "mkdtemp ", sa->s) ; + if (chmod(sa->s, 0755) < 0) { e = errno ; goto err ; } { size_t tmplen = satmp.len ; - char fn[llen - sabase + 9] ; + char fn[llen + 9] ; if (!stralloc_cats(sa, "/scandir") || !stralloc_0(sa)) { e = errno ; goto err ; } - memcpy(fn, sa->s + sabase, llen - sabase) ; - memcpy(fn + llen - sabase, "/scandir", 9) ; + memcpy(fn, sa->s, llen) ; + memcpy(fn + llen, "/scandir", 9) ; if (sareadlink(&satmp, fn) < 0 || !stralloc_0(&satmp)) { e = errno ; goto err ; } - if (symlink(satmp.s + tmplen, sa->s + sabase) < 0) { e = errno ; goto err ; } + if (symlink(satmp.s + tmplen, sa->s) < 0) { e = errno ; goto err ; } satmp.len = tmplen ; - sa->len = newlen ; } - if (!stralloc_cats(sa, "/state") || !stralloc_0(sa)) { e = errno ; goto err ; } + sa->len = newlen ; + if (!stralloc_catb(sa, "/suffix", 8)) { e = errno ; goto err ; } + if (!openwritenclose_unsafe(sa->s, suffix, suffixlen)) { e = errno ; goto err ; } + sa->len = newlen ; + if (!stralloc_catb(sa, "/state", 7)) { e = errno ; goto err ; } { char tmpstate[newdb->nlong + newdb->nshort] ; unsigned int i = newdb->nlong + newdb->nshort ; while (i--) tmpstate[i] = newstate[i] & 1 ; - if (!openwritenclose_unsafe(sa->s + sabase, tmpstate, newdb->nlong + newdb->nshort)) { e = errno ; goto err ; } + if (!openwritenclose_unsafe(sa->s, tmpstate, newdb->nlong + newdb->nshort)) { e = errno ; goto err ; } } sa->len = newlen ; - if (!stralloc_cats(sa, "/compiled") || !stralloc_0(sa)) { e = errno ; goto err ; } - if (symlink(newcompiled, sa->s + sabase) < 0) goto err ; + if (!stralloc_catb(sa, "/compiled", 10)) { e = errno ; goto err ; } + if (symlink(newcompiled, sa->s) < 0) goto err ; sa->len = newlen ; - if (!stralloc_cats(sa, "/servicedirs") || !stralloc_0(sa)) { e = errno ; goto err ; } - if (mkdir(sa->s + sabase, 0755) < 0) { e = errno ; goto err ; } + if (!stralloc_catb(sa, "/servicedirs", 13)) { e = errno ; goto err ; } + if (mkdir(sa->s, 0755) < 0) { e = errno ; goto err ; } sdlen = sa->len ; sa->s[sdlen - 1] = '/' ; @@ -384,18 +385,18 @@ static inline void make_new_livedir (unsigned char const *oldstate, s6rc_db_t co memcpy(oldfn, live, livelen) ; memcpy(oldfn + livelen, "/servicedirs/", 13) ; memcpy(oldfn + livelen + 13, oldname, oldnamelen + 1) ; - if (rename(oldfn, sa->s + sabase) < 0) goto rollback ; - if (!s6rc_servicedir_copy_online(newfn, sa->s + sabase)) { i++ ; e = errno ; goto rollback ; } + if (rename(oldfn, sa->s) < 0) goto rollback ; + if (!s6rc_servicedir_copy_online(newfn, sa->s)) { i++ ; e = errno ; goto rollback ; } } - else if (!s6rc_servicedir_copy_offline(newfn, sa->s + sabase)) { e = errno ; goto rollback ; } + else if (!s6rc_servicedir_copy_offline(newfn, sa->s)) { e = errno ; goto rollback ; } } sa->len = newlen ; sa->s[sa->len++] = 0 ; { - char tmpfn[llen + 5 - sabase] ; - memcpy(tmpfn, sa->s + sabase, llen - sabase) ; - memcpy(tmpfn + llen - sabase, ".new", 5) ; + char tmpfn[llen + 5] ; + memcpy(tmpfn, sa->s, llen) ; + memcpy(tmpfn + llen, ".new", 5) ; if (unlink(tmpfn) < 0 && errno != ENOENT) { e = errno ; goto rollback ; } if (symlink(sa->s + dirlen, tmpfn) < 0) { e = errno ; goto rollback ; } @@ -417,21 +418,21 @@ static inline void make_new_livedir (unsigned char const *oldstate, s6rc_db_t co dienomem() ; i = olddb->nlong ; while (i--) - s6rc_servicedir_unsupervise(sa->s + sabase, olddb->string + olddb->services[i].name, (oldstate[i] & 33) == 1) ; - rm_rf(sa->s + sabase) ; + s6rc_servicedir_unsupervise(sa->s, suffix, olddb->string + olddb->services[i].name, (oldstate[i] & 33) == 1) ; + rm_rf(sa->s) ; - sa->len = sabase ; + sa->len = 0 ; satmp.len = tmpbase ; return ; rollback: sa->len = newlen ; sa->s[sa->len++] = 0 ; - rollback_servicedirs(sa->s + sabase, newstate, invimage, olddb, newdb, i) ; + rollback_servicedirs(sa->s, newstate, invimage, olddb, newdb, i) ; err: sa->len = newlen ; sa->s[sa->len++] = 0 ; - rm_rf(sa->s + sabase) ; + rm_rf(sa->s) ; errno = e ; strerr_diefu2sys(111, "make new live directory in ", sa->s) ; } @@ -650,6 +651,7 @@ int main (int argc, char const *const *argv, char const *const *envp) int fdoldc, fdnewc ; s6rc_db_t olddb, newdb ; unsigned int oldn, newn ; + size_t suffixlen = 0 ; char dbfn[livelen + 10] ; tain_now_g() ; @@ -666,8 +668,10 @@ int main (int argc, char const *const *argv, char const *const *envp) strerr_diefu2sys(111, "take lock on ", argv[0]) ; - /* Read the sizes of the compiled dbs */ + /* Read the sizes of the suffix and compiled dbs */ + if (!s6rc_livedir_suffixsize(live, &suffixlen)) + strerr_diefu2sys(111, "read suffix size for ", live) ; fdoldc = open_readb(dbfn) ; if (!s6rc_db_read_sizes(fdoldc, &olddb)) strerr_diefu3sys(111, "read ", dbfn, "/n") ; @@ -694,6 +698,7 @@ int main (int argc, char const *const *argv, char const *const *envp) char newstringblob[newdb.stringlen] ; unsigned char oldstate[oldn] ; unsigned char newstate[newn] ; + char suffix[suffixlen + 1] ; int r ; olddb.services = oldserviceblob ; @@ -706,6 +711,15 @@ int main (int argc, char const *const *argv, char const *const *envp) newdb.string = newstringblob ; + /* Read the suffix */ + + { + ssize_t rr = s6rc_livedir_suffix(live, suffix, suffixlen) ; + if (rr != suffixlen) strerr_diefu2sys(111, "read suffix for ", live) ; + suffix[suffixlen] = 0 ; + } + + /* Read the dbs */ r = s6rc_db_read(fdoldc, &olddb) ; @@ -791,8 +805,8 @@ int main (int argc, char const *const *argv, char const *const *envp) if (verbosity >= 2) strerr_warni1x("updating state and service directories") ; - make_new_livedir(oldstate, &olddb, newstate, &newdb, argv[0], invimage, &sa) ; - r = s6rc_servicedir_manage_g(live, &deadline) ; + make_new_livedir(oldstate, &olddb, newstate, &newdb, argv[0], invimage, suffix, suffixlen, &sa) ; + r = s6rc_servicedir_manage_g(live, suffix, &deadline) ; if (!r) strerr_diefu2sys(111, "manage new service directories in ", live) ; if (r & 2) strerr_warnw3x("s6-svscan not running on ", live, "/scandir") ; diff --git a/src/s6-rc/s6-rc.c b/src/s6-rc/s6-rc.c index dd329a4..5fa8c4f 100644 --- a/src/s6-rc/s6-rc.c +++ b/src/s6-rc/s6-rc.c @@ -42,6 +42,8 @@ static unsigned int n ; static unsigned char *state ; static unsigned int *pendingdeps ; static tain_t deadline ; +static size_t suffixlen ; +static char *suffix ; static char dryrun[UINT_FMT] = "" ; static inline void announce (void) @@ -130,14 +132,15 @@ static pid_t start_longrun (unsigned int i, int h) unsigned int m = 0 ; char fmt[UINT32_FMT] ; char vfmt[UINT_FMT] ; - char servicefn[livelen + svdlen + 26] ; + char servicefn[livelen + svdlen + suffixlen + 26] ; char const *newargv[7 + !!dryrun[0] * 6] ; memcpy(servicefn, live, livelen) ; memcpy(servicefn + livelen, "/scandir/", 9) ; memcpy(servicefn + livelen + 9, db->string + db->services[i].name, svdlen) ; + memcpy(servicefn + livelen + 9 + svdlen, suffix, suffixlen) ; if (h) { - memcpy(servicefn + livelen + 9 + svdlen, "/notification-fd", 17) ; + memcpy(servicefn + livelen + 9 + svdlen + suffixlen, "/notification-fd", 17) ; if (access(servicefn, F_OK) < 0) { h = 2 ; @@ -145,7 +148,7 @@ static pid_t start_longrun (unsigned int i, int h) strerr_warnwu2sys("access ", servicefn) ; } } - servicefn[livelen + 9 + svdlen] = 0 ; + servicefn[livelen + 9 + svdlen + suffixlen] = 0 ; fmt[uint32_fmt(fmt, compute_timeout(i, !!h))] = 0 ; vfmt[uint_fmt(vfmt, verbosity)] = 0 ; if (dryrun[0]) @@ -172,11 +175,12 @@ static void success_longrun (unsigned int i, int h) if (!dryrun[0]) { size_t svdlen = strlen(db->string + db->services[i].name) ; - char fn[livelen + svdlen + 15] ; + char fn[livelen + svdlen + suffixlen + 15] ; memcpy(fn, live, livelen) ; memcpy(fn + livelen, "/scandir/", 9) ; memcpy(fn + livelen + 9, db->string + db->services[i].name, svdlen) ; - memcpy(fn + livelen + 9 + svdlen, "/down", 6) ; + memcpy(fn + livelen + 9 + svdlen, suffix, suffixlen) ; + memcpy(fn + livelen + 9 + svdlen + suffixlen, "/down", 6) ; if (h) { if (unlink(fn) < 0 && verbosity) @@ -200,11 +204,12 @@ static void failure_longrun (unsigned int i, int h) if (h && !dryrun[0]) { size_t svdlen = strlen(db->string + db->services[i].name) ; - char fn[livelen + svdlen + 10] ; + char fn[livelen + svdlen + suffixlen + 10] ; char const *newargv[5] = { S6_EXTBINPREFIX "s6-svc", "-d", "--", fn, 0 } ; memcpy(fn, live, livelen) ; memcpy(fn + livelen, "/scandir/", 9) ; - memcpy(fn + livelen + 9, db->string + db->services[i].name, svdlen+1) ; + memcpy(fn + livelen + 9, db->string + db->services[i].name, svdlen) ; + memcpy(fn + livelen + 9 + svdlen, suffix, suffixlen + 1) ; if (!child_spawn0(newargv[0], newargv, (char const *const *)environ)) strerr_warnwu2sys("spawn ", newargv[0]) ; } @@ -281,11 +286,12 @@ static void on_failure (unsigned int i, int h, int crashed, unsigned int code) /* static inline void kill_oneshots (void) { - char fn[livelen + S6RC_ONESHOT_RUNNER_LEN + 10] ; + char fn[livelen + S6RC_ONESHOT_RUNNER_LEN + suffixlen + 10] ; char const *newargv[5] = { S6_EXTBINPREFIX "s6-svc", "-h", "--", fn, 0 } ; memcpy(fn, live, livelen) ; memcpy(fn + livelen, "/scandir/", 9) ; - memcpy(fn + livelen + 9, S6RC_ONESHOT_RUNNER, S6RC_ONESHOT_RUNNER_LEN+1) ; + memcpy(fn + livelen + 9, S6RC_ONESHOT_RUNNER, S6RC_ONESHOT_RUNNER_LEN) ; + memcpy(fn + livelen + 9 + S6RC_ONESHOT_RUNNER_LEN, suffix, suffixlen + 1) ; if (!child_spawn0(newargv[0], newargv, (char const *const *)environ)) strerr_warnwu2sys("spawn ", newargv[0]) ; } @@ -486,8 +492,10 @@ int main (int argc, char const *const *argv) } - /* Read the sizes of the compiled db */ + /* Read the sizes of the suffix and compiled db */ + if (!s6rc_livedir_suffixsize(live, &suffixlen)) + strerr_diefu2sys(111, "read suffix size for ", live) ; fdcompiled = open_readb(dbfn) ; if (!s6rc_db_read_sizes(fdcompiled, &dbblob)) strerr_diefu3sys(111, "read ", dbfn, "/n") ; @@ -503,12 +511,23 @@ int main (int argc, char const *const *argv) uint32_t depsblob[dbblob.ndeps << 1] ; char stringblob[dbblob.stringlen] ; unsigned char stateblob[n] ; + char suffixblob[suffixlen + 1] ; dbblob.services = serviceblob ; dbblob.argvs = argvblob ; dbblob.deps = depsblob ; dbblob.string = stringblob ; state = stateblob ; + suffix = suffixblob ; + + + /* Read the suffix */ + + { + ssize_t r = s6rc_livedir_suffix(live, suffix, suffixlen) ; + if (r != suffixlen) strerr_diefu2sys(111, "read suffix for ", live) ; + suffix[suffixlen] = 0 ; + } /* Read live state in bit 0 of state */ |