systemd/1087-infinit-timeout-for-kmod-loaded-modules.patch

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[]);