summaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2021-06-28 17:26:47 +0000
committerLaurent Bercot <ska@appnovation.com>2021-06-28 17:26:47 +0000
commitae1a76cad535a04f0c059e8dae9c8a27a84222a4 (patch)
tree91648546a5c588a5f0e68ef530d311e594440f4e /src/server
parentc26824e1f078b8de0d38cb87d3f291235ab5cf76 (diff)
downloads6-rc-ae1a76cad535a04f0c059e8dae9c8a27a84222a4.tar.xz
Some more code around state
Signed-off-by: Laurent Bercot <ska@appnovation.com>
Diffstat (limited to 'src/server')
-rw-r--r--src/server/service.h108
-rw-r--r--src/server/state.c122
-rw-r--r--src/server/state.h45
-rw-r--r--src/server/transition.h24
4 files changed, 167 insertions, 132 deletions
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