]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/load-dropin.c
bus-proxy: service_name_is_valid will never be < 0
[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
bcd816bd 61 log_error("Failed to open directory %s: %m", path);
9e2f7c11
LP
62 return -errno;
63 }
64
8afbb8e1
LP
65 for (;;) {
66 struct dirent *de;
8afbb8e1
LP
67 _cleanup_free_ char *f = NULL;
68 int k;
69
9fa30063
FW
70 errno = 0;
71 de = readdir(d);
72 if (!de && errno != 0) {
73 k = errno;
8afbb8e1
LP
74 log_error("Failed to read directory %s: %s", path, strerror(k));
75 return -k;
76 }
77
78 if (!de)
79 break;
9e2f7c11
LP
80
81 if (ignore_file(de->d_name))
82 continue;
83
b7def684 84 f = strjoin(path, "/", de->d_name, NULL);
8afbb8e1
LP
85 if (!f)
86 return log_oom();
9e2f7c11 87
5926ccca
LP
88 r = unit_add_dependency_by_name(u, dependency, de->d_name, f, true);
89 if (r < 0)
90 log_error("Cannot add dependency %s to %s, ignoring: %s", de->d_name, u->id, strerror(-r));
9e2f7c11
LP
91 }
92
8afbb8e1 93 return 0;
9e2f7c11 94}
5cb5a6ff 95
aa96c6cb
LP
96static int process_dir(
97 Unit *u,
98 const char *unit_path,
99 const char *name,
100 const char *suffix,
101 UnitDependency dependency,
102 char ***strv) {
103
fdb9161c 104 _cleanup_free_ char *path = NULL;
0301abf4 105
87f0e418 106 assert(u);
99f08d14
LP
107 assert(unit_path);
108 assert(name);
109 assert(suffix);
5cb5a6ff 110
b7def684 111 path = strjoin(unit_path, "/", name, suffix, NULL);
911a4828 112 if (!path)
aa96c6cb 113 return log_oom();
5cb5a6ff 114
bcd816bd
LP
115 if (!u->manager->unit_path_cache || set_get(u->manager->unit_path_cache, path))
116 iterate_dir(u, path, dependency, strv);
0301abf4 117
ac155bb8 118 if (u->instance) {
fdb9161c 119 _cleanup_free_ char *template = NULL, *p = NULL;
99f08d14 120 /* Also try the template dir */
0301abf4 121
f917c3e5
LP
122 template = unit_name_template(name);
123 if (!template)
aa96c6cb 124 return log_oom();
0301abf4 125
fdb9161c
LP
126 p = strjoin(unit_path, "/", template, suffix, NULL);
127 if (!p)
aa96c6cb 128 return log_oom();
0301abf4 129
bcd816bd
LP
130 if (!u->manager->unit_path_cache || set_get(u->manager->unit_path_cache, p))
131 iterate_dir(u, p, dependency, strv);
99f08d14 132 }
0301abf4 133
99f08d14
LP
134 return 0;
135}
0301abf4 136
ae7a7182 137char **unit_find_dropin_paths(Unit *u) {
5926ccca 138 _cleanup_strv_free_ char **strv = NULL;
ae7a7182 139 char **configs = NULL;
aa96c6cb
LP
140 Iterator i;
141 char *t;
5926ccca
LP
142 int r;
143
ae7a7182
OS
144 assert(u);
145
146 SET_FOREACH(t, u->names, i) {
147 char **p;
148
bcd816bd
LP
149 STRV_FOREACH(p, u->manager->lookup_paths.unit_path)
150 process_dir(u, *p, t, ".d", _UNIT_DEPENDENCY_INVALID, &strv);
ae7a7182
OS
151 }
152
aa96c6cb
LP
153 if (strv_isempty(strv))
154 return NULL;
ae7a7182 155
aa96c6cb
LP
156 r = conf_files_list_strv(&configs, ".conf", NULL, (const char**) strv);
157 if (r < 0) {
158 log_error("Failed to get list of configuration files: %s", strerror(-r));
159 strv_free(configs);
160 return NULL;
ae7a7182
OS
161 }
162
163 return configs;
164}
165
166int unit_load_dropin(Unit *u) {
167 Iterator i;
168 char *t, **f;
99f08d14
LP
169
170 assert(u);
171
172 /* Load dependencies from supplementary drop-in directories */
036643a2 173
ac155bb8 174 SET_FOREACH(t, u->names, i) {
99f08d14
LP
175 char **p;
176
ac155bb8 177 STRV_FOREACH(p, u->manager->lookup_paths.unit_path) {
bcd816bd
LP
178 process_dir(u, *p, t, ".wants", UNIT_WANTS, NULL);
179 process_dir(u, *p, t, ".requires", UNIT_REQUIRES, NULL);
036643a2 180 }
0301abf4
LP
181 }
182
ae7a7182
OS
183 u->dropin_paths = unit_find_dropin_paths(u);
184 if (! u->dropin_paths)
185 return 0;
5926ccca 186
ae7a7182 187 STRV_FOREACH(f, u->dropin_paths) {
bcd816bd 188 config_parse(u->id, *f, NULL,
36f822c4
ZJS
189 UNIT_VTABLE(u)->sections,
190 config_item_perf_lookup, load_fragment_gperf_lookup,
191 false, false, false, u);
5926ccca
LP
192 }
193
ae7a7182
OS
194 u->dropin_mtime = now(CLOCK_REALTIME);
195
5cb5a6ff
LP
196 return 0;
197}