diff options
author | Kay Sievers <kay@vrfy.org> | 2014-07-30 09:31:38 -0400 |
---|---|---|
committer | Anthony G. Basile <blueness@gentoo.org> | 2014-07-30 09:31:38 -0400 |
commit | 471a5f341168cff3f07474b7c4a88779bdd8ca1d (patch) | |
tree | 80b5c3a53c25f451220a1cfef1e4dec467719b35 | |
parent | babb0ec5865658d920ef0bb07c89a3122beb8ec2 (diff) |
udev: unify event timeout handling
Signed-off-by: Anthony G. Basile <blueness@gentoo.org>
-rw-r--r-- | man/udev.xml | 7 | ||||
-rw-r--r-- | src/udev/udev-event.c | 53 | ||||
-rw-r--r-- | src/udev/udev-rules.c | 38 | ||||
-rw-r--r-- | src/udev/udev.h | 8 | ||||
-rw-r--r-- | src/udev/udevadm-test.c | 2 | ||||
-rw-r--r-- | src/udev/udevd.c | 32 | ||||
-rw-r--r-- | test/test-udev.c | 5 |
7 files changed, 58 insertions, 87 deletions
diff --git a/man/udev.xml b/man/udev.xml index e40af400bf..96867a3457 100644 --- a/man/udev.xml +++ b/man/udev.xml @@ -510,13 +510,6 @@ </listitem> </varlistentry> <varlistentry> - <term><option>event_timeout=</option></term> - <listitem> - <para>Number of seconds an event waits for operations to finish before - giving up and terminating itself.</para> - </listitem> - </varlistentry> - <varlistentry> <term><option>string_escape=<replaceable>none|replace</replaceable></option></term> <listitem> <para>Usually control and other possibly unsafe characters are replaced diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c index 783c8cf0a7..ec2217e1bb 100644 --- a/src/udev/udev-event.c +++ b/src/udev/udev-event.c @@ -50,7 +50,6 @@ struct udev_event *udev_event_new(struct udev_device *dev) udev_list_init(udev, &event->seclabel_list, false); event->fd_signal = -1; event->birth_usec = now(CLOCK_MONOTONIC); - event->timeout_usec = 30 * 1000 * 1000; return event; } @@ -424,9 +423,10 @@ static int spawn_exec(struct udev_event *event, } static void spawn_read(struct udev_event *event, - const char *cmd, - int fd_stdout, int fd_stderr, - char *result, size_t ressize) + usec_t timeout_usec, + const char *cmd, + int fd_stdout, int fd_stderr, + char *result, size_t ressize) { size_t respos = 0; int fd_ep = -1; @@ -469,15 +469,15 @@ static void spawn_read(struct udev_event *event, struct epoll_event ev[4]; int i; - if (event->timeout_usec > 0) { + if (timeout_usec > 0) { usec_t age_usec; age_usec = now(CLOCK_MONOTONIC) - event->birth_usec; - if (age_usec >= event->timeout_usec) { + if (age_usec >= timeout_usec) { log_error("timeout '%s'", cmd); goto out; } - timeout = ((event->timeout_usec - age_usec) / 1000) + 1000; + timeout = ((timeout_usec - age_usec) / USEC_PER_MSEC) + MSEC_PER_SEC; } else { timeout = -1; } @@ -545,8 +545,9 @@ out: close(fd_ep); } -static int spawn_wait(struct udev_event *event, const char *cmd, pid_t pid) -{ +static int spawn_wait(struct udev_event *event, + usec_t timeout_usec, + const char *cmd, pid_t pid) { struct pollfd pfd[1]; int err = 0; @@ -557,14 +558,14 @@ static int spawn_wait(struct udev_event *event, const char *cmd, pid_t pid) int timeout; int fdcount; - if (event->timeout_usec > 0) { + if (timeout_usec > 0) { usec_t age_usec; age_usec = now(CLOCK_MONOTONIC) - event->birth_usec; - if (age_usec >= event->timeout_usec) + if (age_usec >= timeout_usec) timeout = 1000; else - timeout = ((event->timeout_usec - age_usec) / 1000) + 1000; + timeout = ((timeout_usec - age_usec) / USEC_PER_MSEC) + MSEC_PER_SEC; } else { timeout = -1; } @@ -659,9 +660,9 @@ out: } int udev_event_spawn(struct udev_event *event, + usec_t timeout_usec, const char *cmd, char **envp, const sigset_t *sigmask, - char *result, size_t ressize) -{ + char *result, size_t ressize) { struct udev *udev = event->udev; int outpipe[2] = {-1, -1}; int errpipe[2] = {-1, -1}; @@ -736,11 +737,13 @@ int udev_event_spawn(struct udev_event *event, errpipe[WRITE_END] = -1; } - spawn_read(event, cmd, - outpipe[READ_END], errpipe[READ_END], - result, ressize); + spawn_read(event, + timeout_usec, + cmd, + outpipe[READ_END], errpipe[READ_END], + result, ressize); - err = spawn_wait(event, cmd, pid); + err = spawn_wait(event, timeout_usec, cmd, pid); } out: @@ -835,8 +838,9 @@ static int rename_netif(struct udev_event *event) return rename_netif_dev_fromname_toname(event->dev,udev_device_get_sysname(event->dev),event->name); } -void udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules, const sigset_t *sigmask) -{ +void udev_event_execute_rules(struct udev_event *event, + usec_t timeout_usec, + struct udev_rules *rules, const sigset_t *sigmask) { struct udev_device *dev = event->dev; if (udev_device_get_subsystem(dev) == NULL) @@ -850,7 +854,7 @@ void udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules if (major(udev_device_get_devnum(dev)) != 0) udev_watch_end(event->udev, dev); - udev_rules_apply_to_event(rules, event, sigmask); + udev_rules_apply_to_event(rules, event, timeout_usec, sigmask); if (major(udev_device_get_devnum(dev)) != 0) udev_node_remove(dev); @@ -867,7 +871,7 @@ void udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules udev_watch_end(event->udev, event->dev_db); } - udev_rules_apply_to_event(rules, event, sigmask); + udev_rules_apply_to_event(rules, event, timeout_usec, sigmask); /* rename a new network interface, if needed */ @@ -1011,8 +1015,7 @@ void udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules } } -void udev_event_execute_run(struct udev_event *event, const sigset_t *sigmask) -{ +void udev_event_execute_run(struct udev_event *event, usec_t timeout_usec, const sigset_t *sigmask) { struct udev_list_entry *list_entry; udev_list_entry_foreach(list_entry, udev_list_get_entry(&event->run_list)) { @@ -1035,7 +1038,7 @@ void udev_event_execute_run(struct udev_event *event, const sigset_t *sigmask) udev_event_apply_format(event, cmd, program, sizeof(program)); envp = udev_device_get_properties_envp(event->dev); - udev_event_spawn(event, program, envp, sigmask, NULL, 0); + udev_event_spawn(event, timeout_usec, program, envp, sigmask, NULL, 0); } } } diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index c47d025846..4be7f020aa 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -142,7 +142,6 @@ enum token_type { TK_M_PARENTS_MAX, TK_M_TEST, /* val, mode_t */ - TK_M_EVENT_TIMEOUT, /* int */ TK_M_PROGRAM, /* val */ TK_M_IMPORT_FILE, /* val */ TK_M_IMPORT_PROG, /* val */ @@ -206,7 +205,6 @@ struct token { uid_t uid; gid_t gid; int devlink_prio; - int event_timeout; int watch; enum udev_builtin_cmd builtin_cmd; }; @@ -280,7 +278,6 @@ static const char *token_str(enum token_type type) [TK_M_PARENTS_MAX] = "M PARENTS_MAX", [TK_M_TEST] = "M TEST", - [TK_M_EVENT_TIMEOUT] = "M EVENT_TIMEOUT", [TK_M_PROGRAM] = "M PROGRAM", [TK_M_IMPORT_FILE] = "M IMPORT_FILE", [TK_M_IMPORT_PROG] = "M IMPORT_PROG", @@ -414,9 +411,6 @@ static void dump_token(struct udev_rules *rules, struct token *token) case TK_A_SECLABEL: log_debug("%s %s '%s' '%s'", token_str(type), operation_str(op), attr, value); break; - case TK_M_EVENT_TIMEOUT: - log_debug("%s %u", token_str(type), token->key.event_timeout); - break; case TK_A_GOTO: log_debug("%s '%s' %u", token_str(type), value, token->key.rule_goto); break; @@ -632,8 +626,9 @@ static int import_file_into_properties(struct udev_device *dev, const char *file return 0; } -static int import_program_into_properties(struct udev_event *event, const char *program, const sigset_t *sigmask) -{ +static int import_program_into_properties(struct udev_event *event, + usec_t timeout_usec, + const char *program, const sigset_t *sigmask) { struct udev_device *dev = event->dev; char **envp; char result[UTIL_LINE_SIZE]; @@ -641,7 +636,7 @@ static int import_program_into_properties(struct udev_event *event, const char * int err; envp = udev_device_get_properties_envp(dev); - err = udev_event_spawn(event, program, envp, sigmask, result, sizeof(result)); + err = udev_event_spawn(event, timeout_usec, program, envp, sigmask, result, sizeof(result)); if (err < 0) return err; @@ -947,9 +942,6 @@ static int rule_add_key(struct rule_tmp *rule_tmp, enum token_type type, case TK_A_MODE_ID: token->key.mode = *(mode_t *)data; break; - case TK_M_EVENT_TIMEOUT: - token->key.event_timeout = *(int *)data; - break; case TK_RULE: case TK_M_PARENTS_MIN: case TK_M_PARENTS_MAX: @@ -1467,14 +1459,6 @@ static int add_rule(struct udev_rules *rules, char *line, rule_add_key(&rule_tmp, TK_A_DEVLINK_PRIO, op, NULL, &prio); } - pos = strstr(value, "event_timeout="); - if (pos != NULL) { - int tout = atoi(&pos[strlen("event_timeout=")]); - - rule_add_key(&rule_tmp, TK_M_EVENT_TIMEOUT, op, NULL, &tout); - } - - pos = strstr(value, "string_escape="); if (pos != NULL) { pos = &pos[strlen("string_escape=")]; if (startswith(pos, "none")) @@ -1899,8 +1883,10 @@ int udev_rules_assigning_name_to(struct udev_rules *rules, const char *match_nam } #endif -int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event, const sigset_t *sigmask) -{ +int udev_rules_apply_to_event(struct udev_rules *rules, + struct udev_event *event, + usec_t timeout_usec, + const sigset_t *sigmask) { struct token *cur; struct token *rule; enum escape_type esc = ESCAPE_UNSET; @@ -2094,10 +2080,6 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event goto nomatch; break; } - case TK_M_EVENT_TIMEOUT: - log_debug("OPTIONS event_timeout=%u", cur->key.event_timeout); - event->timeout_usec = cur->key.event_timeout * 1000 * 1000; - break; case TK_M_PROGRAM: { char program[UTIL_PATH_SIZE]; char **envp; @@ -2112,7 +2094,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event rules_str(rules, rule->rule.filename_off), rule->rule.filename_line); - if (udev_event_spawn(event, program, envp, sigmask, result, sizeof(result)) < 0) { + if (udev_event_spawn(event, timeout_usec, program, envp, sigmask, result, sizeof(result)) < 0) { if (cur->key.op != OP_NOMATCH) goto nomatch; } else { @@ -2148,7 +2130,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event rules_str(rules, rule->rule.filename_off), rule->rule.filename_line); - if (import_program_into_properties(event, import, sigmask) != 0) + if (import_program_into_properties(event, timeout_usec, import, sigmask) != 0) if (cur->key.op != OP_NOMATCH) goto nomatch; break; diff --git a/src/udev/udev.h b/src/udev/udev.h index 86a9ea6809..ddd7104a97 100644 --- a/src/udev/udev.h +++ b/src/udev/udev.h @@ -43,7 +43,6 @@ struct udev_event { struct udev_list run_list; int exec_delay; usec_t birth_usec; - usec_t timeout_usec; int fd_signal; unsigned int builtin_run; unsigned int builtin_ret; @@ -72,7 +71,7 @@ struct udev_rules; struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names); struct udev_rules *udev_rules_unref(struct udev_rules *rules); bool udev_rules_check_timestamp(struct udev_rules *rules); -int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event, const sigset_t *sigmask); +int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event, usec_t timeout_usec, const sigset_t *sigmask); int udev_rules_apply_static_dev_perms(struct udev_rules *rules); /* udev-event.c */ @@ -82,10 +81,11 @@ size_t udev_event_apply_format(struct udev_event *event, const char *src, char * int udev_event_apply_subsys_kernel(struct udev_event *event, const char *string, char *result, size_t maxsize, int read_value); int udev_event_spawn(struct udev_event *event, + usec_t timeout_usec, const char *cmd, char **envp, const sigset_t *sigmask, char *result, size_t ressize); -void udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules, const sigset_t *sigset); -void udev_event_execute_run(struct udev_event *event, const sigset_t *sigset); +void udev_event_execute_rules(struct udev_event *event, usec_t timeout_usec, struct udev_rules *rules, const sigset_t *sigset); +void udev_event_execute_run(struct udev_event *event, usec_t timeout_usec, const sigset_t *sigset); int udev_build_argv(struct udev *udev, char *cmd, int *argc, char *argv[]); /* udev-watch.c */ diff --git a/src/udev/udevadm-test.c b/src/udev/udevadm-test.c index 6a2f5489fe..52cc26c1d6 100644 --- a/src/udev/udevadm-test.c +++ b/src/udev/udevadm-test.c @@ -138,7 +138,7 @@ static int adm_test(struct udev *udev, int argc, char *argv[]) goto out; } - udev_event_execute_rules(event, rules, &sigmask_orig); + udev_event_execute_rules(event, 30 * USEC_PER_SEC, rules, &sigmask_orig); udev_list_entry_foreach(entry, udev_device_get_properties_list_entry(dev)) printf("%s=%s\n", udev_list_entry_get_name(entry), udev_list_entry_get_value(entry)); diff --git a/src/udev/udevd.c b/src/udev/udevd.c index 269baa3ce2..ac015a2dc8 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c @@ -74,7 +74,7 @@ static bool reload; static int children; static int children_max; static int exec_delay; -static int event_timeout = 30; +static usec_t event_timeout_usec = 30 * USEC_PER_SEC; static sigset_t sigmask_orig; static UDEV_LIST(event_list); static UDEV_LIST(worker_list); @@ -313,13 +313,10 @@ static void worker_new(struct event *event) } } - if (event_timeout != 30) - udev_event->timeout_usec = event_timeout * USEC_PER_SEC; - /* apply rules, create node, symlinks */ - udev_event_execute_rules(udev_event, rules, &sigmask_orig); + udev_event_execute_rules(udev_event, event_timeout_usec, rules, &sigmask_orig); - udev_event_execute_run(udev_event, &sigmask_orig); + udev_event_execute_run(udev_event, event_timeout_usec, &sigmask_orig); /* apply/restore inotify watch */ if (udev_event->inotify_watch) { @@ -1049,15 +1046,14 @@ static void kernel_cmdline_options(struct udev *udev) } else if (startswith(opt, "udev.exec-delay=")) { exec_delay = strtoul(opt + 16, NULL, 0); } else if (startswith(opt, "udev.event-timeout=")) { - event_timeout = strtoul(opt + 16, NULL, 0); + event_timeout_usec = strtoul(opt + 16, NULL, 0) * USEC_PER_SEC; } free(s); } } -int main(int argc, char *argv[]) -{ +int main(int argc, char *argv[]) { struct udev *udev; sigset_t mask; int daemonize = false; @@ -1111,7 +1107,7 @@ int main(int argc, char *argv[]) exec_delay = strtoul(optarg, NULL, 0); break; case 't': - event_timeout = strtoul(optarg, NULL, 0); + event_timeout_usec = strtoul(optarg, NULL, 0) * USEC_PER_SEC; break; case 'D': debug = true; @@ -1137,6 +1133,7 @@ int main(int argc, char *argv[]) " --debug\n" " --children-max=<maximum number of workers>\n" " --exec-delay=<seconds to wait before executing RUN=>\n" + " --event-timeout=<seconds to wait before terminating an event>\n" " --resolve-names=early|late|never\n" " --version\n" " --help\n" @@ -1443,20 +1440,17 @@ int main(int argc, char *argv[]) if (worker->state != WORKER_RUNNING) continue; - if ((now(CLOCK_MONOTONIC) - worker->event_start_usec) > event_timeout * USEC_PER_SEC) { - log_error("worker [%u] %s timeout; kill it", worker->pid, - worker->event ? worker->event->devpath : "<idle>"); + if ((now(CLOCK_MONOTONIC) - worker->event_start_usec) > event_timeout_usec) { + log_error("worker [%u] %s timeout; kill it", worker->pid, worker->event->devpath); kill(worker->pid, SIGKILL); worker->state = WORKER_KILLED; /* drop reference taken for state 'running' */ worker_unref(worker); - if (worker && worker->event) { - log_error("seq %llu '%s' killed", udev_device_get_seqnum(worker->event->dev), worker->event->devpath); - worker->event->exitcode = -64; - event_queue_delete(worker->event); - worker->event = NULL; - } + log_error("seq %llu '%s' killed", udev_device_get_seqnum(worker->event->dev), worker->event->devpath); + worker->event->exitcode = -64; + event_queue_delete(worker->event); + worker->event = NULL; } } diff --git a/test/test-udev.c b/test/test-udev.c index 1828d54e42..fd4388a678 100644 --- a/test/test-udev.c +++ b/test/test-udev.c @@ -90,7 +90,6 @@ out: return err; } - int main(int argc, char *argv[]) { struct udev *udev = NULL; struct udev_event *event = NULL; @@ -165,8 +164,8 @@ int main(int argc, char *argv[]) { } } - udev_event_execute_rules(event, rules, &sigmask_orig); - udev_event_execute_run(event, NULL); + udev_event_execute_rules(event, USEC_PER_SEC, rules, &sigmask_orig); + udev_event_execute_run(event, USEC_PER_SEC, NULL); out: if (event != NULL && event->fd_signal >= 0) close(event->fd_signal); |