From 89a440efc603e6d6c7fa85b01a5a904baff5cd26 Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Wed, 14 Jul 2021 01:09:14 +0000 Subject: More db/event/state changes Signed-off-by: Laurent Bercot --- src/include-local/db.h | 6 +- src/include/s6-rc/event.h | 18 ----- src/libs6rcd/s6rc_service_common.c | 2 +- src/server/ep.c | 5 +- src/server/ep.h | 6 +- src/server/ev.c | 47 ------------ src/server/ev.h | 19 ----- src/server/event.c | 29 +++++++ src/server/event.h | 29 +++++++ src/server/main.c | 139 +++++++++++++++++++++++++++++++++ src/server/main.h | 2 +- src/server/s6-rcd.c | 139 --------------------------------- src/server/service.c | 18 ----- src/server/state.c | 153 ++++++++++++++++++++----------------- src/server/state.h | 48 +++++++----- 15 files changed, 324 insertions(+), 336 deletions(-) delete mode 100644 src/include/s6-rc/event.h delete mode 100644 src/server/ev.c delete mode 100644 src/server/ev.h create mode 100644 src/server/event.c create mode 100644 src/server/event.h create mode 100644 src/server/main.c delete mode 100644 src/server/s6-rcd.c delete mode 100644 src/server/service.c diff --git a/src/include-local/db.h b/src/include-local/db.h index be7ef20..b35fc42 100644 --- a/src/include-local/db.h +++ b/src/include-local/db.h @@ -34,6 +34,9 @@ struct s6rc_common_s 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 { @@ -94,8 +97,7 @@ struct s6rc_db_s } ; #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 const *) ; +extern s6rc_common_t const *s6rc_service_common (s6rc_db_t const *, s6rc_id_t) ; #endif diff --git a/src/include/s6-rc/event.h b/src/include/s6-rc/event.h deleted file mode 100644 index 864c90c..0000000 --- a/src/include/s6-rc/event.h +++ /dev/null @@ -1,18 +0,0 @@ -/* ISC license. */ - -#ifndef S6RC_EVENT_H -#define S6RC_EVENT_H - -#include - -typedef struct s6rc_event_s s6rc_event_t, *s6rc_event_t_ref ; -struct s6rc_event_s -{ - uint32_t name ; - uint8_t current : 1 ; - uint8_t up : 1 ; - uint8_t extra : 6 ; -} ; -#define S6RC_EVENT_ZERO { .name = 0, .current = 0, .up = 0, .extra = 0 } - -#endif diff --git a/src/libs6rcd/s6rc_service_common.c b/src/libs6rcd/s6rc_service_common.c index 3361695..b91c902 100644 --- a/src/libs6rcd/s6rc_service_common.c +++ b/src/libs6rcd/s6rc_service_common.c @@ -2,7 +2,7 @@ #include "db.h" -s6rc_common_t const *s6rc_service_common (s6rc_db_t const *db, s6rc_id_t const *id) +s6rc_common_t const *s6rc_service_common (s6rc_db_t const *db, s6rc_id_t id) { switch (stype(id)) { diff --git a/src/server/ep.c b/src/server/ep.c index f5557a5..0757b25 100644 --- a/src/server/ep.c +++ b/src/server/ep.c @@ -9,13 +9,14 @@ #include #include -#include +#include "db.h" +#include "event.h" #include "ep.h" typedef struct epelem_s epelem_t, *epelem_t_ref ; struct epelem_s { - uint32_t owner ; + s6rc_id_t owner ; ep_func_t_ref f ; void *aux ; } ; diff --git a/src/server/ep.h b/src/server/ep.h index 96e6c59..e583c05 100644 --- a/src/server/ep.h +++ b/src/server/ep.h @@ -5,17 +5,17 @@ #include -#include +#include "event.h" /* Event processor: the dynamic part */ -typedef void ep_func_t (s6rc_event_t const *, uint32_t, void *) ; +typedef void ep_func_t (event_t const *, uint32_t, void *) ; typedef ep_func_t *ep_func_t_ref ; extern void ep_free (void) ; extern int ep_add (uint8_t, char const *, uint32_t, ep_func_t_ref, void *) ; extern void ep_delete (uint8_t, char const *, uint32_t, ep_func_t_ref, void *) ; -extern void ep_run (s6rc_event_t const *) ; +extern void ep_run (event_t const *) ; #endif diff --git a/src/server/ev.c b/src/server/ev.c deleted file mode 100644 index c201191..0000000 --- a/src/server/ev.c +++ /dev/null @@ -1,47 +0,0 @@ -/* ISC license. */ - -#include - -#include -#include "ev.h" - - -/* Event queue */ - -static genqdyn evq = GENQDYN_INIT(s6rc_event_t, 0, 1) ; /* only clean when it's empty */ - -int ev_enqueue (s6rc_event_t const *ev) -{ - return genqdyn_push(&evq, ev) ; -} - -int ev_pop (s6rc_event_t *ev) -{ - if (!genqdyn_n(&evq)) return 0 ; - *ev = *GENQDYN_PEEK(s6rc_event_t, &evq) ; - return genqdyn_pop(&evq) ; -} - - - /* Event processing (builtins) */ - -void ev_handle (s6rc_event_t const *ev) -{ - switch (ev->type) - { - case S6RC_EVENTTYPE_WANTED_STATE_DOWN : - break ; - case S6RC_EVENTTYPE_WANTED_STATE_UP : - break ; - case S6RC_EVENTTYPE_CURRENT_STATE_DOWN : - break ; - case S6RC_EVENTTYPE_CURRENT_STATE_UP : - break ; - case S6RC_EVENTTYPE_TRANSITION_STOP : - break ; - case S6RC_EVENTTYPE_TRANSITION_START : - break ; - case S6RC_EVENTTYPE_CUSTOM : - break ; - } -} diff --git a/src/server/ev.h b/src/server/ev.h deleted file mode 100644 index 67fe3c1..0000000 --- a/src/server/ev.h +++ /dev/null @@ -1,19 +0,0 @@ -/* ISC license. */ - -#ifndef S6RCD_EV_H -#define S6RCD_EV_H - -#include - - - /* Event queue */ - -extern int ev_enqueue (s6rc_event_t const *) ; -extern int ev_pop (s6rc_event_t *) ; - - - /* Event processor: the builtin part */ - -extern void ev_handle (s6rc_event_t const *) ; - -#endif diff --git a/src/server/event.c b/src/server/event.c new file mode 100644 index 0000000..11b5154 --- /dev/null +++ b/src/server/event.c @@ -0,0 +1,29 @@ +/* ISC license. */ + +#include + +#include "event.h" + + +/* Event queue */ + +static genqdyn evq = GENQDYN_INIT(event_t, 0, 1) ; /* only clean when it's empty */ + +int event_enqueue (event_t const *ev) +{ + return genqdyn_push(&evq, ev) ; +} + +int event_pop (event_t *ev) +{ + if (!genqdyn_n(&evq)) return 0 ; + *ev = *GENQDYN_PEEK(s6rc_event_t, &evq) ; + return genqdyn_pop(&evq) ; +} + + + /* Event processing (builtins) */ + +void event_handle (event_t const *ev) +{ +} diff --git a/src/server/event.h b/src/server/event.h new file mode 100644 index 0000000..b2faac4 --- /dev/null +++ b/src/server/event.h @@ -0,0 +1,29 @@ +/* ISC license. */ + +#ifndef S6RCD_EV_H +#define S6RCD_EV_H + +#include "db.h" + +typedef event_s event_t, *event_t_ref ; +struct event_s +{ + s6rc_id_t id ; + char const *param ; + uint8_t wanted : 1 ; + uint8_t up : 1 ; + uint8_t extra : 6 ; +} ; + + + /* Event queue */ + +extern int event_enqueue (event_t const *) ; +extern int event_pop (event_t *) ; + + + /* Event processor: the builtin part */ + +extern void event_handle (event_t const *) ; + +#endif diff --git a/src/server/main.c b/src/server/main.c new file mode 100644 index 0000000..0fcfb77 --- /dev/null +++ b/src/server/main.c @@ -0,0 +1,139 @@ +/* ISC license. */ + +#include + +#include +#include +#include +#include +#include + +#include "s6-rcd.h" + +#define USAGE "s6-rcd [ -v verbosity ] [ -1 ] [ -t timeout ] [ -T lameducktimeout ] [ -i rulesdir | -x rulesfile ] [ -l livedir ]" +#define dieusage() strerr_dieusage(100, USAGE) ; + +unsigned int verbosity = 1 ; +globalflags_t flags = +{ + .lameduck = 0 ; +} ; + +tain_t lameduckdeadline = TAIN_INFINITE_RELATIVE ; + +int main (int argc, char const *const *argv) +{ + int spfd, sock ; + PROG = "s6-rcd" ; + + { + char const *rules = 0 ; + unsigned int rulestype = 0 ; + int flag1 = 0 ; + unsigned int t = 0, T = 0 ; + subgetopt_t l = SUBGETOPT_ZERO ; + for (;;) + { + int opt = subgetopt_r(argc, argv, "v:1c:n:i:x:t:T:", &l) ; + if (opt == -1) break ; + switch (opt) + { + case 'v' : if (!uint0_scan(l.arg, &verbosity)) dieusage() ; break ; + case '1' : flag1 = 1 ; break ; + case 'i' : rules = l.arg ; rulestype = 1 ; break ; + case 'x' : rules = l.arg ; rulestype = 2 ; break ; + case 't' : if (!uint0_scan(l.arg, &t)) dieusage() ; break ; + case 'T' : if (!uint0_scan(l.arg, &T)) dieusage() ; break ; + default : dieusage() ; + } + } + argc -= l.ind ; argv += l.ind ; + if (t) tain_from_millisecs(&client_answer_tto, t) ; + if (T) tain_from_millisecs(&lameduckdeadline, T) ; + if (!rulestype) strerr_dief1x(100, "no access rights specified!") ; + if (flag1) + { + if (fcntl(1, F_GETFD) < 0) + strerr_dief1sys(100, "called with option -1 but stdout said") ; + } + else close(1) ; + + spfd = signals_init() ; + clientrules_init(rulestype, rules) ; + sock = livedir_init() ; + if (!tain_now_set_stopwatch_g()) + strerr_diefu1sys(111, "initialize clock") ; + if (flag1) + { + fd_write(1, "\n", 1) ; + fd_close(1) ; + } + } + + for (;;) + { + iopause_fd x[2 + client_connections + client_monitors] ; + tain_t deadline ; + uint32_t j = 2 ; + int r = 1 ; + + { + s6rc_event_t ev ; + while (ev_pop(&ev)) { ev_handle(&ev) ; ep_run(&ev) ; } + } + + tain_add_g(&deadline, &tain_infinite_relative) ; + if (flags.lameduck) deadline = lameduckdeadline ; + + x[0].fd = spfd ; + x[0].events = IOPAUSE_READ ; + x[1].fd = sock ; + x[1].events = !flags.lameduck ? IOPAUSE_READ : 0 ; + + for (client_t *c = client_head ; c ; c = c->next) + if (client_prepare_iopause(c, &deadline, x, &j)) r = 0 ; + + if (r) /* clean buffers */ + { + if (flags.lameduck) break ; + if (flags.dbupdate && db_update()) + { + flags.dbupdate = 0 ; + continue ; + } + } + + r = iopause_g(x, j, &deadline) ; + if (r < 0) strerr_diefu1sys(111, "iopause") ; + + if (!r) + { + if (flags.lameduck && !tain_future(&lameduckdeadline)) break ; + for (client_t *c = client_head ; c ; c = c ? c->next : client_head) + if (!tain_future(c->deadline)) client_yoink(&c) ; + continue ; + } + + if (x[0].revents & IOPAUSE_READ) signals_handle() ; + + for (client_t *c = client_head ; c ; c = c ? c->next : client_head) + if (!client_flush(c, x)) client_yoink(&c) ; + + for (client_t *c = client_head ; c ; c = c ? c->next : client_head) + if (!client_read(c, x)) client_yoink(&c) ; + + if (x[1].revents & IOPAUSE_READ) + { + uint8_t perms = 0 ; + int dummy ; + int fd = ipc_accept_nb(x[1].fd, 0, 0, &dummy) ; + if (fd < 0) + if (!error_isagain(errno)) strerr_diefu1sys(111, "accept connection") ; + else continue ; + else if (!clientrules_check(fd, &perms)) fd_close(fd) ; + else client_add(fd, perms) ; + } + } + + return 0 ; +} diff --git a/src/server/main.h b/src/server/main.h index c8495a7..a359170 100644 --- a/src/server/main.h +++ b/src/server/main.h @@ -4,7 +4,7 @@ #define S6RCD_MAIN_H - /* Exported by the main file, s6-rcd.c */ + /* Misc globals, exported by the file containing main() */ typedef struct globalflags_s globalflags_t, *globalflags_t_ref ; struct globalflags_s diff --git a/src/server/s6-rcd.c b/src/server/s6-rcd.c deleted file mode 100644 index 0fcfb77..0000000 --- a/src/server/s6-rcd.c +++ /dev/null @@ -1,139 +0,0 @@ -/* ISC license. */ - -#include - -#include -#include -#include -#include -#include - -#include "s6-rcd.h" - -#define USAGE "s6-rcd [ -v verbosity ] [ -1 ] [ -t timeout ] [ -T lameducktimeout ] [ -i rulesdir | -x rulesfile ] [ -l livedir ]" -#define dieusage() strerr_dieusage(100, USAGE) ; - -unsigned int verbosity = 1 ; -globalflags_t flags = -{ - .lameduck = 0 ; -} ; - -tain_t lameduckdeadline = TAIN_INFINITE_RELATIVE ; - -int main (int argc, char const *const *argv) -{ - int spfd, sock ; - PROG = "s6-rcd" ; - - { - char const *rules = 0 ; - unsigned int rulestype = 0 ; - int flag1 = 0 ; - unsigned int t = 0, T = 0 ; - subgetopt_t l = SUBGETOPT_ZERO ; - for (;;) - { - int opt = subgetopt_r(argc, argv, "v:1c:n:i:x:t:T:", &l) ; - if (opt == -1) break ; - switch (opt) - { - case 'v' : if (!uint0_scan(l.arg, &verbosity)) dieusage() ; break ; - case '1' : flag1 = 1 ; break ; - case 'i' : rules = l.arg ; rulestype = 1 ; break ; - case 'x' : rules = l.arg ; rulestype = 2 ; break ; - case 't' : if (!uint0_scan(l.arg, &t)) dieusage() ; break ; - case 'T' : if (!uint0_scan(l.arg, &T)) dieusage() ; break ; - default : dieusage() ; - } - } - argc -= l.ind ; argv += l.ind ; - if (t) tain_from_millisecs(&client_answer_tto, t) ; - if (T) tain_from_millisecs(&lameduckdeadline, T) ; - if (!rulestype) strerr_dief1x(100, "no access rights specified!") ; - if (flag1) - { - if (fcntl(1, F_GETFD) < 0) - strerr_dief1sys(100, "called with option -1 but stdout said") ; - } - else close(1) ; - - spfd = signals_init() ; - clientrules_init(rulestype, rules) ; - sock = livedir_init() ; - if (!tain_now_set_stopwatch_g()) - strerr_diefu1sys(111, "initialize clock") ; - if (flag1) - { - fd_write(1, "\n", 1) ; - fd_close(1) ; - } - } - - for (;;) - { - iopause_fd x[2 + client_connections + client_monitors] ; - tain_t deadline ; - uint32_t j = 2 ; - int r = 1 ; - - { - s6rc_event_t ev ; - while (ev_pop(&ev)) { ev_handle(&ev) ; ep_run(&ev) ; } - } - - tain_add_g(&deadline, &tain_infinite_relative) ; - if (flags.lameduck) deadline = lameduckdeadline ; - - x[0].fd = spfd ; - x[0].events = IOPAUSE_READ ; - x[1].fd = sock ; - x[1].events = !flags.lameduck ? IOPAUSE_READ : 0 ; - - for (client_t *c = client_head ; c ; c = c->next) - if (client_prepare_iopause(c, &deadline, x, &j)) r = 0 ; - - if (r) /* clean buffers */ - { - if (flags.lameduck) break ; - if (flags.dbupdate && db_update()) - { - flags.dbupdate = 0 ; - continue ; - } - } - - r = iopause_g(x, j, &deadline) ; - if (r < 0) strerr_diefu1sys(111, "iopause") ; - - if (!r) - { - if (flags.lameduck && !tain_future(&lameduckdeadline)) break ; - for (client_t *c = client_head ; c ; c = c ? c->next : client_head) - if (!tain_future(c->deadline)) client_yoink(&c) ; - continue ; - } - - if (x[0].revents & IOPAUSE_READ) signals_handle() ; - - for (client_t *c = client_head ; c ; c = c ? c->next : client_head) - if (!client_flush(c, x)) client_yoink(&c) ; - - for (client_t *c = client_head ; c ; c = c ? c->next : client_head) - if (!client_read(c, x)) client_yoink(&c) ; - - if (x[1].revents & IOPAUSE_READ) - { - uint8_t perms = 0 ; - int dummy ; - int fd = ipc_accept_nb(x[1].fd, 0, 0, &dummy) ; - if (fd < 0) - if (!error_isagain(errno)) strerr_diefu1sys(111, "accept connection") ; - else continue ; - else if (!clientrules_check(fd, &perms)) fd_close(fd) ; - else client_add(fd, perms) ; - } - } - - return 0 ; -} diff --git a/src/server/service.c b/src/server/service.c deleted file mode 100644 index b5d06f4..0000000 --- a/src/server/service.c +++ /dev/null @@ -1,18 +0,0 @@ -/* ISC license. */ - -#include "service.h" - -common_t const *service_common (db_t const *db, stype_t stype, uint32_t i) -{ - if (stype >= STYPE_PHAIL) return 0 ; - if (i >= db->n[stype]) return 0 ; - switch (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/server/state.c b/src/server/state.c index 29d1548..d9e3f61 100644 --- a/src/server/state.c +++ b/src/server/state.c @@ -17,28 +17,28 @@ #include -static stateatom_t const stateatom_zero = STATEATOM_ZERO ; +static sstate_t const sstate_zero = SSTATE_ZERO ; void instance_free (instance_t *ins) { dynstorage_remove(ins->param) ; } -int instance_new (instance_t *ins, stateatom_t const *state, char const *param) ; +int instance_new (instance_t *ins, sstate_t const *st, char const *param) ; { char const *s = dynstorage_add(param) ; if (!s) return 0 ; - ins->state = state ; + ins->state = *st ; inst->param = s ; return 1 ; } -void state_free (state_t *st, uint32_t const *dbn) +void mstate_free (mstate_t *st, uint32_t const *dbn) { - for (s6rc_stype_t type = S6RC_STYPE_LONGRUN ; type < S6RC_STYPE_PHAIL ; type++) + for (size_t type = 0 ; type < S6RC_STYPE_N ; type++) { alloc_free(st->sta[type]) ; - for (size_t i = 0 ; i < dbn[S6RC_STYPE_PHAIL + type] ; i++) + for (size_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) ; @@ -48,18 +48,18 @@ void state_free (state_t *st, uint32_t const *dbn) } } -int state_init (state_t *st, uint32_t const *dbn) +int mstate_init (mstate_t *st, uint32_t const *dbn) { - s6rc_stype_t type = 0 ; - for (; type < S6RC_STYPE_PHAIL ; type++) + size_t type = 0 ; + for (; type < S6RC_STYPE_N ; type++) { - st->sta[type] = alloc(sizeof(stateatom_t) * dbn[type]) ; + st->sta[type] = alloc(dbn[type]) ; if (!st->sta[type]) goto err ; - st->dyn[type] = alloc(sizeof(genalloc) * dbn[S6RC_STYPE_PHAIL + type]) ; + st->dyn[type] = alloc(sizeof(genalloc) * dbn[S6RC_STYPE_N + type]) ; if (!st->dyn[type]) { alloc_free(st->sta[type]) ; goto err ; } for (uint32_t i = 0 ; i < dbn[type] ; i++) - st->sta[type][i] = stateatom_zero ; - for (size_t i = 0 ; i < dbn[S6RC_STYPE_PHAIL + type] ; i++) + st->sta[type][i] = sstate_zero ; + for (uint32_t i = 0 ; i < dbn[S6RC_STYPE_N + type] ; i++) st->dyn[type][i] = genalloc_zero ; } return 1 ; @@ -73,13 +73,50 @@ int state_init (state_t *st, uint32_t const *dbn) return 0 ; } -static int atom_write (buffer *b, stateatom_t const *state) +static int sstate_write (buffer *b, sstate_t const *state) { - char c = state->wanted | (state->current << 1) | (state->transitioning << 2) ; - return buffer_put(b, &c, 1) == 1 ; + return buffer_put(b, (char *)state->bits, 1) == 1 ; } -int state_write (char const *file, state_t const *st, uint32_t const *dbn) +static int sstate_read (buffer *b, sstate_t *state) +{ + return buffer_get(b, (char *)state->bits, 1) == 1 ; +} + +static inline int instance_write (buffer *b, instance_t const *ins) +{ + uint32_t len = strlen(ins->param) ; + char pack[4] ; + uint32_pack_big(pack, len) ; + if (!sstate_write(b, &ins->state)) return 0 ; + if (buffer_put(b, pack, 4) < 4) return 0 ; + if (buffer_put(b, ins->param, len+1) < len+1) return 0 ; + 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) { size_t filelen = strlen(file) ; int fd ; @@ -92,12 +129,12 @@ int state_write (char const *file, state_t const *st, uint32_t const *dbn) if (fd == -1) return 0 ; buffer_init(&b, &buffer_write, fd, buf, 1024) ; - for (s6rc_stype_t type = 0 ; type < S6RC_STYPE_PHAIL ; type++) + for (size_t type = 0 ; type < S6RC_STYPE_N ; type++) for (uint32_t i = 0 ; i < dbn[type] ; i++) - if (!atom_write(&b, st->sta[type] + i)) goto err ; + if (!sstate_write(&b, st->sta[type] + i)) goto err ; - for (s6rc_stype_t type = 0 ; type < S6RC_STYPE_PHAIL ; type++) - for (uint32_t i = 0 ; i < dbn[S6RC_STYPE_PHAIL + type] ; i++) + 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) ; @@ -105,13 +142,7 @@ int state_write (char const *file, state_t const *st, uint32_t const *dbn) uint32_pack_big(pack, n) ; if (buffer_put(&b, pack, 4) < 4) goto err ; for (uint32_t j = 0 ; j < n ; j++) - { - uint32_t len = strlen(p[j].param) ; - uint32_pack_big(pack, len) ; - if (!atom_write(&p[j].state)) goto err ; - if (buffer_put(&b, pack, 4) < 4) goto err ; - if (buffer_put(&b, p[j].param, len+1) < len+1) goto err ; - } + if (!instance_write(&b, p + j)) goto err ; } if (!buffer_flush(&b)) goto err ; @@ -126,32 +157,22 @@ int state_write (char const *file, state_t const *st, uint32_t const *dbn) return 0 ; } -static int atom_read (buffer *b, stateatom_t *state) -{ - char c ; - if (buffer_get(b, &c, 1) < 1) return 0 ; - state->wanted = c & 1 ; - state->current = !!(c & 2) ; - state->transitioning = !!(c & 4) ; - return 1 ; -} - -int state_read (char const *file, state_t *st, uint32_t const *dbn) +int mstate_read (char const *file, mstate_t *st, uint32_t const *dbn) { int fd ; buffer b ; char buf[1024] ; - if (!state_init(st, dbn)) return 0 ; + if (!mstate_init(st, dbn)) return 0 ; fd = openc_read(file) ; if (fd == -1) goto err0 ; buffer_init(&b, &buffer_read, fd, buf, 1024) ; - for (s6rc_stype_t type = 0 ; type < S6RC_STYPE_PHAIL ; type++) + for (size_t type = 0 ; type < S6RC_STYPE_N ; type++) for (uint32_t i = 0 ; i < dbn[type] ; i++) - if (!atom_read(&b, st->sta[type] + i)) goto err ; + if (!sstate_read(&b, st->sta[type] + i)) goto err ; - for (s6rc_stype_t type = 0 ; type < S6RC_STYPE_PHAIL ; type++) - for (uint32_t i = 0 ; i < dbn[S6RC_STYPE_PHAIL + type] ; i++) + 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 ; char pack[4] ; @@ -159,22 +180,8 @@ int state_read (char const *file, state_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 ; i < n ; j++) - { - uint32_t len ; - instance_t *ins = genalloc_s(instance_t, st->dyn[type] + i) + j ; - 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]) goto eproto ; - ins->param = dynstorage_add(param) ; - if (!ins_param) goto err ; - } - } + for (uint32_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) ; } @@ -195,19 +202,29 @@ int state_read (char const *file, state_t *st, uint32_t const *dbn) err: fd_close(fd) ; err0: - state_free(st, dbn) ; + mstate_free(st, dbn) ; return 0 ; } -stateatom_t *state_atom (state_t const *st, s6rc_sid_t const *id) +sstate_t *sstate (mstate_t const *m, s6rc_id_t id, char const *param) { - if (id->param) + if (stype(id) >= S6RC_STYPE_N) { - size_t n = genalloc_len(instance_t, st->dyn[id->stype] + id->i) ; - instance_t *instances = genalloc_s(instance_t, st->dyn[id->stype] + id->i) ; + 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)) ; for (size_t i = 0 ; i < n ; i++) - if (!strcmp(id->param, instances[i].param)) return &instances[i].state ; - return 0 ; + if (!strcmp(param, instances[i].param)) return &instances[i].sstate ; + return STATE_PHAIL ; + } + else return st->sta[stype(id)] + snum(id) ; +} + +int state_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++) + { + uint8_t deptype = db->deptypes[h][common->deps[h] + i] ; + sstate_t *st = sstate(m, db->deps[h][common->deps[h] + i], param) ; } - else return st->sta[id->stype] + id->i ; } diff --git a/src/server/state.h b/src/server/state.h index 2690f45..2084437 100644 --- a/src/server/state.h +++ b/src/server/state.h @@ -3,44 +3,56 @@ #ifndef S6RCD_STATE_H #define S6RCD_STATE_H +#include + #include #include "db.h" /* Service states, instances, machine state */ -typedef struct stateatom_s stateatom_t, *stateatom_t_ref ; -struct stateatom_s +#define SSTATE_STABLE 0x00u +#define SSTATE_WAITING 0x01u +#define SSTATE_TRANSITIONING 0x02u +#define SSTATE_FAILED 0x03u + +#define SSTATE_CURRENT 0x04u +#define SSTATE_WANTED 0x08u +#define SSTATE_EXPLICIT 0x10u +#define SSTATE_GRAY 0x20u +#define SSTATE_BLACK 0x40u +#define SSTATE_INVALID 0x80u + +typedef struct sstate_s sstate_t, *sstate_t_ref ; +struct sstate_s { - uint8_t wanted : 1 ; - uint8_t current : 1 ; - uint8_t transitioning : 1 ; -} ; -#define STATEATOM_ZERO { .wanted = 0, .current = 0, .transitioning = 0 } + uint8_t bits ; +} typedef struct instance_s instance_t, *instance_t_ref ; struct instance_s { char const *param ; /* refcounted pointer to dynstorage */ - stateatom_t state ; + sstate_t sstate ; } ; -typedef struct state_s state_t, *state_t_ref ; -struct state_s +typedef struct mstate_s mstate_t, *mstate_t_ref ; +struct mstate_s { - stateatom_t *sta[S6RC_STYPE_PHAIL] ; - genalloc *dyn[S6RC_STYPE_PHAIL] ; /* every genalloc is a list of instance_t */ + sstate_t *sta[S6RC_STYPE_N] ; + 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 *, stateatom_t const *, char const *) ; +extern int instance_new (instance_t *, uint8_t *, char const *) ; -extern void state_free (state_t *, uint32_t const *) ; -extern int state_init (state_t *, uint32_t const *) ; +extern void mstate_free (mstate_t *, uint32_t const *) ; +extern int mstate_init (mstate_t *, uint32_t const *) ; -extern int state_write (char const *, state_t const *, uint32_t const *) ; -extern int state_read (char const *, state_t *, uint32_t const *) ; /* also inits */ +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 stateatom_t *state_atom (s6rc_db_t const *, state_t const *, s6rc_sid_t const *) ; +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) ; #endif -- cgit v1.2.3