From 9b05e872482e380155f6151e3a966b1ec0d08041 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Sat, 24 Feb 2024 10:15:35 -0500 Subject: [PATCH] LU-10391 lnet: support updating LNet local NI settings The LNet API allows updating specific settings instead of a full new configuration for NIs. We can accomplish this using NLM_F_REPLACE with the LNET_CMD_NETS command. The only change for the user land tools is now you can use large NID addresses. Another change in the user land tools is increasing intf_name field in size from IFNAMSIZ to LNET_MAX_STR_LEN which requires increasing err_str handling. This is because we use struct lnet_dlc_intf_descr both to store network addresses or / and network interfaces. Test-Parameters: trivial testlist=sanity-lnet Change-Id: Id334ed3a73ac6ec7a342d4616e32dcfef46907a7 Signed-off-by: James Simmons Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/53560 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Chris Horn Reviewed-by: Frank Sehr Reviewed-by: Cyril Bordage Reviewed-by: Oleg Drokin --- lnet/klnds/o2iblnd/o2iblnd.c | 9 +- lnet/klnds/socklnd/socklnd.c | 9 +- lnet/lnet/api-ni.c | 211 +++++++++++++++++------- lnet/utils/lnetconfig/liblnetconfig.c | 4 +- lnet/utils/lnetconfig/liblnetconfig.h | 2 +- lnet/utils/lnetctl.c | 293 ++++++++++++++++++++++------------ 6 files changed, 356 insertions(+), 172 deletions(-) diff --git a/lnet/klnds/o2iblnd/o2iblnd.c b/lnet/klnds/o2iblnd/o2iblnd.c index 1145ac1..acdd22d 100644 --- a/lnet/klnds/o2iblnd/o2iblnd.c +++ b/lnet/klnds/o2iblnd/o2iblnd.c @@ -1298,6 +1298,7 @@ static int kiblnd_nl_set(int cmd, struct nlattr *attr, int type, void *data) { struct lnet_lnd_tunables *tunables = data; + int rc = 0; s64 num; if (cmd != LNET_CMD_NETS) @@ -1333,14 +1334,16 @@ kiblnd_nl_set(int cmd, struct nlattr *attr, int type, void *data) break; case LNET_NET_O2IBLND_TUNABLES_ATTR_CONNS_PER_PEER: num = nla_get_s64(attr); - clamp_t(s64, num, 1, 127); - tunables->lnd_tun_u.lnd_o2ib.lnd_conns_per_peer = num; + if (num > -1 || num < 128) + tunables->lnd_tun_u.lnd_o2ib.lnd_conns_per_peer = num; + else + rc = -ERANGE; fallthrough; default: break; } - return 0; + return rc; } static void diff --git a/lnet/klnds/socklnd/socklnd.c b/lnet/klnds/socklnd/socklnd.c index 9d7ad25..1947d36 100644 --- a/lnet/klnds/socklnd/socklnd.c +++ b/lnet/klnds/socklnd/socklnd.c @@ -841,6 +841,7 @@ static int ksocknal_nl_set(int cmd, struct nlattr *attr, int type, void *data) { struct lnet_lnd_tunables *tunables = data; + int rc = 0; s64 num; if (cmd != LNET_CMD_NETS) @@ -853,8 +854,10 @@ ksocknal_nl_set(int cmd, struct nlattr *attr, int type, void *data) case LNET_NET_SOCKLND_TUNABLES_ATTR_CONNS_PER_PEER: /* value values are 1 to 127. Zero mean calculate the value */ num = nla_get_s64(attr); - clamp_t(s64, num, 0, 127); - tunables->lnd_tun_u.lnd_sock.lnd_conns_per_peer = num; + if (num > -1 && num < 128) + tunables->lnd_tun_u.lnd_sock.lnd_conns_per_peer = num; + else + rc = -ERANGE; break; case LNET_NET_SOCKLND_TUNABLES_ATTR_LND_TIMEOUT: num = nla_get_s64(attr); @@ -864,7 +867,7 @@ ksocknal_nl_set(int cmd, struct nlattr *attr, int type, void *data) break; } - return 0; + return rc; } static int diff --git a/lnet/lnet/api-ni.c b/lnet/lnet/api-ni.c index 6816d3f..de2c556 100644 --- a/lnet/lnet/api-ni.c +++ b/lnet/lnet/api-ni.c @@ -3987,29 +3987,30 @@ __u32 lnet_get_dlc_seq_locked(void) } static void -lnet_ni_set_healthv(lnet_nid_t nid, int value, bool all) +lnet_ni_set_healthv(struct lnet_nid *nid, int value) { + bool all = nid_same(nid, &LNET_ANY_NID); struct lnet_net *net; struct lnet_ni *ni; lnet_net_lock(LNET_LOCK_EX); list_for_each_entry(net, &the_lnet.ln_nets, net_list) { list_for_each_entry(ni, &net->net_ni_list, ni_netlist) { - if (all || (nid_is_nid4(&ni->ni_nid) && - lnet_nid_to_nid4(&ni->ni_nid) == nid)) { - atomic_set(&ni->ni_healthv, value); - if (list_empty(&ni->ni_recovery) && - value < LNET_MAX_HEALTH_VALUE) { - CERROR("manually adding local NI %s to recovery\n", - libcfs_nidstr(&ni->ni_nid)); - list_add_tail(&ni->ni_recovery, - &the_lnet.ln_mt_localNIRecovq); - lnet_ni_addref_locked(ni, 0); - } - if (!all) { - lnet_net_unlock(LNET_LOCK_EX); - return; - } + if (!all && !nid_same(&ni->ni_nid, nid)) + continue; + + atomic_set(&ni->ni_healthv, value); + if (list_empty(&ni->ni_recovery) && + value < LNET_MAX_HEALTH_VALUE) { + CERROR("manually adding local NI %s to recovery\n", + libcfs_nidstr(&ni->ni_nid)); + list_add_tail(&ni->ni_recovery, + &the_lnet.ln_mt_localNIRecovq); + lnet_ni_addref_locked(ni, 0); + } + if (!all) { + lnet_net_unlock(LNET_LOCK_EX); + return; } } } @@ -4467,11 +4468,13 @@ LNetCtl(unsigned int cmd, void *arg) "local" : "peer", libcfs_nid2str(cfg->rh_nid), cfg->rh_all); lnet_nid4_to_nid(cfg->rh_nid, &nid); mutex_lock(&the_lnet.ln_api_mutex); - if (cfg->rh_type == LNET_HEALTH_TYPE_LOCAL_NI) - lnet_ni_set_healthv(cfg->rh_nid, value, - cfg->rh_all); - else + if (cfg->rh_type == LNET_HEALTH_TYPE_LOCAL_NI) { + if (cfg->rh_all) + nid = LNET_ANY_NID; + lnet_ni_set_healthv(&nid, value); + } else { lnet_peer_ni_set_healthv(&nid, value, cfg->rh_all); + } mutex_unlock(&the_lnet.ln_api_mutex); return 0; } @@ -5888,9 +5891,10 @@ lnet_genl_parse_local_ni(struct nlattr *entry, struct genl_info *info, int net_id, struct lnet_ioctl_config_ni *conf, bool *ni_list) { - bool create = info->nlhdr->nlmsg_flags & NLM_F_CREATE; struct lnet_ioctl_config_lnd_tunables *tun; + struct lnet_nid nid = LNET_ANY_NID; struct nlattr *settings; + int healthv = -1; int rem3, rc = 0; LIBCFS_ALLOC(tun, sizeof(struct lnet_ioctl_config_lnd_tunables)); @@ -5940,6 +5944,61 @@ lnet_genl_parse_local_ni(struct nlattr *entry, struct genl_info *info, } } *ni_list = true; + } else if (nla_strcmp(settings, "nid") == 0 && + net_id != LNET_NET_ANY && + info->nlhdr->nlmsg_flags & NLM_F_REPLACE) { + char nidstr[LNET_NIDSTR_SIZE]; + + settings = nla_next(settings, &rem3); + if (nla_type(settings) != LN_SCALAR_ATTR_VALUE) { + GENL_SET_ERR_MSG(info, "cannot parse NID"); + GOTO(out, rc = -EINVAL); + } + + rc = nla_strscpy(nidstr, settings, sizeof(nidstr)); + if (rc < 0) { + GENL_SET_ERR_MSG(info, + "failed to parse NID"); + GOTO(out, rc); + } + + CDEBUG(D_NET, "Requested NID %s\n", nidstr); + rc = libcfs_strnid(&nid, strim(nidstr)); + if (rc < 0) { + GENL_SET_ERR_MSG(info, "unsupported NID"); + GOTO(out, rc); + } + } else if (nla_strcmp(settings, "health stats") == 0 && + info->nlhdr->nlmsg_flags & NLM_F_REPLACE) { + struct nlattr *health; + int rem4; + + settings = nla_next(settings, &rem3); + if (nla_type(settings) != LN_SCALAR_ATTR_LIST) { + GENL_SET_ERR_MSG(info, + "cannot parse health stats"); + GOTO(out, rc = -EINVAL); + } + + nla_for_each_nested(health, settings, rem4) { + if (nla_type(health) != LN_SCALAR_ATTR_VALUE || + nla_strcmp(health, "health value") != 0) { + GENL_SET_ERR_MSG(info, + "wrong health config format"); + GOTO(out, rc = -EINVAL); + } + + health = nla_next(health, &rem4); + if (nla_type(health) != + LN_SCALAR_ATTR_INT_VALUE) { + GENL_SET_ERR_MSG(info, + "invalid health config format"); + GOTO(out, rc = -EINVAL); + } + + healthv = nla_get_s64(health); + clamp_t(s64, healthv, 0, LNET_MAX_HEALTH_VALUE); + } } else if (nla_strcmp(settings, "tunables") == 0) { settings = nla_next(settings, &rem3); if (nla_type(settings) != @@ -5958,13 +6017,6 @@ lnet_genl_parse_local_ni(struct nlattr *entry, struct genl_info *info, } else if ((nla_strcmp(settings, "lnd tunables") == 0)) { const struct lnet_lnd *lnd; - lnd = lnet_load_lnd(LNET_NETTYP(net_id)); - if (IS_ERR(lnd)) { - GENL_SET_ERR_MSG(info, - "LND type not supported"); - GOTO(out, rc = PTR_ERR(lnd)); - } - settings = nla_next(settings, &rem3); if (nla_type(settings) != LN_SCALAR_ATTR_LIST) { @@ -5973,12 +6025,49 @@ lnet_genl_parse_local_ni(struct nlattr *entry, struct genl_info *info, GOTO(out, rc = -EINVAL); } - rc = lnet_genl_parse_lnd_tunables(settings, - &tun->lt_tun, lnd); - if (rc < 0) { - GENL_SET_ERR_MSG(info, - "failed to parse lnd tunables"); - GOTO(out, rc); + if (info->nlhdr->nlmsg_flags & NLM_F_REPLACE && + net_id == LNET_NET_ANY) { + struct lnet_net *net; + + lnet_net_lock(LNET_LOCK_EX); + list_for_each_entry(net, &the_lnet.ln_nets, net_list) { + struct lnet_ni *ni; + + if (!net->net_lnd) + continue; + + list_for_each_entry(ni, &net->net_ni_list, ni_netlist) { + if (!nid_same(&nid, &LNET_ANY_NID) && + !nid_same(&nid, &ni->ni_nid)) + continue; + + rc = lnet_genl_parse_lnd_tunables(settings, + &ni->ni_lnd_tunables, + net->net_lnd); + if (rc < 0) { + GENL_SET_ERR_MSG(info, + "failed to parse lnd tunables"); + lnet_net_unlock(LNET_LOCK_EX); + GOTO(out, rc); + } + } + } + lnet_net_unlock(LNET_LOCK_EX); + } else { + lnd = lnet_load_lnd(LNET_NETTYP(net_id)); + if (IS_ERR(lnd)) { + GENL_SET_ERR_MSG(info, + "LND type not supported"); + GOTO(out, rc = PTR_ERR(lnd)); + } + + rc = lnet_genl_parse_lnd_tunables(settings, + &tun->lt_tun, lnd); + if (rc < 0) { + GENL_SET_ERR_MSG(info, + "failed to parse lnd tunables"); + GOTO(out, rc); + } } } else if (nla_strcmp(settings, "CPT") == 0) { struct nlattr *cpt; @@ -6014,10 +6103,36 @@ lnet_genl_parse_local_ni(struct nlattr *entry, struct genl_info *info, } } - if (!create) { + if (info->nlhdr->nlmsg_flags & NLM_F_CREATE) { + if (!strlen(conf->lic_ni_intf)) { + GENL_SET_ERR_MSG(info, + "interface is missing"); + GOTO(out, rc); + } + + rc = lnet_dyn_add_ni(conf, net_id, tun); + switch (rc) { + case -ENOENT: + GENL_SET_ERR_MSG(info, + "cannot parse net"); + break; + case -ERANGE: + GENL_SET_ERR_MSG(info, + "invalid CPT set"); + break; + default: + GENL_SET_ERR_MSG(info, + "cannot add LNet NI"); + case 0: + break; + } + } else if (info->nlhdr->nlmsg_flags & NLM_F_REPLACE && healthv != -1) { + lnet_ni_set_healthv(&nid, healthv); + } else if (!(info->nlhdr->nlmsg_flags & (NLM_F_CREATE | NLM_F_REPLACE))) { struct lnet_net *net; struct lnet_ni *ni; + /* delete case */ rc = -ENODEV; if (!strlen(conf->lic_ni_intf)) { GENL_SET_ERR_MSG(info, @@ -6056,29 +6171,6 @@ lnet_genl_parse_local_ni(struct nlattr *entry, struct genl_info *info, "interface invalid for deleting LNet NI"); lnet_net_unlock(LNET_LOCK_EX); } - } else { - if (!strlen(conf->lic_ni_intf)) { - GENL_SET_ERR_MSG(info, - "interface is missing"); - GOTO(out, rc); - } - - rc = lnet_dyn_add_ni(conf, net_id, tun); - switch (rc) { - case -ENOENT: - GENL_SET_ERR_MSG(info, - "cannot parse net"); - break; - case -ERANGE: - GENL_SET_ERR_MSG(info, - "invalid CPT set"); - break; - default: - GENL_SET_ERR_MSG(info, - "cannot add LNet NI"); - case 0: - break; - } } out: if (tun) @@ -6203,7 +6295,8 @@ static int lnet_net_cmd(struct sk_buff *skb, struct genl_info *info) } /* Handle case of just sent NET with no list of NIDs */ - if (!(info->nlhdr->nlmsg_flags & NLM_F_CREATE) && !ni_list) { + if (!(info->nlhdr->nlmsg_flags & (NLM_F_CREATE | NLM_F_REPLACE)) && + !ni_list) { rc = lnet_dyn_del_net(net_id); if (rc < 0) { GENL_SET_ERR_MSG(info, diff --git a/lnet/utils/lnetconfig/liblnetconfig.c b/lnet/utils/lnetconfig/liblnetconfig.c index 1d87f58..e2c0afe 100644 --- a/lnet/utils/lnetconfig/liblnetconfig.c +++ b/lnet/utils/lnetconfig/liblnetconfig.c @@ -1918,7 +1918,7 @@ int lustre_lnet_config_ni(struct lnet_dlc_network_descr *nw_descr, struct lnet_ioctl_config_lnd_tunables *tun = NULL; char buf[LNET_MAX_STR_LEN]; int rc = LUSTRE_CFG_RC_NO_ERR; - char err_str[LNET_MAX_STR_LEN] = "\"success\""; + char err_str[LNET_MAX_STR_LEN * 2] = "\"success\""; lnet_nid_t *nids = NULL; __u32 nnids = 0; size_t len; @@ -2063,7 +2063,7 @@ int lustre_lnet_del_ni(struct lnet_dlc_network_descr *nw_descr, { struct lnet_ioctl_config_ni data; int rc = LUSTRE_CFG_RC_NO_ERR, i; - char err_str[LNET_MAX_STR_LEN] = "\"success\""; + char err_str[LNET_MAX_STR_LEN * 2] = "\"success\""; lnet_nid_t *nids = NULL; __u32 nnids = 0; struct lnet_dlc_intf_descr *intf_descr, *tmp; diff --git a/lnet/utils/lnetconfig/liblnetconfig.h b/lnet/utils/lnetconfig/liblnetconfig.h index 2fc7c08..8a482a7 100644 --- a/lnet/utils/lnetconfig/liblnetconfig.h +++ b/lnet/utils/lnetconfig/liblnetconfig.h @@ -94,7 +94,7 @@ struct lnet_dlc_network_descr { struct lnet_dlc_intf_descr { struct list_head intf_on_network; - char intf_name[IFNAMSIZ]; + char intf_name[LNET_MAX_STR_LEN]; struct cfs_expr_list *cpt_expr; }; diff --git a/lnet/utils/lnetctl.c b/lnet/utils/lnetctl.c index ccc65e3..97aa63d 100644 --- a/lnet/utils/lnetctl.c +++ b/lnet/utils/lnetctl.c @@ -1671,7 +1671,7 @@ static int yaml_add_ni_tunables(yaml_emitter_t *output, { char num[INT_STRING_LEN]; yaml_event_t event; - int rc; + int rc = 0; if (tunables->lt_cmn.lct_peer_timeout < 0 && tunables->lt_cmn.lct_peer_tx_credits <= 0 && @@ -1870,7 +1870,9 @@ skip_general_settings: if (rc == 0) goto error; - if (LNET_NETTYP(nw_descr->nw_id) == SOCKLND) + if (nw_descr->nw_id == LNET_NET_ANY) + cpp = tunables->lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer; + else if (LNET_NETTYP(nw_descr->nw_id) == SOCKLND) cpp = tunables->lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer; else if (LNET_NETTYP(nw_descr->nw_id) == O2IBLND) cpp = tunables->lt_tun.lnd_tun_u.lnd_o2ib.lnd_conns_per_peer; @@ -1896,7 +1898,7 @@ error: static int yaml_lnet_config_ni(char *net_id, char *ip2net, struct lnet_dlc_network_descr *nw_descr, struct lnet_ioctl_config_lnd_tunables *tunables, - struct cfs_expr_list *global_cpts, + int healthv, struct cfs_expr_list *global_cpts, int version, int flags) { struct lnet_dlc_intf_descr *intf; @@ -1908,14 +1910,19 @@ static int yaml_lnet_config_ni(char *net_id, char *ip2net, int rc; if (!(flags & NLM_F_DUMP) && !ip2net && (!nw_descr || nw_descr->nw_id == 0)) { - fprintf(stdout, "missing mandatory parameters in NI config: '%s'", + fprintf(stdout, "missing mandatory parameters in NI config: '%s'\n", (!nw_descr) ? "network , interface" : (nw_descr->nw_id == 0) ? "network" : "interface"); return -EINVAL; } if ((flags == NLM_F_CREATE) && !ip2net && list_empty(&nw_descr->nw_intflist)) { - fprintf(stdout, "creating a local NI needs at least one interface"); + fprintf(stdout, "creating a local NI needs at least one interface\n"); + return -EINVAL; + } + + if ((flags == NLM_F_REPLACE) && list_empty(&nw_descr->nw_intflist)) { + fprintf(stdout, "updating a local NI needs at least one address\n"); return -EINVAL; } @@ -2047,44 +2054,67 @@ static int yaml_lnet_config_ni(char *net_id, char *ip2net, if (rc == 0) goto emitter_error; - yaml_scalar_event_initialize(&event, NULL, - (yaml_char_t *)YAML_STR_TAG, - (yaml_char_t *)"interfaces", - strlen("interfaces"), 1, 0, - YAML_PLAIN_SCALAR_STYLE); - rc = yaml_emitter_emit(&output, &event); - if (rc == 0) - goto emitter_error; + /* Use NI addresses instead of interface */ + if ((strchr(intf->intf_name, '@') || + strcmp(intf->intf_name, "") == 0) && + flags == NLM_F_REPLACE) { + yaml_scalar_event_initialize(&event, NULL, + (yaml_char_t *)YAML_STR_TAG, + (yaml_char_t *)"nid", + strlen("nid"), 1, 0, + YAML_PLAIN_SCALAR_STYLE); + rc = yaml_emitter_emit(&output, &event); + if (rc == 0) + goto emitter_error; - yaml_mapping_start_event_initialize(&event, NULL, - (yaml_char_t *)YAML_MAP_TAG, - 1, YAML_ANY_MAPPING_STYLE); - rc = yaml_emitter_emit(&output, &event); - if (rc == 0) - goto emitter_error; + yaml_scalar_event_initialize(&event, NULL, + (yaml_char_t *)YAML_STR_TAG, + (yaml_char_t *)intf->intf_name, + strlen(intf->intf_name), 1, 0, + YAML_PLAIN_SCALAR_STYLE); + rc = yaml_emitter_emit(&output, &event); + if (rc == 0) + goto emitter_error; + } else { + yaml_scalar_event_initialize(&event, NULL, + (yaml_char_t *)YAML_STR_TAG, + (yaml_char_t *)"interfaces", + strlen("interfaces"), 1, 0, + YAML_PLAIN_SCALAR_STYLE); + rc = yaml_emitter_emit(&output, &event); + if (rc == 0) + goto emitter_error; - yaml_scalar_event_initialize(&event, NULL, - (yaml_char_t *)YAML_STR_TAG, - (yaml_char_t *)"0", - strlen("0"), 1, 0, - YAML_PLAIN_SCALAR_STYLE); - rc = yaml_emitter_emit(&output, &event); - if (rc == 0) - goto emitter_error; + yaml_mapping_start_event_initialize(&event, NULL, + (yaml_char_t *)YAML_MAP_TAG, + 1, YAML_ANY_MAPPING_STYLE); + rc = yaml_emitter_emit(&output, &event); + if (rc == 0) + goto emitter_error; - yaml_scalar_event_initialize(&event, NULL, - (yaml_char_t *)YAML_STR_TAG, - (yaml_char_t *)intf->intf_name, - strlen(intf->intf_name), 1, 0, - YAML_PLAIN_SCALAR_STYLE); - rc = yaml_emitter_emit(&output, &event); - if (rc == 0) - goto emitter_error; + yaml_scalar_event_initialize(&event, NULL, + (yaml_char_t *)YAML_STR_TAG, + (yaml_char_t *)"0", + strlen("0"), 1, 0, + YAML_PLAIN_SCALAR_STYLE); + rc = yaml_emitter_emit(&output, &event); + if (rc == 0) + goto emitter_error; - yaml_mapping_end_event_initialize(&event); - rc = yaml_emitter_emit(&output, &event); - if (rc == 0) - goto emitter_error; + yaml_scalar_event_initialize(&event, NULL, + (yaml_char_t *)YAML_STR_TAG, + (yaml_char_t *)intf->intf_name, + strlen(intf->intf_name), 1, 0, + YAML_PLAIN_SCALAR_STYLE); + rc = yaml_emitter_emit(&output, &event); + if (rc == 0) + goto emitter_error; + + yaml_mapping_end_event_initialize(&event); + rc = yaml_emitter_emit(&output, &event); + if (rc == 0) + goto emitter_error; + } if (tunables) { rc = yaml_add_ni_tunables(&output, tunables, nw_descr); @@ -2092,6 +2122,51 @@ static int yaml_lnet_config_ni(char *net_id, char *ip2net, goto emitter_error; } + if (flags == NLM_F_REPLACE && healthv > -1) { + char health[INT_STRING_LEN]; + + yaml_scalar_event_initialize(&event, NULL, + (yaml_char_t *)YAML_STR_TAG, + (yaml_char_t *)"health stats", + strlen("health stats"), 1, 0, + YAML_PLAIN_SCALAR_STYLE); + rc = yaml_emitter_emit(&output, &event); + if (rc == 0) + goto emitter_error; + + /* Setup all mappings for data related to the 'health stats' */ + yaml_mapping_start_event_initialize(&event, NULL, + (yaml_char_t *)YAML_MAP_TAG, + 1, YAML_BLOCK_MAPPING_STYLE); + rc = yaml_emitter_emit(&output, &event); + if (rc == 0) + goto emitter_error; + + yaml_scalar_event_initialize(&event, NULL, + (yaml_char_t *)YAML_STR_TAG, + (yaml_char_t *)"health value", + strlen("health value"), 1, 0, + YAML_PLAIN_SCALAR_STYLE); + rc = yaml_emitter_emit(&output, &event); + if (rc == 0) + goto emitter_error; + + snprintf(health, sizeof(health), "%d", healthv); + yaml_scalar_event_initialize(&event, NULL, + (yaml_char_t *)YAML_INT_TAG, + (yaml_char_t *)health, + strlen(health), 1, 0, + YAML_PLAIN_SCALAR_STYLE); + rc = yaml_emitter_emit(&output, &event); + if (rc == 0) + goto emitter_error; + + yaml_mapping_end_event_initialize(&event); + rc = yaml_emitter_emit(&output, &event); + if (rc == 0) + goto emitter_error; + } + if (global_cpts) { __u32 *cpt_array; int count, i; @@ -2373,7 +2448,7 @@ static int jt_add_ni(int argc, char **argv) tunables.lt_tun.lnd_tun_u.lnd_o2ib.lnd_map_on_demand = UINT_MAX; rc = yaml_lnet_config_ni(net_id, ip2net, &nw_descr, - found ? &tunables : NULL, + found ? &tunables : NULL, -1, (cpt_rc == 0) ? global_cpts : NULL, LNET_GENL_VERSION, NLM_F_CREATE); if (rc <= 0) { @@ -2504,7 +2579,7 @@ static int jt_del_ni(int argc, char **argv) } } - rc = yaml_lnet_config_ni(net_id, NULL, &nw_descr, NULL, NULL, + rc = yaml_lnet_config_ni(net_id, NULL, &nw_descr, NULL, -1, NULL, LNET_GENL_VERSION, 0); if (rc <= 0) { if (rc != -EOPNOTSUPP) @@ -2600,19 +2675,21 @@ old_api: return rc; } -static int set_value_helper(int argc, char **argv, +static int set_value_helper(int argc, char **argv, int cmd, int (*cb)(int, bool, char*, int, int, struct cYAML**)) { - char *nid = NULL; + char *nidstr = NULL; long int healthv = -1; bool all = false; long int state = -1; + long int cpp = -1; int rc, opt; struct cYAML *err_rc = NULL; - const char *const short_options = "t:n:s:a"; + const char *const short_options = "t:n:m:s:a"; static const struct option long_options[] = { { .name = "nid", .has_arg = required_argument, .val = 'n' }, { .name = "health", .has_arg = required_argument, .val = 't' }, + { .name = "conns-per-peer", .has_arg = required_argument, .val = 'm' }, { .name = "state", .has_arg = required_argument, .val = 's' }, { .name = "all", .has_arg = no_argument, .val = 'a' }, { .name = NULL } @@ -2622,16 +2699,23 @@ static int set_value_helper(int argc, char **argv, long_options, NULL)) != -1) { switch (opt) { case 'n': - nid = optarg; + nidstr = optarg; break; case 't': if (parse_long(optarg, &healthv) != 0) healthv = -1; break; case 's': - if (parse_long(optarg, &state) != 0) + if (cmd != LNET_CMD_PEERS || + parse_long(optarg, &state) != 0) state = -1; break; + case 'm': + if (cmd != LNET_CMD_NETS || + parse_long(optarg, &cpp) != 0) + cpp = -1; + break; + case 'a': all = true; break; @@ -2640,7 +2724,8 @@ static int set_value_helper(int argc, char **argv, } } - rc = cb(healthv, all, nid, state, -1, &err_rc); + rc = cb(healthv, all, nidstr, cmd == LNET_CMD_PEERS ? state : cpp, -1, + &err_rc); if (rc != LUSTRE_CFG_RC_NO_ERR) cYAML_print_tree2file(stderr, err_rc); @@ -2649,70 +2734,73 @@ static int set_value_helper(int argc, char **argv, return rc; } -static int jt_set_ni_value(int argc, char **argv) +int yaml_lnet_config_ni_healthv(int healthv, bool all, char *nidstr, int cpp, + int seq_no, struct cYAML **err_rc) { - char *nid = NULL; - long int healthv = -1, cpp = -1; - bool all = false; - int rc, opt; - struct cYAML *err_rc = NULL; + struct lnet_ioctl_config_lnd_tunables tunables; + struct lnet_dlc_network_descr nw_descr; + char *net_id = "<255:65535>"; /* LNET_NET_ANY */ + int rc = 0; - const char *const short_options = "a:m:n:t:"; - static const struct option long_options[] = { - { .name = "all", .has_arg = no_argument, .val = 'a' }, - { .name = "conns-per-peer", .has_arg = required_argument, .val = 'm' }, - { .name = "nid", .has_arg = required_argument, .val = 'n' }, - { .name = "health", .has_arg = required_argument, .val = 't' }, - { .name = NULL } }; + /* For NI you can't have both setting all NIDs and a requested NID */ + if (!all && !nidstr) + return -EINVAL; - rc = check_cmd(net_cmds, "net", "set", 0, argc, argv); - if (rc) - return rc; + if (cpp == -1 && healthv == -1) + return 0; - while ((opt = getopt_long(argc, argv, short_options, - long_options, NULL)) != -1) { - switch (opt) { - case 'a': - all = true; - break; - case 'm': - rc = parse_long(optarg, &cpp); - if (rc != 0) { - /* ignore option */ - cpp = -1; - continue; - } - break; - case 'n': - nid = optarg; - break; - case 't': - if (parse_long(optarg, &healthv) != 0) { - /* ignore option */ - healthv = -1; - continue; - } - break; - default: - return 0; - } + if (nidstr) { + net_id = strchr(nidstr, '@'); + if (!net_id) + return -EINVAL; + net_id++; } - if (cpp > -1) - rc = lustre_lnet_config_ni_conns_per_peer(cpp, all, nid, - -1, &err_rc); - if (healthv > -1) - rc = lustre_lnet_config_ni_healthv(healthv, all, nid, - -1, &err_rc); + lustre_lnet_init_nw_descr(&nw_descr); + nw_descr.nw_id = libcfs_str2net(net_id); + rc = lustre_lnet_parse_interfaces(nidstr ? nidstr : "", &nw_descr); if (rc != LUSTRE_CFG_RC_NO_ERR) - cYAML_print_tree2file(stderr, err_rc); + return -EINVAL; - cYAML_free_tree(err_rc); + memset(&tunables, 0, sizeof(tunables)); + tunables.lt_cmn.lct_peer_timeout = -1; + if (nw_descr.nw_id == LNET_NET_ANY && cpp > -1) + tunables.lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer = cpp; + else if (LNET_NETTYP(nw_descr.nw_id) == SOCKLND && (cpp > -1)) + tunables.lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer = cpp; + else if (LNET_NETTYP(nw_descr.nw_id) == O2IBLND && (cpp > -1)) + tunables.lt_tun.lnd_tun_u.lnd_o2ib.lnd_conns_per_peer = cpp; + rc = yaml_lnet_config_ni(net_id, NULL, &nw_descr, + cpp != -1 ? &tunables : NULL, healthv, NULL, + LNET_GENL_VERSION, NLM_F_REPLACE); + if (rc <= 0) { + if (rc == -EOPNOTSUPP) + goto old_api; + return rc; + } +old_api: + if (cpp > -1) + rc = lustre_lnet_config_ni_conns_per_peer(cpp, all, nidstr, + -1, err_rc); + if (healthv > -1) + rc = lustre_lnet_config_ni_healthv(healthv, all, nidstr, + -1, err_rc); return rc; } +static int jt_set_ni_value(int argc, char **argv) +{ + int rc = check_cmd(net_cmds, "net", "set", 0, argc, argv); + + if (rc < 0) + return rc; + + return set_value_helper(argc, argv, LNET_CMD_NETS, + yaml_lnet_config_ni_healthv); +} + static int yaml_lnet_peer_display(yaml_parser_t *reply, bool list_only) { yaml_emitter_t debug; @@ -3227,10 +3315,6 @@ old_api: seq_no, err_rc); else rc = lustre_lnet_set_peer_state(state, lpni_nid, -1, err_rc); - if (rc != LUSTRE_CFG_RC_NO_ERR) - cYAML_print_tree2file(stderr, *err_rc); - - cYAML_free_tree(*err_rc); return rc; } @@ -3242,7 +3326,8 @@ static int jt_set_peer_ni_value(int argc, char **argv) if (rc < 0) return rc; - return set_value_helper(argc, argv, yaml_lnet_config_peer_ni_healthv); + return set_value_helper(argc, argv, LNET_CMD_PEERS, + yaml_lnet_config_peer_ni_healthv); } static int jt_show_recovery(int argc, char **argv) @@ -3358,7 +3443,7 @@ static int jt_show_net(int argc, char **argv) } } - rc = yaml_lnet_config_ni(network, NULL, NULL, NULL, NULL, + rc = yaml_lnet_config_ni(network, NULL, NULL, NULL, -1, NULL, detail, NLM_F_DUMP); if (rc <= 0) { if (rc != -EOPNOTSUPP) -- 1.8.3.1