]> git.proxmox.com Git - systemd.git/blob - src/udev/udev-event.c
New upstream version 240
[systemd.git] / src / udev / udev-event.c
1 /* SPDX-License-Identifier: GPL-2.0+ */
2
3 #include <ctype.h>
4 #include <errno.h>
5 #include <fcntl.h>
6 #include <net/if.h>
7 #include <stddef.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <unistd.h>
11
12 #include "sd-event.h"
13
14 #include "alloc-util.h"
15 #include "device-private.h"
16 #include "device-util.h"
17 #include "fd-util.h"
18 #include "format-util.h"
19 #include "libudev-util.h"
20 #include "netlink-util.h"
21 #include "path-util.h"
22 #include "process-util.h"
23 #include "rlimit-util.h"
24 #include "signal-util.h"
25 #include "stdio-util.h"
26 #include "string-util.h"
27 #include "strv.h"
28 #include "strxcpyx.h"
29 #include "udev-builtin.h"
30 #include "udev-node.h"
31 #include "udev-watch.h"
32 #include "udev.h"
33
34 typedef struct Spawn {
35 const char *cmd;
36 pid_t pid;
37 usec_t timeout_warn_usec;
38 usec_t timeout_usec;
39 usec_t event_birth_usec;
40 bool accept_failure;
41 int fd_stdout;
42 int fd_stderr;
43 char *result;
44 size_t result_size;
45 size_t result_len;
46 } Spawn;
47
48 UdevEvent *udev_event_new(sd_device *dev, usec_t exec_delay_usec, sd_netlink *rtnl) {
49 UdevEvent *event;
50
51 assert(dev);
52
53 event = new(UdevEvent, 1);
54 if (!event)
55 return NULL;
56
57 *event = (UdevEvent) {
58 .dev = sd_device_ref(dev),
59 .birth_usec = now(CLOCK_MONOTONIC),
60 .exec_delay_usec = exec_delay_usec,
61 .rtnl = sd_netlink_ref(rtnl),
62 };
63
64 return event;
65 }
66
67 UdevEvent *udev_event_free(UdevEvent *event) {
68 if (!event)
69 return NULL;
70
71 sd_device_unref(event->dev);
72 sd_device_unref(event->dev_db_clone);
73 sd_netlink_unref(event->rtnl);
74 hashmap_free_free_key(event->run_list);
75 hashmap_free_free_free(event->seclabel_list);
76 free(event->program_result);
77 free(event->name);
78
79 return mfree(event);
80 }
81
82 enum subst_type {
83 SUBST_DEVNODE,
84 SUBST_ATTR,
85 SUBST_ENV,
86 SUBST_KERNEL,
87 SUBST_KERNEL_NUMBER,
88 SUBST_DRIVER,
89 SUBST_DEVPATH,
90 SUBST_ID,
91 SUBST_MAJOR,
92 SUBST_MINOR,
93 SUBST_RESULT,
94 SUBST_PARENT,
95 SUBST_NAME,
96 SUBST_LINKS,
97 SUBST_ROOT,
98 SUBST_SYS,
99 };
100
101 struct subst_map_entry {
102 const char *name;
103 const char fmt;
104 enum subst_type type;
105 };
106
107 static const struct subst_map_entry map[] = {
108 { .name = "devnode", .fmt = 'N', .type = SUBST_DEVNODE },
109 { .name = "tempnode", .fmt = 'N', .type = SUBST_DEVNODE },
110 { .name = "attr", .fmt = 's', .type = SUBST_ATTR },
111 { .name = "sysfs", .fmt = 's', .type = SUBST_ATTR },
112 { .name = "env", .fmt = 'E', .type = SUBST_ENV },
113 { .name = "kernel", .fmt = 'k', .type = SUBST_KERNEL },
114 { .name = "number", .fmt = 'n', .type = SUBST_KERNEL_NUMBER },
115 { .name = "driver", .fmt = 'd', .type = SUBST_DRIVER },
116 { .name = "devpath", .fmt = 'p', .type = SUBST_DEVPATH },
117 { .name = "id", .fmt = 'b', .type = SUBST_ID },
118 { .name = "major", .fmt = 'M', .type = SUBST_MAJOR },
119 { .name = "minor", .fmt = 'm', .type = SUBST_MINOR },
120 { .name = "result", .fmt = 'c', .type = SUBST_RESULT },
121 { .name = "parent", .fmt = 'P', .type = SUBST_PARENT },
122 { .name = "name", .fmt = 'D', .type = SUBST_NAME },
123 { .name = "links", .fmt = 'L', .type = SUBST_LINKS },
124 { .name = "root", .fmt = 'r', .type = SUBST_ROOT },
125 { .name = "sys", .fmt = 'S', .type = SUBST_SYS },
126 };
127
128 static ssize_t subst_format_var(UdevEvent *event,
129 const struct subst_map_entry *entry, char *attr,
130 char *dest, size_t l) {
131 sd_device *parent, *dev = event->dev;
132 const char *val = NULL;
133 char *s = dest;
134 dev_t devnum;
135 int r;
136
137 assert(entry);
138
139 switch (entry->type) {
140 case SUBST_DEVPATH:
141 r = sd_device_get_devpath(dev, &val);
142 if (r < 0)
143 return r;
144 l = strpcpy(&s, l, val);
145 break;
146 case SUBST_KERNEL:
147 r = sd_device_get_sysname(dev, &val);
148 if (r < 0)
149 return r;
150 l = strpcpy(&s, l, val);
151 break;
152 case SUBST_KERNEL_NUMBER:
153 r = sd_device_get_sysnum(dev, &val);
154 if (r < 0)
155 return r == -ENOENT ? 0 : r;
156 l = strpcpy(&s, l, val);
157 break;
158 case SUBST_ID:
159 if (!event->dev_parent)
160 return 0;
161 r = sd_device_get_sysname(event->dev_parent, &val);
162 if (r < 0)
163 return r;
164 l = strpcpy(&s, l, val);
165 break;
166 case SUBST_DRIVER:
167 if (!event->dev_parent)
168 return 0;
169 r = sd_device_get_driver(event->dev_parent, &val);
170 if (r < 0)
171 return r == -ENOENT ? 0 : r;
172 l = strpcpy(&s, l, val);
173 break;
174 case SUBST_MAJOR:
175 case SUBST_MINOR: {
176 char buf[DECIMAL_STR_MAX(unsigned)];
177
178 r = sd_device_get_devnum(dev, &devnum);
179 if (r < 0 && r != -ENOENT)
180 return r;
181 xsprintf(buf, "%u", r < 0 ? 0 : entry->type == SUBST_MAJOR ? major(devnum) : minor(devnum));
182 l = strpcpy(&s, l, buf);
183 break;
184 }
185 case SUBST_RESULT: {
186 char *rest;
187 int i;
188
189 if (!event->program_result)
190 return 0;
191
192 /* get part of the result string */
193 i = 0;
194 if (attr)
195 i = strtoul(attr, &rest, 10);
196 if (i > 0) {
197 char result[UTIL_PATH_SIZE], tmp[UTIL_PATH_SIZE], *cpos;
198
199 strscpy(result, sizeof(result), event->program_result);
200 cpos = result;
201 while (--i) {
202 while (cpos[0] != '\0' && !isspace(cpos[0]))
203 cpos++;
204 while (isspace(cpos[0]))
205 cpos++;
206 if (cpos[0] == '\0')
207 break;
208 }
209 if (i > 0) {
210 log_error("requested part of result string not found");
211 break;
212 }
213 strscpy(tmp, sizeof(tmp), cpos);
214 /* %{2+}c copies the whole string from the second part on */
215 if (rest[0] != '+') {
216 cpos = strchr(tmp, ' ');
217 if (cpos)
218 cpos[0] = '\0';
219 }
220 l = strpcpy(&s, l, tmp);
221 } else
222 l = strpcpy(&s, l, event->program_result);
223 break;
224 }
225 case SUBST_ATTR: {
226 char vbuf[UTIL_NAME_SIZE];
227 size_t len;
228 int count;
229
230 if (!attr)
231 return -EINVAL;
232
233 /* try to read the value specified by "[dmi/id]product_name" */
234 if (util_resolve_subsys_kernel(attr, vbuf, sizeof(vbuf), true) == 0)
235 val = vbuf;
236
237 /* try to read the attribute the device */
238 if (!val)
239 (void) sd_device_get_sysattr_value(dev, attr, &val);
240
241 /* try to read the attribute of the parent device, other matches have selected */
242 if (!val && event->dev_parent && event->dev_parent != dev)
243 (void) sd_device_get_sysattr_value(event->dev_parent, attr, &val);
244
245 if (!val)
246 return 0;
247
248 /* strip trailing whitespace, and replace unwanted characters */
249 if (val != vbuf)
250 strscpy(vbuf, sizeof(vbuf), val);
251 len = strlen(vbuf);
252 while (len > 0 && isspace(vbuf[--len]))
253 vbuf[len] = '\0';
254 count = util_replace_chars(vbuf, UDEV_ALLOWED_CHARS_INPUT);
255 if (count > 0)
256 log_device_debug(dev, "%i character(s) replaced", count);
257 l = strpcpy(&s, l, vbuf);
258 break;
259 }
260 case SUBST_PARENT:
261 r = sd_device_get_parent(dev, &parent);
262 if (r < 0)
263 return r == -ENODEV ? 0 : r;
264 r = sd_device_get_devname(parent, &val);
265 if (r < 0)
266 return r == -ENOENT ? 0 : r;
267 l = strpcpy(&s, l, val + STRLEN("/dev/"));
268 break;
269 case SUBST_DEVNODE:
270 r = sd_device_get_devname(dev, &val);
271 if (r < 0)
272 return r == -ENOENT ? 0 : r;
273 l = strpcpy(&s, l, val);
274 break;
275 case SUBST_NAME:
276 if (event->name)
277 l = strpcpy(&s, l, event->name);
278 else if (sd_device_get_devname(dev, &val) >= 0)
279 l = strpcpy(&s, l, val + STRLEN("/dev/"));
280 else {
281 r = sd_device_get_sysname(dev, &val);
282 if (r < 0)
283 return r;
284 l = strpcpy(&s, l, val);
285 }
286 break;
287 case SUBST_LINKS:
288 FOREACH_DEVICE_DEVLINK(dev, val)
289 if (s == dest)
290 l = strpcpy(&s, l, val + STRLEN("/dev/"));
291 else
292 l = strpcpyl(&s, l, " ", val + STRLEN("/dev/"), NULL);
293 break;
294 case SUBST_ROOT:
295 l = strpcpy(&s, l, "/dev");
296 break;
297 case SUBST_SYS:
298 l = strpcpy(&s, l, "/sys");
299 break;
300 case SUBST_ENV:
301 if (!attr)
302 return 0;
303 r = sd_device_get_property_value(dev, attr, &val);
304 if (r < 0)
305 return r == -ENOENT ? 0 : r;
306 l = strpcpy(&s, l, val);
307 break;
308 default:
309 assert_not_reached("Unknown format substitution type");
310 }
311
312 return s - dest;
313 }
314
315 ssize_t udev_event_apply_format(UdevEvent *event,
316 const char *src, char *dest, size_t size,
317 bool replace_whitespace) {
318 const char *from;
319 char *s;
320 size_t l;
321
322 assert(event);
323 assert(event->dev);
324 assert(src);
325 assert(dest);
326 assert(size > 0);
327
328 from = src;
329 s = dest;
330 l = size;
331
332 for (;;) {
333 const struct subst_map_entry *entry = NULL;
334 char attrbuf[UTIL_PATH_SIZE], *attr;
335 bool format_dollar = false;
336 ssize_t subst_len;
337
338 while (from[0] != '\0') {
339 if (from[0] == '$') {
340 /* substitute named variable */
341 unsigned i;
342
343 if (from[1] == '$') {
344 from++;
345 goto copy;
346 }
347
348 for (i = 0; i < ELEMENTSOF(map); i++) {
349 if (startswith(&from[1], map[i].name)) {
350 entry = &map[i];
351 from += strlen(map[i].name)+1;
352 format_dollar = true;
353 goto subst;
354 }
355 }
356 } else if (from[0] == '%') {
357 /* substitute format char */
358 unsigned i;
359
360 if (from[1] == '%') {
361 from++;
362 goto copy;
363 }
364
365 for (i = 0; i < ELEMENTSOF(map); i++) {
366 if (from[1] == map[i].fmt) {
367 entry = &map[i];
368 from += 2;
369 goto subst;
370 }
371 }
372 }
373 copy:
374 /* copy char */
375 if (l < 2) /* need space for this char and the terminating NUL */
376 goto out;
377 s[0] = from[0];
378 from++;
379 s++;
380 l--;
381 }
382
383 goto out;
384 subst:
385 /* extract possible $format{attr} */
386 if (from[0] == '{') {
387 unsigned i;
388
389 from++;
390 for (i = 0; from[i] != '}'; i++)
391 if (from[i] == '\0') {
392 log_error("missing closing brace for format '%s'", src);
393 goto out;
394 }
395
396 if (i >= sizeof(attrbuf))
397 goto out;
398 memcpy(attrbuf, from, i);
399 attrbuf[i] = '\0';
400 from += i+1;
401 attr = attrbuf;
402 } else
403 attr = NULL;
404
405 subst_len = subst_format_var(event, entry, attr, s, l);
406 if (subst_len < 0) {
407 if (format_dollar)
408 log_device_warning_errno(event->dev, subst_len, "Failed to substitute variable '$%s', ignoring: %m", entry->name);
409 else
410 log_device_warning_errno(event->dev, subst_len, "Failed to apply format '%%%c', ignoring: %m", entry->fmt);
411
412 continue;
413 }
414
415 /* SUBST_RESULT handles spaces itself */
416 if (replace_whitespace && entry->type != SUBST_RESULT)
417 /* util_replace_whitespace can replace in-place,
418 * and does nothing if subst_len == 0
419 */
420 subst_len = util_replace_whitespace(s, s, subst_len);
421
422 s += subst_len;
423 l -= subst_len;
424 }
425
426 out:
427 assert(l >= 1);
428 s[0] = '\0';
429 return l;
430 }
431
432 static int on_spawn_io(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
433 Spawn *spawn = userdata;
434 char buf[4096], *p;
435 size_t size;
436 ssize_t l;
437
438 assert(spawn);
439 assert(fd == spawn->fd_stdout || fd == spawn->fd_stderr);
440 assert(!spawn->result || spawn->result_len < spawn->result_size);
441
442 if (fd == spawn->fd_stdout && spawn->result) {
443 p = spawn->result + spawn->result_len;
444 size = spawn->result_size - spawn->result_len;
445 } else {
446 p = buf;
447 size = sizeof(buf);
448 }
449
450 l = read(fd, p, size - 1);
451 if (l < 0) {
452 if (errno != EAGAIN)
453 log_error_errno(errno, "Failed to read stdout of '%s': %m", spawn->cmd);
454
455 return 0;
456 }
457
458 p[l] = '\0';
459 if (fd == spawn->fd_stdout && spawn->result)
460 spawn->result_len += l;
461
462 /* Log output only if we watch stderr. */
463 if (l > 0 && spawn->fd_stderr >= 0) {
464 _cleanup_strv_free_ char **v = NULL;
465 char **q;
466
467 v = strv_split_newlines(p);
468 if (!v)
469 return 0;
470
471 STRV_FOREACH(q, v)
472 log_debug("'%s'(%s) '%s'", spawn->cmd,
473 fd == spawn->fd_stdout ? "out" : "err", *q);
474 }
475
476 return 0;
477 }
478
479 static int on_spawn_timeout(sd_event_source *s, uint64_t usec, void *userdata) {
480 Spawn *spawn = userdata;
481 char timeout[FORMAT_TIMESPAN_MAX];
482
483 assert(spawn);
484
485 kill_and_sigcont(spawn->pid, SIGKILL);
486
487 log_error("Spawned process '%s' ["PID_FMT"] timed out after %s, killing", spawn->cmd, spawn->pid,
488 format_timespan(timeout, sizeof(timeout), spawn->timeout_usec, USEC_PER_SEC));
489
490 return 1;
491 }
492
493 static int on_spawn_timeout_warning(sd_event_source *s, uint64_t usec, void *userdata) {
494 Spawn *spawn = userdata;
495 char timeout[FORMAT_TIMESPAN_MAX];
496
497 assert(spawn);
498
499 log_warning("Spawned process '%s' ["PID_FMT"] is taking longer than %s to complete", spawn->cmd, spawn->pid,
500 format_timespan(timeout, sizeof(timeout), spawn->timeout_warn_usec, USEC_PER_SEC));
501
502 return 1;
503 }
504
505 static int on_spawn_sigchld(sd_event_source *s, const siginfo_t *si, void *userdata) {
506 Spawn *spawn = userdata;
507
508 assert(spawn);
509
510 switch (si->si_code) {
511 case CLD_EXITED:
512 if (si->si_status == 0) {
513 log_debug("Process '%s' succeeded.", spawn->cmd);
514 sd_event_exit(sd_event_source_get_event(s), 0);
515
516 return 1;
517 }
518
519 log_full(spawn->accept_failure ? LOG_DEBUG : LOG_WARNING,
520 "Process '%s' failed with exit code %i.", spawn->cmd, si->si_status);
521 break;
522 case CLD_KILLED:
523 case CLD_DUMPED:
524 log_warning("Process '%s' terminated by signal %s.", spawn->cmd, signal_to_string(si->si_status));
525
526 break;
527 default:
528 log_error("Process '%s' failed due to unknown reason.", spawn->cmd);
529 }
530
531 sd_event_exit(sd_event_source_get_event(s), -EIO);
532
533 return 1;
534 }
535
536 static int spawn_wait(Spawn *spawn) {
537 _cleanup_(sd_event_unrefp) sd_event *e = NULL;
538 int r, ret;
539
540 assert(spawn);
541
542 r = sd_event_new(&e);
543 if (r < 0)
544 return r;
545
546 if (spawn->timeout_usec > 0) {
547 usec_t usec, age_usec;
548
549 usec = now(CLOCK_MONOTONIC);
550 age_usec = usec - spawn->event_birth_usec;
551 if (age_usec < spawn->timeout_usec) {
552 if (spawn->timeout_warn_usec > 0 &&
553 spawn->timeout_warn_usec < spawn->timeout_usec &&
554 spawn->timeout_warn_usec > age_usec) {
555 spawn->timeout_warn_usec -= age_usec;
556
557 r = sd_event_add_time(e, NULL, CLOCK_MONOTONIC,
558 usec + spawn->timeout_warn_usec, USEC_PER_SEC,
559 on_spawn_timeout_warning, spawn);
560 if (r < 0)
561 return r;
562 }
563
564 spawn->timeout_usec -= age_usec;
565
566 r = sd_event_add_time(e, NULL, CLOCK_MONOTONIC,
567 usec + spawn->timeout_usec, USEC_PER_SEC, on_spawn_timeout, spawn);
568 if (r < 0)
569 return r;
570 }
571 }
572
573 r = sd_event_add_io(e, NULL, spawn->fd_stdout, EPOLLIN, on_spawn_io, spawn);
574 if (r < 0)
575 return r;
576
577 r = sd_event_add_io(e, NULL, spawn->fd_stderr, EPOLLIN, on_spawn_io, spawn);
578 if (r < 0)
579 return r;
580
581 r = sd_event_add_child(e, NULL, spawn->pid, WEXITED, on_spawn_sigchld, spawn);
582 if (r < 0)
583 return r;
584
585 r = sd_event_loop(e);
586 if (r < 0)
587 return r;
588
589 r = sd_event_get_exit_code(e, &ret);
590 if (r < 0)
591 return r;
592
593 return ret;
594 }
595
596 int udev_event_spawn(UdevEvent *event,
597 usec_t timeout_usec,
598 bool accept_failure,
599 const char *cmd,
600 char *result, size_t ressize) {
601 _cleanup_close_pair_ int outpipe[2] = {-1, -1}, errpipe[2] = {-1, -1};
602 _cleanup_strv_free_ char **argv = NULL;
603 char **envp = NULL;
604 Spawn spawn;
605 pid_t pid;
606 int r;
607
608 assert(event);
609 assert(event->dev);
610 assert(result || ressize == 0);
611
612 /* pipes from child to parent */
613 if (result || log_get_max_level() >= LOG_INFO)
614 if (pipe2(outpipe, O_NONBLOCK|O_CLOEXEC) != 0)
615 return log_error_errno(errno, "Failed to create pipe for command '%s': %m", cmd);
616
617 if (log_get_max_level() >= LOG_INFO)
618 if (pipe2(errpipe, O_NONBLOCK|O_CLOEXEC) != 0)
619 return log_error_errno(errno, "Failed to create pipe for command '%s': %m", cmd);
620
621 argv = strv_split_full(cmd, NULL, SPLIT_QUOTES|SPLIT_RELAX);
622 if (!argv)
623 return log_oom();
624
625 if (isempty(argv[0]))
626 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
627 "Invalid command '%s'", cmd);
628
629 /* allow programs in /usr/lib/udev/ to be called without the path */
630 if (!path_is_absolute(argv[0])) {
631 char *program;
632
633 program = path_join(UDEVLIBEXECDIR, argv[0]);
634 if (!program)
635 return log_oom();
636
637 free_and_replace(argv[0], program);
638 }
639
640 r = device_get_properties_strv(event->dev, &envp);
641 if (r < 0)
642 return log_device_error_errno(event->dev, r, "Failed to get device properties");
643
644 log_debug("Starting '%s'", cmd);
645
646 r = safe_fork("(spawn)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid);
647 if (r < 0)
648 return log_error_errno(r, "Failed to fork() to execute command '%s': %m", cmd);
649 if (r == 0) {
650 if (rearrange_stdio(-1, outpipe[WRITE_END], errpipe[WRITE_END]) < 0)
651 _exit(EXIT_FAILURE);
652
653 (void) close_all_fds(NULL, 0);
654 (void) rlimit_nofile_safe();
655
656 execve(argv[0], argv, envp);
657 _exit(EXIT_FAILURE);
658 }
659
660 /* parent closed child's ends of pipes */
661 outpipe[WRITE_END] = safe_close(outpipe[WRITE_END]);
662 errpipe[WRITE_END] = safe_close(errpipe[WRITE_END]);
663
664 spawn = (Spawn) {
665 .cmd = cmd,
666 .pid = pid,
667 .accept_failure = accept_failure,
668 .timeout_warn_usec = udev_warn_timeout(timeout_usec),
669 .timeout_usec = timeout_usec,
670 .event_birth_usec = event->birth_usec,
671 .fd_stdout = outpipe[READ_END],
672 .fd_stderr = errpipe[READ_END],
673 .result = result,
674 .result_size = ressize,
675 };
676 r = spawn_wait(&spawn);
677 if (r < 0)
678 return log_error_errno(r, "Failed to wait spawned command '%s': %m", cmd);
679
680 if (result)
681 result[spawn.result_len] = '\0';
682
683 return r;
684 }
685
686 static int rename_netif(UdevEvent *event) {
687 sd_device *dev = event->dev;
688 const char *action, *oldname;
689 char name[IFNAMSIZ];
690 int ifindex, r;
691
692 if (!event->name)
693 return 0; /* No new name is requested. */
694
695 r = sd_device_get_sysname(dev, &oldname);
696 if (r < 0)
697 return log_device_error_errno(dev, r, "Failed to get sysname: %m");
698
699 if (streq(event->name, oldname))
700 return 0; /* The interface name is already requested name. */
701
702 r = sd_device_get_property_value(dev, "ACTION", &action);
703 if (r < 0)
704 return log_device_error_errno(dev, r, "Failed to get property 'ACTION': %m");
705
706 if (!streq(action, "add"))
707 return 0; /* Rename the interface only when it is added. */
708
709 r = sd_device_get_ifindex(dev, &ifindex);
710 if (r == -ENOENT)
711 return 0; /* Device is not a network interface. */
712 if (r < 0)
713 return log_device_error_errno(dev, r, "Failed to get ifindex: %m");
714
715 strscpy(name, IFNAMSIZ, event->name);
716 r = rtnl_set_link_name(&event->rtnl, ifindex, name);
717 if (r < 0)
718 return log_device_error_errno(dev, r, "Failed to rename network interface %i from '%s' to '%s': %m", ifindex, oldname, name);
719
720 r = device_rename(dev, event->name);
721 if (r < 0)
722 return log_warning_errno(r, "Network interface %i is renamed from '%s' to '%s', but could not update sd_device object: %m", ifindex, oldname, name);
723
724 log_device_debug(dev, "Network interface %i is renamed from '%s' to '%s'", ifindex, oldname, name);
725
726 return 1;
727 }
728
729 static int update_devnode(UdevEvent *event) {
730 sd_device *dev = event->dev;
731 const char *action;
732 bool apply;
733 int r;
734
735 r = sd_device_get_devnum(dev, NULL);
736 if (r == -ENOENT)
737 return 0;
738 if (r < 0)
739 return log_device_error_errno(dev, r, "Failed to get devnum: %m");
740
741 /* remove/update possible left-over symlinks from old database entry */
742 if (event->dev_db_clone)
743 (void) udev_node_update_old_links(dev, event->dev_db_clone);
744
745 if (!event->owner_set) {
746 r = device_get_devnode_uid(dev, &event->uid);
747 if (r < 0 && r != -ENOENT)
748 return log_device_error_errno(dev, r, "Failed to get devnode UID: %m");
749 }
750
751 if (!event->group_set) {
752 r = device_get_devnode_gid(dev, &event->gid);
753 if (r < 0 && r != -ENOENT)
754 return log_device_error_errno(dev, r, "Failed to get devnode GID: %m");
755 }
756
757 if (!event->mode_set) {
758 r = device_get_devnode_mode(dev, &event->mode);
759 if (r < 0 && r != -ENOENT)
760 return log_device_error_errno(dev, r, "Failed to get devnode mode: %m");
761 if (r == -ENOENT) {
762 if (event->gid > 0)
763 /* default 0660 if a group is assigned */
764 event->mode = 0660;
765 else
766 /* default 0600 */
767 event->mode = 0600;
768 }
769 }
770
771 r = sd_device_get_property_value(dev, "ACTION", &action);
772 if (r < 0)
773 return log_device_error_errno(dev, r, "Failed to get property 'ACTION': %m");
774
775 apply = streq(action, "add") || event->owner_set || event->group_set || event->mode_set;
776 return udev_node_add(dev, apply, event->mode, event->uid, event->gid, event->seclabel_list);
777 }
778
779 static void event_execute_rules_on_remove(
780 UdevEvent *event,
781 usec_t timeout_usec,
782 Hashmap *properties_list,
783 UdevRules *rules) {
784
785 sd_device *dev = event->dev;
786 int r;
787
788 r = device_read_db_internal(dev, true);
789 if (r < 0)
790 log_device_debug_errno(dev, r, "Failed to read database under /run/udev/data/: %m");
791
792 r = device_tag_index(dev, NULL, false);
793 if (r < 0)
794 log_device_debug_errno(dev, r, "Failed to remove corresponding tag files under /run/udev/tag/, ignoring: %m");
795
796 r = device_delete_db(dev);
797 if (r < 0)
798 log_device_debug_errno(dev, r, "Failed to delete database under /run/udev/data/, ignoring: %m");
799
800 if (sd_device_get_devnum(dev, NULL) >= 0)
801 (void) udev_watch_end(dev);
802
803 (void) udev_rules_apply_to_event(rules, event, timeout_usec, properties_list);
804
805 if (sd_device_get_devnum(dev, NULL) >= 0)
806 (void) udev_node_remove(dev);
807 }
808
809 int udev_event_execute_rules(UdevEvent *event,
810 usec_t timeout_usec,
811 Hashmap *properties_list,
812 UdevRules *rules) {
813 sd_device *dev = event->dev;
814 const char *subsystem, *action;
815 int r;
816
817 assert(event);
818 assert(rules);
819
820 r = sd_device_get_subsystem(dev, &subsystem);
821 if (r < 0)
822 return log_device_error_errno(dev, r, "Failed to get subsystem: %m");
823
824 r = sd_device_get_property_value(dev, "ACTION", &action);
825 if (r < 0)
826 return log_device_error_errno(dev, r, "Failed to get property 'ACTION': %m");
827
828 if (streq(action, "remove")) {
829 event_execute_rules_on_remove(event, timeout_usec, properties_list, rules);
830 return 0;
831 }
832
833 r = device_clone_with_db(dev, &event->dev_db_clone);
834 if (r < 0)
835 log_device_debug_errno(dev, r, "Failed to clone sd_device object, ignoring: %m");
836
837 if (event->dev_db_clone) {
838 r = sd_device_get_devnum(dev, NULL);
839 if (r < 0) {
840 if (r != -ENOENT)
841 log_device_debug_errno(dev, r, "Failed to get devnum, ignoring: %m");
842
843 if (streq(action, "move")) {
844 r = device_copy_properties(dev, event->dev_db_clone);
845 if (r < 0)
846 log_device_debug_errno(dev, r, "Failed to copy properties from cloned device, ignoring: %m");
847 }
848 } else
849 /* Disable watch during event processing. */
850 (void) udev_watch_end(event->dev_db_clone);
851 }
852
853 (void) udev_rules_apply_to_event(rules, event, timeout_usec, properties_list);
854
855 (void) rename_netif(event);
856 (void) update_devnode(event);
857
858 /* preserve old, or get new initialization timestamp */
859 r = device_ensure_usec_initialized(dev, event->dev_db_clone);
860 if (r < 0)
861 log_device_debug_errno(dev, r, "Failed to set initialization timestamp, ignoring: %m");
862
863 /* (re)write database file */
864 r = device_tag_index(dev, event->dev_db_clone, true);
865 if (r < 0)
866 log_device_debug_errno(dev, r, "Failed to update tags under /run/udev/tag/, ignoring: %m");
867
868 r = device_update_db(dev);
869 if (r < 0)
870 log_device_debug_errno(dev, r, "Failed to update database under /run/udev/data/, ignoring: %m");
871
872 device_set_is_initialized(dev);
873
874 event->dev_db_clone = sd_device_unref(event->dev_db_clone);
875
876 return 0;
877 }
878
879 void udev_event_execute_run(UdevEvent *event, usec_t timeout_usec) {
880 const char *cmd;
881 void *val;
882 Iterator i;
883
884 HASHMAP_FOREACH_KEY(val, cmd, event->run_list, i) {
885 enum udev_builtin_cmd builtin_cmd = PTR_TO_INT(val);
886 char command[UTIL_PATH_SIZE];
887
888 udev_event_apply_format(event, cmd, command, sizeof(command), false);
889
890 if (builtin_cmd >= 0 && builtin_cmd < _UDEV_BUILTIN_MAX)
891 udev_builtin_run(event->dev, builtin_cmd, command, false);
892 else {
893 if (event->exec_delay_usec > 0) {
894 log_debug("delay execution of '%s'", command);
895 (void) usleep(event->exec_delay_usec);
896 }
897
898 udev_event_spawn(event, timeout_usec, false, command, NULL, 0);
899 }
900 }
901 }