From: Yu Watanabe Date: Tue, 16 Oct 2018 21:11:33 +0000 (+0900) Subject: udev: use Hashmap for storing PROGRAM or BUILTIN X-Git-Tag: v240~534^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=29448498c724da7ade1b5efb20d7472c1b128d2c;p=thirdparty%2Fsystemd.git udev: use Hashmap for storing PROGRAM or BUILTIN --- diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c index e015ecf52f1..966be0d9f29 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 601b95882dd..e90b76283cb 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 afdd876e282..d5336ab8f1e 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 d2868d114cd..ea6471b837b 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); }