summaryrefslogtreecommitdiff
path: root/src/udev/udev-event.c
diff options
context:
space:
mode:
authorTom Gundersen <teg@jklm.no>2014-09-11 18:49:04 +0200
committerTom Gundersen <teg@jklm.no>2014-09-11 23:45:01 +0200
commit671174136525ddf208cdbe75d6d6bd159afa961f (patch)
treed320e6f6f180c05be42c5201d34abcc40c52776c /src/udev/udev-event.c
parente926f6475d2f7063f8190076a0dc9ff7ecb227c8 (diff)
udev: timeout - warn after a third of the timeout before killing
Diffstat (limited to 'src/udev/udev-event.c')
-rw-r--r--src/udev/udev-event.c40
1 files changed, 30 insertions, 10 deletions
diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c
index a883edca07..e8d6676616 100644
--- a/src/udev/udev-event.c
+++ b/src/udev/udev-event.c
@@ -541,6 +541,7 @@ out:
static int spawn_wait(struct udev_event *event,
usec_t timeout_usec,
+ usec_t timeout_warn_usec,
const char *cmd, pid_t pid) {
struct pollfd pfd[1];
int err = 0;
@@ -550,6 +551,7 @@ static int spawn_wait(struct udev_event *event,
while (pid > 0) {
int timeout;
+ int timeout_warn = 0;
int fdcount;
if (timeout_usec > 0) {
@@ -558,13 +560,17 @@ static int spawn_wait(struct udev_event *event,
age_usec = now(CLOCK_MONOTONIC) - event->birth_usec;
if (age_usec >= timeout_usec)
timeout = 1000;
- else
- timeout = ((timeout_usec - age_usec) / USEC_PER_MSEC) + MSEC_PER_SEC;
+ else {
+ if (timeout_warn_usec > 0)
+ timeout_warn = ((timeout_warn_usec - age_usec) / USEC_PER_MSEC) + MSEC_PER_SEC;
+
+ timeout = ((timeout_usec - timeout_warn_usec - age_usec) / USEC_PER_MSEC) + MSEC_PER_SEC;
+ }
} else {
timeout = -1;
}
- fdcount = poll(pfd, 1, timeout);
+ fdcount = poll(pfd, 1, timeout_warn);
if (fdcount < 0) {
if (errno == EINTR)
continue;
@@ -573,8 +579,20 @@ static int spawn_wait(struct udev_event *event,
goto out;
}
if (fdcount == 0) {
- log_error("timeout: killing '%s' [%u]", cmd, pid);
- kill(pid, SIGKILL);
+ log_warning("slow: '%s' [%u]", cmd, pid);
+
+ fdcount = poll(pfd, 1, timeout);
+ if (fdcount < 0) {
+ if (errno == EINTR)
+ continue;
+ err = -errno;
+ log_error("failed to poll: %m");
+ goto out;
+ }
+ if (fdcount == 0) {
+ log_error("timeout: killing '%s' [%u]", cmd, pid);
+ kill(pid, SIGKILL);
+ }
}
if (pfd[0].revents & POLLIN) {
@@ -654,6 +672,7 @@ out:
int udev_event_spawn(struct udev_event *event,
usec_t timeout_usec,
+ usec_t timeout_warn_usec,
const char *cmd, char **envp, const sigset_t *sigmask,
char *result, size_t ressize) {
struct udev *udev = event->udev;
@@ -730,7 +749,7 @@ int udev_event_spawn(struct udev_event *event,
outpipe[READ_END], errpipe[READ_END],
result, ressize);
- err = spawn_wait(event, timeout_usec, cmd, pid);
+ err = spawn_wait(event, timeout_usec, timeout_warn_usec, cmd, pid);
}
out:
@@ -769,6 +788,7 @@ static int rename_netif(struct udev_event *event) {
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 *sigmask) {
struct udev_device *dev = event->dev;
@@ -783,7 +803,7 @@ void udev_event_execute_rules(struct udev_event *event,
if (major(udev_device_get_devnum(dev)) != 0)
udev_watch_end(event->udev, dev);
- udev_rules_apply_to_event(rules, event, timeout_usec, sigmask);
+ udev_rules_apply_to_event(rules, event, timeout_usec, timeout_warn_usec, sigmask);
if (major(udev_device_get_devnum(dev)) != 0)
udev_node_remove(dev);
@@ -816,7 +836,7 @@ void udev_event_execute_rules(struct udev_event *event,
}
}
- udev_rules_apply_to_event(rules, event, timeout_usec, sigmask);
+ udev_rules_apply_to_event(rules, event, timeout_usec, timeout_warn_usec, sigmask);
/* rename a new network interface, if needed */
if (udev_device_get_ifindex(dev) > 0 && streq(udev_device_get_action(dev), "add") &&
@@ -889,7 +909,7 @@ void udev_event_execute_rules(struct udev_event *event,
}
}
-void udev_event_execute_run(struct udev_event *event, usec_t timeout_usec, const sigset_t *sigmask) {
+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;
udev_list_entry_foreach(list_entry, udev_list_get_entry(&event->run_list)) {
@@ -912,7 +932,7 @@ void udev_event_execute_run(struct udev_event *event, usec_t timeout_usec, const
udev_event_apply_format(event, cmd, program, sizeof(program));
envp = udev_device_get_properties_envp(event->dev);
- udev_event_spawn(event, timeout_usec, program, envp, sigmask, NULL, 0);
+ udev_event_spawn(event, timeout_usec, timeout_warn_usec, program, envp, sigmask, NULL, 0);
}
}
}