#include <assert.h>
#include <errno.h>
+#include <string.h>
#include "manager.h"
#include "hashmap.h"
#include "macro.h"
#include "strv.h"
+#include "load-fragment.h"
Manager* manager_new(void) {
Manager *m;
goto fail;
if (type == JOB_START || type == JOB_VERIFY_STARTED || type == JOB_RESTART_FINISH) {
- SET_FOREACH(dep, ret->name->meta.requires, state)
+ SET_FOREACH(dep, ret->name->meta.dependencies[NAME_REQUIRES], state)
if ((r = manager_add_job(m, type, dep, mode, NULL)) < 0)
goto fail;
- SET_FOREACH(dep, ret->name->meta.soft_requires, state)
+ SET_FOREACH(dep, ret->name->meta.dependencies[NAME_SOFT_REQUIRES], state)
if ((r = manager_add_job(m, type, dep, JOB_FAIL, NULL)) < 0)
goto fail;
- SET_FOREACH(dep, ret->name->meta.wants, state)
+ SET_FOREACH(dep, ret->name->meta.dependencies[NAME_WANTS], state)
if ((r = manager_add_job(m, type, dep, JOB_FAIL, NULL)) < 0)
goto fail;
- SET_FOREACH(dep, ret->name->meta.requisite, state)
+ SET_FOREACH(dep, ret->name->meta.dependencies[NAME_REQUISITE], state)
if ((r = manager_add_job(m, JOB_VERIFY_STARTED, dep, mode, NULL)) < 0)
goto fail;
- SET_FOREACH(dep, ret->name->meta.soft_requisite, state)
+ SET_FOREACH(dep, ret->name->meta.dependencies[NAME_SOFT_REQUISITE], state)
if ((r = manager_add_job(m, JOB_VERIFY_STARTED, dep, JOB_FAIL, NULL)) < 0)
goto fail;
- SET_FOREACH(dep, ret->name->meta.conflicts, state)
+ SET_FOREACH(dep, ret->name->meta.dependencies[NAME_CONFLICTS], state)
if ((r = manager_add_job(m, type, dep, mode, NULL)) < 0)
goto fail;
} else if (type == JOB_STOP || type == JOB_RESTART || type == JOB_TRY_RESTART) {
- SET_FOREACH(dep, ret->name->meta.required_by, state)
+ SET_FOREACH(dep, ret->name->meta.dependencies[NAME_REQUIRED_BY], state)
if ((r = manager_add_job(m, type, dep, mode, NULL)) < 0)
goto fail;
}
return hashmap_get(m->names, name);
}
-static int detect_type(Name *name) {
- char **n;
+static int verify_type(Name *name) {
+ char *n;
+ void *state;
assert(name);
- name->meta.type = _NAME_TYPE_INVALID;
+ /* Checks that all aliases of this name have the same and valid type */
- STRV_FOREACH(n, name->meta.names) {
+ SET_FOREACH(n, name->meta.names, state) {
NameType t;
- if ((t = name_type_from_string(*n)) == _NAME_TYPE_INVALID)
+ if ((t = name_type_from_string(n)) == _NAME_TYPE_INVALID)
return -EINVAL;
if (name->meta.type == _NAME_TYPE_INVALID) {
return -EINVAL;
}
- return 0;
-}
-
-static int fragment_load(Name *n) {
- assert(n);
-
- /*... */
+ if (name->meta.type == _NAME_TYPE_INVALID)
+ return -EINVAL;
return 0;
}
-static int sysv_load(Service *s) {
+static int service_load_sysv(Service *s) {
assert(s);
- /*... */
+ /* Load service data from SysV init scripts, preferably with
+ * LSB headers ... */
return 0;
}
-static int fstab_load(Name *n) {
+static int name_load_fstab(Name *n) {
assert(n);
assert(n->meta.type == NAME_MOUNT || n->meta.type == NAME_AUTOMOUNT);
- /*... */
+ /* Load mount data from /etc/fstab */
return 0;
}
static int snapshot_load(Snapshot *s) {
assert(s);
- /*... */
+ /* Load snapshots from disk */
+
+ return 0;
+}
+
+static int name_load_dropin(Name *n) {
+ assert(n);
+
+ /* Load dependencies from drop-in directories */
return 0;
}
if (name->meta.state != NAME_STUB)
return 0;
- if ((r = detect_type(name)) < 0)
+ if ((r = verify_type(name)) < 0)
return r;
if (name->meta.type == NAME_SERVICE) {
/* Load a .service file */
- if ((r = fragment_load(name)) == 0)
+ if ((r = name_load_fragment(name)) == 0)
goto finish;
/* Load a classic init script */
if (r == -ENOENT)
- if ((r = sysv_load(SERVICE(name))) == 0)
+ if ((r = service_load_sysv(SERVICE(name))) == 0)
goto finish;
} else if (name->meta.type == NAME_MOUNT ||
name->meta.type == NAME_AUTOMOUNT) {
- if ((r = fstab_load(name)) == 0)
+ if ((r = name_load_fstab(name)) == 0)
goto finish;
} else if (name->meta.type == NAME_SNAPSHOT) {
goto finish;
} else {
- if ((r = fragment_load(name)) == 0)
+ if ((r = name_load_fragment(name)) == 0)
goto finish;
}
return r;
finish:
+ if ((r = name_load_dropin(name)) < 0)
+ return r;
+
name->meta.state = NAME_LOADED;
return 0;
}
assert(m);
+ /* Make sure we are not run recursively */
+ if (m->dispatching_load_queue)
+ return 0;
+
+ m->dispatching_load_queue = true;
+
/* Dispatches the load queue. Takes a name from the queue and
* tries to load its data until the queue is empty */
LIST_REMOVE(Meta, m->load_queue, meta);
}
+ m->dispatching_load_queue = false;
+
return 0;
}
-
-
int manager_load_name(Manager *m, const char *name, Name **_ret) {
Name *ret;
NameType t;
int r;
+ char *n;
assert(m);
assert(name);
assert(_ret);
-/* This will load the service information files, but not actually
- * start any services or anything */
+ if (!name_is_valid(name))
+ return -EINVAL;
+
+ /* This will load the service information files, but not actually
+ * start any services or anything */
if ((ret = manager_get_name(m, name)))
goto finish;
ret->meta.type = t;
- if (!(ret->meta.names = strv_new(name, NULL))) {
+ if (!(n = strdup(name))) {
+ name_free(ret);
+ return -ENOMEM;
+ }
+
+ if (set_put(ret->meta.names, n) < 0) {
name_free(ret);
+ free(n);
return -ENOMEM;
}