diff options
Diffstat (limited to 'src/shared/dropin.c')
-rw-r--r-- | src/shared/dropin.c | 112 |
1 files changed, 43 insertions, 69 deletions
diff --git a/src/shared/dropin.c b/src/shared/dropin.c index 3cbfe13f4c..15ccd1b6ca 100644 --- a/src/shared/dropin.c +++ b/src/shared/dropin.c @@ -29,6 +29,7 @@ #include "escape.h" #include "fd-util.h" #include "fileio-label.h" +#include "fs-util.h" #include "hashmap.h" #include "log.h" #include "macro.h" @@ -42,11 +43,10 @@ int drop_in_file(const char *dir, const char *unit, unsigned level, const char *name, char **_p, char **_q) { + char prefix[DECIMAL_STR_MAX(unsigned)]; _cleanup_free_ char *b = NULL; char *p, *q; - char prefix[DECIMAL_STR_MAX(unsigned)]; - assert(unit); assert(name); assert(_p); @@ -116,125 +116,99 @@ int write_drop_in_format(const char *dir, const char *unit, unsigned level, return write_drop_in(dir, unit, level, name, p); } -static int iterate_dir( +static int unit_file_find_dir( + const char *original_root, const char *path, - UnitDependency dependency, - dependency_consumer_t consumer, - void *arg, - char ***strv) { + char ***dirs) { - _cleanup_closedir_ DIR *d = NULL; - struct dirent *de; + _cleanup_free_ char *chased = NULL; int r; 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(); - + r = chase_symlinks(path, original_root, 0, &chased); + if (r == -ENOENT) /* Ignore -ENOENT, after all most units won't have a drop-in dir */ return 0; - } - - assert(consumer); - - d = opendir(path); - if (!d) { - if (errno == ENOENT) - return 0; - - return log_error_errno(errno, "Failed to open directory %s: %m", path); - } - - FOREACH_DIRENT(de, d, return log_error_errno(errno, "Failed to read directory %s: %m", path)) { - _cleanup_free_ char *f = NULL; - - f = strjoin(path, "/", de->d_name); - if (!f) - return log_oom(); + if (r < 0) + return log_full_errno(LOG_WARNING, r, "Failed to canonicalize path %s: %m", path); - r = consumer(dependency, de->d_name, f, arg); - if (r < 0) - return r; - } + r = strv_push(dirs, chased); + if (r < 0) + return log_oom(); + chased = NULL; return 0; } -int unit_file_process_dir( +static int unit_file_find_dirs( + const char *original_root, Set *unit_path_cache, const char *unit_path, const char *name, const char *suffix, - UnitDependency dependency, - dependency_consumer_t consumer, - void *arg, - char ***strv) { + char ***dirs) { - _cleanup_free_ char *path = NULL; + char *path; int r; assert(unit_path); assert(name); assert(suffix); - path = strjoin(unit_path, "/", name, suffix); - if (!path) - return log_oom(); + path = strjoina(unit_path, "/", name, suffix); - if (!unit_path_cache || set_get(unit_path_cache, path)) - (void) iterate_dir(path, dependency, consumer, arg, strv); + if (!unit_path_cache || set_get(unit_path_cache, path)) { + r = unit_file_find_dir(original_root, path, dirs); + if (r < 0) + return r; + } if (unit_name_is_valid(name, UNIT_NAME_INSTANCE)) { - _cleanup_free_ char *template = NULL, *p = NULL; /* Also try the template dir */ + _cleanup_free_ char *template = NULL; + r = unit_name_template(name, &template); if (r < 0) return log_error_errno(r, "Failed to generate template from unit name: %m"); - p = strjoin(unit_path, "/", template, suffix); - if (!p) - return log_oom(); - - if (!unit_path_cache || set_get(unit_path_cache, p)) - (void) iterate_dir(p, dependency, consumer, arg, strv); + return unit_file_find_dirs(original_root, unit_path_cache, unit_path, template, suffix, dirs); } return 0; } int unit_file_find_dropin_paths( + const char *original_root, char **lookup_path, Set *unit_path_cache, + const char *dir_suffix, + const char *file_suffix, Set *names, - char ***paths) { + char ***ret) { - _cleanup_strv_free_ char **strv = NULL, **ans = NULL; + _cleanup_strv_free_ char **dirs = NULL, **ans = NULL; Iterator i; - char *t; + char *t, **p; int r; - assert(paths); - - SET_FOREACH(t, names, i) { - char **p; + assert(ret); + SET_FOREACH(t, names, i) STRV_FOREACH(p, lookup_path) - unit_file_process_dir(unit_path_cache, *p, t, ".d", _UNIT_DEPENDENCY_INVALID, NULL, NULL, &strv); - } + unit_file_find_dirs(original_root, unit_path_cache, *p, t, dir_suffix, &dirs); - if (strv_isempty(strv)) + if (strv_isempty(dirs)) { + *ret = NULL; return 0; + } - r = conf_files_list_strv(&ans, ".conf", NULL, (const char**) strv); + r = conf_files_list_strv(&ans, file_suffix, NULL, (const char**) dirs); if (r < 0) - return log_warning_errno(r, "Failed to get list of configuration files: %m"); + return log_warning_errno(r, "Failed to sort the list of configuration files: %m"); - *paths = ans; + *ret = ans; ans = NULL; + return 1; } |