From 3f6b6d787b4271e84315c46511db5f5778f6ee5d Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Sun, 16 Aug 2015 20:42:56 +0000 Subject: Safer version of pipelines, with an auto-refilling fdholder --- examples/source/klogd-srv/pipeline-name | 2 +- examples/source/klogd/contents | 2 - examples/source/klogd/type | 1 - examples/source/syslogd-srv/pipeline-name | 2 +- examples/source/syslogd/contents | 2 - examples/source/syslogd/type | 1 - package/deps.mak | 9 +- package/modes | 13 +- package/targets.mak | 3 +- src/libs6rc/s6rc_db_check_pipelines.c | 2 +- src/s6-rc/deps-exe/s6-rc-fdholder-filler | 4 + src/s6-rc/deps-exe/s6-rc-update | 1 + src/s6-rc/s6-rc-compile.c | 213 +++++++++++++----------------- src/s6-rc/s6-rc-db.c | 6 +- src/s6-rc/s6-rc-fdholder-filler.c | 77 +++++++++++ 15 files changed, 197 insertions(+), 141 deletions(-) delete mode 100644 examples/source/klogd/contents delete mode 100644 examples/source/klogd/type delete mode 100644 examples/source/syslogd/contents delete mode 100644 examples/source/syslogd/type create mode 100644 src/s6-rc/deps-exe/s6-rc-fdholder-filler create mode 100644 src/s6-rc/s6-rc-fdholder-filler.c diff --git a/examples/source/klogd-srv/pipeline-name b/examples/source/klogd-srv/pipeline-name index 6634002..fd64770 100644 --- a/examples/source/klogd-srv/pipeline-name +++ b/examples/source/klogd-srv/pipeline-name @@ -1 +1 @@ -klogd-srv-pipeline +klogd diff --git a/examples/source/klogd/contents b/examples/source/klogd/contents deleted file mode 100644 index 5bcde2e..0000000 --- a/examples/source/klogd/contents +++ /dev/null @@ -1,2 +0,0 @@ -klogd-srv -klogd-log diff --git a/examples/source/klogd/type b/examples/source/klogd/type deleted file mode 100644 index 757b422..0000000 --- a/examples/source/klogd/type +++ /dev/null @@ -1 +0,0 @@ -bundle diff --git a/examples/source/syslogd-srv/pipeline-name b/examples/source/syslogd-srv/pipeline-name index 73b2e49..96c5cc7 100644 --- a/examples/source/syslogd-srv/pipeline-name +++ b/examples/source/syslogd-srv/pipeline-name @@ -1 +1 @@ -syslogd-srv-pipeline +syslogd diff --git a/examples/source/syslogd/contents b/examples/source/syslogd/contents deleted file mode 100644 index 122bd36..0000000 --- a/examples/source/syslogd/contents +++ /dev/null @@ -1,2 +0,0 @@ -syslogd-srv -syslogd-log diff --git a/examples/source/syslogd/type b/examples/source/syslogd/type deleted file mode 100644 index 757b422..0000000 --- a/examples/source/syslogd/type +++ /dev/null @@ -1 +0,0 @@ -bundle diff --git a/package/deps.mak b/package/deps.mak index a2a4dc4..b4edef6 100644 --- a/package/deps.mak +++ b/package/deps.mak @@ -12,9 +12,10 @@ src/libs6rc/s6rc_db_read_sizes.o src/libs6rc/s6rc_db_read_sizes.lo: src/libs6rc/ 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/s6-rc/s6-rc-compile.o src/s6-rc/s6-rc-compile.lo: src/s6-rc/s6-rc-compile.c src/include/s6-rc/s6rc.h -src/s6-rc/s6-rc-db.o src/s6-rc/s6-rc-db.lo: src/s6-rc/s6-rc-db.c src/include/s6-rc/s6rc.h +src/s6-rc/s6-rc-db.o src/s6-rc/s6-rc-db.lo: src/s6-rc/s6-rc-db.c src/include/s6-rc/config.h src/include/s6-rc/s6rc.h src/s6-rc/s6-rc-dryrun.o src/s6-rc/s6-rc-dryrun.lo: src/s6-rc/s6-rc-dryrun.c -src/s6-rc/s6-rc-init.o src/s6-rc/s6-rc-init.lo: src/s6-rc/s6-rc-init.c src/include/s6-rc/s6rc.h +src/s6-rc/s6-rc-fdholder-filler.o src/s6-rc/s6-rc-fdholder-filler.lo: src/s6-rc/s6-rc-fdholder-filler.c +src/s6-rc/s6-rc-init.o src/s6-rc/s6-rc-init.lo: src/s6-rc/s6-rc-init.c src/include/s6-rc/config.h src/include/s6-rc/s6rc.h 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 @@ -29,7 +30,9 @@ s6-rc-db: private EXTRA_LIBS := s6-rc-db: src/s6-rc/s6-rc-db.o ${LIBS6RC} -lskarnet s6-rc-dryrun: private EXTRA_LIBS := ${TAINNOW_LIB} s6-rc-dryrun: src/s6-rc/s6-rc-dryrun.o -lskarnet +s6-rc-fdholder-filler: private EXTRA_LIBS := ${TAINNOW_LIB} ${SOCKET_LIB} +s6-rc-fdholder-filler: src/s6-rc/s6-rc-fdholder-filler.o -ls6 -lskarnet s6-rc-init: private EXTRA_LIBS := ${TAINNOW_LIB} ${SOCKET_LIB} s6-rc-init: src/s6-rc/s6-rc-init.o ${LIBS6RC} -ls6 -lskarnet -s6-rc-update: private EXTRA_LIBS := ${TAINNOW_LIB} +s6-rc-update: private EXTRA_LIBS := ${TAINNOW_LIB} ${SOCKET_LIB} s6-rc-update: src/s6-rc/s6-rc-update.o ${LIBS6RC} -ls6 -lexecline -lskarnet diff --git a/package/modes b/package/modes index 7bda1d0..d6bd849 100644 --- a/package/modes +++ b/package/modes @@ -1,6 +1,7 @@ -s6-rc-compile 0755 -s6-rc-db 0755 -s6-rc-dryrun 0755 -s6-rc-init 0755 -s6-rc 0755 -s6-rc-update 0755 +s6-rc-compile 0755 +s6-rc-db 0755 +s6-rc-dryrun 0755 +s6-rc-init 0755 +s6-rc 0755 +s6-rc-update 0755 +s6-rc-fdholder-filler 0755 diff --git a/package/targets.mak b/package/targets.mak index 5f50ad4..0f4d396 100644 --- a/package/targets.mak +++ b/package/targets.mak @@ -8,6 +8,7 @@ s6-rc-init \ s6-rc \ s6-rc-update -LIBEXEC_TARGETS := +LIBEXEC_TARGETS := \ +s6-rc-fdholder-filler LIB_DEFS := S6RC=s6rc 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 #include #include +#include #include #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 +#include +#include +#include +#include +#include +#include +#include + +#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 ; +} -- cgit v1.2.3