From 9fdde3fe9f514f021728db63f387593c273f028e Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Tue, 14 Jul 2015 20:11:53 +0000 Subject: Various bugfixes, thanks Colin Booth (haven't touched the timeouts yet) --- src/include/s6-rc/s6rc-db.h | 1 - src/libs6rc/s6rc_db_read.c | 19 ++++++++----------- src/s6-rc/s6-rc-compile.c | 29 ++++++++++++++--------------- src/s6-rc/s6-rc-db.c | 39 +++++++++++++-------------------------- src/s6-rc/s6-rc.c | 25 +++++++++++++++++-------- 5 files changed, 52 insertions(+), 61 deletions(-) (limited to 'src') diff --git a/src/include/s6-rc/s6rc-db.h b/src/include/s6-rc/s6rc-db.h index cc2bb9f..bc516b2 100644 --- a/src/include/s6-rc/s6rc-db.h +++ b/src/include/s6-rc/s6rc-db.h @@ -41,7 +41,6 @@ struct s6rc_service_s uint32 ndeps[2] ; uint32 timeout[2] ; s6rc_longshot_t x ; - unsigned char type : 1 ; } ; typedef struct s6rc_db_s s6rc_db_t, *s6rc_db_t_ref ; diff --git a/src/libs6rc/s6rc_db_read.c b/src/libs6rc/s6rc_db_read.c index f10462c..7a38797 100644 --- a/src/libs6rc/s6rc_db_read.c +++ b/src/libs6rc/s6rc_db_read.c @@ -53,13 +53,10 @@ static inline int s6rc_db_read_services (buffer *b, s6rc_db_t *db) s6rc_service_t *sv = db->services ; unsigned int nargvs = db->nargvs ; unsigned int argvpos = 0 ; - char type ; -#ifdef DEBUG register unsigned int i = 0 ; -#endif - while (n--) + for (; i < n ; i++) { - DBG("iteration %u - %u remaining", i++, n) ; + DBG("iteration %u/%u remaining", i+1, n) ; if (!s6rc_db_read_uint32(b, &sv->name)) return -1 ; DBG(" name is %u: %s", sv->name, db->string + sv->name) ; if (sv->name >= db->stringlen) return 0 ; @@ -91,10 +88,8 @@ static inline int s6rc_db_read_services (buffer *b, s6rc_db_t *db) DBG(" dep on %u", db->deps[db->ndeps + sv->deps[1] + k]) ; } #endif - if (buffer_get(b, &type, 1) < 1) return -1 ; - if (type) + if (i < db->nlong) { - sv->type = 1 ; if (!s6rc_db_read_uint32(b, &sv->x.longrun.servicedir)) return -1 ; DBG(" longrun - servicedir is %u: %s", sv->x.longrun.servicedir, db->string + sv->x.longrun.servicedir) ; if (!s6rc_db_check_valid_string(db->string, db->stringlen, sv->x.longrun.servicedir)) return 0 ; @@ -103,7 +98,6 @@ static inline int s6rc_db_read_services (buffer *b, s6rc_db_t *db) { unsigned int i = 0 ; DBG(" oneshot") ; - sv->type = 0 ; for (; i < 2 ; i++) { uint32 pos, argc ; @@ -121,8 +115,11 @@ static inline int s6rc_db_read_services (buffer *b, s6rc_db_t *db) if (!nargvs--) return 0 ; db->argvs[argvpos++] = 0 ; } } - if (buffer_get(b, &type, 1) < 1) return -1 ; - if (type != '\376') return 0 ; + { + char c ; + if (buffer_get(b, &c, 1) < 1) return -1 ; + if (c != '\376') return 0 ; + } sv++ ; } if (nargvs) return 0 ; diff --git a/src/s6-rc/s6-rc-compile.c b/src/s6-rc/s6-rc-compile.c index 97990a1..7e4e515 100644 --- a/src/s6-rc/s6-rc-compile.c +++ b/src/s6-rc/s6-rc-compile.c @@ -694,7 +694,6 @@ static inline unsigned int resolve_services (s6rc_db_t *db, before_t const *be, byte_zero(sarray, nbits * n) ; for (; i < db->nlong ; i++) { - db->services[i].type = 1 ; db->services[i].name = longruns[i].common.kname ; db->services[i].flags = longruns[i].common.annotation_flags ; db->services[i].timeout[0] = longruns[i].common.timeout[0] ; @@ -706,7 +705,6 @@ static inline unsigned int resolve_services (s6rc_db_t *db, before_t const *be, } for (i = 0 ; i < db->nshort ; i++) { - db->services[db->nlong + i].type = 0 ; db->services[db->nlong + i].name = oneshots[i].common.kname ; db->services[db->nlong + i].flags = oneshots[i].common.annotation_flags ; db->services[db->nlong + i].timeout[0] = oneshots[i].common.timeout[0] ; @@ -1037,9 +1035,9 @@ static inline void write_servicedirs (char const *compiled, s6rc_db_t const *db, } } -static inline int write_service (buffer *b, s6rc_service_t const *sv) +static inline int write_service (buffer *b, s6rc_service_t const *sv, int type) { - char pack[50] ; + char pack[49] ; unsigned int m ; uint32_pack_big(pack, sv->name) ; uint32_pack_big(pack + 4, sv->flags) ; @@ -1049,19 +1047,18 @@ static inline int write_service (buffer *b, s6rc_service_t const *sv) uint32_pack_big(pack + 20, sv->ndeps[1]) ; uint32_pack_big(pack + 24, sv->deps[0]) ; uint32_pack_big(pack + 28, sv->deps[1]) ; - pack[32] = sv->type ; - if (sv->type) + if (type) { - uint32_pack_big(pack + 33, sv->x.longrun.servicedir) ; - m = 37 ; + uint32_pack_big(pack + 32, sv->x.longrun.servicedir) ; + m = 36 ; } else { - uint32_pack_big(pack + 33, sv->x.oneshot.argc[0]) ; - uint32_pack_big(pack + 37, sv->x.oneshot.argv[0]) ; - uint32_pack_big(pack + 41, sv->x.oneshot.argc[1]) ; - uint32_pack_big(pack + 45, sv->x.oneshot.argv[1]) ; - m = 49 ; + uint32_pack_big(pack + 32, sv->x.oneshot.argc[0]) ; + uint32_pack_big(pack + 36, sv->x.oneshot.argv[0]) ; + uint32_pack_big(pack + 40, sv->x.oneshot.argc[1]) ; + uint32_pack_big(pack + 44, sv->x.oneshot.argv[1]) ; + m = 48 ; } pack[m++] = '\376' ; return (buffer_put(b, pack, m) == m) ; @@ -1107,9 +1104,11 @@ static inline void write_db (char const *compiled, s6rc_db_t const *db) } { - unsigned int i = db->nshort + db->nlong ; + unsigned int i = db->nlong ; s6rc_service_t const *sv = db->services ; - while (i--) if (!write_service(&b, sv++)) goto err ; + while (i--) if (!write_service(&b, sv++, 1)) goto err ; + i = db->nshort ; + while (i--) if (!write_service(&b, sv++, 0)) goto err ; } if (buffer_putflush(&b, S6RC_DB_BANNER_END, S6RC_DB_BANNER_END_LEN) < 0) diff --git a/src/s6-rc/s6-rc-db.c b/src/s6-rc/s6-rc-db.c index 8cfe5b9..5d0493c 100644 --- a/src/s6-rc/s6-rc-db.c +++ b/src/s6-rc/s6-rc-db.c @@ -138,7 +138,6 @@ static unsigned int resolve_service (char const *name) int fd = open_readatb(fdcompiled, "resolve.cdb") ; uint32 x ; char pack[4] ; - unsigned int len ; register int r ; if (fd < 0) strerr_diefu3sys(111, "open ", compiled, "/resolve.cdb") ; if (!cdb_init_map(&c, fd, 1)) @@ -146,7 +145,6 @@ static unsigned int resolve_service (char const *name) r = cdb_find(&c, name, str_len(name)) ; if (r < 0) strerr_diefu3sys(111, "read ", compiled, "/resolve.cdb") ; if (!r) strerr_dief3x(1, name, " is not a valid identifier in ", compiled) ; - len = cdb_datalen(&c) >> 2 ; if (cdb_datalen(&c) != 4) return db->nshort + db->nlong ; if (cdb_read(&c, pack, 4, cdb_datapos(&c)) < 0) strerr_diefu3sys(111, "cdb_read ", compiled, "/resolve.cdb") ; @@ -163,7 +161,7 @@ static unsigned int resolve_service (char const *name) static void print_type (char const *name) { unsigned int n = resolve_service(name) ; - char const *s = n >= db->nshort + db->nlong ? "bundle" : db->services[n].type ? "longrun" : "oneshot" ; + char const *s = n >= db->nshort + db->nlong ? "bundle" : n < db->nlong ? "longrun" : "oneshot" ; if (buffer_puts(buffer_1, s) < 0 || buffer_putflush(buffer_1, "\n", 1) < 0) strerr_diefu1sys(111, "write to stdout") ; @@ -192,23 +190,6 @@ static void print_servicedir (char const *name) strerr_diefu1sys(111, "write to stdout") ; } -static void print_deps (char const *name, int h) -{ - uint32 const *p ; - unsigned int ndeps ; - unsigned int n = resolve_service(name) ; - if (n >= db->nshort + db->nlong) - strerr_dief5x(1, "in database ", compiled, ": identifier ", name, " represents a bundle") ; - p = db->deps + h * db->ndeps + db->services[n].deps[h] ; - ndeps = db->services[n].ndeps[h] ; - while (ndeps--) - if (buffer_puts(buffer_1, db->string + db->services[*p++].name) < 0 - || buffer_put(buffer_1, "\n", 1) < 0) - strerr_diefu1sys(111, "write to stdout") ; - if (!buffer_flush(buffer_1)) - strerr_diefu1sys(111, "write to stdout") ; -} - static void print_script (char const *name, int h) { unsigned int argc ; @@ -239,7 +220,7 @@ static inline void print_flags (char const *name) strerr_diefu1sys(111, "write to stdout") ; } -static void print_atomics (char const *const *argv, int h, int doclosure) +static void print_union (char const *const *argv, int h, int isdeps, int doclosure) { unsigned int n = db->nshort + db->nlong ; cdb_t c = CDB_ZERO ; @@ -266,7 +247,13 @@ static void print_atomics (char const *const *argv, int h, int doclosure) uint32_unpack_big(p, &x) ; p += 4 ; if (x >= db->nshort + db->nlong) strerr_dief2x(4, "invalid database in ", compiled) ; - state[x] |= 1 ; + if (isdeps) + { + register uint32 ndeps = db->services[x].ndeps[h] ; + register uint32 const *deps = db->deps + h * db->ndeps + db->services[x].deps[h] ; + while (ndeps--) state[*deps++] |= 1 ; + } + else state[x] |= 1 ; } } } @@ -290,7 +277,7 @@ static inline void print_help (void) "s6-rc-db type servicename\n" "s6-rc-db [ -u | -d ] timeout atomicname\n" "s6-rc-db contents bundlename\n" -"s6-rc-db [ -u | -d ] dependencies servicename\n" +"s6-rc-db [ -u | -d ] dependencies servicename...\n" "s6-rc-db servicedir longrunname\n" "s6-rc-db [ -u | -d ] script oneshotname\n" "s6-rc-db flags atomicname\n" @@ -461,7 +448,7 @@ int main (int argc, char const *const *argv) print_bundle_contents(argv[1]) ; break ; case 6 : /* dependencies */ - print_deps(argv[1], up) ; + print_union(argv + 1, up, 1, 0) ; break ; case 7 : /* servicedir */ print_servicedir(argv[1]) ; @@ -473,10 +460,10 @@ int main (int argc, char const *const *argv) print_flags(argv[1]) ; break ; case 10 : /* atomics */ - print_atomics(argv + 1, 1, 0) ; + print_union(argv + 1, 1, 0, 0) ; break ; case 11 : /* all-dependencies */ - print_atomics(argv + 1, up, 1) ; + print_union(argv + 1, up, 0, 1) ; break ; } } diff --git a/src/s6-rc/s6-rc.c b/src/s6-rc/s6-rc.c index 4cb68b6..381b910 100644 --- a/src/s6-rc/s6-rc.c +++ b/src/s6-rc/s6-rc.c @@ -127,7 +127,7 @@ static pid_t start_longrun (unsigned int i, int h) strerr_warnwu2sys("access ", servicefn) ; } } - byte_copy(servicefn + livelen + 13 + svdlen, 6, "/down") ; + servicefn[livelen + 13 + svdlen] = 0 ; fmt[uint32_fmt(fmt, db->services[i].timeout[h])] = 0 ; vfmt[uint_fmt(vfmt, verbosity)] = 0 ; if (dryrun[0]) @@ -146,27 +146,35 @@ static pid_t start_longrun (unsigned int i, int h) newargv[m++] = "--" ; newargv[m++] = servicefn ; newargv[m++] = 0 ; + return child_spawn0(newargv[0], newargv, (char const *const *)environ) ; +} +static void success_longrun (unsigned int i, int h) +{ if (!dryrun[0]) { + unsigned int svdlen = str_len(db->string + db->services[i].x.longrun.servicedir) ; + char fn[livelen + svdlen + 19] ; + byte_copy(fn, livelen, live) ; + byte_copy(fn + livelen, 13, "/servicedirs/") ; + byte_copy(fn + livelen + 13, svdlen, db->string + db->services[i].x.longrun.servicedir) ; + byte_copy(fn + livelen + 13 + svdlen, 6, "/down") ; if (h) { - if (unlink(servicefn) < 0 && verbosity) - strerr_warnwu2sys("unlink ", servicefn) ; + if (unlink(fn) < 0 && verbosity) + strerr_warnwu2sys("unlink ", fn) ; } else { - int fd = open_trunc(servicefn) ; + int fd = open_trunc(fn) ; if (fd < 0) { if (verbosity) - strerr_warnwu2sys("touch ", servicefn) ; + strerr_warnwu2sys("touch ", fn) ; } else fd_close(fd) ; } } - servicefn[livelen + 13 + svdlen] = 0 ; - return child_spawn0(newargv[0], newargv, (char const *const *)environ) ; } static void broadcast_success (unsigned int, int) ; @@ -185,7 +193,7 @@ static void examine (unsigned int i, int h) } else { - pidindex[npids].pid = db->services[i].type ? start_longrun(i, h) : start_oneshot(i, h) ; + pidindex[npids].pid = i < db->nlong ? start_longrun(i, h) : start_oneshot(i, h) ; if (pidindex[npids].pid) { pidindex[npids++].i = i ; @@ -218,6 +226,7 @@ static void broadcast_success (unsigned int i, int h) static void on_success (unsigned int i, int h) { + if (i < db->nlong) success_longrun(i, h) ; if (h) state[i] |= 1 ; else state[i] &= 254 ; announce() ; if (verbosity >= 2) -- cgit v1.2.3