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