diff --git a/services/herdd/main.c b/services/herdd/main.c index 6694d44..0b1c729 100644 --- a/services/herdd/main.c +++ b/services/herdd/main.c @@ -1,8 +1,8 @@ #include "log.h" #include "queue.h" -#include "runlevel.h" #include "service.h" #include "spawn.h" +#include "target.h" #include #include @@ -46,7 +46,7 @@ static int load_services(const char *dir, struct queue *out) snprintf(filepath, sizeof filepath, "%s/%s", dir, dent->d_name); tracef(" - %s\n", dent->d_name); struct service *s = NULL; - int err = service_load(filepath, &s); + int err = service_load(dent->d_name, filepath, &s); if (err != SUCCESS) { printf("failed to load %s (%s)\n", filepath, @@ -60,7 +60,7 @@ static int load_services(const char *dir, struct queue *out) return SUCCESS; } -static int load_runlevels(const char *dir, struct queue *out) +static int load_targets(const char *dir, struct queue *out) { DIR *d = opendir(dir); if (!d) { @@ -74,8 +74,8 @@ static int load_runlevels(const char *dir, struct queue *out) char filepath[4096]; snprintf(filepath, sizeof filepath, "%s/%s", dir, dent->d_name); tracef(" - %s\n", dent->d_name); - struct runlevel *rl = NULL; - int err = runlevel_load(filepath, &rl); + struct target *rl = NULL; + int err = target_load(dent->d_name, filepath, &rl); if (err != SUCCESS) { printf("failed to load %s (%s)\n", filepath, @@ -83,7 +83,7 @@ static int load_runlevels(const char *dir, struct queue *out) continue; } - tracef("runlevel: %s\n", rl->rl_description); + tracef("target: %s\n", rl->rl_description); for (size_t i = 0; i < rl->rl_requires_count; i++) { tracef(" requires: %s\n", rl->rl_requires[i]); } @@ -99,19 +99,19 @@ int main(int argc, const char *argv[], const char *envp[]) { sys_remote_set(SYS_REMOTE_NSD, 0, 0); - struct queue *runlevels = global_runlevels(); + struct queue *targets = global_targets(); struct queue *services = global_services(); - int err = load_runlevels("/etc/herdd/runlevels", runlevels); + int err = load_targets("/etc/herdd/targets", targets); err = load_services("/etc/herdd/services", services); - struct runlevel *rl = runlevel_find("single-user"); + struct target *rl = target_find("single-user.target"); if (!rl) { - log_fail("Cannot find runlevel single-user."); + log_fail("Cannot find target single-user."); return -1; } - runlevel_activate(rl); + target_activate(rl); #if 1 pid_t child = fork(); kern_logf(" fork returned %d", child); diff --git a/services/herdd/runlevel.h b/services/herdd/runlevel.h deleted file mode 100644 index 5667352..0000000 --- a/services/herdd/runlevel.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef RUNLEVEL_H_ -#define RUNLEVEL_H_ - -#include "queue.h" - -#include - -struct runlevel { - char *rl_name; - char *rl_description; - char **rl_requires; - size_t rl_requires_count; - struct queue_entry rl_entry; -}; - -extern struct queue *global_runlevels(void); - -extern int runlevel_load(const char *path, struct runlevel **out); -extern struct runlevel *runlevel_find(const char *name); -extern int runlevel_activate(struct runlevel *rl); - -#endif diff --git a/services/herdd/service.c b/services/herdd/service.c index 0c654d2..c5a73f0 100644 --- a/services/herdd/service.c +++ b/services/herdd/service.c @@ -43,13 +43,6 @@ static int parse_service_data(fx_object *in, struct service *out) fx_hashtable *in_unit = NULL; fx_value_get_object(unit_v, &in_unit); - const fx_value *name_v = fx_hashtable_get(in_unit, &FX_CSTR("name")); - if (!name_v || !fx_value_is_type(name_v, FX_TYPE_STRING)) { - return -1; - } - fx_string *name = NULL; - fx_value_get_object(name_v, &name); - const fx_value *description_v = fx_hashtable_get(in_unit, &FX_CSTR("description")); if (!description_v @@ -101,24 +94,23 @@ static int parse_service_data(fx_object *in, struct service *out) } fx_iterator_unref(it); - out->s_name = fx_string_steal(name); out->s_description = fx_string_steal(description); out->s_exec = fx_string_steal(exec); return 0; } -int service_load(const char *path, struct service **out) +int service_load(const char *name, const char *path, struct service **out) { - struct service *rl = malloc(sizeof *rl); - if (!rl) { + struct service *svc = malloc(sizeof *svc); + if (!svc) { errno = ENOMEM; return -1; } FILE *fp = fopen(path, "r"); if (!fp) { - free(rl); + free(svc); return -1; } @@ -128,30 +120,32 @@ int service_load(const char *path, struct service **out) fx_result result = fx_serial_ctx_deserialise(ctx, in, &data, 0); if (fx_result_is_error(result)) { fx_throw(result); - free(rl); + free(svc); errno = EFTYPE; return -1; } if (!fx_value_is_type(&data, FX_TYPE_HASHTABLE)) { fx_value_unset(&data); - free(rl); + free(svc); errno = EFTYPE; return -1; } - if (parse_service_data(data.v_object, rl) != 0) { - free(rl); + if (parse_service_data(data.v_object, svc) != 0) { + free(svc); errno = EFTYPE; return -1; } + svc->s_name = fx_strdup(name); + fx_stream_unref(in); fx_value_unset(&data); fclose(fp); - *out = rl; + *out = svc; return 0; } diff --git a/services/herdd/service.h b/services/herdd/service.h index 7231b6c..0cb2f8f 100644 --- a/services/herdd/service.h +++ b/services/herdd/service.h @@ -18,7 +18,10 @@ struct service { extern struct queue *global_services(void); -extern int service_load(const char *path, struct service **out); +extern int service_load( + const char *name, + const char *path, + struct service **out); extern struct service *service_find(const char *name); extern int service_start(struct service *svc); diff --git a/services/herdd/runlevel.c b/services/herdd/target.c similarity index 67% rename from services/herdd/runlevel.c rename to services/herdd/target.c index a519690..dde35f2 100644 --- a/services/herdd/runlevel.c +++ b/services/herdd/target.c @@ -1,4 +1,4 @@ -#include "runlevel.h" +#include "target.h" #include "log.h" #include "service.h" @@ -14,36 +14,35 @@ #include #include -static struct queue runlevels = QUEUE_INIT; +static struct queue targets = QUEUE_INIT; -struct queue *global_runlevels(void) +struct queue *global_targets(void) { - return &runlevels; + return &targets; } -static int parse_runlevel_data(fx_object *in, struct runlevel *out) +static int parse_target_data(fx_object *in, struct target *out) { if (!fx_object_is_type(in, FX_TYPE_HASHTABLE)) { return -1; } - const fx_value *runlevel_v = fx_hashtable_get(in, &FX_CSTR("runlevel")); - if (!runlevel_v || !fx_value_is_type(runlevel_v, FX_TYPE_HASHTABLE)) { + const fx_value *target_v = fx_hashtable_get(in, &FX_CSTR("target")); + if (!target_v || !fx_value_is_type(target_v, FX_TYPE_HASHTABLE)) { return -1; } - fx_hashtable *in_runlevel = NULL; - fx_value_get_object(runlevel_v, &in_runlevel); + fx_hashtable *in_target = NULL; + fx_value_get_object(target_v, &in_target); - const fx_value *name_v - = fx_hashtable_get(in_runlevel, &FX_CSTR("name")); - if (!name_v || !fx_value_is_type(name_v, FX_TYPE_STRING)) { + const fx_value *unit_v = fx_hashtable_get(in, &FX_CSTR("unit")); + if (!unit_v || !fx_value_is_type(unit_v, FX_TYPE_HASHTABLE)) { return -1; } - fx_string *name = NULL; - fx_value_get_object(name_v, &name); + fx_hashtable *in_unit = NULL; + fx_value_get_object(unit_v, &in_unit); const fx_value *description_v - = fx_hashtable_get(in_runlevel, &FX_CSTR("description")); + = fx_hashtable_get(in_unit, &FX_CSTR("description")); if (!description_v || !fx_value_is_type(description_v, FX_TYPE_STRING)) { return -1; @@ -52,7 +51,7 @@ static int parse_runlevel_data(fx_object *in, struct runlevel *out) fx_value_get_object(description_v, &description); const fx_value *deps_v - = fx_hashtable_get(in_runlevel, &FX_CSTR("requires")); + = fx_hashtable_get(in_target, &FX_CSTR("requires")); if (deps_v && !fx_value_is_type(deps_v, FX_TYPE_ARRAY)) { return -1; } @@ -87,15 +86,14 @@ static int parse_runlevel_data(fx_object *in, struct runlevel *out) } fx_iterator_unref(it); - out->rl_name = fx_string_steal(name); out->rl_description = fx_string_steal(description); return 0; } -int runlevel_load(const char *path, struct runlevel **out) +int target_load(const char *name, const char *path, struct target **out) { - struct runlevel *rl = malloc(sizeof *rl); + struct target *rl = malloc(sizeof *rl); if (!rl) { errno = ENOMEM; return -1; @@ -124,12 +122,14 @@ int runlevel_load(const char *path, struct runlevel **out) return -1; } - if (parse_runlevel_data(data.v_object, rl) != 0) { + if (parse_target_data(data.v_object, rl) != 0) { free(rl); errno = EFTYPE; return -1; } + rl->rl_name = fx_strdup(name); + fx_stream_unref(in); fx_value_unset(&data); @@ -139,12 +139,12 @@ int runlevel_load(const char *path, struct runlevel **out) return 0; } -struct runlevel *runlevel_find(const char *name) +struct target *target_find(const char *name) { - struct queue_entry *cur = queue_first(&runlevels); + struct queue_entry *cur = queue_first(&targets); while (cur) { - struct runlevel *rl - = QUEUE_CONTAINER(struct runlevel, rl_entry, cur); + struct target *rl + = QUEUE_CONTAINER(struct target, rl_entry, cur); if (!strcmp(rl->rl_name, name)) { return rl; } @@ -155,7 +155,7 @@ struct runlevel *runlevel_find(const char *name) return NULL; } -int runlevel_activate(struct runlevel *rl) +int target_activate(struct target *rl) { for (size_t i = 0; i < rl->rl_requires_count; i++) { const char *svc_name = rl->rl_requires[i]; @@ -171,6 +171,6 @@ int runlevel_activate(struct runlevel *rl) } } - log_ok("Reached runlevel %s.", rl->rl_description); + log_ok("Reached target %s.", rl->rl_description); return 0; } diff --git a/services/herdd/target.h b/services/herdd/target.h new file mode 100644 index 0000000..0c8e9d5 --- /dev/null +++ b/services/herdd/target.h @@ -0,0 +1,22 @@ +#ifndef TARGET_H_ +#define TARGET_H_ + +#include "queue.h" + +#include + +struct target { + char *rl_name; + char *rl_description; + char **rl_requires; + size_t rl_requires_count; + struct queue_entry rl_entry; +}; + +extern struct queue *global_targets(void); + +extern int target_load(const char *name, const char *path, struct target **out); +extern struct target *target_find(const char *name); +extern int target_activate(struct target *rl); + +#endif