From ae1a76cad535a04f0c059e8dae9c8a27a84222a4 Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Mon, 28 Jun 2021 17:26:47 +0000 Subject: Some more code around state Signed-off-by: Laurent Bercot --- src/server/service.h | 108 ------------------------------------------ src/server/state.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++++ src/server/state.h | 45 ++++++++++++++++++ src/server/transition.h | 24 ---------- 4 files changed, 167 insertions(+), 132 deletions(-) delete mode 100644 src/server/service.h create mode 100644 src/server/state.c create mode 100644 src/server/state.h delete mode 100644 src/server/transition.h (limited to 'src/server') diff --git a/src/server/service.h b/src/server/service.h deleted file mode 100644 index 86ee341..0000000 --- a/src/server/service.h +++ /dev/null @@ -1,108 +0,0 @@ -/* ISC license. */ - -#ifndef S6RCD_SERVICE_H -#define S6RCD_SERVICE_H - -#include - -#include - - - /* Service types and db representation in memory */ - -typedef enum stype_e stype_t, *stype_t_ref ; -enum stype_e -{ - STYPE_LONGRUN, - STYPE_ONESHOT, - STYPE_EXTERNAL, - STYPE_BUNDLE, - STYPE_VIRTUAL, - STYPE_PHAIL -} ; - -typedef struct common_s common_t, *common_t_ref ; -struct common_s -{ - uint32_t name ; - uint32_t deps[2] ; - uint32_t ndeps[2] ; - uint32_t flag_dynamic : 1 ; - uint32_t flag_essential : 1 ; - uint32_t flags : 30 ; -} ; - -typedef struct satomic_s satomic_t, *satomic_t_ref ; -struct satomic_s -{ - common_t common ; - uint32_t timeout[2] ; -} ; - -typedef struct oneshot_s oneshot_t, *oneshot_t_ref ; -struct oneshot_s -{ - satomic_t satomic ; - uint32_t argc[2] ; - uint32_t argv[2] ; -} ; - -typedef struct longrun_s longrun_t, *longrun_t_ref ; -struct longrun_s -{ - satomic_t satomic ; - uint32_t consumer ; - uint32_t nproducers ; - uint32_t producers ; -} ; - -typedef struct external_s external_t, *external_t_ref ; -struct external_s -{ - common_t common ; -} ; - -typedef struct bundle_s bundle_t, *bundle_t_ref ; -struct bundle_s -{ - common_t common ; - uint32_t ncontents ; - uint32_t contents ; -} ; - -typedef struct virtual_s virtual_t, *virtual_t_ref ; -struct virtual_s -{ - common_t common ; - uint32_t ncontents ; - uint32_t contents ; -} ; - -typedef struct deptype_s deptype_t, *deptype_t_ref ; -struct deptype_s -{ - uint8_t passive : 1 ; - uint8_t soft : 1 ; - uint8_t loose : 1 ; -} ; - -typedef struct db_s db_t, *db_t_ref ; -struct db_s -{ - uint32_t n[STYPE_PHAIL] ; - longrun_t *longruns ; - oneshot_t *oneshots ; - external_t *externals ; - bundle_t *bundles ; - virtual_t *virtuals ; - char const **argvs ; - uint32_t *deps[2] ; - deptype_t *deptypes[2] ; - uint32_t *producers ; - char *storage ; - uint32_t storagelen ; -} ; - -extern common_t const *service_common (db_t const *, stype_t, uint32_t) ; - -#endif diff --git a/src/server/state.c b/src/server/state.c new file mode 100644 index 0000000..0e2afe3 --- /dev/null +++ b/src/server/state.c @@ -0,0 +1,122 @@ +/* ISC license. */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include "state.h" + +void state_free (state_t *st, uint32_t const *dbn) +{ + for (s6rc_stype_t type = S6RC_STYPE_LONGRUN ; type < S6RC_STYPE_PHAIL ; type++) + { + alloc_free(st->sta[type]) ; + for (size_t i = 0 ; i < dbn[S6RC_STYPE_PHAIL + type] ; i++) + genalloc_free(instance_t, st->dyn[type] + i) ; + alloc_free(st->dyn[type]) ; + } +} + +int state_ready (state_t *st, uint32_t const *dbn) +{ + s6rc_stype_t type = 0 ; + for (; type < S6RC_STYPE_PHAIL ; type++) + { + genalloc *q ; + stateatom_t *p = alloc(sizeof(stateatom_t) * dbn[type]) ; + if (!p) goto err ; + q = alloc(sizeof(genalloc) * dbn[S6RC_STYPE_PHAIL + type]) ; + if (!q) { alloc_free(p) ; goto err ; } + st->sta[type] = p ; + for (size_t i = 0 ; i < dbn[S6RC_STYPE_PHAIL + type] ; i++) q[i] = genalloc_zero ; + st->dyn[type] = q ; + } + return 1 ; + + err: + while (type--) + { + alloc_free(st->dyn[type]) ; + alloc_free(st->sta[type]) ; + } + return 0 ; +} + +stateatom_t *state_atom (state_t const *st, s6rc_sid_t const *id) +{ + if (id->param) + { + 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) ; + for (size_t i = 0 ; i < n ; i++) + if (!strcmp(id->param, instances[i].param)) return &instances[i].state ; + return 0 ; + } + else return st->sta[id->stype] + id->i ; +} + +static int atom_write (buffer *b, stateatom_t const *state) +{ + char c = state->wanted | (state->current << 1) | (state->transitioning << 2) ; + return buffer_put(b, &c, 1) == 1 ; +} + +int state_write (char const *file, state_t const *st, uint32_t const *dbn) +{ + size_t filelen = strlen(file) ; + int fd ; + buffer b ; + char buf[1024] ; + char fn[filelen + 12] ; + memcpy(fn, file, filelen) ; + memcpy(fn + filelen, ":tmp:XXXXXX", 12) ; + fd = mkstemp(fn) ; + if (fd == -1) return 0 ; + buffer_init(&b, &buffer_write, fd, buf, 1024) ; + + for (s6rc_stype_t type = 0 ; type < S6RC_STYPE_PHAIL ; type++) + { + char pack[4] ; + uint32_pack_big(pack, dbn[type]) ; + if (buffer_put(&b, pack, 4) < 4) goto err ; + } + for (s6rc_stype_t type = 0 ; type < S6RC_STYPE_PHAIL ; type++) + { + for (uint32_t i = 0 ; i < dbn[type] ; i++) + if (!atom_write(&b, st->sta[type] + i)) goto err ; + for (uint32_t i = 0 ; i < dbn[S6RC_STYPE_PHAIL + 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) ; + char pack[4] ; + 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 (!buffer_flush(&b)) goto err ; + fd_close(fd) ; + if (rename(fn, file) == -1) goto err0 ; + return 1 ; + + err: + fd_close(fd) ; + err0: + unlink_void(fn) ; + return 0 ; +} diff --git a/src/server/state.h b/src/server/state.h new file mode 100644 index 0000000..f0149bc --- /dev/null +++ b/src/server/state.h @@ -0,0 +1,45 @@ +/* ISC license. */ + +#ifndef S6RCD_STATE_H +#define S6RCD_STATE_H + +#include + +#include + + + /* Service states, instances, machine state */ + +typedef struct stateatom_s stateatom_t, *stateatom_t_ref ; +struct stateatom_s +{ + uint8_t wanted : 1 ; + uint8_t current : 1 ; + uint8_t transitioning : 1 ; +} ; + +typedef struct instance_s instance_t, *instance_t_ref ; +struct instance_s +{ + char const *param ; + stateatom_t state ; +} ; + +typedef struct state_s state_t, *state_t_ref ; +struct state_s +{ + stateatom_t *sta[S6RC_STYPE_PHAIL] ; + genalloc *dyn[S6RC_STYPE_PHAIL] ; /* every genalloc is a list of instance_t */ +} ; + +extern void state_free (state_t *, uint32_t const *) ; +extern int state_ready (state_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 *) ; + + +extern stateatom_t *state_atom (s6rc_db_t const *, state_t const *, s6rc_sid_t const *) ; + + +#endif diff --git a/src/server/transition.h b/src/server/transition.h deleted file mode 100644 index 3ade951..0000000 --- a/src/server/transition.h +++ /dev/null @@ -1,24 +0,0 @@ -/* ISC license. */ - -#ifndef S6RCD_TRANSITION_H -#define S6RCD_TRANSITION_H - -#include -#include - - - /* Transitions */ - -typedef struct transition_s transition_t, *transition_t_ref ; -struct transition_s -{ - pid_t pid ; - uint32_t service ; - uint8_t updown : 1 ; -} ; -#define TRANSITION_ZERO { .pid = 0, .service = 0, } - -extern uint32_t ntransitions ; -transitions_t *transitions ; - -#endif -- cgit v1.2.3