summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/include-local/db.h6
-rw-r--r--src/include/s6-rc/event.h18
-rw-r--r--src/libs6rcd/s6rc_service_common.c2
-rw-r--r--src/server/ep.c5
-rw-r--r--src/server/ep.h6
-rw-r--r--src/server/ev.c47
-rw-r--r--src/server/ev.h19
-rw-r--r--src/server/event.c29
-rw-r--r--src/server/event.h29
-rw-r--r--src/server/main.c (renamed from src/server/s6-rcd.c)0
-rw-r--r--src/server/main.h2
-rw-r--r--src/server/service.c18
-rw-r--r--src/server/state.c153
-rw-r--r--src/server/state.h48
14 files changed, 185 insertions, 197 deletions
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 <stdint.h>
-
-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 <skalibs/gensetdyn.h>
#include <skalibs/avltree.h>
-#include <s6-rc/event.h>
+#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 <stdint.h>
-#include <s6-rc/event.h>
+#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 <skalibs/genqdyn.h>
-
-#include <s6-rc/event.h>
-#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 <s6-rc/event.h>
-
-
- /* 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 <skalibs/genqdyn.h>
+
+#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/s6-rcd.c b/src/server/main.c
index 0fcfb77..0fcfb77 100644
--- a/src/server/s6-rcd.c
+++ b/src/server/main.c
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/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 <skalibs/posixishard.h>
-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 <stdint.h>
+
#include <skalibs/genalloc.h>
#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