*
* LGPL HEADER END
*
- * Copyright (c) 2014, 2016, Intel Corporation.
+ * Copyright (c) 2014, 2017, Intel Corporation.
*
* Author:
* Amir Shehata <amir.shehata@intel.com>
#define MANAGE_CMD "manage"
#define modparam_path "/sys/module/lnet/parameters/"
+#define gni_nid_path "/proc/cray_xt/"
const char *gmsg_stat_names[] = {"sent_stats", "received_stats",
"dropped_stats"};
struct lnet_ioctl_ping_data ping;
struct cYAML *root = NULL, *ping_node = NULL, *item = NULL,
*first_seq = NULL, *tmp = NULL, *peer_ni = NULL;
- lnet_process_id_t id;
+ struct lnet_process_id id;
char err_str[LNET_MAX_STR_LEN] = {0};
char *sep, *token, *end;
char buf[6];
int i;
bool flag = false;
- len = (sizeof(lnet_process_id_t) * LNET_INTERFACES_MAX_DEFAULT);
+ len = (sizeof(struct lnet_process_id) * LNET_INTERFACES_MAX_DEFAULT);
data = calloc(1, len);
if (data == NULL)
if (nw == NULL || gw == NULL) {
snprintf(err_str,
sizeof(err_str),
- "\"missing mandatory parameter(s): '%s'\"",
+ "\"missing mandatory parameter in route config:'%s'\"",
(nw == NULL && gw == NULL) ? "network, gateway" :
(nw == NULL) ? "network" : "gateway");
rc = LUSTRE_CFG_RC_MISSING_PARAM;
if (nw == NULL || gw == NULL) {
snprintf(err_str,
sizeof(err_str),
- "\"missing mandatory parameter(s): '%s'\"",
+ "\"missing mandatory parameter in route delete: '%s'\"",
(nw == NULL && gw == NULL) ? "network, gateway" :
(nw == NULL) ? "network" : "gateway");
rc = LUSTRE_CFG_RC_MISSING_PARAM;
int lustre_lnet_show_route(char *nw, char *gw, int hops, int prio, int detail,
int seq_no, struct cYAML **show_rc,
- struct cYAML **err_rc)
+ struct cYAML **err_rc, bool backup)
{
struct lnet_ioctl_config_data data;
lnet_nid_t gateway_nid;
cfg_route.rtr_priority) == NULL)
goto out;
- if (cYAML_create_string(item, "state",
+ if (!backup &&
+ cYAML_create_string(item, "state",
data.cfg_config_u.cfg_route.
rtr_flags ?
"up" : "down") == NULL)
return rc;
}
+static int lustre_lnet_queryip(struct lnet_dlc_intf_descr *intf, __u32 *ip)
+{
+ struct ifreq ifr;
+ int rc;
+
+ memset(&ifr, 0, sizeof(ifr));
+ rc = socket_intf_query(SIOCGIFFLAGS, intf->intf_name, &ifr);
+ if (rc != 0)
+ return LUSTRE_CFG_RC_BAD_PARAM;
+
+ if ((ifr.ifr_flags & IFF_UP) == 0)
+ return LUSTRE_CFG_RC_BAD_PARAM;
+
+ memset(&ifr, 0, sizeof(ifr));
+ rc = socket_intf_query(SIOCGIFADDR, intf->intf_name, &ifr);
+ if (rc != 0)
+ return LUSTRE_CFG_RC_BAD_PARAM;
+
+ *ip = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
+ *ip = bswap_32(*ip);
+
+ return LUSTRE_CFG_RC_NO_ERR;
+}
+
/*
* for each interface in the array of interfaces find the IP address of
* that interface, create its nid and add it to an array of NIDs.
* Stop if any of the interfaces is down
*/
static int lustre_lnet_intf2nids(struct lnet_dlc_network_descr *nw,
- lnet_nid_t **nids, __u32 *nnids)
+ lnet_nid_t **nids, __u32 *nnids,
+ char *err_str, size_t str_len)
{
int i = 0, count = 0, rc;
- struct ifreq ifr;
- __u32 ip;
struct lnet_dlc_intf_descr *intf;
+ char val[LNET_MAX_STR_LEN];
+ __u32 ip;
+ int gni_num;
- if (nw == NULL || nids == NULL)
+
+ if (nw == NULL || nids == NULL) {
+ snprintf(err_str, str_len,
+ "\"unexpected parameters to lustre_lnet_intf2nids()\"");
+ err_str[str_len - 1] = '\0';
return LUSTRE_CFG_RC_BAD_PARAM;
+ }
- list_for_each_entry(intf, &nw->nw_intflist, intf_on_network)
- count++;
+ if (LNET_NETTYP(nw->nw_id) == GNILND) {
+ count = 1;
+ } else {
+ list_for_each_entry(intf, &nw->nw_intflist, intf_on_network)
+ count++;
+ }
*nids = calloc(count, sizeof(lnet_nid_t));
- if (*nids == NULL)
+ if (*nids == NULL) {
+ snprintf(err_str, str_len,
+ "\"out of memory\"");
+ err_str[str_len - 1] = '\0';
return LUSTRE_CFG_RC_OUT_OF_MEM;
-
- list_for_each_entry(intf, &nw->nw_intflist, intf_on_network) {
- memset(&ifr, 0, sizeof(ifr));
- rc = socket_intf_query(SIOCGIFFLAGS, intf->intf_name, &ifr);
- if (rc != 0)
- goto failed;
-
- if ((ifr.ifr_flags & IFF_UP) == 0) {
- rc = LUSTRE_CFG_RC_BAD_PARAM;
+ }
+ /*
+ * special case the GNI interface since it doesn't have an IP
+ * address. The assumption is that there can only be one GNI
+ * interface in the system. No interface name is provided.
+ */
+ if (LNET_NETTYP(nw->nw_id) == GNILND) {
+ rc = read_sysfs_file(gni_nid_path, "nid", val,
+ 1, sizeof(val));
+ if (rc) {
+ snprintf(err_str, str_len,
+ "\"cannot read gni nid\"");
+ err_str[str_len - 1] = '\0';
goto failed;
}
+ gni_num = atoi(val);
- memset(&ifr, 0, sizeof(ifr));
- rc = socket_intf_query(SIOCGIFADDR, intf->intf_name, &ifr);
- if (rc != 0)
- goto failed;
+ (*nids)[i] = LNET_MKNID(nw->nw_id, gni_num);
- ip = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
- ip = bswap_32(ip);
+ goto out;
+ }
+
+ /* look at the other interfaces */
+ list_for_each_entry(intf, &nw->nw_intflist, intf_on_network) {
+ rc = lustre_lnet_queryip(intf, &ip);
+ if (rc != LUSTRE_CFG_RC_NO_ERR) {
+ snprintf(err_str, str_len,
+ "\"couldn't query intf %s\"", intf->intf_name);
+ err_str[str_len - 1] = '\0';
+ goto failed;
+ }
(*nids)[i] = LNET_MKNID(nw->nw_id, ip);
i++;
}
+out:
*nnids = count;
return 0;
return LUSTRE_CFG_RC_MATCH;
}
-int lustre_lnet_resolve_ip2nets_rule(struct lustre_lnet_ip2nets *ip2nets,
- lnet_nid_t **nids, __u32 *nnids)
+static int lustre_lnet_resolve_ip2nets_rule(struct lustre_lnet_ip2nets *ip2nets,
+ lnet_nid_t **nids, __u32 *nnids,
+ char *err_str, size_t str_len)
{
struct ifaddrs *ifa;
int rc = LUSTRE_CFG_RC_NO_ERR;
rc = getifaddrs(&ifa);
- if (rc < 0)
+ if (rc < 0) {
+ snprintf(err_str, str_len,
+ "\"failed to get interface addresses: %d\"", -errno);
+ err_str[str_len - 1] = '\0';
return -errno;
+ }
rc = lustre_lnet_match_ip_to_intf(ifa,
&ip2nets->ip2nets_net.nw_intflist,
&ip2nets->ip2nets_ip_ranges);
if (rc != LUSTRE_CFG_RC_MATCH) {
+ snprintf(err_str, str_len,
+ "\"couldn't match ip to existing interfaces\"");
+ err_str[str_len - 1] = '\0';
freeifaddrs(ifa);
return rc;
}
- rc = lustre_lnet_intf2nids(&ip2nets->ip2nets_net, nids, nnids);
+ rc = lustre_lnet_intf2nids(&ip2nets->ip2nets_net, nids, nnids,
+ err_str, sizeof(err_str));
if (rc != LUSTRE_CFG_RC_NO_ERR) {
*nids = NULL;
*nnids = 0;
* The memory is allocated in that function then freed here when
* it's no longer needed.
*/
- rc = lustre_lnet_resolve_ip2nets_rule(ip2nets, &nids, &nnids);
- if (rc != LUSTRE_CFG_RC_NO_ERR && rc != LUSTRE_CFG_RC_MATCH) {
- snprintf(err_str,
- sizeof(err_str),
- "\"cannot resolve ip2nets rule\"");
+ rc = lustre_lnet_resolve_ip2nets_rule(ip2nets, &nids, &nnids, err_str,
+ sizeof(err_str));
+ if (rc != LUSTRE_CFG_RC_NO_ERR && rc != LUSTRE_CFG_RC_MATCH)
goto out;
- }
if (list_empty(&ip2nets->ip2nets_net.nw_intflist)) {
snprintf(err_str, sizeof(err_str),
snprintf(err_str, sizeof(err_str), "\"success\"");
if (ip2net == NULL && (nw_descr == NULL || nw_descr->nw_id == 0 ||
- list_empty(&nw_descr->nw_intflist))) {
+ (list_empty(&nw_descr->nw_intflist) &&
+ LNET_NETTYP(nw_descr->nw_id) != GNILND))) {
snprintf(err_str,
sizeof(err_str),
- "\"missing mandatory parameters\"");
+ "\"missing mandatory parameters in NI config: '%s'\"",
+ (nw_descr == NULL) ? "network , interface" :
+ (nw_descr->nw_id == 0) ? "network" : "interface");
rc = LUSTRE_CFG_RC_MISSING_PARAM;
goto out;
}
goto out;
}
- if (list_empty(&nw_descr->nw_intflist)) {
+ /*
+ * special case the GNI since no interface name is expected
+ */
+ if (list_empty(&nw_descr->nw_intflist) &&
+ (LNET_NETTYP(nw_descr->nw_id) != GNILND)) {
snprintf(err_str,
sizeof(err_str),
"\"no interface name provided\"");
goto out;
}
- rc = lustre_lnet_intf2nids(nw_descr, &nids, &nnids);
+ rc = lustre_lnet_intf2nids(nw_descr, &nids, &nnids,
+ err_str, sizeof(err_str));
if (rc != 0) {
- snprintf(err_str, sizeof(err_str),
- "\"bad parameter\"");
rc = LUSTRE_CFG_RC_BAD_PARAM;
goto out;
}
snprintf(err_str, sizeof(err_str), "\"success\"");
- if (nw_descr == NULL || nw_descr->nw_id == 0 ||
- list_empty(&nw_descr->nw_intflist)) {
+ if (nw_descr == NULL || nw_descr->nw_id == 0) {
snprintf(err_str,
sizeof(err_str),
- "\"missing mandatory parameter\"");
+ "\"missing mandatory parameter in deleting NI: '%s'\"",
+ (nw_descr == NULL) ? "network , interface" :
+ (nw_descr->nw_id == 0) ? "network" : "interface");
rc = LUSTRE_CFG_RC_MISSING_PARAM;
goto out;
}
goto out;
}
- rc = lustre_lnet_intf2nids(nw_descr, &nids, &nnids);
+ rc = lustre_lnet_intf2nids(nw_descr, &nids, &nnids,
+ err_str, sizeof(err_str));
if (rc != 0) {
- snprintf(err_str, sizeof(err_str),
- "\"bad parameter\"");
rc = LUSTRE_CFG_RC_BAD_PARAM;
goto out;
}
}
int lustre_lnet_show_net(char *nw, int detail, int seq_no,
- struct cYAML **show_rc, struct cYAML **err_rc)
+ struct cYAML **show_rc, struct cYAML **err_rc,
+ bool backup)
{
char *buf;
struct lnet_ioctl_config_ni *ni_data;
net != rc_net)
continue;
+ /* if we're backing up don't store lo */
+ if (backup && LNET_NETTYP(rc_net) == LOLND)
+ continue;
+
/* default rc to -1 in case we hit the goto */
rc = -1;
exist = true;
if (first_seq == NULL)
first_seq = item;
- if (cYAML_create_string(item, "nid",
+ if (!backup &&
+ cYAML_create_string(item, "nid",
libcfs_nid2str(ni_data->lic_nid)) == NULL)
goto out;
- if (cYAML_create_string(item,
+ if (!backup &&
+ cYAML_create_string(item,
"status",
(ni_data->lic_status ==
LNET_NI_STATUS_UP) ?
char *limit;
int k;
+ if (backup)
+ goto continue_without_msg_stats;
+
statistics = cYAML_create_object(item, "statistics");
if (statistics == NULL)
goto out;
if (rc != LUSTRE_CFG_RC_NO_ERR)
goto out;
- tunables = cYAML_create_object(item, "lnd tunables");
- if (tunables == NULL)
- goto out;
-
rc = lustre_ni_show_tunables(tunables, LNET_NETTYP(rc_net),
&lnd->lt_tun);
- if (rc != LUSTRE_CFG_RC_NO_ERR)
+ if (rc != LUSTRE_CFG_RC_NO_ERR &&
+ rc != LUSTRE_CFG_RC_NO_MATCH)
goto out;
- if (cYAML_create_number(item, "tcp bonding",
- ni_data->lic_tcp_bonding)
- == NULL)
- goto out;
+ if (rc != LUSTRE_CFG_RC_NO_MATCH) {
+ tunables = cYAML_create_object(item,
+ "lnd tunables");
+ if (tunables == NULL)
+ goto out;
+ }
- if (cYAML_create_number(item, "dev cpt",
+ if (!backup &&
+ cYAML_create_number(item, "dev cpt",
ni_data->lic_dev_cpt) == NULL)
goto out;
+ if (!backup &&
+ cYAML_create_number(item, "tcp bonding",
+ ni_data->lic_tcp_bonding)
+ == NULL)
+ goto out;
+
/* out put the CPTs in the format: "[x,x,x,...]" */
limit = str_buf + str_buf_len - 3;
pos += snprintf(pos, limit - pos, "\"[");
}
int lustre_lnet_show_routing(int seq_no, struct cYAML **show_rc,
- struct cYAML **err_rc)
+ struct cYAML **err_rc, bool backup)
{
struct lnet_ioctl_config_data *data;
struct lnet_ioctl_pool_cfg *pool_cfg = NULL;
if (root == NULL)
goto out;
- pools_node = cYAML_create_seq(root, "routing");
+ if (backup)
+ pools_node = cYAML_create_object(root, "routing");
+ else
+ pools_node = cYAML_create_seq(root, "routing");
if (pools_node == NULL)
goto out;
pool_cfg = (struct lnet_ioctl_pool_cfg *)data->cfg_bulk;
+ if (backup)
+ goto calculate_buffers;
+
snprintf(node_name, sizeof(node_name), "cpt[%d]", i);
item = cYAML_create_seq_item(pools_node);
if (item == NULL)
if (cpt == NULL)
goto out;
+calculate_buffers:
/* create the tree and print */
for (j = 0; j < LNET_NRBPOOLS; j++) {
- type_node = cYAML_create_object(cpt, pools[j]);
- if (type_node == NULL)
- goto out;
- if (cYAML_create_number(type_node, "npages",
+ if (!backup) {
+ type_node = cYAML_create_object(cpt, pools[j]);
+ if (type_node == NULL)
+ goto out;
+ }
+ if (!backup &&
+ cYAML_create_number(type_node, "npages",
pool_cfg->pl_pools[j].pl_npages)
== NULL)
goto out;
- if (cYAML_create_number(type_node, "nbuffers",
+ if (!backup &&
+ cYAML_create_number(type_node, "nbuffers",
pool_cfg->pl_pools[j].
pl_nbuffers) == NULL)
goto out;
- if (cYAML_create_number(type_node, "credits",
+ if (!backup &&
+ cYAML_create_number(type_node, "credits",
pool_cfg->pl_pools[j].
pl_credits) == NULL)
goto out;
- if (cYAML_create_number(type_node, "mincredits",
+ if (!backup &&
+ cYAML_create_number(type_node, "mincredits",
pool_cfg->pl_pools[j].
pl_mincredits) == NULL)
goto out;
}
if (pool_cfg != NULL) {
+ if (backup) {
+ if (cYAML_create_number(pools_node, "enable",
+ pool_cfg->pl_routing) ==
+ NULL)
+ goto out;
+
+ goto add_buffer_section;
+ }
+
item = cYAML_create_seq_item(pools_node);
if (item == NULL)
goto out;
goto out;
}
+add_buffer_section:
/* create a buffers entry in the show. This is necessary so that
* if the YAML output is used to configure a node, the buffer
* configuration takes hold */
}
int lustre_lnet_show_peer(char *knid, int detail, int seq_no,
- struct cYAML **show_rc, struct cYAML **err_rc)
+ struct cYAML **show_rc, struct cYAML **err_rc,
+ bool backup)
{
/*
* TODO: This function is changing in a future patch to accommodate
*first_seq = NULL, *peer_root = NULL, *tmp = NULL,
*msg_statistics = NULL, *statistics = NULL;
char err_str[LNET_MAX_STR_LEN];
- lnet_process_id_t *list = NULL;
+ struct lnet_process_id *list = NULL;
void *data = NULL;
void *lpni_data;
goto out;
count = 1000;
- size = count * sizeof(lnet_process_id_t);
+ size = count * sizeof(struct lnet_process_id);
list = malloc(size);
if (list == NULL) {
l_errno = ENOMEM;
* requested
*/
if (detail >= 3) {
- if (cYAML_create_number(peer, "peer state",
+ if (!backup &&
+ cYAML_create_number(peer, "peer state",
peer_info.prcfg_state)
== NULL)
goto out;
== NULL)
goto out;
+ if (backup)
+ continue;
+
if (cYAML_create_string(peer_ni, "state",
lpni_cri->cr_aliveness)
== NULL)
int l_errno = 0;
struct cYAML *root = NULL, *list_root = NULL, *first_seq = NULL;
char err_str[LNET_MAX_STR_LEN];
- lnet_process_id_t *list = NULL;
+ struct lnet_process_id *list = NULL;
snprintf(err_str, sizeof(err_str),
"\"out of memory\"");
goto out;
count = 1000;
- size = count * sizeof(lnet_process_id_t);
+ size = count * sizeof(struct lnet_process_id);
list = malloc(size);
if (list == NULL) {
l_errno = ENOMEM;
(prio) ? prio->cy_valueint : -1,
(detail) ? detail->cy_valueint : 0,
(seq_no) ? seq_no->cy_valueint : -1,
- show_rc,
- err_rc);
+ show_rc, err_rc, false);
}
static int handle_yaml_show_net(struct cYAML *tree, struct cYAML **show_rc,
return lustre_lnet_show_net((net) ? net->cy_valuestring : NULL,
(detail) ? detail->cy_valueint : 0,
(seq_no) ? seq_no->cy_valueint : -1,
- show_rc,
- err_rc);
+ show_rc, err_rc, false);
}
static int handle_yaml_show_routing(struct cYAML *tree, struct cYAML **show_rc,
seq_no = cYAML_get_object_item(tree, "seq_no");
return lustre_lnet_show_routing((seq_no) ? seq_no->cy_valueint : -1,
- show_rc, err_rc);
+ show_rc, err_rc, false);
}
static int handle_yaml_show_peers(struct cYAML *tree, struct cYAML **show_rc,
return lustre_lnet_show_peer((nid) ? nid->cy_valuestring : NULL,
(detail) ? detail->cy_valueint : 0,
(seq_no) ? seq_no->cy_valueint : -1,
- show_rc, err_rc);
+ show_rc, err_rc, false);
}
static int handle_yaml_show_stats(struct cYAML *tree, struct cYAML **show_rc,