summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/load-dropin.c6
-rw-r--r--src/core/load-dropin.h3
-rw-r--r--src/shared/dropin.c26
-rw-r--r--src/shared/dropin.h2
-rw-r--r--src/systemctl/systemctl.c2
5 files changed, 28 insertions, 11 deletions
diff --git a/src/core/load-dropin.c b/src/core/load-dropin.c
index f83fa09301..fc07151d37 100644
--- a/src/core/load-dropin.c
+++ b/src/core/load-dropin.c
@@ -57,9 +57,11 @@ int unit_load_dropin(Unit *u) {
char **p;
STRV_FOREACH(p, u->manager->lookup_paths.search_path) {
- unit_file_process_dir(u->manager->unit_path_cache, *p, t, ".wants", UNIT_WANTS,
+ unit_file_process_dir(NULL, u->manager->unit_path_cache, *p, t,
+ ".wants", UNIT_WANTS,
add_dependency_consumer, u, NULL);
- unit_file_process_dir(u->manager->unit_path_cache, *p, t, ".requires", UNIT_REQUIRES,
+ unit_file_process_dir(NULL, u->manager->unit_path_cache, *p, t,
+ ".requires", UNIT_REQUIRES,
add_dependency_consumer, u, NULL);
}
}
diff --git a/src/core/load-dropin.h b/src/core/load-dropin.h
index 942d26724e..319827dfb9 100644
--- a/src/core/load-dropin.h
+++ b/src/core/load-dropin.h
@@ -25,7 +25,8 @@
/* Read service data supplementary drop-in directories */
static inline int unit_find_dropin_paths(Unit *u, char ***paths) {
- return unit_file_find_dropin_paths(u->manager->lookup_paths.search_path,
+ return unit_file_find_dropin_paths(NULL,
+ u->manager->lookup_paths.search_path,
u->manager->unit_path_cache,
u->names,
paths);
diff --git a/src/shared/dropin.c b/src/shared/dropin.c
index 3cbfe13f4c..06cf3de620 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"
@@ -118,38 +119,46 @@ int write_drop_in_format(const char *dir, const char *unit, unsigned level,
static int iterate_dir(
const char *path,
+ const char *original_root,
UnitDependency dependency,
dependency_consumer_t consumer,
void *arg,
char ***strv) {
+ _cleanup_free_ char *chased = NULL;
_cleanup_closedir_ DIR *d = NULL;
struct dirent *de;
int r;
assert(path);
+ r = chase_symlinks(path, original_root, 0, &chased);
+ if (r < 0)
+ return log_full_errno(r == -ENOENT ? LOG_DEBUG : LOG_WARNING,
+ r, "Failed to canonicalize path %s: %m", path);
+
/* The config directories are special, since the order of the
* drop-ins matters */
if (dependency < 0) {
- r = strv_extend(strv, path);
+ r = strv_push(strv, chased);
if (r < 0)
return log_oom();
+ chased = NULL;
return 0;
}
assert(consumer);
- d = opendir(path);
+ d = opendir(chased);
if (!d) {
if (errno == ENOENT)
return 0;
- return log_error_errno(errno, "Failed to open directory %s: %m", path);
+ return log_warning_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)) {
+ FOREACH_DIRENT(de, d, return log_warning_errno(errno, "Failed to read directory %s: %m", path)) {
_cleanup_free_ char *f = NULL;
f = strjoin(path, "/", de->d_name);
@@ -165,6 +174,7 @@ static int iterate_dir(
}
int unit_file_process_dir(
+ const char *original_root,
Set *unit_path_cache,
const char *unit_path,
const char *name,
@@ -186,7 +196,7 @@ int unit_file_process_dir(
return log_oom();
if (!unit_path_cache || set_get(unit_path_cache, path))
- (void) iterate_dir(path, dependency, consumer, arg, strv);
+ (void) iterate_dir(path, original_root, dependency, consumer, arg, strv);
if (unit_name_is_valid(name, UNIT_NAME_INSTANCE)) {
_cleanup_free_ char *template = NULL, *p = NULL;
@@ -201,13 +211,14 @@ int unit_file_process_dir(
return log_oom();
if (!unit_path_cache || set_get(unit_path_cache, p))
- (void) iterate_dir(p, dependency, consumer, arg, strv);
+ (void) iterate_dir(p, original_root, dependency, consumer, arg, strv);
}
return 0;
}
int unit_file_find_dropin_paths(
+ const char *original_root,
char **lookup_path,
Set *unit_path_cache,
Set *names,
@@ -224,7 +235,8 @@ int unit_file_find_dropin_paths(
char **p;
STRV_FOREACH(p, lookup_path)
- unit_file_process_dir(unit_path_cache, *p, t, ".d", _UNIT_DEPENDENCY_INVALID, NULL, NULL, &strv);
+ unit_file_process_dir(original_root, unit_path_cache, *p, t, ".d",
+ _UNIT_DEPENDENCY_INVALID, NULL, NULL, &strv);
}
if (strv_isempty(strv))
diff --git a/src/shared/dropin.h b/src/shared/dropin.h
index c1936f397b..761b250886 100644
--- a/src/shared/dropin.h
+++ b/src/shared/dropin.h
@@ -45,6 +45,7 @@ typedef int (*dependency_consumer_t)(UnitDependency dependency,
void *arg);
int unit_file_process_dir(
+ const char *original_root,
Set * unit_path_cache,
const char *unit_path,
const char *name,
@@ -55,6 +56,7 @@ int unit_file_process_dir(
char ***strv);
int unit_file_find_dropin_paths(
+ const char *original_root,
char **lookup_path,
Set *unit_path_cache,
Set *names,
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 313e47431b..c4e261fc47 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -2601,7 +2601,7 @@ static int unit_find_paths(
return log_error_errno(r, "Failed to add unit name: %m");
if (dropin_paths) {
- r = unit_file_find_dropin_paths(lp->search_path, NULL, names, &dropins);
+ r = unit_file_find_dropin_paths(arg_root, lp->search_path, NULL, names, &dropins);
if (r < 0)
return r;
}