summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2017-10-08 15:39:57 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2017-10-08 15:39:57 +0000
commitf9940bb7d1a6ce7d7772e8cbdbbd55a321cc5c18 (patch)
tree352798ff6073e18a467a9ffeab548485070dc568
parent8c341bbaca5e89a9620702bc0025641e815e4195 (diff)
downloads6-rc-f9940bb7d1a6ce7d7772e8cbdbbd55a321cc5c18.tar.xz
Add -s to s6-rc-init; prepare for 0.3.0.0
-rw-r--r--NEWS6
-rw-r--r--doc/index.html2
-rw-r--r--doc/s6-rc-init.html11
-rw-r--r--doc/upgrade.html4
-rw-r--r--package/deps.mak8
-rw-r--r--package/info2
-rw-r--r--src/include/s6-rc/s6rc-servicedir.h6
-rw-r--r--src/include/s6-rc/s6rc-utils.h3
-rw-r--r--src/libs6rc/deps-lib/s6rc2
-rw-r--r--src/libs6rc/s6rc_livedir_suffix.c19
-rw-r--r--src/libs6rc/s6rc_livedir_suffixsize.c24
-rw-r--r--src/libs6rc/s6rc_read_uint.c1
-rw-r--r--src/libs6rc/s6rc_servicedir_manage.c16
-rw-r--r--src/libs6rc/s6rc_servicedir_unsupervise.c10
-rw-r--r--src/s6-rc/s6-rc-init.c34
-rw-r--r--src/s6-rc/s6-rc-update.c82
-rw-r--r--src/s6-rc/s6-rc.c39
17 files changed, 192 insertions, 77 deletions
diff --git a/NEWS b/NEWS
index 08f2e2d..a935c54 100644
--- a/NEWS
+++ b/NEWS
@@ -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&nbsp;<em>suffix</em></tt>&nbsp;: 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>&nbsp;: 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 */