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