From 4c1d58b509c83ff788fe1ad6b5bdd1073977622c Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Tue, 29 Jun 2021 00:16:10 +0000 Subject: Some work on the db representation Signed-off-by: Laurent Bercot --- src/include-local/db.h | 114 +++++++++++++++++++++++++++++++ src/include/s6-rc/db.h | 106 ----------------------------- src/libs6rcd/s6rc_db_free.c | 18 +++++ src/libs6rcd/s6rc_db_read.c | 131 ++++++++++++++++++++++++++++++++++++ src/libs6rcd/s6rc_db_read_hash.c | 15 +++++ src/libs6rcd/s6rc_service_common.c | 19 ++++++ src/libs6rcd/s6rc_service_resolve.c | 33 +++++++++ src/server/db.h | 13 ---- src/server/s6-rcd.h | 1 - src/server/state.c | 20 +++++- src/server/state.h | 3 +- 11 files changed, 349 insertions(+), 124 deletions(-) create mode 100644 src/include-local/db.h delete mode 100644 src/include/s6-rc/db.h create mode 100644 src/libs6rcd/s6rc_db_free.c create mode 100644 src/libs6rcd/s6rc_db_read.c create mode 100644 src/libs6rcd/s6rc_db_read_hash.c create mode 100644 src/libs6rcd/s6rc_service_common.c create mode 100644 src/libs6rcd/s6rc_service_resolve.c delete mode 100644 src/server/db.h (limited to 'src') diff --git a/src/include-local/db.h b/src/include-local/db.h new file mode 100644 index 0000000..a937e7a --- /dev/null +++ b/src/include-local/db.h @@ -0,0 +1,114 @@ +/* ISC license. */ + +#ifndef S6RCD_SERVICE_H +#define S6RCD_SERVICE_H + +#include + + + /* Service types and db representation in memory */ + +#define S6RC_INSTANCES_MAX 0xffffffU +#define S6RC_INSTANCEPARAM_MAXLEN 0xffffffU + +typedef enum s6rc_stype_e s6rc_stype_t, *s6rc_stype_t_ref ; +enum s6rc_stype_e +{ + S6RC_STYPE_LONGRUN, + S6RC_STYPE_ONESHOT, + S6RC_STYPE_EXTERNAL, + S6RC_STYPE_BUNDLE, + S6RC_STYPE_VIRTUAL, + S6RC_STYPE_PHAIL +} ; + + +typedef struct s6rc_baseid_s s6rc_baseid_t, *s6rc_baseid_t_ref ; +struct s6rc_baseid_s +{ + uint32_t i ; + s6rc_stype_t stype ; +} ; + +typedef struct s6rc_id_s s6rc_id_t, *s6rc_id_t_ref ; +struct s6rc_id_s +{ + char const *param ; + s6rc_baseid_t baseid ; +} ; + +typedef struct s6rc_common_s s6rc_common_t, *s6rc_common_t_ref ; +struct s6rc_common_s +{ + uint32_t name ; + uint32_t deps[2] ; + uint32_t ndeps[2] ; + uint32_t flag_essential : 1 ; + uint32_t flags : 31 ; +} ; + +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 argc[2] ; + uint32_t argv[2] ; +} ; + +typedef struct s6rc_longrun_s s6rc_longrun_t, *s6rc_longrun_t_ref ; +struct s6rc_longrun_s +{ + s6rc_atomic_t satomic ; + s6rc_sid_t consumer ; + uint32_t nproducers ; + uint32_t producers ; +} ; + +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_deptype_s s6rc_deptype_t, *s6rc_deptype_t_ref ; +struct s6rc_deptype_s +{ + uint8_t passive : 1 ; + uint8_t soft : 1 ; + uint8_t loose : 1 ; +} ; + +typedef struct s6rc_db_s s6rc_db_t, *s6rc_db_t_ref ; +struct s6rc_db_s +{ + uint32_t n[STYPE_PHAIL << 1] ; + s6rc_longrun_t *longruns ; + s6rc_oneshot_t *oneshots ; + s6rc_external_t *externals ; + s6rc_bundle_t *bundles ; + s6rc_bundle_t *virtuals ; + s6rc_baseid_t *deps[2] ; + s6rc_deptype_t *deptypes[2] ; + s6rc_baseid_t *producers ; + char const **argvs ; + char *storage ; +} ; + +extern s6rc_common_t const *s6rc_service_common (s6rc_db_t const *, s6rc_sid_t const *) ; + +#endif diff --git a/src/include/s6-rc/db.h b/src/include/s6-rc/db.h deleted file mode 100644 index 8953a49..0000000 --- a/src/include/s6-rc/db.h +++ /dev/null @@ -1,106 +0,0 @@ -/* ISC license. */ - -#ifndef S6RC_SERVICE_H -#define S6RC_SERVICE_H - -#include - - - /* Service types and db representation in memory */ - -typedef enum s6rc_stype_e s6rc_stype_t, *s6rc_stype_t_ref ; -enum s6rc_stype_e -{ - S6RC_STYPE_LONGRUN, - S6RC_STYPE_ONESHOT, - S6RC_STYPE_EXTERNAL, - S6RC_STYPE_BUNDLE, - S6RC_STYPE_VIRTUAL, - S6RC_STYPE_PHAIL -} ; - -typedef struct s6rc_sid_s s6rc_sid_t, *s6rc_sid_t_ref ; -struct s6rc_sid_s -{ - uint32_t i ; - char const *param ; - s6rc_stype_t stype ; -} ; - -typedef struct s6rc_common_s s6rc_common_t, *s6rc_common_t_ref ; -struct s6rc_common_s -{ - uint32_t name ; - uint32_t deps[2] ; - uint32_t ndeps[2] ; - uint32_t flag_essential : 1 ; - uint32_t flags : 31 ; -} ; - -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 argc[2] ; - uint32_t argv[2] ; -} ; - -typedef struct s6rc_longrun_s s6rc_longrun_t, *s6rc_longrun_t_ref ; -struct s6rc_longrun_s -{ - s6rc_atomic_t satomic ; - s6rc_sid_t consumer ; - uint32_t nproducers ; - uint32_t producers ; -} ; - -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_deptype_s s6rc_deptype_t, *s6rc_deptype_t_ref ; -struct s6rc_deptype_s -{ - uint8_t passive : 1 ; - uint8_t soft : 1 ; - uint8_t loose : 1 ; -} ; - -typedef struct s6rc_db_s s6rc_db_t, *s6rc_db_t_ref ; -struct s6rc_db_s -{ - uint32_t ntotal ; - uint32_t n[STYPE_PHAIL << 1] ; - uint32_t storagelen ; - s6rc_longrun_t *longruns ; - s6rc_oneshot_t *oneshots ; - s6rc_external_t *externals ; - s6rc_bundle_t *bundles ; - s6rc_bundle_t *virtuals ; - s6rc_sid_t *deps[2] ; - s6rc_deptype_t *deptypes[2] ; - s6rc_sid_t *producers ; - char const **argvs ; - char *storage ; -} ; - -extern s6rc_common_t const *s6rc_service_common (s6rc_db_t const *, s6rc_sid_t const *) ; - -#endif diff --git a/src/libs6rcd/s6rc_db_free.c b/src/libs6rcd/s6rc_db_free.c new file mode 100644 index 0000000..b8eb54e --- /dev/null +++ b/src/libs6rcd/s6rc_db_free.c @@ -0,0 +1,18 @@ +/* ISC license. */ + +#include + +#include "db.h" + +void s6rc_db_free (s6rc_db_t *db) +{ + alloc_free(db->storage) ; + alloc_free(db->argvs) ; + alloc_free(db->producers) ; + alloc_free(db->deptypes[0]) ; + alloc_free(db->deps[0]) ; + alloc_free(db->bundles) ; + alloc_free(db->externals) ; + alloc_free(db->oneshots) ; + alloc_free(db->longruns) ; +} diff --git a/src/libs6rcd/s6rc_db_read.c b/src/libs6rcd/s6rc_db_read.c new file mode 100644 index 0000000..9b60184 --- /dev/null +++ b/src/libs6rcd/s6rc_db_read.c @@ -0,0 +1,131 @@ +/* ISC license. */ + +#include +#include +#include + +#include +#include +#include +#include + +#include "db.h" + +#include + +static int geth (buffer *b, SHA256Schedule *ctx, char *s, size_t len) +{ + if (buffer_get(b, s, len) < len) return 0 ; + sha256_update(ctx, s, len) ; + return 1 ; +} + +static int readu32 (buffer *b, SHA256Schedule *ctx, uint32_t *x) +{ + char pack[4] ; + if (!geth(b, ctx, pack, 4)) return 0 ; + uint32_unpack_big(pack, x) ; + return 1 ; +} + +static int readdeps (buffer *b, SHA256Schedule *ctx, s6rc_baseid_t *deps, uint32_t ndeps, uint32_t const *dbn) +{ + for (uint32_t i = 0 ; i < (ndeps << 1) ; i++) + { + char pack[5] ; + if (!geth(b, ctx, pack, 5)) return 0 ; + if ((unsigned char)pack[0] >= S6RC_STYPE_PHAIL) return (errno = EPROTO, 0) ; + deps[i].stype = pack[0] ; + uint32_unpack_big(pack + 1, &deps[i].i) ; + } + return 1 ; +} + +int s6rc_db_read_main (char const *dir, s6rc_db_t const *db, char *dbhash) +{ + SHA256Schedule ctx = SHA256_INIT() ; + int fd ; + buffer b ; + size_t len = strlen(dir) ; + uint32_t ndeps, nproducers, nargvs, storagelen ; + char buf[1024] ; + char fn[len + 4] ; + memcpy(fn, dir, len) ; + memcpy(fn + len, "/db", 4) ; + fd = openc_read(fn) ; + if (fd == -1) return 0 ; + buffer_init(&b, &buffer_read, fd, buf, 1024) ; + + { + char banner[S6RC_DB_BANNER_START_LEN] ; + if (!geth(&b, &ctx, banner, S6RC_DB_BANNER_START_LEN)) goto err0 ; + if (memcmp(banner, S6RC_DB_BANNER_START, S6RC_DB_BANNER_START_LEN)) { errno = EPROTO ; goto err0 ; } + } + + { + uint32_t ntotal ; + uint32_t nacc = 0 ; + if (!readu32(&b, &ctx, &ntotal)) goto err0 ; + for (s6rc_stype_t type = 0 ; (type < S6RC_STYPE_PHAIL << 1) ; type++) + { + if (!readu32(&b, &ctx, db->n + type)) goto err0 ; + nacc += db->n[type] ; + } + if (ntotal != nacc) { errno = EPROTO ; goto err0 ; } + } + if (!readu32(&b, &ctx, &ndeps)) goto err0 ; + if (!readu32(&b, &ctx, &nproducers)) goto err0 ; + if (!readu32(&b, &ctx, &nargvs)) goto err0 ; + if (!readu32(&b, &ctx, &storagelen)) goto err0 ; + + db->longruns = alloc(sizeof(s6rc_longrun_t) * (db->n[S6RC_STYPE_LONGRUN] + db->n[S6RC_STYPE_PHAIL + S6RC_STYPE_LONGRUN])) ; + if (!db->longruns) goto err0 ; + db->oneshots = alloc(sizeof(s6rc_oneshot_t) * (db->n[S6RC_STYPE_ONESHOT] + db->n[S6RC_STYPE_PHAIL + S6RC_STYPE_ONESHOT])) ; + if (!db->oneshots) goto err1 ; + db->externals = alloc(sizeof(s6rc_external_t) * (db->n[S6RC_STYPE_EXTERNAL] + db->n[S6RC_STYPE_PHAIL + S6RC_STYPE_EXTERNAL])) ; + if (!db->externals) goto err2 ; + db->bundles = alloc(sizeof(s6rc_bundle_t) * (db->n[S6RC_STYPE_BUNDLE] + db->n[S6RC_STYPE_PHAIL + S6RC_STYPE_BUNDLE] + db->n[S6RC_STYPE_VIRTUAL] + db->n[S6RC_STYPE_PHAIL + S6RC_TYPE_VIRTUAL])) ; + if (!db->bundles) goto err3 ; + db->virtuals = db->bundles + db->n[S6RC_STYPE_BUNDLE] + db->n[S6RC_STYPE_PHAIL + S6RC_STYPE_BUNDLE])) ; + db->deps[0] = alloc(sizeof(s6rc_baseid_t) * (ndeps << 1)) ; + if (!db->deps[0]) goto err4 ; + db->deps[1] = db->deps[0] + ndeps ; + db->deptypes[0] = alloc(sizeof(s6rc_deptype_t) * (ndeps << 1)) ; + if (!db->deptypes[0]) goto err5 ; + db->deptypes[1] = db->deptypes[0] + ndeps ; + db->producers = alloc(sizeof(s6rc_baseid_t) * nproducers) ; + if (!db->producers) goto err6 ; + db->argvs = alloc(sizeof(char const *) * nargvs) ; + if (!db->longruns) goto err7 ; + db->storage = alloc(storagelen) ; + if (!db->storage) goto err8 ; + + if (!geth(&b, &ctx, db->storage, storagelen)) goto err ; + if (!geth(&b, &ctx, db->deptypes[0], sizeof(s6rc_deptype_t) * (ndeps << 1))) goto err ; + if (!readdeps(&b, &ctx, db->deps[0], ndeps, db->n)) goto err ; + + sha256_final(&ctx, dbhash) ; + return 1 ; + + err: + alloc_free(db->storage) ; + err8: + alloc_free(db->argvs) ; + err7: + alloc_free(db->producers) ; + err6: + alloc_free(db->deptypes[0]) ; + err5: + alloc_free(db->deps[0]) ; + err4: + alloc_free(db->bundles) ; + err3: + alloc_free(db->externals) ; + err2: + alloc_free(db->oneshots) ; + err1: + alloc_free(db->longruns) ; + err0: + fd_close(fd) ; + return 0 ; +} diff --git a/src/libs6rcd/s6rc_db_read_hash.c b/src/libs6rcd/s6rc_db_read_hash.c new file mode 100644 index 0000000..f33e657 --- /dev/null +++ b/src/libs6rcd/s6rc_db_read_hash.c @@ -0,0 +1,15 @@ +/* ISC license. */ + +#include +#include + +#include "db.h" + +int s6rc_db_read_hash (char const *dir, char *dbhash) +{ + size_t len = strlen(dir) ; + char fn[len + 6] ; + memcpy(fn, dir, len) ; + memcpy(fn + len, "/hash", 6) ; + return openreadnclose(fn, dbhash, 32) == 32 ; +} diff --git a/src/libs6rcd/s6rc_service_common.c b/src/libs6rcd/s6rc_service_common.c new file mode 100644 index 0000000..93c6ee3 --- /dev/null +++ b/src/libs6rcd/s6rc_service_common.c @@ -0,0 +1,19 @@ +/* ISC license. */ + +#include + +#include "db.h" + +s6rc_common_t const *s6rc_service_common (s6rc_db_t const *db, s6rc_sid_t const *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 ; + } +} diff --git a/src/libs6rcd/s6rc_service_resolve.c b/src/libs6rcd/s6rc_service_resolve.c new file mode 100644 index 0000000..a786542 --- /dev/null +++ b/src/libs6rcd/s6rc_service_resolve.c @@ -0,0 +1,33 @@ +/* ISC license. */ + +#include +#include + +#include +#include +#include + +#include "db.h" + +int s6rc_service_resolve (cdb_t *c, s6rc_sid_t *id, char const *s) +{ + size_t len = strlen(s) ; + char const *param = 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 ; + param = 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 ; + return 1 ; +} diff --git a/src/server/db.h b/src/server/db.h deleted file mode 100644 index 2c960bc..0000000 --- a/src/server/db.h +++ /dev/null @@ -1,13 +0,0 @@ -/* ISC license. */ - -#ifndef S6RCD_DB_H -#define S6RCD_DB_H - -#include - - /* Service database */ - -extern int db_load (s6rc_db_t *, char const *) ; -extern int db_read_sizes (s6rc_db_sizes_t *, char const *) ; - -#endif diff --git a/src/server/s6-rcd.h b/src/server/s6-rcd.h index ca0867a..ce47e0b 100644 --- a/src/server/s6-rcd.h +++ b/src/server/s6-rcd.h @@ -6,7 +6,6 @@ #include "client.h" #include "clientrules.h" #include "command.h" -#include "db.h" #include "dynstorage.h" #include "ep.h" #include "ev.h" diff --git a/src/server/state.c b/src/server/state.c index c6fb2d0..29d1548 100644 --- a/src/server/state.c +++ b/src/server/state.c @@ -4,16 +4,19 @@ #include #include #include +#include #include #include #include #include -#include +#include "db.h" #include "dynstorage.h" #include "state.h" +#include + static stateatom_t const stateatom_zero = STATEATOM_ZERO ; void instance_free (instance_t *ins) @@ -154,6 +157,7 @@ int state_read (char const *file, state_t *st, uint32_t const *dbn) char pack[4] ; if (buffer_get(&b, pack, 4) < 4) goto err ; 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 ; i < n ; j++) { @@ -162,10 +166,11 @@ int state_read (char const *file, state_t *st, uint32_t const *dbn) if (!atom_read(&b, &ins->state)) goto err ; if (buffer_get(&b, pack, 4) < 4) goto err ; uint32_unpack_big(pack, &len) ; + if (len > S6RC_INSTANCE_MAXLEN) goto eproto ; { char param[len + 1] ; if (buffer_get(&b, param, len + 1) < len + 1) goto err ; - if (param[len]) { errno = EINVAL ; goto err ; } + if (param[len]) goto eproto ; ins->param = dynstorage_add(param) ; if (!ins_param) goto err ; } @@ -173,9 +178,20 @@ int state_read (char const *file, state_t *st, uint32_t const *dbn) genalloc_setlen(instance_t, st->dyn[type] + i, n) ; } + { + char c ; + switch (buffer_get(&b, &c, 1)) + { + case -1 : goto err ; + case 1 : goto eproto ; + } + } + fd_close(fd) ; return 1 ; + eproto: + errno = EPROTO ; err: fd_close(fd) ; err0: diff --git a/src/server/state.h b/src/server/state.h index f49ffb4..2690f45 100644 --- a/src/server/state.h +++ b/src/server/state.h @@ -5,8 +5,7 @@ #include -#include - +#include "db.h" /* Service states, instances, machine state */ -- cgit v1.3.1