1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 #include "conf-parser.h"
6 #include "load-dropin.h"
7 #include "load-fragment.h"
10 #include "path-util.h"
11 #include "stat-util.h"
14 #include "unit-name.h"
16 int unit_find_dropin_paths(Unit
*u
, bool use_unit_path_cache
, char ***paths
) {
19 return unit_file_find_dropin_paths(NULL
,
20 u
->manager
->lookup_paths
.search_path
,
21 use_unit_path_cache
? u
->manager
->unit_path_cache
: NULL
,
27 static int process_deps(Unit
*u
, UnitDependency dependency
, const char *dir_suffix
) {
28 _cleanup_strv_free_
char **paths
= NULL
;
31 r
= unit_file_find_dropin_paths(NULL
,
32 u
->manager
->lookup_paths
.search_path
,
33 u
->manager
->unit_path_cache
,
40 STRV_FOREACH(p
, paths
) {
41 _cleanup_free_
char *target
= NULL
, *target_file
= NULL
, *entry
= NULL
;
43 if (null_or_empty_path(*p
) > 0) {
44 /* an error usually means an invalid symlink, which is not a mask */
45 log_unit_debug(u
, "%s dependency on %s is masked by %s, ignoring.",
46 unit_dependency_to_string(dependency
), entry
, *p
);
52 log_unit_warning_errno(u
, r
, "%s dropin %s unreadable, ignoring: %m",
53 unit_dependency_to_string(dependency
), *p
);
57 log_unit_warning(u
, "%s dependency dropin %s is not a symlink, ignoring.",
58 unit_dependency_to_string(dependency
), *p
);
62 r
= path_extract_filename(*p
, &entry
);
64 log_unit_warning_errno(u
, r
, "Failed to extract file name of %s dependency dropin %s, ignoring: %m",
65 unit_dependency_to_string(dependency
), *p
);
69 if (!unit_name_is_valid(entry
, UNIT_NAME_ANY
)) {
70 log_unit_warning(u
, "%s dependency dropin %s is not a valid unit name, ignoring.",
71 unit_dependency_to_string(dependency
), *p
);
75 r
= readlink_malloc(*p
, &target
);
77 log_unit_warning_errno(u
, r
, "readlink(\"%s\") failed, ignoring: %m", *p
);
81 r
= path_extract_filename(target
, &target_file
);
83 log_unit_warning_errno(u
, r
, "Failed to extract file name for dropin target %s, ignoring: %m",
88 /* We don't treat this as an error, especially because we didn't check this for a
89 * long time. Nevertheless, we warn, because such mismatch can be mighty confusing. */
90 r
= unit_symlink_name_compatible(entry
, target_file
, u
->instance
);
92 log_unit_warning_errno(u
, r
, "Can't check if names %s and %s are compatible, ignoring: %m",
97 log_unit_warning(u
, "%s dependency dropin %s target %s has different name",
98 unit_dependency_to_string(dependency
), *p
, target
);
100 r
= unit_add_dependency_by_name(u
, dependency
, entry
, true, UNIT_DEPENDENCY_FILE
);
102 log_unit_warning_errno(u
, r
, "Cannot add %s dependency on %s, ignoring: %m",
103 unit_dependency_to_string(dependency
), entry
);
109 int unit_load_dropin(Unit
*u
) {
110 _cleanup_strv_free_
char **l
= NULL
;
115 /* Load dependencies from .wants, .requires and .upholds directories */
116 r
= process_deps(u
, UNIT_WANTS
, ".wants");
120 r
= process_deps(u
, UNIT_REQUIRES
, ".requires");
124 r
= process_deps(u
, UNIT_UPHOLDS
, ".upholds");
128 /* Load .conf dropins */
129 r
= unit_find_dropin_paths(u
, /* use_unit_path_cache = */ true, &l
);
133 r
= strv_extend_strv_consume(&u
->dropin_paths
, TAKE_PTR(l
), /* filter_duplicates = */ true);
138 STRV_FOREACH(f
, u
->dropin_paths
) {
141 r
= config_parse(u
->id
, *f
, NULL
,
142 UNIT_VTABLE(u
)->sections
,
143 config_item_perf_lookup
, load_fragment_gperf_lookup
,
146 u
->dropin_mtime
= MAX(u
->dropin_mtime
, timespec_load(&st
.st_mtim
));