herdd: rename runlevels to targets

This commit is contained in:
2026-05-30 19:47:49 +01:00
parent 97facbed6f
commit 277d87adb0
6 changed files with 74 additions and 77 deletions
+11 -11
View File
@@ -1,8 +1,8 @@
#include "log.h" #include "log.h"
#include "queue.h" #include "queue.h"
#include "runlevel.h"
#include "service.h" #include "service.h"
#include "spawn.h" #include "spawn.h"
#include "target.h"
#include <dirent.h> #include <dirent.h>
#include <errno.h> #include <errno.h>
@@ -46,7 +46,7 @@ static int load_services(const char *dir, struct queue *out)
snprintf(filepath, sizeof filepath, "%s/%s", dir, dent->d_name); snprintf(filepath, sizeof filepath, "%s/%s", dir, dent->d_name);
tracef(" - %s\n", dent->d_name); tracef(" - %s\n", dent->d_name);
struct service *s = NULL; struct service *s = NULL;
int err = service_load(filepath, &s); int err = service_load(dent->d_name, filepath, &s);
if (err != SUCCESS) { if (err != SUCCESS) {
printf("failed to load %s (%s)\n", printf("failed to load %s (%s)\n",
filepath, filepath,
@@ -60,7 +60,7 @@ static int load_services(const char *dir, struct queue *out)
return SUCCESS; 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); DIR *d = opendir(dir);
if (!d) { if (!d) {
@@ -74,8 +74,8 @@ static int load_runlevels(const char *dir, struct queue *out)
char filepath[4096]; char filepath[4096];
snprintf(filepath, sizeof filepath, "%s/%s", dir, dent->d_name); snprintf(filepath, sizeof filepath, "%s/%s", dir, dent->d_name);
tracef(" - %s\n", dent->d_name); tracef(" - %s\n", dent->d_name);
struct runlevel *rl = NULL; struct target *rl = NULL;
int err = runlevel_load(filepath, &rl); int err = target_load(dent->d_name, filepath, &rl);
if (err != SUCCESS) { if (err != SUCCESS) {
printf("failed to load %s (%s)\n", printf("failed to load %s (%s)\n",
filepath, filepath,
@@ -83,7 +83,7 @@ static int load_runlevels(const char *dir, struct queue *out)
continue; 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++) { for (size_t i = 0; i < rl->rl_requires_count; i++) {
tracef(" requires: %s\n", rl->rl_requires[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); sys_remote_set(SYS_REMOTE_NSD, 0, 0);
struct queue *runlevels = global_runlevels(); struct queue *targets = global_targets();
struct queue *services = global_services(); 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); err = load_services("/etc/herdd/services", services);
struct runlevel *rl = runlevel_find("single-user"); struct target *rl = target_find("single-user.target");
if (!rl) { if (!rl) {
log_fail("Cannot find runlevel single-user."); log_fail("Cannot find target single-user.");
return -1; return -1;
} }
runlevel_activate(rl); target_activate(rl);
#if 1 #if 1
pid_t child = fork(); pid_t child = fork();
kern_logf(" fork returned %d", child); kern_logf(" fork returned %d", child);
-22
View File
@@ -1,22 +0,0 @@
#ifndef RUNLEVEL_H_
#define RUNLEVEL_H_
#include "queue.h"
#include <stddef.h>
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
+11 -17
View File
@@ -43,13 +43,6 @@ static int parse_service_data(fx_object *in, struct service *out)
fx_hashtable *in_unit = NULL; fx_hashtable *in_unit = NULL;
fx_value_get_object(unit_v, &in_unit); 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 const fx_value *description_v
= fx_hashtable_get(in_unit, &FX_CSTR("description")); = fx_hashtable_get(in_unit, &FX_CSTR("description"));
if (!description_v if (!description_v
@@ -101,24 +94,23 @@ static int parse_service_data(fx_object *in, struct service *out)
} }
fx_iterator_unref(it); fx_iterator_unref(it);
out->s_name = fx_string_steal(name);
out->s_description = fx_string_steal(description); out->s_description = fx_string_steal(description);
out->s_exec = fx_string_steal(exec); out->s_exec = fx_string_steal(exec);
return 0; 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); struct service *svc = malloc(sizeof *svc);
if (!rl) { if (!svc) {
errno = ENOMEM; errno = ENOMEM;
return -1; return -1;
} }
FILE *fp = fopen(path, "r"); FILE *fp = fopen(path, "r");
if (!fp) { if (!fp) {
free(rl); free(svc);
return -1; 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); fx_result result = fx_serial_ctx_deserialise(ctx, in, &data, 0);
if (fx_result_is_error(result)) { if (fx_result_is_error(result)) {
fx_throw(result); fx_throw(result);
free(rl); free(svc);
errno = EFTYPE; errno = EFTYPE;
return -1; return -1;
} }
if (!fx_value_is_type(&data, FX_TYPE_HASHTABLE)) { if (!fx_value_is_type(&data, FX_TYPE_HASHTABLE)) {
fx_value_unset(&data); fx_value_unset(&data);
free(rl); free(svc);
errno = EFTYPE; errno = EFTYPE;
return -1; return -1;
} }
if (parse_service_data(data.v_object, rl) != 0) { if (parse_service_data(data.v_object, svc) != 0) {
free(rl); free(svc);
errno = EFTYPE; errno = EFTYPE;
return -1; return -1;
} }
svc->s_name = fx_strdup(name);
fx_stream_unref(in); fx_stream_unref(in);
fx_value_unset(&data); fx_value_unset(&data);
fclose(fp); fclose(fp);
*out = rl; *out = svc;
return 0; return 0;
} }
+4 -1
View File
@@ -18,7 +18,10 @@ struct service {
extern struct queue *global_services(void); 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 struct service *service_find(const char *name);
extern int service_start(struct service *svc); extern int service_start(struct service *svc);
@@ -1,4 +1,4 @@
#include "runlevel.h" #include "target.h"
#include "log.h" #include "log.h"
#include "service.h" #include "service.h"
@@ -14,36 +14,35 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
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)) { if (!fx_object_is_type(in, FX_TYPE_HASHTABLE)) {
return -1; return -1;
} }
const fx_value *runlevel_v = fx_hashtable_get(in, &FX_CSTR("runlevel")); const fx_value *target_v = fx_hashtable_get(in, &FX_CSTR("target"));
if (!runlevel_v || !fx_value_is_type(runlevel_v, FX_TYPE_HASHTABLE)) { if (!target_v || !fx_value_is_type(target_v, FX_TYPE_HASHTABLE)) {
return -1; return -1;
} }
fx_hashtable *in_runlevel = NULL; fx_hashtable *in_target = NULL;
fx_value_get_object(runlevel_v, &in_runlevel); fx_value_get_object(target_v, &in_target);
const fx_value *name_v const fx_value *unit_v = fx_hashtable_get(in, &FX_CSTR("unit"));
= fx_hashtable_get(in_runlevel, &FX_CSTR("name")); if (!unit_v || !fx_value_is_type(unit_v, FX_TYPE_HASHTABLE)) {
if (!name_v || !fx_value_is_type(name_v, FX_TYPE_STRING)) {
return -1; return -1;
} }
fx_string *name = NULL; fx_hashtable *in_unit = NULL;
fx_value_get_object(name_v, &name); fx_value_get_object(unit_v, &in_unit);
const fx_value *description_v const fx_value *description_v
= fx_hashtable_get(in_runlevel, &FX_CSTR("description")); = fx_hashtable_get(in_unit, &FX_CSTR("description"));
if (!description_v if (!description_v
|| !fx_value_is_type(description_v, FX_TYPE_STRING)) { || !fx_value_is_type(description_v, FX_TYPE_STRING)) {
return -1; return -1;
@@ -52,7 +51,7 @@ static int parse_runlevel_data(fx_object *in, struct runlevel *out)
fx_value_get_object(description_v, &description); fx_value_get_object(description_v, &description);
const fx_value *deps_v 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)) { if (deps_v && !fx_value_is_type(deps_v, FX_TYPE_ARRAY)) {
return -1; return -1;
} }
@@ -87,15 +86,14 @@ static int parse_runlevel_data(fx_object *in, struct runlevel *out)
} }
fx_iterator_unref(it); fx_iterator_unref(it);
out->rl_name = fx_string_steal(name);
out->rl_description = fx_string_steal(description); out->rl_description = fx_string_steal(description);
return 0; 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) { if (!rl) {
errno = ENOMEM; errno = ENOMEM;
return -1; return -1;
@@ -124,12 +122,14 @@ int runlevel_load(const char *path, struct runlevel **out)
return -1; return -1;
} }
if (parse_runlevel_data(data.v_object, rl) != 0) { if (parse_target_data(data.v_object, rl) != 0) {
free(rl); free(rl);
errno = EFTYPE; errno = EFTYPE;
return -1; return -1;
} }
rl->rl_name = fx_strdup(name);
fx_stream_unref(in); fx_stream_unref(in);
fx_value_unset(&data); fx_value_unset(&data);
@@ -139,12 +139,12 @@ int runlevel_load(const char *path, struct runlevel **out)
return 0; 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) { while (cur) {
struct runlevel *rl struct target *rl
= QUEUE_CONTAINER(struct runlevel, rl_entry, cur); = QUEUE_CONTAINER(struct target, rl_entry, cur);
if (!strcmp(rl->rl_name, name)) { if (!strcmp(rl->rl_name, name)) {
return rl; return rl;
} }
@@ -155,7 +155,7 @@ struct runlevel *runlevel_find(const char *name)
return NULL; 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++) { for (size_t i = 0; i < rl->rl_requires_count; i++) {
const char *svc_name = rl->rl_requires[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; return 0;
} }
+22
View File
@@ -0,0 +1,22 @@
#ifndef TARGET_H_
#define TARGET_H_
#include "queue.h"
#include <stddef.h>
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