diff options
-rw-r--r-- | doc/s6-rc-bundle.html | 11 | ||||
-rw-r--r-- | doc/s6-rc-compile.html | 7 | ||||
-rw-r--r-- | doc/s6-rc-db.html | 27 | ||||
-rw-r--r-- | doc/s6-rc-fdholder-filler.html | 7 | ||||
-rw-r--r-- | doc/s6-rc-init.html | 7 | ||||
-rw-r--r-- | doc/s6-rc-oneshot-run.html | 7 | ||||
-rw-r--r-- | doc/s6-rc-update.html | 7 | ||||
-rw-r--r-- | doc/s6-rc.html | 23 | ||||
-rw-r--r-- | src/include/s6-rc/s6rc-utils.h | 2 | ||||
-rw-r--r-- | src/libs6rc/s6rc_lock.c | 16 | ||||
-rw-r--r-- | src/s6-rc/s6-rc-bundle.c | 8 | ||||
-rw-r--r-- | src/s6-rc/s6-rc-compile.c | 66 | ||||
-rw-r--r-- | src/s6-rc/s6-rc-db.c | 8 | ||||
-rw-r--r-- | src/s6-rc/s6-rc-init.c | 8 | ||||
-rw-r--r-- | src/s6-rc/s6-rc-oneshot-run.c | 8 | ||||
-rw-r--r-- | src/s6-rc/s6-rc-update.c | 10 | ||||
-rw-r--r-- | src/s6-rc/s6-rc.c | 9 |
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> : 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> : 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> : 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> : 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> ] < <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> : 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 <em>live</em></tt> : 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> : 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 <em>convfile</em></tt> : use the conversion file located at <em>convfile</em>. Default is <tt>/dev/null</tt>, meaning no special instructions. </li> + <li> <tt>-b</tt> : 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> : 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") ; |