]>
git.ipfire.org Git - thirdparty/systemd.git/blob - udev/udev-event.c
2 * Copyright (C) 2003-2010 Kay Sievers <kay.sievers@vrfy.org>
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
28 #include <sys/ioctl.h>
29 #include <sys/prctl.h>
31 #include <sys/epoll.h>
33 #include <sys/socket.h>
34 #include <sys/signalfd.h>
35 #include <linux/sockios.h>
39 struct udev_event
*udev_event_new(struct udev_device
*dev
)
41 struct udev_event
*event
;
43 event
= calloc(1, sizeof(struct udev_event
));
47 event
->udev
= udev_device_get_udev(dev
);
48 udev_list_init(&event
->run_list
);
49 event
->fd_signal
= -1;
50 event
->birth_usec
= now_usec();
51 event
->timeout_usec
= 60 * 1000 * 1000;
52 dbg(event
->udev
, "allocated event %p\n", event
);
56 void udev_event_unref(struct udev_event
*event
)
60 udev_list_cleanup_entries(event
->udev
, &event
->run_list
);
61 free(event
->tmp_node
);
62 free(event
->program_result
);
64 dbg(event
->udev
, "free event %p\n", event
);
68 size_t udev_event_apply_format(struct udev_event
*event
, const char *src
, char *dest
, size_t size
)
70 struct udev_device
*dev
= event
->dev
;
90 static const struct subst_map
{
95 { .name
= "tempnode", .fmt
= 'N', .type
= SUBST_TEMP_NODE
},
96 { .name
= "attr", .fmt
= 's', .type
= SUBST_ATTR
},
97 { .name
= "sysfs", .fmt
= 's', .type
= SUBST_ATTR
},
98 { .name
= "env", .fmt
= 'E', .type
= SUBST_ENV
},
99 { .name
= "kernel", .fmt
= 'k', .type
= SUBST_KERNEL
},
100 { .name
= "number", .fmt
= 'n', .type
= SUBST_KERNEL_NUMBER
},
101 { .name
= "driver", .fmt
= 'd', .type
= SUBST_DRIVER
},
102 { .name
= "devpath", .fmt
= 'p', .type
= SUBST_DEVPATH
},
103 { .name
= "id", .fmt
= 'b', .type
= SUBST_ID
},
104 { .name
= "major", .fmt
= 'M', .type
= SUBST_MAJOR
},
105 { .name
= "minor", .fmt
= 'm', .type
= SUBST_MINOR
},
106 { .name
= "result", .fmt
= 'c', .type
= SUBST_RESULT
},
107 { .name
= "parent", .fmt
= 'P', .type
= SUBST_PARENT
},
108 { .name
= "name", .fmt
= 'D', .type
= SUBST_NAME
},
109 { .name
= "links", .fmt
= 'L', .type
= SUBST_LINKS
},
110 { .name
= "root", .fmt
= 'r', .type
= SUBST_ROOT
},
111 { .name
= "sys", .fmt
= 'S', .type
= SUBST_SYS
},
122 enum subst_type type
= SUBST_UNKNOWN
;
123 char attrbuf
[UTIL_PATH_SIZE
];
126 while (from
[0] != '\0') {
127 if (from
[0] == '$') {
128 /* substitute named variable */
131 if (from
[1] == '$') {
136 for (i
= 0; i
< ARRAY_SIZE(map
); i
++) {
137 if (strncmp(&from
[1], map
[i
].name
, strlen(map
[i
].name
)) == 0) {
139 from
+= strlen(map
[i
].name
)+1;
140 dbg(event
->udev
, "will substitute format name '%s'\n", map
[i
].name
);
144 } else if (from
[0] == '%') {
145 /* substitute format char */
148 if (from
[1] == '%') {
153 for (i
= 0; i
< ARRAY_SIZE(map
); i
++) {
154 if (from
[1] == map
[i
].fmt
) {
157 dbg(event
->udev
, "will substitute format char '%c'\n", map
[i
].fmt
);
174 /* extract possible $format{attr} */
175 if (from
[0] == '{') {
179 for (i
= 0; from
[i
] != '}'; i
++) {
180 if (from
[i
] == '\0') {
181 err(event
->udev
, "missing closing brace for format '%s'\n", src
);
185 if (i
>= sizeof(attrbuf
))
187 memcpy(attrbuf
, from
, i
);
197 l
= util_strpcpy(&s
, l
, udev_device_get_devpath(dev
));
198 dbg(event
->udev
, "substitute devpath '%s'\n", udev_device_get_devpath(dev
));
201 l
= util_strpcpy(&s
, l
, udev_device_get_sysname(dev
));
202 dbg(event
->udev
, "substitute kernel name '%s'\n", udev_device_get_sysname(dev
));
204 case SUBST_KERNEL_NUMBER
:
205 if (udev_device_get_sysnum(dev
) == NULL
)
207 l
= util_strpcpy(&s
, l
, udev_device_get_sysnum(dev
));
208 dbg(event
->udev
, "substitute kernel number '%s'\n", udev_device_get_sysnum(dev
));
211 if (event
->dev_parent
== NULL
)
213 l
= util_strpcpy(&s
, l
, udev_device_get_sysname(event
->dev_parent
));
214 dbg(event
->udev
, "substitute id '%s'\n", udev_device_get_sysname(event
->dev_parent
));
219 if (event
->dev_parent
== NULL
)
222 driver
= udev_device_get_driver(event
->dev_parent
);
225 l
= util_strpcpy(&s
, l
, driver
);
226 dbg(event
->udev
, "substitute driver '%s'\n", driver
);
230 char num
[UTIL_PATH_SIZE
];
232 sprintf(num
, "%d", major(udev_device_get_devnum(dev
)));
233 l
= util_strpcpy(&s
, l
, num
);
234 dbg(event
->udev
, "substitute major number '%s'\n", num
);
238 char num
[UTIL_PATH_SIZE
];
240 sprintf(num
, "%d", minor(udev_device_get_devnum(dev
)));
241 l
= util_strpcpy(&s
, l
, num
);
242 dbg(event
->udev
, "substitute minor number '%s'\n", num
);
249 if (event
->program_result
== NULL
)
251 /* get part part of the result string */
254 i
= strtoul(attr
, &rest
, 10);
256 char result
[UTIL_PATH_SIZE
];
257 char tmp
[UTIL_PATH_SIZE
];
260 dbg(event
->udev
, "request part #%d of result string\n", i
);
261 util_strscpy(result
, sizeof(result
), event
->program_result
);
264 while (cpos
[0] != '\0' && !isspace(cpos
[0]))
266 while (isspace(cpos
[0]))
270 err(event
->udev
, "requested part of result string not found\n");
273 util_strscpy(tmp
, sizeof(tmp
), cpos
);
274 /* %{2+}c copies the whole string from the second part on */
275 if (rest
[0] != '+') {
276 cpos
= strchr(tmp
, ' ');
280 l
= util_strpcpy(&s
, l
, tmp
);
281 dbg(event
->udev
, "substitute part of result string '%s'\n", tmp
);
283 l
= util_strpcpy(&s
, l
, event
->program_result
);
284 dbg(event
->udev
, "substitute result string '%s'\n", event
->program_result
);
289 const char *value
= NULL
;
290 char vbuf
[UTIL_NAME_SIZE
];
295 err(event
->udev
, "missing file parameter for attr\n");
299 /* try to read the value specified by "[dmi/id]product_name" */
300 if (util_resolve_subsys_kernel(event
->udev
, attr
, vbuf
, sizeof(vbuf
), 1) == 0)
303 /* try to read the attribute the device */
305 value
= udev_device_get_sysattr_value(event
->dev
, attr
);
307 /* try to read the attribute of the parent device, other matches have selected */
308 if (value
== NULL
&& event
->dev_parent
!= NULL
&& event
->dev_parent
!= event
->dev
)
309 value
= udev_device_get_sysattr_value(event
->dev_parent
, attr
);
314 /* strip trailing whitespace, and replace unwanted characters */
316 util_strscpy(vbuf
, sizeof(vbuf
), value
);
318 while (len
> 0 && isspace(vbuf
[--len
]))
320 count
= udev_util_replace_chars(vbuf
, UDEV_ALLOWED_CHARS_INPUT
);
322 info(event
->udev
, "%i character(s) replaced\n" , count
);
323 l
= util_strpcpy(&s
, l
, vbuf
);
324 dbg(event
->udev
, "substitute sysfs value '%s'\n", vbuf
);
328 struct udev_device
*dev_parent
;
331 dev_parent
= udev_device_get_parent(event
->dev
);
332 if (dev_parent
== NULL
)
334 devnode
= udev_device_get_devnode(dev_parent
);
335 if (devnode
!= NULL
) {
336 size_t devlen
= strlen(udev_get_dev_path(event
->udev
))+1;
338 l
= util_strpcpy(&s
, l
, &devnode
[devlen
]);
339 dbg(event
->udev
, "found parent '%s', got node name '%s'\n",
340 udev_device_get_syspath(dev_parent
), &devnode
[devlen
]);
344 case SUBST_TEMP_NODE
: {
347 char filename
[UTIL_PATH_SIZE
];
350 if (event
->tmp_node
!= NULL
) {
351 l
= util_strpcpy(&s
, l
, event
->tmp_node
);
352 dbg(event
->udev
, "tempnode: return earlier created one\n");
355 devnum
= udev_device_get_devnum(dev
);
356 if (major(devnum
) == 0)
358 /* lookup kernel provided node */
359 if (udev_device_get_knodename(dev
) != NULL
) {
360 util_strscpyl(filename
, sizeof(filename
),
361 udev_get_dev_path(event
->udev
), "/", udev_device_get_knodename(dev
), NULL
);
362 if (stat(filename
, &statbuf
) == 0 && statbuf
.st_rdev
== devnum
) {
363 l
= util_strpcpy(&s
, l
, filename
);
364 dbg(event
->udev
, "tempnode: return kernel node\n");
368 /* lookup /dev/{char,block}/<maj>:<min> */
369 if (strcmp(udev_device_get_subsystem(dev
), "block") == 0)
373 snprintf(filename
, sizeof(filename
), "%s/%s/%u:%u",
374 udev_get_dev_path(event
->udev
), devtype
,
375 major(udev_device_get_devnum(dev
)),
376 minor(udev_device_get_devnum(dev
)));
377 if (stat(filename
, &statbuf
) == 0 && statbuf
.st_rdev
== devnum
) {
378 l
= util_strpcpy(&s
, l
, filename
);
379 dbg(event
->udev
, "tempnode: return maj:min node\n");
382 /* create temporary node */
383 dbg(event
->udev
, "tempnode: create temp node\n");
384 asprintf(&event
->tmp_node
, "%s/.tmp-%s-%u:%u",
385 udev_get_dev_path(event
->udev
), devtype
,
386 major(udev_device_get_devnum(dev
)),
387 minor(udev_device_get_devnum(dev
)));
388 if (event
->tmp_node
== NULL
)
390 udev_node_mknod(dev
, event
->tmp_node
, 0600, 0, 0);
391 l
= util_strpcpy(&s
, l
, event
->tmp_node
);
395 if (event
->name
!= NULL
) {
396 l
= util_strpcpy(&s
, l
, event
->name
);
397 dbg(event
->udev
, "substitute name '%s'\n", event
->name
);
399 l
= util_strpcpy(&s
, l
, udev_device_get_sysname(dev
));
400 dbg(event
->udev
, "substitute sysname '%s'\n", udev_device_get_sysname(dev
));
404 size_t devlen
= strlen(udev_get_dev_path(event
->udev
))+1;
405 struct udev_list_entry
*list_entry
;
407 list_entry
= udev_device_get_devlinks_list_entry(dev
);
408 if (list_entry
== NULL
)
410 l
= util_strpcpy(&s
, l
, &udev_list_entry_get_name(list_entry
)[devlen
]);
411 udev_list_entry_foreach(list_entry
, udev_list_entry_get_next(list_entry
))
412 l
= util_strpcpyl(&s
, l
, " ", &udev_list_entry_get_name(list_entry
)[devlen
], NULL
);
416 l
= util_strpcpy(&s
, l
, udev_get_dev_path(event
->udev
));
417 dbg(event
->udev
, "substitute udev_root '%s'\n", udev_get_dev_path(event
->udev
));
420 l
= util_strpcpy(&s
, l
, udev_get_sys_path(event
->udev
));
421 dbg(event
->udev
, "substitute sys_path '%s'\n", udev_get_sys_path(event
->udev
));
425 dbg(event
->udev
, "missing attribute\n");
430 value
= udev_device_get_property_value(event
->dev
, attr
);
433 dbg(event
->udev
, "substitute env '%s=%s'\n", attr
, value
);
434 l
= util_strpcpy(&s
, l
, value
);
438 err(event
->udev
, "unknown substitution type=%i\n", type
);
445 dbg(event
->udev
, "'%s' -> '%s' (%zu)\n", src
, dest
, l
);
449 static int spawn_exec(struct udev_event
*event
,
450 const char *cmd
, char *const argv
[], char **envp
, const sigset_t
*sigmask
,
451 int fd_stdout
, int fd_stderr
)
453 struct udev
*udev
= event
->udev
;
457 /* discard child output or connect to pipe */
458 fd
= open("/dev/null", O_RDWR
);
460 dup2(fd
, STDIN_FILENO
);
462 dup2(fd
, STDOUT_FILENO
);
464 dup2(fd
, STDERR_FILENO
);
467 err(udev
, "open /dev/null failed: %m\n");
470 /* connect pipes to std{out,err} */
471 if (fd_stdout
>= 0) {
472 dup2(fd_stdout
, STDOUT_FILENO
);
475 if (fd_stderr
>= 0) {
476 dup2(fd_stderr
, STDERR_FILENO
);
480 /* terminate child in case parent goes away */
481 prctl(PR_SET_PDEATHSIG
, SIGTERM
);
483 /* restore original udev sigmask before exec */
485 sigprocmask(SIG_SETMASK
, sigmask
, NULL
);
487 execve(argv
[0], argv
, envp
);
491 err(udev
, "failed to execute '%s' '%s': %m\n", argv
[0], cmd
);
495 static int spawn_read(struct udev_event
*event
,
497 int fd_stdout
, int fd_stderr
,
498 char *result
, size_t ressize
)
500 struct udev
*udev
= event
->udev
;
503 struct epoll_event ep_outpipe
, ep_errpipe
;
506 /* read from child if requested */
507 if (fd_stdout
< 0 && fd_stderr
< 0)
510 fd_ep
= epoll_create1(EPOLL_CLOEXEC
);
513 err(udev
, "error creating epoll fd: %m\n");
517 if (fd_stdout
>= 0) {
518 memset(&ep_outpipe
, 0, sizeof(struct epoll_event
));
519 ep_outpipe
.events
= EPOLLIN
;
520 ep_outpipe
.data
.ptr
= &fd_stdout
;
521 if (epoll_ctl(fd_ep
, EPOLL_CTL_ADD
, fd_stdout
, &ep_outpipe
) < 0) {
522 err(udev
, "fail to add fd to epoll: %m\n");
527 if (fd_stderr
>= 0) {
528 memset(&ep_errpipe
, 0, sizeof(struct epoll_event
));
529 ep_errpipe
.events
= EPOLLIN
;
530 ep_errpipe
.data
.ptr
= &fd_stderr
;
531 if (epoll_ctl(fd_ep
, EPOLL_CTL_ADD
, fd_stderr
, &ep_errpipe
) < 0) {
532 err(udev
, "fail to add fd to epoll: %m\n");
537 /* read child output */
538 while (fd_stdout
>= 0 || fd_stderr
>= 0) {
541 struct epoll_event ev
[4];
544 if (event
->timeout_usec
> 0) {
545 unsigned long long age_usec
;
547 age_usec
= now_usec() - event
->birth_usec
;
548 if (age_usec
>= event
->timeout_usec
) {
550 err(udev
, "timeout '%s'\n", cmd
);
553 timeout
= ((event
->timeout_usec
- age_usec
) / 1000) + 1000;
558 fdcount
= epoll_wait(fd_ep
, ev
, ARRAY_SIZE(ev
), timeout
);
563 err(udev
, "failed to poll: %m\n");
568 err(udev
, "timeout '%s'\n", cmd
);
572 for (i
= 0; i
< fdcount
; i
++) {
573 int *fd
= (int *)ev
[i
].data
.ptr
;
575 if (ev
[i
].events
& EPOLLIN
) {
579 count
= read(*fd
, buf
, sizeof(buf
)-1);
584 /* store stdout result */
585 if (result
!= NULL
&& *fd
== fd_stdout
) {
586 if (respos
+ count
< ressize
) {
587 memcpy(&result
[respos
], buf
, count
);
590 err(udev
, "'%s' ressize %zd too short\n", cmd
, ressize
);
595 /* log debug output only if we watch stderr */
596 if (fd_stderr
>= 0) {
601 while ((line
= strsep(&pos
, "\n"))) {
602 if (pos
!= NULL
|| line
[0] != '\0')
603 info(udev
, "'%s'(%s) '%s'\n", cmd
, *fd
== fd_stdout
? "out" : "err" , line
);
606 } else if (ev
[i
].events
& EPOLLHUP
) {
607 if (epoll_ctl(fd_ep
, EPOLL_CTL_DEL
, *fd
, NULL
) < 0) {
609 err(udev
, "failed to remove fd from epoll: %m\n");
617 /* return the child's stdout string */
618 if (result
!= NULL
) {
619 result
[respos
] = '\0';
620 dbg(udev
, "result='%s'\n", result
);
628 static int spawn_wait(struct udev_event
*event
, const char *cmd
, pid_t pid
)
630 struct udev
*udev
= event
->udev
;
631 struct pollfd pfd
[1];
634 pfd
[0].events
= POLLIN
;
635 pfd
[0].fd
= event
->fd_signal
;
641 if (event
->timeout_usec
> 0) {
642 unsigned long long age_usec
;
644 age_usec
= now_usec() - event
->birth_usec
;
645 if (age_usec
>= event
->timeout_usec
)
648 timeout
= ((event
->timeout_usec
- age_usec
) / 1000) + 1000;
653 fdcount
= poll(pfd
, 1, timeout
);
658 err(udev
, "failed to poll: %m\n");
662 err(udev
, "timeout: killing '%s' [%u]\n", cmd
, pid
);
666 if (pfd
[0].revents
& POLLIN
) {
667 struct signalfd_siginfo fdsi
;
671 size
= read(event
->fd_signal
, &fdsi
, sizeof(struct signalfd_siginfo
));
672 if (size
!= sizeof(struct signalfd_siginfo
))
675 switch (fdsi
.ssi_signo
) {
677 event
->sigterm
= true;
680 if (waitpid(pid
, &status
, WNOHANG
) < 0)
682 if (WIFEXITED(status
)) {
683 info(udev
, "'%s' [%u] exit with return code %i\n", cmd
, pid
, WEXITSTATUS(status
));
684 if (WEXITSTATUS(status
) != 0)
686 } else if (WIFSIGNALED(status
)) {
687 err(udev
, "'%s' [%u] terminated by signal %i (%s)\n", cmd
, pid
, WTERMSIG(status
), strsignal(WTERMSIG(status
)));
689 } else if (WIFSTOPPED(status
)) {
690 err(udev
, "'%s' [%u] stopped\n", cmd
, pid
);
692 } else if (WIFCONTINUED(status
)) {
693 err(udev
, "'%s' [%u] continued\n", cmd
, pid
);
696 err(udev
, "'%s' [%u] exit with status 0x%04x\n", cmd
, pid
, status
);
708 int udev_event_spawn(struct udev_event
*event
,
709 const char *cmd
, char **envp
, const sigset_t
*sigmask
,
710 char *result
, size_t ressize
)
712 struct udev
*udev
= event
->udev
;
713 int outpipe
[2] = {-1, -1};
714 int errpipe
[2] = {-1, -1};
716 char arg
[UTIL_PATH_SIZE
];
717 char program
[UTIL_PATH_SIZE
];
718 char *argv
[((sizeof(arg
) + 1) / 2) + 1];
722 /* build argv from command */
723 util_strscpy(arg
, sizeof(arg
), cmd
);
725 if (strchr(arg
, ' ') != NULL
) {
728 while (pos
!= NULL
&& pos
[0] != '\0') {
729 if (pos
[0] == '\'') {
730 /* do not separate quotes */
732 argv
[i
] = strsep(&pos
, "\'");
734 while (pos
[0] == ' ')
737 argv
[i
] = strsep(&pos
, " ");
739 while (pos
[0] == ' ')
742 dbg(udev
, "arg[%i] '%s'\n", i
, argv
[i
]);
751 /* pipes from child to parent */
752 if (result
!= NULL
|| udev_get_log_priority(udev
) >= LOG_INFO
) {
753 if (pipe2(outpipe
, O_NONBLOCK
) != 0) {
755 err(udev
, "pipe failed: %m\n");
759 if (udev_get_log_priority(udev
) >= LOG_INFO
) {
760 if (pipe2(errpipe
, O_NONBLOCK
) != 0) {
762 err(udev
, "pipe failed: %m\n");
767 /* allow programs in /lib/udev/ to be called without the path */
768 if (argv
[0][0] != '/') {
769 util_strscpyl(program
, sizeof(program
), LIBEXECDIR
"/", argv
[0], NULL
);
776 /* child closes parent's ends of pipes */
777 if (outpipe
[READ_END
] >= 0) {
778 close(outpipe
[READ_END
]);
779 outpipe
[READ_END
] = -1;
781 if (errpipe
[READ_END
] >= 0) {
782 close(errpipe
[READ_END
]);
783 errpipe
[READ_END
] = -1;
786 info(udev
, "starting '%s'\n", cmd
);
788 err
= spawn_exec(event
, cmd
, argv
, envp
, sigmask
,
789 outpipe
[WRITE_END
], errpipe
[WRITE_END
]);
793 err(udev
, "fork of '%s' failed: %m\n", cmd
);
797 /* parent closed child's ends of pipes */
798 if (outpipe
[WRITE_END
] >= 0) {
799 close(outpipe
[WRITE_END
]);
800 outpipe
[WRITE_END
] = -1;
802 if (errpipe
[WRITE_END
] >= 0) {
803 close(errpipe
[WRITE_END
]);
804 errpipe
[WRITE_END
] = -1;
807 err
= spawn_read(event
, cmd
,
808 outpipe
[READ_END
], errpipe
[READ_END
],
811 err
= spawn_wait(event
, cmd
, pid
);
815 if (outpipe
[READ_END
] >= 0)
816 close(outpipe
[READ_END
]);
817 if (outpipe
[WRITE_END
] >= 0)
818 close(outpipe
[WRITE_END
]);
819 if (errpipe
[READ_END
] >= 0)
820 close(errpipe
[READ_END
]);
821 if (errpipe
[WRITE_END
] >= 0)
822 close(errpipe
[WRITE_END
]);
826 static void rename_netif_kernel_log(struct ifreq ifr
)
831 klog
= open("/dev/kmsg", O_WRONLY
);
835 f
= fdopen(klog
, "w");
841 fprintf(f
, "<30>udevd[%u]: renamed network interface %s to %s\n",
842 getpid(), ifr
.ifr_name
, ifr
.ifr_newname
);
846 static int rename_netif(struct udev_event
*event
)
848 struct udev_device
*dev
= event
->dev
;
854 info(event
->udev
, "changing net interface name from '%s' to '%s'\n",
855 udev_device_get_sysname(dev
), event
->name
);
857 sk
= socket(PF_INET
, SOCK_DGRAM
, 0);
860 err(event
->udev
, "error opening socket: %m\n");
864 memset(&ifr
, 0x00, sizeof(struct ifreq
));
865 util_strscpy(ifr
.ifr_name
, IFNAMSIZ
, udev_device_get_sysname(dev
));
866 util_strscpy(ifr
.ifr_newname
, IFNAMSIZ
, event
->name
);
867 err
= ioctl(sk
, SIOCSIFNAME
, &ifr
);
869 rename_netif_kernel_log(ifr
);
873 /* keep trying if the destination interface name already exists */
878 /* free our own name, another process may wait for us */
879 snprintf(ifr
.ifr_newname
, IFNAMSIZ
, "rename%u", udev_device_get_ifindex(dev
));
880 err
= ioctl(sk
, SIOCSIFNAME
, &ifr
);
886 /* log temporary name */
887 rename_netif_kernel_log(ifr
);
889 /* wait a maximum of 90 seconds for our target to become available */
890 util_strscpy(ifr
.ifr_name
, IFNAMSIZ
, ifr
.ifr_newname
);
891 util_strscpy(ifr
.ifr_newname
, IFNAMSIZ
, event
->name
);
894 const struct timespec duration
= { 0, 1000 * 1000 * 1000 / 20 };
896 dbg(event
->udev
, "wait for netif '%s' to become free, loop=%i\n",
897 event
->name
, (90 * 20) - loop
);
898 nanosleep(&duration
, NULL
);
900 err
= ioctl(sk
, SIOCSIFNAME
, &ifr
);
902 rename_netif_kernel_log(ifr
);
912 err(event
->udev
, "error changing net interface name %s to %s: %m\n", ifr
.ifr_name
, ifr
.ifr_newname
);
917 int udev_event_execute_rules(struct udev_event
*event
, struct udev_rules
*rules
, const sigset_t
*sigmask
)
919 struct udev_device
*dev
= event
->dev
;
922 if (udev_device_get_subsystem(dev
) == NULL
)
925 if (strcmp(udev_device_get_action(dev
), "remove") == 0) {
926 udev_device_read_db(dev
, NULL
);
927 udev_device_delete_db(dev
);
928 udev_device_tag_index(dev
, NULL
, false);
930 if (major(udev_device_get_devnum(dev
)) != 0)
931 udev_watch_end(event
->udev
, dev
);
933 udev_rules_apply_to_event(rules
, event
, sigmask
);
935 if (major(udev_device_get_devnum(dev
)) != 0)
936 err
= udev_node_remove(dev
);
938 event
->dev_db
= udev_device_new_from_syspath(event
->udev
, udev_device_get_syspath(dev
));
939 if (event
->dev_db
!= NULL
) {
940 udev_device_read_db(event
->dev_db
, NULL
);
941 udev_device_set_info_loaded(event
->dev_db
);
943 /* disable watch during event processing */
944 if (major(udev_device_get_devnum(dev
)) != 0)
945 udev_watch_end(event
->udev
, event
->dev_db
);
948 udev_rules_apply_to_event(rules
, event
, sigmask
);
950 /* rename a new network interface, if needed */
951 if (udev_device_get_ifindex(dev
) > 0 && strcmp(udev_device_get_action(dev
), "add") == 0 &&
952 event
->name
!= NULL
&& strcmp(event
->name
, udev_device_get_sysname(dev
)) != 0) {
953 char syspath
[UTIL_PATH_SIZE
];
956 err
= rename_netif(event
);
958 info(event
->udev
, "renamed netif to '%s'\n", event
->name
);
960 /* delete stale db file */
961 udev_device_delete_db(dev
);
962 udev_device_tag_index(dev
, NULL
, false);
964 /* remember old name */
965 udev_device_add_property(dev
, "INTERFACE_OLD", udev_device_get_sysname(dev
));
967 /* now change the devpath, because the kernel device name has changed */
968 util_strscpy(syspath
, sizeof(syspath
), udev_device_get_syspath(dev
));
969 pos
= strrchr(syspath
, '/');
972 util_strscpy(pos
, sizeof(syspath
) - (pos
- syspath
), event
->name
);
973 udev_device_set_syspath(event
->dev
, syspath
);
974 udev_device_add_property(dev
, "INTERFACE", udev_device_get_sysname(dev
));
975 info(event
->udev
, "changed devpath to '%s'\n", udev_device_get_devpath(dev
));
980 if (major(udev_device_get_devnum(dev
)) != 0) {
981 char filename
[UTIL_PATH_SIZE
];
983 if (event
->tmp_node
!= NULL
) {
984 info(event
->udev
, "cleanup temporary device node\n");
985 util_unlink_secure(event
->udev
, event
->tmp_node
);
986 free(event
->tmp_node
);
987 event
->tmp_node
= NULL
;
990 /* no rule, use kernel provided name */
991 if (event
->name
== NULL
) {
992 if (udev_device_get_knodename(dev
) != NULL
) {
993 event
->name
= strdup(udev_device_get_knodename(dev
));
994 info(event
->udev
, "no node name set, will use kernel supplied name '%s'\n", event
->name
);
996 event
->name
= strdup(udev_device_get_sysname(event
->dev
));
997 info(event
->udev
, "no node name set, will use device name '%s'\n", event
->name
);
1001 if (event
->name
== NULL
|| event
->name
[0] == '\0') {
1002 udev_device_delete_db(dev
);
1003 udev_device_tag_index(dev
, NULL
, false);
1004 udev_device_unref(event
->dev_db
);
1006 err(event
->udev
, "no node name, something went wrong, ignoring\n");
1010 if (udev_device_get_knodename(dev
) != NULL
&& strcmp(udev_device_get_knodename(dev
), event
->name
) != 0)
1011 err(event
->udev
, "kernel-provided name '%s' and NAME= '%s' disagree, "
1012 "please use SYMLINK+= or change the kernel to provide the proper name\n",
1013 udev_device_get_knodename(dev
), event
->name
);
1015 /* set device node name */
1016 util_strscpyl(filename
, sizeof(filename
), udev_get_dev_path(event
->udev
), "/", event
->name
, NULL
);
1017 udev_device_set_devnode(dev
, filename
);
1019 /* remove/update possible left-over symlinks from old database entry */
1020 if (event
->dev_db
!= NULL
)
1021 udev_node_update_old_links(dev
, event
->dev_db
);
1023 if (!event
->mode_set
) {
1024 if (udev_device_get_devnode_mode(dev
) > 0) {
1025 /* kernel supplied value */
1026 event
->mode
= udev_device_get_devnode_mode(dev
);
1027 } else if (event
->gid
> 0) {
1028 /* default 0660 if a group is assigned */
1036 err
= udev_node_add(dev
, event
->mode
, event
->uid
, event
->gid
);
1039 /* preserve old, or get new initialization timestamp */
1040 if (event
->dev_db
!= NULL
&& udev_device_get_usec_initialized(event
->dev_db
) > 0)
1041 udev_device_set_usec_initialized(event
->dev
, udev_device_get_usec_initialized(event
->dev_db
));
1043 udev_device_set_usec_initialized(event
->dev
, now_usec());
1045 /* (re)write database file */
1046 udev_device_update_db(dev
);
1047 udev_device_tag_index(dev
, event
->dev_db
, true);
1048 udev_device_set_is_initialized(dev
);
1050 udev_device_unref(event
->dev_db
);
1051 event
->dev_db
= NULL
;
1057 int udev_event_execute_run(struct udev_event
*event
, const sigset_t
*sigmask
)
1059 struct udev_list_entry
*list_entry
;
1062 dbg(event
->udev
, "executing run list\n");
1063 udev_list_entry_foreach(list_entry
, udev_list_get_entry(&event
->run_list
)) {
1064 const char *cmd
= udev_list_entry_get_name(list_entry
);
1066 if (strncmp(cmd
, "socket:", strlen("socket:")) == 0) {
1067 struct udev_monitor
*monitor
;
1069 monitor
= udev_monitor_new_from_socket(event
->udev
, &cmd
[strlen("socket:")]);
1070 if (monitor
== NULL
)
1072 udev_monitor_send_device(monitor
, NULL
, event
->dev
);
1073 udev_monitor_unref(monitor
);
1075 char program
[UTIL_PATH_SIZE
];
1078 if (event
->exec_delay
> 0) {
1079 info(event
->udev
, "delay execution of '%s'\n", program
);
1080 sleep(event
->exec_delay
);
1083 udev_event_apply_format(event
, cmd
, program
, sizeof(program
));
1084 envp
= udev_device_get_properties_envp(event
->dev
);
1085 if (udev_event_spawn(event
, program
, envp
, sigmask
, NULL
, 0) < 0) {
1086 if (udev_list_entry_get_num(list_entry
))