s/name/unit

This commit is contained in:
Lennart Poettering
2010-01-26 21:39:06 +01:00
parent fd79db6a5d
commit 87f0e418cf
38 changed files with 1734 additions and 1572 deletions

View File

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

View 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 UnitActiveState automount_active_state(Unit *u) {
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 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,

View 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

View 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)) {

View 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);

View File

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

View File

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

6
fixme
View File

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

74
job.c
View File

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

8
job.h
View File

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

View 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 */

View 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

View 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) {
#define FOLLOW_MAX 8
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"
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" },
{ "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, &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"),
{ "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, &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"),
{ "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(n->automount.exec_context, "Automount"),
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;
/* Clear the symlink name set first */
while ((k = set_steal_first(symlink_names)))
free(k);
/* 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 */
if (r == 0)
n->meta.id = t;
return r;
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;
}

View 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

View 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 */

View 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

8
main.c
View File

@@ -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");

190
manager.c
View File

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

View File

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

38
mount.c
View File

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

Some files were not shown because too many files have changed in this diff Show More