X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fcore%2Fload-dropin.c;h=6ff592be8b1cf944e9177ceae96a62b7c6ab1b52;hb=5e592c66bdf76dfc8445b332f7a5088ca504ee90;hp=8e10d8fb4c2164031597439daff8626068956095;hpb=8afbb8e1180dce3cb33a14fc3ec5afcf501104e6;p=elogind.git diff --git a/src/core/load-dropin.c b/src/core/load-dropin.c index 8e10d8fb4..6ff592be8 100644 --- a/src/core/load-dropin.c +++ b/src/core/load-dropin.c @@ -29,40 +29,48 @@ #include "unit-name.h" #include "conf-parser.h" #include "load-fragment.h" +#include "conf-files.h" -static int load_dropin_config_file(Unit *u, const char *path) { - assert(u); - assert(path); - - if (!endswith(path, ".conf")) - return 0; - - return config_parse(path, NULL, UNIT_VTABLE(u)->sections, config_item_perf_lookup, (void*) load_fragment_gperf_lookup, false, u); -} +static int iterate_dir( + Unit *u, + const char *path, + UnitDependency dependency, + char ***strv) { -static int iterate_dir(Unit *u, const char *path, UnitDependency dependency) { _cleanup_closedir_ DIR *d = NULL; int r; assert(u); assert(path); + /* The config directories are special, since the order of the + * drop-ins matters */ + if (dependency < 0) { + r = strv_extend(strv, path); + if (r < 0) + return log_oom(); + + return 0; + } + d = opendir(path); if (!d) { if (errno == ENOENT) return 0; + log_error("Failed to open directory %s: %m", path); return -errno; } for (;;) { struct dirent *de; - union dirent_storage buf; _cleanup_free_ char *f = NULL; int k; - k = readdir_r(d, &buf.de, &de); - if (k != 0) { + errno = 0; + de = readdir(d); + if (!de && errno != 0) { + k = errno; log_error("Failed to read directory %s: %s", path, strerror(k)); return -k; } @@ -77,23 +85,23 @@ static int iterate_dir(Unit *u, const char *path, UnitDependency dependency) { if (!f) return log_oom(); - if (dependency >= 0) { - r = unit_add_dependency_by_name(u, dependency, de->d_name, f, true); - if (r < 0) - log_error("Cannot add dependency %s to %s, ignoring: %s", de->d_name, u->id, strerror(-r)); - } else { - r = load_dropin_config_file(u, f); - if (r < 0) - log_error("Cannot load drop-in configuration file %s for %s, ignoring: %s", f, u->id, strerror(-r)); - } + r = unit_add_dependency_by_name(u, dependency, de->d_name, f, true); + if (r < 0) + log_error("Cannot add dependency %s to %s, ignoring: %s", de->d_name, u->id, strerror(-r)); } return 0; } -static int process_dir(Unit *u, const char *unit_path, const char *name, const char *suffix, UnitDependency dependency) { - int r; - char *path; +static int process_dir( + Unit *u, + const char *unit_path, + const char *name, + const char *suffix, + UnitDependency dependency, + char ***strv) { + + _cleanup_free_ char *path = NULL; assert(u); assert(unit_path); @@ -102,49 +110,62 @@ static int process_dir(Unit *u, const char *unit_path, const char *name, const c path = strjoin(unit_path, "/", name, suffix, NULL); if (!path) - return -ENOMEM; - - if (u->manager->unit_path_cache && - !set_get(u->manager->unit_path_cache, path)) - r = 0; - else - r = iterate_dir(u, path, dependency); - free(path); + return log_oom(); - if (r < 0) - return r; + if (!u->manager->unit_path_cache || set_get(u->manager->unit_path_cache, path)) + iterate_dir(u, path, dependency, strv); if (u->instance) { - char *template; + _cleanup_free_ char *template = NULL, *p = NULL; /* Also try the template dir */ template = unit_name_template(name); if (!template) - return -ENOMEM; + return log_oom(); - path = strjoin(unit_path, "/", template, suffix, NULL); - free(template); + p = strjoin(unit_path, "/", template, suffix, NULL); + if (!p) + return log_oom(); - if (!path) - return -ENOMEM; + if (!u->manager->unit_path_cache || set_get(u->manager->unit_path_cache, p)) + iterate_dir(u, p, dependency, strv); + } - if (u->manager->unit_path_cache && - !set_get(u->manager->unit_path_cache, path)) - r = 0; - else - r = iterate_dir(u, path, dependency); - free(path); + return 0; +} - if (r < 0) - return r; +char **unit_find_dropin_paths(Unit *u) { + _cleanup_strv_free_ char **strv = NULL; + char **configs = NULL; + Iterator i; + char *t; + int r; + + assert(u); + + SET_FOREACH(t, u->names, i) { + char **p; + + STRV_FOREACH(p, u->manager->lookup_paths.unit_path) + process_dir(u, *p, t, ".d", _UNIT_DEPENDENCY_INVALID, &strv); } - return 0; + if (strv_isempty(strv)) + return NULL; + + r = conf_files_list_strv(&configs, ".conf", NULL, (const char**) strv); + if (r < 0) { + log_error("Failed to get list of configuration files: %s", strerror(-r)); + strv_free(configs); + return NULL; + } + + return configs; } int unit_load_dropin(Unit *u) { Iterator i; - char *t; + char *t, **f; assert(u); @@ -154,22 +175,22 @@ int unit_load_dropin(Unit *u) { char **p; STRV_FOREACH(p, u->manager->lookup_paths.unit_path) { - int r; - - r = process_dir(u, *p, t, ".wants", UNIT_WANTS); - if (r < 0) - return r; + process_dir(u, *p, t, ".wants", UNIT_WANTS, NULL); + process_dir(u, *p, t, ".requires", UNIT_REQUIRES, NULL); + } + } - r = process_dir(u, *p, t, ".requires", UNIT_REQUIRES); - if (r < 0) - return r; + u->dropin_paths = unit_find_dropin_paths(u); + if (! u->dropin_paths) + return 0; - /* This loads the drop-in config snippets */ - r = process_dir(u, *p, t, ".d", _UNIT_TYPE_INVALID); - if (r < 0) - return r; - } + STRV_FOREACH(f, u->dropin_paths) { + config_parse(u->id, *f, NULL, + UNIT_VTABLE(u)->sections, config_item_perf_lookup, + (void*) load_fragment_gperf_lookup, false, false, u); } + u->dropin_mtime = now(CLOCK_REALTIME); + return 0; }