1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2010 Lennart Poettering
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 #include "conf-parser.h"
24 #include "load-dropin.h"
25 #include "load-fragment.h"
27 #include "stat-util.h"
28 #include "string-util.h"
30 #include "unit-name.h"
33 static int unit_name_compatible(const char *a
, const char *b
) {
34 _cleanup_free_
char *prefix
= NULL
;
37 /* the straightforward case: the symlink name matches the target */
41 r
= unit_name_template(a
, &prefix
);
46 /* oom, or some other failure. Just skip the warning. */
49 /* an instance name points to a target that is just the template name */
56 static int process_deps(Unit
*u
, UnitDependency dependency
, const char *dir_suffix
) {
57 _cleanup_strv_free_
char **paths
= NULL
;
61 r
= unit_file_find_dropin_paths(NULL
,
62 u
->manager
->lookup_paths
.search_path
,
63 u
->manager
->unit_path_cache
,
71 STRV_FOREACH(p
, paths
) {
73 _cleanup_free_
char *target
= NULL
;
77 if (null_or_empty_path(*p
) > 0) {
78 /* an error usually means an invalid symlink, which is not a mask */
79 log_unit_debug(u
, "%s dependency on %s is masked by %s, ignoring.",
80 unit_dependency_to_string(dependency
), entry
, *p
);
86 log_unit_warning_errno(u
, r
, "%s dropin %s unreadable, ignoring: %m",
87 unit_dependency_to_string(dependency
), *p
);
91 log_unit_warning(u
, "%s dependency dropin %s is not a symlink, ignoring.",
92 unit_dependency_to_string(dependency
), *p
);
96 if (!unit_name_is_valid(entry
, UNIT_NAME_ANY
)) {
97 log_unit_warning(u
, "%s dependency dropin %s is not a valid unit name, ignoring.",
98 unit_dependency_to_string(dependency
), *p
);
102 r
= readlink_malloc(*p
, &target
);
104 log_unit_warning_errno(u
, r
, "readlink(\"%s\") failed, ignoring: %m", *p
);
108 /* We don't treat this as an error, especially because we didn't check this for a
109 * long time. Nevertheless, we warn, because such mismatch can be mighty confusing. */
110 r
= unit_name_compatible(entry
, basename(target
));
112 log_unit_warning_errno(u
, r
, "Can't check if names %s and %s are compatible, ignoring: %m", entry
, basename(target
));
116 log_unit_warning(u
, "%s dependency dropin %s target %s has different name",
117 unit_dependency_to_string(dependency
), *p
, target
);
119 r
= unit_add_dependency_by_name(u
, dependency
, entry
, *p
, true, UNIT_DEPENDENCY_FILE
);
121 log_unit_warning_errno(u
, r
, "Cannot add %s dependency on %s, ignoring: %m",
122 unit_dependency_to_string(dependency
), entry
);
128 int unit_load_dropin(Unit
*u
) {
129 _cleanup_strv_free_
char **l
= NULL
;
135 /* Load dependencies from .wants and .requires directories */
136 r
= process_deps(u
, UNIT_WANTS
, ".wants");
140 r
= process_deps(u
, UNIT_REQUIRES
, ".requires");
144 /* Load .conf dropins */
145 r
= unit_find_dropin_paths(u
, &l
);
149 if (!u
->dropin_paths
) {
153 r
= strv_extend_strv(&u
->dropin_paths
, l
, true);
158 STRV_FOREACH(f
, u
->dropin_paths
)
159 (void) config_parse(u
->id
, *f
, NULL
,
160 UNIT_VTABLE(u
)->sections
,
161 config_item_perf_lookup
, load_fragment_gperf_lookup
,
164 u
->dropin_mtime
= now(CLOCK_REALTIME
);