From a1478a0e517293f63fdaaa62133a39ec2e6b84d4 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 31 May 2022 14:06:07 +0200 Subject: [PATCH] services: switch to vlist preparatation for supporting service types Signed-off-by: Felix Fietkau --- network.c | 2 ++ network.h | 2 +- service.c | 42 +++++++++++++++++++++++++++++------------- service.h | 13 ++++++++++++- ubus.c | 2 +- 5 files changed, 45 insertions(+), 16 deletions(-) diff --git a/network.c b/network.c index a6259ed..9e9485c 100644 --- a/network.c +++ b/network.c @@ -296,6 +296,7 @@ static int network_reload(struct network *net) network_pex_close(net); network_services_free(net); network_hosts_update_start(net); + network_services_update_start(net); switch (net->config.type) { case NETWORK_TYPE_FILE: @@ -306,6 +307,7 @@ static int network_reload(struct network *net) break; } + network_services_update_done(net); network_hosts_update_done(net); uloop_timeout_set(&net->connect_timer, 10); diff --git a/network.h b/network.h index 7e023fb..da0a281 100644 --- a/network.h +++ b/network.h @@ -50,7 +50,7 @@ struct network { struct vlist_tree peers; struct avl_tree groups; - struct avl_tree services; + struct vlist_tree services; struct uloop_timeout connect_timer; diff --git a/service.c b/service.c index 908fe3b..f7daacd 100644 --- a/service.c +++ b/service.c @@ -7,26 +7,20 @@ enum { SERVICE_ATTR_TYPE, + SERVICE_ATTR_CONFIG, SERVICE_ATTR_MEMBERS, __SERVICE_ATTR_MAX }; static const struct blobmsg_policy service_policy[__SERVICE_ATTR_MAX] = { [SERVICE_ATTR_TYPE] = { "type", BLOBMSG_TYPE_STRING }, + [SERVICE_ATTR_CONFIG] = { "config", BLOBMSG_TYPE_TABLE }, [SERVICE_ATTR_MEMBERS] = { "members", BLOBMSG_TYPE_ARRAY }, }; -void network_services_init(struct network *net) -{ - avl_init(&net->services, avl_strcmp, false, NULL); -} - void network_services_free(struct network *net) { - struct network_service *s, *tmp; - - avl_remove_all_elements(&net->services, s, node, tmp) - free(s); + vlist_flush_all(&net->services); } static int @@ -81,10 +75,11 @@ service_add(struct network *net, struct blob_attr *data) { struct network_service *s; struct blob_attr *tb[__SERVICE_ATTR_MAX]; - struct blob_attr *cur; + struct blob_attr *cur, *config; const char *name = blobmsg_name(data); const char *type = NULL; char *name_buf, *type_buf; + void *config_buf; int n_members; blobmsg_parse(service_policy, __SERVICE_ATTR_MAX, tb, @@ -96,17 +91,22 @@ service_add(struct network *net, struct blob_attr *data) if (blobmsg_check_array(tb[SERVICE_ATTR_MEMBERS], BLOBMSG_TYPE_STRING) < 0) return; + config = tb[SERVICE_ATTR_CONFIG]; + n_members = service_parse_members(net, NULL, tb[SERVICE_ATTR_MEMBERS]); s = calloc_a(sizeof(*s) + n_members * sizeof(s->members[0]), &name_buf, strlen(name) + 1, - &type_buf, type ? strlen(type) + 1 : 0); + &type_buf, type ? strlen(type) + 1 : 0, + &config_buf, config ? blob_pad_len(config) : 0); - s->node.key = strcpy(name_buf, name); + strcpy(name_buf, name); if (type) s->type = strcpy(type_buf, type); + if (config) + s->config = memcpy(config_buf, config, blob_pad_len(config)); service_parse_members(net, s, tb[SERVICE_ATTR_MEMBERS]); - avl_insert(&net->services, &s->node); + vlist_add(&net->services, &s->node, name_buf); } void network_services_add(struct network *net, struct blob_attr *data) @@ -117,3 +117,19 @@ void network_services_add(struct network *net, struct blob_attr *data) blobmsg_for_each_attr(cur, data, rem) service_add(net, cur); } + +static void +service_update(struct vlist_tree *tree, struct vlist_node *node_new, + struct vlist_node *node_old) +{ + struct network_service *s_old; + + s_old = container_of_safe(node_old, struct network_service, node); + if (s_old) + free(s_old); +} + +void network_services_init(struct network *net) +{ + vlist_init(&net->services, avl_strcmp, service_update); +} diff --git a/service.h b/service.h index ff652b7..b85fbe6 100644 --- a/service.h +++ b/service.h @@ -6,8 +6,9 @@ #define __UNETD_SERVICE_H struct network_service { - struct avl_node node; + struct vlist_node node; + struct blob_attr *config; const char *type; int n_members; @@ -18,4 +19,14 @@ void network_services_init(struct network *net); void network_services_free(struct network *net); void network_services_add(struct network *net, struct blob_attr *data); +static inline void network_services_update_start(struct network *net) +{ + vlist_update(&net->services); +} + +static inline void network_services_update_done(struct network *net) +{ + vlist_flush(&net->services); +} + #endif diff --git a/ubus.c b/ubus.c index 76c1980..a17b2f7 100644 --- a/ubus.c +++ b/ubus.c @@ -67,7 +67,7 @@ ubus_service_get_network_members(struct blob_buf *b, struct network *n, struct network_service *s; int i; - s = avl_find_element(&n->services, name, s, node); + s = vlist_find(&n->services, name, s, node); if (!s) return; -- 2.30.2