1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
5 #include <sys/inotify.h>
8 #include "alloc-util.h"
9 #include "device-nodes.h"
10 #include "device-util.h"
16 #include "parse-util.h"
17 #include "path-util.h"
18 #include "signal-util.h"
19 #include "string-table.h"
20 #include "string-util.h"
22 #include "udev-util.h"
25 static const char* const resolve_name_timing_table
[_RESOLVE_NAME_TIMING_MAX
] = {
26 [RESOLVE_NAME_NEVER
] = "never",
27 [RESOLVE_NAME_LATE
] = "late",
28 [RESOLVE_NAME_EARLY
] = "early",
31 DEFINE_STRING_TABLE_LOOKUP(resolve_name_timing
, ResolveNameTiming
);
33 int udev_parse_config_full(
34 unsigned *ret_children_max
,
35 usec_t
*ret_exec_delay_usec
,
36 usec_t
*ret_event_timeout_usec
,
37 ResolveNameTiming
*ret_resolve_name_timing
,
38 int *ret_timeout_signal
) {
40 _cleanup_free_
char *log_val
= NULL
, *children_max
= NULL
, *exec_delay
= NULL
, *event_timeout
= NULL
, *resolve_names
= NULL
, *timeout_signal
= NULL
;
43 r
= parse_env_file(NULL
, "/etc/udev/udev.conf",
45 "children_max", &children_max
,
46 "exec_delay", &exec_delay
,
47 "event_timeout", &event_timeout
,
48 "resolve_names", &resolve_names
,
49 "timeout_signal", &timeout_signal
);
62 ((log_val
[0] == '"' && log_val
[n
-1] == '"') ||
63 (log_val
[0] == '\'' && log_val
[n
-1] == '\''))) {
64 log_val
[n
- 1] = '\0';
69 /* we set the udev log level here explicitly, this is supposed
70 * to regulate the code in libudev/ and udev/. */
71 r
= log_set_max_level_from_string(log
);
73 log_syntax(NULL
, LOG_WARNING
, "/etc/udev/udev.conf", 0, r
,
74 "failed to set udev log level '%s', ignoring: %m", log
);
77 if (ret_children_max
&& children_max
) {
78 r
= safe_atou(children_max
, ret_children_max
);
80 log_syntax(NULL
, LOG_WARNING
, "/etc/udev/udev.conf", 0, r
,
81 "failed to parse children_max=%s, ignoring: %m", children_max
);
84 if (ret_exec_delay_usec
&& exec_delay
) {
85 r
= parse_sec(exec_delay
, ret_exec_delay_usec
);
87 log_syntax(NULL
, LOG_WARNING
, "/etc/udev/udev.conf", 0, r
,
88 "failed to parse exec_delay=%s, ignoring: %m", exec_delay
);
91 if (ret_event_timeout_usec
&& event_timeout
) {
92 r
= parse_sec(event_timeout
, ret_event_timeout_usec
);
94 log_syntax(NULL
, LOG_WARNING
, "/etc/udev/udev.conf", 0, r
,
95 "failed to parse event_timeout=%s, ignoring: %m", event_timeout
);
98 if (ret_resolve_name_timing
&& resolve_names
) {
101 t
= resolve_name_timing_from_string(resolve_names
);
103 log_syntax(NULL
, LOG_WARNING
, "/etc/udev/udev.conf", 0, r
,
104 "failed to parse resolve_names=%s, ignoring.", resolve_names
);
106 *ret_resolve_name_timing
= t
;
109 if (ret_timeout_signal
&& timeout_signal
) {
110 r
= signal_from_string(timeout_signal
);
112 log_syntax(NULL
, LOG_WARNING
, "/etc/udev/udev.conf", 0, r
,
113 "failed to parse timeout_signal=%s, ignoring: %m", timeout_signal
);
115 *ret_timeout_signal
= r
;
121 /* Note that if -ENOENT is returned, it will be logged at debug level rather than error,
122 * because it's an expected, common occurrence that the caller will handle with a fallback */
123 static int device_new_from_dev_path(const char *devlink
, sd_device
**ret_device
) {
129 if (stat(devlink
, &st
) < 0)
130 return log_full_errno(errno
== ENOENT
? LOG_DEBUG
: LOG_ERR
, errno
,
131 "Failed to stat() %s: %m", devlink
);
133 if (!S_ISBLK(st
.st_mode
))
134 return log_error_errno(SYNTHETIC_ERRNO(ENOTBLK
),
135 "%s does not point to a block device: %m", devlink
);
137 r
= sd_device_new_from_devnum(ret_device
, 'b', st
.st_rdev
);
139 return log_error_errno(r
, "Failed to initialize device from %s: %m", devlink
);
144 struct DeviceMonitorData
{
150 static void device_monitor_data_free(struct DeviceMonitorData
*d
) {
153 sd_device_unref(d
->device
);
156 static int device_monitor_handler(sd_device_monitor
*monitor
, sd_device
*device
, void *userdata
) {
157 struct DeviceMonitorData
*data
= userdata
;
162 assert(data
->sysname
|| data
->devlink
);
163 assert(!data
->device
);
165 /* Ignore REMOVE events here. We are waiting for initialization after all, not de-initialization. We
166 * might see a REMOVE event from an earlier use of the device (devices by the same name are recycled
167 * by the kernel after all), which we should not get confused by. After all we cannot distinguish use
168 * cycles of the devices, as the udev queue is entirely asynchronous.
170 * If we see a REMOVE event here for the use cycle we actually care about then we won't notice of
171 * course, but that should be OK, given the timeout logic used on the wait loop: this will be noticed
172 * by means of -ETIMEDOUT. Thus we won't notice immediately, but eventually, and that should be
173 * sufficient for an error path that should regularly not happen.
175 * (And yes, we only need to special case REMOVE. It's the only "negative" event type, where a device
176 * ceases to exist. All other event types are "positive": the device exists and is registered in the
177 * udev database, thus whenever we see the event, we can consider it initialized.) */
178 if (device_for_action(device
, DEVICE_ACTION_REMOVE
))
181 if (data
->sysname
&& sd_device_get_sysname(device
, &sysname
) >= 0 && streq(sysname
, data
->sysname
))
187 FOREACH_DEVICE_DEVLINK(device
, devlink
)
188 if (path_equal(devlink
, data
->devlink
))
191 if (sd_device_get_devname(device
, &devlink
) >= 0 && path_equal(devlink
, data
->devlink
))
198 data
->device
= sd_device_ref(device
);
199 return sd_event_exit(sd_device_monitor_get_event(monitor
), 0);
202 static int device_wait_for_initialization_internal(
205 const char *subsystem
,
209 _cleanup_(sd_device_monitor_unrefp
) sd_device_monitor
*monitor
= NULL
;
210 _cleanup_(sd_event_source_unrefp
) sd_event_source
*timeout_source
= NULL
;
211 _cleanup_(sd_event_unrefp
) sd_event
*event
= NULL
;
212 /* Ensure that if !_device && devlink, device gets unrefd on errors since it will be new */
213 _cleanup_(sd_device_unrefp
) sd_device
*device
= sd_device_ref(_device
);
214 _cleanup_(device_monitor_data_free
) struct DeviceMonitorData data
= {
219 assert(device
|| (subsystem
&& devlink
));
221 /* Devlink might already exist, if it does get the device to use the sysname filtering */
222 if (!device
&& devlink
) {
223 r
= device_new_from_dev_path(devlink
, &device
);
224 if (r
< 0 && r
!= -ENOENT
)
229 if (sd_device_get_is_initialized(device
) > 0) {
231 *ret
= sd_device_ref(device
);
234 /* We need either the sysname or the devlink for filtering */
235 assert_se(sd_device_get_sysname(device
, &data
.sysname
) >= 0 || devlink
);
238 /* Wait until the device is initialized, so that we can get access to the ID_PATH property */
240 r
= sd_event_new(&event
);
242 return log_error_errno(r
, "Failed to get default event: %m");
244 r
= sd_device_monitor_new(&monitor
);
246 return log_error_errno(r
, "Failed to acquire monitor: %m");
248 if (device
&& !subsystem
) {
249 r
= sd_device_get_subsystem(device
, &subsystem
);
250 if (r
< 0 && r
!= -ENOENT
)
251 return log_device_error_errno(device
, r
, "Failed to get subsystem: %m");
255 r
= sd_device_monitor_filter_add_match_subsystem_devtype(monitor
, subsystem
, NULL
);
257 return log_error_errno(r
, "Failed to add %s subsystem match to monitor: %m", subsystem
);
260 r
= sd_device_monitor_attach_event(monitor
, event
);
262 return log_error_errno(r
, "Failed to attach event to device monitor: %m");
264 r
= sd_device_monitor_start(monitor
, device_monitor_handler
, &data
);
266 return log_error_errno(r
, "Failed to start device monitor: %m");
268 if (deadline
!= USEC_INFINITY
) {
269 r
= sd_event_add_time(
270 event
, &timeout_source
,
271 CLOCK_MONOTONIC
, deadline
, 0,
272 NULL
, INT_TO_PTR(-ETIMEDOUT
));
274 return log_error_errno(r
, "Failed to add timeout event source: %m");
277 /* Check again, maybe things changed. Udev will re-read the db if the device wasn't initialized
279 if (!device
&& devlink
) {
280 r
= device_new_from_dev_path(devlink
, &device
);
281 if (r
< 0 && r
!= -ENOENT
)
284 if (device
&& sd_device_get_is_initialized(device
) > 0) {
286 *ret
= sd_device_ref(device
);
290 r
= sd_event_loop(event
);
292 return log_error_errno(r
, "Failed to wait for device to be initialized: %m");
295 *ret
= TAKE_PTR(data
.device
);
299 int device_wait_for_initialization(sd_device
*device
, const char *subsystem
, usec_t deadline
, sd_device
**ret
) {
300 return device_wait_for_initialization_internal(device
, NULL
, subsystem
, deadline
, ret
);
303 int device_wait_for_devlink(const char *devlink
, const char *subsystem
, usec_t deadline
, sd_device
**ret
) {
304 return device_wait_for_initialization_internal(NULL
, devlink
, subsystem
, deadline
, ret
);
307 int device_is_renaming(sd_device
*dev
) {
312 r
= sd_device_get_property_value(dev
, "ID_RENAMING", NULL
);
321 bool device_for_action(sd_device
*dev
, DeviceAction action
) {
326 if (device_get_action(dev
, &a
) < 0)
332 void log_device_uevent(sd_device
*device
, const char *str
) {
333 DeviceAction action
= _DEVICE_ACTION_INVALID
;
339 (void) device_get_seqnum(device
, &seqnum
);
340 (void) device_get_action(device
, &action
);
341 log_device_debug(device
, "%s%s(SEQNUM=%"PRIu64
", ACTION=%s)",
342 strempty(str
), isempty(str
) ? "" : " ",
343 seqnum
, strna(device_action_to_string(action
)));
346 int udev_rule_parse_value(char *str
, char **ret_value
, char **ret_endpos
) {
351 /* value must be double quotated */
352 is_escaped
= str
[0] == 'e';
359 /* unescape double quotation '\"'->'"' */
360 for (i
= j
= str
; *i
!= '"'; i
++, j
++) {
363 if (i
[0] == '\\' && i
[1] == '"')
369 _cleanup_free_
char *unescaped
= NULL
;
371 /* find the end position of value */
372 for (i
= str
; *i
!= '"'; i
++) {
380 r
= cunescape_length(str
, i
- str
, 0, &unescaped
);
383 assert(r
<= i
- str
);
384 memcpy(str
, unescaped
, r
+ 1);
392 size_t udev_replace_whitespace(const char *str
, char *to
, size_t len
) {
393 bool is_space
= false;
399 /* Copy from 'str' to 'to', while removing all leading and trailing whitespace, and replacing
400 * each run of consecutive whitespace with a single underscore. The chars from 'str' are copied
401 * up to the \0 at the end of the string, or at most 'len' chars. This appends \0 to 'to', at
402 * the end of the copied characters.
404 * If 'len' chars are copied into 'to', the final \0 is placed at len+1 (i.e. 'to[len] = \0'),
405 * so the 'to' buffer must have at least len+1 chars available.
407 * Note this may be called with 'str' == 'to', i.e. to replace whitespace in-place in a buffer.
408 * This function can handle that situation.
410 * Note that only 'len' characters are read from 'str'. */
412 i
= strspn(str
, WHITESPACE
);
414 for (j
= 0; j
< len
&& i
< len
&& str
[i
] != '\0'; i
++) {
415 if (isspace(str
[i
])) {
434 size_t udev_replace_chars(char *str
, const char *allow
) {
435 size_t i
= 0, replaced
= 0;
439 /* allow chars in allow list, plain ascii, hex-escaping and valid utf8. */
441 while (str
[i
] != '\0') {
444 if (allow_listed_char_for_devnode(str
[i
], allow
)) {
449 /* accept hex encoding */
450 if (str
[i
] == '\\' && str
[i
+1] == 'x') {
455 /* accept valid utf8 */
456 len
= utf8_encoded_valid_unichar(str
+ i
, (size_t) -1);
462 /* if space is allowed, replace whitespace with ordinary space */
463 if (isspace(str
[i
]) && allow
&& strchr(allow
, ' ')) {
470 /* everything else is replaced with '_' */
478 int udev_resolve_subsys_kernel(const char *string
, char *result
, size_t maxsize
, bool read_value
) {
479 _cleanup_(sd_device_unrefp
) sd_device
*dev
= NULL
;
480 _cleanup_free_
char *temp
= NULL
;
481 char *subsys
, *sysname
, *attr
;
488 /* handle "[<SUBSYSTEM>/<KERNEL>]<attribute>" format */
490 if (string
[0] != '[')
493 temp
= strdup(string
);
499 sysname
= strchr(subsys
, '/');
503 sysname
= &sysname
[1];
505 attr
= strchr(sysname
, ']');
515 if (read_value
&& !attr
)
518 r
= sd_device_new_from_subsystem_sysname(&dev
, subsys
, sysname
);
523 r
= sd_device_get_sysattr_value(dev
, attr
, &val
);
524 if (r
< 0 && r
!= -ENOENT
)
529 strscpy(result
, maxsize
, val
);
530 log_debug("value '[%s/%s]%s' is '%s'", subsys
, sysname
, attr
, result
);
532 r
= sd_device_get_syspath(dev
, &val
);
536 strscpyl(result
, maxsize
, val
, attr
? "/" : NULL
, attr
?: NULL
, NULL
);
537 log_debug("path '[%s/%s]%s' is '%s'", subsys
, sysname
, strempty(attr
), result
);
542 int udev_queue_is_empty(void) {
543 return access("/run/udev/queue", F_OK
) < 0 ?
544 (errno
== ENOENT
? true : -errno
) : false;
547 int udev_queue_init(void) {
548 _cleanup_close_
int fd
= -1;
550 fd
= inotify_init1(IN_CLOEXEC
);
554 if (inotify_add_watch(fd
, "/run/udev" , IN_DELETE
) < 0)