]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/load-dropin.c
login: replace readdir_r with readdir
[thirdparty/systemd.git] / src / core / load-dropin.c
CommitLineData
d6c9574f 1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
5cb5a6ff 2
a7334b09
LP
3/***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
a7334b09
LP
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2 16 Lesser General Public License for more details.
a7334b09 17
5430f7f2 18 You should have received a copy of the GNU Lesser General Public License
a7334b09
LP
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
0301abf4
LP
22#include <dirent.h>
23#include <errno.h>
24
25#include "unit.h"
5cb5a6ff 26#include "load-dropin.h"
b952f2e1 27#include "log.h"
036643a2 28#include "strv.h"
9e2f7c11 29#include "unit-name.h"
8afbb8e1
LP
30#include "conf-parser.h"
31#include "load-fragment.h"
5926ccca 32#include "conf-files.h"
8afbb8e1 33
aa96c6cb
LP
34static int iterate_dir(
35 Unit *u,
36 const char *path,
37 UnitDependency dependency,
38 char ***strv) {
39
8afbb8e1 40 _cleanup_closedir_ DIR *d = NULL;
9e2f7c11
LP
41 int r;
42
99f08d14
LP
43 assert(u);
44 assert(path);
45
5926ccca
LP
46 /* The config directories are special, since the order of the
47 * drop-ins matters */
48 if (dependency < 0) {
49 r = strv_extend(strv, path);
50 if (r < 0)
51 return log_oom();
52
53 return 0;
54 }
55
f917c3e5
LP
56 d = opendir(path);
57 if (!d) {
9e2f7c11
LP
58 if (errno == ENOENT)
59 return 0;
60
61 return -errno;
62 }
63
8afbb8e1
LP
64 for (;;) {
65 struct dirent *de;
66 union dirent_storage buf;
67 _cleanup_free_ char *f = NULL;
68 int k;
69
70 k = readdir_r(d, &buf.de, &de);
71 if (k != 0) {
72 log_error("Failed to read directory %s: %s", path, strerror(k));
73 return -k;
74 }
75
76 if (!de)
77 break;
9e2f7c11
LP
78
79 if (ignore_file(de->d_name))
80 continue;
81
b7def684 82 f = strjoin(path, "/", de->d_name, NULL);
8afbb8e1
LP
83 if (!f)
84 return log_oom();
9e2f7c11 85
5926ccca
LP
86 r = unit_add_dependency_by_name(u, dependency, de->d_name, f, true);
87 if (r < 0)
88 log_error("Cannot add dependency %s to %s, ignoring: %s", de->d_name, u->id, strerror(-r));
9e2f7c11
LP
89 }
90
8afbb8e1 91 return 0;
9e2f7c11 92}
5cb5a6ff 93
aa96c6cb
LP
94static int process_dir(
95 Unit *u,
96 const char *unit_path,
97 const char *name,
98 const char *suffix,
99 UnitDependency dependency,
100 char ***strv) {
101
0301abf4 102 int r;
99f08d14 103 char *path;
0301abf4 104
87f0e418 105 assert(u);
99f08d14
LP
106 assert(unit_path);
107 assert(name);
108 assert(suffix);
5cb5a6ff 109
b7def684 110 path = strjoin(unit_path, "/", name, suffix, NULL);
911a4828 111 if (!path)
aa96c6cb 112 return log_oom();
5cb5a6ff 113
ac155bb8
MS
114 if (u->manager->unit_path_cache &&
115 !set_get(u->manager->unit_path_cache, path))
99f08d14
LP
116 r = 0;
117 else
5926ccca 118 r = iterate_dir(u, path, dependency, strv);
99f08d14 119 free(path);
0301abf4 120
99f08d14
LP
121 if (r < 0)
122 return r;
0301abf4 123
ac155bb8 124 if (u->instance) {
99f08d14
LP
125 char *template;
126 /* Also try the template dir */
0301abf4 127
f917c3e5
LP
128 template = unit_name_template(name);
129 if (!template)
aa96c6cb 130 return log_oom();
0301abf4 131
b7def684 132 path = strjoin(unit_path, "/", template, suffix, NULL);
99f08d14 133 free(template);
0301abf4 134
cd0ed1db 135 if (!path)
aa96c6cb 136 return log_oom();
0301abf4 137
ac155bb8
MS
138 if (u->manager->unit_path_cache &&
139 !set_get(u->manager->unit_path_cache, path))
99f08d14
LP
140 r = 0;
141 else
5926ccca 142 r = iterate_dir(u, path, dependency, strv);
99f08d14 143 free(path);
0301abf4 144
99f08d14
LP
145 if (r < 0)
146 return r;
147 }
0301abf4 148
99f08d14
LP
149 return 0;
150}
0301abf4 151
ae7a7182 152char **unit_find_dropin_paths(Unit *u) {
5926ccca 153 _cleanup_strv_free_ char **strv = NULL;
ae7a7182 154 char **configs = NULL;
aa96c6cb
LP
155 Iterator i;
156 char *t;
5926ccca
LP
157 int r;
158
ae7a7182
OS
159 assert(u);
160
161 SET_FOREACH(t, u->names, i) {
162 char **p;
163
164 STRV_FOREACH(p, u->manager->lookup_paths.unit_path) {
165 /* This loads the drop-in config snippets */
166 r = process_dir(u, *p, t, ".d", _UNIT_DEPENDENCY_INVALID, &strv);
167 if (r < 0)
168 return NULL;
169 }
170 }
171
aa96c6cb
LP
172 if (strv_isempty(strv))
173 return NULL;
ae7a7182 174
aa96c6cb
LP
175 r = conf_files_list_strv(&configs, ".conf", NULL, (const char**) strv);
176 if (r < 0) {
177 log_error("Failed to get list of configuration files: %s", strerror(-r));
178 strv_free(configs);
179 return NULL;
ae7a7182
OS
180 }
181
182 return configs;
183}
184
185int unit_load_dropin(Unit *u) {
186 Iterator i;
187 char *t, **f;
ae7a7182 188 int r;
99f08d14
LP
189
190 assert(u);
191
192 /* Load dependencies from supplementary drop-in directories */
036643a2 193
ac155bb8 194 SET_FOREACH(t, u->names, i) {
99f08d14
LP
195 char **p;
196
ac155bb8 197 STRV_FOREACH(p, u->manager->lookup_paths.unit_path) {
5926ccca 198 r = process_dir(u, *p, t, ".wants", UNIT_WANTS, NULL);
f917c3e5 199 if (r < 0)
99f08d14
LP
200 return r;
201
5926ccca 202 r = process_dir(u, *p, t, ".requires", UNIT_REQUIRES, NULL);
f917c3e5 203 if (r < 0)
99f08d14 204 return r;
036643a2 205 }
0301abf4
LP
206 }
207
ae7a7182
OS
208 u->dropin_paths = unit_find_dropin_paths(u);
209 if (! u->dropin_paths)
210 return 0;
5926ccca 211
ae7a7182 212 STRV_FOREACH(f, u->dropin_paths) {
e8e581bf
ZJS
213 r = config_parse(u->id, *f, NULL,
214 UNIT_VTABLE(u)->sections, config_item_perf_lookup,
db5c0122 215 (void*) load_fragment_gperf_lookup, false, false, u);
ae7a7182 216 if (r < 0)
5926ccca 217 return r;
5926ccca
LP
218 }
219
ae7a7182
OS
220 u->dropin_mtime = now(CLOCK_REALTIME);
221
5cb5a6ff
LP
222 return 0;
223}