summaryrefslogtreecommitdiff
path: root/src/libs6rc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs6rc')
-rw-r--r--src/libs6rc/s6rc_db_free.c17
-rw-r--r--src/libs6rc/s6rc_db_load.c140
-rw-r--r--src/libs6rc/s6rc_service_common.c16
-rw-r--r--src/libs6rc/s6rc_service_common_tn.c21
-rw-r--r--src/libs6rc/s6rc_service_id.c12
-rw-r--r--src/libs6rc/s6rc_service_num.c13
-rw-r--r--src/libs6rc/s6rc_service_recheck_instance.c31
-rw-r--r--src/libs6rc/s6rc_service_resolve.c13
-rw-r--r--src/libs6rc/s6rc_service_type.c13
-rw-r--r--src/libs6rc/s6rc_service_typenum.c13
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 ;
+}