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 "queue.h"
#include "runlevel.h"
#include "service.h"
#include "spawn.h"
#include "target.h"
#include <dirent.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);
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);
-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_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;
}
+4 -1
View File
@@ -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);
@@ -1,4 +1,4 @@
#include "runlevel.h"
#include "target.h"
#include "log.h"
#include "service.h"
@@ -14,36 +14,35 @@
#include <stdlib.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)) {
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;
}
+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