aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2010-01-29 03:18:09 +0100
committerLennart Poettering <lennart@poettering.net>2010-01-29 03:18:09 +0100
commitf50e0a012340fa8dfe6ec7f0cd869f5f3a052d7a (patch)
tree79ef58ce7acbc8dffcb0af8284a0f4e5922bbe88
parentadd mount enumerator (diff)
downloadsystemd-f50e0a012340fa8dfe6ec7f0cd869f5f3a052d7a.tar.gz
systemd-f50e0a012340fa8dfe6ec7f0cd869f5f3a052d7a.tar.bz2
systemd-f50e0a012340fa8dfe6ec7f0cd869f5f3a052d7a.zip
implement coldpluggin
-rw-r--r--Makefile1
-rw-r--r--automount.c4
-rw-r--r--device.c66
-rw-r--r--job.c9
-rw-r--r--load-fragment.c7
-rw-r--r--load-fstab.c11
-rw-r--r--load-fstab.h12
-rw-r--r--main.c15
-rw-r--r--manager.c82
-rw-r--r--manager.h20
-rw-r--r--mount.c139
-rw-r--r--mount.h3
-rw-r--r--unit.c15
-rw-r--r--unit.h9
14 files changed, 222 insertions, 171 deletions
diff --git a/Makefile b/Makefile
index 22c84db77..d35620e0c 100644
--- a/Makefile
+++ b/Makefile
@@ -21,7 +21,6 @@ COMMON= \
snapshot.o \
socket.o \
timer.o \
- load-fstab.o \
load-dropin.o \
execute.o
diff --git a/automount.c b/automount.c
index eb9c3d3c1..5d4a240aa 100644
--- a/automount.c
+++ b/automount.c
@@ -20,10 +20,6 @@ static int automount_init(Unit *u) {
if ((r = unit_load_fragment(u)) < 0)
return r;
- /* Load entry from /etc/fstab */
- if ((r = unit_load_fstab(u)) < 0)
- return r;
-
/* Load drop-in directory data */
if ((r = unit_load_dropin(u)) < 0)
return r;
diff --git a/device.c b/device.c
index 6d7e2c6fa..34d760a48 100644
--- a/device.c
+++ b/device.c
@@ -8,6 +8,16 @@
#include "strv.h"
#include "log.h"
+static const UnitActiveState state_translation_table[_DEVICE_STATE_MAX] = {
+ [DEVICE_DEAD] = UNIT_INACTIVE,
+ [DEVICE_AVAILABLE] = UNIT_ACTIVE
+};
+
+static const char* const state_string_table[_DEVICE_STATE_MAX] = {
+ [DEVICE_DEAD] = "dead",
+ [DEVICE_AVAILABLE] = "available"
+};
+
static void device_done(Unit *u) {
Device *d = DEVICE(u);
@@ -15,13 +25,31 @@ static void device_done(Unit *u) {
free(d->sysfs);
}
-static void device_dump(Unit *u, FILE *f, const char *prefix) {
+static void device_set_state(Device *d, DeviceState state) {
+ DeviceState old_state;
+ assert(d);
- static const char* const state_table[_DEVICE_STATE_MAX] = {
- [DEVICE_DEAD] = "dead",
- [DEVICE_AVAILABLE] = "available"
- };
+ old_state = d->state;
+ d->state = state;
+ log_debug("%s changed %s → %s", unit_id(UNIT(d)), state_string_table[old_state], state_string_table[state]);
+
+ unit_notify(UNIT(d), state_translation_table[old_state], state_translation_table[state]);
+}
+
+static int device_coldplug(Unit *u) {
+ Device *d = DEVICE(u);
+
+ assert(d);
+ assert(d->state == DEVICE_DEAD);
+
+ if (d->sysfs)
+ device_set_state(d, DEVICE_AVAILABLE);
+
+ return 0;
+}
+
+static void device_dump(Unit *u, FILE *f, const char *prefix) {
Device *d = DEVICE(u);
assert(d);
@@ -29,8 +57,14 @@ static void device_dump(Unit *u, FILE *f, const char *prefix) {
fprintf(f,
"%sDevice State: %s\n"
"%sSysfs Path: %s\n",
- prefix, state_table[d->state],
- prefix, d->sysfs);
+ prefix, state_string_table[d->state],
+ prefix, strna(d->sysfs));
+}
+
+static UnitActiveState device_active_state(Unit *u) {
+ assert(u);
+
+ return state_translation_table[DEVICE(u)->state];
}
static int device_add_escaped_name(Unit *u, const char *prefix, const char *dn, bool make_id) {
@@ -108,11 +142,9 @@ static int device_process_device(Manager *m, struct udev_device *dev) {
}
if ((model = udev_device_get_property_value(dev, "ID_MODEL_FROM_DATABASE")) ||
- (model = udev_device_get_property_value(dev, "ID_MODEL")))
- if (!(u->meta.description = strdup(model))) {
- r = -ENOMEM;
+ (model = udev_device_get_property_value(dev, "ID_MODEL")))
+ if ((r = unit_set_description(u, model)) < 0)
goto fail;
- }
} else {
delete = false;
@@ -229,19 +261,17 @@ fail:
return r;
}
-static UnitActiveState device_active_state(Unit *u) {
- return DEVICE(u)->state == DEVICE_DEAD ? UNIT_INACTIVE : UNIT_ACTIVE;
-}
-
const UnitVTable device_vtable = {
.suffix = ".device",
.init = unit_load_fragment_and_dropin,
.done = device_done,
+ .coldplug = device_coldplug,
+
.dump = device_dump,
- .enumerate = device_enumerate,
- .shutdown = device_shutdown,
+ .active_state = device_active_state,
- .active_state = device_active_state
+ .enumerate = device_enumerate,
+ .shutdown = device_shutdown
};
diff --git a/job.c b/job.c
index ff30864e4..148c7458b 100644
--- a/job.c
+++ b/job.c
@@ -5,6 +5,7 @@
#include "macro.h"
#include "job.h"
+#include "log.h"
Job* job_new(Manager *m, JobType type, Unit *unit) {
Job *j;
@@ -405,10 +406,18 @@ int job_finish_and_invalidate(Job *j, bool success) {
assert(j);
assert(j->installed);
+ log_debug("Job %s/%s finished, success=%s", unit_id(j->unit), job_type_to_string(j->type), yes_no(success));
+
/* Patch restart jobs so that they become normal start jobs */
if (success && (j->type == JOB_RESTART || j->type == JOB_TRY_RESTART)) {
+
+ log_debug("Converting job %s/%s → %s/%s",
+ unit_id(j->unit), job_type_to_string(j->type),
+ unit_id(j->unit), job_type_to_string(JOB_START));
+
j->state = JOB_RUNNING;
j->type = JOB_START;
+
job_schedule_run(j);
return 0;
}
diff --git a/load-fragment.c b/load-fragment.c
index 94bdf171a..0cdaaa204 100644
--- a/load-fragment.c
+++ b/load-fragment.c
@@ -807,10 +807,11 @@ static int load_from_path(Unit *u, const char *path) {
goto finish;
+ if (id == k)
+ unit_choose_id(u, id);
free(k);
}
- unit_choose_id(u, id);
free(u->meta.load_path);
u->meta.load_path = filename;
@@ -860,10 +861,10 @@ int unit_load_fragment(Unit *u) {
/* If syslog or kernel logging is requested, make sure
* our own logging daemon is run first. */
- if ((k = unit_add_dependency(u, UNIT_AFTER, u->meta.manager->special_units[SPECIAL_LOGGER_SOCKET])) < 0)
+ if ((k = unit_add_dependency_by_name(u, UNIT_AFTER, SPECIAL_LOGGER_SOCKET)) < 0)
return k;
- if ((k = unit_add_dependency(u, UNIT_REQUIRES, u->meta.manager->special_units[SPECIAL_LOGGER_SOCKET])) < 0)
+ if ((k = unit_add_dependency_by_name(u, UNIT_REQUIRES, SPECIAL_LOGGER_SOCKET)) < 0)
return k;
}
diff --git a/load-fstab.c b/load-fstab.c
deleted file mode 100644
index d611426ce..000000000
--- a/load-fstab.c
+++ /dev/null
@@ -1,11 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8 -*-*/
-
-#include "load-fstab.h"
-
-int unit_load_fstab(Unit *u) {
- assert(u);
-
- /* Load dependencies from /etc/fstab */
-
- return 0;
-}
diff --git a/load-fstab.h b/load-fstab.h
deleted file mode 100644
index b0cef7ddf..000000000
--- a/load-fstab.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8 -*-*/
-
-#ifndef fooloadfstabhfoo
-#define fooloadfstabhfoo
-
-#include "unit.h"
-
-/* Read service data from /etc/fstab */
-
-int unit_load_fstab(Unit *u);
-
-#endif
diff --git a/main.c b/main.c
index 2486f0629..be733f0cd 100644
--- a/main.c
+++ b/main.c
@@ -21,7 +21,12 @@ int main(int argc, char *argv[]) {
goto finish;
}
- if ((r = manager_load_unit(m, "default.target", &target)) < 0) {
+ if ((r = manager_coldplug(m)) < 0) {
+ log_error("Failed to retrieve coldplug information: %s", strerror(-r));
+ goto finish;
+ }
+
+ if ((r = manager_load_unit(m, SPECIAL_DEFAULT_TARGET, &target)) < 0) {
log_error("Failed to load default target: %s", strerror(-r));
goto finish;
}
@@ -37,10 +42,10 @@ int main(int argc, char *argv[]) {
printf("→ By jobs:\n");
manager_dump_jobs(m, stdout, "\t");
- if ((r = manager_loop(m)) < 0) {
- log_error("Failed to run mainloop: %s", strerror(-r));
- goto finish;
- }
+ /* if ((r = manager_loop(m)) < 0) { */
+ /* log_error("Failed to run mainloop: %s", strerror(-r)); */
+ /* goto finish; */
+ /* } */
retval = 0;
diff --git a/manager.c b/manager.c
index 23d450d33..9355a6a6f 100644
--- a/manager.c
+++ b/manager.c
@@ -17,14 +17,6 @@
#include "log.h"
#include "util.h"
-static const char * const special_table[_SPECIAL_UNIT_MAX] = {
- [SPECIAL_SYSLOG_SERVICE] = "syslog.service",
- [SPECIAL_DBUS_SERVICE] = "messagebus.service",
- [SPECIAL_LOGGER_SOCKET] = "systemd-logger.socket",
- [SPECIAL_KBREQUEST_TARGET] = "kbrequest.target",
- [SPECIAL_CTRL_ALT_DEL_TARGET] = "ctrl-alt-del.target"
-};
-
static int manager_setup_signals(Manager *m) {
sigset_t mask;
struct epoll_event ev;
@@ -58,35 +50,6 @@ static int manager_setup_signals(Manager *m) {
return 0;
}
-static int manager_load_special_units(Manager *m) {
- SpecialUnit c;
- int r;
-
- assert(m);
-
- /* Loads all 'special' units, so that we have easy access to them later */
-
- for (c = 0; c < _SPECIAL_UNIT_MAX; c++)
- if ((r = manager_load_unit(m, special_table[c], m->special_units+c)) < 0)
- return r;
-
- return 0;
-}
-
-static int manager_enumerate(Manager *m) {
- int r;
- UnitType c;
-
- assert(m);
-
- for (c = 0; c < _UNIT_TYPE_MAX; c++)
- if (unit_vtable[c]->enumerate)
- if ((r = unit_vtable[c]->enumerate(m)) < 0)
- return r;
-
- return 0;
-}
-
Manager* manager_new(void) {
Manager *m;
@@ -113,12 +76,6 @@ Manager* manager_new(void) {
if (manager_setup_signals(m) < 0)
goto fail;
- if (manager_load_special_units(m) < 0)
- goto fail;
-
- if (manager_enumerate(m) < 0)
- goto fail;
-
return m;
fail:
@@ -156,6 +113,39 @@ void manager_free(Manager *m) {
free(m);
}
+int manager_coldplug(Manager *m) {
+ int r;
+ UnitType c;
+ Iterator i;
+ Unit *u;
+ char *k;
+
+ assert(m);
+
+ /* First, let's ask every type to load all units from
+ * disk/kernel that it might know */
+ for (c = 0; c < _UNIT_TYPE_MAX; c++)
+ if (unit_vtable[c]->enumerate)
+ if ((r = unit_vtable[c]->enumerate(m)) < 0)
+ return r;
+
+ manager_dispatch_load_queue(m);
+
+ /* Then, let's set up their initial state. */
+ HASHMAP_FOREACH_KEY(u, k, m->units, i) {
+
+ /* ignore aliases */
+ if (unit_id(u) != k)
+ continue;
+
+ if (UNIT_VTABLE(u)->coldplug)
+ if ((r = UNIT_VTABLE(u)->coldplug(u)) < 0)
+ return r;
+ }
+
+ return 0;
+}
+
static void transaction_delete_job(Manager *m, Job *j) {
assert(m);
assert(j);
@@ -874,6 +864,8 @@ int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, bool for
if ((r = transaction_activate(m, mode)) < 0)
return r;
+ log_debug("Enqueued job %s/%s", unit_id(unit), job_type_to_string(type));
+
if (_ret)
*_ret = ret;
@@ -893,7 +885,7 @@ Unit *manager_get_unit(Manager *m, const char *name) {
return hashmap_get(m->units, name);
}
-static void dispatch_load_queue(Manager *m) {
+void manager_dispatch_load_queue(Manager *m) {
Meta *meta;
assert(m);
@@ -951,7 +943,7 @@ int manager_load_unit(Manager *m, const char *path, Unit **_ret) {
}
unit_add_to_load_queue(ret);
- dispatch_load_queue(m);
+ manager_dispatch_load_queue(m);
*_ret = ret;
return 0;
diff --git a/manager.h b/manager.h
index 64c9b8064..793a55fb4 100644
--- a/manager.h
+++ b/manager.h
@@ -30,14 +30,12 @@ struct Watch {
#include "list.h"
#include "set.h"
-typedef enum SpecialUnit {
- SPECIAL_SYSLOG_SERVICE,
- SPECIAL_DBUS_SERVICE,
- SPECIAL_LOGGER_SOCKET,
- SPECIAL_CTRL_ALT_DEL_TARGET,
- SPECIAL_KBREQUEST_TARGET,
- _SPECIAL_UNIT_MAX
-} SpecialUnit;
+#define SPECIAL_DEFAULT_TARGET "default.target"
+#define SPECIAL_SYSLOG_SERVICE "syslog.service"
+#define SPECIAL_DBUS_SERVICE "messagebus.service"
+#define SPECIAL_LOGGER_SOCKET "systemd-logger.socket"
+#define SPECIAL_KBREQUEST_TARGET "kbrequest.target"
+#define SPECIAL_CTRL_ALT_DEL_TARGET "ctrl-alt-del.target"
struct Manager {
uint32_t current_job_id;
@@ -69,14 +67,14 @@ struct Manager {
Watch signal_watch;
- Unit *special_units[_SPECIAL_UNIT_MAX]; /* some special units */
-
struct udev* udev;
};
Manager* manager_new(void);
void manager_free(Manager *m);
+int manager_coldplug(Manager *m);
+
Job *manager_get_job(Manager *m, uint32_t id);
Unit *manager_get_unit(Manager *m, const char *name);
@@ -90,7 +88,9 @@ void manager_transaction_unlink_job(Manager *m, Job *j);
void manager_clear_jobs(Manager *m);
+void manager_dispatch_load_queue(Manager *m);
void manager_dispatch_run_queue(Manager *m);
+
int manager_loop(Manager *m);
#endif
diff --git a/mount.c b/mount.c
index ddf0520ed..d9d461a59 100644
--- a/mount.c
+++ b/mount.c
@@ -7,30 +7,24 @@
#include "unit.h"
#include "mount.h"
#include "load-fragment.h"
-#include "load-fstab.h"
#include "load-dropin.h"
#include "log.h"
-static int mount_init(Unit *u) {
- int r;
- Mount *m = MOUNT(u);
-
- assert(m);
-
- /* Load a .mount file */
- if ((r = unit_load_fragment(u)) < 0)
- return r;
-
- /* Load entry from /etc/fstab */
- if ((r = unit_load_fstab(u)) < 0)
- return r;
-
- /* Load drop-in directory data */
- if ((r = unit_load_dropin(u)) < 0)
- return r;
+static const UnitActiveState state_translation_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 r;
-}
+static const char* const state_string_table[_MOUNT_STATE_MAX] = {
+ [MOUNT_DEAD] = "dead",
+ [MOUNT_MOUNTING] = "mounting",
+ [MOUNT_MOUNTED] = "mounted",
+ [MOUNT_UNMOUNTING] = "unmounting",
+ [MOUNT_MAINTAINANCE] = "maintainance"
+};
static void mount_done(Unit *u) {
Mount *d = MOUNT(u);
@@ -40,16 +34,31 @@ static void mount_done(Unit *u) {
free(d->where);
}
-static void mount_dump(Unit *u, FILE *f, const char *prefix) {
+static void mount_set_state(Mount *m, MountState state) {
+ MountState old_state;
+ assert(m);
+
+ old_state = m->state;
+ m->state = state;
+
+ log_debug("%s changed %s → %s", unit_id(UNIT(m)), state_string_table[old_state], state_string_table[state]);
+
+ unit_notify(UNIT(m), state_translation_table[old_state], state_translation_table[state]);
+}
+
+static int mount_coldplug(Unit *u) {
+ Mount *m = MOUNT(u);
+
+ assert(m);
+ assert(m->state == MOUNT_DEAD);
- static const char* const state_table[_MOUNT_STATE_MAX] = {
- [MOUNT_DEAD] = "dead",
- [MOUNT_MOUNTING] = "mounting",
- [MOUNT_MOUNTED] = "mounted",
- [MOUNT_UNMOUNTING] = "unmounting",
- [MOUNT_MAINTAINANCE] = "maintainance"
- };
+ if (m->from_proc_self_mountinfo)
+ mount_set_state(m, MOUNT_MOUNTED);
+ return 0;
+}
+
+static void mount_dump(Unit *u, FILE *f, const char *prefix) {
Mount *s = MOUNT(u);
assert(s);
@@ -57,10 +66,20 @@ static void mount_dump(Unit *u, FILE *f, const char *prefix) {
fprintf(f,
"%sMount State: %s\n"
"%sWhere: %s\n"
- "%sWhat: %s\n",
- prefix, state_table[s->state],
+ "%sWhat: %s\n"
+ "%sFrom /etc/fstab: %s\n"
+ "%sFrom /proc/self/mountinfo: %s\n",
+ prefix, state_string_table[s->state],
prefix, s->where,
- prefix, s->what);
+ prefix, s->what,
+ prefix, yes_no(s->from_etc_fstab),
+ prefix, yes_no(s->from_proc_self_mountinfo));
+}
+
+static UnitActiveState mount_active_state(Unit *u) {
+ assert(u);
+
+ return state_translation_table[MOUNT(u)->state];
}
static void mount_shutdown(Manager *m) {
@@ -136,12 +155,13 @@ static int mount_add_path_links(Mount *m) {
return 0;
}
-static int mount_add_one(Manager *m, const char *what, const char *where) {
+static int mount_add_one(Manager *m, const char *what, const char *where, bool live) {
char *e;
int r;
Unit *u;
bool delete;
+ assert(m);
assert(what);
assert(where);
@@ -172,16 +192,23 @@ static int mount_add_one(Manager *m, const char *what, const char *where) {
goto fail;
if (!(MOUNT(u)->what = strdup(what)) ||
- !(MOUNT(u)->where = strdup(where)) ||
- !(u->meta.description = strdup(where))) {
- r = -ENOMEM;
+ !(MOUNT(u)->where = strdup(where))) {
+ r = -ENOMEM;
+ goto fail;
+ }
+
+ if ((r = unit_set_description(u, where)) < 0)
goto fail;
- }
} else {
delete = false;
free(e);
}
+ if (live)
+ MOUNT(u)->from_proc_self_mountinfo = true;
+ else
+ MOUNT(u)->from_etc_fstab = true;
+
if ((r = mount_add_node_links(MOUNT(u))) < 0)
goto fail;
@@ -189,6 +216,7 @@ static int mount_add_one(Manager *m, const char *what, const char *where) {
goto fail;
unit_add_to_load_queue(u);
+
return 0;
fail:
@@ -207,10 +235,10 @@ static char *fstab_node_to_udev_node(char *p) {
if (startswith(p, "LABEL=")) {
- if (!(t = strdup(p+6)))
+ if (!(t = xescape(p+6, "/ ")))
return NULL;
- r = asprintf(&dn, "/dev/disk/by-label/%s", xescape(t, "/ "));
+ r = asprintf(&dn, "/dev/disk/by-label/%s", t);
free(t);
if (r < 0)
@@ -221,10 +249,10 @@ static char *fstab_node_to_udev_node(char *p) {
if (startswith(p, "UUID=")) {
- if (!(t = strdup(p+5)))
+ if (!(t = xescape(p+5, "/ ")))
return NULL;
- r = asprintf(&dn, "/dev/disk/by-uuid/%s", ascii_strlower(xescape(t, "/ ")));
+ r = asprintf(&dn, "/dev/disk/by-uuid/%s", ascii_strlower(t));
free(t);
if (r < 0)
@@ -267,7 +295,7 @@ static int mount_load_etc_fstab(Manager *m) {
if (where[0] == '/')
path_kill_slashes(where);
- r = mount_add_one(m, what, where);
+ r = mount_add_one(m, what, where, false);
free(what);
free(where);
@@ -282,7 +310,7 @@ finish:
return r;
}
-static int mount_load_proc_mounts(Manager *m) {
+static int mount_load_proc_self_mountinfo(Manager *m) {
FILE *f;
int r;
@@ -338,7 +366,7 @@ static int mount_load_proc_mounts(Manager *m) {
}
free(path);
- r = mount_add_one(m, d, p);
+ r = mount_add_one(m, d, p, true);
free(d);
free(p);
@@ -361,7 +389,7 @@ static int mount_enumerate(Manager *m) {
if ((r = mount_load_etc_fstab(m)) < 0)
goto fail;
- if ((r = mount_load_proc_mounts(m)) < 0)
+ if ((r = mount_load_proc_self_mountinfo(m)) < 0)
goto fail;
return 0;
@@ -371,28 +399,17 @@ fail:
return r;
}
-static UnitActiveState mount_active_state(Unit *u) {
-
- 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(u)->state];
-}
-
const UnitVTable mount_vtable = {
.suffix = ".mount",
- .init = mount_init,
+ .init = unit_load_fragment_and_dropin,
.done = mount_done,
+ .coldplug = mount_coldplug,
+
.dump = mount_dump,
- .enumerate = mount_enumerate,
- .shutdown = mount_shutdown,
+ .active_state = mount_active_state,
- .active_state = mount_active_state
+ .enumerate = mount_enumerate,
+ .shutdown = mount_shutdown
};
diff --git a/mount.h b/mount.h
index 5b5d5a38c..9a8079f48 100644
--- a/mount.h
+++ b/mount.h
@@ -22,6 +22,9 @@ struct Mount {
MountState state;
char *what, *where;
+
+ bool from_etc_fstab:1;
+ bool from_proc_self_mountinfo:1;
};
extern const UnitVTable mount_vtable;
diff --git a/unit.c b/unit.c
index 7723393db..7954c0418 100644
--- a/unit.c
+++ b/unit.c
@@ -170,6 +170,19 @@ int unit_choose_id(Unit *u, const char *name) {
return 0;
}
+int unit_set_description(Unit *u, const char *description) {
+ char *s;
+
+ assert(u);
+
+ if (!(s = strdup(description)))
+ return -ENOMEM;
+
+ free(u->meta.description);
+ u->meta.description = s;
+ return 0;
+}
+
void unit_add_to_load_queue(Unit *u) {
assert(u);
@@ -586,7 +599,7 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) {
else {
assert(u->meta.job->state == JOB_RUNNING);
- /* Let's check of this state change
+ /* Let's check whether this state change
* constitutes a finished job, or maybe
* cotradicts a running job and hence needs to
* invalidate jobs. */
diff --git a/unit.h b/unit.h
index 0cd09fe5a..3e42ebe90 100644
--- a/unit.h
+++ b/unit.h
@@ -144,6 +144,7 @@ struct UnitVTable {
int (*init)(Unit *u);
void (*done)(Unit *u);
+ int (*coldplug)(Unit *u);
void (*dump)(Unit *u, FILE *f, const char *prefix);
@@ -161,7 +162,14 @@ struct UnitVTable {
void (*sigchld_event)(Unit *u, pid_t pid, int code, int status);
void (*timer_event)(Unit *u, uint64_t n_elapsed, Watch *w);
+ /* This is called for each unit type and should be used to
+ * enumerate existing devices and load them. However,
+ * everything that is loaded here should still stay in
+ * inactive state. It is the job of the coldplug() call above
+ * to put the units into the initial state. */
int (*enumerate)(Manager *m);
+
+ /* Type specific cleanups. */
void (*shutdown)(Manager *m);
};
@@ -202,6 +210,7 @@ int unit_add_dependency(Unit *u, UnitDependency d, Unit *other);
int unit_add_dependency_by_name(Unit *u, UnitDependency d, const char *name);
int unit_choose_id(Unit *u, const char *name);
+int unit_set_description(Unit *u, const char *description);
void unit_add_to_load_queue(Unit *u);