]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/shared/udev-util.c
license: LGPL-2.1+ -> LGPL-2.1-or-later
[thirdparty/systemd.git] / src / shared / udev-util.c
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
b237a168 2
152d0efa 3#include <errno.h>
030a0d79 4#include <unistd.h>
b237a168 5
152d0efa 6#include "alloc-util.h"
f822c5d5 7#include "device-util.h"
686d13b9 8#include "env-file.h"
aea3253e 9#include "escape.h"
b237a168 10#include "log.h"
aea3253e 11#include "macro.h"
4b3ca79e 12#include "parse-util.h"
030a0d79 13#include "path-util.h"
e2099267 14#include "signal-util.h"
bc768f04 15#include "string-table.h"
b237a168
ZJS
16#include "string-util.h"
17#include "udev-util.h"
aea3253e 18#include "utf8.h"
b237a168 19
bc768f04
ZJS
20static const char* const resolve_name_timing_table[_RESOLVE_NAME_TIMING_MAX] = {
21 [RESOLVE_NAME_NEVER] = "never",
22 [RESOLVE_NAME_LATE] = "late",
23 [RESOLVE_NAME_EARLY] = "early",
24};
25
26DEFINE_STRING_TABLE_LOOKUP(resolve_name_timing, ResolveNameTiming);
27
4b3ca79e
ZJS
28int udev_parse_config_full(
29 unsigned *ret_children_max,
30 usec_t *ret_exec_delay_usec,
a14e7af1 31 usec_t *ret_event_timeout_usec,
e2099267
MS
32 ResolveNameTiming *ret_resolve_name_timing,
33 int *ret_timeout_signal) {
4b3ca79e 34
e2099267 35 _cleanup_free_ char *log_val = NULL, *children_max = NULL, *exec_delay = NULL, *event_timeout = NULL, *resolve_names = NULL, *timeout_signal = NULL;
b237a168
ZJS
36 int r;
37
aa8fbc74 38 r = parse_env_file(NULL, "/etc/udev/udev.conf",
4b3ca79e
ZJS
39 "udev_log", &log_val,
40 "children_max", &children_max,
41 "exec_delay", &exec_delay,
9b2934cb 42 "event_timeout", &event_timeout,
e2099267
MS
43 "resolve_names", &resolve_names,
44 "timeout_signal", &timeout_signal);
4b3ca79e 45 if (r == -ENOENT)
b237a168
ZJS
46 return 0;
47 if (r < 0)
48 return r;
49
4b3ca79e
ZJS
50 if (log_val) {
51 const char *log;
52 size_t n;
53
54 /* unquote */
55 n = strlen(log_val);
56 if (n >= 2 &&
57 ((log_val[0] == '"' && log_val[n-1] == '"') ||
58 (log_val[0] == '\'' && log_val[n-1] == '\''))) {
59 log_val[n - 1] = '\0';
60 log = log_val + 1;
61 } else
62 log = log_val;
63
64 /* we set the udev log level here explicitly, this is supposed
65 * to regulate the code in libudev/ and udev/. */
66 r = log_set_max_level_from_string_realm(LOG_REALM_UDEV, log);
67 if (r < 0)
d7921114
ZJS
68 log_syntax(NULL, LOG_WARNING, "/etc/udev/udev.conf", 0, r,
69 "failed to set udev log level '%s', ignoring: %m", log);
4b3ca79e
ZJS
70 }
71
72 if (ret_children_max && children_max) {
73 r = safe_atou(children_max, ret_children_max);
74 if (r < 0)
d7921114 75 log_syntax(NULL, LOG_WARNING, "/etc/udev/udev.conf", 0, r,
e2099267 76 "failed to parse children_max=%s, ignoring: %m", children_max);
4b3ca79e
ZJS
77 }
78
79 if (ret_exec_delay_usec && exec_delay) {
80 r = parse_sec(exec_delay, ret_exec_delay_usec);
81 if (r < 0)
d7921114 82 log_syntax(NULL, LOG_WARNING, "/etc/udev/udev.conf", 0, r,
e2099267 83 "failed to parse exec_delay=%s, ignoring: %m", exec_delay);
4b3ca79e
ZJS
84 }
85
86 if (ret_event_timeout_usec && event_timeout) {
87 r = parse_sec(event_timeout, ret_event_timeout_usec);
88 if (r < 0)
d7921114 89 log_syntax(NULL, LOG_WARNING, "/etc/udev/udev.conf", 0, r,
e2099267 90 "failed to parse event_timeout=%s, ignoring: %m", event_timeout);
4b3ca79e 91 }
b237a168 92
a14e7af1
ZJS
93 if (ret_resolve_name_timing && resolve_names) {
94 ResolveNameTiming t;
95
96 t = resolve_name_timing_from_string(resolve_names);
97 if (t < 0)
d7921114 98 log_syntax(NULL, LOG_WARNING, "/etc/udev/udev.conf", 0, r,
e2099267 99 "failed to parse resolve_names=%s, ignoring.", resolve_names);
a14e7af1
ZJS
100 else
101 *ret_resolve_name_timing = t;
102 }
e2099267
MS
103
104 if (ret_timeout_signal && timeout_signal) {
105 r = signal_from_string(timeout_signal);
106 if (r < 0)
107 log_syntax(NULL, LOG_WARNING, "/etc/udev/udev.conf", 0, r,
108 "failed to parse timeout_signal=%s, ignoring: %m", timeout_signal);
109 else
110 *ret_timeout_signal = r;
111 }
a14e7af1 112
b237a168
ZJS
113 return 0;
114}
ed435031 115
030a0d79
LB
116/* Note that if -ENOENT is returned, it will be logged at debug level rather than error,
117 * because it's an expected, common occurrence that the caller will handle with a fallback */
118static int device_new_from_dev_path(const char *devlink, sd_device **ret_device) {
119 struct stat st;
120 int r;
121
122 assert(devlink);
123
fe79f107
ZJS
124 if (stat(devlink, &st) < 0)
125 return log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_ERR, errno,
126 "Failed to stat() %s: %m", devlink);
030a0d79
LB
127
128 if (!S_ISBLK(st.st_mode))
fe79f107
ZJS
129 return log_error_errno(SYNTHETIC_ERRNO(ENOTBLK),
130 "%s does not point to a block device: %m", devlink);
030a0d79
LB
131
132 r = sd_device_new_from_devnum(ret_device, 'b', st.st_rdev);
133 if (r < 0)
134 return log_error_errno(r, "Failed to initialize device from %s: %m", devlink);
135
136 return 0;
137}
138
ed435031
ZJS
139struct DeviceMonitorData {
140 const char *sysname;
030a0d79 141 const char *devlink;
ed435031
ZJS
142 sd_device *device;
143};
144
ce5eef65
LB
145static void device_monitor_data_free(struct DeviceMonitorData *d) {
146 assert(d);
147
148 sd_device_unref(d->device);
149}
150
ed435031
ZJS
151static int device_monitor_handler(sd_device_monitor *monitor, sd_device *device, void *userdata) {
152 struct DeviceMonitorData *data = userdata;
153 const char *sysname;
154
155 assert(device);
156 assert(data);
030a0d79 157 assert(data->sysname || data->devlink);
ed435031
ZJS
158 assert(!data->device);
159
e13d96ca
LP
160 /* Ignore REMOVE events here. We are waiting for initialization after all, not de-initialization. We
161 * might see a REMOVE event from an earlier use of the device (devices by the same name are recycled
162 * by the kernel after all), which we should not get confused by. After all we cannot distinguish use
163 * cycles of the devices, as the udev queue is entirely asynchronous.
164 *
165 * If we see a REMOVE event here for the use cycle we actually care about then we won't notice of
166 * course, but that should be OK, given the timeout logic used on the wait loop: this will be noticed
167 * by means of -ETIMEDOUT. Thus we won't notice immediately, but eventually, and that should be
168 * sufficient for an error path that should regularly not happen.
169 *
170 * (And yes, we only need to special case REMOVE. It's the only "negative" event type, where a device
171 * ceases to exist. All other event types are "positive": the device exists and is registered in the
172 * udev database, thus whenever we see the event, we can consider it initialized.) */
173 if (device_for_action(device, DEVICE_ACTION_REMOVE))
174 return 0;
175
030a0d79
LB
176 if (data->sysname && sd_device_get_sysname(device, &sysname) >= 0 && streq(sysname, data->sysname))
177 goto found;
178
179 if (data->devlink) {
180 const char *devlink;
181
182 FOREACH_DEVICE_DEVLINK(device, devlink)
183 if (path_equal(devlink, data->devlink))
184 goto found;
185
186 if (sd_device_get_devname(device, &devlink) >= 0 && path_equal(devlink, data->devlink))
187 goto found;
ed435031
ZJS
188 }
189
190 return 0;
030a0d79
LB
191
192found:
193 data->device = sd_device_ref(device);
194 return sd_event_exit(sd_device_monitor_get_event(monitor), 0);
ed435031
ZJS
195}
196
030a0d79
LB
197static int device_wait_for_initialization_internal(
198 sd_device *_device,
199 const char *devlink,
200 const char *subsystem,
9e3d9067 201 usec_t deadline,
030a0d79 202 sd_device **ret) {
9e3d9067 203
ed435031 204 _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor = NULL;
1b47436e 205 _cleanup_(sd_event_source_unrefp) sd_event_source *timeout_source = NULL;
ed435031 206 _cleanup_(sd_event_unrefp) sd_event *event = NULL;
030a0d79
LB
207 /* Ensure that if !_device && devlink, device gets unrefd on errors since it will be new */
208 _cleanup_(sd_device_unrefp) sd_device *device = sd_device_ref(_device);
ce5eef65 209 _cleanup_(device_monitor_data_free) struct DeviceMonitorData data = {
030a0d79
LB
210 .devlink = devlink,
211 };
ed435031
ZJS
212 int r;
213
030a0d79 214 assert(device || (subsystem && devlink));
ed435031 215
030a0d79
LB
216 /* Devlink might already exist, if it does get the device to use the sysname filtering */
217 if (!device && devlink) {
218 r = device_new_from_dev_path(devlink, &device);
219 if (r < 0 && r != -ENOENT)
220 return r;
ed435031
ZJS
221 }
222
030a0d79
LB
223 if (device) {
224 if (sd_device_get_is_initialized(device) > 0) {
225 if (ret)
226 *ret = sd_device_ref(device);
227 return 0;
228 }
229 /* We need either the sysname or the devlink for filtering */
230 assert_se(sd_device_get_sysname(device, &data.sysname) >= 0 || devlink);
231 }
ed435031
ZJS
232
233 /* Wait until the device is initialized, so that we can get access to the ID_PATH property */
234
fc40bfa7 235 r = sd_event_new(&event);
ed435031
ZJS
236 if (r < 0)
237 return log_error_errno(r, "Failed to get default event: %m");
238
239 r = sd_device_monitor_new(&monitor);
240 if (r < 0)
241 return log_error_errno(r, "Failed to acquire monitor: %m");
242
030a0d79 243 if (device && !subsystem) {
f822c5d5
YW
244 r = sd_device_get_subsystem(device, &subsystem);
245 if (r < 0 && r != -ENOENT)
246 return log_device_error_errno(device, r, "Failed to get subsystem: %m");
247 }
248
249 if (subsystem) {
250 r = sd_device_monitor_filter_add_match_subsystem_devtype(monitor, subsystem, NULL);
251 if (r < 0)
252 return log_error_errno(r, "Failed to add %s subsystem match to monitor: %m", subsystem);
253 }
ed435031
ZJS
254
255 r = sd_device_monitor_attach_event(monitor, event);
256 if (r < 0)
257 return log_error_errno(r, "Failed to attach event to device monitor: %m");
258
259 r = sd_device_monitor_start(monitor, device_monitor_handler, &data);
260 if (r < 0)
261 return log_error_errno(r, "Failed to start device monitor: %m");
262
9e3d9067
LP
263 if (deadline != USEC_INFINITY) {
264 r = sd_event_add_time(
39cf0351 265 event, &timeout_source,
9e3d9067 266 CLOCK_MONOTONIC, deadline, 0,
bac0bfc1 267 NULL, INT_TO_PTR(-ETIMEDOUT));
1b47436e
YW
268 if (r < 0)
269 return log_error_errno(r, "Failed to add timeout event source: %m");
270 }
271
ed435031
ZJS
272 /* Check again, maybe things changed. Udev will re-read the db if the device wasn't initialized
273 * yet. */
030a0d79
LB
274 if (!device && devlink) {
275 r = device_new_from_dev_path(devlink, &device);
276 if (r < 0 && r != -ENOENT)
277 return r;
278 }
279 if (device && sd_device_get_is_initialized(device) > 0) {
ed435031
ZJS
280 if (ret)
281 *ret = sd_device_ref(device);
282 return 0;
283 }
284
285 r = sd_event_loop(event);
286 if (r < 0)
1b47436e 287 return log_error_errno(r, "Failed to wait for device to be initialized: %m");
ed435031
ZJS
288
289 if (ret)
290 *ret = TAKE_PTR(data.device);
291 return 0;
292}
90ba130f 293
9e3d9067
LP
294int device_wait_for_initialization(sd_device *device, const char *subsystem, usec_t deadline, sd_device **ret) {
295 return device_wait_for_initialization_internal(device, NULL, subsystem, deadline, ret);
030a0d79
LB
296}
297
9e3d9067
LP
298int device_wait_for_devlink(const char *devlink, const char *subsystem, usec_t deadline, sd_device **ret) {
299 return device_wait_for_initialization_internal(NULL, devlink, subsystem, deadline, ret);
030a0d79
LB
300}
301
90ba130f
YW
302int device_is_renaming(sd_device *dev) {
303 int r;
304
305 assert(dev);
306
307 r = sd_device_get_property_value(dev, "ID_RENAMING", NULL);
b9daaedb
LP
308 if (r == -ENOENT)
309 return false;
310 if (r < 0)
90ba130f
YW
311 return r;
312
b9daaedb 313 return true;
90ba130f 314}
a707c65b
YW
315
316bool device_for_action(sd_device *dev, DeviceAction action) {
317 DeviceAction a;
318
319 assert(dev);
320
321 if (device_get_action(dev, &a) < 0)
322 return false;
323
324 return a == action;
325}
aea3253e
YLY
326
327int udev_rule_parse_value(char *str, char **ret_value, char **ret_endpos) {
328 char *i, *j;
329 int r;
330 bool is_escaped;
331
332 /* value must be double quotated */
333 is_escaped = str[0] == 'e';
334 str += is_escaped;
335 if (str[0] != '"')
336 return -EINVAL;
337 str++;
338
339 if (!is_escaped) {
340 /* unescape double quotation '\"'->'"' */
341 for (i = j = str; *i != '"'; i++, j++) {
342 if (*i == '\0')
343 return -EINVAL;
344 if (i[0] == '\\' && i[1] == '"')
345 i++;
346 *j = *i;
347 }
348 j[0] = '\0';
349 } else {
350 _cleanup_free_ char *unescaped = NULL;
351
352 /* find the end position of value */
353 for (i = str; *i != '"'; i++) {
354 if (i[0] == '\\')
355 i++;
356 if (*i == '\0')
357 return -EINVAL;
358 }
359 i[0] = '\0';
360
361 r = cunescape_length(str, i - str, 0, &unescaped);
362 if (r < 0)
363 return r;
364 assert(r <= i - str);
365 memcpy(str, unescaped, r + 1);
366 }
367
368 *ret_value = str;
369 *ret_endpos = i + 1;
370 return 0;
371}