}
}
-static char *get_next_delimiter_in_nid(char *str, char sep)
-{
- char *at, *comma;
-
- /* first find the '@' */
- at = strchr(str, '@');
- if (!at)
- return str;
-
- /* now that you found the at find the sep after */
- comma = strchr(at, sep);
- return comma;
-}
-
int tokenize_nidstr(char *nidstr, char *out[LNET_MAX_STR_LEN], char *err_str)
{
int bracket = 0, num_str = 0;
return num_nids;
}
-int lustre_lnet_parse_nids(char *nids, char **array, int size,
- char ***out_array)
-{
- int num_nids = 0;
- char *comma = nids, *cur, *entry;
- char **new_array;
- int i, len, start = 0, finish = 0;
-
- if (nids == NULL || strlen(nids) == 0)
- return size;
-
- /* count the number or new nids, by counting the number of comma*/
- while (comma) {
- comma = get_next_delimiter_in_nid(comma, ',');
- if (comma) {
- comma++;
- num_nids++;
- } else {
- num_nids++;
- }
- }
-
- /*
- * if the array is not NULL allocate a large enough array to house
- * the old and new entries
- */
- new_array = calloc(sizeof(char*),
- (size > 0) ? size + num_nids : num_nids);
-
- if (!new_array)
- goto failed;
-
- /* parse our the new nids and add them to the tail of the array */
- comma = nids;
- cur = nids;
- start = (size > 0) ? size: 0;
- finish = (size > 0) ? size + num_nids : num_nids;
- for (i = start; i < finish; i++) {
- comma = get_next_delimiter_in_nid(comma, ',');
- if (!comma)
- /*
- * the length of the string to be parsed out is
- * from cur to end of string. So it's good enough
- * to strlen(cur)
- */
- len = strlen(cur) + 1;
- else
- /* length of the string is comma - cur */
- len = (comma - cur) + 1;
-
- entry = calloc(1, len);
- if (!entry) {
- finish = i > 0 ? i - 1: 0;
- goto failed;
- }
- memcpy(entry, cur, len - 1);
- entry[len] = '\0';
- new_array[i] = entry;
- if (comma) {
- comma++;
- cur = comma;
- }
- }
-
- /* add the old entries in the array and delete the old array*/
- for (i = 0; i < size; i++)
- new_array[i] = array[i];
-
- if (array)
- free(array);
-
- *out_array = new_array;
-
- return finish;
-
-failed:
- for (i = start; i < finish; i++)
- free(new_array[i]);
- if (new_array)
- free(new_array);
-
- return size;
-}
-
/*
* format expected:
* <intf>[<expr>], <intf>[<expr>],..
return rc;
}
-static void lustre_lnet_clean_ip2nets(struct lustre_lnet_ip2nets *ip2nets)
-{
- struct lustre_lnet_ip_range_descr *ipr, *tmp;
- struct cfs_expr_list *el, *el_tmp;
-
- list_for_each_entry_safe(ipr, tmp,
- &ip2nets->ip2nets_ip_ranges,
- ipr_entry) {
- list_del(&ipr->ipr_entry);
- list_for_each_entry_safe(el, el_tmp, &ipr->ipr_expr,
- el_link) {
- list_del(&el->el_link);
- cfs_expr_list_free(el);
- }
- free(ipr);
- }
-}
-
-/*
- * returns an rc < 0 if there is an error
- * otherwise it returns the number IPs generated
- * it also has out params: net - network name
- */
-static int lnet_expr2ips(char *nidstr, __u32 *ip_list,
- struct lustre_lnet_ip2nets *ip2nets,
- __u32 *net, char *err_str)
-{
- struct lustre_lnet_ip_range_descr *ipr;
- char *comp1, *comp2;
- int ip_idx = MAX_NUM_IPS - 1;
- int ip_range_len, rc = LUSTRE_CFG_RC_NO_ERR;
- __u32 net_type;
- char ip_range[LNET_MAX_STR_LEN];
-
- /* separate the two components of the NID */
- comp1 = nidstr;
- comp2 = strchr(nidstr, '@');
- if (comp2 == NULL) {
- snprintf(err_str,
- LNET_MAX_STR_LEN,
- "\"cannot parse NID %s\"", nidstr);
- err_str[LNET_MAX_STR_LEN - 1] = '\0';
- rc = LUSTRE_CFG_RC_BAD_PARAM;
- goto out;
- }
-
- /* length of the expected ip-range */
- ip_range_len = comp2 - comp1;
- if (ip_range_len >= LNET_MAX_STR_LEN) {
- snprintf(err_str,
- LNET_MAX_STR_LEN,
- "\"too long ip_range '%s'\"", nidstr);
- err_str[LNET_MAX_STR_LEN - 1] = '\0';
- rc = LUSTRE_CFG_RC_BAD_PARAM;
- goto out;
- }
-
- /* move beyond '@' */
- comp2++;
-
- /*
- * if the net component is either o2ib or tcp then we expect
- * an IP range which could only be a single IP address.
- * Parse that.
- */
- *net = libcfs_str2net(comp2);
- net_type = LNET_NETTYP(*net);
- /* expression support is for o2iblnd and socklnd only */
- if (net_type != O2IBLND && net_type != SOCKLND)
- return LUSTRE_CFG_RC_SKIP;
-
- strncpy(ip_range, comp1, ip_range_len);
- ip_range[ip_range_len] = '\0';
- ip2nets->ip2nets_net.nw_id = *net;
-
- rc = lustre_lnet_add_ip_range(&ip2nets->ip2nets_ip_ranges, ip_range);
- if (rc != LUSTRE_CFG_RC_NO_ERR) {
- snprintf(err_str,
- LNET_MAX_STR_LEN,
- "\"cannot parse ip_range '%.100s'\"", ip_range);
- err_str[LNET_MAX_STR_LEN - 1] = '\0';
- rc = LUSTRE_CFG_RC_BAD_PARAM;
- goto out;
- }
-
- /*
- * Generate all the IP Addresses from the parsed range. For sanity
- * we allow only a max of MAX_NUM_IPS nids to be configured for
- * a single peer.
- */
- list_for_each_entry(ipr, &ip2nets->ip2nets_ip_ranges, ipr_entry)
- ip_idx = cfs_ip_addr_range_gen(ip_list, MAX_NUM_IPS,
- &ipr->ipr_expr);
-
- if (ip_idx == MAX_NUM_IPS - 1) {
- snprintf(err_str, LNET_MAX_STR_LEN,
- "no NIDs provided for configuration");
- err_str[LNET_MAX_STR_LEN - 1] = '\0';
- rc = LUSTRE_CFG_RC_NO_MATCH;
- goto out;
- } else if (ip_idx == -1) {
- rc = LUSTRE_CFG_RC_LAST_ELEM;
- } else {
- rc = ip_idx;
- }
-
-out:
- return rc;
-}
-
static int lustre_lnet_handle_peer_nidlist(lnet_nid_t *nidlist, int num_nids,
bool is_mr, __u32 cmd,
char *cmd_type, char *err_str)
return rc;
}
-static int lustre_lnet_handle_peer_ip2nets(char **nid, int num_nids, bool mr,
- bool range, __u32 cmd,
- char *cmd_type, char *err_str)
-{
- __u32 net = LNET_NIDNET(LNET_NID_ANY);
- int ip_idx;
- int i, j, rc = LUSTRE_CFG_RC_NO_ERR;
- __u32 ip_list[MAX_NUM_IPS];
- struct lustre_lnet_ip2nets ip2nets;
- struct lnet_ioctl_peer_cfg data;
- lnet_nid_t peer_nid;
- lnet_nid_t prim_nid = LNET_NID_ANY;
-
- /* initialize all lists */
- INIT_LIST_HEAD(&ip2nets.ip2nets_ip_ranges);
- INIT_LIST_HEAD(&ip2nets.ip2nets_net.network_on_rule);
- INIT_LIST_HEAD(&ip2nets.ip2nets_net.nw_intflist);
-
- /* each nid entry is an expression */
- for (i = 0; i < num_nids; i++) {
- if (!range && i == 0)
- prim_nid = libcfs_str2nid(nid[0]);
- else if (range)
- prim_nid = LNET_NID_ANY;
-
- rc = lnet_expr2ips(nid[i], ip_list, &ip2nets, &net, err_str);
- if (rc == LUSTRE_CFG_RC_SKIP)
- continue;
- else if (rc == LUSTRE_CFG_RC_LAST_ELEM)
- rc = -1;
- else if (rc < LUSTRE_CFG_RC_NO_ERR)
- goto out;
-
- ip_idx = rc;
-
- for (j = MAX_NUM_IPS - 1; j > ip_idx; j--) {
- peer_nid = LNET_MKNID(net, ip_list[j]);
- if (peer_nid == LNET_NID_ANY) {
- snprintf(err_str,
- LNET_MAX_STR_LEN,
- "\"cannot parse NID\"");
- err_str[LNET_MAX_STR_LEN - 1] = '\0';
- rc = LUSTRE_CFG_RC_BAD_PARAM;
- goto out;
- }
-
- LIBCFS_IOC_INIT_V2(data, prcfg_hdr);
- data.prcfg_mr = mr;
-
- if (prim_nid == LNET_NID_ANY && j == MAX_NUM_IPS - 1) {
- prim_nid = peer_nid;
- peer_nid = LNET_NID_ANY;
- }
-
- if (!range && num_nids > 1 && i == 0 &&
- cmd == IOC_LIBCFS_DEL_PEER_NI)
- continue;
- else if (!range && i == 0)
- peer_nid = LNET_NID_ANY;
-
- LIBCFS_IOC_INIT_V2(data, prcfg_hdr);
- data.prcfg_mr = mr;
- data.prcfg_prim_nid = prim_nid;
- data.prcfg_cfg_nid = peer_nid;
-
- /*
- * If prim_nid is not provided then the first nid in the
- * list becomes the prim_nid. First time round the loop
- * use LNET_NID_ANY for the first parameter, then use
- * nid[0] as the key nid after wards
- */
- rc = dispatch_peer_ni_cmd(cmd, &data, err_str,
- cmd_type);
- if (rc != 0)
- goto out;
-
- /*
- * we just deleted the entire peer using the
- * primary_nid. So don't bother iterating through
- * the rest of the nids
- */
- if (prim_nid != LNET_NID_ANY &&
- peer_nid == LNET_NID_ANY &&
- cmd == IOC_LIBCFS_DEL_PEER_NI)
- goto next_nid;
- }
-next_nid:
- lustre_lnet_clean_ip2nets(&ip2nets);
- }
-
-out:
- lustre_lnet_clean_ip2nets(&ip2nets);
- return rc;
-}
-
int lustre_lnet_config_peer_nidlist(char *pnidstr, lnet_nid_t *lnet_nidlist,
int num_nids, bool is_mr, int seq_no,
struct cYAML **err_rc)
return rc;
}
-int lustre_lnet_config_peer_nid(char *pnid, char **nid, int num_nids,
- bool mr, bool ip2nets, int seq_no,
- struct cYAML **err_rc)
-{
- int rc = LUSTRE_CFG_RC_NO_ERR;
- char err_str[LNET_MAX_STR_LEN] = {0};
- char **nid_array = NULL;
-
- snprintf(err_str, sizeof(err_str), "\"Success\"");
-
- if (ip2nets) {
- rc = lustre_lnet_handle_peer_ip2nets(nid, num_nids, mr,
- ip2nets, IOC_LIBCFS_ADD_PEER_NI,
- ADD_CMD, err_str);
- goto out;
- }
-
- if (pnid) {
- if (libcfs_str2nid(pnid) == LNET_NID_ANY) {
- snprintf(err_str, sizeof(err_str),
- "bad primary NID: '%s'",
- pnid);
- rc = LUSTRE_CFG_RC_MISSING_PARAM;
- goto out;
- }
-
- num_nids++;
-
- nid_array = calloc(sizeof(*nid_array), num_nids);
- if (!nid_array) {
- snprintf(err_str, sizeof(err_str),
- "out of memory");
- rc = LUSTRE_CFG_RC_OUT_OF_MEM;
- goto out;
- }
- nid_array[0] = pnid;
- memcpy(&nid_array[1], nid, sizeof(*nid) * (num_nids - 1));
- }
-
- rc = lustre_lnet_handle_peer_ip2nets((pnid) ? nid_array : nid,
- num_nids, mr, ip2nets,
- IOC_LIBCFS_ADD_PEER_NI, ADD_CMD,
- err_str);
- if (rc)
- goto out;
-
-out:
- if (nid_array)
- free(nid_array);
-
- cYAML_build_error(rc, seq_no, ADD_CMD, "peer_ni", err_str, err_rc);
- return rc;
-}
-
int lustre_lnet_del_peer_nidlist(char *pnidstr, lnet_nid_t *lnet_nidlist,
int num_nids, int seq_no,
struct cYAML **err_rc)
return rc;
}
-int lustre_lnet_del_peer_nid(char *pnid, char **nid, int num_nids,
- bool ip2nets, int seq_no, struct cYAML **err_rc)
-{
- int rc = LUSTRE_CFG_RC_NO_ERR;
- char err_str[LNET_MAX_STR_LEN] = {0};
- char **nid_array = NULL;
-
- snprintf(err_str, sizeof(err_str), "\"Success\"");
-
- if (ip2nets) {
- rc = lustre_lnet_handle_peer_ip2nets(nid, num_nids, false,
- ip2nets, IOC_LIBCFS_DEL_PEER_NI,
- DEL_CMD, err_str);
- goto out;
- }
-
- if (pnid == NULL) {
- snprintf(err_str, sizeof(err_str),
- "\"Primary nid is not provided\"");
- rc = LUSTRE_CFG_RC_MISSING_PARAM;
- goto out;
- } else if (!ip2nets) {
- if (libcfs_str2nid(pnid) == LNET_NID_ANY) {
- rc = LUSTRE_CFG_RC_BAD_PARAM;
- snprintf(err_str, sizeof(err_str),
- "bad key NID: '%s'",
- pnid);
- goto out;
- }
- }
-
- num_nids++;
- nid_array = calloc(sizeof(*nid_array), num_nids);
- if (!nid_array) {
- snprintf(err_str, sizeof(err_str),
- "out of memory");
- rc = LUSTRE_CFG_RC_OUT_OF_MEM;
- goto out;
- }
- nid_array[0] = pnid;
- memcpy(&nid_array[1], nid, sizeof(*nid) * (num_nids - 1));
-
- rc = lustre_lnet_handle_peer_ip2nets(nid_array, num_nids, false,
- ip2nets, IOC_LIBCFS_DEL_PEER_NI,
- DEL_CMD, err_str);
- if (rc)
- goto out;
-
-out:
- if (nid_array)
- free(nid_array);
-
- cYAML_build_error(rc, seq_no, DEL_CMD, "peer_ni", err_str, err_rc);
- return rc;
-}
-
int lustre_lnet_route_common(char *nw, char *nidstr, int hops, int prio,
int sen, int seq_no, struct cYAML **err_rc,
int cmd)
struct cYAML **err_rc);
/*
- * lustre_lnet_config_peer_nid
- * Add a peer nid to a peer with primary nid pnid. If no pnid is given
- * then the first nid in the nid list becomes the primary nid for
- * a newly created peer.
- * Otherwise if pnid is provided and it's unique then a new peer is
- * created with pnid as the primary NID and the nids in the nid list as
- * secondary nids.
- * If any of the peers nids provided in with exception to the pnid is
- * not unique the operation fails. Some peer nids might have already
- * been added. It's the role of the caller of this API to remove the
- * added NIDs if they wish.
- *
- * pnid - Primary NID of the peer
- * nid - list of nids to add
- * num_nids - number of nids in the nid array
- * mr - true if this peer is MR capable.
- * ip2nets - true if a list of nid expressions are given to configure
- * multiple peers
- * seq_no - sequence number of the command
- * err_rc - YAML strucutre of the resultant return code.
- */
-int lustre_lnet_config_peer_nid(char *pnid, char **nid, int num_nids,
- bool mr, bool ip2nets, int seq_no,
- struct cYAML **err_rc);
-
-/*
* lustre_lnet_config_peer_nidlist
* Add a peer NID to a peer with primary NID pnid. If a pnid is not provided
* then the first NID in the NID list becomes the primary NID for a newly
struct cYAML **err_rc);
/*
- * lustre_lnet_del_peer_nid
- * Delete the nids given in the nid list from the peer with primary NID
- * pnid. If pnid is NULL or it doesn't identify a peer the operation
- * fails and no change happens to the system.
- * The operation is aborted on the first NID that fails to be deleted.
- *
- * pnid - Primary NID of the peer
- * nid - list of nids to add
- * num_nids - number of nids in the nid array
- * ip2nets - used to specify a range of nids
- * seq_no - sequence number of the command
- * err_rc - YAML strucutre of the resultant return code.
- */
-int lustre_lnet_del_peer_nid(char *pnid, char **nid, int num_nids,
- bool ip2nets, int seq_no, struct cYAML **err_rc);
-
-/*
* lustre_lnet_del_peer_nidlist
* Delete the NIDs given in the NID list from the peer with the primary NID
* pnid. If pnid is NULL, or it doesn't identify a peer, the operation fails,
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
- * freeing the array. If an initial array is provided then copy over
- * the contents of that array into the new array and append to it the
- * new content.
- * The nids can be of the form "nid [,nid, nid, nid]"
- * nids: nids string to be parsed
- * array: initial array of content
- * size: num of elements in the array
- * out_array: [OUT] new allocated array.
- * Returns size of array
- * sets the out_array to NULL on failure.
- */
-int lustre_lnet_parse_nids(char *nids, char **array, int size,
- char ***out_array);
-
#endif /* LIB_LNET_CONFIG_API_H */