From 53d7f0de3feeb8ad93bb8c319c3f0f314c7d31cf Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Wed, 21 Jul 2021 13:16:39 +0000 Subject: New id/typenum mapping, monitor filter, cdb in db_load, etc. Signed-off-by: Laurent Bercot --- src/include-local/db.h | 103 ---------------- src/include/s6-rc/db.h | 108 +++++++++++++++++ src/libs6rc/s6rc_db_free.c | 17 +++ src/libs6rc/s6rc_db_load.c | 140 ++++++++++++++++++++++ src/libs6rc/s6rc_service_common.c | 16 +-- src/libs6rc/s6rc_service_common_tn.c | 21 ++++ src/libs6rc/s6rc_service_id.c | 12 ++ src/libs6rc/s6rc_service_num.c | 13 ++ src/libs6rc/s6rc_service_recheck_instance.c | 31 +++++ src/libs6rc/s6rc_service_resolve.c | 13 +- src/libs6rc/s6rc_service_type.c | 13 ++ src/libs6rc/s6rc_service_typenum.c | 13 ++ src/libs6rcd/s6rc_db_free.c | 16 --- src/libs6rcd/s6rc_db_load.c | 129 -------------------- src/libs6rcd/s6rc_service_common.c | 16 --- src/libs6rcd/s6rc_service_resolve.c | 31 ----- src/server/client.c | 19 ++- src/server/client.h | 8 +- src/server/deps.c | 88 ++++++++++++++ src/server/deps.h | 19 +++ src/server/state.c | 179 +++++++++++++++++----------- src/server/state.h | 39 ++++-- 22 files changed, 640 insertions(+), 404 deletions(-) delete mode 100644 src/include-local/db.h create mode 100644 src/include/s6-rc/db.h create mode 100644 src/libs6rc/s6rc_db_free.c create mode 100644 src/libs6rc/s6rc_db_load.c create mode 100644 src/libs6rc/s6rc_service_common_tn.c create mode 100644 src/libs6rc/s6rc_service_id.c create mode 100644 src/libs6rc/s6rc_service_num.c create mode 100644 src/libs6rc/s6rc_service_recheck_instance.c create mode 100644 src/libs6rc/s6rc_service_type.c create mode 100644 src/libs6rc/s6rc_service_typenum.c delete mode 100644 src/libs6rcd/s6rc_db_free.c delete mode 100644 src/libs6rcd/s6rc_db_load.c delete mode 100644 src/libs6rcd/s6rc_service_common.c delete mode 100644 src/libs6rcd/s6rc_service_resolve.c create mode 100644 src/server/deps.c create mode 100644 src/server/deps.h diff --git a/src/include-local/db.h b/src/include-local/db.h deleted file mode 100644 index b35fc42..0000000 --- a/src/include-local/db.h +++ /dev/null @@ -1,103 +0,0 @@ -/* ISC license. */ - -#ifndef S6RCD_SERVICE_H -#define S6RCD_SERVICE_H - -#include - -#include - -#define S6RC_ARGV_MAX 0x00ffffffu -#define S6RC_INSTANCES_MAX 0x00ffffffu -#define S6RC_INSTANCEPARAM_MAXLEN 0x00ffffffu - - /* Service types and db representation in memory */ - -#define S6RC_STYPE_LONGRUN 0 -#define S6RC_STYPE_ONESHOT 1 -#define S6RC_STYPE_EXTERNAL 2 -#define S6RC_STYPE_BUNDLE 3 -#define S6RC_STYPE_VIRTUAL 4 -#define S6RC_STYPE_N 5 - -typedef uint32_t s6rc_id_t, *s6rc_id_t_ref ; - -#define stype(sid) ((sid) >> 28) -#define snum(sid) ((sid) & 0x0fffffffu) - -typedef struct s6rc_common_s s6rc_common_t, *s6rc_common_t_ref ; -struct s6rc_common_s -{ - uint32_t name ; - uint32_t flags ; - uint32_t deps[2] ; - uint32_t ndeps[2] ; -} ; - -#define S6RC_DB_FLAG_ESSENTIAL 0x80000000u -#define S6RC_DB_FLAG_WEAK 0x40000000u - -typedef struct s6rc_atomic_s s6rc_atomic_t, *s6rc_atomic_t_ref ; -struct s6rc_atomic_s -{ - s6rc_common_t common ; - uint32_t timeout[2] ; -} ; - -typedef struct s6rc_oneshot_s s6rc_oneshot_t, *s6rc_oneshot_t_ref ; -struct s6rc_oneshot_s -{ - s6rc_atomic_t satomic ; - uint32_t argv[2] ; -} ; - -typedef struct s6rc_longrun_s s6rc_longrun_t, *s6rc_longrun_t_ref ; -struct s6rc_longrun_s -{ - s6rc_atomic_t satomic ; - uint32_t nproducers ; - uint32_t producers ; - s6rc_id_t consumer ; -} ; - -typedef struct s6rc_external_s s6rc_external_t, *s6rc_external_t_ref ; -struct s6rc_external_s -{ - s6rc_common_t common ; -} ; - -typedef struct s6rc_bundle_s s6rc_bundle_t, *s6rc_bundle_t_ref ; -struct s6rc_bundle_s -{ - s6rc_common_t common ; - uint32_t ncontents ; - uint32_t contents ; -} ; - -#define s6rc_deptype_passive(dep) ((dep) & 0x01u) -#define s6rc_deptype_soft(dep) ((dep) & 0x02u) -#define s6rc_deptype_loose(dep) ((dep) & 0x04u) - -typedef struct s6rc_db_s s6rc_db_t, *s6rc_db_t_ref ; -struct s6rc_db_s -{ - char const *map ; - size_t size ; - uint32_t const *n ; - s6rc_longrun_t const *longruns ; - s6rc_oneshot_t const *oneshots ; - s6rc_external_t const *externals ; - s6rc_bundle_t const *bundles ; - s6rc_bundle_t const *virtuals ; - s6rc_id_t const *deps[2] ; - uint8_t const *deptypes[2] ; - s6rc_id_t const *producers ; - char const *storage ; - char const **argvs ; /* alloced */ -} ; -#define S6RC_DB_ZERO = { .map = 0, .len = 0 } - -extern int s6rc_service_resolve (cdb_t *, char const *, s6rc_id_t *, char const **) ; -extern s6rc_common_t const *s6rc_service_common (s6rc_db_t const *, s6rc_id_t) ; - -#endif diff --git a/src/include/s6-rc/db.h b/src/include/s6-rc/db.h new file mode 100644 index 0000000..be2c46c --- /dev/null +++ b/src/include/s6-rc/db.h @@ -0,0 +1,108 @@ +/* ISC license. */ + +#ifndef S6RCD_SERVICE_H +#define S6RCD_SERVICE_H + +#include +#include + +#include + +#define S6RC_ARGV_MAX 0x00ffffffu +#define S6RC_INSTANCES_MAX 0x00ffffffu +#define S6RC_INSTANCEPARAM_MAXLEN 0x00ffffffu + + /* Service types and db representation in memory */ + +#define S6RC_STYPE_LONGRUN 0 +#define S6RC_STYPE_ONESHOT 1 +#define S6RC_STYPE_EXTERNAL 2 +#define S6RC_STYPE_BUNDLE 3 +#define S6RC_STYPE_VIRTUAL 4 +#define S6RC_STYPE_N 5 + +typedef struct s6rc_common_s s6rc_common_t, *s6rc_common_t_ref ; +struct s6rc_common_s +{ + uint32_t name ; + uint32_t flags ; + uint32_t deps[2] ; + uint32_t ndeps[2] ; +} ; + +#define S6RC_DB_FLAG_ESSENTIAL 0x80000000u +#define S6RC_DB_FLAG_WEAK 0x40000000u + + /* + s6rc_common_t must always be the first field of a service, + so we can cast the pointer to s6rc_longrun_t * and friends + in a C-approved way. + */ + +typedef struct s6rc_atomic_s s6rc_atomic_t, *s6rc_atomic_t_ref ; +struct s6rc_atomic_s +{ + s6rc_common_t common ; + uint32_t timeout[2] ; +} ; + +typedef struct s6rc_longrun_s s6rc_longrun_t, *s6rc_longrun_t_ref ; +struct s6rc_longrun_s +{ + s6rc_atomic_t satomic ; + uint32_t nproducers ; + uint32_t producers ; + s6rc_id_t consumer ; +} ; + +typedef struct s6rc_oneshot_s s6rc_oneshot_t, *s6rc_oneshot_t_ref ; +struct s6rc_oneshot_s +{ + s6rc_atomic_t satomic ; + uint32_t argv[2] ; +} ; + +typedef struct s6rc_external_s s6rc_external_t, *s6rc_external_t_ref ; +struct s6rc_external_s +{ + s6rc_common_t common ; +} ; + +typedef struct s6rc_bundle_s s6rc_bundle_t, *s6rc_bundle_t_ref ; +struct s6rc_bundle_s +{ + s6rc_common_t common ; + uint32_t ncontents ; + uint32_t contents ; +} ; + +typedef struct s6rc_db_s s6rc_db_t, *s6rc_db_t_ref ; +struct s6rc_db_s +{ + char const *map ; + off_t size ; + uint32_t const *n ; + s6rc_longrun_t const *longruns ; + s6rc_oneshot_t const *oneshots ; + s6rc_external_t const *externals ; + s6rc_bundle_t const *bundles ; + s6rc_bundle_t const *virtuals ; + s6rc_id_t const *deps[2] ; + uint8_t const *deptypes[2] ; + s6rc_id_t const *producers ; + char const *storage ; + char const **argvs ; /* alloced */ +} ; +#define S6RC_DB_ZERO = { .map = 0, .len = 0 } + +extern uint32_t s6rc_service_id (uint32_t const *, uint8_t, uint32_t) ; +extern void s6rc_service_typenum (uin32_t const *, uint32_t, uint8_t *, uint32_t *) ; +extern uint8_t s6rc_service_type (uint32_t const *, uint32_t) ; +extern uint32_t s6rc_service_num (uint32_t const *, uint32_t) ; + +extern int s6rc_service_resolve (cdb_t *, char const *, uint32_t *, char const **) ; +extern s6rc_common_t const *s6rc_service_common (s6rc_db_t const *, uint32_t) ; +extern s6rc_common_t const *s6rc_service_common_tn (s6rc_db_t const *, uint8_t, uint32_t) ; +extern int s6rc_service_recheck_instance (s6rc_db_t const *, cdb_t *, uint32_t *, char const **) ; + +#endif diff --git a/src/libs6rc/s6rc_db_free.c b/src/libs6rc/s6rc_db_free.c new file mode 100644 index 0000000..7e7ed54 --- /dev/null +++ b/src/libs6rc/s6rc_db_free.c @@ -0,0 +1,17 @@ +/* ISC license. */ + +#include +#include + +#include + +#include + +void s6rc_db_free (s6rc_db_t *db) +{ + int e = errno ; + alloc_free(db->argvs) ; + munmap(db->map, db->size) ; + db->map = 0 ; + errno = e ; +} diff --git a/src/libs6rc/s6rc_db_load.c b/src/libs6rc/s6rc_db_load.c new file mode 100644 index 0000000..8463e55 --- /dev/null +++ b/src/libs6rc/s6rc_db_load.c @@ -0,0 +1,140 @@ +/* ISC license. */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include + +static int gethu32 (buffer *b, SHA256Schedule *ctx, uint32_t *n) +{ + if (buffer_get(b, (char *)n, 4) < 4) return 0 ; + sha256_update(ctx, (char *)n, 4) ; + return 1 ; +} + +int s6rc_db_load (char const *dir, s6rc_db_t *db, cdb_t *c) +{ + SHA256Schedule ctx = SHA256_INIT() ; + uint32_t ntotal, ndeps, nproducers, storagelen, nargv ; + size_t len = strlen(dir) ; + buffer b ; + int fd ; + char buf[4096] ; + char fn[len + 13] ; + memcpy(fn, dir, len) ; + memcpy(fn + len, "/db_nomap", 10) ; + fd = openc_read(fn) ; + if (fd == -1) return 0 ; + buffer_init(&b, &buffer_read, fd, buf, 4096) ; + { + uint32_t canary ; + if (!gethu32(&b, &canary)) goto err0 ; + if (canary != 0x11223344u) { errno = EILSEQ ; goto err0 ; } + } + if (!gethu32(&b, &ctx, &ntotal)) goto err0 ; + if (!gethu32(&b, &ctx, &ndeps)) goto err0 ; + if (!gethu32(&b, &ctx, &nproducers)) goto err0 ; + if (!gethu32(&b, &ctx, &storagelen)) goto err0 ; + if (!gethu32(&b, &ctx, &nargv)) goto err0 ; + if (nargv > S6RC_ARGV_MAX) goto eproto0 ; + + { + uint32_t argvs[nargv ? nargv : 1] ; + if (buffer_get(&b, (char *)argvs, nargv * 4) < nargv * 4) goto err0 ; + { + char c ; + ssize_t r = buffer_get(&b, &c, 1) ; + if (r < 0) goto err0 ; + if (r) goto eproto0 ; + } + fd_close(fd) ; + sha256_update(&ctx, (char *)argvs, nargv * 4) ; + memcpy(fn + len, "/db", 4) ; + + { + struct stat st ; + void *map ; + fd = openc_read(fn) ; + if (fd == -1) return 0 ; + if (fstat(fd, &st) == -1) goto err0 ; + if (!S_ISREG(st.st_mode)) goto eproto0 ; + if (st.st_size < 8 * S6RC_STYPE_N) goto eproto0 ; + map = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0) ; + if (map == MAP_FAILED) goto err0 ; + fd_close(fd) ; + db->size = st.st_size ; + db->map = map ; + } + db->n = (uint32_t const *)db->map ; + if (ntotal != db->n[0] + db->n[1] + db->n[2] + db->n[3] + db->n[4] + db->n[5] + db->n[6] + db->n[7] + db->n[8] + db->n[9]) + { + errno = EPROTO ; + goto err1 ; + } + + memcpy(fn + len, "/resolve.cdb", 13) ; + if (!cdb_mapfile(fn, c)) goto err1 ; + + { + ssize_t r ; + memcpy(fn + len, "/hash", 6) ; + r = openreadnclose(fn, buf+32, 33) ; + if (r == 33) goto eproto2 ; + if (r < 32) goto err2 ; + sha256_update(&ctx, db->map, db->size) ; + sha256_update(&ctx, c->map, c->size) ; + sha256_final(&ctx, buf) ; + if (memcmp(buf, buf+32, 32)) goto eproto2 ; + } + + db->longruns = (s6rc_longrun_t const *)(db->map + 4 * 2 * S6RC_STYPE_N) ; + db->oneshots = (s6rc_oneshot_t const *)(db->longruns + db->n[S6RC_STYPE_LONGRUN] + db->n[S6RC_STYPE_N + S6RC_STYPE_LONGRUN]) ; + db->externals = (s6rc_external_t const *)(db->oneshots + db->n[S6RC_STYPE_ONESHOT] + db->n[S6RC_STYPE_N + S6RC_STYPE_ONESHOT]) ; + db->bundles = (s6rc_bundle_t const *)(db->externals + db->n[S6RC_STYPE_EXTERNAL] + db->n[S6RC_STYPE_N + S6RC_STYPE_EXTERNAL]) ; + db->virtuals = (s6rc_bundle_t const *)(db->bundles + db->n[S6RC_STYPE_BUNDLE] + db->n[S6RC_STYPE_N + S6RC_STYPE_BUNDLE]) ; + db->deps[0] = (s6rc_id_t const *)(db->virtuals + db->n[S6RC_STYPE_VIRTUAL] + db->n[S6RC_STYPE_N + S6RC_STYPE_VIRTUAL]) ; + db->deps[1] = db->deps[0] + ndeps ; + db->producers = db->deps[1] + ndeps ; + db->deptypes[0] = (uint8_t const *)(db->producers + nproducers) ; + db->deptypes[1] = db->deptypes[0] + ndeps ; + db->storage = (char const *)(db->deptypes[1] + ndeps) ; + if (db->storage + storagelen != db->map + db->size) goto eproto2 ; + + db->argvs = (char const **)alloc(sizeof(char const *) * nargv) ; + if (!db->argvs) goto err2 ; + for (uint32_t i = 0 ; i < nargv ; i++) + db->argvs[i] = argvs[i] ? db->storage + argvs[i] : 0 ; + } + return 1 ; + + eproto2: + errno = EPROTO ; + err2: + cdb_free(c) ; + err1: + { + int e = errno ; + munmap(db->map, db->size) ; + errno = e ; + } + db->map = 0 ; + return 0 ; + + eproto0: + errno = EPROTO ; + err0: + fd_close(fd) ; + return 0 ; +} diff --git a/src/libs6rc/s6rc_service_common.c b/src/libs6rc/s6rc_service_common.c index f3146be..8cbf839 100644 --- a/src/libs6rc/s6rc_service_common.c +++ b/src/libs6rc/s6rc_service_common.c @@ -4,16 +4,10 @@ #include -s6rc_common_t const *s6rc_service_common (s6rc_db_t const *db, s6rc_sid_t const *id) +s6rc_common_t const *s6rc_service_common (s6rc_db_t const *db, uint32_t id) { - uint32_t i = id->i + (id->param ? db->n[id->stype] : 0) ; - switch (id->stype) - { - case STYPE_LONGRUN : return &db->longruns[i].common ; - case STYPE_ONESHOT : return &db->oneshots[i].common ; - case STYPE_EXTERNAL : return &db->externals[i].common ; - case STYPE_BUNDLE : return &db->bundles[i].common ; - case STYPE_VIRTUAL : return &db->virtuals[i].common ; - default : return 0 ; - } + uint32_t num ; + uint8_t type ; + s6rc_service_typenum(db->n, id, &type, &num) ; + return s6rc_service_common_tn(db, type, num) ; } diff --git a/src/libs6rc/s6rc_service_common_tn.c b/src/libs6rc/s6rc_service_common_tn.c new file mode 100644 index 0000000..85ab3b5 --- /dev/null +++ b/src/libs6rc/s6rc_service_common_tn.c @@ -0,0 +1,21 @@ +/* ISC license. */ + +#include + +s6rc_common_t const *s6rc_service_common_tn (s6rc_db_t const *db, uint8_t type, uint32_t num) +{ + switch (type) + { + case STYPE_LONGRUN : return &db->longruns[num].common ; + case S6RC_STYPE_N + STYPE_LONGRUN : return &db->longruns[db->n[S6RC_STYPE_LONGRUN] + num].common ; + case STYPE_ONESHOT : return &db->oneshots[num].common ; + case S6RC_STYPE_N + STYPE_ONESHOT : return &db->oneshots[db->n[S6RC_STYPE_ONESHOT] + num].common ; + case STYPE_EXTERNAL : return &db->externals[num].common ; + case S6RC_STYPE_N + STYPE_EXTERNAL : return &db->externals[db->n[S6RC_STYPE_EXTERNAL] + num].common ; + case STYPE_BUNDLE : return &db->bundles[num].common ; + case S6RC_STYPE_N + STYPE_BUNDLE : return &db->bundles[db->n[S6RC_STYPE_BUNDLE] + num].common ; + case STYPE_VIRTUAL : return &db->virtuals[num].common ; + case S6RC_STYPE_N + STYPE_VIRTUAL : return &db->virtuals[db->n[S6RC_STYPE_VIRTUAL] + num].common ; + default : return 0 ; + } +} diff --git a/src/libs6rc/s6rc_service_id.c b/src/libs6rc/s6rc_service_id.c new file mode 100644 index 0000000..3b23161 --- /dev/null +++ b/src/libs6rc/s6rc_service_id.c @@ -0,0 +1,12 @@ +/* ISC license. */ + +#include + +#include + +uint32_t s6rc_service_id (uint32_t const *dbn, uint8_t type, uint32_t num) +{ + uint32_t acc = 0 ; + for (uint8_t t = 0 ; t < type ; t++) acc += dbn[t] ; + return acc + num ; +} diff --git a/src/libs6rc/s6rc_service_num.c b/src/libs6rc/s6rc_service_num.c new file mode 100644 index 0000000..a70fc82 --- /dev/null +++ b/src/libs6rc/s6rc_service_num.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +#include + +#include + +uint32_t s6rc_service_num (uint32_t const *dbn, uint32_t id) +{ + uint32_t num ; + uint8_t type ; + s6rc_service_typenum(dbn, id, &type, &num) ; + return num ; +} diff --git a/src/libs6rc/s6rc_service_recheck_instance.c b/src/libs6rc/s6rc_service_recheck_instance.c new file mode 100644 index 0000000..b91ea2e --- /dev/null +++ b/src/libs6rc/s6rc_service_recheck_instance.c @@ -0,0 +1,31 @@ +/* ISC license. */ + +#include + +#include +#include + +#include + +int s6rc_service_recheck_instance (s6rc_db_t const *db, cdb_t *c, uint32_t *id, char const **param) +{ + uint8_t type ; + uint32_t num ; + s6rc_service_typenum(db->n, *id) ; + if (type < S6RC_STYPE_N) return 0 ; + else + { + s6rc_common_t *common = s6rc_service_common(db->n, type, num) ; + size_t namelen = strlen(db->storage + common->name) ; + size_t paramlen = strlen(*param) ; + int r ; + char tmp[namelen + paramlen] ; + memcpy(tmp, db->storage + common->name, namelen) ; + memcpy(tmp + namelen, *param, paramlen) ; + r = cdb_find(c, tmp, namelen + paramlen) ; + if (r <= 0) return r ; + } + uint32_unpack_big(cdb_datapos(c), id) ; + *param = 0 ; + return 1 ; +} diff --git a/src/libs6rc/s6rc_service_resolve.c b/src/libs6rc/s6rc_service_resolve.c index 858f67c..52caae7 100644 --- a/src/libs6rc/s6rc_service_resolve.c +++ b/src/libs6rc/s6rc_service_resolve.c @@ -9,11 +9,10 @@ #include -int s6rc_service_resolve (cdb_t *c, s6rc_sid_t *id, char const *s) +int s6rc_service_resolve (cdb_t *c, char const *s, uint32_t *id, char const **param) { size_t len = strlen(s) ; - char const *param = 0 ; - char pack[5] ; + char const *p = 0 ; int r = cdb_find(c, s, len) ; if (r < 0) return r ; if (!r) @@ -23,11 +22,9 @@ int s6rc_service_resolve (cdb_t *c, s6rc_sid_t *id, char const *s) if (at == len - 1) return (errno = EINVAL, -1) ; r = cdb_find(c, s, at + 1) ; if (r <= 0) return r ; - param = s + at + 1 ; + p = s + at + 1 ; } - if (cdb_read(c, pack, 5, cdb_datapos(c)) < 0) return -1 ; - id->stype = pack[0] ; - uint32_unpack_big(pack + 1, &id->i) ; - id->param = param ; + uint32_unpack_big(cdb_datapos(c), id) ; + *param = p ; return 1 ; } diff --git a/src/libs6rc/s6rc_service_type.c b/src/libs6rc/s6rc_service_type.c new file mode 100644 index 0000000..aadd5a3 --- /dev/null +++ b/src/libs6rc/s6rc_service_type.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +#include + +#include + +uint8_t s6rc_service_type (uint32_t const *dbn, uint32_t id) +{ + uint32_t num ; + uint8_t type ; + s6rc_service_typenum(dbn, id, &type, &num) ; + return type ; +} diff --git a/src/libs6rc/s6rc_service_typenum.c b/src/libs6rc/s6rc_service_typenum.c new file mode 100644 index 0000000..3c008c6 --- /dev/null +++ b/src/libs6rc/s6rc_service_typenum.c @@ -0,0 +1,13 @@ +/* ISC license. */ + +#include + +#include + +void s6rc_service_typenum (uint32_t const *db, uint32_t id, uint8_t *type, uint32_t *num) +{ + uint8_t t = 0 ; + while (id >= dbn[t]) id -= dbn[t++] ; + *type = t ; + *num = id ; +} diff --git a/src/libs6rcd/s6rc_db_free.c b/src/libs6rcd/s6rc_db_free.c deleted file mode 100644 index 07f4ccd..0000000 --- a/src/libs6rcd/s6rc_db_free.c +++ /dev/null @@ -1,16 +0,0 @@ -/* ISC license. */ - -#include - -#include - -#include "db.h" - -void s6rc_db_free (s6rc_db_t *db) -{ - int e = errno ; - alloc_free(db->argvs) ; - munmap(db->map, db->size) ; - db->map = 0 ; - errno = e ; -} diff --git a/src/libs6rcd/s6rc_db_load.c b/src/libs6rcd/s6rc_db_load.c deleted file mode 100644 index e42afc9..0000000 --- a/src/libs6rcd/s6rc_db_load.c +++ /dev/null @@ -1,129 +0,0 @@ -/* ISC license. */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "db.h" - -#include - -static int gethu32 (buffer *b, SHA256Schedule *ctx, uint32_t *n) -{ - if (buffer_get(b, (char *)n, 4) < 4) return 0 ; - sha256_update(ctx, (char *)n, 4) ; - return 1 ; -} - -int s6rc_db_load (char const *dir, s6rc_db_t *db) -{ - SHA256Schedule ctx = SHA256_INIT() ; - uint32_t ntotal, ndeps, nproducers, storagelen, nargv ; - size_t len = strlen(dir) ; - buffer b ; - int fd ; - char buf[4096] ; - char fn[len + 10] ; - memcpy(fn, dir, len) ; - memcpy(fn + len, "/db_nomap", 10) ; - fd = openc_read(fn) ; - if (fd == -1) return 0 ; - buffer_init(&b, &buffer_read, fd, buf, 4096) ; - { - uint32_t canary ; - if (!gethu32(&b, &canary)) goto err0 ; - if (canary != 0x11223344u) { errno = EILSEQ ; goto err0 ; } - } - if (!gethu32(&b, &ctx, &ntotal)) goto err0 ; - if (!gethu32(&b, &ctx, &ndeps)) goto err0 ; - if (!gethu32(&b, &ctx, &nproducers)) goto err0 ; - if (!gethu32(&b, &ctx, &storagelen)) goto err0 ; - if (!gethu32(&b, &ctx, &nargv)) goto err0 ; - if (nargv > S6RC_ARGV_MAX) goto eproto0 ; - - { - uint32_t argvs[nargv ? nargv : 1] ; - if (buffer_get(&b, (char *)argvs, nargv * 4) < nargv * 4) goto err0 ; - { - char c ; - ssize_t r = buffer_get(&b, &c, 1) ; - if (r < 0) goto err0 ; - if (r) goto eproto0 ; - } - fd_close(fd) ; - sha256_update(&ctx, (char *)argvs, nargv * 4) ; - memcpy(fn + len, "/db", 4) ; - - { - struct stat st ; - void *map ; - fd = openc_read(fn) ; - if (fd == -1) return 0 ; - if (fstat(fd, &st) == -1) goto err0 ; - if (!S_ISREG(st.st_mode)) goto eproto0 ; - if (st.st_size < 8 * S6RC_STYPE_N) goto eproto0 ; - map = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0) ; - if (map == MAP_FAILED) goto err0 ; - fd_close(fd) ; - db->size = st.st_size ; - db->map = map ; - } - db->n = (uint32_t const *)db->map ; - if (ntotal != db->n[0] + db->n[1] + db->n[2] + db->n[3] + db->n[4] + db->n[5] + db->n[6] + db->n[7] + db->n[8] + db->n[9]) goto eproto1 ; - - { - ssize_t r ; - memcpy(fn + len, "/hash", 6) ; - r = openreadnclose(fn, buf+32, 33) ; - if (r == 33) goto eproto1 ; - if (r < 32) goto err1 ; - sha256_update(&ctx, db->map, db->size) ; - sha256_final(&ctx, buf) ; - if (memcmp(buf, buf+32, 32)) goto eproto1 ; - } - - db->longruns = (s6rc_longrun_t const *)(db->map + 4 * 2 * S6RC_STYPE_N) ; - db->oneshots = (s6rc_oneshot_t const *)(db->longruns + db->n[S6RC_STYPE_LONGRUN] + db->n[S6RC_STYPE_N + S6RC_STYPE_LONGRUN]) ; - db->externals = (s6rc_external_t const *)(db->oneshots + db->n[S6RC_STYPE_ONESHOT] + db->n[S6RC_STYPE_N + S6RC_STYPE_ONESHOT]) ; - db->bundles = (s6rc_bundle_t const *)(db->externals + db->n[S6RC_STYPE_EXTERNAL] + db->n[S6RC_STYPE_N + S6RC_STYPE_EXTERNAL]) ; - db->virtuals = (s6rc_bundle_t const *)(db->bundles + db->n[S6RC_STYPE_BUNDLE] + db->n[S6RC_STYPE_N + S6RC_STYPE_BUNDLE]) ; - db->deps[0] = (s6rc_id_t const *)(db->virtuals + db->n[S6RC_STYPE_VIRTUAL] + db->n[S6RC_STYPE_N + S6RC_STYPE_VIRTUAL]) ; - db->deps[1] = db->deps[0] + ndeps ; - db->producers = db->deps[1] + ndeps ; - db->deptypes[0] = (uint8_t const *)(db->producers + nproducers) ; - db->deptypes[1] = db->deptypes[0] + ndeps ; - db->storage = (char const *)(db->deptypes[1] + ndeps) ; - if (db->storage + storagelen != db->map + db->size) goto eproto1 ; - - db->argvs = (char const **)alloc(sizeof(char const *) * nargv) ; - if (!db->argvs) goto err1 ; - for (uint32_t i = 0 ; i < nargv ; i++) - db->argvs[i] = argvs[i] ? db->storage + argvs[i] : 0 ; - } - return 1 ; - - eproto1: - errno = EPROTO ; - err1: - { - int e = errno ; - munmap(db->map, db->size) ; - errno = e ; - } - db->map = 0 ; - return 0 ; - - eproto0: - errno = EPROTO ; - err0: - fd_close(fd) ; - return 0 ; -} diff --git a/src/libs6rcd/s6rc_service_common.c b/src/libs6rcd/s6rc_service_common.c deleted file mode 100644 index b91c902..0000000 --- a/src/libs6rcd/s6rc_service_common.c +++ /dev/null @@ -1,16 +0,0 @@ -/* ISC license. */ - -#include "db.h" - -s6rc_common_t const *s6rc_service_common (s6rc_db_t const *db, s6rc_id_t id) -{ - switch (stype(id)) - { - case STYPE_LONGRUN : return &db->longruns[snum(id)].common ; - case STYPE_ONESHOT : return &db->oneshots[snum(id)].common ; - case STYPE_EXTERNAL : return &db->externals[snum(id)].common ; - case STYPE_BUNDLE : return &db->bundles[snum(id)].common ; - case STYPE_VIRTUAL : return &db->virtuals[snum(id)].common ; - default : return 0 ; - } -} diff --git a/src/libs6rcd/s6rc_service_resolve.c b/src/libs6rcd/s6rc_service_resolve.c deleted file mode 100644 index fe863be..0000000 --- a/src/libs6rcd/s6rc_service_resolve.c +++ /dev/null @@ -1,31 +0,0 @@ -/* ISC license. */ - -#include -#include - -#include -#include -#include - -#include "db.h" - -int s6rc_service_resolve (cdb_t *c, char const *s, s6rc_id_t *id, char const **param) -{ - size_t len = strlen(s) ; - char const *p = 0 ; - char pack[5] ; - int r = cdb_find(c, s, len) ; - if (r < 0) return r ; - if (!r) - { - size_t at = byte_chr(s, len, '@') ; - if (at == len) return 0 ; - if (at == len - 1) return (errno = EINVAL, -1) ; - r = cdb_find(c, s, at + 1) ; - if (r <= 0) return r ; - p = s + at + 1 ; - } - uint32_unpack_big(cdb_datapos(c), id) ; - *param = p ; - return 1 ; -} diff --git a/src/server/client.c b/src/server/client.c index c69794f..29ee197 100644 --- a/src/server/client.c +++ b/src/server/client.c @@ -51,7 +51,7 @@ void client_yoink (client_t **c) client_t *prev = (*c)->prev ; if (prev) prev->next = (*c)->next ; else client_head = (*c)->next ; if ((*c)->next) (*c)->next->prev = prev ; - if (ismonitored(*c)) nmonitors-- ; + if (ismonitored(*c)) client_monitors-- ; client_free(*c) ; *c = prev ; client_connections-- ; @@ -134,6 +134,19 @@ void monitor_put (uint32_t v, char const *s, size_t len) { if (!client_monitors) return ; for (client_t *c = client_head ; c ; c = c->next) - if (ismonitored(c) && v >= c->monitor_verbosity && !textmessage_put(&c->monitor, s, len)) - strerr_diefu1sys("queue message to monitor") ; + if (ismonitored(c) && v >= c->monitor_verbosity) + if (!textmessage_put(&c->monitor, s, len)) + strerr_diefu1sys("queue message to monitor") ; +} + +void monitor_announce (uint32_t id, uint8_t state) +{ + char pack[6] = "E" ; + if (!client_monitors) return ; + uint32_pack_big(pack + 1, id) ; + pack[5] = state ; + for (client_t *c = client_head ; c ; c = c->next) + if (ismonitored(c) && bitarray_peek(c->monitor_filter, id)) + if (!textmessage_put(&c->monitor, pack, 6)) + strerr_diefu1sys("queue message to monitor") ; } diff --git a/src/server/client.h b/src/server/client.h index 4b6cccc..1acdf53 100644 --- a/src/server/client.h +++ b/src/server/client.h @@ -22,10 +22,11 @@ struct client_s uint32_t xindex[2] ; s6rc_connection_t connection ; textmessage_sender_t monitor ; + unsigned char *monitor_filter ; uint32_t monitor_verbosity ; uint8_t perms ; } ; -#define CLIENT_ZERO { .next = 0, .xindex = 0, .connection = S6RC_CONNECTION_ZERO, .monitor = TEXTMESSAGE_SENDER_ZERO, .monitor_verbosity = 0, .perms = 0 } +#define CLIENT_ZERO { .next = 0, .xindex = 0, .connection = S6RC_CONNECTION_ZERO, .monitor = TEXTMESSAGE_SENDER_ZERO, .monitor_filter = 0, .monitor_verbosity = 0, .perms = 0 } extern tain_t client_answer_tto ; extern client_t *client_head ; @@ -40,7 +41,8 @@ extern int client_add (int, uint8_t) ; /* Monitors */ extern uint32_t client_monitors ; -extern int monitor_finish (client_t *) ; -extern int monitor_put (uint32_t, char const *, size_t) ; +extern void monitor_finish (client_t *) ; +extern void monitor_put (uint32_t, char const *, size_t) ; +extern void monitor_announce (uint32_t, uint8_t) ; #endif diff --git a/src/server/deps.c b/src/server/deps.c new file mode 100644 index 0000000..fc8028d --- /dev/null +++ b/src/server/deps.c @@ -0,0 +1,88 @@ +/* ISC license. */ + +#include +#include +#include + +#include "db.h" +#include "state.h" + +int deps_fulfilled (s6rc_db_t const *db, mstate_t const *m, s6rc_id_t id, char const *param, int h) +{ + s6rc_common_t const *common = s6rc_service_common(db, id) ; + for (uint32_t i = 0 ; i < common->ndeps[h] ; i++) + { + s6rc_id_t depid = db->deps[h][common->deps[h] + i] ; + sstate_t *st = sstate(m, depid, param) ; + uint8_t deptype = db->deptypes[h][common->deps[h] + i] ; + if (!(st->bits & SSTATE_WANTED) == h && stype(depid) != S6RC_STYPE_EXTERNAL && stype(depid) != S6RC_STYPE_N + S6RC_STYPE_EXTERNAL) return 0 ; + if (!(st->bits & SSTATE_CURRENT) != h && !(st->bits & SSTATE_TRANSITIONING)) continue ; + if (s6rc_deptype_soft(deptype) && st->bits & SSTATE_FAILED) continue ; + if (s6rc_deptype_loose(deptype) && !(st->bits & SSTATE_TRANSITIONING)) continue ; + return 0 ; + } + return 1 ; +} + +static int sstate_zerotmp (sstate_t *st, void *arg) +{ + st->tmp = 0 ; + (void)arg ; + return 1 ; +} + +static int instance_zerotmp (instance_t *ins, void *arg) +{ + return sstate_zerotmp(&ins->sstate) ; +} + +typedef struct recinfo_s recinfo_t, *recinfo_t_ref ; +struct recinfo_s +{ + s6rc_db_t const *db ; + mstate_t *m ; + char const *param ; + uint8_t h : 1 ; +} + +static int mstate_dep_closure_rec (recinfo_t *recinfo, s6rc_id_t id) +{ + sstate_t *st = sstate(recinfo->db, recinfo->m, id, recinfo->param) ; + if (!st) + { + st = instance_create(recinfo->m, id, recinfo->param) ; + if (!st) return 0 ; + } + if (!(st->tmp & SSTATE_GRAY)) + { + uint32_t ndeps = re + } +} + +static void mstate_dep_closure (s6rc_db_t const *db, mstate_t *m, sstate_t *st, char const *param, int h) +{ + recinfo_t recinfo = { .db = db, .m = m, .param = param, .h = !!h } ; + mstate_dep_closure_rec(&recinfo, st) ; +} + +int mstate_change_wanted (s6rc_db_t const *db, cdb_t *c, mstate_t *m, char const *const *args, size_t n, int h) +{ + mstate_iterate(m, db->n, &sstate_zerotmp, &instancelen_nop, &instance_zerotmp, 0) ; + for (size_t i = 0 ; i < n ; n++) + { + sstate_t *st ; + s6rc_id_t id ; + char const *param ; + int r = s6rc_service_resolve(c, args[i], &id, ¶m) ; + if (r < 0) return -1 ; + if (!r) return 1 + i ; + st = sstate(db, m, id, param) ; + if (!st) /* instance not found */ + { + st = instance_create(m, id, param) ; + if (!st) return -1 ; + } + st->tmp |= SSTATE_MARK | SSTATE_EXPLICIT ; + mstate_dep_closure(db, m, st, param, h) ; + } +} diff --git a/src/server/deps.h b/src/server/deps.h new file mode 100644 index 0000000..f8321dd --- /dev/null +++ b/src/server/deps.h @@ -0,0 +1,19 @@ +/* ISC license. */ + +#ifndef S6RCD_DEPS_H +#define S6RCD_DEPS_H + +#include + +#include "db.h" + + + /* Dependencies */ + +#define deptype_passive(dt) ((dt) & 0x01u) +#define deptype_soft(dt) ((dt) & 0x02u) +#define deptype_loose(dt) ((dt) & 0x04u) + +extern int deps_fulfilled (s6rc_db_t const *, mstate_t const *, s6rc_id_t, char const *, int) ; + +#endif diff --git a/src/server/state.c b/src/server/state.c index d9e3f61..f106c20 100644 --- a/src/server/state.c +++ b/src/server/state.c @@ -11,7 +11,7 @@ #include #include -#include "db.h" +#include #include "dynstorage.h" #include "state.h" @@ -19,26 +19,43 @@ static sstate_t const sstate_zero = SSTATE_ZERO ; -void instance_free (instance_t *ins) +static inline void instance_free (instance_t *ins) { dynstorage_remove(ins->param) ; } -int instance_new (instance_t *ins, sstate_t const *st, char const *param) ; +void instance_remove (mstate_t *m, uint8_t type, uint32_t num, char const *param) { - char const *s = dynstorage_add(param) ; - if (!s) return 0 ; - ins->state = *st ; - inst->param = s ; - return 1 ; + genalloc *g = m->dyn[type] + num ; + instance_t *ins = genalloc_s(instance_t, g) ; + uint32_t n = genalloc_len(instance_t, g) ; + uint32_t i = 0 ; + for (; i < n ; i++) if (!strcmp(param, ins[i].param)) break ; + if (i >= n) return ; + instance_free(ins + i) ; + ins[i] = ins[n-1] ; + genalloc_setlen(instance_t, g, n-1) ; +} + +sstate_t *instance_create (mstate_t *m, uint8_t type, uint32_t num, char const *param) +{ + genalloc *g = m->dyn[type] + num ; + instance_t ins = { .sstate = SSTATE_ZERO, .param = dynstorage_add(param) } ; + if (!ins.param) return 0 ; + if (!genalloc_catb(instance_t, g, &ins, 1)) + { + dynstorage_remove(ins.param) ; + return 0 ; + } + return &genalloc_s(instance_t, g)[genalloc_len(instance_t, g) - 1].sstate ; } void mstate_free (mstate_t *st, uint32_t const *dbn) { - for (size_t type = 0 ; type < S6RC_STYPE_N ; type++) + for (uint8_t type = 0 ; type < S6RC_STYPE_N ; type++) { alloc_free(st->sta[type]) ; - for (size_t i = 0 ; i < dbn[S6RC_STYPE_N + type] ; i++) + for (uint32_t i = 0 ; i < dbn[S6RC_STYPE_N + type] ; i++) { for (size_t j = 0 ; j < genalloc_len(instance_t, st->dyn[type] + i) ; j++) instance_free(genalloc_s(instance_t, st->dyn[type] + i) + j) ; @@ -50,7 +67,7 @@ void mstate_free (mstate_t *st, uint32_t const *dbn) int mstate_init (mstate_t *st, uint32_t const *dbn) { - size_t type = 0 ; + uint8_t type = 0 ; for (; type < S6RC_STYPE_N ; type++) { st->sta[type] = alloc(dbn[type]) ; @@ -73,18 +90,40 @@ int mstate_init (mstate_t *st, uint32_t const *dbn) return 0 ; } -static int sstate_write (buffer *b, sstate_t const *state) +int mstate_iterate (mstate_t *m, uint32_t const *dbn, sstate_func_ref staf, instancelen_func_ref lenf, instance_func_ref dynf, void *arg) +{ + for (uint8_t type = 0 ; type < S6RC_STYPE_N ; type++) + for (uint32_t i = 0 ; i < dbn[type] ; i++) + if (!staf(m->sta[type] + i, arg)) return 0 ; + + for (uint8_t type = 0 ; type < S6RC_STYPE_N ; type++) + for (uint32_t i = 0 ; i < dbn[S6RC_STYPE_N + type] ; i++) + { + uint32_t n = genalloc_len(instance_t, m->dyn[type] + i) ; + instance_t const *p = genalloc_s(instance_t, m->dyn[type] + i) ; + if (!lenf(n, arg)) return 0 ; + for (size_t j = 0 ; j < n ; j++) + if (!dynf(p + j, arg)) goto err ; + } + + return 1 ; +} + +static int sstate_write (sstate_t *state, void *b) { - return buffer_put(b, (char *)state->bits, 1) == 1 ; + return buffer_put((buffer *)b, (char *)&state->bits, 1) == 1 ; } -static int sstate_read (buffer *b, sstate_t *state) +static int instancelen_write (uint32_t n, void *b) { - return buffer_get(b, (char *)state->bits, 1) == 1 ; + char pack[4] ; + uint32_pack_big(pack, n) ; + return buffer_put((buffer *)b, pack, 4) == 4 ; } -static inline int instance_write (buffer *b, instance_t const *ins) +static int instance_write (instance_t *ins, void *arg) { + buffer *b = arg ; uint32_t len = strlen(ins->param) ; char pack[4] ; uint32_pack_big(pack, len) ; @@ -94,29 +133,7 @@ static inline int instance_write (buffer *b, instance_t const *ins) return 1 ; } -static inline int instance_read (buffer *b, instance_t *ins) -{ - sstate_t st ; - char const *p ; - uint32_t len ; - char pack[4] ; - if (!sstate_read(b, &st)) return 0 ; - if (buffer_get(&b, pack, 4) < 4) return 0 ; - uint32_unpack_big(pack, &len) ; - if (len > S6RC_INSTANCE_MAXLEN) return (errno = EPROTO, 0) ; - { - char param[len + 1] ; - if (buffer_get(&b, param, len + 1) < len + 1) return 0 ; - if (param[len]) return (errno = EPROTO, 0) ; - p = dynstorage_add(param) ; - if (!p) return 0 ; - } - ins->sstate = st ; - ins->param = p ; - return 1 ; -} - -int mstate_write (char const *file, mstate_t const *st, uint32_t const *dbn) +int mstate_write (char const *file, mstate_t const *m, uint32_t const *dbn) { size_t filelen = strlen(file) ; int fd ; @@ -128,23 +145,7 @@ int mstate_write (char const *file, mstate_t const *st, uint32_t const *dbn) fd = mkstemp(fn) ; if (fd == -1) return 0 ; buffer_init(&b, &buffer_write, fd, buf, 1024) ; - - for (size_t type = 0 ; type < S6RC_STYPE_N ; type++) - for (uint32_t i = 0 ; i < dbn[type] ; i++) - if (!sstate_write(&b, st->sta[type] + i)) goto err ; - - for (size_t type = 0 ; type < S6RC_STYPE_N ; type++) - for (uint32_t i = 0 ; i < dbn[S6RC_STYPE_N + type] ; i++) - { - uint32_t n = genalloc_len(instance_t, st->dyn[type] + i) ; - instance_t const *p = genalloc_s(instance_t, st->dyn[type] + i) ; - char pack[4] ; - uint32_pack_big(pack, n) ; - if (buffer_put(&b, pack, 4) < 4) goto err ; - for (uint32_t j = 0 ; j < n ; j++) - if (!instance_write(&b, p + j)) goto err ; - } - + if (!mstate_iterate(m, &sstate_write, &instancelen_write, &instance_write, &b)) goto err ; if (!buffer_flush(&b)) goto err ; fd_close(fd) ; if (rename(fn, file) == -1) goto err0 ; @@ -157,6 +158,33 @@ int mstate_write (char const *file, mstate_t const *st, uint32_t const *dbn) return 0 ; } +static int sstate_read (buffer *b, sstate_t *state) +{ + return buffer_get(b, (char *)&state->bits, 1) == 1 ; +} + +static int instance_read (buffer *b, instance_t *ins) +{ + sstate_t st ; + char const *p ; + uint32_t len ; + char pack[4] ; + if (!sstate_read(b, &st)) return 0 ; + if (buffer_get(&b, pack, 4) < 4) return 0 ; + uint32_unpack_big(pack, &len) ; + if (len > S6RC_INSTANCE_MAXLEN) return (errno = EPROTO, 0) ; + { + char param[len + 1] ; + if (buffer_get(&b, param, len + 1) < len + 1) return 0 ; + if (param[len]) return (errno = EPROTO, 0) ; + p = dynstorage_add(param) ; + if (!p) return 0 ; + } + ins->sstate = st ; + ins->param = p ; + return 1 ; +} + int mstate_read (char const *file, mstate_t *st, uint32_t const *dbn) { int fd ; @@ -167,11 +195,11 @@ int mstate_read (char const *file, mstate_t *st, uint32_t const *dbn) if (fd == -1) goto err0 ; buffer_init(&b, &buffer_read, fd, buf, 1024) ; - for (size_t type = 0 ; type < S6RC_STYPE_N ; type++) + for (uint8_t type = 0 ; type < S6RC_STYPE_N ; type++) for (uint32_t i = 0 ; i < dbn[type] ; i++) if (!sstate_read(&b, st->sta[type] + i)) goto err ; - for (size_t type = 0 ; type < S6RC_STYPE_N ; type++) + for (uint8_t type = 0 ; type < S6RC_STYPE_N ; type++) for (uint32_t i = 0 ; i < dbn[S6RC_STYPE_N + type] ; i++) { uint32_t n ; @@ -180,7 +208,7 @@ int mstate_read (char const *file, mstate_t *st, uint32_t const *dbn) uint32_unpack_big(pack, &n) ; if (n > S6RC_INSTANCES_MAX) goto eproto ; if (!genalloc_ready(instance_t, st->dyn[type] + i, n)) goto err ; - for (uint32_t j = 0 ; j < n ; j++) + for (size_t j = 0 ; j < n ; j++) if (!instance_read(&b, genalloc_s(instance_t, st->dyn[type] + i) + j)) goto err ; genalloc_setlen(instance_t, st->dyn[type] + i, n) ; } @@ -206,25 +234,32 @@ int mstate_read (char const *file, mstate_t *st, uint32_t const *dbn) return 0 ; } -sstate_t *sstate (mstate_t const *m, s6rc_id_t id, char const *param) +sstate_t *sstate_tn (mstate_t *m, uint8_t type, uint32_t num, char const *param) { - if (stype(id) >= S6RC_STYPE_N) + if (type >= S6RC_STYPE_N) { - size_t n = genalloc_len(instance_t, st->dyn[stype(id)] + snum(id)) ; - instance_t *instances = genalloc_s(instance_t, st->dyn[stype(id)] + snum(id)) ; + size_t n = genalloc_len(instance_t, m->dyn[type] + num) ; + instance_t *instances = genalloc_s(instance_t, m->dyn[type] + num) ; for (size_t i = 0 ; i < n ; i++) if (!strcmp(param, instances[i].param)) return &instances[i].sstate ; - return STATE_PHAIL ; + return 0 ; } - else return st->sta[stype(id)] + snum(id) ; + else return m->sta[type] + num ; } -int state_deps_fulfilled (s6rc_db_t const *db, mstate_t const *m, s6rc_id_t id, char const *param, int h) +sstate_t *sstate (uint32_t const *dbn, mstate_t *m, uint32_t id, char const *param) { - s6rc_common_t const *common = s6rc_service_common(db, id) ; - for (uint32_t i = 0 ; i < common->ndeps[h] ; i++) - { - uint8_t deptype = db->deptypes[h][common->deps[h] + i] ; - sstate_t *st = sstate(m, db->deps[h][common->deps[h] + i], param) ; - } + uint32_t num ; + uint8_t type ; + s6rc_service_typenum(dbn, id, &type, &num) ; + return sstate_tn(m, type, num, param) ; } + +static int instancelen_nop_ (uint32_t n, void *arg) +{ + (void)n ; + (void)arg ; + return 1 ; +} + +instancelen_func_ref const instancelen_nop = &instancelen_nop_ ; diff --git a/src/server/state.h b/src/server/state.h index 2084437..9831115 100644 --- a/src/server/state.h +++ b/src/server/state.h @@ -11,23 +11,27 @@ /* Service states, instances, machine state */ -#define SSTATE_STABLE 0x00u -#define SSTATE_WAITING 0x01u -#define SSTATE_TRANSITIONING 0x02u -#define SSTATE_FAILED 0x03u - + /* bits */ +#define SSTATE_TRANSITIONING 0x01u +#define SSTATE_FAILED 0x02u #define SSTATE_CURRENT 0x04u #define SSTATE_WANTED 0x08u #define SSTATE_EXPLICIT 0x10u -#define SSTATE_GRAY 0x20u -#define SSTATE_BLACK 0x40u #define SSTATE_INVALID 0x80u + /* tmp */ +#define SSTATE_GRAY 0x01u +#define SSTATE_BLACK 0x02u +#define SSTATE_MARK 0x04u +#define SSTATE_EXPLICIT 0x08u + typedef struct sstate_s sstate_t, *sstate_t_ref ; struct sstate_s { - uint8_t bits ; + uint8_t bits ; /* the real state, saved to the fs */ + uint8_t tmp ; /* bits used for computations e.g. recursive dep walks */ } +#define SSTATE_ZERO { .bits = 0, .tmp = 0 } typedef struct instance_s instance_t, *instance_t_ref ; struct instance_s @@ -43,8 +47,17 @@ struct mstate_s genalloc *dyn[S6RC_STYPE_N] ; /* every genalloc is a list of instance_t */ } ; -extern void instance_free (instance_t *) ; -extern int instance_new (instance_t *, uint8_t *, char const *) ; +typedef int sstate_func (sstate_t *, void *) ; +typedef sstate_func *sstate_func_ref ; +typedef int instancelen_func (uint32_t, void *) ; +typedef instancelen_func *instancelen_func_ref ; +typedef instance_func (instance_t *, void *) ; +typedef instance_func *instance_func_ref ; + +extern instancelen_func_ref const instancelen_nop ; + +extern sstate_t *instance_create (mstate_t *, s6rc_id_t, char const *) ; +extern void instance_remove (mstate_t *, s6rc_id_t, char const *) ; extern void mstate_free (mstate_t *, uint32_t const *) ; extern int mstate_init (mstate_t *, uint32_t const *) ; @@ -52,7 +65,9 @@ extern int mstate_init (mstate_t *, uint32_t const *) ; extern int mstate_write (char const *, mstate_t const *, uint32_t const *) ; extern int mstate_read (char const *, mstate_t *, uint32_t const *) ; /* also inits */ -extern sstate_t *sstate_get (s6rc_db_t const *, mstate_t const *, s6rc_id_t, char const *) ; -extern int sstate_deps_fulfilled (s6rc_db_t const *, mstate_t const *, s6rc_id_t, char const *, int) ; +extern int mstate_iterate (mstate_t *, uint32_t const *, sstate_func_ref, instancelen_func_ref, instance_func_ref, void *) ; + +extern sstate_t *sstate_tn (mstate_t *, uint8_t, uint32_t, char const *) ; +extern sstate_t *sstate (uint32_t const *, mstate_t *, uint32_t, char const *) ; #endif -- cgit v1.2.3