From dff466c2bacd2db0d28087bba8c6250cdd5eeb8e Mon Sep 17 00:00:00 2001 From: James Simmons Date: Wed, 19 Jul 2023 12:07:26 -0400 Subject: [PATCH] LU-9680 utils: add updating the key table for Netlink. Currently lnetconfig implementation only sends the key table once to construct a YAML document. Add the ability to update the key table at a latter time. New keys will be used by the YAML document. Test-Parameters: trivial Change-Id: Ie2201f91eb24d06c7e2a2d4abe3da3805f74e5a7 Signed-off-by: James Simmons Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/51715 Tested-by: Oleg Drokin Reviewed-by: Oleg Drokin --- lnet/utils/lnetconfig/liblnetconfig_netlink.c | 55 ++++++++++++++++----------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/lnet/utils/lnetconfig/liblnetconfig_netlink.c b/lnet/utils/lnetconfig/liblnetconfig_netlink.c index 06830c6..7e056ca 100644 --- a/lnet/utils/lnetconfig/liblnetconfig_netlink.c +++ b/lnet/utils/lnetconfig/liblnetconfig_netlink.c @@ -858,6 +858,29 @@ unwind: } } +static bool cleanup_children(struct yaml_nl_node *parent) +{ + struct yaml_nl_node *child; + + if (nl_list_empty(&parent->children)) { + struct ln_key_props *keys = parent->keys.lkl_list; + int i; + + for (i = 1; i < parent->keys.lkl_maxattr; i++) + if (keys[i].lkp_value) + free(keys[i].lkp_value); + nl_list_del(&parent->list); + return true; + } + + while ((child = get_next_child(parent, 0)) != NULL) { + if (cleanup_children(child)) + free(child); + } + + return false; +} + /* This is the CB_VALID callback for the Netlink library that we * have hooked into. Any successful Netlink message is passed to * this function which handles both the incoming key tables and @@ -878,6 +901,15 @@ static int yaml_netlink_msg_parse(struct nl_msg *msg, void *arg) scalar_attr_policy)) return NL_SKIP; + /* If root already exists this means we are updating the + * key table. Free old key table. + */ + if (data->root && (nlh->nlmsg_flags & NLM_F_REPLACE)) { + cleanup_children(data->root); + free(data->root); + data->root = NULL; + } + if (attrs[LN_SCALAR_ATTR_LIST]) { int rc = yaml_parse_key_list(data, NULL, attrs[LN_SCALAR_ATTR_LIST]); @@ -963,29 +995,6 @@ static int yaml_netlink_msg_error(struct sockaddr_nl *who, return NL_STOP; } -static bool cleanup_children(struct yaml_nl_node *parent) -{ - struct yaml_nl_node *child; - - if (nl_list_empty(&parent->children)) { - struct ln_key_props *keys = parent->keys.lkl_list; - int i; - - for (i = 1; i < parent->keys.lkl_maxattr; i++) - if (keys[i].lkp_value) - free(keys[i].lkp_value); - nl_list_del(&parent->list); - return true; - } - - while ((child = get_next_child(parent, 0)) != NULL) { - if (cleanup_children(child)) - free(child); - } - - return false; -} - /* This is the libnl callback for when the last Netlink packet * is finished being parsed or its called right away in case * the Linux kernel reports back an error from the Netlink layer. -- 1.8.3.1