implement coldpluggin

This commit is contained in:
Lennart Poettering 2010-01-29 03:18:09 +01:00
parent b08d03ffe5
commit f50e0a0123
14 changed files with 224 additions and 173 deletions

View File

@ -21,7 +21,6 @@ COMMON= \
snapshot.o \ snapshot.o \
socket.o \ socket.o \
timer.o \ timer.o \
load-fstab.o \
load-dropin.o \ load-dropin.o \
execute.o execute.o

View File

@ -20,10 +20,6 @@ static int automount_init(Unit *u) {
if ((r = unit_load_fragment(u)) < 0) if ((r = unit_load_fragment(u)) < 0)
return r; return r;
/* Load entry from /etc/fstab */
if ((r = unit_load_fstab(u)) < 0)
return r;
/* Load drop-in directory data */ /* Load drop-in directory data */
if ((r = unit_load_dropin(u)) < 0) if ((r = unit_load_dropin(u)) < 0)
return r; return r;

View File

@ -8,6 +8,16 @@
#include "strv.h" #include "strv.h"
#include "log.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) { static void device_done(Unit *u) {
Device *d = DEVICE(u); Device *d = DEVICE(u);
@ -15,13 +25,31 @@ static void device_done(Unit *u) {
free(d->sysfs); free(d->sysfs);
} }
static void device_set_state(Device *d, DeviceState state) {
DeviceState old_state;
assert(d);
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) { 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 *d = DEVICE(u); Device *d = DEVICE(u);
assert(d); assert(d);
@ -29,8 +57,14 @@ static void device_dump(Unit *u, FILE *f, const char *prefix) {
fprintf(f, fprintf(f,
"%sDevice State: %s\n" "%sDevice State: %s\n"
"%sSysfs Path: %s\n", "%sSysfs Path: %s\n",
prefix, state_table[d->state], prefix, state_string_table[d->state],
prefix, d->sysfs); 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) { 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")) || if ((model = udev_device_get_property_value(dev, "ID_MODEL_FROM_DATABASE")) ||
(model = udev_device_get_property_value(dev, "ID_MODEL"))) (model = udev_device_get_property_value(dev, "ID_MODEL")))
if (!(u->meta.description = strdup(model))) { if ((r = unit_set_description(u, model)) < 0)
r = -ENOMEM;
goto fail; goto fail;
}
} else { } else {
delete = false; delete = false;
@ -229,19 +261,17 @@ fail:
return r; return r;
} }
static UnitActiveState device_active_state(Unit *u) {
return DEVICE(u)->state == DEVICE_DEAD ? UNIT_INACTIVE : UNIT_ACTIVE;
}
const UnitVTable device_vtable = { const UnitVTable device_vtable = {
.suffix = ".device", .suffix = ".device",
.init = unit_load_fragment_and_dropin, .init = unit_load_fragment_and_dropin,
.done = device_done, .done = device_done,
.coldplug = device_coldplug,
.dump = device_dump, .dump = device_dump,
.enumerate = device_enumerate, .active_state = device_active_state,
.shutdown = device_shutdown,
.active_state = device_active_state .enumerate = device_enumerate,
.shutdown = device_shutdown
}; };

9
job.c
View File

@ -5,6 +5,7 @@
#include "macro.h" #include "macro.h"
#include "job.h" #include "job.h"
#include "log.h"
Job* job_new(Manager *m, JobType type, Unit *unit) { Job* job_new(Manager *m, JobType type, Unit *unit) {
Job *j; Job *j;
@ -405,10 +406,18 @@ int job_finish_and_invalidate(Job *j, bool success) {
assert(j); assert(j);
assert(j->installed); 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 */ /* Patch restart jobs so that they become normal start jobs */
if (success && (j->type == JOB_RESTART || j->type == JOB_TRY_RESTART)) { 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->state = JOB_RUNNING;
j->type = JOB_START; j->type = JOB_START;
job_schedule_run(j); job_schedule_run(j);
return 0; return 0;
} }

View File

@ -807,10 +807,11 @@ static int load_from_path(Unit *u, const char *path) {
goto finish; goto finish;
if (id == k)
unit_choose_id(u, id);
free(k); free(k);
} }
unit_choose_id(u, id);
free(u->meta.load_path); free(u->meta.load_path);
u->meta.load_path = filename; u->meta.load_path = filename;
@ -860,10 +861,10 @@ int unit_load_fragment(Unit *u) {
/* If syslog or kernel logging is requested, make sure /* If syslog or kernel logging is requested, make sure
* our own logging daemon is run first. */ * 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; 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; return k;
} }

View File

@ -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;
}

View File

@ -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

15
main.c
View File

@ -21,7 +21,12 @@ int main(int argc, char *argv[]) {
goto finish; 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)); log_error("Failed to load default target: %s", strerror(-r));
goto finish; goto finish;
} }
@ -37,10 +42,10 @@ int main(int argc, char *argv[]) {
printf("→ By jobs:\n"); printf("→ By jobs:\n");
manager_dump_jobs(m, stdout, "\t"); manager_dump_jobs(m, stdout, "\t");
if ((r = manager_loop(m)) < 0) { /* if ((r = manager_loop(m)) < 0) { */
log_error("Failed to run mainloop: %s", strerror(-r)); /* log_error("Failed to run mainloop: %s", strerror(-r)); */
goto finish; /* goto finish; */
} /* } */
retval = 0; retval = 0;

View File

@ -17,14 +17,6 @@
#include "log.h" #include "log.h"
#include "util.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) { static int manager_setup_signals(Manager *m) {
sigset_t mask; sigset_t mask;
struct epoll_event ev; struct epoll_event ev;
@ -58,35 +50,6 @@ static int manager_setup_signals(Manager *m) {
return 0; 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* manager_new(void) {
Manager *m; Manager *m;
@ -113,12 +76,6 @@ Manager* manager_new(void) {
if (manager_setup_signals(m) < 0) if (manager_setup_signals(m) < 0)
goto fail; goto fail;
if (manager_load_special_units(m) < 0)
goto fail;
if (manager_enumerate(m) < 0)
goto fail;
return m; return m;
fail: fail:
@ -156,6 +113,39 @@ void manager_free(Manager *m) {
free(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) { static void transaction_delete_job(Manager *m, Job *j) {
assert(m); assert(m);
assert(j); 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) if ((r = transaction_activate(m, mode)) < 0)
return r; return r;
log_debug("Enqueued job %s/%s", unit_id(unit), job_type_to_string(type));
if (_ret) if (_ret)
*_ret = ret; *_ret = ret;
@ -893,7 +885,7 @@ Unit *manager_get_unit(Manager *m, const char *name) {
return hashmap_get(m->units, name); return hashmap_get(m->units, name);
} }
static void dispatch_load_queue(Manager *m) { void manager_dispatch_load_queue(Manager *m) {
Meta *meta; Meta *meta;
assert(m); assert(m);
@ -951,7 +943,7 @@ int manager_load_unit(Manager *m, const char *path, Unit **_ret) {
} }
unit_add_to_load_queue(ret); unit_add_to_load_queue(ret);
dispatch_load_queue(m); manager_dispatch_load_queue(m);
*_ret = ret; *_ret = ret;
return 0; return 0;

View File

@ -30,14 +30,12 @@ struct Watch {
#include "list.h" #include "list.h"
#include "set.h" #include "set.h"
typedef enum SpecialUnit { #define SPECIAL_DEFAULT_TARGET "default.target"
SPECIAL_SYSLOG_SERVICE, #define SPECIAL_SYSLOG_SERVICE "syslog.service"
SPECIAL_DBUS_SERVICE, #define SPECIAL_DBUS_SERVICE "messagebus.service"
SPECIAL_LOGGER_SOCKET, #define SPECIAL_LOGGER_SOCKET "systemd-logger.socket"
SPECIAL_CTRL_ALT_DEL_TARGET, #define SPECIAL_KBREQUEST_TARGET "kbrequest.target"
SPECIAL_KBREQUEST_TARGET, #define SPECIAL_CTRL_ALT_DEL_TARGET "ctrl-alt-del.target"
_SPECIAL_UNIT_MAX
} SpecialUnit;
struct Manager { struct Manager {
uint32_t current_job_id; uint32_t current_job_id;
@ -69,14 +67,14 @@ struct Manager {
Watch signal_watch; Watch signal_watch;
Unit *special_units[_SPECIAL_UNIT_MAX]; /* some special units */
struct udev* udev; struct udev* udev;
}; };
Manager* manager_new(void); Manager* manager_new(void);
void manager_free(Manager *m); void manager_free(Manager *m);
int manager_coldplug(Manager *m);
Job *manager_get_job(Manager *m, uint32_t id); Job *manager_get_job(Manager *m, uint32_t id);
Unit *manager_get_unit(Manager *m, const char *name); 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_clear_jobs(Manager *m);
void manager_dispatch_load_queue(Manager *m);
void manager_dispatch_run_queue(Manager *m); void manager_dispatch_run_queue(Manager *m);
int manager_loop(Manager *m); int manager_loop(Manager *m);
#endif #endif

141
mount.c
View File

@ -7,30 +7,24 @@
#include "unit.h" #include "unit.h"
#include "mount.h" #include "mount.h"
#include "load-fragment.h" #include "load-fragment.h"
#include "load-fstab.h"
#include "load-dropin.h" #include "load-dropin.h"
#include "log.h" #include "log.h"
static int mount_init(Unit *u) { static const UnitActiveState state_translation_table[_MOUNT_STATE_MAX] = {
int r; [MOUNT_DEAD] = UNIT_INACTIVE,
Mount *m = MOUNT(u); [MOUNT_MOUNTING] = UNIT_ACTIVATING,
[MOUNT_MOUNTED] = UNIT_ACTIVE,
[MOUNT_UNMOUNTING] = UNIT_DEACTIVATING,
[MOUNT_MAINTAINANCE] = UNIT_INACTIVE,
};
assert(m); static const char* const state_string_table[_MOUNT_STATE_MAX] = {
[MOUNT_DEAD] = "dead",
/* Load a .mount file */ [MOUNT_MOUNTING] = "mounting",
if ((r = unit_load_fragment(u)) < 0) [MOUNT_MOUNTED] = "mounted",
return r; [MOUNT_UNMOUNTING] = "unmounting",
[MOUNT_MAINTAINANCE] = "maintainance"
/* 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;
return r;
}
static void mount_done(Unit *u) { static void mount_done(Unit *u) {
Mount *d = MOUNT(u); Mount *d = MOUNT(u);
@ -40,16 +34,31 @@ static void mount_done(Unit *u) {
free(d->where); free(d->where);
} }
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);
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) { static void mount_dump(Unit *u, FILE *f, const char *prefix) {
static const char* const state_table[_MOUNT_STATE_MAX] = {
[MOUNT_DEAD] = "dead",
[MOUNT_MOUNTING] = "mounting",
[MOUNT_MOUNTED] = "mounted",
[MOUNT_UNMOUNTING] = "unmounting",
[MOUNT_MAINTAINANCE] = "maintainance"
};
Mount *s = MOUNT(u); Mount *s = MOUNT(u);
assert(s); assert(s);
@ -57,10 +66,20 @@ static void mount_dump(Unit *u, FILE *f, const char *prefix) {
fprintf(f, fprintf(f,
"%sMount State: %s\n" "%sMount State: %s\n"
"%sWhere: %s\n" "%sWhere: %s\n"
"%sWhat: %s\n", "%sWhat: %s\n"
prefix, state_table[s->state], "%sFrom /etc/fstab: %s\n"
"%sFrom /proc/self/mountinfo: %s\n",
prefix, state_string_table[s->state],
prefix, s->where, 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) { static void mount_shutdown(Manager *m) {
@ -136,12 +155,13 @@ static int mount_add_path_links(Mount *m) {
return 0; 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; char *e;
int r; int r;
Unit *u; Unit *u;
bool delete; bool delete;
assert(m);
assert(what); assert(what);
assert(where); assert(where);
@ -172,16 +192,23 @@ static int mount_add_one(Manager *m, const char *what, const char *where) {
goto fail; goto fail;
if (!(MOUNT(u)->what = strdup(what)) || if (!(MOUNT(u)->what = strdup(what)) ||
!(MOUNT(u)->where = strdup(where)) || !(MOUNT(u)->where = strdup(where))) {
!(u->meta.description = strdup(where))) { r = -ENOMEM;
r = -ENOMEM; goto fail;
}
if ((r = unit_set_description(u, where)) < 0)
goto fail; goto fail;
}
} else { } else {
delete = false; delete = false;
free(e); 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) if ((r = mount_add_node_links(MOUNT(u))) < 0)
goto fail; goto fail;
@ -189,6 +216,7 @@ static int mount_add_one(Manager *m, const char *what, const char *where) {
goto fail; goto fail;
unit_add_to_load_queue(u); unit_add_to_load_queue(u);
return 0; return 0;
fail: fail:
@ -207,10 +235,10 @@ static char *fstab_node_to_udev_node(char *p) {
if (startswith(p, "LABEL=")) { if (startswith(p, "LABEL=")) {
if (!(t = strdup(p+6))) if (!(t = xescape(p+6, "/ ")))
return NULL; return NULL;
r = asprintf(&dn, "/dev/disk/by-label/%s", xescape(t, "/ ")); r = asprintf(&dn, "/dev/disk/by-label/%s", t);
free(t); free(t);
if (r < 0) if (r < 0)
@ -221,10 +249,10 @@ static char *fstab_node_to_udev_node(char *p) {
if (startswith(p, "UUID=")) { if (startswith(p, "UUID=")) {
if (!(t = strdup(p+5))) if (!(t = xescape(p+5, "/ ")))
return NULL; 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); free(t);
if (r < 0) if (r < 0)
@ -267,7 +295,7 @@ static int mount_load_etc_fstab(Manager *m) {
if (where[0] == '/') if (where[0] == '/')
path_kill_slashes(where); path_kill_slashes(where);
r = mount_add_one(m, what, where); r = mount_add_one(m, what, where, false);
free(what); free(what);
free(where); free(where);
@ -282,7 +310,7 @@ finish:
return r; return r;
} }
static int mount_load_proc_mounts(Manager *m) { static int mount_load_proc_self_mountinfo(Manager *m) {
FILE *f; FILE *f;
int r; int r;
@ -338,7 +366,7 @@ static int mount_load_proc_mounts(Manager *m) {
} }
free(path); free(path);
r = mount_add_one(m, d, p); r = mount_add_one(m, d, p, true);
free(d); free(d);
free(p); free(p);
@ -361,7 +389,7 @@ static int mount_enumerate(Manager *m) {
if ((r = mount_load_etc_fstab(m)) < 0) if ((r = mount_load_etc_fstab(m)) < 0)
goto fail; goto fail;
if ((r = mount_load_proc_mounts(m)) < 0) if ((r = mount_load_proc_self_mountinfo(m)) < 0)
goto fail; goto fail;
return 0; return 0;
@ -371,28 +399,17 @@ fail:
return r; 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 = { const UnitVTable mount_vtable = {
.suffix = ".mount", .suffix = ".mount",
.init = mount_init, .init = unit_load_fragment_and_dropin,
.done = mount_done, .done = mount_done,
.coldplug = mount_coldplug,
.dump = mount_dump, .dump = mount_dump,
.enumerate = mount_enumerate, .active_state = mount_active_state,
.shutdown = mount_shutdown,
.active_state = mount_active_state .enumerate = mount_enumerate,
.shutdown = mount_shutdown
}; };

View File

@ -22,6 +22,9 @@ struct Mount {
MountState state; MountState state;
char *what, *where; char *what, *where;
bool from_etc_fstab:1;
bool from_proc_self_mountinfo:1;
}; };
extern const UnitVTable mount_vtable; extern const UnitVTable mount_vtable;

15
unit.c
View File

@ -170,6 +170,19 @@ int unit_choose_id(Unit *u, const char *name) {
return 0; 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) { void unit_add_to_load_queue(Unit *u) {
assert(u); assert(u);
@ -586,7 +599,7 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) {
else { else {
assert(u->meta.job->state == JOB_RUNNING); 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 * constitutes a finished job, or maybe
* cotradicts a running job and hence needs to * cotradicts a running job and hence needs to
* invalidate jobs. */ * invalidate jobs. */

9
unit.h
View File

@ -144,6 +144,7 @@ struct UnitVTable {
int (*init)(Unit *u); int (*init)(Unit *u);
void (*done)(Unit *u); void (*done)(Unit *u);
int (*coldplug)(Unit *u);
void (*dump)(Unit *u, FILE *f, const char *prefix); 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 (*sigchld_event)(Unit *u, pid_t pid, int code, int status);
void (*timer_event)(Unit *u, uint64_t n_elapsed, Watch *w); 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); int (*enumerate)(Manager *m);
/* Type specific cleanups. */
void (*shutdown)(Manager *m); 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_add_dependency_by_name(Unit *u, UnitDependency d, const char *name);
int unit_choose_id(Unit *u, 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); void unit_add_to_load_queue(Unit *u);