136 lines
5.3 KiB
Diff
136 lines
5.3 KiB
Diff
|
---
|
||
|
src/udev/udev-event.c | 42 ++++++++++++++++++++++++++++++++++++++++++
|
||
|
src/udev/udev.h | 1 +
|
||
|
src/udev/udevd.c | 23 +++++++++++++++++++++--
|
||
|
3 files changed, 64 insertions(+), 2 deletions(-)
|
||
|
|
||
|
--- src/udev/udev-event.c
|
||
|
+++ src/udev/udev-event.c 2014-09-24 14:32:53.115639820 +0000
|
||
|
@@ -959,6 +959,46 @@ void udev_event_execute_rules(struct ude
|
||
|
}
|
||
|
}
|
||
|
|
||
|
+#ifdef HAVE_KMOD
|
||
|
+static inline void udev_check_and_set_kmod(enum udev_builtin_cmd builtin_cmd, struct udev_event *event) {
|
||
|
+ char filename[UTIL_PATH_SIZE];
|
||
|
+ switch (builtin_cmd) {
|
||
|
+ case UDEV_BUILTIN_KMOD:
|
||
|
+ snprintf(filename, sizeof(filename), "/run/udev/kmod/%u", (unsigned)getpid());
|
||
|
+ touch(filename);
|
||
|
+ default:
|
||
|
+ break;
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+static inline void udev_check_and_unset_kmod(enum udev_builtin_cmd builtin_cmd, struct udev_event *event) {
|
||
|
+ char filename[UTIL_PATH_SIZE];
|
||
|
+ switch (builtin_cmd) {
|
||
|
+ case UDEV_BUILTIN_KMOD:
|
||
|
+ snprintf(filename, sizeof(filename), "/run/udev/kmod/%u", (unsigned)getpid());
|
||
|
+ unlink(filename);
|
||
|
+ default:
|
||
|
+ break;
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+bool udev_check_for_kmod(pid_t pid) {
|
||
|
+ char filename[UTIL_PATH_SIZE];
|
||
|
+ struct stat st;
|
||
|
+ snprintf(filename, sizeof(filename), "/run/udev/kmod/%u", (unsigned)pid);
|
||
|
+ if (stat(filename, &st) == 0) {
|
||
|
+ return true;
|
||
|
+ }
|
||
|
+ return false;
|
||
|
+}
|
||
|
+#else
|
||
|
+# define udev_set_kmod (a,b)
|
||
|
+# define udev_unset_kmod(a,b)
|
||
|
+bool udev_check_for_kmod(pid_t pid) {
|
||
|
+ return false;
|
||
|
+}
|
||
|
+#endif
|
||
|
+
|
||
|
void udev_event_execute_run(struct udev_event *event, usec_t timeout_usec, usec_t timeout_warn_usec, const sigset_t *sigmask) {
|
||
|
struct udev_list_entry *list_entry;
|
||
|
|
||
|
@@ -970,7 +1010,9 @@ void udev_event_execute_run(struct udev_
|
||
|
char command[UTIL_PATH_SIZE];
|
||
|
|
||
|
udev_event_apply_format(event, cmd, command, sizeof(command));
|
||
|
+ udev_check_and_set_kmod(builtin_cmd, event);
|
||
|
udev_builtin_run(event->dev, builtin_cmd, command, false);
|
||
|
+ udev_check_and_unset_kmod(builtin_cmd, event);
|
||
|
} else {
|
||
|
char program[UTIL_PATH_SIZE];
|
||
|
char **envp;
|
||
|
--- src/udev/udevd.c
|
||
|
+++ src/udev/udevd.c 2014-09-24 15:02:30.895592379 +0000
|
||
|
@@ -76,6 +76,7 @@ static int children_max;
|
||
|
static int exec_delay;
|
||
|
static usec_t event_timeout_usec = 180 * USEC_PER_SEC;
|
||
|
static usec_t event_timeout_warn_usec = 180 * USEC_PER_SEC / 3;
|
||
|
+static bool event_killkmod = false;
|
||
|
static sigset_t sigmask_orig;
|
||
|
static UDEV_LIST(event_list);
|
||
|
static UDEV_LIST(worker_list);
|
||
|
@@ -1017,6 +1018,12 @@ static void kernel_cmdline_options(struc
|
||
|
}
|
||
|
event_timeout_usec *= USEC_PER_SEC;
|
||
|
event_timeout_warn_usec = (event_timeout_usec / 3) ? : 1;
|
||
|
+ } else if (startswith(opt, "udev.killkmod=")) {
|
||
|
+ r = parse_boolean(opt + 14);
|
||
|
+ if (r < 0)
|
||
|
+ log_warning("Invalid udev.killkmod Ignoring: %s", opt + 14);
|
||
|
+ else
|
||
|
+ event_killkmod = r;
|
||
|
}
|
||
|
|
||
|
free(s);
|
||
|
@@ -1065,7 +1072,7 @@ int main(int argc, char *argv[]) {
|
||
|
}
|
||
|
|
||
|
for (;;) {
|
||
|
- int option, r;
|
||
|
+ int option;
|
||
|
|
||
|
option = getopt_long(argc, argv, "c:de:DtN:hV", options, NULL);
|
||
|
if (option == -1)
|
||
|
@@ -1356,6 +1363,12 @@ int main(int argc, char *argv[]) {
|
||
|
udev_list_node_init(&event_list);
|
||
|
udev_list_node_init(&worker_list);
|
||
|
|
||
|
+ r = mkdir_p("/run/udev/kmod", 0755);
|
||
|
+ if (r < 0 && errno != EEXIST) {
|
||
|
+ log_error("could not create /run/udev/kmod: %m");
|
||
|
+ goto exit;
|
||
|
+ }
|
||
|
+
|
||
|
for (;;) {
|
||
|
static usec_t last_usec;
|
||
|
struct epoll_event ev[8];
|
||
|
@@ -1440,7 +1453,13 @@ int main(int argc, char *argv[]) {
|
||
|
|
||
|
if (worker->state != WORKER_RUNNING)
|
||
|
continue;
|
||
|
-
|
||
|
+#ifdef HAVE_KMOD
|
||
|
+ if (udev_check_for_kmod(worker->pid)) {
|
||
|
+ log_debug("worker [%u] %s is using kmod", worker->pid, worker->event->devpath);
|
||
|
+ if (!event_killkmod)
|
||
|
+ continue;
|
||
|
+ }
|
||
|
+#endif
|
||
|
ts = now(CLOCK_MONOTONIC);
|
||
|
|
||
|
if ((ts - worker->event_start_usec) > event_timeout_warn_usec) {
|
||
|
--- src/udev/udev.h
|
||
|
+++ src/udev/udev.h 2014-09-24 14:33:33.824008084 +0000
|
||
|
@@ -88,6 +88,7 @@ int udev_event_spawn(struct udev_event *
|
||
|
char *result, size_t ressize);
|
||
|
void udev_event_execute_rules(struct udev_event *event, usec_t timeout_usec, usec_t timeout_warn_usec,
|
||
|
struct udev_rules *rules, const sigset_t *sigset);
|
||
|
+bool udev_check_for_kmod(pid_t pid);
|
||
|
void udev_event_execute_run(struct udev_event *event, usec_t timeout_usec, usec_t timeout_warn_usec, const sigset_t *sigset);
|
||
|
int udev_build_argv(struct udev *udev, char *cmd, int *argc, char *argv[]);
|
||
|
|