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;
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)
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;
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,
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);
s->sysv_runlevels = d;
}
-
} else if (startswith(t, "description:")) {
size_t k = strlen(t);
* 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
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;
while ((de = readdir(d))) {
Unit *service;
+ int a, b;
if (ignore_file(de->d_name))
continue;
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) {
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;