diff options
author | Laurent Bercot <ska-skaware@skarnet.org> | 2021-06-28 17:26:47 +0000 |
---|---|---|
committer | Laurent Bercot <ska@appnovation.com> | 2021-06-28 17:26:47 +0000 |
commit | ae1a76cad535a04f0c059e8dae9c8a27a84222a4 (patch) | |
tree | 91648546a5c588a5f0e68ef530d311e594440f4e | |
parent | c26824e1f078b8de0d38cb87d3f291235ab5cf76 (diff) | |
download | s6-rc-ae1a76cad535a04f0c059e8dae9c8a27a84222a4.tar.xz |
Some more code around state
Signed-off-by: Laurent Bercot <ska@appnovation.com>
-rw-r--r-- | src/include/s6-rc/db.h | 110 | ||||
-rw-r--r-- | src/include/s6-rc/event.h | 5 | ||||
-rw-r--r-- | src/libs6rc/s6rc_service_common.c | 19 | ||||
-rw-r--r-- | src/libs6rc/s6rc_service_resolve.c | 33 | ||||
-rw-r--r-- | src/server/service.h | 108 | ||||
-rw-r--r-- | src/server/state.c | 122 | ||||
-rw-r--r-- | src/server/state.h | 45 | ||||
-rw-r--r-- | src/server/transition.h | 24 |
8 files changed, 291 insertions, 175 deletions
diff --git a/src/include/s6-rc/db.h b/src/include/s6-rc/db.h index 0f03967..8953a49 100644 --- a/src/include/s6-rc/db.h +++ b/src/include/s6-rc/db.h @@ -1,23 +1,53 @@ /* ISC license. */ -#ifndef S6RC_DB_H -#define S6RC_DB_H +#ifndef S6RC_SERVICE_H +#define S6RC_SERVICE_H #include <stdint.h> -#include <skalibs/diuint32.h> -#include <skalibs/buffer.h> -#define S6RC_DB_BANNER_START "s6rc-db: start\n" -#define S6RC_DB_BANNER_START_LEN (sizeof(S6RC_DB_BANNER_START) - 1) -#define S6RC_DB_BANNER_END "\ns6rc-db: end\n" -#define S6RC_DB_BANNER_END_LEN (sizeof(S6RC_DB_BANNER_END) - 1) -#define S6RC_DB_FLAG_ESSENTIAL 0x00000001U + /* Service types and db representation in memory */ +typedef enum s6rc_stype_e s6rc_stype_t, *s6rc_stype_t_ref ; +enum s6rc_stype_e +{ + S6RC_STYPE_LONGRUN, + S6RC_STYPE_ONESHOT, + S6RC_STYPE_EXTERNAL, + S6RC_STYPE_BUNDLE, + S6RC_STYPE_VIRTUAL, + S6RC_STYPE_PHAIL +} ; + +typedef struct s6rc_sid_s s6rc_sid_t, *s6rc_sid_t_ref ; +struct s6rc_sid_s +{ + uint32_t i ; + char const *param ; + s6rc_stype_t stype ; +} ; + +typedef struct s6rc_common_s s6rc_common_t, *s6rc_common_t_ref ; +struct s6rc_common_s +{ + uint32_t name ; + uint32_t deps[2] ; + uint32_t ndeps[2] ; + uint32_t flag_essential : 1 ; + uint32_t flags : 31 ; +} ; + +typedef struct s6rc_atomic_s s6rc_atomic_t, *s6rc_atomic_t_ref ; +struct s6rc_atomic_s +{ + s6rc_common_t common ; + uint32_t timeout[2] ; +} ; typedef struct s6rc_oneshot_s s6rc_oneshot_t, *s6rc_oneshot_t_ref ; struct s6rc_oneshot_s { + s6rc_atomic_t satomic ; uint32_t argc[2] ; uint32_t argv[2] ; } ; @@ -25,52 +55,52 @@ struct s6rc_oneshot_s typedef struct s6rc_longrun_s s6rc_longrun_t, *s6rc_longrun_t_ref ; struct s6rc_longrun_s { - uint32_t consumer ; + s6rc_atomic_t satomic ; + s6rc_sid_t consumer ; uint32_t nproducers ; uint32_t producers ; } ; -typedef union s6rc_longshot_u s6rc_longshot_t, *s6rc_longshot_t_ref ; -union s6rc_longshot_u +typedef struct s6rc_external_s s6rc_external_t, *s6rc_external_t_ref ; +struct s6rc_external_s { - s6rc_oneshot_t oneshot ; - s6rc_longrun_t longrun ; + s6rc_common_t common ; } ; -typedef struct s6rc_service_s s6rc_service_t, *s6rc_service_t_ref ; -struct s6rc_service_s +typedef struct s6rc_bundle_s s6rc_bundle_t, *s6rc_bundle_t_ref ; +struct s6rc_bundle_s { - uint32_t name ; - uint32_t flags ; - uint32_t deps[2] ; - uint32_t ndeps[2] ; - uint32_t timeout[2] ; - s6rc_longshot_t x ; + s6rc_common_t common ; + uint32_t ncontents ; + uint32_t contents ; +} ; + +typedef struct s6rc_deptype_s s6rc_deptype_t, *s6rc_deptype_t_ref ; +struct s6rc_deptype_s +{ + uint8_t passive : 1 ; + uint8_t soft : 1 ; + uint8_t loose : 1 ; } ; typedef struct s6rc_db_s s6rc_db_t, *s6rc_db_t_ref ; struct s6rc_db_s { - s6rc_service_t *services ; - unsigned int nshort ; - unsigned int nlong ; - unsigned int stringlen ; - unsigned int nargvs ; - unsigned int ndeps ; - unsigned int nproducers ; - char *string ; + uint32_t ntotal ; + uint32_t n[STYPE_PHAIL << 1] ; + uint32_t storagelen ; + s6rc_longrun_t *longruns ; + s6rc_oneshot_t *oneshots ; + s6rc_external_t *externals ; + s6rc_bundle_t *bundles ; + s6rc_bundle_t *virtuals ; + s6rc_sid_t *deps[2] ; + s6rc_deptype_t *deptypes[2] ; + s6rc_sid_t *producers ; char const **argvs ; - uint32_t *deps ; - uint32_t *producers ; + char *storage ; } ; -extern int s6rc_db_read_uint32 (buffer *, uint32_t *) ; - -extern int s6rc_db_read_sizes (int, s6rc_db_t *) ; -extern int s6rc_db_read (int, s6rc_db_t *) ; - -extern int s6rc_db_check_pipelines (s6rc_db_t const *, diuint32 *) ; -extern int s6rc_db_check_depcycles (s6rc_db_t const *, int, diuint32 *) ; -extern int s6rc_db_check_revdeps (s6rc_db_t const *) ; +extern s6rc_common_t const *s6rc_service_common (s6rc_db_t const *, s6rc_sid_t const *) ; #endif diff --git a/src/include/s6-rc/event.h b/src/include/s6-rc/event.h index f99b571..864c90c 100644 --- a/src/include/s6-rc/event.h +++ b/src/include/s6-rc/event.h @@ -9,11 +9,10 @@ typedef struct s6rc_event_s s6rc_event_t, *s6rc_event_t_ref ; struct s6rc_event_s { uint32_t name ; - uint32_t instance ; - uint8_t wanted : 1 ; + uint8_t current : 1 ; uint8_t up : 1 ; uint8_t extra : 6 ; } ; -#define S6RC_EVENT_ZERO { .name = 0, .instance = 0, .wanted = 0, .updown = 0, .extra = 0 } +#define S6RC_EVENT_ZERO { .name = 0, .current = 0, .up = 0, .extra = 0 } #endif diff --git a/src/libs6rc/s6rc_service_common.c b/src/libs6rc/s6rc_service_common.c new file mode 100644 index 0000000..f3146be --- /dev/null +++ b/src/libs6rc/s6rc_service_common.c @@ -0,0 +1,19 @@ +/* ISC license. */ + +#include <stdint.h> + +#include <s6-rc/db.h> + +s6rc_common_t const *s6rc_service_common (s6rc_db_t const *db, s6rc_sid_t const *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 ; + } +} diff --git a/src/libs6rc/s6rc_service_resolve.c b/src/libs6rc/s6rc_service_resolve.c new file mode 100644 index 0000000..858f67c --- /dev/null +++ b/src/libs6rc/s6rc_service_resolve.c @@ -0,0 +1,33 @@ +/* ISC license. */ + +#include <string.h> +#include <errno.h> + +#include <skalibs/uint32.h> +#include <skalibs/bytestr.h> +#include <skalibs/cdb.h> + +#include <s6-rc/db.h> + +int s6rc_service_resolve (cdb_t *c, s6rc_sid_t *id, char const *s) +{ + size_t len = strlen(s) ; + char const *param = 0 ; + char pack[5] ; + int r = cdb_find(c, s, len) ; + if (r < 0) return r ; + 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 (r <= 0) return r ; + param = 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 ; + return 1 ; +} 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 <stdint.h> - -#include <skalibs/stralloc.h> - - - /* 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 <stdint.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> + +#include <skalibs/alloc.h> +#include <skalibs/genalloc.h> +#include <skalibs/buffer.h> +#include <skalibs/djbunix.h> + +#include <s6-rc/db.h> +#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 <skalibs/genalloc.h> + +#include <s6-rc/db.h> + + + /* 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 <sys/types.h> -#include <stdint.h> - - - /* 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 |