From 0e030c4fb7bc482785d336be9b97b1183b6abd20 Mon Sep 17 00:00:00 2001 From: Chris Horn Date: Sat, 22 Jun 2019 12:03:09 -0500 Subject: [PATCH] LU-12410 lnet: Implement DLC wrapper for cfs_parse_nidlist Implement a simple wrapper around cfs_parse_nidlist to be used by DLC commands. The wrapper serves to sanitize the nidstr, so that is suitable to be input to cfs_parse_nidlist. We do not want to allow an asterisk character in this string because the resultant nidlist, when expanded, would define too many nids for the various operations that will utilize this functionality. Test-Parameters: trivial Signed-off-by: Chris Horn Change-Id: I59280317af4af05eca1c8c598eadf8871e28bcf1 Reviewed-on: https://review.whamcloud.com/35304 Reviewed-by: Petros Koutoupis Reviewed-by: Shaun Tancheff Tested-by: jenkins Tested-by: Maloo Reviewed-by: Oleg Drokin --- lnet/utils/lnetconfig/liblnetconfig.c | 55 +++++++++++++++++++++++++++++++++++ lnet/utils/lnetconfig/liblnetconfig.h | 31 ++++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/lnet/utils/lnetconfig/liblnetconfig.c b/lnet/utils/lnetconfig/liblnetconfig.c index 5a50b21..2004833 100644 --- a/lnet/utils/lnetconfig/liblnetconfig.c +++ b/lnet/utils/lnetconfig/liblnetconfig.c @@ -262,6 +262,61 @@ static char *get_next_delimiter_in_nid(char *str, char sep) return comma; } +int lustre_lnet_parse_nidstr(char *nidstr, lnet_nid_t *lnet_nidlist, + int max_nids, char *err_str) +{ + int rc, num_nids = 0; + struct list_head nidlist; + + if (!nidstr) { + snprintf(err_str, LNET_MAX_STR_LEN, "supplied nidstr is NULL"); + return LUSTRE_CFG_RC_BAD_PARAM; + } + + if (strchr(nidstr, '*')) { + snprintf(err_str, LNET_MAX_STR_LEN, + "asterisk not allowed in nidstring \"%s\"", nidstr); + return LUSTRE_CFG_RC_BAD_PARAM; + } + + INIT_LIST_HEAD(&nidlist); + rc = cfs_parse_nidlist(nidstr, strlen(nidstr), &nidlist); + if (rc == 0) { + snprintf(err_str, LNET_MAX_STR_LEN, + "Unable to parse nidlist from: %s\n", nidstr); + return LUSTRE_CFG_RC_BAD_PARAM; + } + + if (list_empty(&nidlist)) { + snprintf(err_str, LNET_MAX_STR_LEN, + "\"%s\" does not specify any valid nid lists", nidstr); + return LUSTRE_CFG_RC_BAD_PARAM; + } + + num_nids = cfs_expand_nidlist(&nidlist, lnet_nidlist, max_nids); + + if (num_nids == -1) { + snprintf(err_str, LNET_MAX_STR_LEN, + "\"%s\" specifies more than the %d NIDs allowed by this operation.", + nidstr, max_nids); + return LUSTRE_CFG_RC_BAD_PARAM; + } + + if (num_nids < 0) { + snprintf(err_str, LNET_MAX_STR_LEN, + "Failed to expand nidstr: %s", strerror(num_nids)); + return LUSTRE_CFG_RC_OUT_OF_MEM; + } + + if (num_nids == 0) { + snprintf(err_str, LNET_MAX_STR_LEN, + "\"%s\" did not expand to any nids", nidstr); + return LUSTRE_CFG_RC_BAD_PARAM; + } + + return num_nids; +} + int lustre_lnet_parse_nids(char *nids, char **array, int size, char ***out_array) { diff --git a/lnet/utils/lnetconfig/liblnetconfig.h b/lnet/utils/lnetconfig/liblnetconfig.h index a5cecda..8152259 100644 --- a/lnet/utils/lnetconfig/liblnetconfig.h +++ b/lnet/utils/lnetconfig/liblnetconfig.h @@ -653,6 +653,37 @@ int lustre_lnet_parse_interfaces(char *intf_str, struct lnet_dlc_network_descr *nw_descr); /* + * lustre_lnet_parse_nidstr + * This is a small wrapper around cfs_parse_nidlist. + * nidstr - A string parseable by cfs_parse_nidlist + * lnet_nidlist - An array of lnet_nid_t to hold the nids specified + * by the nidstring. + * max_nids - Size of the lnet_nidlist array, and the maximum number of + * nids that can be expressed by the nidstring. If the + * nidstring expands to a larger number of nids than max_nids + * then an error is returned. + * err_str - char pointer where we store an informative error + * message when an error is encountered + * Returns: + * The number (> 0) of lnet_nid_t stored in the supplied array, or + * LUSTRE_CFG_RC_BAD_PARAM if: + * - nidstr is NULL + * - nidstr contains an asterisk. This character is not allowed + * because it would cause the size of the expanded nidlist to exceed + * the maximum number of nids that is supported by expected callers + * of this function. + * - cfs_parse_nidlist fails to parse the nidstring + * - The nidlist populated by cfs_parse_nidlist is empty + * - The nidstring expands to a larger number of nids than max_nids + * - The nidstring expands to zero nids + * LUSTRE_CFG_RC_OUT_OF_MEM if: + * - cfs_expand_nidlist can return ENOMEM. We return out of mem in + * this case. + */ +int lustre_lnet_parse_nidstr(char *nidstr, lnet_nid_t *lnet_nidlist, + int max_nids, char *err_str); + +/* * lustre_lnet_parse_nids * Parse a set of nids into a locally allocated array and return the * pointer of the array to the caller. The caller is responsible for -- 1.8.3.1