services: herdd: implement scanning and parsing of runlevel and service config files
This commit is contained in:
+102
-37
@@ -1,5 +1,14 @@
|
||||
#include "log.h"
|
||||
#include "queue.h"
|
||||
#include "runlevel.h"
|
||||
#include "service.h"
|
||||
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <fx/ds/string.h>
|
||||
#include <mango/log.h>
|
||||
#include <mango/task.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@@ -7,61 +16,117 @@
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef TRACE
|
||||
#define tracef(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define tracef(...)
|
||||
#endif
|
||||
|
||||
static void *thread_func(void *arg)
|
||||
{
|
||||
kern_logf("started thread with arg %p", arg);
|
||||
tracef("started thread with arg %p\n", arg);
|
||||
errno = 100;
|
||||
tracef("thread done");
|
||||
return (void *)0xdeadbeef;
|
||||
}
|
||||
|
||||
static int load_services(const char *dir, struct queue *out)
|
||||
{
|
||||
DIR *d = opendir(dir);
|
||||
if (!d) {
|
||||
printf("cannot open '%s': %s\n", dir, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct dirent *dent = NULL;
|
||||
|
||||
while ((dent = readdir(d))) {
|
||||
char filepath[4096];
|
||||
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);
|
||||
if (err != SUCCESS) {
|
||||
printf("failed to load %s (%s)\n",
|
||||
filepath,
|
||||
strerror(errno));
|
||||
}
|
||||
|
||||
queue_push_back(out, &s->s_entry);
|
||||
}
|
||||
|
||||
closedir(d);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
static int load_runlevels(const char *dir, struct queue *out)
|
||||
{
|
||||
DIR *d = opendir(dir);
|
||||
if (!d) {
|
||||
printf("cannot open '%s': %s\n", dir, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct dirent *dent = NULL;
|
||||
|
||||
while ((dent = readdir(d))) {
|
||||
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);
|
||||
if (err != SUCCESS) {
|
||||
printf("failed to load %s (%s)\n",
|
||||
filepath,
|
||||
strerror(errno));
|
||||
continue;
|
||||
}
|
||||
|
||||
tracef("runlevel: %s\n", rl->rl_description);
|
||||
for (size_t i = 0; i < rl->rl_requires_count; i++) {
|
||||
tracef(" requires: %s\n", rl->rl_requires[i]);
|
||||
}
|
||||
|
||||
queue_push_back(out, &rl->rl_entry);
|
||||
}
|
||||
|
||||
closedir(d);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int main(int argc, const char *argv[], const char *envp[])
|
||||
{
|
||||
sys_remote_set(SYS_REMOTE_NSD, 0, 0);
|
||||
|
||||
kern_logf("herdd");
|
||||
kern_logf("args:");
|
||||
struct queue *runlevels = global_runlevels();
|
||||
struct queue *services = global_services();
|
||||
|
||||
for (int i = 0; i < argc; i++) {
|
||||
kern_logf("[%d]: %s", i, argv[i]);
|
||||
int err = load_runlevels("/etc/herdd/runlevels", runlevels);
|
||||
err = load_services("/etc/herdd/services", services);
|
||||
|
||||
struct runlevel *rl = runlevel_find("single-user");
|
||||
if (!rl) {
|
||||
log_fail("Cannot find runlevel single-user.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
kern_logf("env:");
|
||||
runlevel_activate(rl);
|
||||
|
||||
for (int i = 0; envp[i]; i++) {
|
||||
kern_logf("[%d]: %s", i, envp[i]);
|
||||
}
|
||||
kern_handle_t new_task = 123, new_space = 456;
|
||||
kern_status_t status = task_duplicate(&new_task, &new_space);
|
||||
kern_logf(
|
||||
" task_duplicate returned %d (%x/%x)",
|
||||
status,
|
||||
new_task,
|
||||
new_space);
|
||||
|
||||
kern_logf("self = %p", pthread_self());
|
||||
errno = 200;
|
||||
|
||||
#if 1
|
||||
int dir = open("/", 0);
|
||||
if (dir >= 0) {
|
||||
kern_logf("opened '/'");
|
||||
char buf[4096] = {0};
|
||||
struct dentry *dent = (struct dentry *)buf;
|
||||
long len = getdents(dir, dent, sizeof buf);
|
||||
if (len < 0) {
|
||||
kern_logf("getdents failed (%s)", strerror(errno));
|
||||
} else {
|
||||
for (long i = 0; i < len;) {
|
||||
dent = (struct dentry *)(buf + i);
|
||||
kern_logf(" - %s", dent->d_name);
|
||||
i += dent->d_reclen;
|
||||
}
|
||||
}
|
||||
close(dir);
|
||||
if (new_task == KERN_HANDLE_INVALID) {
|
||||
kern_log("this is the child");
|
||||
} else {
|
||||
kern_logf("open() failed: %s", strerror(errno));
|
||||
kern_log("this is the parent");
|
||||
}
|
||||
#endif
|
||||
|
||||
pthread_t thread;
|
||||
pthread_create(&thread, NULL, thread_func, (void *)0xdeafcafe);
|
||||
kern_logf("started thread %p", thread);
|
||||
void *ret = NULL;
|
||||
pthread_join(thread, &ret);
|
||||
kern_logf("thread returned %p", ret);
|
||||
printf("hello\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user