summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/s6-rc-bundle.html11
-rw-r--r--doc/s6-rc-compile.html7
-rw-r--r--doc/s6-rc-db.html27
-rw-r--r--doc/s6-rc-fdholder-filler.html7
-rw-r--r--doc/s6-rc-init.html7
-rw-r--r--doc/s6-rc-oneshot-run.html7
-rw-r--r--doc/s6-rc-update.html7
-rw-r--r--doc/s6-rc.html23
-rw-r--r--src/include/s6-rc/s6rc-utils.h2
-rw-r--r--src/libs6rc/s6rc_lock.c16
-rw-r--r--src/s6-rc/s6-rc-bundle.c8
-rw-r--r--src/s6-rc/s6-rc-compile.c66
-rw-r--r--src/s6-rc/s6-rc-db.c8
-rw-r--r--src/s6-rc/s6-rc-init.c8
-rw-r--r--src/s6-rc/s6-rc-oneshot-run.c8
-rw-r--r--src/s6-rc/s6-rc-update.c10
-rw-r--r--src/s6-rc/s6-rc.c9
17 files changed, 148 insertions, 83 deletions
diff --git a/doc/s6-rc-bundle.html b/doc/s6-rc-bundle.html
index 7647006..4bae71a 100644
--- a/doc/s6-rc-bundle.html
+++ b/doc/s6-rc-bundle.html
@@ -36,9 +36,9 @@ operation.
<pre>
s6-rc-bundle help
- s6-rc-bundle [ -f ] [ -l <em>live</em> ] [ -c <em>compiled</em> ] add <em>bundlename</em> <em>contents...</em>
- s6-rc-bundle [ -f ] [ -l <em>live</em> ] [ -c <em>compiled</em> ] delete <em>bundlenames...</em>
- s6-rc-bundle [ -f ] [ -l <em>live</em> ] [ -c <em>compiled</em> ] multiple <em>args...</em>
+ s6-rc-bundle [ -f ] [ -l <em>live</em> ] [ -c <em>compiled</em> ] [ -b ] add <em>bundlename</em> <em>contents...</em>
+ s6-rc-bundle [ -f ] [ -l <em>live</em> ] [ -c <em>compiled</em> ] [ -b ] delete <em>bundlenames...</em>
+ s6-rc-bundle [ -f ] [ -l <em>live</em> ] [ -c <em>compiled</em> ] [ -b ] multiple <em>args...</em>
</pre>
<ul>
@@ -66,6 +66,11 @@ when given a nonexisting name to delete (it will do nothing), or
when given an existing name to add (it will replace the definition).
By default, s6-rc-bundle will complain and exit when asked to delete a
nonexistent name or to add an existing name. </li>
+ <li> <tt>-b</tt>&nbsp;: blocking lock. If the database is currently
+being used by another program, s6-rc-bundle will wait until that
+other program has released its lock on the database, then proceed.
+By default, s6-rc-bundle fails with an error message if the database
+is currently in use. </li>
</ul>
<h2> Exit codes </h2>
diff --git a/doc/s6-rc-compile.html b/doc/s6-rc-compile.html
index 61f6dd2..cfacde1 100644
--- a/doc/s6-rc-compile.html
+++ b/doc/s6-rc-compile.html
@@ -36,7 +36,7 @@ the current service database via
<h2> Interface </h2>
<pre>
- s6-rc-compile [ -v <em>verbosity</em> ] [ -u <em>uids</em> ] [ -g <em>gids</em> ] [ -h <em>fdhuser</em> ] <em>compiled</em> <em>source...</em>
+ s6-rc-compile [ -v <em>verbosity</em> ] [ -u <em>uids</em> ] [ -g <em>gids</em> ] [ -h <em>fdhuser</em> ] [ -b ] <em>compiled</em> <em>source...</em>
</pre>
<ul>
@@ -77,6 +77,11 @@ numerical GIDs. </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>-b</tt>&nbsp;: make
+<a href="s6-rc-oneshot-runner.html">s6-rc-oneshot-runner</a>
+invocations wait instead of fail on lock contention. This
+should not change anything in practice, and you can ignore
+that option. </li>
</ul>
<p>
diff --git a/doc/s6-rc-db.html b/doc/s6-rc-db.html
index a9d8b9d..5c664f5 100644
--- a/doc/s6-rc-db.html
+++ b/doc/s6-rc-db.html
@@ -37,17 +37,17 @@ operation.
<pre>
s6-rc-db help
- s6-rc-db [ -l <em>live</em> ] [ -c <em>compiled</em> ] check
- s6-rc-db [ -l <em>live</em> ] [ -c <em>compiled</em> ] list all|services|oneshots|longruns|bundles
- s6-rc-db [ -l <em>live</em> ] [ -c <em>compiled</em> ] type <em>servicename</em>
- s6-rc-db [ -l <em>live</em> ] [ -c <em>compiled</em> ] [ -u | -d ] timeout <em>atomicname</em>
- s6-rc-db [ -l <em>live</em> ] [ -c <em>compiled</em> ] contents <em>bundlename</em>
- s6-rc-db [ -l <em>live</em> ] [ -c <em>compiled</em> ] [ -u | -d ] dependencies <em>servicename</em>
- s6-rc-db [ -l <em>live</em> ] [ -c <em>compiled</em> ] pipeline <em>longrunname</em>
- s6-rc-db [ -l <em>live</em> ] [ -c <em>compiled</em> ] [ -u | -d ] script <em>oneshotname</em>
- s6-rc-db [ -l <em>live</em> ] [ -c <em>compiled</em> ] flags <em>atomicname</em>
- s6-rc-db [ -l <em>live</em> ] [ -c <em>compiled</em> ] atomics <em>servicename...</em>
- s6-rc-db [ -l <em>live</em> ] [ -c <em>compiled</em> ] [ -u | -d ] all-dependencies <em>servicename...</em>
+ s6-rc-db [ -l <em>live</em> ] [ -c <em>compiled</em> ] [ -b ] check
+ s6-rc-db [ -l <em>live</em> ] [ -c <em>compiled</em> ] [ -b ] list all|services|oneshots|longruns|bundles
+ s6-rc-db [ -l <em>live</em> ] [ -c <em>compiled</em> ] [ -b ] type <em>servicename</em>
+ s6-rc-db [ -l <em>live</em> ] [ -c <em>compiled</em> ] [ -b ] [ -u | -d ] timeout <em>atomicname</em>
+ s6-rc-db [ -l <em>live</em> ] [ -c <em>compiled</em> ] [ -b ] contents <em>bundlename</em>
+ s6-rc-db [ -l <em>live</em> ] [ -c <em>compiled</em> ] [ -b ] [ -u | -d ] dependencies <em>servicename</em>
+ s6-rc-db [ -l <em>live</em> ] [ -c <em>compiled</em> ] [ -b ] pipeline <em>longrunname</em>
+ s6-rc-db [ -l <em>live</em> ] [ -c <em>compiled</em> ] [ -b ] [ -u | -d ] script <em>oneshotname</em>
+ s6-rc-db [ -l <em>live</em> ] [ -c <em>compiled</em> ] [ -b ] flags <em>atomicname</em>
+ s6-rc-db [ -l <em>live</em> ] [ -c <em>compiled</em> ] [ -b ] atomics <em>servicename...</em>
+ s6-rc-db [ -l <em>live</em> ] [ -c <em>compiled</em> ] [ -b ] [ -u | -d ] all-dependencies <em>servicename...</em>
</pre>
<ul>
@@ -78,6 +78,11 @@ ignored when it is irrelevant. </li>
<li> <tt>-d</tt>&nbsp;: for commands that use different data
depending on whether it's about bringing the service up or down,
select the "down" data. This option is ignored when it is irrelevant. </li>
+ <li> <tt>-b</tt>&nbsp;: blocking lock. If the database is currently
+being used by another program, s6-rc-db will wait until that
+other program has released its lock on the database, then proceed.
+By default, s6-rc-db fails with an error message if the database
+is currently in use. </li>
</ul>
<h2> Exit codes </h2>
diff --git a/doc/s6-rc-fdholder-filler.html b/doc/s6-rc-fdholder-filler.html
index 83132fd..a835663 100644
--- a/doc/s6-rc-fdholder-filler.html
+++ b/doc/s6-rc-fdholder-filler.html
@@ -34,7 +34,7 @@ in internal scripts created by
<h2> Interface </h2>
<pre>
- s6-rc-fdholder-filler [ -1 ] [ -t <em>timeout</em> ] <em>longrunnames...</em>
+ s6-rc-fdholder-filler [ -1 ] [ -t <em>timeout</em> ] &lt; <em>longrunnamesfile</em>
</pre>
<ul>
@@ -42,7 +42,10 @@ in internal scripts created by
connected to the
<a href="http://skarnet.org/software/s6/s6-fdholderd.html">s6-fdholderd</a>
daemon instance managed by s6-rc as the internal <em>s6rc-fdholder</em> service. </li>
- <li> For every argument <em>longrun</em> in <em>longrunnames...</em>, it
+ <li> It reads a list of longrun names from its stdin, one per line.
+Empty lines are ignored; comments starting with <tt>#</tt> are ignored;
+leading whitespace is ignored, but trailing whitespace is not. </li>
+ <li> For every name <em>longrun</em> that it finds, it
creates an anonymous pipe, and stores both ends of that pipe into the
<a href="http://skarnet.org/software/s6/s6-fdholderd.html">s6-fdholderd</a>
instance, with the <tt>pipe:s6-rc-r-<em>longrun</em></tt> (for the reading
diff --git a/doc/s6-rc-init.html b/doc/s6-rc-init.html
index 67ed7de..f24c20a 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> ] <em>scandir</em>
+ s6-rc-init [ -c <em>compiled</em> ] [ -l <em>live</em> ] [ -t <em>timeout</em> ] [ -b ] <em>scandir</em>
</pre>
<ul>
@@ -74,6 +74,11 @@ 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>-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.
+By default, s6-rc-init fails with an error message if the database
+is currently in use. </li>
</ul>
<h2> Typical usage </h2>
diff --git a/doc/s6-rc-oneshot-run.html b/doc/s6-rc-oneshot-run.html
index 351e9e1..8cddcb5 100644
--- a/doc/s6-rc-oneshot-run.html
+++ b/doc/s6-rc-oneshot-run.html
@@ -33,7 +33,7 @@ in internal scripts created by
<h2> Interface </h2>
<pre>
- s6-rc-oneshot-run [ -l <em>live</em> ] up|down <em>n</em>
+ s6-rc-oneshot-run [ -l <em>live</em> ] [ -b ] up|down <em>n</em>
</pre>
<ul>
@@ -49,6 +49,11 @@ live directory). </li>
<li> <tt>-l&nbsp;<em>live</em></tt>&nbsp;: use the live directory in
<em>live</em>. Default is <tt>/run/s6-rc</tt>, or what was given to the
<tt>--livedir</tt> configure option at compile time. </li>
+ <li> <tt>-b</tt>&nbsp;: blocking lock. If the service database is currently
+being used by another program, s6-rc-oneshot-run will wait until that
+other program has released its lock on the database, then proceed.
+By default, s6-rc-oneshot-run fails with an error message if the database
+is currently in use. </li>
</ul>
<h2> Exit codes </h2>
diff --git a/doc/s6-rc-update.html b/doc/s6-rc-update.html
index e424f98..52ab42d 100644
--- a/doc/s6-rc-update.html
+++ b/doc/s6-rc-update.html
@@ -38,7 +38,7 @@ situations it cannot solve.
<h2> Interface </h2>
<pre>
- s6-rc-update [ -n ] [ -v <em>verbosity</em> ] [ -t <em>timeout</em> ] [ -l <em>live</em> ] [ -f <em>convfile</em> ] <em>newdb</em>
+ s6-rc-update [ -n ] [ -v <em>verbosity</em> ] [ -t <em>timeout</em> ] [ -l <em>live</em> ] [ -f <em>convfile</em> ] [ -b ] <em>newdb</em>
</pre>
<ul>
@@ -95,6 +95,11 @@ The default can be changed at compile-time by giving the
<li> <tt>-f&nbsp;<em>convfile</em></tt>&nbsp;: use the conversion
file located at <em>convfile</em>. Default is <tt>/dev/null</tt>,
meaning no special instructions. </li>
+ <li> <tt>-b</tt>&nbsp;: blocking lock. If the database is currently
+being used by another program, s6-rc-update will wait until that
+other program has released its lock on the database, then proceed.
+By default, s6-rc-update fails with an error message if the database
+is currently in use. </li>
</ul>
<h2> Transition details </h2>
diff --git a/doc/s6-rc.html b/doc/s6-rc.html
index 5e851d3..a6e64d9 100644
--- a/doc/s6-rc.html
+++ b/doc/s6-rc.html
@@ -44,9 +44,9 @@ especially when asking for a state change.
<pre>
s6-rc help
- s6-rc [ -l live ] [ -a ] [ -u | -d ] list <em>servicenames...</em>
- s6-rc [ -l live ] [ -a ] [ -u | -d ] listall <em>servicenames...</em>
- s6-rc [ -l live ] [ -a ] [ -u | -d ] [ -p ] [ -v <em>verbosity</em> ] [ -n <em>dryrunthrottle</em> ] [ -t timeout ] change [ <em>servicenames...</em> ]
+ s6-rc [ -l live ] [ -b ] [ -a ] [ -u | -d ] list <em>servicenames...</em>
+ s6-rc [ -l live ] [ -b ] [ -a ] [ -u | -d ] listall <em>servicenames...</em>
+ s6-rc [ -l live ] [ -b ] [ -a ] [ -u | -d ] [ -p ] [ -v <em>verbosity</em> ] [ -n <em>dryrunthrottle</em> ] [ -t timeout ] change [ <em>servicenames...</em> ]
</pre>
<ul>
@@ -95,6 +95,14 @@ giving the <tt>--livedir=<em>live</em></tt> option to <tt>./configure</tt>. </li
the selection. This is useful for instance at
shutdown time: <tt>s6-rc -da change</tt>
will stop all services. </li>
+ <li> <tt>-b</tt>&nbsp;: blocking lock. If the service database is currently
+being used by another program, s6-rc will wait until that
+other program has released its lock on the database, then proceed.
+By default, s6-rc fails with an error message if the service database
+is currently in use. The default is the safe behaviour: for instance,
+it will correctly detect and fail nested s6-rc invocations (which are
+an admin error), whereas <tt>s6-rc -b</tt> would deadlock in
+such a case. </li>
</ul>
<h3> Up or down </h3>
@@ -310,10 +318,13 @@ milliseconds to complete successfully.
bringing up all its dependencies first (recursively).
</p>
-<pre> s6-rc -ad change </pre>
+<pre> s6-rc -bad change </pre>
<p>
- Brings down all the currently running services in an orderly manner.
-This is typically run at shutdown time.
+ Waits for any pending program of the s6-rc family to stop using
+the live database and current compiled service database, then
+brings down all the currently running services in an orderly manner.
+This is typically run at shutdown time. (And it's not necessarily
+a bad change!)
</p>
<pre> s6-rc -l /zork -ua listall <em>myservicebundle</em> </pre>
diff --git a/src/include/s6-rc/s6rc-utils.h b/src/include/s6-rc/s6rc-utils.h
index 4eb65f5..22d8324 100644
--- a/src/include/s6-rc/s6rc-utils.h
+++ b/src/include/s6-rc/s6rc-utils.h
@@ -8,7 +8,7 @@
#include <s6-rc/s6rc-db.h>
extern void s6rc_graph_closure (s6rc_db_t const *, unsigned char *, unsigned int, int) ;
-extern int s6rc_lock (char const *, int, int *, char const *, int, int *) ;
+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 *) ;
diff --git a/src/libs6rc/s6rc_lock.c b/src/libs6rc/s6rc_lock.c
index dab3035..2a623d0 100644
--- a/src/libs6rc/s6rc_lock.c
+++ b/src/libs6rc/s6rc_lock.c
@@ -5,7 +5,17 @@
#include <skalibs/djbunix.h>
#include <s6-rc/s6rc-utils.h>
-int s6rc_lock (char const *live, int lwhat, int *llfd, char const *compiled, int cwhat, int *ccfd)
+static inline int lockex (int fd, int blocking)
+{
+ return blocking ? lock_ex(fd) : lock_exnb(fd) ;
+}
+
+static inline int locksh (int fd, int blocking)
+{
+ return blocking ? lock_sh(fd) : lock_shnb(fd) ;
+}
+
+int s6rc_lock (char const *live, int lwhat, int *llfd, char const *compiled, int cwhat, int *ccfd, int blocking)
{
int e = 0 ;
int lfd = -1, cfd = -1 ;
@@ -18,7 +28,7 @@ int s6rc_lock (char const *live, int lwhat, int *llfd, char const *compiled, int
memcpy(lfn + llen, "/lock", 6) ;
lfd = open_create(lfn) ;
if (lfd < 0) return 0 ;
- if ((lwhat > 1 ? lock_ex(lfd) : lock_sh(lfd)) < 0) { e = errno ; goto lerr ; }
+ if ((lwhat > 1 ? lockex(lfd, blocking) : locksh(lfd, blocking)) < 0) { e = errno ; goto lerr ; }
}
if (cwhat)
@@ -31,7 +41,7 @@ int s6rc_lock (char const *live, int lwhat, int *llfd, char const *compiled, int
if (cfd < 0)
if (cwhat > 1 || errno != EROFS) { e = errno ; goto lerr ; }
else cfd = -errno ;
- else if ((cwhat > 1 ? lock_ex(cfd) : lock_sh(cfd)) < 0) { e = errno ; goto cerr ; }
+ else if ((cwhat > 1 ? lockex(cfd, blocking) : locksh(cfd, blocking)) < 0) { e = errno ; goto cerr ; }
}
if (lwhat) *llfd = lfd ;
diff --git a/src/s6-rc/s6-rc-bundle.c b/src/s6-rc/s6-rc-bundle.c
index 78bfcbe..837d3b9 100644
--- a/src/s6-rc/s6-rc-bundle.c
+++ b/src/s6-rc/s6-rc-bundle.c
@@ -18,7 +18,7 @@
#include <s6-rc/config.h>
#include <s6-rc/s6rc.h>
-#define USAGE "s6-rc-bundle [ -l live ] [ -c compiled ] command... (use s6-rc-bundle help for more information)"
+#define USAGE "s6-rc-bundle [ -l live ] [ -c compiled ] [ -b ] command... (use s6-rc-bundle help for more information)"
#define dieusage() strerr_dieusage(100, USAGE)
static void cleanup (char const *compiled)
@@ -259,18 +259,20 @@ int main (int argc, char const **argv)
char const *compiled = 0 ;
unsigned int what ;
int force = 0 ;
+ int blocking = 0 ;
PROG = "s6-rc-bundle" ;
{
subgetopt_t l = SUBGETOPT_ZERO ;
for (;;)
{
- int opt = subgetopt_r(argc, argv, "fl:c:", &l) ;
+ int opt = subgetopt_r(argc, argv, "fl:c:b", &l) ;
if (opt == -1) break ;
switch (opt)
{
case 'f' : force = 1 ; break ;
case 'l' : live = l.arg ; break ;
case 'c' : compiled = l.arg ; break ;
+ case 'b' : blocking = 1 ; break ;
default : dieusage() ;
}
}
@@ -301,7 +303,7 @@ int main (int argc, char const **argv)
compiled = compiledblob ;
}
- if (!s6rc_lock(0, 0, 0, compiled, 2, &compiledlock))
+ if (!s6rc_lock(0, 0, 0, compiled, 2, &compiledlock, blocking))
strerr_diefu2sys(111, "take lock on ", compiled) ;
fdcompiled = open_readb(compiled) ;
if (fdcompiled < 0)
diff --git a/src/s6-rc/s6-rc-compile.c b/src/s6-rc/s6-rc-compile.c
index fdf2602..60bae6b 100644
--- a/src/s6-rc/s6-rc-compile.c
+++ b/src/s6-rc/s6-rc-compile.c
@@ -26,22 +26,12 @@
#include <s6-rc/config.h>
#include <s6-rc/s6rc.h>
-#define USAGE "s6-rc-compile [ -v verbosity ] [ -u okuid,okuid... ] [ -g okgid,okgid... ] [ -h fdholder_user ] destdir sources..."
+#define USAGE "s6-rc-compile [ -v verbosity ] [ -u okuid,okuid... ] [ -g okgid,okgid... ] [ -h fdholder_user ] [ -b ] destdir sources..."
#define dieusage() strerr_dieusage(100, USAGE)
#define dienomem() strerr_dief1x(111, "out of memory") ;
#define S6RC_INTERNALS "s6-rc-compile internals"
-#define S6RC_ONESHOT_RUNNER_RUNSCRIPT \
-"#!" EXECLINE_SHEBANGPREFIX "execlineb -P\n" \
-EXECLINE_EXTBINPREFIX "fdmove -c 2 1\n" \
-EXECLINE_EXTBINPREFIX "fdmove 1 3\n" \
-S6_EXTBINPREFIX "s6-ipcserver-socketbinder -- s\n" \
-S6_EXTBINPREFIX "s6-ipcserverd -1 --\n" \
-S6_EXTBINPREFIX "s6-ipcserver-access -v0 -E -l0 -i data/rules --\n" \
-S6_EXTBINPREFIX "s6-sudod -t 2000 --\n" \
-S6RC_EXTLIBEXECPREFIX "s6-rc-oneshot-run -l ../.. --\n"
-
static unsigned int verbosity = 1 ;
static stralloc keep = STRALLOC_ZERO ;
static stralloc data = STRALLOC_ZERO ;
@@ -56,7 +46,6 @@ enum servicetype_e
} ;
-
/* The names tree */
@@ -84,7 +73,6 @@ static genalloc nameinfo = GENALLOC_ZERO ; /* nameinfo_t */
static avltree names_map = AVLTREE_INIT(8, 3, 8, &names_dtok, &names_cmp, &nameinfo) ;
-
/* Services before resolution */
@@ -137,7 +125,6 @@ struct before_s
#define BEFORE_ZERO { .indices = GENALLOC_ZERO, .oneshots = GENALLOC_ZERO, .longruns = GENALLOC_ZERO, .bundles = GENALLOC_ZERO, .nargvs = 0, .specialdeps = { 0, 0 } } ;
-
/* Read all the sources, populate the name map */
@@ -151,8 +138,7 @@ static char const *typestr (servicetype_t type)
static int add_name_nocheck (before_t *be, char const *srcdir, char const *name, servicetype_t type, unsigned int *pos, unsigned int *kpos)
{
- unsigned int id ;
-
+ uint32_t id ;
if (verbosity >= 4)
strerr_warnt6x("from ", srcdir, ": adding identifier ", name, " of type ", typestr(type)) ;
@@ -211,7 +197,7 @@ static int add_name_nocheck (before_t *be, char const *srcdir, char const *name,
.type = type
} ;
size_t namelen = strlen(name) ;
- unsigned int i = genalloc_len(nameinfo_t, &nameinfo) ;
+ uint32_t i = genalloc_len(nameinfo_t, &nameinfo) ;
if (type == SVTYPE_ONESHOT || type == SVTYPE_LONGRUN)
if (!stralloc_catb(&keep, name, namelen + 1)) dienomem() ;
if (!stralloc_catb(&data, name, namelen + 1)) dienomem() ;
@@ -528,7 +514,7 @@ static inline void add_pipeline_bundles (before_t *be)
while (i--) if (longruns[i].pipelinename)
{
bundle_t bundle = { .listindex = genalloc_len(unsigned int, &be->indices), .n = 1 } ;
- unsigned int id ;
+ uint32_t id ;
nameinfo_t const *info ;
unsigned int j = i ;
if (verbosity >= 3) strerr_warni2x("creating bundle for pipeline ", data.s + longruns[i].pipelinename) ;
@@ -554,7 +540,6 @@ static inline void add_pipeline_bundles (before_t *be)
}
-
/* Resolve all names and dependencies */
@@ -584,7 +569,7 @@ static void resolve_bundle_rec (bundle_recinfo_t *recinfo, unsigned int i)
recinfo->mark[i] |= 1 ;
for (; j < me->n ; j++)
{
- unsigned int id ;
+ uint32_t id ;
nameinfo_t const *p ;
avltree_search(&names_map, data.s + listindex[j], &id) ;
p = genalloc_s(nameinfo_t, &nameinfo) + id ;
@@ -650,7 +635,7 @@ static void resolve_deps (common_t const *me, unsigned int nlong, unsigned int n
unsigned int j = 0 ;
for (; j < me->ndeps ; j++)
{
- unsigned int id ;
+ uint32_t id ;
nameinfo_t const *p ;
avltree_search(&names_map, data.s + indices[me->depindex + j], &id) ;
p = genalloc_s(nameinfo_t, &nameinfo) + id ;
@@ -691,7 +676,7 @@ static void resolve_deps (common_t const *me, unsigned int nlong, unsigned int n
static uint32_t resolve_prodcons (longrun_t const *longruns, unsigned int i, int h, uint32_t nlong)
{
- unsigned int j ;
+ uint32_t j ;
nameinfo_t const *p ;
if (!longruns[i].pipeline[h]) return nlong ;
avltree_search(&names_map, data.s + longruns[i].pipeline[h], &j) ;
@@ -700,7 +685,7 @@ static uint32_t resolve_prodcons (longrun_t const *longruns, unsigned int i, int
{
case SVTYPE_LONGRUN :
{
- unsigned int k ;
+ uint32_t k ;
nameinfo_t const *q ;
avltree_search(&names_map, data.s + longruns[p->i].pipeline[!h], &k) ;
q = genalloc_s(nameinfo_t, &nameinfo) + k ;
@@ -808,7 +793,6 @@ static inline void flatlist_services (s6rc_db_t *db, unsigned char const *sarray
}
-
/* Write the compiled database */
@@ -884,7 +868,7 @@ static inline void init_compiled (char const *compiled)
int compiledlock ;
if (mkdir(compiled, 0755) < 0)
strerr_diefu2sys(111, "mkdir ", compiled) ;
- if (!s6rc_lock(0, 0, 0, compiled, 2, &compiledlock))
+ if (!s6rc_lock(0, 0, 0, compiled, 2, &compiledlock, 0))
strerr_diefu2sys(111, "take lock on ", compiled) ;
auto_dir(compiled, "servicedirs") ;
}
@@ -926,8 +910,9 @@ static void make_skel (char const *compiled, char const *name, uid_t const *uids
auto_dir(compiled, fn) ;
}
-static inline void write_oneshot_runner (char const *compiled, uid_t const *uids, size_t uidn, gid_t const *gids, size_t gidn)
+static inline void write_oneshot_runner (char const *compiled, uid_t const *uids, size_t uidn, gid_t const *gids, size_t gidn, int blocking)
{
+ size_t base = satmp.len ;
size_t i ;
char fn[34 + sizeof(S6RC_ONESHOT_RUNNER)] = "servicedirs/" S6RC_ONESHOT_RUNNER "/data/rules/gid/" ;
make_skel(compiled, S6RC_ONESHOT_RUNNER, uids, uidn, gids, gidn, 3) ;
@@ -953,7 +938,19 @@ static inline void write_oneshot_runner (char const *compiled, uid_t const *uids
memcpy(fn + 28 + S6RC_ONESHOT_RUNNER_LEN + len, "/allow", 7) ;
auto_file(compiled, fn, "", 0) ;
}
- auto_file(compiled, "servicedirs/" S6RC_ONESHOT_RUNNER "/run", S6RC_ONESHOT_RUNNER_RUNSCRIPT, sizeof(S6RC_ONESHOT_RUNNER_RUNSCRIPT) - 1) ;
+ if (!stralloc_cats(&satmp, "#!"
+ EXECLINE_SHEBANGPREFIX "execlineb -P\n"
+ EXECLINE_EXTBINPREFIX "fdmove -c 2 1\n"
+ EXECLINE_EXTBINPREFIX "fdmove 1 3\n"
+ S6_EXTBINPREFIX "s6-ipcserver-socketbinder -- s\n"
+ S6_EXTBINPREFIX "s6-ipcserverd -1 --\n"
+ S6_EXTBINPREFIX "s6-ipcserver-access -v0 -E -l0 -i data/rules --\n"
+ S6_EXTBINPREFIX "s6-sudod -t 2000 --\n"
+ S6RC_EXTLIBEXECPREFIX "s6-rc-oneshot-run -l ../.. ")
+ || (blocking && !stralloc_cats(&satmp, "-b "))
+ || !stralloc_cats(&satmp, "--\n")) dienomem() ;
+ auto_file(compiled, "servicedirs/" S6RC_ONESHOT_RUNNER "/run", satmp.s + base, satmp.len - base) ;
+ satmp.len = base ;
auto_rights(compiled, "servicedirs/" S6RC_ONESHOT_RUNNER "/run", 0755) ;
}
@@ -1058,9 +1055,9 @@ static inline void write_fdholder (char const *compiled, s6rc_db_t const *db, ui
auto_rights(compiled, "servicedirs/" S6RC_FDHOLDER "/run", 0755) ;
}
-static inline void write_specials (char const *compiled, s6rc_db_t const *db, uid_t const *uids, size_t uidn, gid_t const *gids, size_t gidn, char const *fdhuser)
+static inline void write_specials (char const *compiled, s6rc_db_t const *db, uid_t const *uids, size_t uidn, gid_t const *gids, size_t gidn, char const *fdhuser, int blocking)
{
- write_oneshot_runner(compiled, uids, uidn, gids, gidn) ;
+ write_oneshot_runner(compiled, uids, uidn, gids, gidn, blocking) ;
write_fdholder(compiled, db, uids, uidn, gids, gidn, fdhuser) ;
}
@@ -1367,7 +1364,8 @@ static inline void write_compiled (
size_t uidn,
gid_t const *gids,
size_t gidn,
- char const *fdhuser)
+ char const *fdhuser,
+ int blocking)
{
if (verbosity >= 2) strerr_warni2x("writing compiled information to ", compiled) ;
init_compiled(compiled) ;
@@ -1375,7 +1373,7 @@ static inline void write_compiled (
write_resolve(compiled, db, bundles, nbundles, bdeps) ;
stralloc_free(&data) ;
write_db(compiled, db) ;
- write_specials(compiled, db, uids, uidn, gids, gidn, fdhuser) ;
+ write_specials(compiled, db, uids, uidn, gids, gidn, fdhuser, blocking) ;
write_servicedirs(compiled, db, srcdirs) ;
}
@@ -1384,6 +1382,7 @@ int main (int argc, char const *const *argv)
before_t before = BEFORE_ZERO ;
char const *compiled ;
char const *fdhuser = 0 ;
+ int blocking = 0 ;
size_t uidn = 0, gidn = 0 ;
uid_t uids[256] ;
gid_t gids[256] ;
@@ -1392,7 +1391,7 @@ int main (int argc, char const *const *argv)
subgetopt_t l = SUBGETOPT_ZERO ;
for (;;)
{
- int opt = subgetopt_r(argc, argv, "v:u:g:h:", &l) ;
+ int opt = subgetopt_r(argc, argv, "v:u:g:h:b", &l) ;
if (opt == -1) break ;
switch (opt)
{
@@ -1400,6 +1399,7 @@ int main (int argc, char const *const *argv)
case 'u' : if (!uid_scanlist(uids, 255, l.arg, &uidn)) dieusage() ; break ;
case 'g' : if (!gid_scanlist(gids, 255, l.arg, &gidn)) dieusage() ; break ;
case 'h' : fdhuser = l.arg ; break ;
+ case 'b' : blocking = 1 ; break ;
default : dieusage() ;
}
}
@@ -1446,7 +1446,7 @@ int main (int argc, char const *const *argv)
uint32_t deps[db.ndeps << 1] ;
db.deps = deps ;
flatlist_services(&db, sarray) ;
- write_compiled(compiled, &db, srcdirs, bundles, nbundles, bdeps, uids, uidn, gids, gidn, fdhuser) ;
+ write_compiled(compiled, &db, srcdirs, bundles, nbundles, bdeps, uids, uidn, gids, gidn, fdhuser, blocking) ;
}
}
diff --git a/src/s6-rc/s6-rc-db.c b/src/s6-rc/s6-rc-db.c
index 8e4b92a..ce983dc 100644
--- a/src/s6-rc/s6-rc-db.c
+++ b/src/s6-rc/s6-rc-db.c
@@ -13,7 +13,7 @@
#include <s6-rc/config.h>
#include <s6-rc/s6rc.h>
-#define USAGE "s6-rc-db [ -u | -d ] [ -l live ] [ -c compiled ] command... (use s6-rc-db help for more information)"
+#define USAGE "s6-rc-db [ -u | -d ] [ -l live ] [ -c compiled ] [ -b ] command... (use s6-rc-db help for more information)"
#define dieusage() strerr_dieusage(100, USAGE)
static char const *compiled = 0 ;
@@ -344,12 +344,13 @@ int main (int argc, char const *const *argv)
char const *live = S6RC_LIVE_BASE ;
unsigned int what, subwhat = 0 ;
int up = 1 ;
+ int blocking = 0 ;
PROG = "s6-rc-db" ;
{
subgetopt_t l = SUBGETOPT_ZERO ;
for (;;)
{
- int opt = subgetopt_r(argc, argv, "udl:c:", &l) ;
+ int opt = subgetopt_r(argc, argv, "udl:c:b", &l) ;
if (opt == -1) break ;
switch (opt)
{
@@ -357,6 +358,7 @@ int main (int argc, char const *const *argv)
case 'c' : compiled = l.arg ; break ;
case 'u' : up = 1 ; break ;
case 'd' : up = 0 ; break ;
+ case 'b' : blocking = 1 ; break ;
default : dieusage() ;
}
}
@@ -387,7 +389,7 @@ int main (int argc, char const *const *argv)
compiled = compiledblob ;
}
- if (!s6rc_lock(0, 0, 0, compiled, 1, &compiledlock))
+ if (!s6rc_lock(0, 0, 0, compiled, 1, &compiledlock, blocking))
strerr_diefu2sys(111, "take lock on ", compiled) ;
fdcompiled = open_readb(compiled) ;
if (fdcompiled < 0)
diff --git a/src/s6-rc/s6-rc-init.c b/src/s6-rc/s6-rc-init.c
index 386fbe7..c749609 100644
--- a/src/s6-rc/s6-rc-init.c
+++ b/src/s6-rc/s6-rc-init.c
@@ -14,7 +14,7 @@
#include <s6-rc/config.h>
#include <s6-rc/s6rc.h>
-#define USAGE "s6-rc-init [ -c compiled ] [ -l live ] [ -t timeout ] scandir"
+#define USAGE "s6-rc-init [ -c compiled ] [ -l live ] [ -t timeout ] [ -b ] scandir"
#define dieusage() strerr_dieusage(100, USAGE)
#define dienomem() strerr_diefu1sys(111, "stralloc_catb")
@@ -37,19 +37,21 @@ int main (int argc, char const *const *argv)
size_t dirlen ;
char const *live = S6RC_LIVE_BASE ;
char const *compiled = S6RC_COMPILED_BASE ;
+ int blocking = 0 ;
PROG = "s6-rc-init" ;
{
unsigned int t = 0 ;
subgetopt_t l = SUBGETOPT_ZERO ;
for (;;)
{
- int opt = subgetopt_r(argc, argv, "c:l:t:", &l) ;
+ int opt = subgetopt_r(argc, argv, "c:l:t:b", &l) ;
if (opt == -1) break ;
switch (opt)
{
case 'c' : compiled = l.arg ; break ;
case 'l' : live = l.arg ; break ;
case 't' : if (!uint0_scan(l.arg, &t)) dieusage() ; break ;
+ case 'b' : blocking = 1 ; break ;
default : dieusage() ;
}
}
@@ -89,7 +91,7 @@ int main (int argc, char const *const *argv)
unlink(live) ;
rm_rf(satmp.s) ;
if (mkdir(satmp.s, 0755) < 0) strerr_diefu2sys(111, "mkdir ", satmp.s) ;
- if (!s6rc_lock(satmp.s, 2, &fdlock, 0, 0, 0))
+ if (!s6rc_lock(satmp.s, 2, &fdlock, 0, 0, 0, blocking))
{
char tmp[satmp.len] ;
memcpy(tmp, satmp.s, satmp.len) ;
diff --git a/src/s6-rc/s6-rc-oneshot-run.c b/src/s6-rc/s6-rc-oneshot-run.c
index 3bb38a8..01e51ba 100644
--- a/src/s6-rc/s6-rc-oneshot-run.c
+++ b/src/s6-rc/s6-rc-oneshot-run.c
@@ -10,7 +10,7 @@
#include <s6-rc/config.h>
#include <s6-rc/s6rc.h>
-#define USAGE "s6-rc-oneshot-run [ -l live ] up|down servicenumber"
+#define USAGE "s6-rc-oneshot-run [ -l live ] [ -b ] up|down servicenumber"
#define dieusage() strerr_dieusage(100, USAGE)
int main (int argc, char const *const *argv, char const *const *envp)
@@ -18,16 +18,18 @@ int main (int argc, char const *const *argv, char const *const *envp)
char const *live = S6RC_LIVE_BASE ;
unsigned int number ;
int up ;
+ int blocking = 0 ;
PROG = "s6-rc-oneshot-run" ;
{
subgetopt_t l = SUBGETOPT_ZERO ;
for (;;)
{
- int opt = subgetopt_r(argc, argv, "l:", &l) ;
+ int opt = subgetopt_r(argc, argv, "l:b", &l) ;
if (opt == -1) break ;
switch (opt)
{
case 'l' : live = l.arg ; break ;
+ case 'b' : blocking = 1 ; break ;
default : dieusage() ;
}
}
@@ -48,7 +50,7 @@ int main (int argc, char const *const *argv, char const *const *envp)
memcpy(compiled, live, livelen) ;
memcpy(compiled + livelen, "/compiled", 10) ;
- if (!s6rc_lock(0, 0, 0, compiled, 1, &compiledlock))
+ if (!s6rc_lock(0, 0, 0, compiled, 1, &compiledlock, blocking))
strerr_diefu2sys(111, "take lock on ", compiled) ;
fdcompiled = open_readb(compiled) ;
if (fdcompiled < 0)
diff --git a/src/s6-rc/s6-rc-update.c b/src/s6-rc/s6-rc-update.c
index 4008388..5f4d25e 100644
--- a/src/s6-rc/s6-rc-update.c
+++ b/src/s6-rc/s6-rc-update.c
@@ -27,7 +27,7 @@
#include <s6-rc/config.h>
#include <s6-rc/s6rc.h>
-#define USAGE "s6-rc-update [ -n ] [ -v verbosity ] [ -t timeout ] [ -l live ] [ -f conversion_file ] newdb"
+#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") ;
@@ -611,13 +611,14 @@ int main (int argc, char const *const *argv, char const *const *envp)
char const *convfile = "/dev/null" ;
tain_t deadline ;
int dryrun = 0 ;
+ int blocking = 0 ;
PROG = "s6-rc-update" ;
{
unsigned int t = 0 ;
subgetopt_t l = SUBGETOPT_ZERO ;
for (;;)
{
- int opt = subgetopt_r(argc, argv, "v:t:nl:f:", &l) ;
+ int opt = subgetopt_r(argc, argv, "v:t:nl:f:b", &l) ;
if (opt == -1) break ;
switch (opt)
{
@@ -626,6 +627,7 @@ int main (int argc, char const *const *argv, char const *const *envp)
case 'n' : dryrun = 1 ; break ;
case 'l' : live = l.arg ; break ;
case 'f' : convfile = l.arg ; break ;
+ case 'b' : blocking = 1 ; break ;
default : dieusage() ;
}
}
@@ -658,9 +660,9 @@ int main (int argc, char const *const *argv, char const *const *envp)
memcpy(dbfn, live, livelen) ;
memcpy(dbfn + livelen, "/compiled", 10) ;
- if (!s6rc_lock(live, 2, &livelock, dbfn, 1, &oldlock))
+ if (!s6rc_lock(live, 2, &livelock, dbfn, 1, &oldlock, blocking))
strerr_diefu4sys(111, "take lock on ", live, " and ", dbfn) ;
- if (!s6rc_lock(0, 0, 0, argv[0], 1, &newlock))
+ if (!s6rc_lock(0, 0, 0, argv[0], 1, &newlock, blocking))
strerr_diefu2sys(111, "take lock on ", argv[0]) ;
diff --git a/src/s6-rc/s6-rc.c b/src/s6-rc/s6-rc.c
index f81d38d..615cbf8 100644
--- a/src/s6-rc/s6-rc.c
+++ b/src/s6-rc/s6-rc.c
@@ -21,7 +21,7 @@
#include <s6-rc/config.h>
#include <s6-rc/s6rc.h>
-#define USAGE "s6-rc [ -v verbosity ] [ -n dryrunthrottle ] [ -t timeout ] [ -l live ] [ -u | -d ] [ -p ] [ -a ] help|list|listall|change [ servicenames... ]"
+#define USAGE "s6-rc [ -v verbosity ] [ -n dryrunthrottle ] [ -t timeout ] [ -l live ] [ -b ] [ -u | -d ] [ -p ] [ -a ] help|list|listall|change [ servicenames... ]"
#define dieusage() strerr_dieusage(100, USAGE)
typedef struct pidindex_s pidindex_t ;
@@ -374,7 +374,7 @@ static inline void print_help (void)
int main (int argc, char const *const *argv)
{
- int up = 1, prune = 0, selectlive = 0, takelocks = 1 ;
+ int up = 1, prune = 0, selectlive = 0, takelocks = 1, blocking = 0 ;
unsigned int what ;
PROG = "s6-rc" ;
{
@@ -382,7 +382,7 @@ int main (int argc, char const *const *argv)
subgetopt_t l = SUBGETOPT_ZERO ;
for (;;)
{
- int opt = subgetopt_r(argc, argv, "v:n:t:l:udpaX", &l) ;
+ int opt = subgetopt_r(argc, argv, "v:n:t:l:udpaXb", &l) ;
if (opt == -1) break ;
switch (opt)
{
@@ -401,6 +401,7 @@ int main (int argc, char const *const *argv)
case 'p' : prune = 1 ; break ;
case 'a' : selectlive = 1 ; break ;
case 'X' : takelocks = 0 ; break ;
+ case 'b' : blocking = 1 ; break ;
default : dieusage() ;
}
}
@@ -432,7 +433,7 @@ int main (int argc, char const *const *argv)
if (takelocks)
{
int livelock, compiledlock ;
- if (!s6rc_lock(live, 1 + (what >= 3), &livelock, dbfn, 1, &compiledlock))
+ if (!s6rc_lock(live, 1 + (what >= 3), &livelock, dbfn, 1, &compiledlock, blocking))
strerr_diefu1sys(111, "take locks") ;
if (coe(livelock) < 0)
strerr_diefu3sys(111, "coe ", live, "/lock") ;