chiark / gitweb /
s/name/unit
authorLennart Poettering <lennart@poettering.net>
Tue, 26 Jan 2010 20:39:06 +0000 (21:39 +0100)
committerLennart Poettering <lennart@poettering.net>
Tue, 26 Jan 2010 20:39:06 +0000 (21:39 +0100)
38 files changed:
Makefile
automount.c
automount.h
conf-parser.c
conf-parser.h
device.c
device.h
fixme
job.c
job.h
load-dropin.c
load-dropin.h
load-fragment.c
load-fragment.h
load-fstab.c
load-fstab.h
main.c
manager.c
manager.h
mount.c
mount.h
name.c [deleted file]
name.h [deleted file]
service.c
service.h
snapshot.c
snapshot.h
socket.c
socket.h
target.c
target.h
test-engine.c
timer.c
timer.h
unit.c [new file with mode: 0644]
unit.h [new file with mode: 0644]
util.c
util.h

index c473262..9a86220 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ CFLAGS=-Wall -Wextra -O0 -g -pipe -D_GNU_SOURCE -fdiagnostics-show-option -Wno-u
 LIBS=-lrt -lcap
 
 COMMON= \
-       name.o \
+       unit.o \
        util.o \
        set.o \
        hashmap.o \
index b64bacb..7b397c9 100644 (file)
@@ -2,43 +2,43 @@
 
 #include <errno.h>
 
-#include "name.h"
+#include "unit.h"
 #include "automount.h"
 #include "load-fragment.h"
 #include "load-fstab.h"
 #include "load-dropin.h"
 
-static int automount_init(Name *n) {
+static int automount_init(Unit *u) {
         int r;
-        Automount *a = AUTOMOUNT(n);
+        Automount *a = AUTOMOUNT(u);
 
         assert(a);
 
         exec_context_init(&a->exec_context);
 
         /* Load a .automount file */
-        if ((r = name_load_fragment(n)) < 0 && errno != -ENOENT)
+        if ((r = unit_load_fragment(u)) < 0 && errno != -ENOENT)
                 return r;
 
         /* Load entry from /etc/fstab */
-        if ((r = name_load_fstab(n)) < 0)
+        if ((r = unit_load_fstab(u)) < 0)
                 return r;
 
         /* Load drop-in directory data */
-        if ((r = name_load_dropin(n)) < 0)
+        if ((r = unit_load_dropin(u)) < 0)
                 return r;
 
         return 0;
 }
 
-static void automount_done(Name *n) {
-        Automount *d = AUTOMOUNT(n);
+static void automount_done(Unit *u) {
+        Automount *d = AUTOMOUNT(u);
 
         assert(d);
         free(d->path);
 }
 
-static void automount_dump(Name *n, FILE *f, const char *prefix) {
+static void automount_dump(Unit *u, FILE *f, const char *prefix) {
 
         static const char* const state_table[_AUTOMOUNT_STATE_MAX] = {
                 [AUTOMOUNT_DEAD] = "dead",
@@ -59,7 +59,7 @@ static void automount_dump(Name *n, FILE *f, const char *prefix) {
         };
 
         AutomountExecCommand c;
-        Automount *s = AUTOMOUNT(n);
+        Automount *s = AUTOMOUNT(u);
 
         assert(s);
 
@@ -79,23 +79,23 @@ static void automount_dump(Name *n, FILE *f, const char *prefix) {
         }
 }
 
-static NameActiveState automount_active_state(Name *n) {
-
-        static const NameActiveState table[_AUTOMOUNT_STATE_MAX] = {
-                [AUTOMOUNT_DEAD] = NAME_INACTIVE,
-                [AUTOMOUNT_START_PRE] = NAME_ACTIVATING,
-                [AUTOMOUNT_START_POST] = NAME_ACTIVATING,
-                [AUTOMOUNT_WAITING] = NAME_ACTIVE,
-                [AUTOMOUNT_RUNNING] = NAME_ACTIVE,
-                [AUTOMOUNT_STOP_PRE] = NAME_DEACTIVATING,
-                [AUTOMOUNT_STOP_POST] = NAME_DEACTIVATING,
-                [AUTOMOUNT_MAINTAINANCE] = NAME_INACTIVE,
+static UnitActiveState automount_active_state(Unit *u) {
+
+        static const UnitActiveState table[_AUTOMOUNT_STATE_MAX] = {
+                [AUTOMOUNT_DEAD] = UNIT_INACTIVE,
+                [AUTOMOUNT_START_PRE] = UNIT_ACTIVATING,
+                [AUTOMOUNT_START_POST] = UNIT_ACTIVATING,
+                [AUTOMOUNT_WAITING] = UNIT_ACTIVE,
+                [AUTOMOUNT_RUNNING] = UNIT_ACTIVE,
+                [AUTOMOUNT_STOP_PRE] = UNIT_DEACTIVATING,
+                [AUTOMOUNT_STOP_POST] = UNIT_DEACTIVATING,
+                [AUTOMOUNT_MAINTAINANCE] = UNIT_INACTIVE,
         };
 
-        return table[AUTOMOUNT(n)->state];
+        return table[AUTOMOUNT(u)->state];
 }
 
-const NameVTable automount_vtable = {
+const UnitVTable automount_vtable = {
         .suffix = ".mount",
 
         .init = automount_init,
index b6dfd5b..acd7ca2 100644 (file)
@@ -5,7 +5,7 @@
 
 typedef struct Automount Automount;
 
-#include "name.h"
+#include "unit.h"
 
 typedef enum AutomountState {
         AUTOMOUNT_DEAD,
@@ -41,6 +41,6 @@ struct Automount {
         Mount *mount;
 };
 
-extern const NameVTable automount_vtable;
+extern const UnitVTable automount_vtable;
 
 #endif
index c7f48ea..78078cc 100644 (file)
@@ -109,7 +109,7 @@ static int parse_line(const char *filename, unsigned line, char **section, const
                         }
                 }
 
-                r = config_parse(fn, sections, t, userdata);
+                r = config_parse(fn, NULL, sections, t, userdata);
                 free(path);
                 return r;
         }
@@ -162,19 +162,20 @@ static int parse_line(const char *filename, unsigned line, char **section, const
 }
 
 /* Go through the file and parse each line */
-int config_parse(const char *filename, const char* const * sections, const ConfigItem *t, void *userdata) {
+int config_parse(const char *filename, FILE *f, const char* const * sections, const ConfigItem *t, void *userdata) {
         unsigned line = 0;
         char *section = NULL;
-        FILE *f;
         int r;
 
         assert(filename);
         assert(t);
 
-        if (!(f = fopen(filename, "re"))) {
-                r = -errno;
-                log_error("Failed to open configuration file '%s': %s", filename, strerror(-r));
-                goto finish;
+        if (!f) {
+                if (!(f = fopen(filename, "re"))) {
+                        r = -errno;
+                        log_error("Failed to open configuration file '%s': %s", filename, strerror(-r));
+                        goto finish;
+                }
         }
 
         while (!feof(f)) {
index a8bed39..eb9b284 100644 (file)
@@ -21,7 +21,7 @@ typedef struct ConfigItem {
 /* The configuration file parsing routine. Expects a table of
  * config_items in *t that is terminated by an item where lvalue is
  * NULL */
-int config_parse(const char *filename, const char* const * sections, const ConfigItem *t, void *userdata);
+int config_parse(const char *filename, FILE *f, const char* const * sections, const ConfigItem *t, void *userdata);
 
 /* Generic parsers */
 int config_parse_int(const char *filename, unsigned line, const char *section, const char *lvalue, const char *rvalue, void *data, void *userdata);
index ec0a40a..b8bab4b 100644 (file)
--- a/device.c
+++ b/device.c
@@ -1,24 +1,24 @@
 /*-*- Mode: C; c-basic-offset: 8 -*-*/
 
-#include "name.h"
+#include "unit.h"
 #include "device.h"
 #include "strv.h"
 
-static void device_done(Name *n) {
-        Device *d = DEVICE(n);
+static void device_done(Unit *u) {
+        Device *d = DEVICE(u);
 
         assert(d);
         strv_free(d->sysfs);
 }
 
-static void device_dump(Name *n, FILE *f, const char *prefix) {
+static void device_dump(Unit *u, FILE *f, const char *prefix) {
 
         static const char* const state_table[_DEVICE_STATE_MAX] = {
                 [DEVICE_DEAD] = "dead",
                 [DEVICE_AVAILABLE] = "available"
         };
 
-        Device *s = DEVICE(n);
+        Device *s = DEVICE(u);
 
         assert(s);
 
@@ -27,14 +27,14 @@ static void device_dump(Name *n, FILE *f, const char *prefix) {
                 prefix, state_table[s->state]);
 }
 
-static NameActiveState device_active_state(Name *n) {
-        return DEVICE(n)->state == DEVICE_DEAD ? NAME_INACTIVE : NAME_ACTIVE;
+static UnitActiveState device_active_state(Unit *u) {
+        return DEVICE(u)->state == DEVICE_DEAD ? UNIT_INACTIVE : UNIT_ACTIVE;
 }
 
-const NameVTable device_vtable = {
+const UnitVTable device_vtable = {
         .suffix = ".device",
 
-        .init = name_load_fragment_and_dropin,
+        .init = unit_load_fragment_and_dropin,
         .done = device_done,
         .dump = device_dump,
 
index e2597f7..09523ec 100644 (file)
--- a/device.h
+++ b/device.h
@@ -5,7 +5,7 @@
 
 typedef struct Device Device;
 
-#include "name.h"
+#include "unit.h"
 
 /* We simply watch devices, we cannot plug/unplug them. That
  * simplifies the state engine greatly */
@@ -24,6 +24,6 @@ struct Device {
         char **sysfs;
 };
 
-extern const NameVTable device_vtable;
+extern const UnitVTable device_vtable;
 
 #endif
diff --git a/fixme b/fixme
index 7e5f943..f3f723e 100644 (file)
--- a/fixme
+++ b/fixme
@@ -3,9 +3,9 @@
 
 - need gc for active jobs that nothing cares for
 
-- need gc for names that are not referenced anymore
+- need gc for units that are not referenced anymore
 
-- refreshing of names (i.e. reload config files)
+- refreshing of units (i.e. reload config files)
 
 - dbusification
 
@@ -37,6 +37,6 @@
 
 - templating/instances
 
-- verify fragment data after loading: refuse cycles on yourself, service names contradicting, more than one Start executable, ...
+- verify fragment data after loading: refuse cycles on yourself, service units contradicting, more than one Start executable, ...
 
 - rate limit startups
diff --git a/job.c b/job.c
index 4daed49..ff30864 100644 (file)
--- a/job.c
+++ b/job.c
@@ -6,12 +6,12 @@
 #include "macro.h"
 #include "job.h"
 
-Job* job_new(Manager *m, JobType type, Name *name) {
+Job* job_new(Manager *m, JobType type, Unit *unit) {
         Job *j;
 
         assert(m);
         assert(type < _JOB_TYPE_MAX);
-        assert(name);
+        assert(unit);
 
         if (!(j = new0(Job, 1)))
                 return NULL;
@@ -19,7 +19,7 @@ Job* job_new(Manager *m, JobType type, Name *name) {
         j->manager = m;
         j->id = m->current_job_id++;
         j->type = type;
-        j->name = name;
+        j->unit = unit;
 
         /* We don't link it here, that's what job_dependency() is for */
 
@@ -31,8 +31,8 @@ void job_free(Job *j) {
 
         /* Detach from next 'bigger' objects */
         if (j->installed) {
-                if (j->name->meta.job == j)
-                        j->name->meta.job = NULL;
+                if (j->unit->meta.job == j)
+                        j->unit->meta.job = NULL;
 
                 hashmap_remove(j->manager->jobs, UINT32_TO_PTR(j->id));
                 j->installed = false;
@@ -142,7 +142,7 @@ void job_dump(Job *j, FILE*f, const char *prefix) {
                 "%s\tState: %s\n"
                 "%s\tForced: %s\n",
                 prefix, j->id,
-                prefix, name_id(j->name), job_type_to_string(j->type),
+                prefix, unit_id(j->unit), job_type_to_string(j->type),
                 prefix, job_state_table[j->state],
                 prefix, yes_no(j->forced));
 }
@@ -257,12 +257,12 @@ bool job_type_is_conflicting(JobType a, JobType b) {
 
 bool job_is_runnable(Job *j) {
         Iterator i;
-        Name *other;
+        Unit *other;
 
         assert(j);
         assert(j->installed);
 
-        /* Checks whether there is any job running for the names this
+        /* Checks whether there is any job running for the units this
          * job needs to be running after (in the case of a 'positive'
          * job type) or before (in the case of a 'negative' job type
          * . */
@@ -277,7 +277,7 @@ bool job_is_runnable(Job *j) {
                  * dependencies, regardless whether they are
                  * starting or stopping something. */
 
-                SET_FOREACH(other, j->name->meta.dependencies[NAME_AFTER], i)
+                SET_FOREACH(other, j->unit->meta.dependencies[UNIT_AFTER], i)
                         if (other->meta.job)
                                 return false;
         }
@@ -285,7 +285,7 @@ bool job_is_runnable(Job *j) {
         /* Also, if something else is being stopped and we should
          * change state after it, then lets wait. */
 
-        SET_FOREACH(other, j->name->meta.dependencies[NAME_BEFORE], i)
+        SET_FOREACH(other, j->unit->meta.dependencies[UNIT_BEFORE], i)
                 if (other->meta.job &&
                     (other->meta.job->type == JOB_STOP ||
                      other->meta.job->type == JOB_RESTART ||
@@ -328,16 +328,16 @@ int job_run_and_invalidate(Job *j) {
         switch (j->type) {
 
                 case JOB_START:
-                        r = name_start(j->name);
+                        r = unit_start(j->unit);
                         if (r == -EBADR)
                                 r = 0;
                         break;
 
                 case JOB_VERIFY_ACTIVE: {
-                        NameActiveState t = name_active_state(j->name);
-                        if (NAME_IS_ACTIVE_OR_RELOADING(t))
+                        UnitActiveState t = unit_active_state(j->unit);
+                        if (UNIT_IS_ACTIVE_OR_RELOADING(t))
                                 r = -EALREADY;
-                        else if (t == NAME_ACTIVATING)
+                        else if (t == UNIT_ACTIVATING)
                                 r = -EAGAIN;
                         else
                                 r = -ENOEXEC;
@@ -345,39 +345,39 @@ int job_run_and_invalidate(Job *j) {
                 }
 
                 case JOB_STOP:
-                        r = name_stop(j->name);
+                        r = unit_stop(j->unit);
                         break;
 
                 case JOB_RELOAD:
-                        r = name_reload(j->name);
+                        r = unit_reload(j->unit);
                         break;
 
                 case JOB_RELOAD_OR_START:
-                        if (name_active_state(j->name) == NAME_ACTIVE)
-                                r = name_reload(j->name);
+                        if (unit_active_state(j->unit) == UNIT_ACTIVE)
+                                r = unit_reload(j->unit);
                         else
-                                r = name_start(j->name);
+                                r = unit_start(j->unit);
                         break;
 
                 case JOB_RESTART: {
-                        NameActiveState t = name_active_state(j->name);
-                        if (t == NAME_INACTIVE || t == NAME_ACTIVATING) {
+                        UnitActiveState t = unit_active_state(j->unit);
+                        if (t == UNIT_INACTIVE || t == UNIT_ACTIVATING) {
                                 j->type = JOB_START;
-                                r = name_start(j->name);
+                                r = unit_start(j->unit);
                         } else
-                                r = name_stop(j->name);
+                                r = unit_stop(j->unit);
                         break;
                 }
 
                 case JOB_TRY_RESTART: {
-                        NameActiveState t = name_active_state(j->name);
-                        if (t == NAME_INACTIVE || t == NAME_DEACTIVATING)
+                        UnitActiveState t = unit_active_state(j->unit);
+                        if (t == UNIT_INACTIVE || t == UNIT_DEACTIVATING)
                                 r = -ENOEXEC;
-                        else if (t == NAME_ACTIVATING) {
+                        else if (t == UNIT_ACTIVATING) {
                                 j->type = JOB_START;
-                                r = name_start(j->name);
+                                r = unit_start(j->unit);
                         } else
-                                r = name_stop(j->name);
+                                r = unit_stop(j->unit);
                         break;
                 }
 
@@ -397,9 +397,9 @@ int job_run_and_invalidate(Job *j) {
 }
 
 int job_finish_and_invalidate(Job *j, bool success) {
-        Name *n;
-        Name *other;
-        NameType t;
+        Unit *u;
+        Unit *other;
+        UnitType t;
         Iterator i;
 
         assert(j);
@@ -413,7 +413,7 @@ int job_finish_and_invalidate(Job *j, bool success) {
                 return 0;
         }
 
-        n = j->name;
+        u = j->unit;
         t = j->type;
         job_free(j);
 
@@ -424,14 +424,14 @@ int job_finish_and_invalidate(Job *j, bool success) {
                     t == JOB_VERIFY_ACTIVE ||
                     t == JOB_RELOAD_OR_START) {
 
-                        SET_FOREACH(other, n->meta.dependencies[NAME_REQUIRED_BY], i)
+                        SET_FOREACH(other, u->meta.dependencies[UNIT_REQUIRED_BY], i)
                                 if (other->meta.job &&
                                     (other->meta.type == JOB_START ||
                                      other->meta.type == JOB_VERIFY_ACTIVE ||
                                      other->meta.type == JOB_RELOAD_OR_START))
                                         job_finish_and_invalidate(other->meta.job, false);
 
-                        SET_FOREACH(other, n->meta.dependencies[NAME_SOFT_REQUIRED_BY], i)
+                        SET_FOREACH(other, u->meta.dependencies[UNIT_SOFT_REQUIRED_BY], i)
                                 if (other->meta.job &&
                                     !other->meta.job->forced &&
                                     (other->meta.type == JOB_START ||
@@ -441,7 +441,7 @@ int job_finish_and_invalidate(Job *j, bool success) {
 
                 } else if (t == JOB_STOP) {
 
-                        SET_FOREACH(other, n->meta.dependencies[NAME_CONFLICTS], i)
+                        SET_FOREACH(other, u->meta.dependencies[UNIT_CONFLICTS], i)
                                 if (other->meta.job &&
                                     (t == JOB_START ||
                                      t == JOB_VERIFY_ACTIVE ||
@@ -451,10 +451,10 @@ int job_finish_and_invalidate(Job *j, bool success) {
         }
 
         /* Try to start the next jobs that can be started */
-        SET_FOREACH(other, n->meta.dependencies[NAME_AFTER], i)
+        SET_FOREACH(other, u->meta.dependencies[UNIT_AFTER], i)
                 if (other->meta.job)
                         job_schedule_run(other->meta.job);
-        SET_FOREACH(other, n->meta.dependencies[NAME_BEFORE], i)
+        SET_FOREACH(other, u->meta.dependencies[UNIT_BEFORE], i)
                 if (other->meta.job)
                         job_schedule_run(other->meta.job);
 
diff --git a/job.h b/job.h
index 5527d6e..dd5e31a 100644 (file)
--- a/job.h
+++ b/job.h
@@ -13,12 +13,12 @@ typedef enum JobState JobState;
 typedef enum JobMode JobMode;
 
 #include "manager.h"
-#include "name.h"
+#include "unit.h"
 #include "hashmap.h"
 #include "list.h"
 
 enum JobType {
-        JOB_START,                  /* if a name does not support being started, we'll just wait until it becomes active */
+        JOB_START,                  /* if a unit does not support being started, we'll just wait until it becomes active */
         JOB_VERIFY_ACTIVE,
 
         JOB_STOP,
@@ -64,7 +64,7 @@ struct Job {
         Manager *manager;
         uint32_t id;
 
-        Name *name;
+        Unit *unit;
 
         JobType type;
         JobState state;
@@ -86,7 +86,7 @@ struct Job {
 
 };
 
-Job* job_new(Manager *m, JobType type, Name *name);
+Job* job_new(Manager *m, JobType type, Unit *unit);
 void job_free(Job *job);
 void job_dump(Job *j, FILE*f, const char *prefix);
 
index 7105cb8..3023cda 100644 (file)
@@ -2,8 +2,8 @@
 
 #include "load-dropin.h"
 
-int name_load_dropin(Name *n) {
-        assert(n);
+int unit_load_dropin(Unit *u) {
+        assert(u);
 
         /* Load dependencies from supplementary drop-in directories */
 
index c4971a5..e1179ac 100644 (file)
@@ -3,10 +3,10 @@
 #ifndef fooloaddropinhfoo
 #define fooloaddropinhfoo
 
-#include "name.h"
+#include "unit.h"
 
 /* Read service data supplementary drop-in directories */
 
-int name_load_dropin(Name *n);
+int unit_load_dropin(Unit *u);
 
 #endif
index cf1e149..7877a8c 100644 (file)
@@ -1,11 +1,13 @@
 /*-*- Mode: C; c-basic-offset: 8 -*-*/
 
+#include <linux/oom.h>
 #include <assert.h>
 #include <errno.h>
 #include <string.h>
-#include <linux/oom.h>
+#include <unistd.h>
+#include <fcntl.h>
 
-#include "name.h"
+#include "unit.h"
 #include "strv.h"
 #include "conf-parser.h"
 #include "load-fragment.h"
@@ -20,8 +22,8 @@ static int config_parse_deps(
                 void *data,
                 void *userdata) {
 
-        NameDependency d = PTR_TO_UINT(data);
-        Name *name = userdata;
+        UnitDependency d = PTR_TO_UINT(data);
+        Unit *u = userdata;
         char *w;
         size_t l;
         char *state;
@@ -33,18 +35,18 @@ static int config_parse_deps(
         FOREACH_WORD(w, &l, rvalue, state) {
                 char *t;
                 int r;
-                Name *other;
+                Unit *other;
 
                 if (!(t = strndup(w, l)))
                         return -ENOMEM;
 
-                r = manager_load_name(name->meta.manager, t, &other);
+                r = manager_load_unit(u->meta.manager, t, &other);
                 free(t);
 
                 if (r < 0)
                         return r;
 
-                if ((r = name_add_dependency(name, d, other)) < 0)
+                if ((r = unit_add_dependency(u, d, other)) < 0)
                         return r;
         }
 
@@ -60,8 +62,7 @@ static int config_parse_names(
                 void *data,
                 void *userdata) {
 
-        Set **set = data;
-        Name *name = userdata;
+        Unit *u = userdata;
         char *w;
         size_t l;
         char *state;
@@ -74,42 +75,33 @@ static int config_parse_names(
         FOREACH_WORD(w, &l, rvalue, state) {
                 char *t;
                 int r;
-                Name *other;
+                Unit *other;
 
                 if (!(t = strndup(w, l)))
                         return -ENOMEM;
 
-                other = manager_get_name(name->meta.manager, t);
+                other = manager_get_unit(u->meta.manager, t);
 
                 if (other) {
 
-                        if (other != name) {
+                        if (other != u) {
 
-                                if (other->meta.load_state != NAME_STUB) {
+                                if (other->meta.load_state != UNIT_STUB) {
                                         free(t);
                                         return -EEXIST;
                                 }
 
-                                if ((r = name_merge(name, other)) < 0) {
+                                if ((r = unit_merge(u, other)) < 0) {
                                         free(t);
                                         return r;
                                 }
                         }
 
                 } else {
-
-                        if (!*set)
-                                if (!(*set = set_new(trivial_hash_func, trivial_compare_func))) {
-                                        free(t);
-                                        return -ENOMEM;
-                                }
-
-                        if ((r = set_put(*set, t)) < 0) {
+                        if ((r = unit_add_name(u, t)) < 0) {
                                 free(t);
                                 return r;
                         }
-
-                        t = NULL;
                 }
 
                 free(t);
@@ -458,17 +450,127 @@ static int config_parse_service_restart(
         return 0;
 }
 
-int name_load_fragment(Name *n) {
-
-        static const char* const section_table[_NAME_TYPE_MAX] = {
-                [NAME_SERVICE]   = "Service",
-                [NAME_TIMER]     = "Timer",
-                [NAME_SOCKET]    = "Socket",
-                [NAME_TARGET]    = "Target",
-                [NAME_DEVICE]    = "Device",
-                [NAME_MOUNT]     = "Mount",
-                [NAME_AUTOMOUNT] = "Automount",
-                [NAME_SNAPSHOT]  = "Snapshot"
+#define FOLLOW_MAX 8
+
+static char *build_path(const char *path, const char *filename) {
+        char *e, *r;
+        size_t k;
+
+        assert(path);
+        assert(filename);
+
+        /* This removes the last component of path and appends
+         * filename, unless the latter is absolute anyway or the
+         * former isn't */
+
+        if (filename[0] == '/')
+                return strdup(filename);
+
+        if (!(e = strrchr(path, '/')))
+                return strdup(filename);
+
+        k = strlen(filename);
+        if (!(r = new(char, e-path+1+k+1)))
+                return NULL;
+
+        memcpy(r, path, e-path+1);
+        memcpy(r+(e-path)+1, filename, k+1);
+
+        return r;
+}
+
+static int open_follow(const char **filename, FILE **_f, Set *names) {
+        unsigned c;
+        int fd, r;
+        FILE *f;
+        char *n = NULL;
+        const char *fn;
+
+        assert(filename);
+        assert(*filename);
+        assert(_f);
+        assert(names);
+
+        fn = *filename;
+
+        for (c = 0; c < FOLLOW_MAX; c++) {
+                char *target, *k, *name;
+
+                /* Add the file name we are currently looking at to
+                 * the names of this unit */
+                name = file_name_from_path(fn);
+                if (!set_get(names, name)) {
+
+                        if (!(name = strdup(name))) {
+                                r = -ENOMEM;
+                                goto finish;
+                        }
+
+                        if ((r = set_put(names, name)) < 0) {
+                                free(name);
+                                goto finish;
+                        }
+
+                        free(name);
+                }
+
+                /* Try to open the file name, but don' if its a symlink */
+                fd = open(fn, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
+                if (fd >= 0 || errno != ELOOP)
+                        break;
+
+                /* Hmm, so this is a symlink. Let's read the name, and follow it manually */
+                if ((r = readlink_malloc(fn, &target)) < 0)
+                        goto finish;
+
+                k = build_path(fn, target);
+                free(target);
+
+                if (!k) {
+                        r = -ENOMEM;
+                        goto finish;
+                }
+
+                free(n);
+                fn = n = k;
+        }
+
+        if (c >= FOLLOW_MAX) {
+                r = -ELOOP;
+                goto finish;
+        }
+
+        if (fd < 0) {
+                r = -errno;
+                goto finish;
+        }
+
+        if (!(f = fdopen(fd, "r"))) {
+                r = -errno;
+                assert(close_nointr(fd) == 0);
+                goto finish;
+        }
+
+        *_f = f;
+        *filename = fn;
+        r = 0;
+
+finish:
+        free(n);
+        return r;
+}
+
+int unit_load_fragment(Unit *u) {
+
+        static const char* const section_table[_UNIT_TYPE_MAX] = {
+                [UNIT_SERVICE]   = "Service",
+                [UNIT_TIMER]     = "Timer",
+                [UNIT_SOCKET]    = "Socket",
+                [UNIT_TARGET]    = "Target",
+                [UNIT_DEVICE]    = "Device",
+                [UNIT_MOUNT]     = "Mount",
+                [UNIT_AUTOMOUNT] = "Automount",
+                [UNIT_SNAPSHOT]  = "Snapshot"
         };
 
 #define EXEC_CONTEXT_CONFIG_ITEMS(context, section) \
@@ -482,73 +584,110 @@ int name_load_fragment(Name *n) {
                 { "Environment",            config_parse_strv,            &(context).environment,                            section   }
 
         const ConfigItem items[] = {
-                { "Names",                  config_parse_names,           &n->meta.names,                                    "Meta"    },
-                { "Description",            config_parse_string,          &n->meta.description,                              "Meta"    },
-                { "Requires",               config_parse_deps,            UINT_TO_PTR(NAME_REQUIRES),                        "Meta"    },
-                { "SoftRequires",           config_parse_deps,            UINT_TO_PTR(NAME_SOFT_REQUIRES),                   "Meta"    },
-                { "Wants",                  config_parse_deps,            UINT_TO_PTR(NAME_WANTS),                           "Meta"    },
-                { "Requisite",              config_parse_deps,            UINT_TO_PTR(NAME_REQUISITE),                       "Meta"    },
-                { "SoftRequisite",          config_parse_deps,            UINT_TO_PTR(NAME_SOFT_REQUISITE),                  "Meta"    },
-                { "Conflicts",              config_parse_deps,            UINT_TO_PTR(NAME_CONFLICTS),                       "Meta"    },
-                { "Before",                 config_parse_deps,            UINT_TO_PTR(NAME_BEFORE),                          "Meta"    },
-                { "After",                  config_parse_deps,            UINT_TO_PTR(NAME_AFTER),                           "Meta"    },
-
-                { "PIDFile",                config_parse_path,            &n->service.pid_file,                              "Service" },
-                { "ExecStartPre",           config_parse_exec,            &n->service.exec_command[SERVICE_EXEC_START_PRE],  "Service" },
-                { "ExecStart",              config_parse_exec,            &n->service.exec_command[SERVICE_EXEC_START],      "Service" },
-                { "ExecStartPost",          config_parse_exec,            &n->service.exec_command[SERVICE_EXEC_START_POST], "Service" },
-                { "ExecReload",             config_parse_exec,            &n->service.exec_command[SERVICE_EXEC_RELOAD],     "Service" },
-                { "ExecStop",               config_parse_exec,            &n->service.exec_command[SERVICE_EXEC_STOP],       "Service" },
-                { "ExecStopPost",           config_parse_exec,            &n->service.exec_command[SERVICE_EXEC_STOP_POST],  "Service" },
-                { "RestartSec",             config_parse_usec,            &n->service.restart_usec,                          "Service" },
-                { "TimeoutSec",             config_parse_usec,            &n->service.timeout_usec,                          "Service" },
-                { "Type",                   config_parse_service_type,    &n->service,                                       "Service" },
-                { "Restart",                config_parse_service_restart, &n->service,                                       "Service" },
-                EXEC_CONTEXT_CONFIG_ITEMS(n->service.exec_context, "Service"),
-
-                { "ListenStream",           config_parse_listen,          &n->socket,                                        "Socket"  },
-                { "ListenDatagram",         config_parse_listen,          &n->socket,                                        "Socket"  },
-                { "ListenSequentialPacket", config_parse_listen,          &n->socket,                                        "Socket"  },
-                { "ListenFIFO",             config_parse_listen,          &n->socket,                                        "Socket"  },
-                { "BindIPv6Only",           config_parse_socket_bind,     &n->socket,                                        "Socket"  },
-                { "Backlog",                config_parse_unsigned,        &n->socket.backlog,                                "Socket"  },
-                { "ExecStartPre",           config_parse_exec,            &n->service.exec_command[SOCKET_EXEC_START_PRE],   "Socket"  },
-                { "ExecStartPost",          config_parse_exec,            &n->service.exec_command[SOCKET_EXEC_START_POST],  "Socket"  },
-                { "ExecStopPre",            config_parse_exec,            &n->service.exec_command[SOCKET_EXEC_STOP_PRE],    "Socket"  },
-                { "ExecStopPost",           config_parse_exec,            &n->service.exec_command[SOCKET_EXEC_STOP_POST],   "Socket"  },
-                EXEC_CONTEXT_CONFIG_ITEMS(n->socket.exec_context, "Socket"),
-
-                EXEC_CONTEXT_CONFIG_ITEMS(n->automount.exec_context, "Automount"),
+                { "Names",                  config_parse_names,           u,                                                 "Meta"    },
+                { "Description",            config_parse_string,          &u->meta.description,                              "Meta"    },
+                { "Requires",               config_parse_deps,            UINT_TO_PTR(UNIT_REQUIRES),                        "Meta"    },
+                { "SoftRequires",           config_parse_deps,            UINT_TO_PTR(UNIT_SOFT_REQUIRES),                   "Meta"    },
+                { "Wants",                  config_parse_deps,            UINT_TO_PTR(UNIT_WANTS),                           "Meta"    },
+                { "Requisite",              config_parse_deps,            UINT_TO_PTR(UNIT_REQUISITE),                       "Meta"    },
+                { "SoftRequisite",          config_parse_deps,            UINT_TO_PTR(UNIT_SOFT_REQUISITE),                  "Meta"    },
+                { "Conflicts",              config_parse_deps,            UINT_TO_PTR(UNIT_CONFLICTS),                       "Meta"    },
+                { "Before",                 config_parse_deps,            UINT_TO_PTR(UNIT_BEFORE),                          "Meta"    },
+                { "After",                  config_parse_deps,            UINT_TO_PTR(UNIT_AFTER),                           "Meta"    },
+
+                { "PIDFile",                config_parse_path,            &u->service.pid_file,                              "Service" },
+                { "ExecStartPre",           config_parse_exec,            &u->service.exec_command[SERVICE_EXEC_START_PRE],  "Service" },
+                { "ExecStart",              config_parse_exec,            &u->service.exec_command[SERVICE_EXEC_START],      "Service" },
+                { "ExecStartPost",          config_parse_exec,            &u->service.exec_command[SERVICE_EXEC_START_POST], "Service" },
+                { "ExecReload",             config_parse_exec,            &u->service.exec_command[SERVICE_EXEC_RELOAD],     "Service" },
+                { "ExecStop",               config_parse_exec,            &u->service.exec_command[SERVICE_EXEC_STOP],       "Service" },
+                { "ExecStopPost",           config_parse_exec,            &u->service.exec_command[SERVICE_EXEC_STOP_POST],  "Service" },
+                { "RestartSec",             config_parse_usec,            &u->service.restart_usec,                          "Service" },
+                { "TimeoutSec",             config_parse_usec,            &u->service.timeout_usec,                          "Service" },
+                { "Type",                   config_parse_service_type,    &u->service,                                       "Service" },
+                { "Restart",                config_parse_service_restart, &u->service,                                       "Service" },
+                EXEC_CONTEXT_CONFIG_ITEMS(u->service.exec_context, "Service"),
+
+                { "ListenStream",           config_parse_listen,          &u->socket,                                        "Socket"  },
+                { "ListenDatagram",         config_parse_listen,          &u->socket,                                        "Socket"  },
+                { "ListenSequentialPacket", config_parse_listen,          &u->socket,                                        "Socket"  },
+                { "ListenFIFO",             config_parse_listen,          &u->socket,                                        "Socket"  },
+                { "BindIPv6Only",           config_parse_socket_bind,     &u->socket,                                        "Socket"  },
+                { "Backlog",                config_parse_unsigned,        &u->socket.backlog,                                "Socket"  },
+                { "ExecStartPre",           config_parse_exec,            &u->service.exec_command[SOCKET_EXEC_START_PRE],   "Socket"  },
+                { "ExecStartPost",          config_parse_exec,            &u->service.exec_command[SOCKET_EXEC_START_POST],  "Socket"  },
+                { "ExecStopPre",            config_parse_exec,            &u->service.exec_command[SOCKET_EXEC_STOP_PRE],    "Socket"  },
+                { "ExecStopPost",           config_parse_exec,            &u->service.exec_command[SOCKET_EXEC_STOP_POST],   "Socket"  },
+                EXEC_CONTEXT_CONFIG_ITEMS(u->socket.exec_context, "Socket"),
+
+                EXEC_CONTEXT_CONFIG_ITEMS(u->automount.exec_context, "Automount"),
 
                 { NULL, NULL, NULL, NULL }
         };
 
 #undef EXEC_CONTEXT_CONFIG_ITEMS
 
-        char *t;
+        char *t, *k;
         int r;
         const char *sections[3];
         Iterator i;
+        Set *symlink_names;
 
-        assert(n);
-        assert(n->meta.load_state == NAME_STUB);
+        assert(u);
+        assert(u->meta.load_state == UNIT_STUB);
 
         sections[0] = "Meta";
-        sections[1] = section_table[n->meta.type];
+        sections[1] = section_table[u->meta.type];
         sections[2] = NULL;
 
-        SET_FOREACH(t, n->meta.names, i) {
+        if (!(symlink_names = set_new(string_hash_func, string_compare_func)))
+                return -ENOMEM;
 
-                /* Try to find a name we can load this with */
-                if ((r = config_parse(t, sections, items, n)) == -ENOENT)
-                        continue;
+        /* Try to find a name we can load this with */
+        SET_FOREACH(t, u->meta.names, i) {
+                FILE *f;
+                char *fn;
 
-                /* Yay, we succeeded! Now let's call this our identifier */
-                if (r == 0)
-                        n->meta.id = t;
+                /* Clear the symlink name set first */
+                while ((k = set_steal_first(symlink_names)))
+                        free(k);
 
-                return r;
+                /* Instead of opening the path right away, we manually
+                 * follow all symlinks and add their name to our unit
+                 * name set while doing so */
+                fn = t;
+                if ((r = open_follow((const char**) &fn, &f, symlink_names)) < 0) {
+                        if (r == -ENOENT)
+                                continue;
+
+                        goto finish;
+                }
+
+                /* Now, parse the file contents */
+                r = config_parse(fn, f, sections, items, u);
+                if (fn != t)
+                        free(fn);
+                if (r < 0)
+                        goto finish;
+
+                /* Let's try to add in all symlink names we found */
+                while ((k = set_steal_first(symlink_names)))
+                        if ((r = unit_add_name(u, k)) < 0)
+                                goto finish;
+
+                /* Yay, we succeeded! Now let's call this our identifier */
+                u->meta.id = t;
+                goto finish;
         }
 
-        return -ENOENT;
+
+        r = -ENOENT;
+
+finish:
+        while ((k = set_steal_first(symlink_names)))
+                free(k);
+
+        set_free(symlink_names);
+
+        return r;
 }
index 523426f..475bf64 100644 (file)
@@ -3,10 +3,10 @@
 #ifndef fooloadfragmenthfoo
 #define fooloadfragmenthfoo
 
-#include "name.h"
+#include "unit.h"
 
 /* Read service data from .desktop file style configuration fragments */
 
-int name_load_fragment(Name *n);
+int unit_load_fragment(Unit *u);
 
 #endif
index cfefcb6..d611426 100644 (file)
@@ -2,8 +2,8 @@
 
 #include "load-fstab.h"
 
-int name_load_fstab(Name *n) {
-        assert(n);
+int unit_load_fstab(Unit *u) {
+        assert(u);
 
         /* Load dependencies from /etc/fstab */
 
index e705650..b0cef7d 100644 (file)
@@ -3,10 +3,10 @@
 #ifndef fooloadfstabhfoo
 #define fooloadfstabhfoo
 
-#include "name.h"
+#include "unit.h"
 
 /* Read service data from /etc/fstab */
 
-int name_load_fstab(Name *n);
+int unit_load_fstab(Unit *u);
 
 #endif
diff --git a/main.c b/main.c
index 99f7d68..e139c4b 100644 (file)
--- a/main.c
+++ b/main.c
@@ -10,7 +10,7 @@
 
 int main(int argc, char *argv[]) {
         Manager *m = NULL;
-        Name *target = NULL;
+        Unit *target = NULL;
         Job *job = NULL;
         int r, retval = 1;
 
@@ -21,7 +21,7 @@ int main(int argc, char *argv[]) {
                 goto finish;
         }
 
-        if ((r = manager_load_name(m, "default.target", &target)) < 0) {
+        if ((r = manager_load_unit(m, "default.target", &target)) < 0) {
                 log_error("Failed to load default target: %s", strerror(-r));
                 goto finish;
         }
@@ -31,8 +31,8 @@ int main(int argc, char *argv[]) {
                 goto finish;
         }
 
-        printf("→ By names:\n");
-        manager_dump_names(m, stdout, "\t");
+        printf("→ By units:\n");
+        manager_dump_units(m, stdout, "\t");
 
         printf("→ By jobs:\n");
         manager_dump_jobs(m, stdout, "\t");
index 7950a8a..819164c 100644 (file)
--- a/manager.c
+++ b/manager.c
@@ -26,7 +26,7 @@ Manager* manager_new(void) {
 
         m->signal_fd = m->epoll_fd = -1;
 
-        if (!(m->names = hashmap_new(string_hash_func, string_compare_func)))
+        if (!(m->units = hashmap_new(string_hash_func, string_compare_func)))
                 goto fail;
 
         if (!(m->jobs = hashmap_new(trivial_hash_func, trivial_compare_func)))
@@ -63,18 +63,18 @@ fail:
 }
 
 void manager_free(Manager *m) {
-        Name *n;
+        Unit *u;
         Job *j;
 
         assert(m);
 
-        while ((n = hashmap_first(m->names)))
-                name_free(n);
-
-        while ((j = hashmap_steal_first(m->transaction_jobs)))
+        while ((j = hashmap_first(m->transaction_jobs)))
                 job_free(j);
 
-        hashmap_free(m->names);
+        while ((u = hashmap_first(m->units)))
+                unit_free(u);
+
+        hashmap_free(m->units);
         hashmap_free(m->jobs);
         hashmap_free(m->transaction_jobs);
         hashmap_free(m->watch_pids);
@@ -99,13 +99,13 @@ static void transaction_delete_job(Manager *m, Job *j) {
                 job_free(j);
 }
 
-static void transaction_delete_name(Manager *m, Name *n) {
+static void transaction_delete_unit(Manager *m, Unit *u) {
         Job *j;
 
-        /* Deletes all jobs associated with a certain name from the
+        /* Deletes all jobs associated with a certain unit from the
          * transaction */
 
-        while ((j = hashmap_get(m->transaction_jobs, n)))
+        while ((j = hashmap_get(m->transaction_jobs, u)))
                 transaction_delete_job(m, j);
 }
 
@@ -129,7 +129,7 @@ static void transaction_find_jobs_that_matter_to_anchor(Manager *m, Job *j, unsi
 
         assert(m);
 
-        /* A recursive sweep through the graph that marks all names
+        /* A recursive sweep through the graph that marks all units
          * that matter to the anchor job, i.e. are directly or
          * indirectly a dependency of the anchor job via paths that
          * are fully marked as mattering. */
@@ -145,7 +145,7 @@ static void transaction_find_jobs_that_matter_to_anchor(Manager *m, Job *j, unsi
                 if (!l->matters)
                         continue;
 
-                /* This name has already been marked */
+                /* This unit has already been marked */
                 if (l->object->generation == generation)
                         continue;
 
@@ -161,7 +161,7 @@ static void transaction_merge_and_delete_job(Manager *m, Job *j, Job *other, Job
 
         assert(j);
         assert(other);
-        assert(j->name == other->name);
+        assert(j->unit == other->unit);
         assert(!j->installed);
 
         /* Merges 'other' into 'j' and then deletes j. */
@@ -240,7 +240,7 @@ static int delete_one_unmergeable_job(Manager *m, Job *j) {
                                 return -ENOEXEC;
 
                         /* Ok, we can drop one, so let's do so. */
-                        log_debug("Try to fix job merging by deleting job %s/%s", name_id(d->name), job_type_to_string(d->type));
+                        log_debug("Try to fix job merging by deleting job %s/%s", unit_id(d->unit), job_type_to_string(d->type));
                         transaction_delete_job(m, d);
                         return 0;
                 }
@@ -291,8 +291,8 @@ static int transaction_merge_jobs(Manager *m) {
                         assert_se(job_type_merge(&t, k->type) == 0);
 
                 /* If an active job is mergeable, merge it too */
-                if (j->name->meta.job)
-                        job_type_merge(&t, j->name->meta.job->type); /* Might fail. Which is OK */
+                if (j->unit->meta.job)
+                        job_type_merge(&t, j->unit->meta.job->type); /* Might fail. Which is OK */
 
                 while ((k = j->transaction_next)) {
                         if (j->installed) {
@@ -309,11 +309,11 @@ static int transaction_merge_jobs(Manager *m) {
         return 0;
 }
 
-static bool name_matters_to_anchor(Name *n, Job *j) {
-        assert(n);
+static bool unit_matters_to_anchor(Unit *u, Job *j) {
+        assert(u);
         assert(!j->transaction_prev);
 
-        /* Checks whether at least one of the jobs for this name
+        /* Checks whether at least one of the jobs for this unit
          * matters to the anchor. */
 
         LIST_FOREACH(transaction, j, j)
@@ -325,7 +325,7 @@ static bool name_matters_to_anchor(Name *n, Job *j) {
 
 static int transaction_verify_order_one(Manager *m, Job *j, Job *from, unsigned generation) {
         Iterator i;
-        Name *n;
+        Unit *u;
         int r;
 
         assert(m);
@@ -349,11 +349,11 @@ static int transaction_verify_order_one(Manager *m, Job *j, Job *from, unsigned
                 for (k = from; k; k = (k->generation == generation ? k->marker : NULL)) {
 
                         if (!k->installed &&
-                            !name_matters_to_anchor(k->name, k)) {
+                            !unit_matters_to_anchor(k->unit, k)) {
                                 /* Ok, we can drop this one, so let's
                                  * do so. */
-                                log_debug("Breaking order cycle by deleting job %s/%s", name_id(k->name), job_type_to_string(k->type));
-                                transaction_delete_name(m, k->name);
+                                log_debug("Breaking order cycle by deleting job %s/%s", unit_id(k->unit), job_type_to_string(k->type));
+                                transaction_delete_unit(m, k->unit);
                                 return -EAGAIN;
                         }
 
@@ -372,17 +372,17 @@ static int transaction_verify_order_one(Manager *m, Job *j, Job *from, unsigned
         j->generation = generation;
 
         /* We assume that the the dependencies are bidirectional, and
-         * hence can ignore NAME_AFTER */
-        SET_FOREACH(n, j->name->meta.dependencies[NAME_BEFORE], i) {
+         * hence can ignore UNIT_AFTER */
+        SET_FOREACH(u, j->unit->meta.dependencies[UNIT_BEFORE], i) {
                 Job *o;
 
-                /* Is there a job for this name? */
-                if (!(o = hashmap_get(m->transaction_jobs, n)))
+                /* Is there a job for this unit? */
+                if (!(o = hashmap_get(m->transaction_jobs, u)))
 
                         /* Ok, there is no job for this in the
                          * transaction, but maybe there is already one
                          * running? */
-                        if (!(o = n->meta.job))
+                        if (!(o = u->meta.job))
                                 continue;
 
                 if ((r = transaction_verify_order_one(m, o, j, generation)) < 0)
@@ -427,7 +427,7 @@ static void transaction_collect_garbage(Manager *m) {
                         if (j->object_list)
                                 continue;
 
-                        log_debug("Garbage collecting job %s/%s", name_id(j->name), job_type_to_string(j->type));
+                        log_debug("Garbage collecting job %s/%s", unit_id(j->unit), job_type_to_string(j->type));
                         transaction_delete_job(m, j);
                         again = true;
                         break;
@@ -451,9 +451,9 @@ static int transaction_is_destructive(Manager *m, JobMode mode) {
                 assert(!j->transaction_prev);
                 assert(!j->transaction_next);
 
-                if (j->name->meta.job &&
-                    j->name->meta.job != j &&
-                    !job_type_is_superset(j->type, j->name->meta.job->type))
+                if (j->unit->meta.job &&
+                    j->unit->meta.job != j &&
+                    !job_type_is_superset(j->type, j->unit->meta.job->type))
                         return -EEXIST;
         }
 
@@ -483,12 +483,12 @@ static void transaction_minimize_impact(Manager *m) {
                                 /* Would this stop a running service?
                                  * Would this change an existing job?
                                  * If so, let's drop this entry */
-                                if ((j->type != JOB_STOP || NAME_IS_INACTIVE_OR_DEACTIVATING(name_active_state(j->name))) &&
-                                    (!j->name->meta.job  || job_type_is_conflicting(j->type, j->name->meta.job->state)))
+                                if ((j->type != JOB_STOP || UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(j->unit))) &&
+                                    (!j->unit->meta.job  || job_type_is_conflicting(j->type, j->unit->meta.job->state)))
                                         continue;
 
                                 /* Ok, let's get rid of this */
-                                log_debug("Deleting %s/%s to minimize impact", name_id(j->name), job_type_to_string(j->type));
+                                log_debug("Deleting %s/%s to minimize impact", unit_id(j->unit), job_type_to_string(j->type));
                                 transaction_delete_job(m, j);
                                 again = true;
                                 break;
@@ -524,10 +524,10 @@ static int transaction_apply(Manager *m, JobMode mode) {
                 if (j->installed)
                         continue;
 
-                if (j->name->meta.job)
-                        job_free(j->name->meta.job);
+                if (j->unit->meta.job)
+                        job_free(j->unit->meta.job);
 
-                j->name->meta.job = j;
+                j->unit->meta.job = j;
                 j->installed = true;
 
                 /* We're fully installed. Now let's free data we don't
@@ -629,21 +629,21 @@ rollback:
         return r;
 }
 
-static Job* transaction_add_one_job(Manager *m, JobType type, Name *name, bool force, bool *is_new) {
+static Job* transaction_add_one_job(Manager *m, JobType type, Unit *unit, bool force, bool *is_new) {
         Job *j, *f;
         int r;
 
         assert(m);
-        assert(name);
+        assert(unit);
 
         /* Looks for an axisting prospective job and returns that. If
          * it doesn't exist it is created and added to the prospective
          * jobs list. */
 
-        f = hashmap_get(m->transaction_jobs, name);
+        f = hashmap_get(m->transaction_jobs, unit);
 
         LIST_FOREACH(transaction, j, f) {
-                assert(j->name == name);
+                assert(j->unit == unit);
 
                 if (j->type == type) {
                         if (is_new)
@@ -652,9 +652,9 @@ static Job* transaction_add_one_job(Manager *m, JobType type, Name *name, bool f
                 }
         }
 
-        if (name->meta.job && name->meta.job->type == type)
-                j = name->meta.job;
-        else if (!(j = job_new(m, type, name)))
+        if (unit->meta.job && unit->meta.job->type == type)
+                j = unit->meta.job;
+        else if (!(j = job_new(m, type, unit)))
                 return NULL;
 
         j->generation = 0;
@@ -664,7 +664,7 @@ static Job* transaction_add_one_job(Manager *m, JobType type, Name *name, bool f
 
         LIST_PREPEND(Job, transaction, f, j);
 
-        if ((r = hashmap_replace(m->transaction_jobs, name, f)) < 0) {
+        if ((r = hashmap_replace(m->transaction_jobs, unit, f)) < 0) {
                 job_free(j);
                 return NULL;
         }
@@ -682,9 +682,9 @@ void manager_transaction_unlink_job(Manager *m, Job *j) {
         if (j->transaction_prev)
                 j->transaction_prev->transaction_next = j->transaction_next;
         else if (j->transaction_next)
-                hashmap_replace(m->transaction_jobs, j->name, j->transaction_next);
+                hashmap_replace(m->transaction_jobs, j->unit, j->transaction_next);
         else
-                hashmap_remove_value(m->transaction_jobs, j->name, j);
+                hashmap_remove_value(m->transaction_jobs, j->unit, j);
 
         if (j->transaction_next)
                 j->transaction_next->transaction_prev = j->transaction_prev;
@@ -701,32 +701,32 @@ void manager_transaction_unlink_job(Manager *m, Job *j) {
 
                 if (other) {
                         log_debug("Deleting job %s/%s as dependency of job %s/%s",
-                                  name_id(other->name), job_type_to_string(other->type),
-                                  name_id(j->name), job_type_to_string(j->type));
+                                  unit_id(other->unit), job_type_to_string(other->type),
+                                  unit_id(j->unit), job_type_to_string(j->type));
                         transaction_delete_job(m, other);
                 }
         }
 }
 
-static int transaction_add_job_and_dependencies(Manager *m, JobType type, Name *name, Job *by, bool matters, bool force, Job **_ret) {
+static int transaction_add_job_and_dependencies(Manager *m, JobType type, Unit *unit, Job *by, bool matters, bool force, Job **_ret) {
         Job *ret;
         Iterator i;
-        Name *dep;
+        Unit *dep;
         int r;
         bool is_new;
 
         assert(m);
         assert(type < _JOB_TYPE_MAX);
-        assert(name);
+        assert(unit);
 
-        if (name->meta.load_state != NAME_LOADED)
+        if (unit->meta.load_state != UNIT_LOADED)
                 return -EINVAL;
 
-        if (!name_job_is_applicable(name, type))
+        if (!unit_job_is_applicable(unit, type))
                 return -EBADR;
 
         /* First add the job. */
-        if (!(ret = transaction_add_one_job(m, type, name, force, &is_new)))
+        if (!(ret = transaction_add_one_job(m, type, unit, force, &is_new)))
                 return -ENOMEM;
 
         /* Then, add a link to the job. */
@@ -736,28 +736,28 @@ static int transaction_add_job_and_dependencies(Manager *m, JobType type, Name *
         if (is_new) {
                 /* Finally, recursively add in all dependencies. */
                 if (type == JOB_START || type == JOB_RELOAD_OR_START) {
-                        SET_FOREACH(dep, ret->name->meta.dependencies[NAME_REQUIRES], i)
+                        SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUIRES], i)
                                 if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, true, force, NULL)) < 0 && r != -EBADR)
                                         goto fail;
-                        SET_FOREACH(dep, ret->name->meta.dependencies[NAME_SOFT_REQUIRES], i)
+                        SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_SOFT_REQUIRES], i)
                                 if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, !force, force, NULL)) < 0 && r != -EBADR)
                                         goto fail;
-                        SET_FOREACH(dep, ret->name->meta.dependencies[NAME_WANTS], i)
+                        SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_WANTS], i)
                                 if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, false, force, NULL)) < 0 && r != -EBADR)
                                         goto fail;
-                        SET_FOREACH(dep, ret->name->meta.dependencies[NAME_REQUISITE], i)
+                        SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUISITE], i)
                                 if ((r = transaction_add_job_and_dependencies(m, JOB_VERIFY_ACTIVE, dep, ret, true, force, NULL)) < 0 && r != -EBADR)
                                         goto fail;
-                        SET_FOREACH(dep, ret->name->meta.dependencies[NAME_SOFT_REQUISITE], i)
+                        SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_SOFT_REQUISITE], i)
                                 if ((r = transaction_add_job_and_dependencies(m, JOB_VERIFY_ACTIVE, dep, ret, !force, force, NULL)) < 0 && r != -EBADR)
                                         goto fail;
-                        SET_FOREACH(dep, ret->name->meta.dependencies[NAME_CONFLICTS], i)
+                        SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_CONFLICTS], i)
                                 if ((r = transaction_add_job_and_dependencies(m, JOB_STOP, dep, ret, true, force, NULL)) < 0 && r != -EBADR)
                                         goto fail;
 
                 } else if (type == JOB_STOP || type == JOB_RESTART || type == JOB_TRY_RESTART) {
 
-                        SET_FOREACH(dep, ret->name->meta.dependencies[NAME_REQUIRED_BY], i)
+                        SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUIRED_BY], i)
                                 if ((r = transaction_add_job_and_dependencies(m, type, dep, ret, true, force, NULL)) < 0 && r != -EBADR)
                                         goto fail;
                 }
@@ -771,16 +771,16 @@ fail:
         return r;
 }
 
-int manager_add_job(Manager *m, JobType type, Name *name, JobMode mode, bool force, Job **_ret) {
+int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, bool force, Job **_ret) {
         int r;
         Job *ret;
 
         assert(m);
         assert(type < _JOB_TYPE_MAX);
-        assert(name);
+        assert(unit);
         assert(mode < _JOB_MODE_MAX);
 
-        if ((r = transaction_add_job_and_dependencies(m, type, name, NULL, true, force, &ret))) {
+        if ((r = transaction_add_job_and_dependencies(m, type, unit, NULL, true, force, &ret))) {
                 transaction_abort(m);
                 return r;
         }
@@ -800,11 +800,11 @@ Job *manager_get_job(Manager *m, uint32_t id) {
         return hashmap_get(m->jobs, UINT32_TO_PTR(id));
 }
 
-Name *manager_get_name(Manager *m, const char *name) {
+Unit *manager_get_unit(Manager *m, const char *name) {
         assert(m);
         assert(name);
 
-        return hashmap_get(m->names, name);
+        return hashmap_get(m->units, name);
 }
 
 static void dispatch_load_queue(Manager *m) {
@@ -818,20 +818,20 @@ static void dispatch_load_queue(Manager *m) {
 
         m->dispatching_load_queue = true;
 
-        /* Dispatches the load queue. Takes a name from the queue and
+        /* Dispatches the load queue. Takes a unit from the queue and
          * tries to load its data until the queue is empty */
 
         while ((meta = m->load_queue)) {
                 assert(meta->in_load_queue);
 
-                name_load(NAME(meta));
+                unit_load(UNIT(meta));
         }
 
         m->dispatching_load_queue = false;
 }
 
-int manager_load_name(Manager *m, const char *name, Name **_ret) {
-        Name *ret;
+int manager_load_unit(Manager *m, const char *name, Unit **_ret) {
+        Unit *ret;
         int r;
 
         assert(m);
@@ -841,20 +841,20 @@ int manager_load_name(Manager *m, const char *name, Name **_ret) {
         /* This will load the service information files, but not actually
          * start any services or anything */
 
-        if ((ret = manager_get_name(m, name))) {
+        if ((ret = manager_get_unit(m, name))) {
                 *_ret = ret;
                 return 0;
         }
 
-        if (!(ret = name_new(m)))
+        if (!(ret = unit_new(m)))
                 return -ENOMEM;
 
-        if ((r = name_add_name(ret, name)) < 0) {
-                name_free(ret);
+        if ((r = unit_add_name(ret, name)) < 0) {
+                unit_free(ret);
                 return r;
         }
 
-        name_add_to_load_queue(ret);
+        unit_add_to_load_queue(ret);
         dispatch_load_queue(m);
 
         *_ret = ret;
@@ -872,17 +872,17 @@ void manager_dump_jobs(Manager *s, FILE *f, const char *prefix) {
                 job_dump(j, f, prefix);
 }
 
-void manager_dump_names(Manager *s, FILE *f, const char *prefix) {
+void manager_dump_units(Manager *s, FILE *f, const char *prefix) {
         Iterator i;
-        Name *n;
+        Unit *u;
         const char *t;
 
         assert(s);
         assert(f);
 
-        HASHMAP_FOREACH_KEY(n, t, s->names, i)
-                if (name_id(n) == t)
-                        name_dump(n, f, prefix);
+        HASHMAP_FOREACH_KEY(u, t, s->units, i)
+                if (unit_id(u) == t)
+                        unit_dump(u, f, prefix);
 }
 
 void manager_clear_jobs(Manager *m) {
@@ -919,7 +919,7 @@ static int manager_dispatch_sigchld(Manager *m) {
 
         for (;;) {
                 siginfo_t si;
-                Name *n;
+                Unit *u;
 
                 zero(si);
                 if (waitid(P_ALL, 0, &si, WNOHANG) < 0)
@@ -931,10 +931,10 @@ static int manager_dispatch_sigchld(Manager *m) {
                 if (si.si_code != CLD_EXITED && si.si_code != CLD_KILLED && si.si_code != CLD_DUMPED)
                         continue;
 
-                if (!(n = hashmap_remove(m->watch_pids, UINT32_TO_PTR(si.si_pid))))
+                if (!(u = hashmap_remove(m->watch_pids, UINT32_TO_PTR(si.si_pid))))
                         continue;
 
-                NAME_VTABLE(n)->sigchld_event(n, si.si_pid, si.si_code, si.si_status);
+                UNIT_VTABLE(u)->sigchld_event(u, si.si_pid, si.si_code, si.si_status);
         }
 
         return 0;
@@ -990,21 +990,21 @@ static int process_event(Manager *m, struct epoll_event *ev) {
                         break;
 
                 case MANAGER_FD: {
-                        Name *n;
+                        Unit *u;
 
-                        /* Some fd event, to be dispatched to the names */
-                        assert_se(n = ev->data.ptr);
-                        NAME_VTABLE(n)->fd_event(n, ev->data.fd, ev->events);
+                        /* Some fd event, to be dispatched to the units */
+                        assert_se(u = ev->data.ptr);
+                        UNIT_VTABLE(u)->fd_event(u, ev->data.fd, ev->events);
                         break;
                 }
 
                 case MANAGER_TIMER: {
-                        Name *n;
-                        uint64_t u;
+                        Unit *u;
+                        uint64_t v;
                         ssize_t k;
 
-                        /* Some timer event, to be dispatched to the names */
-                        if ((k = read(ev->data.fd, &u, sizeof(u))) != sizeof(u)) {
+                        /* Some timer event, to be dispatched to the units */
+                        if ((k = read(ev->data.fd, &v, sizeof(v))) != sizeof(v)) {
 
                                 if (k < 0 && (errno == EINTR || errno == EAGAIN))
                                         break;
@@ -1012,8 +1012,8 @@ static int process_event(Manager *m, struct epoll_event *ev) {
                                 return k < 0 ? -errno : -EIO;
                         }
 
-                        assert_se(n = ev->data.ptr);
-                        NAME_VTABLE(n)->timer_event(n, ev->data.fd, u);
+                        assert_se(u = ev->data.ptr);
+                        UNIT_VTABLE(u)->timer_event(u, ev->data.fd, v);
                         break;
                 }
 
index ddc9610..432d730 100644 (file)
--- a/manager.h
+++ b/manager.h
@@ -10,7 +10,7 @@
 typedef struct Manager Manager;
 typedef enum ManagerEventType ManagerEventType;
 
-#include "name.h"
+#include "unit.h"
 #include "job.h"
 #include "hashmap.h"
 #include "list.h"
@@ -25,28 +25,28 @@ enum ManagerEventType {
 struct Manager {
         uint32_t current_job_id;
 
-        /* Note that the set of names we know of is allowed to be
+        /* Note that the set of units we know of is allowed to be
          * incosistent. However the subset of it that is loaded may
          * not, and the list of jobs may neither. */
 
-        /* Active jobs and names */
-        Hashmap *names;  /* name string => Name object n:1 */
+        /* Active jobs and units */
+        Hashmap *units;  /* name string => Unit object n:1 */
         Hashmap *jobs;   /* job id => Job object 1:1 */
 
-        /* Names that need to be loaded */
+        /* Units that need to be loaded */
         LIST_HEAD(Meta, load_queue); /* this is actually more a stack than a queue, but uh. */
 
         /* Jobs that need to be run */
         LIST_HEAD(Job, run_queue);   /* more a stack than a queue, too */
 
         /* Jobs to be added */
-        Hashmap *transaction_jobs;      /* Name object => Job object list 1:1 */
+        Hashmap *transaction_jobs;      /* Unit object => Job object list 1:1 */
         JobDependency *transaction_anchor;
 
         bool dispatching_load_queue:1;
         bool dispatching_run_queue:1;
 
-        Hashmap *watch_pids;  /* pid => Name object n:1 */
+        Hashmap *watch_pids;  /* pid => Unit object n:1 */
 
         int epoll_fd;
         int signal_fd;
@@ -56,12 +56,12 @@ Manager* manager_new(void);
 void manager_free(Manager *m);
 
 Job *manager_get_job(Manager *m, uint32_t id);
-Name *manager_get_name(Manager *m, const char *name);
+Unit *manager_get_unit(Manager *m, const char *name);
 
-int manager_load_name(Manager *m, const char *name, Name **_ret);
-int manager_add_job(Manager *m, JobType type, Name *name, JobMode mode, bool force, Job **_ret);
+int manager_load_unit(Manager *m, const char *name, Unit **_ret);
+int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, bool force, Job **_ret);
 
-void manager_dump_names(Manager *s, FILE *f, const char *prefix);
+void manager_dump_units(Manager *s, FILE *f, const char *prefix);
 void manager_dump_jobs(Manager *s, FILE *f, const char *prefix);
 
 void manager_transaction_unlink_job(Manager *m, Job *j);
diff --git a/mount.c b/mount.c
index 21d3477..f4a6d6f 100644 (file)
--- a/mount.c
+++ b/mount.c
@@ -2,41 +2,41 @@
 
 #include <errno.h>
 
-#include "name.h"
+#include "unit.h"
 #include "mount.h"
 #include "load-fragment.h"
 #include "load-fstab.h"
 #include "load-dropin.h"
 
-static int mount_init(Name *n) {
+static int mount_init(Unit *u) {
         int r;
-        Mount *m = MOUNT(n);
+        Mount *m = MOUNT(u);
 
         assert(m);
 
         /* Load a .mount file */
-        if ((r = name_load_fragment(n)) < 0 && errno != -ENOENT)
+        if ((r = unit_load_fragment(u)) < 0 && errno != -ENOENT)
                 return r;
 
         /* Load entry from /etc/fstab */
-        if ((r = name_load_fstab(n)) < 0)
+        if ((r = unit_load_fstab(u)) < 0)
                 return r;
 
         /* Load drop-in directory data */
-        if ((r = name_load_dropin(n)) < 0)
+        if ((r = unit_load_dropin(u)) < 0)
                 return r;
 
         return r;
 }
 
-static void mount_done(Name *n) {
-        Mount *d = MOUNT(n);
+static void mount_done(Unit *u) {
+        Mount *d = MOUNT(u);
 
         assert(d);
         free(d->path);
 }
 
-static void mount_dump(Name *n, FILE *f, const char *prefix) {
+static void mount_dump(Unit *u, FILE *f, const char *prefix) {
 
         static const char* const state_table[_MOUNT_STATE_MAX] = {
                 [MOUNT_DEAD] = "dead",
@@ -46,7 +46,7 @@ static void mount_dump(Name *n, FILE *f, const char *prefix) {
                 [MOUNT_MAINTAINANCE] = "maintainance"
         };
 
-        Mount *s = MOUNT(n);
+        Mount *s = MOUNT(u);
 
         assert(s);
 
@@ -57,20 +57,20 @@ static void mount_dump(Name *n, FILE *f, const char *prefix) {
                 prefix, s->path);
 }
 
-static NameActiveState mount_active_state(Name *n) {
+static UnitActiveState mount_active_state(Unit *u) {
 
-        static const NameActiveState table[_MOUNT_STATE_MAX] = {
-                [MOUNT_DEAD] = NAME_INACTIVE,
-                [MOUNT_MOUNTING] = NAME_ACTIVATING,
-                [MOUNT_MOUNTED] = NAME_ACTIVE,
-                [MOUNT_UNMOUNTING] = NAME_DEACTIVATING,
-                [MOUNT_MAINTAINANCE] = NAME_INACTIVE,
+        static const UnitActiveState table[_MOUNT_STATE_MAX] = {
+                [MOUNT_DEAD] = UNIT_INACTIVE,
+                [MOUNT_MOUNTING] = UNIT_ACTIVATING,
+                [MOUNT_MOUNTED] = UNIT_ACTIVE,
+                [MOUNT_UNMOUNTING] = UNIT_DEACTIVATING,
+                [MOUNT_MAINTAINANCE] = UNIT_INACTIVE,
         };
 
-        return table[MOUNT(n)->state];
+        return table[MOUNT(u)->state];
 }
 
-const NameVTable mount_vtable = {
+const UnitVTable mount_vtable = {
         .suffix = ".mount",
 
         .init = mount_init,
diff --git a/mount.h b/mount.h
index b437b2e..734e96c 100644 (file)
--- a/mount.h
+++ b/mount.h
@@ -5,7 +5,7 @@
 
 typedef struct Mount Mount;
 
-#include "name.h"
+#include "unit.h"
 
 typedef enum MountState {
         MOUNT_DEAD,
@@ -23,6 +23,6 @@ struct Mount {
         char *path;
 };
 
-extern const NameVTable mount_vtable;
+extern const UnitVTable mount_vtable;
 
 #endif
diff --git a/name.c b/name.c
deleted file mode 100644 (file)
index e755eda..0000000
--- a/name.c
+++ /dev/null
@@ -1,829 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8 -*-*/
-
-#include <assert.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/epoll.h>
-#include <sys/timerfd.h>
-#include <sys/poll.h>
-
-#include "set.h"
-#include "name.h"
-#include "macro.h"
-#include "strv.h"
-#include "load-fragment.h"
-#include "load-dropin.h"
-#include "log.h"
-
-const NameVTable * const name_vtable[_NAME_TYPE_MAX] = {
-        [NAME_SERVICE] = &service_vtable,
-        [NAME_TIMER] = &timer_vtable,
-        [NAME_SOCKET] = &socket_vtable,
-        [NAME_TARGET] = &target_vtable,
-        [NAME_DEVICE] = &device_vtable,
-        [NAME_MOUNT] = &mount_vtable,
-        [NAME_AUTOMOUNT] = &automount_vtable,
-        [NAME_SNAPSHOT] = &snapshot_vtable
-};
-
-NameType name_type_from_string(const char *n) {
-        NameType t;
-
-        assert(n);
-
-        for (t = 0; t < _NAME_TYPE_MAX; t++)
-                if (endswith(n, name_vtable[t]->suffix))
-                        return t;
-
-        return _NAME_TYPE_INVALID;
-}
-
-#define VALID_CHARS                             \
-        "0123456789"                            \
-        "abcdefghijklmnopqrstuvwxyz"            \
-        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"            \
-        "-_"
-
-bool name_is_valid(const char *n) {
-        NameType t;
-        const char *e, *i;
-
-        assert(n);
-
-        if (strlen(n) >= NAME_MAX)
-                return false;
-
-        t = name_type_from_string(n);
-        if (t < 0 || t >= _NAME_TYPE_MAX)
-                return false;
-
-        if (!(e = strrchr(n, '.')))
-                return false;
-
-        for (i = n; i < e; i++)
-                if (!strchr(VALID_CHARS, *i))
-                        return false;
-
-        return true;
-}
-
-Name *name_new(Manager *m) {
-        Name *n;
-
-        assert(m);
-
-        if (!(n = new0(Name, 1)))
-                return NULL;
-
-        if (!(n->meta.names = set_new(string_hash_func, string_compare_func))) {
-                free(n);
-                return NULL;
-        }
-
-        n->meta.manager = m;
-        n->meta.type = _NAME_TYPE_INVALID;
-
-        return n;
-}
-
-int name_add_name(Name *n, const char *text) {
-        NameType t;
-        char *s;
-        int r;
-
-        assert(n);
-        assert(text);
-
-        if ((t = name_type_from_string(text)) == _NAME_TYPE_INVALID)
-                return -EINVAL;
-
-        if (n->meta.type != _NAME_TYPE_INVALID && t != n->meta.type)
-                return -EINVAL;
-
-        if (!(s = strdup(text)))
-                return -ENOMEM;
-
-        if ((r = set_put(n->meta.names, s)) < 0) {
-                free(s);
-                return r;
-        }
-
-        if ((r = hashmap_put(n->meta.manager->names, s, n)) < 0) {
-                set_remove(n->meta.names, s);
-                free(s);
-                return r;
-        }
-
-        n->meta.type = t;
-
-        if (!n->meta.id)
-                n->meta.id = s;
-
-        return 0;
-}
-
-void name_add_to_load_queue(Name *n) {
-        assert(n);
-
-        if (n->meta.load_state != NAME_STUB || n->meta.in_load_queue)
-                return;
-
-        LIST_PREPEND(Meta, load_queue, n->meta.manager->load_queue, &n->meta);
-        n->meta.in_load_queue = true;
-}
-
-static void bidi_set_free(Name *name, Set *s) {
-        Iterator i;
-        Name *other;
-
-        assert(name);
-
-        /* Frees the set and makes sure we are dropped from the
-         * inverse pointers */
-
-        SET_FOREACH(other, s, i) {
-                NameDependency d;
-
-                for (d = 0; d < _NAME_DEPENDENCY_MAX; d++)
-                        set_remove(other->meta.dependencies[d], name);
-        }
-
-        set_free(s);
-}
-
-void name_free(Name *name) {
-        NameDependency d;
-        Iterator i;
-        char *t;
-
-        assert(name);
-
-        /* Detach from next 'bigger' objects */
-
-        SET_FOREACH(t, name->meta.names, i)
-                hashmap_remove_value(name->meta.manager->names, t, name);
-
-        if (name->meta.in_load_queue)
-                LIST_REMOVE(Meta, load_queue, name->meta.manager->load_queue, &name->meta);
-
-        if (name->meta.load_state == NAME_LOADED)
-                if (NAME_VTABLE(name)->done)
-                        NAME_VTABLE(name)->done(name);
-
-        /* Free data and next 'smaller' objects */
-        if (name->meta.job)
-                job_free(name->meta.job);
-
-        for (d = 0; d < _NAME_DEPENDENCY_MAX; d++)
-                bidi_set_free(name, name->meta.dependencies[d]);
-
-        free(name->meta.description);
-
-        while ((t = set_steal_first(name->meta.names)))
-                free(t);
-        set_free(name->meta.names);
-
-        free(name);
-}
-
-NameActiveState name_active_state(Name *name) {
-        assert(name);
-
-        if (name->meta.load_state != NAME_LOADED)
-                return NAME_INACTIVE;
-
-        return NAME_VTABLE(name)->active_state(name);
-}
-
-static int ensure_merge(Set **s, Set *other) {
-
-        if (!other)
-                return 0;
-
-        if (*s)
-                return set_merge(*s, other);
-
-        if (!(*s = set_copy(other)))
-                return -ENOMEM;
-
-        return 0;
-}
-
-/* FIXME: Does not rollback on failure! */
-int name_merge(Name *name, Name *other) {
-        int r;
-        NameDependency d;
-
-        assert(name);
-        assert(other);
-        assert(name->meta.manager == other->meta.manager);
-
-        /* This merges 'other' into 'name'. FIXME: This does not
-         * rollback on failure. */
-
-        if (name->meta.type != other->meta.type)
-                return -EINVAL;
-
-        if (other->meta.load_state != NAME_STUB)
-                return -EINVAL;
-
-        /* Merge names */
-        if ((r = ensure_merge(&name->meta.names, other->meta.names)) < 0)
-                return r;
-
-        /* Merge dependencies */
-        for (d = 0; d < _NAME_DEPENDENCY_MAX; d++)
-                /* fixme, the inverse mapping is missing */
-                if ((r = ensure_merge(&name->meta.dependencies[d], other->meta.dependencies[d])) < 0)
-                        return r;
-
-        return 0;
-}
-
-const char* name_id(Name *n) {
-        assert(n);
-
-        if (n->meta.id)
-                return n->meta.id;
-
-        return set_first(n->meta.names);
-}
-
-const char *name_description(Name *n) {
-        assert(n);
-
-        if (n->meta.description)
-                return n->meta.description;
-
-        return name_id(n);
-}
-
-void name_dump(Name *n, FILE *f, const char *prefix) {
-
-        static const char* const load_state_table[_NAME_LOAD_STATE_MAX] = {
-                [NAME_STUB] = "stub",
-                [NAME_LOADED] = "loaded",
-                [NAME_FAILED] = "failed"
-        };
-
-        static const char* const active_state_table[_NAME_ACTIVE_STATE_MAX] = {
-                [NAME_ACTIVE] = "active",
-                [NAME_INACTIVE] = "inactive",
-                [NAME_ACTIVATING] = "activating",
-                [NAME_DEACTIVATING] = "deactivating"
-        };
-
-        static const char* const dependency_table[_NAME_DEPENDENCY_MAX] = {
-                [NAME_REQUIRES] = "Requires",
-                [NAME_SOFT_REQUIRES] = "SoftRequires",
-                [NAME_WANTS] = "Wants",
-                [NAME_REQUISITE] = "Requisite",
-                [NAME_SOFT_REQUISITE] = "SoftRequisite",
-                [NAME_REQUIRED_BY] = "RequiredBy",
-                [NAME_SOFT_REQUIRED_BY] = "SoftRequiredBy",
-                [NAME_WANTED_BY] = "WantedBy",
-                [NAME_CONFLICTS] = "Conflicts",
-                [NAME_BEFORE] = "Before",
-                [NAME_AFTER] = "After",
-        };
-
-        char *t;
-        NameDependency d;
-        Iterator i;
-        char *prefix2;
-
-        assert(n);
-
-        if (!prefix)
-                prefix = "";
-        prefix2 = strappend(prefix, "\t");
-        if (!prefix2)
-                prefix2 = "";
-
-        fprintf(f,
-                "%s→ Name %s:\n"
-                "%s\tDescription: %s\n"
-                "%s\tName Load State: %s\n"
-                "%s\tName Active State: %s\n",
-                prefix, name_id(n),
-                prefix, name_description(n),
-                prefix, load_state_table[n->meta.load_state],
-                prefix, active_state_table[name_active_state(n)]);
-
-        SET_FOREACH(t, n->meta.names, i)
-                fprintf(f, "%s\tName: %s\n", prefix, t);
-
-        for (d = 0; d < _NAME_DEPENDENCY_MAX; d++) {
-                Name *other;
-
-                if (set_isempty(n->meta.dependencies[d]))
-                        continue;
-
-                SET_FOREACH(other, n->meta.dependencies[d], i)
-                        fprintf(f, "%s\t%s: %s\n", prefix, dependency_table[d], name_id(other));
-        }
-
-        if (NAME_VTABLE(n)->dump)
-                NAME_VTABLE(n)->dump(n, f, prefix2);
-
-        if (n->meta.job)
-                job_dump(n->meta.job, f, prefix2);
-
-        free(prefix2);
-}
-
-static int verify_type(Name *name) {
-        char *n;
-        Iterator i;
-
-        assert(name);
-
-        /* Checks that all aliases of this name have the same and valid type */
-
-        SET_FOREACH(n, name->meta.names, i) {
-                NameType t;
-
-                if ((t = name_type_from_string(n)) == _NAME_TYPE_INVALID)
-                        return -EINVAL;
-
-                if (name->meta.type == _NAME_TYPE_INVALID) {
-                        name->meta.type = t;
-                        continue;
-                }
-
-                if (name->meta.type != t)
-                        return -EINVAL;
-        }
-
-        if (name->meta.type == _NAME_TYPE_INVALID)
-                return -EINVAL;
-
-        return 0;
-}
-
-/* Common implementation for multiple backends */
-int name_load_fragment_and_dropin(Name *n) {
-        int r;
-
-        assert(n);
-
-        /* Load a .socket file */
-        if ((r = name_load_fragment(n)) < 0)
-                return r;
-
-        /* Load drop-in directory data */
-        if ((r = name_load_dropin(n)) < 0)
-                return r;
-
-        return 0;
-}
-
-int name_load(Name *name) {
-        int r;
-
-        assert(name);
-
-        if (name->meta.in_load_queue) {
-                LIST_REMOVE(Meta, load_queue, name->meta.manager->load_queue, &name->meta);
-                name->meta.in_load_queue = false;
-        }
-
-        if (name->meta.load_state != NAME_STUB)
-                return 0;
-
-        if ((r = verify_type(name)) < 0)
-                return r;
-
-        if (NAME_VTABLE(name)->init)
-                if ((r = NAME_VTABLE(name)->init(name)) < 0)
-                        goto fail;
-
-        name->meta.load_state = NAME_LOADED;
-        return 0;
-
-fail:
-        name->meta.load_state = NAME_FAILED;
-        return r;
-}
-
-/* Errors:
- *         -EBADR:    This name type does not support starting.
- *         -EALREADY: Name is already started.
- *         -EAGAIN:   An operation is already in progress. Retry later.
- */
-int name_start(Name *n) {
-        NameActiveState state;
-
-        assert(n);
-
-        if (!NAME_VTABLE(n)->start)
-                return -EBADR;
-
-        state = name_active_state(n);
-        if (NAME_IS_ACTIVE_OR_RELOADING(state))
-                return -EALREADY;
-
-        /* We don't suppress calls to ->start() here when we are
-         * already starting, to allow this request to be used as a
-         * "hurry up" call, for example when the name is in some "auto
-         * restart" state where it waits for a holdoff timer to elapse
-         * before it will start again. */
-
-        return NAME_VTABLE(n)->start(n);
-}
-
-bool name_can_start(Name *n) {
-        assert(n);
-
-        return !!NAME_VTABLE(n)->start;
-}
-
-/* Errors:
- *         -EBADR:    This name type does not support stopping.
- *         -EALREADY: Name is already stopped.
- *         -EAGAIN:   An operation is already in progress. Retry later.
- */
-int name_stop(Name *n) {
-        NameActiveState state;
-
-        assert(n);
-
-        if (!NAME_VTABLE(n)->stop)
-                return -EBADR;
-
-        state = name_active_state(n);
-        if (state == NAME_INACTIVE)
-                return -EALREADY;
-
-        if (state == NAME_DEACTIVATING)
-                return 0;
-
-        return NAME_VTABLE(n)->stop(n);
-}
-
-/* Errors:
- *         -EBADR:    This name type does not support reloading.
- *         -ENOEXEC:  Name is not started.
- *         -EAGAIN:   An operation is already in progress. Retry later.
- */
-int name_reload(Name *n) {
-        NameActiveState state;
-
-        assert(n);
-
-        if (!name_can_reload(n))
-                return -EBADR;
-
-        state = name_active_state(n);
-        if (name_active_state(n) == NAME_ACTIVE_RELOADING)
-                return -EALREADY;
-
-        if (name_active_state(n) != NAME_ACTIVE)
-                return -ENOEXEC;
-
-        return NAME_VTABLE(n)->reload(n);
-}
-
-bool name_can_reload(Name *n) {
-        assert(n);
-
-        if (!NAME_VTABLE(n)->reload)
-                return false;
-
-        if (!NAME_VTABLE(n)->can_reload)
-                return true;
-
-        return NAME_VTABLE(n)->can_reload(n);
-}
-
-static void retroactively_start_dependencies(Name *n) {
-        Iterator i;
-        Name *other;
-
-        assert(n);
-        assert(NAME_IS_ACTIVE_OR_ACTIVATING(name_active_state(n)));
-
-        SET_FOREACH(other, n->meta.dependencies[NAME_REQUIRES], i)
-                if (!NAME_IS_ACTIVE_OR_ACTIVATING(name_active_state(other)))
-                        manager_add_job(n->meta.manager, JOB_START, other, JOB_REPLACE, true, NULL);
-
-        SET_FOREACH(other, n->meta.dependencies[NAME_SOFT_REQUIRES], i)
-                if (!NAME_IS_ACTIVE_OR_ACTIVATING(name_active_state(other)))
-                        manager_add_job(n->meta.manager, JOB_START, other, JOB_FAIL, false, NULL);
-
-        SET_FOREACH(other, n->meta.dependencies[NAME_REQUISITE], i)
-                if (!NAME_IS_ACTIVE_OR_ACTIVATING(name_active_state(other)))
-                        manager_add_job(n->meta.manager, JOB_START, other, JOB_REPLACE, true, NULL);
-
-        SET_FOREACH(other, n->meta.dependencies[NAME_WANTS], i)
-                if (!NAME_IS_ACTIVE_OR_ACTIVATING(name_active_state(other)))
-                        manager_add_job(n->meta.manager, JOB_START, other, JOB_FAIL, false, NULL);
-
-        SET_FOREACH(other, n->meta.dependencies[NAME_CONFLICTS], i)
-                if (!NAME_IS_ACTIVE_OR_ACTIVATING(name_active_state(other)))
-                        manager_add_job(n->meta.manager, JOB_STOP, other, JOB_REPLACE, true, NULL);
-}
-
-static void retroactively_stop_dependencies(Name *n) {
-        Iterator i;
-        Name *other;
-
-        assert(n);
-        assert(NAME_IS_INACTIVE_OR_DEACTIVATING(name_active_state(n)));
-
-        SET_FOREACH(other, n->meta.dependencies[NAME_REQUIRED_BY], i)
-                if (!NAME_IS_INACTIVE_OR_DEACTIVATING(name_active_state(other)))
-                        manager_add_job(n->meta.manager, JOB_STOP, other, JOB_REPLACE, true, NULL);
-}
-
-void name_notify(Name *n, NameActiveState os, NameActiveState ns) {
-        assert(n);
-        assert(os < _NAME_ACTIVE_STATE_MAX);
-        assert(ns < _NAME_ACTIVE_STATE_MAX);
-        assert(!(os == NAME_ACTIVE && ns == NAME_ACTIVATING));
-        assert(!(os == NAME_INACTIVE && ns == NAME_DEACTIVATING));
-
-        if (os == ns)
-                return;
-
-        if (!NAME_IS_ACTIVE_OR_RELOADING(os) && NAME_IS_ACTIVE_OR_RELOADING(ns))
-                n->meta.active_enter_timestamp = now(CLOCK_REALTIME);
-        else if (NAME_IS_ACTIVE_OR_RELOADING(os) && !NAME_IS_ACTIVE_OR_RELOADING(ns))
-                n->meta.active_exit_timestamp = now(CLOCK_REALTIME);
-
-        if (n->meta.job) {
-
-                if (n->meta.job->state == JOB_WAITING)
-
-                        /* So we reached a different state for this
-                         * job. Let's see if we can run it now if it
-                         * failed previously due to EAGAIN. */
-                        job_schedule_run(n->meta.job);
-
-                else {
-                        assert(n->meta.job->state == JOB_RUNNING);
-
-                        /* Let's check of this state change
-                         * constitutes a finished job, or maybe
-                         * cotradicts a running job and hence needs to
-                         * invalidate jobs. */
-
-                        switch (n->meta.job->type) {
-
-                                case JOB_START:
-                                case JOB_VERIFY_ACTIVE:
-
-                                        if (NAME_IS_ACTIVE_OR_RELOADING(ns)) {
-                                                job_finish_and_invalidate(n->meta.job, true);
-                                                return;
-                                        } else if (ns == NAME_ACTIVATING)
-                                                return;
-                                        else
-                                                job_finish_and_invalidate(n->meta.job, false);
-
-                                        break;
-
-                                case JOB_RELOAD:
-                                case JOB_RELOAD_OR_START:
-
-                                        if (ns == NAME_ACTIVE) {
-                                                job_finish_and_invalidate(n->meta.job, true);
-                                                return;
-                                        } else if (ns == NAME_ACTIVATING || ns == NAME_ACTIVE_RELOADING)
-                                                return;
-                                        else
-                                                job_finish_and_invalidate(n->meta.job, false);
-
-                                        break;
-
-                                case JOB_STOP:
-                                case JOB_RESTART:
-                                case JOB_TRY_RESTART:
-
-                                        if (ns == NAME_INACTIVE) {
-                                                job_finish_and_invalidate(n->meta.job, true);
-                                                return;
-                                        } else if (ns == NAME_DEACTIVATING)
-                                                return;
-                                        else
-                                                job_finish_and_invalidate(n->meta.job, false);
-
-                                        break;
-
-                                default:
-                                        assert_not_reached("Job type unknown");
-                        }
-                }
-        }
-
-        /* If this state change happened without being requested by a
-         * job, then let's retroactively start or stop dependencies */
-
-        if (NAME_IS_INACTIVE_OR_DEACTIVATING(os) && NAME_IS_ACTIVE_OR_ACTIVATING(ns))
-                retroactively_start_dependencies(n);
-        else if (NAME_IS_ACTIVE_OR_ACTIVATING(os) && NAME_IS_INACTIVE_OR_DEACTIVATING(ns))
-                retroactively_stop_dependencies(n);
-}
-
-int name_watch_fd(Name *n, int fd, uint32_t events) {
-        struct epoll_event ev;
-
-        assert(n);
-        assert(fd >= 0);
-
-        zero(ev);
-        ev.data.fd = fd;
-        ev.data.ptr = n;
-        ev.data.u32 = MANAGER_FD;
-        ev.events = events;
-
-        if (epoll_ctl(n->meta.manager->epoll_fd, EPOLL_CTL_ADD, fd, &ev) >= 0)
-                return 0;
-
-        if (errno == EEXIST)
-                if (epoll_ctl(n->meta.manager->epoll_fd, EPOLL_CTL_MOD, fd, &ev) >= 0)
-                        return 0;
-
-        return -errno;
-}
-
-void name_unwatch_fd(Name *n, int fd) {
-        assert(n);
-        assert(fd >= 0);
-
-        assert_se(epoll_ctl(n->meta.manager->epoll_fd, EPOLL_CTL_DEL, fd, NULL) >= 0 || errno == ENOENT);
-}
-
-int name_watch_pid(Name *n, pid_t pid) {
-        assert(n);
-        assert(pid >= 1);
-
-        return hashmap_put(n->meta.manager->watch_pids, UINT32_TO_PTR(pid), n);
-}
-
-void name_unwatch_pid(Name *n, pid_t pid) {
-        assert(n);
-        assert(pid >= 1);
-
-        hashmap_remove(n->meta.manager->watch_pids, UINT32_TO_PTR(pid));
-}
-
-int name_watch_timer(Name *n, usec_t delay, int *id) {
-        struct epoll_event ev;
-        int fd;
-        struct itimerspec its;
-        int flags;
-        bool ours;
-
-        assert(n);
-        assert(id);
-
-        /* This will try to reuse the old timer if there is one */
-
-        if (*id >= 0) {
-                ours = false;
-                fd = *id;
-
-        } else {
-                ours = true;
-
-                if ((fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC)) < 0)
-                        return -errno;
-        }
-
-        zero(its);
-
-        if (delay <= 0) {
-                /* Set absolute time in the past, but not 0, since we
-                 * don't want to disarm the timer */
-                its.it_value.tv_sec = 0;
-                its.it_value.tv_nsec = 1;
-
-                flags = TFD_TIMER_ABSTIME;
-        } else {
-                timespec_store(&its.it_value, delay);
-                flags = 0;
-        }
-
-        /* This will also flush the elapse counter */
-        if (timerfd_settime(fd, flags, &its, NULL) < 0)
-                goto fail;
-
-        zero(ev);
-        ev.data.fd = fd;
-        ev.data.ptr = n;
-        ev.data.u32 = MANAGER_TIMER;
-        ev.events = POLLIN;
-
-        if (epoll_ctl(n->meta.manager->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0)
-                goto fail;
-
-        *id = fd;
-        return 0;
-
-fail:
-        if (ours)
-                assert_se(close_nointr(fd) == 0);
-
-        return -errno;
-}
-
-void name_unwatch_timer(Name *n, int *id) {
-        assert(n);
-        assert(id);
-
-        if (*id >= 0) {
-                assert_se(epoll_ctl(n->meta.manager->epoll_fd, EPOLL_CTL_DEL, *id, NULL) >= 0);
-                assert_se(close_nointr(*id) == 0);
-
-                *id = -1;
-        }
-}
-
-char *name_change_suffix(const char *t, const char *suffix) {
-        char *e, *n;
-        size_t a, b;
-
-        assert(t);
-        assert(name_is_valid(t));
-        assert(suffix);
-
-        assert_se(e = strrchr(t, '.'));
-        a = e - t;
-        b = strlen(suffix);
-
-        if (!(n = new(char, a + b + 1)))
-                return NULL;
-
-        memcpy(n, t, a);
-        memcpy(n+a, suffix, b+1);
-
-        return n;
-}
-
-bool name_job_is_applicable(Name *n, JobType j) {
-        assert(n);
-        assert(j >= 0 && j < _JOB_TYPE_MAX);
-
-        switch (j) {
-                case JOB_VERIFY_ACTIVE:
-                case JOB_START:
-                        return true;
-
-                case JOB_STOP:
-                case JOB_RESTART:
-                case JOB_TRY_RESTART:
-                        return name_can_start(n);
-
-                case JOB_RELOAD:
-                        return name_can_reload(n);
-
-                case JOB_RELOAD_OR_START:
-                        return name_can_reload(n) && name_can_start(n);
-
-                default:
-                        assert_not_reached("Invalid job type");
-        }
-}
-
-int name_add_dependency(Name *n, NameDependency d, Name *other) {
-
-        static const NameDependency inverse_table[_NAME_DEPENDENCY_MAX] = {
-                [NAME_REQUIRES] = NAME_REQUIRED_BY,
-                [NAME_SOFT_REQUIRES] = NAME_SOFT_REQUIRED_BY,
-                [NAME_WANTS] = NAME_WANTED_BY,
-                [NAME_REQUISITE] = NAME_REQUIRED_BY,
-                [NAME_SOFT_REQUISITE] = NAME_SOFT_REQUIRED_BY,
-                [NAME_REQUIRED_BY] = _NAME_DEPENDENCY_INVALID,
-                [NAME_SOFT_REQUIRED_BY] = _NAME_DEPENDENCY_INVALID,
-                [NAME_WANTED_BY] = _NAME_DEPENDENCY_INVALID,
-                [NAME_CONFLICTS] = NAME_CONFLICTS,
-                [NAME_BEFORE] = NAME_AFTER,
-                [NAME_AFTER] = NAME_BEFORE
-        };
-        int r;
-
-        assert(n);
-        assert(d >= 0 && d < _NAME_DEPENDENCY_MAX);
-        assert(inverse_table[d] != _NAME_DEPENDENCY_INVALID);
-        assert(other);
-
-        if (n == other)
-                return 0;
-
-        if ((r = set_ensure_allocated(&n->meta.dependencies[d], trivial_hash_func, trivial_compare_func)) < 0)
-                return r;
-
-        if ((r = set_ensure_allocated(&other->meta.dependencies[inverse_table[d]], trivial_hash_func, trivial_compare_func)) < 0)
-                return r;
-
-        if ((r = set_put(n->meta.dependencies[d], other)) < 0)
-                return r;
-
-        if ((r = set_put(other->meta.dependencies[inverse_table[d]], n)) < 0) {
-                set_remove(n->meta.dependencies[d], other);
-                return r;
-        }
-
-        return 0;
-}
diff --git a/name.h b/name.h
deleted file mode 100644 (file)
index cf1861f..0000000
--- a/name.h
+++ /dev/null
@@ -1,236 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8 -*-*/
-
-#ifndef foonamehfoo
-#define foonamehfoo
-
-#include <stdbool.h>
-#include <stdlib.h>
-
-typedef union Name Name;
-typedef struct Meta Meta;
-typedef struct NameVTable NameVTable;
-typedef enum NameType NameType;
-typedef enum NameLoadState NameLoadState;
-typedef enum NameActiveState NameActiveState;
-typedef enum NameDependency NameDependency;
-
-#include "job.h"
-#include "manager.h"
-#include "set.h"
-#include "util.h"
-#include "list.h"
-#include "socket-util.h"
-#include "execute.h"
-#include "util.h"
-
-#define NAME_MAX 32
-#define DEFAULT_TIMEOUT_USEC (20*USEC_PER_SEC)
-#define DEFAULT_RESTART_USEC (100*USEC_PER_MSEC)
-
-enum NameType {
-        NAME_SERVICE = 0,
-        NAME_TIMER,
-        NAME_SOCKET,
-        NAME_TARGET,
-        NAME_DEVICE,
-        NAME_MOUNT,
-        NAME_AUTOMOUNT,
-        NAME_SNAPSHOT,
-        _NAME_TYPE_MAX,
-        _NAME_TYPE_INVALID = -1,
-};
-
-enum NameLoadState {
-        NAME_STUB,
-        NAME_LOADED,
-        NAME_FAILED,
-        _NAME_LOAD_STATE_MAX
-};
-
-enum NameActiveState {
-        NAME_ACTIVE,
-        NAME_ACTIVE_RELOADING,
-        NAME_INACTIVE,
-        NAME_ACTIVATING,
-        NAME_DEACTIVATING,
-        _NAME_ACTIVE_STATE_MAX
-};
-
-static inline bool NAME_IS_ACTIVE_OR_RELOADING(NameActiveState t) {
-        return t == NAME_ACTIVE || t == NAME_ACTIVE_RELOADING;
-}
-
-static inline bool NAME_IS_ACTIVE_OR_ACTIVATING(NameActiveState t) {
-        return t == NAME_ACTIVE || t == NAME_ACTIVATING || t == NAME_ACTIVE_RELOADING;
-}
-
-static inline bool NAME_IS_INACTIVE_OR_DEACTIVATING(NameActiveState t) {
-        return t == NAME_INACTIVE || t == NAME_DEACTIVATING;
-}
-
-enum NameDependency {
-        /* Positive dependencies */
-        NAME_REQUIRES,
-        NAME_SOFT_REQUIRES,
-        NAME_WANTS,
-        NAME_REQUISITE,
-        NAME_SOFT_REQUISITE,
-
-        /* Inverse of the above */
-        NAME_REQUIRED_BY,       /* inverse of 'requires' and 'requisite' is 'required_by' */
-        NAME_SOFT_REQUIRED_BY,  /* inverse of 'soft_requires' and 'soft_requisite' is 'soft_required_by' */
-        NAME_WANTED_BY,         /* inverse of 'wants' */
-
-        /* Negative dependencies */
-        NAME_CONFLICTS,         /* inverse of 'conflicts' is 'conflicts' */
-
-        /* Order */
-        NAME_BEFORE,            /* inverse of before is after and vice versa */
-        NAME_AFTER,
-
-        _NAME_DEPENDENCY_MAX,
-        _NAME_DEPENDENCY_INVALID = -1
-};
-
-struct Meta {
-        Manager *manager;
-        NameType type;
-        NameLoadState load_state;
-
-        char *id; /* One name is special because we use it for identification. Points to an entry in the names set */
-
-        Set *names;
-        Set *dependencies[_NAME_DEPENDENCY_MAX];
-
-        char *description;
-
-        /* If there is something to do with this name, then this is
-         * the job for it */
-        Job *job;
-
-        bool in_load_queue:1;
-
-        usec_t active_enter_timestamp;
-        usec_t active_exit_timestamp;
-
-        /* Load queue */
-        LIST_FIELDS(Meta, load_queue);
-};
-
-#include "service.h"
-#include "timer.h"
-#include "socket.h"
-#include "target.h"
-#include "device.h"
-#include "mount.h"
-#include "automount.h"
-#include "snapshot.h"
-
-union Name {
-        Meta meta;
-        Service service;
-        Timer timer;
-        Socket socket;
-        Target target;
-        Device device;
-        Mount mount;
-        Automount automount;
-        Snapshot snapshot;
-};
-
-struct NameVTable {
-        const char *suffix;
-
-        int (*init)(Name *n);
-        void (*done)(Name *n);
-
-        void (*dump)(Name *n, FILE *f, const char *prefix);
-
-        int (*start)(Name *n);
-        int (*stop)(Name *n);
-        int (*reload)(Name *n);
-
-        bool (*can_reload)(Name *n);
-
-        /* Boils down the more complex internal state of this name to
-         * a simpler one that the engine can understand */
-        NameActiveState (*active_state)(Name *n);
-
-        void (*fd_event)(Name *n, int fd, uint32_t events);
-        void (*sigchld_event)(Name *n, pid_t pid, int code, int status);
-        void (*timer_event)(Name *n, int id, uint64_t n_elapsed);
-
-        void (*retry)(Name *n);
-};
-
-extern const NameVTable * const name_vtable[_NAME_TYPE_MAX];
-
-#define NAME_VTABLE(n) name_vtable[(n)->meta.type]
-
-/* For casting a name into the various name types */
-#define DEFINE_CAST(UPPERCASE, MixedCase)                               \
-        static inline MixedCase* UPPERCASE(Name *name) {                \
-                if (!name || name->meta.type != NAME_##UPPERCASE)       \
-                        return NULL;                                    \
-                                                                        \
-                return (MixedCase*) name;                               \
-        }
-
-/* For casting the various name types into a name */
-#define NAME(o) ((Name*) (o))
-
-DEFINE_CAST(SOCKET, Socket);
-DEFINE_CAST(TIMER, Timer);
-DEFINE_CAST(SERVICE, Service);
-DEFINE_CAST(TARGET, Target);
-DEFINE_CAST(DEVICE, Device);
-DEFINE_CAST(MOUNT, Mount);
-DEFINE_CAST(AUTOMOUNT, Automount);
-DEFINE_CAST(SNAPSHOT, Snapshot);
-
-NameType name_type_from_string(const char *n);
-bool name_is_valid(const char *n);
-
-Name *name_new(Manager *m);
-void name_free(Name *name);
-
-int name_add_name(Name *n, const char *text);
-int name_add_dependency(Name *n, NameDependency d, Name *other);
-
-void name_add_to_load_queue(Name *n);
-
-int name_merge(Name *name, Name *other);
-
-int name_load_fragment_and_dropin(Name *n);
-int name_load(Name *name);
-
-const char* name_id(Name *n);
-const char *name_description(Name *n);
-
-NameActiveState name_active_state(Name *name);
-
-void name_dump(Name *n, FILE *f, const char *prefix);
-
-bool name_can_reload(Name *n);
-bool name_can_start(Name *n);
-
-int name_start(Name *n);
-int name_stop(Name *n);
-int name_reload(Name *n);
-
-void name_notify(Name *n, NameActiveState os, NameActiveState ns);
-
-int name_watch_fd(Name *n, int fd, uint32_t events);
-void name_unwatch_fd(Name *n, int fd);
-
-int name_watch_pid(Name *n, pid_t pid);
-void name_unwatch_pid(Name *n, pid_t pid);
-
-int name_watch_timer(Name *n, usec_t delay, int *id);
-void name_unwatch_timer(Name *n, int *id);
-
-char *name_change_suffix(const char *t, const char *suffix);
-
-bool name_job_is_applicable(Name *n, JobType j);
-
-#endif
index 1e4824d..ef10cdb 100644 (file)
--- a/service.c
+++ b/service.c
@@ -3,31 +3,31 @@
 #include <errno.h>
 #include <signal.h>
 
-#include "name.h"
+#include "unit.h"
 #include "service.h"
 #include "load-fragment.h"
 #include "load-dropin.h"
 #include "log.h"
 
-static const NameActiveState state_table[_SERVICE_STATE_MAX] = {
-        [SERVICE_DEAD] = NAME_INACTIVE,
-        [SERVICE_START_PRE] = NAME_ACTIVATING,
-        [SERVICE_START] = NAME_ACTIVATING,
-        [SERVICE_START_POST] = NAME_ACTIVATING,
-        [SERVICE_RUNNING] = NAME_ACTIVE,
-        [SERVICE_RELOAD] = NAME_ACTIVE_RELOADING,
-        [SERVICE_STOP] = NAME_DEACTIVATING,
-        [SERVICE_STOP_SIGTERM] = NAME_DEACTIVATING,
-        [SERVICE_STOP_SIGKILL] = NAME_DEACTIVATING,
-        [SERVICE_STOP_POST] = NAME_DEACTIVATING,
-        [SERVICE_FINAL_SIGTERM] = NAME_DEACTIVATING,
-        [SERVICE_FINAL_SIGKILL] = NAME_DEACTIVATING,
-        [SERVICE_MAINTAINANCE] = NAME_INACTIVE,
-        [SERVICE_AUTO_RESTART] = NAME_ACTIVATING,
+static const UnitActiveState state_table[_SERVICE_STATE_MAX] = {
+        [SERVICE_DEAD] = UNIT_INACTIVE,
+        [SERVICE_START_PRE] = UNIT_ACTIVATING,
+        [SERVICE_START] = UNIT_ACTIVATING,
+        [SERVICE_START_POST] = UNIT_ACTIVATING,
+        [SERVICE_RUNNING] = UNIT_ACTIVE,
+        [SERVICE_RELOAD] = UNIT_ACTIVE_RELOADING,
+        [SERVICE_STOP] = UNIT_DEACTIVATING,
+        [SERVICE_STOP_SIGTERM] = UNIT_DEACTIVATING,
+        [SERVICE_STOP_SIGKILL] = UNIT_DEACTIVATING,
+        [SERVICE_STOP_POST] = UNIT_DEACTIVATING,
+        [SERVICE_FINAL_SIGTERM] = UNIT_DEACTIVATING,
+        [SERVICE_FINAL_SIGKILL] = UNIT_DEACTIVATING,
+        [SERVICE_MAINTAINANCE] = UNIT_INACTIVE,
+        [SERVICE_AUTO_RESTART] = UNIT_ACTIVATING,
 };
 
-static void service_done(Name *n) {
-        Service *s = SERVICE(n);
+static void service_done(Unit *u) {
+        Service *s = SERVICE(u);
 
         assert(s);
 
@@ -41,16 +41,16 @@ static void service_done(Name *n) {
         /* This will leak a process, but at least no memory or any of
          * our resources */
         if (s->main_pid > 0) {
-                name_unwatch_pid(n, s->main_pid);
+                unit_unwatch_pid(u, s->main_pid);
                 s->main_pid = 0;
         }
 
         if (s->control_pid > 0) {
-                name_unwatch_pid(n, s->control_pid);
+                unit_unwatch_pid(u, s->control_pid);
                 s->control_pid = 0;
         }
 
-        name_unwatch_timer(n, &s->timer_id);
+        unit_unwatch_timer(u, &s->timer_id);
 }
 
 static int service_load_sysv(Service *s) {
@@ -62,9 +62,9 @@ static int service_load_sysv(Service *s) {
         return -ENOENT;
 }
 
-static int service_init(Name *n) {
+static int service_init(Unit *u) {
         int r;
-        Service *s = SERVICE(n);
+        Service *s = SERVICE(u);
 
         assert(s);
 
@@ -84,27 +84,27 @@ static int service_init(Name *n) {
         s->state = SERVICE_DEAD;
 
         /* Load a .service file */
-        r = name_load_fragment(n);
+        r = unit_load_fragment(u);
 
         /* Load a classic init script as a fallback */
         if (r == -ENOENT)
                 r = service_load_sysv(s);
 
         if (r < 0) {
-                service_done(n);
+                service_done(u);
                 return r;
         }
 
         /* Load dropin directory data */
-        if ((r = name_load_dropin(n)) < 0) {
-                service_done(n);
+        if ((r = unit_load_dropin(u)) < 0) {
+                service_done(u);
                 return r;
         }
 
         return 0;
 }
 
-static void service_dump(Name *n, FILE *f, const char *prefix) {
+static void service_dump(Unit *u, FILE *f, const char *prefix) {
 
         static const char* const state_table[_SERVICE_STATE_MAX] = {
                 [SERVICE_DEAD] = "dead",
@@ -133,7 +133,7 @@ static void service_dump(Name *n, FILE *f, const char *prefix) {
         };
 
         ServiceExecCommand c;
-        Service *s = SERVICE(n);
+        Service *s = SERVICE(u);
         char *prefix2;
 
         assert(s);
@@ -216,7 +216,7 @@ static void service_set_state(Service *s, ServiceState state) {
             state != SERVICE_FINAL_SIGTERM &&
             state != SERVICE_FINAL_SIGKILL &&
             state != SERVICE_AUTO_RESTART)
-                name_unwatch_timer(NAME(s), &s->timer_id);
+                unit_unwatch_timer(UNIT(s), &s->timer_id);
 
         if (state != SERVICE_START_POST &&
             state != SERVICE_RUNNING &&
@@ -225,7 +225,7 @@ static void service_set_state(Service *s, ServiceState state) {
             state != SERVICE_STOP_SIGTERM &&
             state != SERVICE_STOP_SIGKILL)
                 if (s->main_pid >= 0) {
-                        name_unwatch_pid(NAME(s), s->main_pid);
+                        unit_unwatch_pid(UNIT(s), s->main_pid);
                         s->main_pid = 0;
                 }
 
@@ -240,7 +240,7 @@ static void service_set_state(Service *s, ServiceState state) {
             state != SERVICE_FINAL_SIGTERM &&
             state != SERVICE_FINAL_SIGKILL)
                 if (s->control_pid >= 0) {
-                        name_unwatch_pid(NAME(s), s->control_pid);
+                        unit_unwatch_pid(UNIT(s), s->control_pid);
                         s->control_pid = 0;
                 }
 
@@ -252,7 +252,7 @@ static void service_set_state(Service *s, ServiceState state) {
             state != SERVICE_STOP_POST)
                 s->control_command = NULL;
 
-        name_notify(NAME(s), state_table[old_state], state_table[s->state]);
+        unit_notify(UNIT(s), state_table[old_state], state_table[s->state]);
 }
 
 static int service_collect_fds(Service *s, int **fds, unsigned *n_fds) {
@@ -266,21 +266,21 @@ static int service_collect_fds(Service *s, int **fds, unsigned *n_fds) {
         assert(fds);
         assert(n_fds);
 
-        SET_FOREACH(t, NAME(s)->meta.names, i) {
+        SET_FOREACH(t, UNIT(s)->meta.names, i) {
                 char *k;
-                Name *p;
+                Unit *p;
                 int *cfds;
                 unsigned cn_fds;
 
                 /* Look for all socket objects that go by any of our
-                 * names and collect their fds */
+                 * units and collect their fds */
 
-                if (!(k = name_change_suffix(t, ".socket"))) {
+                if (!(k = unit_name_change_suffix(t, ".socket"))) {
                         r = -ENOMEM;
                         goto fail;
                 }
 
-                p = manager_get_name(NAME(s)->meta.manager, k);
+                p = manager_get_unit(UNIT(s)->meta.manager, k);
                 free(k);
 
                 if ((r = socket_collect_fds(SOCKET(p), &cfds, &cn_fds)) < 0)
@@ -335,15 +335,15 @@ static int service_spawn(Service *s, ExecCommand *c, bool timeout, bool pass_fds
                         goto fail;
 
         if (timeout) {
-                if ((r = name_watch_timer(NAME(s), s->timeout_usec, &s->timer_id)) < 0)
+                if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_id)) < 0)
                         goto fail;
         } else
-                name_unwatch_timer(NAME(s), &s->timer_id);
+                unit_unwatch_timer(UNIT(s), &s->timer_id);
 
         if ((r = exec_spawn(c, &s->exec_context, fds, n_fds, &pid)) < 0)
                 goto fail;
 
-        if ((r = name_watch_pid(NAME(s), pid)) < 0)
+        if ((r = unit_watch_pid(UNIT(s), pid)) < 0)
                 /* FIXME: we need to do something here */
                 goto fail;
 
@@ -356,7 +356,7 @@ fail:
         free(fds);
 
         if (timeout)
-                name_unwatch_timer(NAME(s), &s->timer_id);
+                unit_unwatch_timer(UNIT(s), &s->timer_id);
 
         return r;
 }
@@ -372,7 +372,7 @@ static void service_enter_dead(Service *s, bool success, bool allow_restart) {
             (s->restart == SERVICE_RESTART_ALWAYS ||
              (s->restart == SERVICE_RESTART_ON_SUCCESS && !s->failure))) {
 
-                if ((r = name_watch_timer(NAME(s), s->restart_usec, &s->timer_id)) < 0)
+                if ((r = unit_watch_timer(UNIT(s), s->restart_usec, &s->timer_id)) < 0)
                         goto fail;
 
                 service_set_state(s, SERVICE_AUTO_RESTART);
@@ -382,7 +382,7 @@ static void service_enter_dead(Service *s, bool success, bool allow_restart) {
         return;
 
 fail:
-        log_warning("%s failed to run install restart timer: %s", name_id(NAME(s)), strerror(-r));
+        log_warning("%s failed to run install restart timer: %s", unit_id(UNIT(s)), strerror(-r));
         service_enter_dead(s, false, false);
 }
 
@@ -407,7 +407,7 @@ static void service_enter_stop_post(Service *s, bool success) {
         return;
 
 fail:
-        log_warning("%s failed to run stop executable: %s", name_id(NAME(s)), strerror(-r));
+        log_warning("%s failed to run stop executable: %s", unit_id(UNIT(s)), strerror(-r));
         service_enter_signal(s, SERVICE_FINAL_SIGTERM, false);
 }
 
@@ -450,7 +450,7 @@ static void service_enter_signal(Service *s, ServiceState state, bool success) {
         return;
 
 fail:
-        log_warning("%s failed to kill processes: %s", name_id(NAME(s)), strerror(-r));
+        log_warning("%s failed to kill processes: %s", unit_id(UNIT(s)), strerror(-r));
 
         if (sent)  {
                 s->failure = true;
@@ -480,7 +480,7 @@ static void service_enter_stop(Service *s, bool success) {
         return;
 
 fail:
-        log_warning("%s failed to run stop executable: %s", name_id(NAME(s)), strerror(-r));
+        log_warning("%s failed to run stop executable: %s", unit_id(UNIT(s)), strerror(-r));
         service_enter_signal(s, SERVICE_STOP_SIGTERM, false);
 }
 
@@ -500,7 +500,7 @@ static void service_enter_start_post(Service *s) {
         return;
 
 fail:
-        log_warning("%s failed to run start-post executable: %s", name_id(NAME(s)), strerror(-r));
+        log_warning("%s failed to run start-post executable: %s", unit_id(UNIT(s)), strerror(-r));
         service_enter_stop(s, false);
 }
 
@@ -538,7 +538,7 @@ static void service_enter_start(Service *s) {
         return;
 
 fail:
-        log_warning("%s failed to run start exectuable: %s", name_id(NAME(s)), strerror(-r));
+        log_warning("%s failed to run start exectuable: %s", unit_id(UNIT(s)), strerror(-r));
         service_enter_stop(s, false);
 }
 
@@ -559,7 +559,7 @@ static void service_enter_start_pre(Service *s) {
         return;
 
 fail:
-        log_warning("%s failed to run start-pre executable: %s", name_id(NAME(s)), strerror(-r));
+        log_warning("%s failed to run start-pre executable: %s", unit_id(UNIT(s)), strerror(-r));
         service_enter_dead(s, false, true);
 }
 
@@ -567,16 +567,16 @@ static void service_enter_restart(Service *s) {
         int r;
         assert(s);
 
-        if ((r = manager_add_job(NAME(s)->meta.manager, JOB_START, NAME(s), JOB_FAIL, false, NULL)) < 0)
+        if ((r = manager_add_job(UNIT(s)->meta.manager, JOB_START, UNIT(s), JOB_FAIL, false, NULL)) < 0)
                 goto fail;
 
-        log_debug("%s scheduled restart job.", name_id(NAME(s)));
+        log_debug("%s scheduled restart job.", unit_id(UNIT(s)));
         service_enter_dead(s, true, false);
         return;
 
 fail:
 
-        log_warning("%s failed to schedule restart job: %s", name_id(NAME(s)), strerror(-r));
+        log_warning("%s failed to schedule restart job: %s", unit_id(UNIT(s)), strerror(-r));
         service_enter_dead(s, false, false);
 }
 
@@ -597,7 +597,7 @@ static void service_enter_reload(Service *s) {
         return;
 
 fail:
-        log_warning("%s failed to run reload executable: %s", name_id(NAME(s)), strerror(-r));
+        log_warning("%s failed to run reload executable: %s", unit_id(UNIT(s)), strerror(-r));
         service_enter_stop(s, false);
 }
 
@@ -619,7 +619,7 @@ static void service_run_next(Service *s, bool success) {
         return;
 
 fail:
-        log_warning("%s failed to run spawn next executable: %s", name_id(NAME(s)), strerror(-r));
+        log_warning("%s failed to run spawn next executable: %s", unit_id(UNIT(s)), strerror(-r));
 
         if (s->state == SERVICE_STOP)
                 service_enter_stop_post(s, false);
@@ -629,8 +629,8 @@ fail:
                 service_enter_stop(s, false);
 }
 
-static int service_start(Name *n) {
-        Service *s = SERVICE(n);
+static int service_start(Unit *u) {
+        Service *s = SERVICE(u);
 
         assert(s);
 
@@ -659,8 +659,8 @@ static int service_start(Name *n) {
         return 0;
 }
 
-static int service_stop(Name *n) {
-        Service *s = SERVICE(n);
+static int service_stop(Unit *u) {
+        Service *s = SERVICE(u);
 
         assert(s);
 
@@ -681,8 +681,8 @@ static int service_stop(Name *n) {
         return 0;
 }
 
-static int service_reload(Name *n) {
-        Service *s = SERVICE(n);
+static int service_reload(Unit *u) {
+        Service *s = SERVICE(u);
 
         assert(s);
 
@@ -692,18 +692,18 @@ static int service_reload(Name *n) {
         return 0;
 }
 
-static bool service_can_reload(Name *n) {
-        Service *s = SERVICE(n);
+static bool service_can_reload(Unit *u) {
+        Service *s = SERVICE(u);
 
         assert(s);
 
         return !!s->exec_command[SERVICE_EXEC_RELOAD];
 }
 
-static NameActiveState service_active_state(Name *n) {
-        assert(n);
+static UnitActiveState service_active_state(Unit *u) {
+        assert(u);
 
-        return state_table[SERVICE(n)->state];
+        return state_table[SERVICE(u)->state];
 }
 
 static int main_pid_good(Service *s) {
@@ -727,8 +727,8 @@ static bool control_pid_good(Service *s) {
         return s->control_pid > 0;
 }
 
-static void service_sigchld_event(Name *n, pid_t pid, int code, int status) {
-        Service *s = SERVICE(n);
+static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
+        Service *s = SERVICE(u);
         bool success;
 
         assert(s);
@@ -747,7 +747,7 @@ static void service_sigchld_event(Name *n, pid_t pid, int code, int status) {
                         s->exec_command[SERVICE_EXEC_START]->exec_status = s->main_exec_status;
                 }
 
-                log_debug("%s: main process exited, code=%s status=%i", name_id(n), sigchld_code(code), status);
+                log_debug("%s: main process exited, code=%s status=%i", unit_id(u), sigchld_code(code), status);
 
                 /* The service exited, so the service is officially
                  * gone. */
@@ -784,7 +784,7 @@ static void service_sigchld_event(Name *n, pid_t pid, int code, int status) {
                 exec_status_fill(&s->control_command->exec_status, pid, code, status);
                 s->control_pid = 0;
 
-                log_debug("%s: control process exited, code=%s status=%i", name_id(n), sigchld_code(code), status);
+                log_debug("%s: control process exited, code=%s status=%i", unit_id(u), sigchld_code(code), status);
 
                 /* If we are shutting things down anyway we
                  * don't care about failing commands. */
@@ -840,7 +840,7 @@ static void service_sigchld_event(Name *n, pid_t pid, int code, int status) {
                                          * executed. */
 
                                         if ((r = service_load_pid_file(s)) < 0)
-                                                log_warning("%s: failed to load PID file %s: %s", name_id(NAME(s)), s->pid_file, strerror(-r));
+                                                log_warning("%s: failed to load PID file %s: %s", unit_id(UNIT(s)), s->pid_file, strerror(-r));
                                 }
 
                                 /* Fall through */
@@ -888,8 +888,8 @@ static void service_sigchld_event(Name *n, pid_t pid, int code, int status) {
                 assert_not_reached("Got SIGCHLD for unkown PID");
 }
 
-static void service_timer_event(Name *n, int id, uint64_t elapsed) {
-        Service *s = SERVICE(n);
+static void service_timer_event(Unit *u, int id, uint64_t elapsed) {
+        Service *s = SERVICE(u);
 
         assert(s);
         assert(elapsed == 1);
@@ -902,17 +902,17 @@ static void service_timer_event(Name *n, int id, uint64_t elapsed) {
         case SERVICE_START:
         case SERVICE_START_POST:
         case SERVICE_RELOAD:
-                log_warning("%s operation timed out. Stopping.", name_id(n));
+                log_warning("%s operation timed out. Stopping.", unit_id(u));
                 service_enter_stop(s, false);
                 break;
 
         case SERVICE_STOP:
-                log_warning("%s stopping timed out. Terminating.", name_id(n));
+                log_warning("%s stopping timed out. Terminating.", unit_id(u));
                 service_enter_signal(s, SERVICE_STOP_SIGTERM, false);
                 break;
 
         case SERVICE_STOP_SIGTERM:
-                log_warning("%s stopping timed out. Killing.", name_id(n));
+                log_warning("%s stopping timed out. Killing.", unit_id(u));
                 service_enter_signal(s, SERVICE_STOP_SIGKILL, false);
                 break;
 
@@ -921,27 +921,27 @@ static void service_timer_event(Name *n, int id, uint64_t elapsed) {
                  * Must be something we cannot kill, so let's just be
                  * weirded out and continue */
 
-                log_warning("%s still around after SIGKILL. Ignoring.", name_id(n));
+                log_warning("%s still around after SIGKILL. Ignoring.", unit_id(u));
                 service_enter_stop_post(s, false);
                 break;
 
         case SERVICE_STOP_POST:
-                log_warning("%s stopping timed out (2). Terminating.", name_id(n));
+                log_warning("%s stopping timed out (2). Terminating.", unit_id(u));
                 service_enter_signal(s, SERVICE_FINAL_SIGTERM, false);
                 break;
 
         case SERVICE_FINAL_SIGTERM:
-                log_warning("%s stopping timed out (2). Killing.", name_id(n));
+                log_warning("%s stopping timed out (2). Killing.", unit_id(u));
                 service_enter_signal(s, SERVICE_FINAL_SIGKILL, false);
                 break;
 
         case SERVICE_FINAL_SIGKILL:
-                log_warning("%s still around after SIGKILL (2). Entering maintainance mode.", name_id(n));
+                log_warning("%s still around after SIGKILL (2). Entering maintainance mode.", unit_id(u));
                 service_enter_dead(s, false, true);
                 break;
 
         case SERVICE_AUTO_RESTART:
-                log_debug("%s holdoff time over, scheduling restart.", name_id(n));
+                log_debug("%s holdoff time over, scheduling restart.", unit_id(u));
                 service_enter_restart(s);
                 break;
 
@@ -950,7 +950,7 @@ static void service_timer_event(Name *n, int id, uint64_t elapsed) {
         }
 }
 
-const NameVTable service_vtable = {
+const UnitVTable service_vtable = {
         .suffix = ".service",
 
         .init = service_init,
index 41dabff..17bcd2a 100644 (file)
--- a/service.h
+++ b/service.h
@@ -5,7 +5,7 @@
 
 typedef struct Service Service;
 
-#include "name.h"
+#include "unit.h"
 
 typedef enum ServiceState {
         SERVICE_DEAD,
@@ -73,6 +73,6 @@ struct Service {
         int timer_id;
 };
 
-const NameVTable service_vtable;
+const UnitVTable service_vtable;
 
 #endif
index 8fd819e..3e55075 100644 (file)
@@ -1,21 +1,21 @@
 /*-*- Mode: C; c-basic-offset: 8 -*-*/
 
-#include "name.h"
+#include "unit.h"
 #include "snapshot.h"
 
-static void snapshot_done(Name *n) {
-        Snapshot *s = SNAPSHOT(n);
+static void snapshot_done(Unit *u) {
+        Snapshot *s = SNAPSHOT(u);
 
         assert(s);
 
         /* Nothing here for now */
 }
 
-static NameActiveState snapshot_active_state(Name *n) {
-        return SNAPSHOT(n)->state == SNAPSHOT_DEAD ? NAME_INACTIVE : NAME_ACTIVE;
+static UnitActiveState snapshot_active_state(Unit *u) {
+        return SNAPSHOT(u)->state == SNAPSHOT_DEAD ? UNIT_INACTIVE : UNIT_ACTIVE;
 }
 
-const NameVTable snapshot_vtable = {
+const UnitVTable snapshot_vtable = {
         .suffix = ".snapshot",
 
         .done = snapshot_done,
index 8d35e17..563af41 100644 (file)
@@ -5,7 +5,7 @@
 
 typedef struct Snapshot Snapshot;
 
-#include "name.h"
+#include "unit.h"
 
 typedef enum SnapshotState {
         SNAPSHOT_DEAD,
@@ -19,6 +19,6 @@ struct Snapshot {
         bool cleanup:1;
 };
 
-extern const NameVTable snapshot_vtable;
+extern const UnitVTable snapshot_vtable;
 
 #endif
index 23e347d..3d02f41 100644 (file)
--- a/socket.c
+++ b/socket.c
@@ -8,27 +8,27 @@
 #include <sys/poll.h>
 #include <signal.h>
 
-#include "name.h"
+#include "unit.h"
 #include "socket.h"
 #include "log.h"
 
-static const NameActiveState state_table[_SOCKET_STATE_MAX] = {
-        [SOCKET_DEAD] = NAME_INACTIVE,
-        [SOCKET_START_PRE] = NAME_ACTIVATING,
-        [SOCKET_START_POST] = NAME_ACTIVATING,
-        [SOCKET_LISTENING] = NAME_ACTIVE,
-        [SOCKET_RUNNING] = NAME_ACTIVE,
-        [SOCKET_STOP_PRE] = NAME_DEACTIVATING,
-        [SOCKET_STOP_PRE_SIGTERM] = NAME_DEACTIVATING,
-        [SOCKET_STOP_PRE_SIGKILL] = NAME_DEACTIVATING,
-        [SOCKET_STOP_POST] = NAME_DEACTIVATING,
-        [SOCKET_STOP_POST_SIGTERM] = NAME_DEACTIVATING,
-        [SOCKET_STOP_POST_SIGKILL] = NAME_DEACTIVATING,
-        [SOCKET_MAINTAINANCE] = NAME_INACTIVE,
+static const UnitActiveState state_table[_SOCKET_STATE_MAX] = {
+        [SOCKET_DEAD] = UNIT_INACTIVE,
+        [SOCKET_START_PRE] = UNIT_ACTIVATING,
+        [SOCKET_START_POST] = UNIT_ACTIVATING,
+        [SOCKET_LISTENING] = UNIT_ACTIVE,
+        [SOCKET_RUNNING] = UNIT_ACTIVE,
+        [SOCKET_STOP_PRE] = UNIT_DEACTIVATING,
+        [SOCKET_STOP_PRE_SIGTERM] = UNIT_DEACTIVATING,
+        [SOCKET_STOP_PRE_SIGKILL] = UNIT_DEACTIVATING,
+        [SOCKET_STOP_POST] = UNIT_DEACTIVATING,
+        [SOCKET_STOP_POST_SIGTERM] = UNIT_DEACTIVATING,
+        [SOCKET_STOP_POST_SIGKILL] = UNIT_DEACTIVATING,
+        [SOCKET_MAINTAINANCE] = UNIT_INACTIVE,
 };
 
-static void socket_done(Name *n) {
-        Socket *s = SOCKET(n);
+static void socket_done(Unit *u) {
+        Socket *s = SOCKET(u);
         SocketPort *p;
 
         assert(s);
@@ -47,17 +47,17 @@ static void socket_done(Name *n) {
         s->control_command = NULL;
 
         if (s->control_pid > 0) {
-                name_unwatch_pid(n, s->control_pid);
+                unit_unwatch_pid(u, s->control_pid);
                 s->control_pid = 0;
         }
 
         s->service = NULL;
 
-        name_unwatch_timer(n, &s->timer_id);
+        unit_unwatch_timer(u, &s->timer_id);
 }
 
-static int socket_init(Name *n) {
-        Socket *s = SOCKET(n);
+static int socket_init(Unit *u) {
+        Socket *s = SOCKET(u);
         char *t;
         int r;
 
@@ -71,27 +71,27 @@ static int socket_init(Name *n) {
         s->timeout_usec = DEFAULT_TIMEOUT_USEC;
         exec_context_init(&s->exec_context);
 
-        if ((r = name_load_fragment_and_dropin(n)) < 0)
+        if ((r = unit_load_fragment_and_dropin(u)) < 0)
                 goto fail;
 
-        if (!(t = name_change_suffix(name_id(n), ".service"))) {
+        if (!(t = unit_name_change_suffix(unit_id(u), ".service"))) {
                 r = -ENOMEM;
                 goto fail;
         }
 
-        r = manager_load_name(n->meta.manager, t, (Name**) &s->service);
+        r = manager_load_unit(u->meta.manager, t, (Unit**) &s->service);
         free(t);
 
         if (r < 0)
                 goto fail;
 
-        if ((r = name_add_dependency(n, NAME_BEFORE, NAME(s->service))) < 0)
+        if ((r = unit_add_dependency(u, UNIT_BEFORE, UNIT(s->service))) < 0)
                 goto fail;
 
         return 0;
 
 fail:
-        socket_done(n);
+        socket_done(u);
         return r;
 }
 
@@ -108,7 +108,7 @@ static const char* listen_lookup(int type) {
         return NULL;
 }
 
-static void socket_dump(Name *n, FILE *f, const char *prefix) {
+static void socket_dump(Unit *u, FILE *f, const char *prefix) {
 
         static const char* const state_table[_SOCKET_STATE_MAX] = {
                 [SOCKET_DEAD] = "dead",
@@ -133,7 +133,7 @@ static void socket_dump(Name *n, FILE *f, const char *prefix) {
         };
 
         SocketExecCommand c;
-        Socket *s = SOCKET(n);
+        Socket *s = SOCKET(u);
         SocketPort *p;
 
         assert(s);
@@ -183,7 +183,7 @@ static void socket_close_fds(Socket *s) {
                 if (p->fd < 0)
                         continue;
 
-                name_unwatch_fd(NAME(s), p->fd);
+                unit_unwatch_fd(UNIT(s), p->fd);
                 assert_se(close_nointr(p->fd) >= 0);
 
                 p->fd = -1;
@@ -250,7 +250,7 @@ static void socket_unwatch_fds(Socket *s) {
                 if (p->fd < 0)
                         continue;
 
-                name_unwatch_fd(NAME(s), p->fd);
+                unit_unwatch_fd(UNIT(s), p->fd);
         }
 }
 
@@ -264,7 +264,7 @@ static int socket_watch_fds(Socket *s) {
                 if (p->fd < 0)
                         continue;
 
-                if ((r = name_watch_fd(NAME(s), p->fd, POLLIN)) < 0)
+                if ((r = unit_watch_fd(UNIT(s), p->fd, POLLIN)) < 0)
                         goto fail;
         }
 
@@ -290,7 +290,7 @@ static void socket_set_state(Socket *s, SocketState state) {
             state != SOCKET_STOP_POST &&
             state != SOCKET_STOP_POST_SIGTERM &&
             state != SOCKET_STOP_POST_SIGKILL)
-                name_unwatch_timer(NAME(s), &s->timer_id);
+                unit_unwatch_timer(UNIT(s), &s->timer_id);
 
         if (state != SOCKET_START_PRE &&
             state != SOCKET_START_POST &&
@@ -301,7 +301,7 @@ static void socket_set_state(Socket *s, SocketState state) {
             state != SOCKET_STOP_POST_SIGTERM &&
             state != SOCKET_STOP_POST_SIGKILL)
                 if (s->control_pid >= 0) {
-                        name_unwatch_pid(NAME(s), s->control_pid);
+                        unit_unwatch_pid(UNIT(s), s->control_pid);
                         s->control_pid = 0;
                 }
 
@@ -322,7 +322,7 @@ static void socket_set_state(Socket *s, SocketState state) {
         if (state != SOCKET_LISTENING)
                 socket_unwatch_fds(s);
 
-        name_notify(NAME(s), state_table[old_state], state_table[s->state]);
+        unit_notify(UNIT(s), state_table[old_state], state_table[s->state]);
 }
 
 static int socket_spawn(Socket *s, ExecCommand *c, bool timeout, pid_t *_pid) {
@@ -334,15 +334,15 @@ static int socket_spawn(Socket *s, ExecCommand *c, bool timeout, pid_t *_pid) {
         assert(_pid);
 
         if (timeout) {
-                if ((r = name_watch_timer(NAME(s), s->timeout_usec, &s->timer_id)) < 0)
+                if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_id)) < 0)
                         goto fail;
         } else
-                name_unwatch_timer(NAME(s), &s->timer_id);
+                unit_unwatch_timer(UNIT(s), &s->timer_id);
 
         if ((r = exec_spawn(c, &s->exec_context, NULL, 0, &pid)) < 0)
                 goto fail;
 
-        if ((r = name_watch_pid(NAME(s), pid)) < 0)
+        if ((r = unit_watch_pid(UNIT(s), pid)) < 0)
                 /* FIXME: we need to do something here */
                 goto fail;
 
@@ -352,7 +352,7 @@ static int socket_spawn(Socket *s, ExecCommand *c, bool timeout, pid_t *_pid) {
 
 fail:
         if (timeout)
-                name_unwatch_timer(NAME(s), &s->timer_id);
+                unit_unwatch_timer(UNIT(s), &s->timer_id);
 
         return r;
 }
@@ -385,7 +385,7 @@ static void socket_enter_stop_post(Socket *s, bool success) {
         return;
 
 fail:
-        log_warning("%s failed to run stop-post executable: %s", name_id(NAME(s)), strerror(-r));
+        log_warning("%s failed to run stop-post executable: %s", unit_id(UNIT(s)), strerror(-r));
         socket_enter_dead(s, false);
 }
 
@@ -414,7 +414,7 @@ static void socket_enter_signal(Socket *s, SocketState state, bool success) {
         return;
 
 fail:
-        log_warning("%s failed to kill processes: %s", name_id(NAME(s)), strerror(-r));
+        log_warning("%s failed to kill processes: %s", unit_id(UNIT(s)), strerror(-r));
 
         if (state == SOCKET_STOP_PRE_SIGTERM || state == SOCKET_STOP_PRE_SIGKILL)
                 socket_enter_stop_post(s, false);
@@ -441,7 +441,7 @@ static void socket_enter_stop_pre(Socket *s, bool success) {
         return;
 
 fail:
-        log_warning("%s failed to run stop-pre executable: %s", name_id(NAME(s)), strerror(-r));
+        log_warning("%s failed to run stop-pre executable: %s", unit_id(UNIT(s)), strerror(-r));
         socket_enter_stop_post(s, false);
 }
 
@@ -451,14 +451,14 @@ static void socket_enter_start_post(Socket *s) {
 
         if ((r = socket_open_fds(s)) < 0 ||
             (r = socket_watch_fds(s)) < 0) {
-                log_warning("%s failed to listen on sockets: %s", name_id(NAME(s)), strerror(-r));
+                log_warning("%s failed to listen on sockets: %s", unit_id(UNIT(s)), strerror(-r));
                 goto fail;
         }
 
         if ((s->control_command = s->exec_command[SOCKET_EXEC_START_POST])) {
 
                 if ((r = socket_spawn(s, s->control_command, true, &s->control_pid)) < 0) {
-                        log_warning("%s failed to run start-post executable: %s", name_id(NAME(s)), strerror(-r));
+                        log_warning("%s failed to run start-post executable: %s", unit_id(UNIT(s)), strerror(-r));
                         goto fail;
                 }
 
@@ -488,7 +488,7 @@ static void socket_enter_start_pre(Socket *s) {
         return;
 
 fail:
-        log_warning("%s failed to run start-pre exectuable: %s", name_id(NAME(s)), strerror(-r));
+        log_warning("%s failed to run start-pre exectuable: %s", unit_id(UNIT(s)), strerror(-r));
         socket_enter_dead(s, false);
 }
 
@@ -497,14 +497,14 @@ static void socket_enter_running(Socket *s) {
 
         assert(s);
 
-        if ((r = manager_add_job(NAME(s)->meta.manager, JOB_START, NAME(s->service), JOB_REPLACE, true, NULL)) < 0)
+        if ((r = manager_add_job(UNIT(s)->meta.manager, JOB_START, UNIT(s->service), JOB_REPLACE, true, NULL)) < 0)
                 goto fail;
 
         socket_set_state(s, SOCKET_RUNNING);
         return;
 
 fail:
-        log_warning("%s failed to queue socket startup job: %s", name_id(NAME(s)), strerror(-r));
+        log_warning("%s failed to queue socket startup job: %s", unit_id(UNIT(s)), strerror(-r));
         socket_enter_dead(s, false);
 }
 
@@ -534,8 +534,8 @@ fail:
                 socket_enter_stop_pre(s, false);
 }
 
-static int socket_start(Name *n) {
-        Socket *s = SOCKET(n);
+static int socket_start(Unit *u) {
+        Socket *s = SOCKET(u);
 
         assert(s);
 
@@ -554,7 +554,7 @@ static int socket_start(Name *n) {
                 return 0;
 
         /* Cannot run this without the service being around */
-        if (s->service->meta.load_state != NAME_LOADED)
+        if (s->service->meta.load_state != UNIT_LOADED)
                 return -ENOENT;
 
         assert(s->state == SOCKET_DEAD || s->state == SOCKET_MAINTAINANCE);
@@ -564,8 +564,8 @@ static int socket_start(Name *n) {
         return 0;
 }
 
-static int socket_stop(Name *n) {
-        Socket *s = SOCKET(n);
+static int socket_stop(Unit *u) {
+        Socket *s = SOCKET(u);
 
         assert(s);
 
@@ -581,18 +581,18 @@ static int socket_stop(Name *n) {
         return 0;
 }
 
-static NameActiveState socket_active_state(Name *n) {
-        assert(n);
+static UnitActiveState socket_active_state(Unit *u) {
+        assert(u);
 
-        return state_table[SOCKET(n)->state];
+        return state_table[SOCKET(u)->state];
 }
 
-static void socket_fd_event(Name *n, int fd, uint32_t events) {
-        Socket *s = SOCKET(n);
+static void socket_fd_event(Unit *u, int fd, uint32_t events) {
+        Socket *s = SOCKET(u);
 
         assert(s);
 
-        log_info("Incoming traffic on %s", name_id(n));
+        log_info("Incoming traffic on %s", unit_id(u));
 
         if (events != POLLIN)
                 socket_enter_stop_pre(s, false);
@@ -600,8 +600,8 @@ static void socket_fd_event(Name *n, int fd, uint32_t events) {
         socket_enter_running(s);
 }
 
-static void socket_sigchld_event(Name *n, pid_t pid, int code, int status) {
-        Socket *s = SOCKET(n);
+static void socket_sigchld_event(Unit *u, pid_t pid, int code, int status) {
+        Socket *s = SOCKET(u);
         bool success;
 
         assert(s);
@@ -616,7 +616,7 @@ static void socket_sigchld_event(Name *n, pid_t pid, int code, int status) {
         exec_status_fill(&s->control_command->exec_status, pid, code, status);
         s->control_pid = 0;
 
-        log_debug("%s: control process exited, code=%s status=%i", name_id(n), sigchld_code(code), status);
+        log_debug("%s: control process exited, code=%s status=%i", unit_id(u), sigchld_code(code), status);
 
         if (s->control_command->command_next &&
             (success || (s->state == SOCKET_EXEC_STOP_PRE || s->state == SOCKET_EXEC_STOP_POST)))
@@ -659,8 +659,8 @@ static void socket_sigchld_event(Name *n, pid_t pid, int code, int status) {
         }
 }
 
-static void socket_timer_event(Name *n, int id, uint64_t elapsed) {
-        Socket *s = SOCKET(n);
+static void socket_timer_event(Unit *u, int id, uint64_t elapsed) {
+        Socket *s = SOCKET(u);
 
         assert(s);
         assert(elapsed == 1);
@@ -671,37 +671,37 @@ static void socket_timer_event(Name *n, int id, uint64_t elapsed) {
 
         case SOCKET_START_PRE:
         case SOCKET_START_POST:
-                log_warning("%s operation timed out. Stopping.", name_id(n));
+                log_warning("%s operation timed out. Stopping.", unit_id(u));
                 socket_enter_stop_pre(s, false);
                 break;
 
         case SOCKET_STOP_PRE:
-                log_warning("%s stopping timed out. Terminating.", name_id(n));
+                log_warning("%s stopping timed out. Terminating.", unit_id(u));
                 socket_enter_signal(s, SOCKET_STOP_PRE_SIGTERM, false);
                 break;
 
         case SOCKET_STOP_PRE_SIGTERM:
-                log_warning("%s stopping timed out. Killing.", name_id(n));
+                log_warning("%s stopping timed out. Killing.", unit_id(u));
                 socket_enter_signal(s, SOCKET_STOP_PRE_SIGKILL, false);
                 break;
 
         case SOCKET_STOP_PRE_SIGKILL:
-                log_warning("%s still around after SIGKILL. Ignoring.", name_id(n));
+                log_warning("%s still around after SIGKILL. Ignoring.", unit_id(u));
                 socket_enter_stop_post(s, false);
                 break;
 
         case SOCKET_STOP_POST:
-                log_warning("%s stopping timed out (2). Terminating.", name_id(n));
+                log_warning("%s stopping timed out (2). Terminating.", unit_id(u));
                 socket_enter_signal(s, SOCKET_STOP_POST_SIGTERM, false);
                 break;
 
         case SOCKET_STOP_POST_SIGTERM:
-                log_warning("%s stopping timed out (2). Killing.", name_id(n));
+                log_warning("%s stopping timed out (2). Killing.", unit_id(u));
                 socket_enter_signal(s, SOCKET_STOP_POST_SIGKILL, false);
                 break;
 
         case SOCKET_STOP_POST_SIGKILL:
-                log_warning("%s still around after SIGKILL (2). Entering maintainance mode.", name_id(n));
+                log_warning("%s still around after SIGKILL (2). Entering maintainance mode.", unit_id(u));
                 socket_enter_dead(s, false);
                 break;
 
@@ -742,7 +742,7 @@ int socket_collect_fds(Socket *s, int **fds, unsigned *n_fds) {
         return 0;
 }
 
-const NameVTable socket_vtable = {
+const UnitVTable socket_vtable = {
         .suffix = ".socket",
 
         .init = socket_init,
index 1e651c6..c34689b 100644 (file)
--- a/socket.h
+++ b/socket.h
@@ -5,7 +5,7 @@
 
 typedef struct Socket Socket;
 
-#include "name.h"
+#include "unit.h"
 #include "socket-util.h"
 
 typedef enum SocketState {
@@ -78,6 +78,6 @@ struct Socket {
 /* Called from the service code when collecting fds */
 int socket_collect_fds(Socket *s, int **fds, unsigned *n_fds);
 
-extern const NameVTable socket_vtable;
+extern const UnitVTable socket_vtable;
 
 #endif
index 12a2192..6754676 100644 (file)
--- a/target.c
+++ b/target.c
@@ -1,25 +1,25 @@
 /*-*- Mode: C; c-basic-offset: 8 -*-*/
 
-#include "name.h"
+#include "unit.h"
 #include "target.h"
 #include "load-fragment.h"
 
-static void target_done(Name *n) {
-        Target *m = TARGET(n);
+static void target_done(Unit *u) {
+        Target *m = TARGET(u);
 
         assert(m);
 
         /* Nothing here for now */
 }
 
-static NameActiveState target_active_state(Name *n) {
-        return TARGET(n)->state == TARGET_DEAD ? NAME_INACTIVE : NAME_ACTIVE;
+static UnitActiveState target_active_state(Unit *u) {
+        return TARGET(u)->state == TARGET_DEAD ? UNIT_INACTIVE : UNIT_ACTIVE;
 }
 
-const NameVTable target_vtable = {
+const UnitVTable target_vtable = {
         .suffix = ".target",
 
-        .init = name_load_fragment,
+        .init = unit_load_fragment,
         .done = target_done,
 
         .active_state = target_active_state
index 61f2803..16cd9c4 100644 (file)
--- a/target.h
+++ b/target.h
@@ -5,7 +5,7 @@
 
 typedef struct Target Target;
 
-#include "name.h"
+#include "unit.h"
 
 typedef enum TargetState {
         TARGET_DEAD,
@@ -18,6 +18,6 @@ struct Target {
         TargetState state;
 };
 
-extern const NameVTable target_vtable;
+extern const UnitVTable target_vtable;
 
 #endif
index 53cac92..c14a340 100644 (file)
@@ -9,7 +9,7 @@
 
 int main(int argc, char *argv[]) {
         Manager *m = NULL;
-        Name *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL, *g = NULL, *h = NULL;
+        Unit *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL, *g = NULL, *h = NULL;
         Job *j;
 
         assert_se(chdir("test2") == 0);
@@ -17,10 +17,10 @@ int main(int argc, char *argv[]) {
         assert_se(m = manager_new());
 
         printf("Load1:\n");
-        assert_se(manager_load_name(m, "a.service", &a) == 0);
-        assert_se(manager_load_name(m, "b.service", &b) == 0);
-        assert_se(manager_load_name(m, "c.service", &c) == 0);
-        manager_dump_names(m, stdout, "\t");
+        assert_se(manager_load_unit(m, "a.service", &a) == 0);
+        assert_se(manager_load_unit(m, "b.service", &b) == 0);
+        assert_se(manager_load_unit(m, "c.service", &c) == 0);
+        manager_dump_units(m, stdout, "\t");
 
         printf("Test1: (Trivial)\n");
         assert_se(manager_add_job(m, JOB_START, c, JOB_REPLACE, false, &j) == 0);
@@ -28,9 +28,9 @@ int main(int argc, char *argv[]) {
 
         printf("Load2:\n");
         manager_clear_jobs(m);
-        assert_se(manager_load_name(m, "d.service", &d) == 0);
-        assert_se(manager_load_name(m, "e.service", &e) == 0);
-        manager_dump_names(m, stdout, "\t");
+        assert_se(manager_load_unit(m, "d.service", &d) == 0);
+        assert_se(manager_load_unit(m, "e.service", &e) == 0);
+        manager_dump_units(m, stdout, "\t");
 
         printf("Test2: (Cyclic Order, Unfixable)\n");
         assert_se(manager_add_job(m, JOB_START, d, JOB_REPLACE, false, &j) == -ENOEXEC);
@@ -45,8 +45,8 @@ int main(int argc, char *argv[]) {
         manager_dump_jobs(m, stdout, "\t");
 
         printf("Load3:\n");
-        assert_se(manager_load_name(m, "g.service", &g) == 0);
-        manager_dump_names(m, stdout, "\t");
+        assert_se(manager_load_unit(m, "g.service", &g) == 0);
+        manager_dump_units(m, stdout, "\t");
 
         printf("Test5: (Colliding transaction, fail)\n");
         assert_se(manager_add_job(m, JOB_START, g, JOB_FAIL, false, &j) == -EEXIST);
@@ -67,8 +67,8 @@ int main(int argc, char *argv[]) {
         manager_dump_jobs(m, stdout, "\t");
 
         printf("Load4:\n");
-        assert_se(manager_load_name(m, "h.service", &h) == 0);
-        manager_dump_names(m, stdout, "\t");
+        assert_se(manager_load_unit(m, "h.service", &h) == 0);
+        manager_dump_units(m, stdout, "\t");
 
         printf("Test10: (Unmeargable job type of auxiliary job, fail)\n");
         assert_se(manager_add_job(m, JOB_START, h, JOB_FAIL, false, &j) == 0);
diff --git a/timer.c b/timer.c
index 0c89136..2934620 100644 (file)
--- a/timer.c
+++ b/timer.c
@@ -1,29 +1,29 @@
 /*-*- Mode: C; c-basic-offset: 8 -*-*/
 
-#include "name.h"
+#include "unit.h"
 #include "timer.h"
 
-static void timer_done(Name *n) {
-        Timer *t = TIMER(n);
+static void timer_done(Unit *u) {
+        Timer *t = TIMER(u);
 
         assert(t);
 }
 
-static NameActiveState timer_active_state(Name *n) {
+static UnitActiveState timer_active_state(Unit *u) {
 
-        static const NameActiveState table[_TIMER_STATE_MAX] = {
-                [TIMER_DEAD] = NAME_INACTIVE,
-                [TIMER_WAITING] = NAME_ACTIVE,
-                [TIMER_RUNNING] = NAME_ACTIVE
+        static const UnitActiveState table[_TIMER_STATE_MAX] = {
+                [TIMER_DEAD] = UNIT_INACTIVE,
+                [TIMER_WAITING] = UNIT_ACTIVE,
+                [TIMER_RUNNING] = UNIT_ACTIVE
         };
 
-        return table[TIMER(n)->state];
+        return table[TIMER(u)->state];
 }
 
-const NameVTable timer_vtable = {
+const UnitVTable timer_vtable = {
         .suffix = ".timer",
 
-        .init = name_load_fragment_and_dropin,
+        .init = unit_load_fragment_and_dropin,
         .done = timer_done,
 
         .active_state = timer_active_state
diff --git a/timer.h b/timer.h
index fcbddc0..ff9f73c 100644 (file)
--- a/timer.h
+++ b/timer.h
@@ -5,7 +5,7 @@
 
 typedef struct Timer Timer;
 
-#include "name.h"
+#include "unit.h"
 
 typedef enum TimerState {
         TIMER_DEAD,
@@ -25,6 +25,6 @@ struct Timer {
         Service *service;
 };
 
-const NameVTable timer_vtable;
+const UnitVTable timer_vtable;
 
 #endif
diff --git a/unit.c b/unit.c
new file mode 100644 (file)
index 0000000..15401e2
--- /dev/null
+++ b/unit.c
@@ -0,0 +1,807 @@
+/*-*- Mode: C; c-basic-offset: 8 -*-*/
+
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/epoll.h>
+#include <sys/timerfd.h>
+#include <sys/poll.h>
+
+#include "set.h"
+#include "unit.h"
+#include "macro.h"
+#include "strv.h"
+#include "load-fragment.h"
+#include "load-dropin.h"
+#include "log.h"
+
+const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX] = {
+        [UNIT_SERVICE] = &service_vtable,
+        [UNIT_TIMER] = &timer_vtable,
+        [UNIT_SOCKET] = &socket_vtable,
+        [UNIT_TARGET] = &target_vtable,
+        [UNIT_DEVICE] = &device_vtable,
+        [UNIT_MOUNT] = &mount_vtable,
+        [UNIT_AUTOMOUNT] = &automount_vtable,
+        [UNIT_SNAPSHOT] = &snapshot_vtable
+};
+
+UnitType unit_name_to_type(const char *n) {
+        UnitType t;
+
+        assert(n);
+
+        for (t = 0; t < _UNIT_TYPE_MAX; t++)
+                if (endswith(n, unit_vtable[t]->suffix))
+                        return t;
+
+        return _UNIT_TYPE_INVALID;
+}
+
+#define VALID_CHARS                             \
+        "0123456789"                            \
+        "abcdefghijklmnopqrstuvwxyz"            \
+        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"            \
+        "-_"
+
+bool unit_name_is_valid(const char *n) {
+        UnitType t;
+        const char *e, *i;
+
+        assert(n);
+
+        if (strlen(n) >= UNIT_NAME_MAX)
+                return false;
+
+        t = unit_name_to_type(n);
+        if (t < 0 || t >= _UNIT_TYPE_MAX)
+                return false;
+
+        if (!(e = strrchr(n, '.')))
+                return false;
+
+        for (i = n; i < e; i++)
+                if (!strchr(VALID_CHARS, *i))
+                        return false;
+
+        return true;
+}
+
+char *unit_name_change_suffix(const char *n, const char *suffix) {
+        char *e, *r;
+        size_t a, b;
+
+        assert(n);
+        assert(unit_name_is_valid(n));
+        assert(suffix);
+
+        assert_se(e = strrchr(n, '.'));
+        a = e - n;
+        b = strlen(suffix);
+
+        if (!(r = new(char, a + b + 1)))
+                return NULL;
+
+        memcpy(r, n, a);
+        memcpy(r+a, suffix, b+1);
+
+        return r;
+}
+
+Unit *unit_new(Manager *m) {
+        Unit *u;
+
+        assert(m);
+
+        if (!(u = new0(Unit, 1)))
+                return NULL;
+
+        if (!(u->meta.names = set_new(string_hash_func, string_compare_func))) {
+                free(u);
+                return NULL;
+        }
+
+        u->meta.manager = m;
+        u->meta.type = _UNIT_TYPE_INVALID;
+
+        return u;
+}
+
+int unit_add_name(Unit *u, const char *text) {
+        UnitType t;
+        char *s;
+        int r;
+
+        assert(u);
+        assert(text);
+
+        if (!unit_name_is_valid(text))
+                return -EINVAL;
+
+        if ((t = unit_name_to_type(text)) == _UNIT_TYPE_INVALID)
+                return -EINVAL;
+
+        if (u->meta.type != _UNIT_TYPE_INVALID && t != u->meta.type)
+                return -EINVAL;
+
+        if (!(s = strdup(text)))
+                return -ENOMEM;
+
+        if ((r = set_put(u->meta.names, s)) < 0) {
+                free(s);
+
+                if (r == -EEXIST)
+                        return 0;
+
+                return r;
+        }
+
+        if ((r = hashmap_put(u->meta.manager->units, s, u)) < 0) {
+                set_remove(u->meta.names, s);
+                free(s);
+                return r;
+        }
+
+        u->meta.type = t;
+
+        if (!u->meta.id)
+                u->meta.id = s;
+
+        return 0;
+}
+
+void unit_add_to_load_queue(Unit *u) {
+        assert(u);
+
+        if (u->meta.load_state != UNIT_STUB || u->meta.in_load_queue)
+                return;
+
+        LIST_PREPEND(Meta, load_queue, u->meta.manager->load_queue, &u->meta);
+        u->meta.in_load_queue = true;
+}
+
+static void bidi_set_free(Unit *u, Set *s) {
+        Iterator i;
+        Unit *other;
+
+        assert(u);
+
+        /* Frees the set and makes sure we are dropped from the
+         * inverse pointers */
+
+        SET_FOREACH(other, s, i) {
+                UnitDependency d;
+
+                for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
+                        set_remove(other->meta.dependencies[d], u);
+        }
+
+        set_free(s);
+}
+
+void unit_free(Unit *u) {
+        UnitDependency d;
+        Iterator i;
+        char *t;
+
+        assert(u);
+
+        /* Detach from next 'bigger' objects */
+
+        SET_FOREACH(t, u->meta.names, i)
+                hashmap_remove_value(u->meta.manager->units, t, u);
+
+        if (u->meta.in_load_queue)
+                LIST_REMOVE(Meta, load_queue, u->meta.manager->load_queue, &u->meta);
+
+        if (u->meta.load_state == UNIT_LOADED)
+                if (UNIT_VTABLE(u)->done)
+                        UNIT_VTABLE(u)->done(u);
+
+        /* Free data and next 'smaller' objects */
+        if (u->meta.job)
+                job_free(u->meta.job);
+
+        for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
+                bidi_set_free(u, u->meta.dependencies[d]);
+
+        free(u->meta.description);
+
+        while ((t = set_steal_first(u->meta.names)))
+                free(t);
+        set_free(u->meta.names);
+
+        free(u);
+}
+
+UnitActiveState unit_active_state(Unit *u) {
+        assert(u);
+
+        if (u->meta.load_state != UNIT_LOADED)
+                return UNIT_INACTIVE;
+
+        return UNIT_VTABLE(u)->active_state(u);
+}
+
+static int ensure_merge(Set **s, Set *other) {
+
+        if (!other)
+                return 0;
+
+        if (*s)
+                return set_merge(*s, other);
+
+        if (!(*s = set_copy(other)))
+                return -ENOMEM;
+
+        return 0;
+}
+
+/* FIXME: Does not rollback on failure! */
+int unit_merge(Unit *u, Unit *other) {
+        int r;
+        UnitDependency d;
+
+        assert(u);
+        assert(other);
+        assert(u->meta.manager == other->meta.manager);
+
+        /* This merges 'other' into 'unit'. FIXME: This does not
+         * rollback on failure. */
+
+        if (u->meta.type != u->meta.type)
+                return -EINVAL;
+
+        if (u->meta.load_state != UNIT_STUB)
+                return -EINVAL;
+
+        /* Merge names */
+        if ((r = ensure_merge(&u->meta.names, other->meta.names)) < 0)
+                return r;
+
+        /* Merge dependencies */
+        for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
+                /* fixme, the inverse mapping is missing */
+                if ((r = ensure_merge(&u->meta.dependencies[d], other->meta.dependencies[d])) < 0)
+                        return r;
+
+        return 0;
+}
+
+const char* unit_id(Unit *u) {
+        assert(u);
+
+        if (u->meta.id)
+                return u->meta.id;
+
+        return set_first(u->meta.names);
+}
+
+const char *unit_description(Unit *u) {
+        assert(u);
+
+        if (u->meta.description)
+                return u->meta.description;
+
+        return unit_id(u);
+}
+
+void unit_dump(Unit *u, FILE *f, const char *prefix) {
+
+        static const char* const load_state_table[_UNIT_LOAD_STATE_MAX] = {
+                [UNIT_STUB] = "stub",
+                [UNIT_LOADED] = "loaded",
+                [UNIT_FAILED] = "failed"
+        };
+
+        static const char* const active_state_table[_UNIT_ACTIVE_STATE_MAX] = {
+                [UNIT_ACTIVE] = "active",
+                [UNIT_INACTIVE] = "inactive",
+                [UNIT_ACTIVATING] = "activating",
+                [UNIT_DEACTIVATING] = "deactivating"
+        };
+
+        static const char* const dependency_table[_UNIT_DEPENDENCY_MAX] = {
+                [UNIT_REQUIRES] = "Requires",
+                [UNIT_SOFT_REQUIRES] = "SoftRequires",
+                [UNIT_WANTS] = "Wants",
+                [UNIT_REQUISITE] = "Requisite",
+                [UNIT_SOFT_REQUISITE] = "SoftRequisite",
+                [UNIT_REQUIRED_BY] = "RequiredBy",
+                [UNIT_SOFT_REQUIRED_BY] = "SoftRequiredBy",
+                [UNIT_WANTED_BY] = "WantedBy",
+                [UNIT_CONFLICTS] = "Conflicts",
+                [UNIT_BEFORE] = "Before",
+                [UNIT_AFTER] = "After",
+        };
+
+        char *t;
+        UnitDependency d;
+        Iterator i;
+        char *prefix2;
+
+        assert(u);
+
+        if (!prefix)
+                prefix = "";
+        prefix2 = strappend(prefix, "\t");
+        if (!prefix2)
+                prefix2 = "";
+
+        fprintf(f,
+                "%s→ Unit %s:\n"
+                "%s\tDescription: %s\n"
+                "%s\tUnit Load State: %s\n"
+                "%s\tUnit Active State: %s\n",
+                prefix, unit_id(u),
+                prefix, unit_description(u),
+                prefix, load_state_table[u->meta.load_state],
+                prefix, active_state_table[unit_active_state(u)]);
+
+        SET_FOREACH(t, u->meta.names, i)
+                fprintf(f, "%s\tName: %s\n", prefix, t);
+
+        for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++) {
+                Unit *other;
+
+                if (set_isempty(u->meta.dependencies[d]))
+                        continue;
+
+                SET_FOREACH(other, u->meta.dependencies[d], i)
+                        fprintf(f, "%s\t%s: %s\n", prefix, dependency_table[d], unit_id(other));
+        }
+
+        if (UNIT_VTABLE(u)->dump)
+                UNIT_VTABLE(u)->dump(u, f, prefix2);
+
+        if (u->meta.job)
+                job_dump(u->meta.job, f, prefix2);
+
+        free(prefix2);
+}
+
+/* Common implementation for multiple backends */
+int unit_load_fragment_and_dropin(Unit *u) {
+        int r;
+
+        assert(u);
+
+        /* Load a .socket file */
+        if ((r = unit_load_fragment(u)) < 0)
+                return r;
+
+        /* Load drop-in directory data */
+        if ((r = unit_load_dropin(u)) < 0)
+                return r;
+
+        return 0;
+}
+
+int unit_load(Unit *u) {
+        int r;
+
+        assert(u);
+
+        if (u->meta.in_load_queue) {
+                LIST_REMOVE(Meta, load_queue, u->meta.manager->load_queue, &u->meta);
+                u->meta.in_load_queue = false;
+        }
+
+        if (u->meta.load_state != UNIT_STUB)
+                return 0;
+
+        if (UNIT_VTABLE(u)->init)
+                if ((r = UNIT_VTABLE(u)->init(u)) < 0)
+                        goto fail;
+
+        u->meta.load_state = UNIT_LOADED;
+        return 0;
+
+fail:
+        u->meta.load_state = UNIT_FAILED;
+        return r;
+}
+
+/* Errors:
+ *         -EBADR:    This unit type does not support starting.
+ *         -EALREADY: Unit is already started.
+ *         -EAGAIN:   An operation is already in progress. Retry later.
+ */
+int unit_start(Unit *u) {
+        UnitActiveState state;
+
+        assert(u);
+
+        if (!UNIT_VTABLE(u)->start)
+                return -EBADR;
+
+        state = unit_active_state(u);
+        if (UNIT_IS_ACTIVE_OR_RELOADING(state))
+                return -EALREADY;
+
+        /* We don't suppress calls to ->start() here when we are
+         * already starting, to allow this request to be used as a
+         * "hurry up" call, for example when the unit is in some "auto
+         * restart" state where it waits for a holdoff timer to elapse
+         * before it will start again. */
+
+        return UNIT_VTABLE(u)->start(u);
+}
+
+bool unit_can_start(Unit *u) {
+        assert(u);
+
+        return !!UNIT_VTABLE(u)->start;
+}
+
+/* Errors:
+ *         -EBADR:    This unit type does not support stopping.
+ *         -EALREADY: Unit is already stopped.
+ *         -EAGAIN:   An operation is already in progress. Retry later.
+ */
+int unit_stop(Unit *u) {
+        UnitActiveState state;
+
+        assert(u);
+
+        if (!UNIT_VTABLE(u)->stop)
+                return -EBADR;
+
+        state = unit_active_state(u);
+        if (state == UNIT_INACTIVE)
+                return -EALREADY;
+
+        if (state == UNIT_DEACTIVATING)
+                return 0;
+
+        return UNIT_VTABLE(u)->stop(u);
+}
+
+/* Errors:
+ *         -EBADR:    This unit type does not support reloading.
+ *         -ENOEXEC:  Unit is not started.
+ *         -EAGAIN:   An operation is already in progress. Retry later.
+ */
+int unit_reload(Unit *u) {
+        UnitActiveState state;
+
+        assert(u);
+
+        if (!unit_can_reload(u))
+                return -EBADR;
+
+        state = unit_active_state(u);
+        if (unit_active_state(u) == UNIT_ACTIVE_RELOADING)
+                return -EALREADY;
+
+        if (unit_active_state(u) != UNIT_ACTIVE)
+                return -ENOEXEC;
+
+        return UNIT_VTABLE(u)->reload(u);
+}
+
+bool unit_can_reload(Unit *u) {
+        assert(u);
+
+        if (!UNIT_VTABLE(u)->reload)
+                return false;
+
+        if (!UNIT_VTABLE(u)->can_reload)
+                return true;
+
+        return UNIT_VTABLE(u)->can_reload(u);
+}
+
+static void retroactively_start_dependencies(Unit *u) {
+        Iterator i;
+        Unit *other;
+
+        assert(u);
+        assert(UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)));
+
+        SET_FOREACH(other, u->meta.dependencies[UNIT_REQUIRES], i)
+                if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
+                        manager_add_job(u->meta.manager, JOB_START, other, JOB_REPLACE, true, NULL);
+
+        SET_FOREACH(other, u->meta.dependencies[UNIT_SOFT_REQUIRES], i)
+                if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
+                        manager_add_job(u->meta.manager, JOB_START, other, JOB_FAIL, false, NULL);
+
+        SET_FOREACH(other, u->meta.dependencies[UNIT_REQUISITE], i)
+                if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
+                        manager_add_job(u->meta.manager, JOB_START, other, JOB_REPLACE, true, NULL);
+
+        SET_FOREACH(other, u->meta.dependencies[UNIT_WANTS], i)
+                if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
+                        manager_add_job(u->meta.manager, JOB_START, other, JOB_FAIL, false, NULL);
+
+        SET_FOREACH(other, u->meta.dependencies[UNIT_CONFLICTS], i)
+                if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
+                        manager_add_job(u->meta.manager, JOB_STOP, other, JOB_REPLACE, true, NULL);
+}
+
+static void retroactively_stop_dependencies(Unit *u) {
+        Iterator i;
+        Unit *other;
+
+        assert(u);
+        assert(UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(u)));
+
+        SET_FOREACH(other, u->meta.dependencies[UNIT_REQUIRED_BY], i)
+                if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
+                        manager_add_job(u->meta.manager, JOB_STOP, other, JOB_REPLACE, true, NULL);
+}
+
+void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) {
+        assert(u);
+        assert(os < _UNIT_ACTIVE_STATE_MAX);
+        assert(ns < _UNIT_ACTIVE_STATE_MAX);
+        assert(!(os == UNIT_ACTIVE && ns == UNIT_ACTIVATING));
+        assert(!(os == UNIT_INACTIVE && ns == UNIT_DEACTIVATING));
+
+        if (os == ns)
+                return;
+
+        if (!UNIT_IS_ACTIVE_OR_RELOADING(os) && UNIT_IS_ACTIVE_OR_RELOADING(ns))
+                u->meta.active_enter_timestamp = now(CLOCK_REALTIME);
+        else if (UNIT_IS_ACTIVE_OR_RELOADING(os) && !UNIT_IS_ACTIVE_OR_RELOADING(ns))
+                u->meta.active_exit_timestamp = now(CLOCK_REALTIME);
+
+        if (u->meta.job) {
+
+                if (u->meta.job->state == JOB_WAITING)
+
+                        /* So we reached a different state for this
+                         * job. Let's see if we can run it now if it
+                         * failed previously due to EAGAIN. */
+                        job_schedule_run(u->meta.job);
+
+                else {
+                        assert(u->meta.job->state == JOB_RUNNING);
+
+                        /* Let's check of this state change
+                         * constitutes a finished job, or maybe
+                         * cotradicts a running job and hence needs to
+                         * invalidate jobs. */
+
+                        switch (u->meta.job->type) {
+
+                        case JOB_START:
+                        case JOB_VERIFY_ACTIVE:
+
+                                if (UNIT_IS_ACTIVE_OR_RELOADING(ns)) {
+                                        job_finish_and_invalidate(u->meta.job, true);
+                                        return;
+                                } else if (ns == UNIT_ACTIVATING)
+                                        return;
+                                else
+                                        job_finish_and_invalidate(u->meta.job, false);
+
+                                break;
+
+                        case JOB_RELOAD:
+                        case JOB_RELOAD_OR_START:
+
+                                if (ns == UNIT_ACTIVE) {
+                                        job_finish_and_invalidate(u->meta.job, true);
+                                        return;
+                                } else if (ns == UNIT_ACTIVATING || ns == UNIT_ACTIVE_RELOADING)
+                                        return;
+                                else
+                                        job_finish_and_invalidate(u->meta.job, false);
+
+                                break;
+
+                        case JOB_STOP:
+                        case JOB_RESTART:
+                        case JOB_TRY_RESTART:
+
+                                if (ns == UNIT_INACTIVE) {
+                                        job_finish_and_invalidate(u->meta.job, true);
+                                        return;
+                                } else if (ns == UNIT_DEACTIVATING)
+                                        return;
+                                else
+                                        job_finish_and_invalidate(u->meta.job, false);
+
+                                break;
+
+                        default:
+                                assert_not_reached("Job type unknown");
+                        }
+                }
+        }
+
+        /* If this state change happened without being requested by a
+         * job, then let's retroactively start or stop dependencies */
+
+        if (UNIT_IS_INACTIVE_OR_DEACTIVATING(os) && UNIT_IS_ACTIVE_OR_ACTIVATING(ns))
+                retroactively_start_dependencies(u);
+        else if (UNIT_IS_ACTIVE_OR_ACTIVATING(os) && UNIT_IS_INACTIVE_OR_DEACTIVATING(ns))
+                retroactively_stop_dependencies(u);
+}
+
+int unit_watch_fd(Unit *u, int fd, uint32_t events) {
+        struct epoll_event ev;
+
+        assert(u);
+        assert(fd >= 0);
+
+        zero(ev);
+        ev.data.fd = fd;
+        ev.data.ptr = u;
+        ev.data.u32 = MANAGER_FD;
+        ev.events = events;
+
+        if (epoll_ctl(u->meta.manager->epoll_fd, EPOLL_CTL_ADD, fd, &ev) >= 0)
+                return 0;
+
+        if (errno == EEXIST)
+                if (epoll_ctl(u->meta.manager->epoll_fd, EPOLL_CTL_MOD, fd, &ev) >= 0)
+                        return 0;
+
+        return -errno;
+}
+
+void unit_unwatch_fd(Unit *u, int fd) {
+        assert(u);
+        assert(fd >= 0);
+
+        assert_se(epoll_ctl(u->meta.manager->epoll_fd, EPOLL_CTL_DEL, fd, NULL) >= 0 || errno == ENOENT);
+}
+
+int unit_watch_pid(Unit *u, pid_t pid) {
+        assert(u);
+        assert(pid >= 1);
+
+        return hashmap_put(u->meta.manager->watch_pids, UINT32_TO_PTR(pid), u);
+}
+
+void unit_unwatch_pid(Unit *u, pid_t pid) {
+        assert(u);
+        assert(pid >= 1);
+
+        hashmap_remove(u->meta.manager->watch_pids, UINT32_TO_PTR(pid));
+}
+
+int unit_watch_timer(Unit *u, usec_t delay, int *id) {
+        struct epoll_event ev;
+        int fd;
+        struct itimerspec its;
+        int flags;
+        bool ours;
+
+        assert(u);
+        assert(id);
+
+        /* This will try to reuse the old timer if there is one */
+
+        if (*id >= 0) {
+                ours = false;
+                fd = *id;
+
+        } else {
+                ours = true;
+
+                if ((fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC)) < 0)
+                        return -errno;
+        }
+
+        zero(its);
+
+        if (delay <= 0) {
+                /* Set absolute time in the past, but not 0, since we
+                 * don't want to disarm the timer */
+                its.it_value.tv_sec = 0;
+                its.it_value.tv_nsec = 1;
+
+                flags = TFD_TIMER_ABSTIME;
+        } else {
+                timespec_store(&its.it_value, delay);
+                flags = 0;
+        }
+
+        /* This will also flush the elapse counter */
+        if (timerfd_settime(fd, flags, &its, NULL) < 0)
+                goto fail;
+
+        zero(ev);
+        ev.data.fd = fd;
+        ev.data.ptr = u;
+        ev.data.u32 = MANAGER_TIMER;
+        ev.events = POLLIN;
+
+        if (epoll_ctl(u->meta.manager->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0)
+                goto fail;
+
+        *id = fd;
+        return 0;
+
+fail:
+        if (ours)
+                assert_se(close_nointr(fd) == 0);
+
+        return -errno;
+}
+
+void unit_unwatch_timer(Unit *u, int *id) {
+        assert(u);
+        assert(id);
+
+        if (*id < 0)
+                return;
+
+        assert_se(epoll_ctl(u->meta.manager->epoll_fd, EPOLL_CTL_DEL, *id, NULL) >= 0);
+        assert_se(close_nointr(*id) == 0);
+        *id = -1;
+}
+
+bool unit_job_is_applicable(Unit *u, JobType j) {
+        assert(u);
+        assert(j >= 0 && j < _JOB_TYPE_MAX);
+
+        switch (j) {
+
+        case JOB_VERIFY_ACTIVE:
+        case JOB_START:
+                return true;
+
+        case JOB_STOP:
+        case JOB_RESTART:
+        case JOB_TRY_RESTART:
+                return unit_can_start(u);
+
+        case JOB_RELOAD:
+                return unit_can_reload(u);
+
+        case JOB_RELOAD_OR_START:
+                return unit_can_reload(u) && unit_can_start(u);
+
+        default:
+                assert_not_reached("Invalid job type");
+        }
+}
+
+int unit_add_dependency(Unit *u, UnitDependency d, Unit *other) {
+
+        static const UnitDependency inverse_table[_UNIT_DEPENDENCY_MAX] = {
+                [UNIT_REQUIRES] = UNIT_REQUIRED_BY,
+                [UNIT_SOFT_REQUIRES] = UNIT_SOFT_REQUIRED_BY,
+                [UNIT_WANTS] = UNIT_WANTED_BY,
+                [UNIT_REQUISITE] = UNIT_REQUIRED_BY,
+                [UNIT_SOFT_REQUISITE] = UNIT_SOFT_REQUIRED_BY,
+                [UNIT_REQUIRED_BY] = _UNIT_DEPENDENCY_INVALID,
+                [UNIT_SOFT_REQUIRED_BY] = _UNIT_DEPENDENCY_INVALID,
+                [UNIT_WANTED_BY] = _UNIT_DEPENDENCY_INVALID,
+                [UNIT_CONFLICTS] = UNIT_CONFLICTS,
+                [UNIT_BEFORE] = UNIT_AFTER,
+                [UNIT_AFTER] = UNIT_BEFORE
+        };
+        int r;
+
+        assert(u);
+        assert(d >= 0 && d < _UNIT_DEPENDENCY_MAX);
+        assert(inverse_table[d] != _UNIT_DEPENDENCY_INVALID);
+        assert(other);
+
+        /* We won't allow dependencies on ourselves. We will not
+         * consider them an error however. */
+        if (u == other)
+                return 0;
+
+        if ((r = set_ensure_allocated(&u->meta.dependencies[d], trivial_hash_func, trivial_compare_func)) < 0)
+                return r;
+
+        if ((r = set_ensure_allocated(&other->meta.dependencies[inverse_table[d]], trivial_hash_func, trivial_compare_func)) < 0)
+                return r;
+
+        if ((r = set_put(u->meta.dependencies[d], other)) < 0)
+                return r;
+
+        if ((r = set_put(other->meta.dependencies[inverse_table[d]], u)) < 0) {
+                set_remove(u->meta.dependencies[d], other);
+                return r;
+        }
+
+        return 0;
+}
diff --git a/unit.h b/unit.h
new file mode 100644 (file)
index 0000000..7803f31
--- /dev/null
+++ b/unit.h
@@ -0,0 +1,235 @@
+/*-*- Mode: C; c-basic-offset: 8 -*-*/
+
+#ifndef foounithfoo
+#define foounithfoo
+
+#include <stdbool.h>
+#include <stdlib.h>
+
+typedef union Unit Unit;
+typedef struct Meta Meta;
+typedef struct UnitVTable UnitVTable;
+typedef enum UnitType UnitType;
+typedef enum UnitLoadState UnitLoadState;
+typedef enum UnitActiveState UnitActiveState;
+typedef enum UnitDependency UnitDependency;
+
+#include "job.h"
+#include "manager.h"
+#include "set.h"
+#include "util.h"
+#include "list.h"
+#include "socket-util.h"
+#include "execute.h"
+#include "util.h"
+
+#define UNIT_NAME_MAX 32
+#define DEFAULT_TIMEOUT_USEC (20*USEC_PER_SEC)
+#define DEFAULT_RESTART_USEC (100*USEC_PER_MSEC)
+
+enum UnitType {
+        UNIT_SERVICE = 0,
+        UNIT_TIMER,
+        UNIT_SOCKET,
+        UNIT_TARGET,
+        UNIT_DEVICE,
+        UNIT_MOUNT,
+        UNIT_AUTOMOUNT,
+        UNIT_SNAPSHOT,
+        _UNIT_TYPE_MAX,
+        _UNIT_TYPE_INVALID = -1,
+};
+
+enum UnitLoadState {
+        UNIT_STUB,
+        UNIT_LOADED,
+        UNIT_FAILED,
+        _UNIT_LOAD_STATE_MAX
+};
+
+enum UnitActiveState {
+        UNIT_ACTIVE,
+        UNIT_ACTIVE_RELOADING,
+        UNIT_INACTIVE,
+        UNIT_ACTIVATING,
+        UNIT_DEACTIVATING,
+        _UNIT_ACTIVE_STATE_MAX
+};
+
+static inline bool UNIT_IS_ACTIVE_OR_RELOADING(UnitActiveState t) {
+        return t == UNIT_ACTIVE || t == UNIT_ACTIVE_RELOADING;
+}
+
+static inline bool UNIT_IS_ACTIVE_OR_ACTIVATING(UnitActiveState t) {
+        return t == UNIT_ACTIVE || t == UNIT_ACTIVATING || t == UNIT_ACTIVE_RELOADING;
+}
+
+static inline bool UNIT_IS_INACTIVE_OR_DEACTIVATING(UnitActiveState t) {
+        return t == UNIT_INACTIVE || t == UNIT_DEACTIVATING;
+}
+
+enum UnitDependency {
+        /* Positive dependencies */
+        UNIT_REQUIRES,
+        UNIT_SOFT_REQUIRES,
+        UNIT_WANTS,
+        UNIT_REQUISITE,
+        UNIT_SOFT_REQUISITE,
+
+        /* Inverse of the above */
+        UNIT_REQUIRED_BY,       /* inverse of 'requires' and 'requisite' is 'required_by' */
+        UNIT_SOFT_REQUIRED_BY,  /* inverse of 'soft_requires' and 'soft_requisite' is 'soft_required_by' */
+        UNIT_WANTED_BY,         /* inverse of 'wants' */
+
+        /* Negative dependencies */
+        UNIT_CONFLICTS,         /* inverse of 'conflicts' is 'conflicts' */
+
+        /* Order */
+        UNIT_BEFORE,            /* inverse of before is after and vice versa */
+        UNIT_AFTER,
+
+        _UNIT_DEPENDENCY_MAX,
+        _UNIT_DEPENDENCY_INVALID = -1
+};
+
+struct Meta {
+        Manager *manager;
+        UnitType type;
+        UnitLoadState load_state;
+
+        char *id; /* One name is special because we use it for identification. Points to an entry in the names set */
+
+        Set *names;
+        Set *dependencies[_UNIT_DEPENDENCY_MAX];
+
+        char *description;
+
+        /* If there is something to do with this unit, then this is
+         * the job for it */
+        Job *job;
+
+        bool in_load_queue:1;
+
+        usec_t active_enter_timestamp;
+        usec_t active_exit_timestamp;
+
+        /* Load queue */
+        LIST_FIELDS(Meta, load_queue);
+};
+
+#include "service.h"
+#include "timer.h"
+#include "socket.h"
+#include "target.h"
+#include "device.h"
+#include "mount.h"
+#include "automount.h"
+#include "snapshot.h"
+
+union Unit {
+        Meta meta;
+        Service service;
+        Timer timer;
+        Socket socket;
+        Target target;
+        Device device;
+        Mount mount;
+        Automount automount;
+        Snapshot snapshot;
+};
+
+struct UnitVTable {
+        const char *suffix;
+
+        int (*init)(Unit *u);
+        void (*done)(Unit *u);
+
+        void (*dump)(Unit *u, FILE *f, const char *prefix);
+
+        int (*start)(Unit *u);
+        int (*stop)(Unit *u);
+        int (*reload)(Unit *u);
+
+        bool (*can_reload)(Unit *u);
+
+        /* Boils down the more complex internal state of this unit to
+         * a simpler one that the engine can understand */
+        UnitActiveState (*active_state)(Unit *u);
+
+        void (*fd_event)(Unit *u, int fd, uint32_t events);
+        void (*sigchld_event)(Unit *u, pid_t pid, int code, int status);
+        void (*timer_event)(Unit *u, int id, uint64_t n_elapsed);
+
+        void (*retry)(Unit *u);
+};
+
+extern const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX];
+
+#define UNIT_VTABLE(u) unit_vtable[(u)->meta.type]
+
+/* For casting a unit into the various unit types */
+#define DEFINE_CAST(UPPERCASE, MixedCase)                               \
+        static inline MixedCase* UPPERCASE(Unit *u) {                   \
+                if (!u || u->meta.type != UNIT_##UPPERCASE)             \
+                        return NULL;                                    \
+                                                                        \
+                return (MixedCase*) u;                                  \
+        }
+
+/* For casting the various unit types into a unit */
+#define UNIT(u) ((Unit*) (u))
+
+DEFINE_CAST(SOCKET, Socket);
+DEFINE_CAST(TIMER, Timer);
+DEFINE_CAST(SERVICE, Service);
+DEFINE_CAST(TARGET, Target);
+DEFINE_CAST(DEVICE, Device);
+DEFINE_CAST(MOUNT, Mount);
+DEFINE_CAST(AUTOMOUNT, Automount);
+DEFINE_CAST(SNAPSHOT, Snapshot);
+
+UnitType unit_name_to_type(const char *n);
+bool unit_name_is_valid(const char *n);
+char *unit_name_change_suffix(const char *n, const char *suffix);
+
+Unit *unit_new(Manager *m);
+void unit_free(Unit *u);
+
+int unit_add_name(Unit *u, const char *name);
+int unit_add_dependency(Unit *u, UnitDependency d, Unit *other);
+
+void unit_add_to_load_queue(Unit *u);
+
+int unit_merge(Unit *u, Unit *other);
+
+int unit_load_fragment_and_dropin(Unit *u);
+int unit_load(Unit *unit);
+
+const char* unit_id(Unit *u);
+const char *unit_description(Unit *u);
+
+UnitActiveState unit_active_state(Unit *u);
+
+void unit_dump(Unit *u, FILE *f, const char *prefix);
+
+bool unit_can_reload(Unit *u);
+bool unit_can_start(Unit *u);
+
+int unit_start(Unit *u);
+int unit_stop(Unit *u);
+int unit_reload(Unit *u);
+
+void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns);
+
+int unit_watch_fd(Unit *u, int fd, uint32_t events);
+void unit_unwatch_fd(Unit *u, int fd);
+
+int unit_watch_pid(Unit *u, pid_t pid);
+void unit_unwatch_pid(Unit *u, pid_t pid);
+
+int unit_watch_timer(Unit *u, usec_t delay, int *id);
+void unit_unwatch_timer(Unit *u, int *id);
+
+bool unit_job_is_applicable(Unit *u, JobType j);
+
+#endif
diff --git a/util.c b/util.c
index b4b07e9..f752a24 100644 (file)
--- a/util.c
+++ b/util.c
@@ -402,3 +402,44 @@ char *strappend(const char *s, const char *suffix) {
 
         return r;
 }
+
+int readlink_malloc(const char *p, char **r) {
+        size_t l = 100;
+
+        assert(p);
+        assert(r);
+
+        for (;;) {
+                char *c;
+                ssize_t n;
+
+                if (!(c = new(char, l)))
+                        return -ENOMEM;
+
+                if ((n = readlink(p, c, l-1)) < 0) {
+                        int ret = -errno;
+                        free(c);
+                        return ret;
+                }
+
+                if ((size_t) n < l-1) {
+                        c[n] = 0;
+                        *r = c;
+                        return 0;
+                }
+
+                free(c);
+                l *= 2;
+        }
+}
+
+char *file_name_from_path(const char *p) {
+        char *r;
+
+        assert(p);
+
+        if ((r = strrchr(p, '/')))
+                return r + 1;
+
+        return (char*) p;
+}
diff --git a/util.h b/util.h
index 3e86b29..8cc6043 100644 (file)
--- a/util.h
+++ b/util.h
@@ -91,4 +91,8 @@ int read_one_line_file(const char *fn, char **line);
 
 char *strappend(const char *s, const char *suffix);
 
+int readlink_malloc(const char *p, char **r);
+
+char *file_name_from_path(const char *p);
+
 #endif