From: Frederic Crozat Date: Fri, 30 Sep 2011 13:55:31 +0000 Subject: parse /etc/insserv.conf and adds dependencies accordingly (bnc#721428) --- src/core/service.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/src/core/service.c b/src/core/service.c index 3617c24..3c66cdb 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -3443,6 +3443,108 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags) { } #ifdef HAVE_SYSV_COMPAT +static void sysv_parse_insserv_conf(Manager *mgr, const char* filename) { + FILE *f = NULL; + int r; + + if (!(f = fopen(filename, "re"))) { + log_debug("Failed to open file %s", filename); + r = errno == ENOENT ? 0 : -errno; + goto finish; + } + + while (!feof(f)) { + char l[LINE_MAX], *t; + char **parsed = NULL; + + if (!fgets(l, sizeof(l), f)) { + if (feof(f)) + break; + + r = -errno; + log_error("Failed to read configuration file '%s': %s", filename, strerror(-r)); + goto finish; + } + + t = strstrip(l); + if (*t != '$' && *t != '<') + continue; + + parsed = strv_split(t,WHITESPACE); + /* we ignore , not used, equivalent to X-Interactive */ + if (parsed && !startswith_no_case (parsed[0], "")) { + char *facility; + Unit *u; + if (sysv_translate_facility(parsed[0], NULL, &facility) < 0) + continue; + if (streq(facility, SPECIAL_REMOTE_FS_TARGET)) { + /* insert also a Wants dependency from remote-fs-pre on remote-fs */ + u = manager_get_unit(mgr, SPECIAL_REMOTE_FS_TARGET); + if (u) { + unit_add_dependency_by_name(u, UNIT_WANTS, SPECIAL_REMOTE_FS_PRE_TARGET, NULL, true); + free (facility); + facility=strdup(SPECIAL_REMOTE_FS_PRE_TARGET); + } + } + u = manager_get_unit(mgr, facility); + if (u && (u->type == UNIT_TARGET)) { + char *dep = NULL, *name, **j; + + STRV_FOREACH (j, parsed+1) { + if (*j[0] == '+') + name = *j+1; + else + name = *j; + if (streq(name, "boot.localfs") || + streq(name, "boot.crypto")) + continue; + if ((sysv_translate_facility(name, NULL, &dep) < 0) || !dep) + continue; + + r = unit_add_two_dependencies_by_name_inverse(u, UNIT_WANTS, UNIT_BEFORE, dep, NULL, true); + if (*j[0] != '+') + r = unit_add_dependency_by_name(u, UNIT_REQUIRES, dep, NULL, true); + free(dep); + } + } + free(facility); + } + strv_free(parsed); + } +finish: + if (f) + fclose(f); + +} + +static void sysv_facility_in_insserv_conf(Manager *mgr) { + DIR *d =NULL; + struct dirent *de; + +#ifdef TARGET_DEBIAN + if (!(d = opendir("/etc/insserv.conf.d/"))) + if (errno != ENOENT) { + log_warning("opendir() failed on /etc/insserv.conf.d/ %s", strerror(errno)); + goto finish; + } + + while ((de = readdir(d))) { + char *path = NULL; + if (ignore_file(de->d_name)) + continue; + + path = join("/etc/insserv.conf.d/", de->d_name, NULL); + sysv_parse_insserv_conf(mgr, path); + free(path); + } +finish: + if (d) + closedir(d); +#endif + + sysv_parse_insserv_conf(mgr, "/etc/insserv.conf"); +} + static int service_enumerate(Manager *m) { char **p; @@ -3603,6 +3705,8 @@ static int service_enumerate(Manager *m) { r = 0; + sysv_facility_in_insserv_conf (m); + finish: for (i = 0; i < ELEMENTSOF(rcnd_table); i++)