From 3e5700428e768438bb1083e004be23201ede4e08 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 12 Nov 2018 15:24:11 +0900 Subject: [PATCH] network: allocate hashmap objects when they are required --- src/network/netdev/netdev.c | 4 ++ src/network/networkd-address-label.c | 4 ++ src/network/networkd-address.c | 4 ++ src/network/networkd-fdb.c | 4 ++ src/network/networkd-manager.c | 63 ++++++++++------------ src/network/networkd-network.c | 36 +++---------- src/network/networkd-network.h | 2 +- src/network/networkd-radv.c | 7 ++- src/network/networkd-route.c | 4 ++ src/network/networkd-routing-policy-rule.c | 4 ++ src/network/test-networkd-conf.c | 1 - 11 files changed, 66 insertions(+), 67 deletions(-) diff --git a/src/network/netdev/netdev.c b/src/network/netdev/netdev.c index 4c683874eb..33931bad92 100644 --- a/src/network/netdev/netdev.c +++ b/src/network/netdev/netdev.c @@ -729,6 +729,10 @@ int netdev_load_one(Manager *manager, const char *filename) { return log_error_errno(r, "Failed to generate predictable MAC address for %s: %m", netdev->ifname); } + r = hashmap_ensure_allocated(&netdev->manager->netdevs, &string_hash_ops); + if (r < 0) + return r; + r = hashmap_put(netdev->manager->netdevs, netdev->ifname, netdev); if (r < 0) return r; diff --git a/src/network/networkd-address-label.c b/src/network/networkd-address-label.c index 1392cba538..691bbf4761 100644 --- a/src/network/networkd-address-label.c +++ b/src/network/networkd-address-label.c @@ -65,6 +65,10 @@ static int address_label_new_static(Network *network, const char *filename, unsi if (filename) { label->section = TAKE_PTR(n); + r = hashmap_ensure_allocated(&network->address_labels_by_section, &network_config_hash_ops); + if (r < 0) + return r; + r = hashmap_put(network->address_labels_by_section, label->section, label); if (r < 0) return r; diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c index d028f7226e..09f041602c 100644 --- a/src/network/networkd-address.c +++ b/src/network/networkd-address.c @@ -74,6 +74,10 @@ int address_new_static(Network *network, const char *filename, unsigned section_ if (filename) { address->section = TAKE_PTR(n); + r = hashmap_ensure_allocated(&network->addresses_by_section, &network_config_hash_ops); + if (r < 0) + return r; + r = hashmap_put(network->addresses_by_section, address->section, address); if (r < 0) return r; diff --git a/src/network/networkd-fdb.c b/src/network/networkd-fdb.c index 3203470db3..c7742a93fb 100644 --- a/src/network/networkd-fdb.c +++ b/src/network/networkd-fdb.c @@ -72,6 +72,10 @@ int fdb_entry_new_static( if (filename) { fdb_entry->section = TAKE_PTR(n); + r = hashmap_ensure_allocated(&network->fdb_entries_by_section, &network_config_hash_ops); + if (r < 0) + return r; + r = hashmap_put(network->fdb_entries_by_section, fdb_entry->section, fdb_entry); if (r < 0) return r; diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index ac649863b4..fce8f4610c 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -1213,7 +1213,6 @@ static int manager_dirty_handler(sd_event_source *s, void *userdata) { Link *manager_dhcp6_prefix_get(Manager *m, struct in6_addr *addr) { assert_return(m, NULL); - assert_return(m->dhcp6_prefixes, NULL); assert_return(addr, NULL); return hashmap_get(m->dhcp6_prefixes, addr); @@ -1232,13 +1231,31 @@ static int dhcp6_route_add_handler(sd_netlink *nl, sd_netlink_message *m, void * return 0; } +static void dhcp6_prefixes_hash_func(const void *p, struct siphash *state) { + const struct in6_addr *addr = p; + + assert(p); + + siphash24_compress(addr, sizeof(*addr), state); +} + +static int dhcp6_prefixes_compare_func(const void *_a, const void *_b) { + const struct in6_addr *a = _a, *b = _b; + + return memcmp(a, b, sizeof(*a)); +} + +static const struct hash_ops dhcp6_prefixes_hash_ops = { + .hash = dhcp6_prefixes_hash_func, + .compare = dhcp6_prefixes_compare_func, +}; + int manager_dhcp6_prefix_add(Manager *m, struct in6_addr *addr, Link *link) { - int r; - Route *route; _cleanup_free_ char *buf = NULL; + Route *route; + int r; assert_return(m, -EINVAL); - assert_return(m->dhcp6_prefixes, -ENODATA); assert_return(addr, -EINVAL); r = route_add(link, AF_INET6, (union in_addr_union *) addr, 64, @@ -1253,6 +1270,10 @@ int manager_dhcp6_prefix_add(Manager *m, struct in6_addr *addr, Link *link) { (void) in_addr_to_string(AF_INET6, (union in_addr_union *) addr, &buf); log_link_debug(link, "Adding prefix route %s/64", strnull(buf)); + r = hashmap_ensure_allocated(&m->dhcp6_prefixes, &dhcp6_prefixes_hash_ops); + if (r < 0) + return r; + return hashmap_put(m->dhcp6_prefixes, addr, link); } @@ -1270,13 +1291,12 @@ static int dhcp6_route_remove_handler(sd_netlink *nl, sd_netlink_message *m, voi } static int manager_dhcp6_prefix_remove(Manager *m, struct in6_addr *addr) { + _cleanup_free_ char *buf = NULL; + Route *route; Link *l; int r; - Route *route; - _cleanup_free_ char *buf = NULL; assert_return(m, -EINVAL); - assert_return(m->dhcp6_prefixes, -ENODATA); assert_return(addr, -EINVAL); l = hashmap_remove(m->dhcp6_prefixes, addr); @@ -1300,9 +1320,9 @@ static int manager_dhcp6_prefix_remove(Manager *m, struct in6_addr *addr) { } int manager_dhcp6_prefix_remove_all(Manager *m, Link *link) { + struct in6_addr *addr; Iterator i; Link *l; - struct in6_addr *addr; assert_return(m, -EINVAL); assert_return(link, -EINVAL); @@ -1317,25 +1337,6 @@ int manager_dhcp6_prefix_remove_all(Manager *m, Link *link) { return 0; } -static void dhcp6_prefixes_hash_func(const void *p, struct siphash *state) { - const struct in6_addr *addr = p; - - assert(p); - - siphash24_compress(addr, sizeof(*addr), state); -} - -static int dhcp6_prefixes_compare_func(const void *_a, const void *_b) { - const struct in6_addr *a = _a, *b = _b; - - return memcmp(a, b, sizeof(*a)); -} - -static const struct hash_ops dhcp6_prefixes_hash_ops = { - .hash = dhcp6_prefixes_hash_func, - .compare = dhcp6_prefixes_compare_func, -}; - int manager_new(Manager **ret) { _cleanup_(manager_freep) Manager *m = NULL; int r; @@ -1372,10 +1373,6 @@ int manager_new(Manager **ret) { if (r < 0) return r; - m->netdevs = hashmap_new(&string_hash_ops); - if (!m->netdevs) - return -ENOMEM; - LIST_HEAD_INIT(m->networks); r = sd_resolve_default(&m->resolve); @@ -1390,10 +1387,6 @@ int manager_new(Manager **ret) { if (r < 0) return r; - m->dhcp6_prefixes = hashmap_new(&dhcp6_prefixes_hash_ops); - if (!m->dhcp6_prefixes) - return -ENOMEM; - m->duid.type = DUID_TYPE_EN; (void) routing_policy_load_rules(m->state_file, &m->rules_saved); diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 85d0c1f54e..989c92322b 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -193,34 +193,6 @@ int network_load_one(Manager *manager, const char *filename) { .ipv6_accept_ra_route_table = RT_TABLE_MAIN, }; - network->stacked_netdevs = hashmap_new(&string_hash_ops); - if (!network->stacked_netdevs) - return log_oom(); - - network->addresses_by_section = hashmap_new(&network_config_hash_ops); - if (!network->addresses_by_section) - return log_oom(); - - network->routes_by_section = hashmap_new(&network_config_hash_ops); - if (!network->routes_by_section) - return log_oom(); - - network->fdb_entries_by_section = hashmap_new(&network_config_hash_ops); - if (!network->fdb_entries_by_section) - return log_oom(); - - network->address_labels_by_section = hashmap_new(&network_config_hash_ops); - if (!network->address_labels_by_section) - log_oom(); - - network->prefixes_by_section = hashmap_new(&network_config_hash_ops); - if (!network->prefixes_by_section) - return log_oom(); - - network->rules_by_section = hashmap_new(&network_config_hash_ops); - if (!network->rules_by_section) - return log_oom(); - network->filename = strdup(filename); if (!network->filename) return log_oom(); @@ -615,6 +587,10 @@ int config_parse_netdev(const char *unit, case NETDEV_KIND_IPVLAN: case NETDEV_KIND_VXLAN: case NETDEV_KIND_VCAN: + r = hashmap_ensure_allocated(&network->stacked_netdevs, &string_hash_ops); + if (r < 0) + return log_oom(); + r = hashmap_put(network->stacked_netdevs, netdev->ifname, netdev); if (r < 0) { log_syntax(unit, LOG_ERR, filename, line, r, "Cannot add NetDev '%s' to network: %m", rvalue); @@ -753,6 +729,10 @@ int config_parse_tunnel(const char *unit, return 0; } + r = hashmap_ensure_allocated(&network->stacked_netdevs, &string_hash_ops); + if (r < 0) + return log_oom(); + r = hashmap_put(network->stacked_netdevs, netdev->ifname, netdev); if (r < 0) { log_syntax(unit, LOG_ERR, filename, line, r, "Cannot add VLAN '%s' to network, ignoring: %m", rvalue); diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index 919a2c4b3c..5c1fccbc41 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -89,8 +89,8 @@ typedef struct NetworkConfigSection { int network_config_section_new(const char *filename, unsigned line, NetworkConfigSection **s); void network_config_section_free(NetworkConfigSection *network); - DEFINE_TRIVIAL_CLEANUP_FUNC(NetworkConfigSection*, network_config_section_free); +extern const struct hash_ops network_config_hash_ops; typedef struct Manager Manager; diff --git a/src/network/networkd-radv.c b/src/network/networkd-radv.c index d893c1e5d5..346d64953b 100644 --- a/src/network/networkd-radv.c +++ b/src/network/networkd-radv.c @@ -160,8 +160,11 @@ int prefix_new_static(Network *network, const char *filename, if (filename) { prefix->section = TAKE_PTR(n); - r = hashmap_put(network->prefixes_by_section, prefix->section, - prefix); + r = hashmap_ensure_allocated(&network->prefixes_by_section, &network_config_hash_ops); + if (r < 0) + return r; + + r = hashmap_put(network->prefixes_by_section, prefix->section, prefix); if (r < 0) return r; } diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index 1e16e4a392..f13e126543 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -102,6 +102,10 @@ int route_new_static(Network *network, const char *filename, unsigned section_li if (filename) { route->section = TAKE_PTR(n); + r = hashmap_ensure_allocated(&network->routes_by_section, &network_config_hash_ops); + if (r < 0) + return r; + r = hashmap_put(network->routes_by_section, route->section, route); if (r < 0) return r; diff --git a/src/network/networkd-routing-policy-rule.c b/src/network/networkd-routing-policy-rule.c index 4750073d28..683c166289 100644 --- a/src/network/networkd-routing-policy-rule.c +++ b/src/network/networkd-routing-policy-rule.c @@ -412,6 +412,10 @@ static int routing_policy_rule_new_static(Network *network, const char *filename if (filename) { rule->section = TAKE_PTR(n); + r = hashmap_ensure_allocated(&network->rules_by_section, &network_config_hash_ops); + if (r < 0) + return r; + r = hashmap_put(network->rules_by_section, rule->section, rule); if (r < 0) return r; diff --git a/src/network/test-networkd-conf.c b/src/network/test-networkd-conf.c index abef6e761a..86d4e7e733 100644 --- a/src/network/test-networkd-conf.c +++ b/src/network/test-networkd-conf.c @@ -172,7 +172,6 @@ static void test_config_parse_address_one(const char *rvalue, int family, unsign _cleanup_(network_freep) Network *network = NULL; assert_se(network = new0(Network, 1)); - assert_se(network->addresses_by_section = hashmap_new(NULL)); assert_se(config_parse_address("network", "filename", 1, "section", 1, "Address", 0, rvalue, network, network) == 0); assert_se(network->n_static_addresses == n_addresses); if (n_addresses > 0) {