From 9b5150b63e35f30a5cce8571225518597f690f41 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 17 Oct 2018 06:47:16 +0900 Subject: [PATCH] udev: use Hashmap for storing global properties --- src/udev/udev-event.c | 2 +- src/udev/udev-rules.c | 16 +++------ src/udev/udev.h | 4 +-- src/udev/udevd.c | 76 +++++++++++++++++++++++++++++-------------- 4 files changed, 59 insertions(+), 39 deletions(-) diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c index 966be0d9f2..75e5866bb0 100644 --- a/src/udev/udev-event.c +++ b/src/udev/udev-event.c @@ -791,7 +791,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_list *properties_list, + Hashmap *properties_list, struct udev_rules *rules) { struct udev_device *dev = event->dev; diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index e90b76283c..752e17f2ae 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -1716,7 +1716,7 @@ int udev_rules_apply_to_event( struct udev_event *event, usec_t timeout_usec, usec_t timeout_warn_usec, - struct udev_list *properties_list) { + Hashmap *properties_list) { struct token *cur; struct token *rule; enum escape_type esc = ESCAPE_UNSET; @@ -1784,18 +1784,10 @@ int udev_rules_apply_to_event( value = udev_device_get_property_value(event->dev, key_name); /* check global properties */ - if (!value && properties_list) { - struct udev_list_entry *list_entry; + if (!value && properties_list) + value = hashmap_get(properties_list, key_name); - list_entry = udev_list_get_entry(properties_list); - list_entry = udev_list_entry_get_by_name(list_entry, key_name); - if (list_entry != NULL) - value = udev_list_entry_get_value(list_entry); - } - - if (!value) - value = ""; - if (match_key(rules, cur, value)) + if (match_key(rules, cur, strempty(value))) goto nomatch; break; } diff --git a/src/udev/udev.h b/src/udev/udev.h index d5336ab8f1..99217545dc 100644 --- a/src/udev/udev.h +++ b/src/udev/udev.h @@ -56,7 +56,7 @@ 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, usec_t timeout_usec, usec_t timeout_warn_usec, - struct udev_list *properties_list); + Hashmap *properties_list); int udev_rules_apply_static_dev_perms(struct udev_rules *rules); /* udev-event.c */ @@ -74,7 +74,7 @@ int udev_event_spawn(struct udev_event *event, const char *cmd, 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_list *properties_list, + Hashmap *properties_list, struct udev_rules *rules); void udev_event_execute_run(struct udev_event *event, usec_t timeout_usec, usec_t timeout_warn_usec); diff --git a/src/udev/udevd.c b/src/udev/udevd.c index 06a122bd6a..20fd23053a 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c @@ -75,7 +75,7 @@ typedef struct Manager { pid_t pid; /* the process that originally allocated the manager object */ struct udev_rules *rules; - struct udev_list properties; + Hashmap *properties; struct udev_monitor *monitor; struct udev_ctrl *ctrl; @@ -293,7 +293,7 @@ static void manager_free(Manager *manager) { udev_ctrl_unref(manager->ctrl); udev_ctrl_connection_unref(manager->ctrl_conn_blocking); - udev_list_cleanup(&manager->properties); + hashmap_free_free_free(manager->properties); udev_rules_unref(manager->rules); safe_close(manager->fd_inotify); @@ -444,7 +444,7 @@ static void worker_spawn(Manager *manager, struct event *event) { /* apply rules, create node, symlinks */ udev_event_execute_rules(udev_event, arg_event_timeout_usec, arg_event_timeout_warn_usec, - &manager->properties, + manager->properties, manager->rules); udev_event_execute_run(udev_event, @@ -918,7 +918,7 @@ static int on_ctrl_msg(sd_event_source *s, int fd, uint32_t revents, void *userd _cleanup_(udev_ctrl_connection_unrefp) struct udev_ctrl_connection *ctrl_conn = NULL; _cleanup_(udev_ctrl_msg_unrefp) struct udev_ctrl_msg *ctrl_msg = NULL; const char *str; - int i; + int i, r; assert(manager); @@ -954,27 +954,56 @@ static int on_ctrl_msg(sd_event_source *s, int fd, uint32_t revents, void *userd } str = udev_ctrl_get_set_env(ctrl_msg); - if (str != NULL) { - _cleanup_free_ char *key = NULL; + if (str) { + _cleanup_free_ char *key = NULL, *val = NULL, *old_key = NULL, *old_val = NULL; + char *eq; - key = strdup(str); - if (key) { - char *val; - - val = strchr(key, '='); - if (val != NULL) { - val[0] = '\0'; - val = &val[1]; - if (val[0] == '\0') { - log_debug("udevd message (ENV) received, unset '%s'", key); - udev_list_entry_add(&manager->properties, key, NULL); - } else { - log_debug("udevd message (ENV) received, set '%s=%s'", key, val); - udev_list_entry_add(&manager->properties, key, val); - } - } else - log_error("wrong key format '%s'", key); + eq = strchr(str, '='); + if (!eq) { + log_error("Invalid key format '%s'", str); + return 1; } + + key = strndup(str, eq - str); + if (!key) { + log_oom(); + return 1; + } + + old_val = hashmap_remove2(manager->properties, key, (void **) &old_key); + + r = hashmap_ensure_allocated(&manager->properties, &string_hash_ops); + if (r < 0) { + log_oom(); + return 1; + } + + eq++; + if (!isempty(eq)) { + log_debug("udevd message (ENV) received, unset '%s'", key); + + r = hashmap_put(manager->properties, key, NULL); + if (r < 0) { + log_oom(); + return 1; + } + } else { + val = strdup(eq); + if (!val) { + log_oom(); + return 1; + } + + log_debug("udevd message (ENV) received, set '%s=%s'", key, val); + + r = hashmap_put(manager->properties, key, val); + if (r < 0) { + log_oom(); + return 1; + } + } + + key = val = NULL; manager_kill_workers(manager); } @@ -1529,7 +1558,6 @@ static int manager_new(Manager **ret, int fd_ctrl, int fd_uevent, const char *cg return log_error_errno(ENOMEM, "error reading rules"); LIST_HEAD_INIT(manager->events); - udev_list_init(NULL, &manager->properties, true); manager->cgroup = cgroup;