summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/include/s6-rc/db.h6
-rw-r--r--src/libs6rc/s6rc_db_free.c2
-rw-r--r--src/libs6rc/s6rc_db_init.c (renamed from src/libs6rc/s6rc_db_load.c)6
-rw-r--r--src/libs6rc/s6rc_service_recheck_instance.c10
-rw-r--r--src/libs6rc/s6rc_service_resolve.c17
-rw-r--r--src/server/clientrules.c20
-rw-r--r--src/server/deps.c71
-rw-r--r--src/server/state.c17
-rw-r--r--src/server/state.h8
9 files changed, 94 insertions, 63 deletions
diff --git a/src/include/s6-rc/db.h b/src/include/s6-rc/db.h
index 416d920..713b76b 100644
--- a/src/include/s6-rc/db.h
+++ b/src/include/s6-rc/db.h
@@ -81,6 +81,7 @@ struct s6rc_db_s
{
char const *map ;
off_t size ;
+ cdb resolve ;
uint32_t const *n ;
s6rc_longrun_t const *longruns ;
s6rc_oneshot_t const *oneshots ;
@@ -93,7 +94,10 @@ struct s6rc_db_s
char const *storage ;
char const **argvs ; /* alloced */
} ;
-#define S6RC_DB_ZERO = { .map = 0, .len = 0 }
+#define S6RC_DB_ZERO = { .map = 0, .len = 0, .resolve = CDB_ZERO }
+
+extern void s6rc_db_free (s6rc_db_t *) ;
+extern int s6rc_db_init (s6rc_db_t *, char const *) ;
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 *) ;
diff --git a/src/libs6rc/s6rc_db_free.c b/src/libs6rc/s6rc_db_free.c
index 7e7ed54..549cfc8 100644
--- a/src/libs6rc/s6rc_db_free.c
+++ b/src/libs6rc/s6rc_db_free.c
@@ -4,6 +4,7 @@
#include <errno.h>
#include <skalibs/alloc.h>
+#include <skalibs/cdb.h>
#include <s6-rc/db.h>
@@ -11,6 +12,7 @@ void s6rc_db_free (s6rc_db_t *db)
{
int e = errno ;
alloc_free(db->argvs) ;
+ cdb_free(&db->resolve) ;
munmap(db->map, db->size) ;
db->map = 0 ;
errno = e ;
diff --git a/src/libs6rc/s6rc_db_load.c b/src/libs6rc/s6rc_db_init.c
index bcc5f2f..075d0c3 100644
--- a/src/libs6rc/s6rc_db_load.c
+++ b/src/libs6rc/s6rc_db_init.c
@@ -24,7 +24,7 @@ static int gethu32 (buffer *b, SHA256Schedule *ctx, uint32_t *n)
return 1 ;
}
-int s6rc_db_load (char const *dir, s6rc_db_t *db, cdb_t *c)
+int s6rc_db_init (s6rc_db_t *db, char const *dir)
{
SHA256Schedule ctx = SHA256_INIT() ;
uint32_t ntotal, ndeps, nproducers, storagelen, nargv ;
@@ -85,7 +85,7 @@ int s6rc_db_load (char const *dir, s6rc_db_t *db, cdb_t *c)
}
memcpy(fn + len, "/resolve.cdb", 13) ;
- if (!cdb_mapfile(fn, c)) goto err1 ;
+ if (!cdb_init(&db->resolve, fn)) goto err1 ;
{
ssize_t r ;
@@ -122,7 +122,7 @@ int s6rc_db_load (char const *dir, s6rc_db_t *db, cdb_t *c)
eproto2:
errno = EPROTO ;
err2:
- cdb_free(c) ;
+ cdb_free(&db->resolve) ;
err1:
{
int e = errno ;
diff --git a/src/libs6rc/s6rc_service_recheck_instance.c b/src/libs6rc/s6rc_service_recheck_instance.c
index b91ea2e..e8cf42c 100644
--- a/src/libs6rc/s6rc_service_recheck_instance.c
+++ b/src/libs6rc/s6rc_service_recheck_instance.c
@@ -7,14 +7,15 @@
#include <s6-rc/db.h>
-int s6rc_service_recheck_instance (s6rc_db_t const *db, cdb_t *c, uint32_t *id, char const **param)
+int s6rc_service_recheck_instance (s6rc_db_t const *db, 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
{
+ cdb_reader reader = CDB_READER_ZERO ;
+ cdb_data data ;
s6rc_common_t *common = s6rc_service_common(db->n, type, num) ;
size_t namelen = strlen(db->storage + common->name) ;
size_t paramlen = strlen(*param) ;
@@ -22,10 +23,11 @@ int s6rc_service_recheck_instance (s6rc_db_t const *db, cdb_t *c, uint32_t *id,
char tmp[namelen + paramlen] ;
memcpy(tmp, db->storage + common->name, namelen) ;
memcpy(tmp + namelen, *param, paramlen) ;
- r = cdb_find(c, tmp, namelen + paramlen) ;
+ r = cdb_find(c, &reader, &data, tmp, namelen + paramlen) ;
if (r <= 0) return r ;
+ if (data.len != 4) return -1 ;
+ uint32_unpack_big(data.s, id) ;
}
- 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 52caae7..6868e6b 100644
--- a/src/libs6rc/s6rc_service_resolve.c
+++ b/src/libs6rc/s6rc_service_resolve.c
@@ -1,7 +1,6 @@
/* ISC license. */
#include <string.h>
-#include <errno.h>
#include <skalibs/uint32.h>
#include <skalibs/bytestr.h>
@@ -9,22 +8,26 @@
#include <s6-rc/db.h>
-int s6rc_service_resolve (cdb_t *c, char const *s, uint32_t *id, char const **param)
+int s6rc_service_resolve (s6rc_db_t const *db, char const *s, uint32_t *id, char const **param)
{
size_t len = strlen(s) ;
char const *p = 0 ;
- int r = cdb_find(c, s, len) ;
+ cdb_reader reader = CDB_READER_ZERO ;
+ cdb_data data ;
+ int r = cdb_find(c, &reader, &data, s, len) ;
if (r < 0) return r ;
- if (!r)
+ else 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 (at == len - 1) return -1 ;
+ cdb_findstart(&reader) ;
+ r = cdb_find(c, &reader, &data, s, at + 1) ;
if (r <= 0) return r ;
p = s + at + 1 ;
}
- uint32_unpack_big(cdb_datapos(c), id) ;
+ if (data.len != 4) return -1 ;
+ uint32_unpack_big(data.s, id) ;
*param = p ;
return 1 ;
}
diff --git a/src/server/clientrules.c b/src/server/clientrules.c
index 4050b2f..6c930d8 100644
--- a/src/server/clientrules.c
+++ b/src/server/clientrules.c
@@ -17,8 +17,7 @@
static unsigned int rulestype = 0 ;
static char const *rules = 0 ;
-static int cdbfd = -1 ;
-static struct cdb cdbmap = CDB_ZERO ;
+static cdb cdbmap = CDB_ZERO ;
void clientrules_init (unsigned int type, char const *s)
{
@@ -26,28 +25,17 @@ void clientrules_init (unsigned int type, char const *s)
rules = s ;
if (rulestype == 2)
{
- cdbfd = open_readb(rules) ;
- if (cdbfd < 0) strerr_diefu3sys(111, "open ", rules, " for reading") ;
- if (cdb_init(&cdbmap, cdbfd) < 0)
+ if (!cdb_init(&cdbmap, rules))
strerr_diefu2sys(111, "cdb_init ", rules) ;
}
}
void clientrules_reload ()
{
- int fd ;
- struct cdb c = CDB_ZERO ;
+ cdb c = CDB_ZERO ;
if (rulestype != 2) break ;
- fd = open_readb(rules) ;
- if (fd < 0) break ;
- if (cdb_init(&c, fd) < 0)
- {
- fd_close(fd) ;
- break ;
- }
+ if (!cdb_init(&c, rules)) break ;
cdb_free(&cdbmap) ;
- fd_close(cdbfd) ;
- cdbfd = fd ;
cdbmap = c ;
}
diff --git a/src/server/deps.c b/src/server/deps.c
index 12e0fb6..b1a1fd4 100644
--- a/src/server/deps.c
+++ b/src/server/deps.c
@@ -15,7 +15,7 @@ static int state_allownext (sstate_t const *st, uint8_t deptype, uint8_t subtype
|| (s6rc_deptype_loose(deptype) && !(st->bits & SSTATE_TRANSITIONING))
}
-static int instances_alldown (mstate_t const *m, uint8_t deptype, uint8_t type, uint32_t num)
+static int instances_testalldown (mstate_t const *m, uint8_t deptype, uint8_t type, uint32_t num)
{
instance_t const *ins = genalloc_s(instance_t, m->dyn[type] + num) ;
size_t n = genalloc_len(instance_t, m->dyn[type] + num) ;
@@ -38,7 +38,7 @@ int deps_fulfilled (s6rc_db_t const *db, mstate_t const *m, uint32_t id, char co
uint8_t deptype = db->deptypes[h][common->deps[h] + i] ;
s6rc_service_typenum(db->n, db->deps[h][common->deps[h] + i], &subtype, &subnum) ;
if (!h && type < S6RC_STYPE_N && subtype >= S6RC_STYPE_N)
- return instances_alldown(m, deptype, subtype, subnum) ;
+ return instances_testalldown(m, deptype, subtype, subnum) ;
if (h && type >= S6RC_STYPE_N && subtype < S6RC_STYPE_N)
param = 0 ;
if (!state_allownext(sstate_tn(m, subtype, subnum, param), deptype, subtype, h))
@@ -47,18 +47,6 @@ int deps_fulfilled (s6rc_db_t const *db, mstate_t const *m, uint32_t id, char co
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
{
@@ -66,37 +54,70 @@ struct recinfo_s
mstate_t *m ;
char const *param ;
uint8_t h : 1 ;
+ uint8_t force : 1 ;
}
-static int mstate_dep_closure_rec (recinfo_t *recinfo, uint32_t id)
+static int mstate_dep_closure_rec (recinfo_t *recinfo, uint32_t id, char const *param)
{
- sstate_t *st = sstate(recinfo->db, recinfo->m, id, recinfo->param) ;
+ sstate_t *st ;
+ st = sstate(recinfo->db, recinfo->m, id, param) ;
if (!st)
{
- st = instance_create(recinfo->m, id, recinfo->param) ;
+ if (!recinfo->h) return 1 ;
+ st = instance_create(recinfo->m, id, param) ;
if (!st) return 0 ;
}
- if (!(st->tmp & SSTATE_GRAY))
+ if (!(st->tmp & SSTATE_TRANSITIONING))
{
- uint32_t ndeps = re
+ s6rc_common_t const *common ;
+ uint32_t num ;
+ uint8_t type ;
+ st->tmp |= SSTATE_TRANSITIONING ;
+ s6rc_service_typenum(recinfo->db->n, id, &type, &num) ;
+ common = s6rc_service_common_tn(recinfo->db, type, num) ;
+ if (!recinfo->h && !recinfo->force && common->flags & S6RC_DB_FLAG_ESSENTIAL) return (errno = EPERM, 0) ;
+ for (uint32_t i = 0 ; i < common->ndeps[recinfo->h] ; i++)
+ {
+ uint32_t subid = recinfo->db->deps[recinfo->h][common->deps[recinfo->h] + i] ;
+ uint32_t subnum ;
+ uint8_t subtype ;
+ if (s6rc_service_recheck_instance(recinfo->db, &subid, &param) < 0) return (errno = EPROTO, 0) ;
+ if (deptype_passive(recinfo->db->deptypes[recinfo->h][common->deps[recinfo->h] + i])) continue ;
+ s6rc_service_typenum(recinfo->db->n, subid, &subtype, &subnum) ;
+ if (!recinfo->h && type < S6RC_STYPE_N && subtype >= S6RC_STYPE_N)
+ {
+ instance_t const *ins = genalloc_s(instance_t, recinfo->m->dyn[subtype] + subnum) ;
+ size_t n = genalloc_len(instance_t, recinfo->m->dyn[subtype] + subnum) ;
+ for (size_t j = 0 ; j < n ; j++)
+ if (!mstate_dep_closure_rec(recinfo, subid, ins[j].param)) return 0 ;
+ }
+ else
+ {
+ if (recinfo->h && type >= S6RC_STYPE_N && subtype < S6RC_STYPE_N)
+ param = 0 ;
+ if (!mstate_dep_closure_rec(recinfo, subid, param))
+ return 0 ;
+ }
+ }
+ st->tmp |= SSTATE_WANTED ;
}
}
-static void mstate_dep_closure (s6rc_db_t const *db, mstate_t *m, sstate_t *st, char const *param, int h)
+static void mstate_dep_closure (s6rc_db_t const *db, mstate_t *m, sstate_t *st, char const *param, int h, int force)
{
- recinfo_t recinfo = { .db = db, .m = m, .param = param, .h = !!h } ;
+ recinfo_t recinfo = { .db = db, .m = m, .param = param, .h = !!h, .force = !!force } ;
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)
+int mstate_change_wanted (s6rc_db_t const *db, mstate_t *m, char const *const *args, size_t n, int h, int force)
{
- mstate_iterate(m, db->n, &sstate_zerotmp, &instancelen_nop, &instance_zerotmp, 0) ;
+ mstate_zerotmp(m, db->n) ;
for (size_t i = 0 ; i < n ; n++)
{
sstate_t *st ;
uint32_t id ;
char const *param ;
- int r = s6rc_service_resolve(c, args[i], &id, &param) ;
+ int r = s6rc_service_resolve(&db->resolve, args[i], &id, &param) ;
if (r < 0) return -1 ;
if (!r) return 1 + i ;
st = sstate(db, m, id, param) ;
@@ -105,7 +126,7 @@ int mstate_change_wanted (s6rc_db_t const *db, cdb_t *c, mstate_t *m, char const
st = instance_create(m, id, param) ;
if (!st) return -1 ;
}
- st->tmp |= SSTATE_MARK | SSTATE_EXPLICIT ;
+ st->tmp |= SSTATE_WANTED | SSTATE_EXPLICIT ;
mstate_dep_closure(db, m, st, param, h) ;
}
}
diff --git a/src/server/state.c b/src/server/state.c
index f106c20..6176e82 100644
--- a/src/server/state.c
+++ b/src/server/state.c
@@ -263,3 +263,20 @@ static int instancelen_nop_ (uint32_t n, void *arg)
}
instancelen_func_ref const instancelen_nop = &instancelen_nop_ ;
+
+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) ;
+}
+
+void mstate_zerotmp (mstate_t *m, uint32_t const *dbn)
+{
+ mstate_iterate(m, dbn, &sstate_zerotmp, &instancelen_nop, &instance_zerotmp, 0) ;
+}
diff --git a/src/server/state.h b/src/server/state.h
index 2decb80..a6b82f6 100644
--- a/src/server/state.h
+++ b/src/server/state.h
@@ -11,7 +11,6 @@
/* Service states, instances, machine state */
- /* bits */
#define SSTATE_TRANSITIONING 0x01u
#define SSTATE_FAILED 0x02u
#define SSTATE_CURRENT 0x04u
@@ -19,12 +18,6 @@
#define SSTATE_EXPLICIT 0x10u
#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
{
@@ -66,6 +59,7 @@ 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 int mstate_iterate (mstate_t *, uint32_t const *, sstate_func_ref, instancelen_func_ref, instance_func_ref, void *) ;
+extern void mstate_zerotmp (mstate_t *, uint32_t const *) ;
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 *) ;