diff options
Diffstat (limited to 'src/libs6rc')
-rw-r--r-- | src/libs6rc/s6rc_db_free.c | 17 | ||||
-rw-r--r-- | src/libs6rc/s6rc_db_load.c | 140 | ||||
-rw-r--r-- | src/libs6rc/s6rc_service_common.c | 16 | ||||
-rw-r--r-- | src/libs6rc/s6rc_service_common_tn.c | 21 | ||||
-rw-r--r-- | src/libs6rc/s6rc_service_id.c | 12 | ||||
-rw-r--r-- | src/libs6rc/s6rc_service_num.c | 13 | ||||
-rw-r--r-- | src/libs6rc/s6rc_service_recheck_instance.c | 31 | ||||
-rw-r--r-- | src/libs6rc/s6rc_service_resolve.c | 13 | ||||
-rw-r--r-- | src/libs6rc/s6rc_service_type.c | 13 | ||||
-rw-r--r-- | src/libs6rc/s6rc_service_typenum.c | 13 |
10 files changed, 270 insertions, 19 deletions
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 <sys/mman.h> +#include <errno.h> + +#include <skalibs/alloc.h> + +#include <s6-rc/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/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 <stdint.h> +#include <string.h> +#include <errno.h> +#include <sys/stat.h> +#include <sys/mman.h> + +#include <skalibs/uint32.h> +#include <skalibs/alloc.h> +#include <skalibs/buffer.h> +#include <skalibs/djbunix.h> +#include <skalibs/cdb.h> +#include <skalibs/sha256.h> + +#include <s6-rc/db.h> + +#include <skalibs/posixishard.h> + +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 <s6-rc/db.h> -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 <s6-rc/db.h> + +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 <stdint.h> + +#include <s6-rc/db.h> + +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 <stdint.h> + +#include <s6-rc/db.h> + +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 <string.h> + +#include <skalibs/uint32.h> +#include <skalibs/cdb.h> + +#include <s6-rc/db.h> + +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 <s6-rc/db.h> -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 <stdint.h> + +#include <s6-rc/db.h> + +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 <stdint.h> + +#include <s6-rc/db.h> + +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 ; +} |