summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2010-04-24 04:26:33 +0200
committerLennart Poettering <lennart@poettering.net>2010-04-24 04:26:33 +0200
commitdb06e3b6a5254ec247de5bc1a1b6a8670c2f4b2b (patch)
treee0703cc30360f14305184d45529579279463919c
parentab8cabad2643f392cf9fd3bf97c665c4d159692f (diff)
service: sysv priorities in link names should take precedence, since they are possibly fixed up by chkconfig
-rw-r--r--manager.c26
-rw-r--r--manager.h1
-rw-r--r--service.c98
3 files changed, 47 insertions, 78 deletions
diff --git a/manager.c b/manager.c
index c6555d40bc..cf1c1481c1 100644
--- a/manager.c
+++ b/manager.c
@@ -1536,15 +1536,15 @@ unsigned manager_dispatch_load_queue(Manager *m) {
return n;
}
-int manager_load_unit(Manager *m, const char *name, const char *path, Unit **_ret) {
+int manager_load_unit_prepare(Manager *m, const char *name, const char *path, Unit **_ret) {
Unit *ret;
int r;
assert(m);
assert(name || path);
- /* This will load the service information files, but not actually
- * start any services or anything. */
+ /* This will prepare the unit for loading, but not actually
+ * load anything from disk. */
if (path && !is_path(path))
return -EINVAL;
@@ -1577,6 +1577,24 @@ int manager_load_unit(Manager *m, const char *name, const char *path, Unit **_re
unit_add_to_load_queue(ret);
unit_add_to_dbus_queue(ret);
+ if (_ret)
+ *_ret = ret;
+
+ return 0;
+}
+
+int manager_load_unit(Manager *m, const char *name, const char *path, Unit **_ret) {
+ Unit *ret;
+ int r;
+
+ assert(m);
+
+ /* This will load the service information files, but not actually
+ * start any services or anything. */
+
+ if ((r = manager_load_unit_prepare(m, name, path, &ret)) < 0)
+ return r;
+
manager_dispatch_load_queue(m);
if (_ret)
@@ -1767,6 +1785,8 @@ static int manager_process_signal_fd(Manager *m) {
case SIGTERM:
if (m->running_as == MANAGER_INIT)
+ /* This is for compatibility with the
+ * original sysvinit */
m->exit_code = MANAGER_REEXECUTE;
else
m->exit_code = MANAGER_EXIT;
diff --git a/manager.h b/manager.h
index 3790cfd281..0a09430f56 100644
--- a/manager.h
+++ b/manager.h
@@ -240,6 +240,7 @@ Unit *manager_get_unit(Manager *m, const char *name);
int manager_get_unit_from_dbus_path(Manager *m, const char *s, Unit **_u);
int manager_get_job_from_dbus_path(Manager *m, const char *s, Job **_j);
+int manager_load_unit_prepare(Manager *m, const char *name, const char *path, Unit **_ret);
int manager_load_unit(Manager *m, const char *name, const char *path, Unit **_ret);
int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, bool force, Job **_ret);
diff --git a/service.c b/service.c
index 298cc27edb..ec466181ee 100644
--- a/service.c
+++ b/service.c
@@ -273,71 +273,12 @@ static int sysv_exec_commands(Service *s) {
return 0;
}
-static int priority_from_rcd(Service *s, const char *init_script) {
- char **p;
- unsigned i;
-
- STRV_FOREACH(p, UNIT(s)->meta.manager->sysvrcnd_path)
- for (i = 0; i < ELEMENTSOF(rcnd_table); i += 2) {
- char *path;
- DIR *d;
- struct dirent *de;
-
- if (asprintf(&path, "%s/%s", *p, rcnd_table[i]) < 0)
- return -ENOMEM;
-
- d = opendir(path);
- free(path);
-
- if (!d) {
- if (errno != ENOENT)
- log_warning("opendir() failed on %s: %s", path, strerror(errno));
-
- continue;
- }
-
- while ((de = readdir(d))) {
- int a, b;
-
- if (ignore_file(de->d_name))
- continue;
-
- if (de->d_name[0] != 'S')
- continue;
-
- if (strlen(de->d_name) < 4)
- continue;
-
- if (!streq(de->d_name + 3, init_script))
- continue;
-
- /* Yay, we found it! Now decode the priority */
-
- a = undecchar(de->d_name[1]);
- b = undecchar(de->d_name[2]);
-
- if (a < 0 || b < 0)
- continue;
-
- s->sysv_start_priority = a*10 + b;
-
- log_debug("Determined priority %i from link farm for %s", s->sysv_start_priority, UNIT(s)->meta.id);
-
- closedir(d);
- return 0;
- }
-
- closedir(d);
- }
-
- return 0;
-}
-
static int service_load_sysv_path(Service *s, const char *path) {
FILE *f;
Unit *u;
unsigned line = 0;
int r;
+ bool normal_service;
enum {
NORMAL,
DESCRIPTION,
@@ -416,7 +357,7 @@ static int service_load_sysv_path(Service *s, const char *path) {
if (start_priority < 0 || start_priority > 99)
log_warning("[%s:%u] Start priority out of range. Ignoring.", path, line);
- else
+ else if (s->sysv_start_priority < 0)
s->sysv_start_priority = start_priority;
char_array_0(runlevels);
@@ -434,7 +375,6 @@ static int service_load_sysv_path(Service *s, const char *path) {
s->sysv_runlevels = d;
}
-
} else if (startswith(t, "description:")) {
size_t k = strlen(t);
@@ -634,20 +574,15 @@ static int service_load_sysv_path(Service *s, const char *path) {
* a priority for *all* init scripts here, since they are
* needed as soon as at least one non-LSB script is used. */
- if (s->sysv_start_priority < 0) {
- log_debug("%s has no chkconfig header, trying to determine SysV priority from link farm.", u->meta.id);
-
- if ((r = priority_from_rcd(s, file_name_from_path(path))) < 0)
- goto finish;
-
- if (s->sysv_start_priority < 0)
- log_warning("%s has neither a chkconfig header nor a directory link, cannot order unit!", u->meta.id);
- }
+ if (s->sysv_start_priority < 0)
+ log_warning("%s has neither a chkconfig header nor a directory link, cannot order unit!", u->meta.id);
if ((r = sysv_exec_commands(s)) < 0)
goto finish;
- if (!s->sysv_runlevels || chars_intersect("12345", s->sysv_runlevels)) {
+ normal_service = !s->sysv_runlevels || chars_intersect("12345", s->sysv_runlevels);
+
+ if (normal_service) {
/* If there a runlevels configured for this service
* but none of the standard ones, then we assume this
* is some special kind of service (which might be
@@ -664,8 +599,8 @@ static int service_load_sysv_path(Service *s, const char *path) {
s->kill_mode = KILL_PROCESS_GROUP;
/* Don't timeout special services during boot (like fsck) */
- if (s->sysv_runlevels && !chars_intersect("12345", s->sysv_runlevels))
- s->timeout_usec = -1;
+ if (s->sysv_runlevels && !normal_service)
+ s->timeout_usec = 0;
u->meta.load_state = UNIT_LOADED;
r = 0;
@@ -2210,6 +2145,7 @@ static int service_enumerate(Manager *m) {
while ((de = readdir(d))) {
Unit *service;
+ int a, b;
if (ignore_file(de->d_name))
continue;
@@ -2220,6 +2156,12 @@ static int service_enumerate(Manager *m) {
if (strlen(de->d_name) < 4)
continue;
+ a = undecchar(de->d_name[1]);
+ b = undecchar(de->d_name[2]);
+
+ if (a < 0 || b < 0)
+ continue;
+
free(fpath);
fpath = NULL;
if (asprintf(&fpath, "%s/%s/%s", *p, rcnd_table[i], de->d_name) < 0) {
@@ -2242,9 +2184,15 @@ static int service_enumerate(Manager *m) {
goto finish;
}
- if ((r = manager_load_unit(m, name, NULL, &service)) < 0)
+ if ((r = manager_load_unit_prepare(m, name, NULL, &service)) < 0)
goto finish;
+ if (de->d_name[0] == 'S')
+ SERVICE(service)->sysv_start_priority = a*10 + b;
+
+ manager_dispatch_load_queue(m);
+ service = unit_follow_merge(service);
+
if (de->d_name[0] == 'S') {
Unit *runlevel_target;