summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2015-08-16 20:42:56 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2015-08-16 20:42:56 +0000
commit3f6b6d787b4271e84315c46511db5f5778f6ee5d (patch)
treecc1c02da1baa1878eedcce143f7a34217c45544e /src
parent983061db31e02d62359dd8a0cb1e9f125950cfdb (diff)
downloads6-rc-3f6b6d787b4271e84315c46511db5f5778f6ee5d.tar.xz
Safer version of pipelines, with an auto-refilling fdholder
Diffstat (limited to 'src')
-rw-r--r--src/libs6rc/s6rc_db_check_pipelines.c2
-rw-r--r--src/s6-rc/deps-exe/s6-rc-fdholder-filler4
-rw-r--r--src/s6-rc/deps-exe/s6-rc-update1
-rw-r--r--src/s6-rc/s6-rc-compile.c213
-rw-r--r--src/s6-rc/s6-rc-db.c6
-rw-r--r--src/s6-rc/s6-rc-fdholder-filler.c77
6 files changed, 180 insertions, 123 deletions
diff --git a/src/libs6rc/s6rc_db_check_pipelines.c b/src/libs6rc/s6rc_db_check_pipelines.c
index 19dc141..d2547fc 100644
--- a/src/libs6rc/s6rc_db_check_pipelines.c
+++ b/src/libs6rc/s6rc_db_check_pipelines.c
@@ -31,7 +31,7 @@ int s6rc_db_check_pipelines (s6rc_db_t const *db, diuint32 *problem)
j = i ;
for (;;)
{
- register unsigned int k = db->services[j].x.longrun.pipeline[1] ;
+ register uint32 k = db->services[j].x.longrun.pipeline[1] ;
if (k >= db->nlong) break ;
if (k == i || bitarray_peek(black, k))
{
diff --git a/src/s6-rc/deps-exe/s6-rc-fdholder-filler b/src/s6-rc/deps-exe/s6-rc-fdholder-filler
new file mode 100644
index 0000000..ccb415f
--- /dev/null
+++ b/src/s6-rc/deps-exe/s6-rc-fdholder-filler
@@ -0,0 +1,4 @@
+-ls6
+-lskarnet
+${TAINNOW_LIB}
+${SOCKET_LIB}
diff --git a/src/s6-rc/deps-exe/s6-rc-update b/src/s6-rc/deps-exe/s6-rc-update
index ba32165..bebbac1 100644
--- a/src/s6-rc/deps-exe/s6-rc-update
+++ b/src/s6-rc/deps-exe/s6-rc-update
@@ -3,3 +3,4 @@ ${LIBS6RC}
-lexecline
-lskarnet
${TAINNOW_LIB}
+${SOCKET_LIB}
diff --git a/src/s6-rc/s6-rc-compile.c b/src/s6-rc/s6-rc-compile.c
index 57edec9..65b9857 100644
--- a/src/s6-rc/s6-rc-compile.c
+++ b/src/s6-rc/s6-rc-compile.c
@@ -25,6 +25,7 @@
#include <execline/config.h>
#include <execline/execline.h>
#include <s6/config.h>
+#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..."
@@ -42,6 +43,21 @@ 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"
+#define S6RC_FDHOLDER_RUNSCRIPT \
+"#!" EXECLINE_SHEBANGPREFIX "execlineb -P\n" \
+EXECLINE_EXTBINPREFIX "pipeline -dw --\n{\n " \
+EXECLINE_EXTBINPREFIX "if -n --\n {\n " \
+EXECLINE_EXTBINPREFIX "forstdin -x 1 -- i\n " \
+EXECLINE_EXTBINPREFIX "exit 1\n }\n " \
+EXECLINE_EXTBINPREFIX "if -nt --\n {\n " \
+EXECLINE_EXTBINPREFIX "redirfd -r 0 data/pipes-to-create\n " \
+EXECLINE_EXTBINPREFIX "withstdinas PIPES\n " \
+EXECLINE_EXTBINPREFIX "import -u -sd\"\n\" -- PIPES\n " \
+S6_EXTBINPREFIX "s6-ipcclient -l0 -- s\n " \
+S6RC_BINPREFIX "s6-rc-fdholder-filler -1 -- $PIPES\n }\n " \
+S6_EXTBINPREFIX "s6-svc -t .\n}\n" \
+S6_EXTBINPREFIX "s6-fdholder-daemon -1 -i data/rules -- s\n"
+
static unsigned int verbosity = 1 ;
static stralloc keep = STRALLOC_ZERO ;
static stralloc data = STRALLOC_ZERO ;
@@ -255,82 +271,6 @@ static unsigned int add_internal_longrun (before_t *be, char const *name)
return pos ;
}
-static unsigned int add_internal_oneshot (before_t *be, char const *name, char const *ups, unsigned int upn, char const *downs, unsigned int downn)
-{
- unsigned int pos ;
- oneshot_t service =
- {
- .common =
- {
- .ndeps = 2,
- .depindex = genalloc_len(unsigned int, &be->indices),
- .annotation_flags = 0,
- .timeout = { 0, 0 }
- },
- .argvindex = { keep.len, keep.len + downn }
- } ;
- service.argc[0] = byte_count(downs, downn, '\0') ;
- service.argc[1] = byte_count(ups, upn, '\0') ;
- if (!genalloc_catb(unsigned int, &be->indices, be->specialdeps, 2)
- || !stralloc_catb(&keep, downs, downn)
- || !stralloc_catb(&keep, ups, upn)) dienomem() ;
- add_name_nocheck(be, S6RC_INTERNALS, name, SVTYPE_ONESHOT, &pos, &service.common.kname) ;
- if (!genalloc_append(oneshot_t, &be->oneshots, &service)) dienomem() ;
- be->nargvs += service.argc[0] + service.argc[1] + 2 ;
- return pos ;
-}
-
-static void add_word (char const *word)
-{
- if (!stralloc_cats(&satmp, word) || !stralloc_0(&satmp)) dienomem() ;
-}
-
-static unsigned int add_storepipe (before_t *be, char const *name)
-{
- unsigned int pos, sep, base = satmp.len ;
- unsigned int namelen = str_len(name) ;
- char svname[16 + namelen] ;
- byte_copy(svname, 15, "s6rc-storepipe-") ;
- byte_copy(svname + 15, namelen + 1, name) ;
-
- add_word(EXECLINE_EXTBINPREFIX "piperw") ;
- add_word("0") ;
- add_word("1") ;
- add_word(EXECLINE_EXTBINPREFIX "if") ;
- add_word(EXECLINE_BLOCK_QUOTE_STRING S6_EXTBINPREFIX "s6-fdholder-store") ;
- add_word(EXECLINE_BLOCK_QUOTE_STRING "../s6rc-fdholder/s") ;
- add_word(EXECLINE_BLOCK_QUOTE_STRING "pipe:s6rc-r-") ; satmp.len-- ; add_word(name) ;
- add_word(EXECLINE_BLOCK_END_STRING) ;
- add_word(EXECLINE_EXTBINPREFIX "if") ;
- add_word("-nt") ;
- add_word(EXECLINE_BLOCK_QUOTE_STRING S6_EXTBINPREFIX "s6-fdholder-store") ;
- add_word(EXECLINE_BLOCK_QUOTE_STRING "-d1") ;
- add_word(EXECLINE_BLOCK_QUOTE_STRING "../s6rc-fdholder/s") ;
- add_word(EXECLINE_BLOCK_QUOTE_STRING "pipe:s6rc-w-") ; satmp.len-- ; add_word(name) ;
- add_word(EXECLINE_BLOCK_END_STRING) ;
- add_word(EXECLINE_EXTBINPREFIX "exit") ;
- add_word("1") ;
-
- sep = satmp.len ;
-
- add_word(EXECLINE_EXTBINPREFIX "foreground") ;
- add_word(EXECLINE_BLOCK_QUOTE_STRING S6_EXTBINPREFIX "s6-fdholder-delete") ;
- add_word(EXECLINE_BLOCK_QUOTE_STRING "../s6rc-fdholder/s") ;
- add_word(EXECLINE_BLOCK_QUOTE_STRING "pipe:s6rc-w-") ; satmp.len-- ; add_word(name) ;
- add_word(EXECLINE_BLOCK_END_STRING) ;
- add_word(EXECLINE_EXTBINPREFIX "foreground") ;
- add_word(EXECLINE_BLOCK_QUOTE_STRING S6_EXTBINPREFIX "s6-fdholder-delete") ;
- add_word(EXECLINE_BLOCK_QUOTE_STRING "../s6rc-fdholder/s") ;
- add_word(EXECLINE_BLOCK_QUOTE_STRING "pipe:s6rc-r-") ; satmp.len-- ; add_word(name) ;
- add_word(EXECLINE_BLOCK_END_STRING) ;
- add_word(EXECLINE_EXTBINPREFIX "exit") ;
- add_word("0") ;
-
- pos = add_internal_oneshot(be, svname, satmp.s + base, sep - base, satmp.s + sep, satmp.len - sep) ;
- satmp.len = base ;
- return pos ;
-}
-
static int uint_uniq (unsigned int const *list, unsigned int n, unsigned int pos)
{
while (n--) if (pos == list[n]) return 0 ;
@@ -498,16 +438,8 @@ static inline void add_longrun (before_t *be, int dirfd, char const *srcdir, cha
if (n != 1)
strerr_dief5x(1, srcdir, "/", name, "/producer-for", " should only contain one service name") ;
service.pipeline[1] = genalloc_s(unsigned int, &be->indices)[relatedindex] ;
- {
- unsigned int dummy ;
- unsigned int namelen = str_len(data.s + service.pipeline[1]) ;
- char svname[16 + namelen] ;
- byte_copy(svname, 15, "s6rc-storepipe-") ;
- byte_copy(svname + 15, namelen + 1, data.s + service.pipeline[1]) ;
- add_name_nocheck(be, srcdir, svname, SVTYPE_UNDEFINED, &n, &dummy) ;
- if (!genalloc_append(unsigned int, &be->indices, &n)) dienomem() ;
- service.common.ndeps += 2 ;
- }
+ if (!genalloc_append(unsigned int, &be->indices, &be->specialdeps[1])) dienomem() ;
+ service.common.ndeps += 2 ;
if (verbosity >= 3)
strerr_warni3x(name, " is a producer for ", data.s + service.pipeline[1]) ;
fd = 1 ;
@@ -517,12 +449,15 @@ static inline void add_longrun (before_t *be, int dirfd, char const *srcdir, cha
if (n != 1)
strerr_dief5x(1, srcdir, "/", name, "/consumer-for", " should only contain one service name") ;
service.pipeline[0] = genalloc_s(unsigned int, &be->indices)[relatedindex] ;
+ genalloc_setlen(unsigned int, &be->indices, relatedindex) ;
+ if (!fd)
+ {
+ genalloc_append(unsigned int, &be->indices, &be->specialdeps[1]) ;
+ service.common.ndeps++ ;
+ }
+ else fd = 0 ;
if (verbosity >= 3)
strerr_warni3x(name, " is a consumer for ", data.s + service.pipeline[0]) ;
- n = add_storepipe(be, name) ;
- genalloc_s(unsigned int, &be->indices)[relatedindex] = n ;
- service.common.ndeps++ ;
- fd = 0 ;
}
if (fd && add_namelist(be, dirfd, srcdir, name, "pipeline-name", &relatedindex, &n))
{
@@ -626,16 +561,7 @@ static inline void add_pipeline_bundles (before_t *be)
strerr_dief5x(1, "longrun service ", keep.s + longruns[j].common.kname, " declares a consumer ", data.s + longruns[j].pipeline[1], " that is not a longrun service") ;
if (!genalloc_append(unsigned int, &be->indices, &info->pos)) dienomem() ;
j = info->i ;
- {
- unsigned int namelen = str_len(data.s + info->pos) ;
- char svname[16 + namelen] ;
- byte_copy(svname, 15, "s6rc-storepipe-") ;
- byte_copy(svname + 15, namelen + 1, data.s + info->pos) ;
- avltree_search(&names_map, svname, &id) ;
- info = genalloc_s(nameinfo_t, &nameinfo) + id ;
- if (!genalloc_append(unsigned int, &be->indices, &info->pos)) dienomem() ;
- }
- bundle.n += 2 ;
+ bundle.n++ ;
}
if (!genalloc_append(bundle_t, &be->bundles, &bundle)) dienomem() ;
}
@@ -750,7 +676,7 @@ static void resolve_deps (common_t const *me, unsigned int nlong, unsigned int n
{
char fmt[UINT_FMT] ;
fmt[uint_fmt(fmt, nlong + p->i)] = 0 ;
- strerr_warnt7x("atomic ", keep.s + me->kname, " depends on oneshot ", data.s + p->pos, " (", fmt, ")") ;
+ strerr_warnt6x(keep.s + me->kname, " depends on oneshot ", data.s + p->pos, " (", fmt, ")") ;
}
break ;
case SVTYPE_LONGRUN :
@@ -759,7 +685,7 @@ static void resolve_deps (common_t const *me, unsigned int nlong, unsigned int n
{
char fmt[UINT_FMT] ;
fmt[uint_fmt(fmt, p->i)] = 0 ;
- strerr_warnt7x("atomic ", keep.s + me->kname, " depends on longrun ", data.s + p->pos, " (", fmt, ")") ;
+ strerr_warnt6x(keep.s + me->kname, " depends on longrun ", data.s + p->pos, " (", fmt, ")") ;
}
break ;
case SVTYPE_BUNDLE :
@@ -768,7 +694,7 @@ static void resolve_deps (common_t const *me, unsigned int nlong, unsigned int n
{
char fmt[UINT_FMT] ;
fmt[uint_fmt(fmt, nlong + p->i)] = 0 ;
- strerr_warnt4x("atomic ", keep.s + me->kname, " depends on bundle ", data.s + p->pos) ;
+ strerr_warnt3x(keep.s + me->kname, " depends on bundle ", data.s + p->pos) ;
}
break ;
default :
@@ -884,14 +810,14 @@ static inline void flatlist_services (s6rc_db_t *db, unsigned char const *sarray
if (verbosity >= 3) strerr_warni1x("checking database correctness") ;
if (s6rc_db_check_depcycles(db, 1, &problem))
- strerr_dief4x(1, "cyclic service dependency involving", db->string + db->services[problem.left].name, " and ", db->string + db->services[problem.right].name) ;
+ strerr_dief5x(1, "cyclic service dependency", " reached from ", db->string + db->services[problem.left].name, " and involving ", db->string + db->services[problem.right].name) ;
r = s6rc_db_check_pipelines(db, &problem) ;
if (r)
{
if (r == 1)
- strerr_dief4x(1, "cyclic longrun pipeline involving", db->string + db->services[problem.left].name, " and ", db->string + db->services[problem.right].name) ;
+ strerr_dief5x(1, "cyclic longrun pipeline", " reached from ", db->string + db->services[problem.left].name, " and involving ", db->string + db->services[problem.right].name) ;
else
- strerr_dief4x(1, "longrun pipeline collision involving", db->string + db->services[problem.left].name, " and ", db->string + db->services[problem.right].name) ;
+ strerr_dief5x(1, "longrun pipeline collision", " reached from ", db->string + db->services[problem.left].name, " and involving ", db->string + db->services[problem.right].name) ;
}
}
@@ -986,16 +912,18 @@ static inline void write_sizes (char const *compiled, s6rc_db_t const *db)
auto_file(compiled, "n", pack, 20) ;
}
-static void make_skel (char const *compiled, char const *name, uint64 const *uids, unsigned int uidn, gid_t const *gids, unsigned int gidn)
+static void make_skel (char const *compiled, char const *name, uint64 const *uids, unsigned int uidn, gid_t const *gids, unsigned int gidn, unsigned int notif)
{
unsigned int namelen = str_len(name) ;
- unsigned int i = uidn ;
+ char fmt[UINT_FMT] ;
+ unsigned int i = uint_fmt(fmt, notif) ;
+ fmt[i++] = '\n' ;
char fn[UINT64_FMT + namelen + 35] ;
byte_copy(fn, 12, "servicedirs/") ;
byte_copy(fn + 12, namelen + 1, name) ;
auto_dir(compiled, fn) ;
byte_copy(fn + 12 + namelen, 17, "/notification-fd") ;
- auto_file(compiled, fn, "3\n", 2) ;
+ auto_file(compiled, fn, fmt, i) ;
byte_copy(fn + 13 + namelen, 5, "data") ;
auto_dir(compiled, fn) ;
byte_copy(fn + 17 + namelen, 7, "/rules") ;
@@ -1008,6 +936,7 @@ static void make_skel (char const *compiled, char const *name, uint64 const *uid
byte_copy(fn + 23 + namelen, 5, "/uid") ;
auto_dir(compiled, fn) ;
fn[27 + namelen] = '/' ;
+ i = uidn ;
while (i--)
{
unsigned int len = uint64_fmt(fn + 28 + namelen, uids[i]) ;
@@ -1029,15 +958,42 @@ static void make_skel (char const *compiled, char const *name, uint64 const *uid
static inline void write_oneshot_runner (char const *compiled, uint64 const *uids, unsigned int uidn, gid_t const *gids, unsigned int gidn)
{
- make_skel(compiled, S6RC_ONESHOT_RUNNER, uids, uidn, gids, gidn) ;
+ make_skel(compiled, S6RC_ONESHOT_RUNNER, uids, uidn, gids, gidn, 3) ;
auto_file(compiled, "servicedirs/" S6RC_ONESHOT_RUNNER "/run", S6RC_ONESHOT_RUNNER_RUNSCRIPT, sizeof(S6RC_ONESHOT_RUNNER_RUNSCRIPT) - 1) ;
auto_rights(compiled, "servicedirs/" S6RC_ONESHOT_RUNNER "/run", 0755) ;
}
-static inline void write_fdholder (char const *compiled, uint64 const *uids, unsigned int uidn, gid_t const *gids, unsigned int gidn, char const *fdhuser)
+static inline int write_pipelines (stralloc *sa, s6rc_db_t const *db)
+{
+ uint32 i = db->nlong ;
+ unsigned char black[bitarray_div8(db->nlong)] ;
+ byte_zero(black, bitarray_div8(db->nlong)) ;
+ while (i--) if (!bitarray_peek(black, i))
+ {
+ uint32 j = i ;
+ for (;;)
+ {
+ register uint32 k = db->services[j].x.longrun.pipeline[0] ;
+ if (k >= db->nlong) break ;
+ j = k ;
+ }
+ for (;;)
+ {
+ register uint32 k = db->services[j].x.longrun.pipeline[1] ;
+ bitarray_set(black, j) ;
+ if (k >= db->nlong) break ;
+ if (!string_quote(sa, db->string + db->services[k].name, str_len(db->string + db->services[k].name))
+ || !stralloc_catb(sa, " ", 1)) return 0 ;
+ j = k ;
+ }
+ }
+ return 1 ;
+}
+
+static inline void write_fdholder (char const *compiled, s6rc_db_t const *db, uint64 const *uids, unsigned int uidn, gid_t const *gids, unsigned int gidn, char const *fdhuser)
{
unsigned int base = satmp.len ;
- make_skel(compiled, S6RC_FDHOLDER, uids, uidn, gids, gidn) ;
+ make_skel(compiled, S6RC_FDHOLDER, uids, uidn, gids, gidn, 1) ;
{
char fn[62 + S6RC_FDHOLDER_LEN + UINT64_FMT] = "servicedirs/" S6RC_FDHOLDER "/data/rules/uid/" ;
char fmt[7 + UINT64_FMT] = "../uid/" ;
@@ -1074,9 +1030,17 @@ static inline void write_fdholder (char const *compiled, uint64 const *uids, uns
}
if (!stralloc_cats(&satmp,
- "#!" EXECLINE_SHEBANGPREFIX "execlineb -P\n" \
- EXECLINE_EXTBINPREFIX "fdmove -c 2 1\n" \
- EXECLINE_EXTBINPREFIX "fdmove 1 3\n")) dienomem() ;
+ "#!" EXECLINE_SHEBANGPREFIX "execlineb -P\n"
+ EXECLINE_EXTBINPREFIX "pipeline -dw --\n{\n "
+ EXECLINE_EXTBINPREFIX "if -n --\n {\n "
+ EXECLINE_EXTBINPREFIX "forstdin -x 1 -- i\n "
+ EXECLINE_EXTBINPREFIX "exit 1\n }\n "
+ EXECLINE_EXTBINPREFIX "if -nt --\n {\n "
+ S6_EXTBINPREFIX "s6-ipcclient -l0 -- s\n "
+ S6RC_BINPREFIX "s6-rc-fdholder-filler -1 -- ")
+ || !write_pipelines(&satmp, db)
+ || !stralloc_cats(&satmp, "\n }\n "
+ S6_EXTBINPREFIX "s6-svc -t .\n}\n")) dienomem() ;
if (fdhuser)
{
if (!stralloc_cats(&satmp, S6_EXTBINPREFIX "s6-envuidgid -i -- ")
@@ -1094,10 +1058,10 @@ static inline void write_fdholder (char const *compiled, uint64 const *uids, uns
auto_rights(compiled, "servicedirs/" S6RC_FDHOLDER "/run", 0755) ;
}
-static inline void write_specials (char const *compiled, uint64 const *uids, unsigned int uidn, gid_t const *gids, unsigned int gidn, char const *fdhuser)
+static inline void write_specials (char const *compiled, s6rc_db_t const *db, uint64 const *uids, unsigned int uidn, gid_t const *gids, unsigned int gidn, char const *fdhuser)
{
write_oneshot_runner(compiled, uids, uidn, gids, gidn) ;
- write_fdholder(compiled, uids, uidn, gids, gidn, fdhuser) ;
+ write_fdholder(compiled, db, uids, uidn, gids, gidn, fdhuser) ;
}
static inline void write_resolve (char const *compiled, s6rc_db_t const *db, bundle_t const *bundles, unsigned int nbundles, uint32 const *bdeps)
@@ -1427,7 +1391,18 @@ static inline void write_db (char const *compiled, s6rc_db_t const *db)
strerr_diefu2sys(111, "write to ", dbfn) ;
}
-static inline void write_compiled (char const *compiled, s6rc_db_t const *db, char const *const *srcdirs, bundle_t const *bundles, unsigned int nbundles, uint32 const *bdeps, uint64 const *uids, unsigned int uidn, gid_t const *gids, unsigned int gidn, char const *fdhuser)
+static inline void write_compiled (
+ char const *compiled,
+ s6rc_db_t const *db,
+ char const *const *srcdirs,
+ bundle_t const *bundles,
+ unsigned int nbundles,
+ uint32 const *bdeps,
+ uint64 const *uids,
+ unsigned int uidn,
+ gid_t const *gids,
+ unsigned int gidn,
+ char const *fdhuser)
{
if (verbosity >= 2) strerr_warni2x("writing compiled information to ", compiled) ;
init_compiled(compiled) ;
@@ -1435,7 +1410,7 @@ static inline void write_compiled (char const *compiled, s6rc_db_t const *db, ch
write_resolve(compiled, db, bundles, nbundles, bdeps) ;
stralloc_free(&data) ;
write_db(compiled, db) ;
- write_specials(compiled, uids, uidn, gids, gidn, fdhuser) ;
+ write_specials(compiled, db, uids, uidn, gids, gidn, fdhuser) ;
write_servicedirs(compiled, db, srcdirs) ;
}
diff --git a/src/s6-rc/s6-rc-db.c b/src/s6-rc/s6-rc-db.c
index 97f0956..a89b1e4 100644
--- a/src/s6-rc/s6-rc-db.c
+++ b/src/s6-rc/s6-rc-db.c
@@ -440,14 +440,14 @@ int main (int argc, char const *const *argv)
if (s6rc_db_check_revdeps(&dbblob))
strerr_dief3x(4, "invalid service database in ", compiled, ": direct and reverse dependencies are mismatched") ;
if (s6rc_db_check_depcycles(&dbblob, 1, &problem))
- strerr_dief8x(4, "invalid service database in ", compiled, ": dependency ", "cycle", " involving ", stringblob + serviceblob[problem.left].name, " and ", stringblob + serviceblob[problem.right].name) ;
+ strerr_dief8x(4, "invalid service database in ", compiled, ": dependency ", "cycle", " reached from ", stringblob + serviceblob[problem.left].name, " and involving ", stringblob + serviceblob[problem.right].name) ;
r = s6rc_db_check_pipelines(&dbblob, &problem) ;
if (r)
{
if (r == 1)
- strerr_dief8x(4, "invalid service database in ", compiled, ": pipeline ", "cycle", " involving ", stringblob + serviceblob[problem.left].name, " and ", stringblob + serviceblob[problem.right].name) ;
+ strerr_dief8x(4, "invalid service database in ", compiled, ": pipeline ", "cycle", " reached from ", stringblob + serviceblob[problem.left].name, " and involving ", stringblob + serviceblob[problem.right].name) ;
else
- strerr_dief8x(4, "invalid service database in ", compiled, ": pipeline ", "collision", " involving ", stringblob + serviceblob[problem.left].name, " and ", stringblob + serviceblob[problem.right].name) ;
+ strerr_dief8x(4, "invalid service database in ", compiled, ": pipeline ", "collision", " reached from ", stringblob + serviceblob[problem.left].name, " and involving ", stringblob + serviceblob[problem.right].name) ;
}
break ;
}
diff --git a/src/s6-rc/s6-rc-fdholder-filler.c b/src/s6-rc/s6-rc-fdholder-filler.c
new file mode 100644
index 0000000..06afdee
--- /dev/null
+++ b/src/s6-rc/s6-rc-fdholder-filler.c
@@ -0,0 +1,77 @@
+/* ISC license. */
+
+#include <unistd.h>
+#include <errno.h>
+#include <skalibs/uint.h>
+#include <skalibs/bytestr.h>
+#include <skalibs/strerr2.h>
+#include <skalibs/sgetopt.h>
+#include <skalibs/tai.h>
+#include <s6/s6-fdholder.h>
+
+#define USAGE "s6-rc-fdholder-filler [ -1 ] [ -t timeout ] longrunnames..."
+#define dieusage() strerr_dieusage(100, USAGE)
+
+int main (int argc, char const *const *argv)
+{
+ s6_fdholder_t a = S6_FDHOLDER_ZERO ;
+ tain_t deadline ;
+ int notif = 0 ;
+ PROG = "s6-rc-fdholder-filler" ;
+ {
+ unsigned int t = 0 ;
+ subgetopt_t l = SUBGETOPT_ZERO ;
+ for (;;)
+ {
+ register int opt = subgetopt_r(argc, argv, "1t:", &l) ;
+ if (opt == -1) break ;
+ switch (opt)
+ {
+ case '1': notif = 1 ; break ;
+ case 't': if (!uint0_scan(l.arg, &t)) dieusage() ; break ;
+ default : strerr_dieusage(100, USAGE) ;
+ }
+ }
+ argc -= l.ind ; argv += l.ind ;
+ if (t) tain_from_millisecs(&deadline, t) ;
+ else deadline = tain_infinite_relative ;
+ }
+
+ s6_fdholder_init(&a, 6) ;
+ tain_now_g() ;
+ tain_add_g(&deadline, &deadline) ;
+ if (argc)
+ {
+ tain_t offset = { .sec = TAI_ZERO } ;
+ int p[2] ;
+ unsigned int n = argc ;
+ unsigned int i = 0 ;
+ s6_fdholder_fd_t dump[n<<1] ;
+ for (; i < n ; i++)
+ {
+ unsigned int len = str_len(argv[i]) ;
+ if (len + 12 > S6_FDHOLDER_ID_SIZE)
+ {
+ errno = ENAMETOOLONG ;
+ strerr_diefu2sys(111, "create identifier for ", argv[i]) ;
+ }
+ if (pipe(p) < 0)
+ strerr_diefu1sys(111, "create pipe") ;
+ dump[i<<1].fd = p[0] ;
+ tain_add_g(&dump[i<<1].limit, &tain_infinite_relative) ;
+ offset.nano = i << 1 ;
+ tain_add(&dump[i<<1].limit, &dump[i<<1].limit, &offset) ;
+ byte_copy(dump[i<<1].id, 12, "pipe:s6rc-r-") ;
+ byte_copy(dump[i<<1].id + 12, len + 1, argv[i]) ;
+ dump[(i<<1)+1].fd = p[1] ;
+ offset.nano = 1 ;
+ tain_add(&dump[(i<<1)+1].limit, &dump[i<<1].limit, &offset) ;
+ byte_copy(dump[(i<<1)+1].id, 12 + len, dump[i<<1].id) ;
+ dump[(i<<1)+1].id[10] = 'w' ;
+ }
+ if (!s6_fdholder_setdump_g(&a, dump, n << 1, &deadline))
+ strerr_diefu1sys(111, "transfer pipes") ;
+ }
+ if (notif) write(1, "\n", 1) ;
+ return 0 ;
+}