From 29448498c724da7ade1b5efb20d7472c1b128d2c Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 17 Oct 2018 06:11:33 +0900 Subject: [PATCH] udev: use Hashmap for storing PROGRAM or BUILTIN --- src/udev/udev-event.c | 15 +++++++++------ src/udev/udev-rules.c | 27 ++++++++++++++++++++++----- src/udev/udev.h | 2 +- src/udev/udevadm-test.c | 7 +++++-- 4 files changed, 37 insertions(+), 14 deletions(-) diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c index e015ecf52f..966be0d9f2 100644 --- a/src/udev/udev-event.c +++ b/src/udev/udev-event.c @@ -44,16 +44,18 @@ struct udev_event *udev_event_new(struct udev_device *dev) { if (event == NULL) return NULL; event->dev = dev; - udev_list_init(NULL, &event->run_list, false); event->birth_usec = now(CLOCK_MONOTONIC); return event; } void udev_event_unref(struct udev_event *event) { + void *p; + if (event == NULL) return; sd_netlink_unref(event->rtnl); - udev_list_cleanup(&event->run_list); + while ((p = hashmap_steal_first_key(event->run_list))) + free(p); hashmap_free_free_free(event->seclabel_list); free(event->program_result); free(event->name); @@ -888,12 +890,13 @@ void udev_event_execute_rules(struct udev_event *event, } void udev_event_execute_run(struct udev_event *event, usec_t timeout_usec, usec_t timeout_warn_usec) { - struct udev_list_entry *list_entry; + const char *cmd; + void *val; + Iterator i; - udev_list_entry_foreach(list_entry, udev_list_get_entry(&event->run_list)) { + HASHMAP_FOREACH_KEY(val, cmd, event->run_list, i) { + enum udev_builtin_cmd builtin_cmd = PTR_TO_INT(val); char command[UTIL_PATH_SIZE]; - const char *cmd = udev_list_entry_get_name(list_entry); - enum udev_builtin_cmd builtin_cmd = udev_list_entry_get_num(list_entry); udev_event_apply_format(event, cmd, command, sizeof(command), false); diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index 601b95882d..e90b76283c 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -2388,16 +2388,33 @@ int udev_rules_apply_to_event( } case TK_A_RUN_BUILTIN: case TK_A_RUN_PROGRAM: { - struct udev_list_entry *entry; + _cleanup_free_ char *cmd = NULL; + + if (IN_SET(cur->key.op, OP_ASSIGN, OP_ASSIGN_FINAL)) { + void *p; + + while ((p = hashmap_steal_first_key(event->run_list))) + free(p); + } + + r = hashmap_ensure_allocated(&event->run_list, NULL); + if (r < 0) + return log_oom(); + + cmd = strdup(rules_str(rules, cur->key.value_off)); + if (!cmd) + return log_oom(); + + r = hashmap_put(event->run_list, cmd, INT_TO_PTR(cur->key.builtin_cmd)); + if (r < 0) + return log_oom(); + + cmd = NULL; - if (IN_SET(cur->key.op, OP_ASSIGN, OP_ASSIGN_FINAL)) - udev_list_cleanup(&event->run_list); log_debug("RUN '%s' %s:%u", rules_str(rules, cur->key.value_off), rules_str(rules, rule->rule.filename_off), rule->rule.filename_line); - entry = udev_list_entry_add(&event->run_list, rules_str(rules, cur->key.value_off), NULL); - udev_list_entry_set_num(entry, cur->key.builtin_cmd); break; } case TK_A_GOTO: diff --git a/src/udev/udev.h b/src/udev/udev.h index afdd876e28..d5336ab8f1 100644 --- a/src/udev/udev.h +++ b/src/udev/udev.h @@ -30,7 +30,7 @@ struct udev_event { uid_t uid; gid_t gid; Hashmap *seclabel_list; - struct udev_list run_list; + Hashmap *run_list; int exec_delay; usec_t birth_usec; sd_netlink *rtnl; diff --git a/src/udev/udevadm-test.c b/src/udev/udevadm-test.c index d2868d114c..ea6471b837 100644 --- a/src/udev/udevadm-test.c +++ b/src/udev/udevadm-test.c @@ -92,6 +92,9 @@ int test_main(int argc, char *argv[], void *userdata) { _cleanup_(udev_event_unrefp) struct udev_event *event = NULL; struct udev_list_entry *entry; sigset_t mask, sigmask_orig; + const char *cmd; + Iterator i; + void *val; int r; log_set_max_level(LOG_DEBUG); @@ -138,10 +141,10 @@ int test_main(int argc, char *argv[], void *userdata) { 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)); - udev_list_entry_foreach(entry, udev_list_get_entry(&event->run_list)) { + HASHMAP_FOREACH_KEY(val, cmd, event->run_list, i) { char program[UTIL_PATH_SIZE]; - udev_event_apply_format(event, udev_list_entry_get_name(entry), program, sizeof(program), false); + udev_event_apply_format(event, cmd, program, sizeof(program), false); printf("run: '%s'\n", program); }