]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/load-dropin.c
Add SPDX license identifiers to source files under the LGPL
[thirdparty/systemd.git] / src / core / load-dropin.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
a7334b09
LP
2/***
3 This file is part of systemd.
4
5 Copyright 2010 Lennart Poettering
6
7 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
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
a7334b09
LP
10 (at your option) any later version.
11
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
5430f7f2 15 Lesser General Public License for more details.
a7334b09 16
5430f7f2 17 You should have received a copy of the GNU Lesser General Public License
a7334b09
LP
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19***/
20
0301abf4 21
cf0fbc49 22#include "conf-parser.h"
317cd27a 23#include "fs-util.h"
5cb5a6ff 24#include "load-dropin.h"
cf0fbc49 25#include "load-fragment.h"
b952f2e1 26#include "log.h"
95778782 27#include "stat-util.h"
317cd27a 28#include "string-util.h"
036643a2 29#include "strv.h"
9e2f7c11 30#include "unit-name.h"
cf0fbc49 31#include "unit.h"
8afbb8e1 32
45f4238a 33static int unit_name_compatible(const char *a, const char *b) {
317cd27a
ZJS
34 _cleanup_free_ char *prefix = NULL;
35 int r;
36
37 /* the straightforward case: the symlink name matches the target */
38 if (streq(a, b))
45f4238a 39 return 1;
317cd27a
ZJS
40
41 r = unit_name_template(a, &prefix);
e450032f
ZJS
42 if (r == -EINVAL)
43 /* not a template */
45f4238a 44 return 0;
e450032f
ZJS
45 if (r < 0)
46 /* oom, or some other failure. Just skip the warning. */
45f4238a 47 return r;
317cd27a
ZJS
48
49 /* an instance name points to a target that is just the template name */
50 if (streq(prefix, b))
45f4238a 51 return 1;
317cd27a 52
45f4238a 53 return 0;
317cd27a
ZJS
54}
55
95778782
ZJS
56static int process_deps(Unit *u, UnitDependency dependency, const char *dir_suffix) {
57 _cleanup_strv_free_ char **paths = NULL;
58 char **p;
9e2f7c11
LP
59 int r;
60
95778782
ZJS
61 r = unit_file_find_dropin_paths(NULL,
62 u->manager->lookup_paths.search_path,
63 u->manager->unit_path_cache,
64 dir_suffix,
65 NULL,
66 u->names,
67 &paths);
1a7f1b38 68 if (r < 0)
95778782
ZJS
69 return r;
70
71 STRV_FOREACH(p, paths) {
72 const char *entry;
317cd27a 73 _cleanup_free_ char *target = NULL;
95778782
ZJS
74
75 entry = basename(*p);
76
5be5d39b
ZJS
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);
81 continue;
82 }
83
95778782
ZJS
84 r = is_symlink(*p);
85 if (r < 0) {
86 log_unit_warning_errno(u, r, "%s dropin %s unreadable, ignoring: %m",
87 unit_dependency_to_string(dependency), *p);
88 continue;
89 }
90 if (r == 0) {
91 log_unit_warning(u, "%s dependency dropin %s is not a symlink, ignoring.",
92 unit_dependency_to_string(dependency), *p);
93 continue;
94 }
95
317cd27a
ZJS
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);
99 continue;
100 }
101
102 r = readlink_malloc(*p, &target);
103 if (r < 0) {
104 log_unit_warning_errno(u, r, "readlink(\"%s\") failed, ignoring: %m", *p);
105 continue;
106 }
107
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. */
45f4238a
LP
110 r = unit_name_compatible(entry, basename(target));
111 if (r < 0) {
112 log_unit_warning_errno(u, r, "Can't check if names %s and %s are compatible, ignoring: %m", entry, basename(target));
113 continue;
114 }
115 if (r == 0)
317cd27a
ZJS
116 log_unit_warning(u, "%s dependency dropin %s target %s has different name",
117 unit_dependency_to_string(dependency), *p, target);
95778782 118
eef85c4a 119 r = unit_add_dependency_by_name(u, dependency, entry, *p, true, UNIT_DEPENDENCY_FILE);
95778782 120 if (r < 0)
800f478c
LP
121 log_unit_warning_errno(u, r, "Cannot add %s dependency on %s, ignoring: %m",
122 unit_dependency_to_string(dependency), entry);
95778782 123 }
9e2f7c11 124
8afbb8e1 125 return 0;
9e2f7c11 126}
5cb5a6ff 127
ae7a7182 128int unit_load_dropin(Unit *u) {
d7e0da1d 129 _cleanup_strv_free_ char **l = NULL;
95778782 130 char **f;
1a7f1b38 131 int r;
99f08d14
LP
132
133 assert(u);
134
95778782
ZJS
135 /* Load dependencies from .wants and .requires directories */
136 r = process_deps(u, UNIT_WANTS, ".wants");
137 if (r < 0)
138 return r;
99f08d14 139
95778782
ZJS
140 r = process_deps(u, UNIT_REQUIRES, ".requires");
141 if (r < 0)
142 return r;
0301abf4 143
95778782 144 /* Load .conf dropins */
d7e0da1d 145 r = unit_find_dropin_paths(u, &l);
1a7f1b38 146 if (r <= 0)
ae7a7182 147 return 0;
5926ccca 148
d7e0da1d
LP
149 if (!u->dropin_paths) {
150 u->dropin_paths = l;
151 l = NULL;
152 } else {
153 r = strv_extend_strv(&u->dropin_paths, l, true);
154 if (r < 0)
155 return log_oom();
156 }
157
bcde742e
LP
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,
162 0, u);
5926ccca 163
ae7a7182
OS
164 u->dropin_mtime = now(CLOCK_REALTIME);
165
5cb5a6ff
LP
166 return 0;
167}