Whamcloud - gitweb
LU-10151 lnet: report better config error with lnetctl
[fs/lustre-release.git] / lnet / utils / lnetconfig / liblnetconfig.c
index bee4a29..2df6a36 100644 (file)
@@ -51,7 +51,6 @@
 #include <fcntl.h>
 #include <ifaddrs.h>
 #include "liblnetconfig.h"
-#include "cyaml.h"
 
 #define CONFIG_CMD             "configure"
 #define UNCONFIG_CMD           "unconfigure"
@@ -63,6 +62,9 @@
 
 #define modparam_path "/sys/module/lnet/parameters/"
 
+const char *gmsg_stat_names[] = {"sent_stats", "received_stats",
+                                "dropped_stats"};
+
 /*
  * lustre_lnet_ip_range_descr
  *     Describes an IP range.
@@ -237,6 +239,7 @@ int lustre_lnet_add_intf_descr(struct list_head *list, char *intf, int len)
 void lustre_lnet_init_nw_descr(struct lnet_dlc_network_descr *nw_descr)
 {
        if (nw_descr != NULL) {
+               nw_descr->nw_id = 0;
                INIT_LIST_HEAD(&nw_descr->network_on_rule);
                INIT_LIST_HEAD(&nw_descr->nw_intflist);
        }
@@ -393,8 +396,7 @@ failed:
 
 int lustre_lnet_config_lib_init(void)
 {
-       return register_ioc_dev(LNET_DEV_ID, LNET_DEV_PATH,
-                               LNET_DEV_MAJOR, LNET_DEV_MINOR);
+       return register_ioc_dev(LNET_DEV_ID, LNET_DEV_PATH);
 }
 
 void lustre_lnet_config_lib_uninit(void)
@@ -604,8 +606,8 @@ static int infra_ping_nid(char *ping_nids, char *oper, int param, int ioc_call,
                                        libcfs_nid2str(ping.ping_id.nid)) == NULL)
                        goto out;
 
-               if (cYAML_create_string(item, "Multi-Rail", ping.mr_info ? "True" :
-                                       "False") == NULL)
+               if (cYAML_create_string(item, "Multi-Rail", ping.mr_info ?
+                                       "True" : "False") == NULL)
                        goto out;
 
                tmp = cYAML_create_seq(item, "peer ni");
@@ -669,6 +671,16 @@ int lustre_lnet_ping_nid(char *ping_nids, int timeout, int seq_no,
        return rc;
 }
 
+int lustre_lnet_discover_nid(char *ping_nids, int force, int seq_no,
+                        struct cYAML **show_rc, struct cYAML **err_rc)
+{
+       int rc;
+
+       rc = infra_ping_nid(ping_nids, "discover", force, IOC_LIBCFS_DISCOVER,
+                           seq_no, show_rc, err_rc);
+       return rc;
+}
+
 int lustre_lnet_config_peer_nid(char *pnid, char **nid, int num_nids,
                                bool mr, int seq_no, struct cYAML **err_rc)
 {
@@ -810,7 +822,7 @@ int lustre_lnet_config_route(char *nw, char *gw, int hops, int prio,
        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;
@@ -893,7 +905,7 @@ int lustre_lnet_del_route(char *nw, char *gw,
        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;
@@ -1530,10 +1542,13 @@ int lustre_lnet_config_ni(struct lnet_dlc_network_descr *nw_descr,
 
        snprintf(err_str, sizeof(err_str), "\"success\"");
 
-       if (ip2net == NULL && nw_descr == NULL) {
+       if (ip2net == NULL && (nw_descr == NULL || nw_descr->nw_id == 0 ||
+           list_empty(&nw_descr->nw_intflist))) {
                snprintf(err_str,
                         sizeof(err_str),
-                        "\"mandatory parameters not specified.\"");
+                        "\"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;
        }
@@ -1667,10 +1682,13 @@ int lustre_lnet_del_ni(struct lnet_dlc_network_descr *nw_descr,
 
        snprintf(err_str, sizeof(err_str), "\"success\"");
 
-       if (nw_descr == NULL) {
+       if (nw_descr == NULL || nw_descr->nw_id == 0 ||
+           list_empty(&nw_descr->nw_intflist)) {
                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;
        }
@@ -1738,6 +1756,47 @@ out:
        return rc;
 }
 
+static bool
+add_msg_stats_to_yaml_blk(struct cYAML *yaml,
+                         struct lnet_ioctl_comm_count *counts)
+{
+       if (cYAML_create_number(yaml, "put",
+                               counts->ico_put_count)
+                                       == NULL)
+               return false;
+       if (cYAML_create_number(yaml, "get",
+                               counts->ico_get_count)
+                                       == NULL)
+               return false;
+       if (cYAML_create_number(yaml, "reply",
+                               counts->ico_reply_count)
+                                       == NULL)
+               return false;
+       if (cYAML_create_number(yaml, "ack",
+                               counts->ico_ack_count)
+                                       == NULL)
+               return false;
+       if (cYAML_create_number(yaml, "hello",
+                               counts->ico_hello_count)
+                                       == NULL)
+               return false;
+
+       return true;
+}
+
+static struct lnet_ioctl_comm_count *
+get_counts(struct lnet_ioctl_element_msg_stats *msg_stats, int idx)
+{
+       if (idx == 0)
+               return &msg_stats->im_send_stats;
+       if (idx == 1)
+               return &msg_stats->im_recv_stats;
+       if (idx == 2)
+               return &msg_stats->im_drop_stats;
+
+       return NULL;
+}
+
 int lustre_lnet_show_net(char *nw, int detail, int seq_no,
                         struct cYAML **show_rc, struct cYAML **err_rc)
 {
@@ -1745,6 +1804,7 @@ int lustre_lnet_show_net(char *nw, int detail, int seq_no,
        struct lnet_ioctl_config_ni *ni_data;
        struct lnet_ioctl_config_lnd_tunables *lnd;
        struct lnet_ioctl_element_stats *stats;
+       struct lnet_ioctl_element_msg_stats msg_stats;
        __u32 net = LNET_NIDNET(LNET_NID_ANY);
        __u32 prev_net = LNET_NIDNET(LNET_NID_ANY);
        int rc = LUSTRE_CFG_RC_OUT_OF_MEM, i, j;
@@ -1881,6 +1941,7 @@ int lustre_lnet_show_net(char *nw, int detail, int seq_no,
 
                if (detail) {
                        char *limit;
+                       int k;
 
                        statistics = cYAML_create_object(item, "statistics");
                        if (statistics == NULL)
@@ -1901,6 +1962,40 @@ int lustre_lnet_show_net(char *nw, int detail, int seq_no,
                                                        == NULL)
                                goto out;
 
+                       if (detail < 2)
+                               goto continue_without_msg_stats;
+
+                       LIBCFS_IOC_INIT_V2(msg_stats, im_hdr);
+                       msg_stats.im_hdr.ioc_len = sizeof(msg_stats);
+                       msg_stats.im_idx = i;
+
+                       rc = l_ioctl(LNET_DEV_ID,
+                                    IOC_LIBCFS_GET_LOCAL_NI_MSG_STATS,
+                                    &msg_stats);
+                       if (rc != 0) {
+                               l_errno = errno;
+                               goto continue_without_msg_stats;
+                       }
+
+                       for (k = 0; k < 3; k++) {
+                               struct lnet_ioctl_comm_count *counts;
+                               struct cYAML *msg_statistics = NULL;
+
+                               msg_statistics = cYAML_create_object(item,
+                                                (char *)gmsg_stat_names[k]);
+                               if (msg_statistics == NULL)
+                                       goto out;
+
+                               counts = get_counts(&msg_stats, k);
+                               if (counts == NULL)
+                                       goto out;
+
+                               if (!add_msg_stats_to_yaml_blk(msg_statistics,
+                                                              counts))
+                                       goto out;
+                       }
+
+continue_without_msg_stats:
                        tunables = cYAML_create_object(item, "tunables");
                        if (!tunables)
                                goto out;
@@ -2020,6 +2115,32 @@ out:
        return rc;
 }
 
+int ioctl_set_value(__u32 val, int ioc, char *name,
+                   int seq_no, struct cYAML **err_rc)
+{
+       struct lnet_ioctl_set_value data;
+       int rc = LUSTRE_CFG_RC_NO_ERR;
+       char err_str[LNET_MAX_STR_LEN];
+
+       snprintf(err_str, sizeof(err_str), "\"success\"");
+
+       LIBCFS_IOC_INIT_V2(data, sv_hdr);
+       data.sv_value = val;
+
+       rc = l_ioctl(LNET_DEV_ID, ioc , &data);
+       if (rc != 0) {
+               rc = -errno;
+               snprintf(err_str,
+                        sizeof(err_str),
+                        "\"cannot configure %s to %d: %s\"", name,
+                        val, strerror(errno));
+       }
+
+       cYAML_build_error(rc, seq_no, ADD_CMD, name, err_str, err_rc);
+
+       return rc;
+}
+
 int lustre_lnet_config_max_intf(int max, int seq_no, struct cYAML **err_rc)
 {
        int rc = LUSTRE_CFG_RC_NO_ERR;
@@ -2067,36 +2188,8 @@ int lustre_lnet_config_discovery(int enable, int seq_no, struct cYAML **err_rc)
 
 int lustre_lnet_config_numa_range(int range, int seq_no, struct cYAML **err_rc)
 {
-       struct lnet_ioctl_set_value data;
-       int rc = LUSTRE_CFG_RC_NO_ERR;
-       char err_str[LNET_MAX_STR_LEN];
-
-       snprintf(err_str, sizeof(err_str), "\"success\"");
-
-       if (range < 0) {
-               snprintf(err_str,
-                        sizeof(err_str),
-                        "\"range must be >= 0\"");
-               rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
-               goto out;
-       }
-
-       LIBCFS_IOC_INIT_V2(data, sv_hdr);
-       data.sv_value = range;
-
-       rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_SET_NUMA_RANGE, &data);
-       if (rc != 0) {
-               rc = -errno;
-               snprintf(err_str,
-                        sizeof(err_str),
-                        "\"cannot configure numa_range: %s\"", strerror(errno));
-               goto out;
-       }
-
-out:
-       cYAML_build_error(rc, seq_no, ADD_CMD, "numa_range", err_str, err_rc);
-
-       return rc;
+       return ioctl_set_value(range, IOC_LIBCFS_SET_NUMA_RANGE,
+                              "numa_range", seq_no, err_rc);
 }
 
 int lustre_lnet_config_buffers(int tiny, int small, int large, int seq_no,
@@ -2300,15 +2393,16 @@ int lustre_lnet_show_peer(char *knid, int detail, int seq_no,
        struct lnet_ioctl_peer_cfg peer_info;
        struct lnet_peer_ni_credit_info *lpni_cri;
        struct lnet_ioctl_element_stats *lpni_stats;
+       struct lnet_ioctl_element_msg_stats *msg_stats;
        lnet_nid_t *nidp;
        int rc = LUSTRE_CFG_RC_OUT_OF_MEM;
-       int i;
-       int j;
+       int i, j, k;
        int l_errno = 0;
        __u32 count;
        __u32 size;
        struct cYAML *root = NULL, *peer = NULL, *peer_ni = NULL,
-                    *first_seq = NULL, *peer_root = NULL, *tmp = NULL;
+                    *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;
        void *data = NULL;
@@ -2423,6 +2517,16 @@ int lustre_lnet_show_peer(char *knid, int detail, int seq_no,
                                        peer_info.prcfg_mr ? "True" : "False")
                    == NULL)
                        goto out;
+               /*
+                * print out the state of the peer only if details are
+                * requested
+                */
+               if (detail >= 3) {
+                       if (cYAML_create_number(peer, "peer state",
+                                               peer_info.prcfg_state)
+                               == NULL)
+                               goto out;
+               }
 
                tmp = cYAML_create_seq(peer, "peer ni");
                if (tmp == NULL)
@@ -2433,7 +2537,8 @@ int lustre_lnet_show_peer(char *knid, int detail, int seq_no,
                        nidp = lpni_data;
                        lpni_cri = (void*)nidp + sizeof(nidp);
                        lpni_stats = (void *)lpni_cri + sizeof(*lpni_cri);
-                       lpni_data = (void *)lpni_stats + sizeof(*lpni_stats);
+                       msg_stats = (void *)lpni_stats + sizeof(*lpni_stats);
+                       lpni_data = (void *)msg_stats + sizeof(*msg_stats);
 
                        peer_ni = cYAML_create_seq_item(tmp);
                        if (peer_ni == NULL)
@@ -2482,24 +2587,49 @@ int lustre_lnet_show_peer(char *knid, int detail, int seq_no,
                            == NULL)
                                goto out;
 
-                       if (cYAML_create_number(peer_ni, "send_count",
+                       if (cYAML_create_number(peer_ni, "refcount",
+                                               lpni_cri->cr_refcount) == NULL)
+                               goto out;
+
+                       statistics = cYAML_create_object(peer_ni, "statistics");
+                       if (statistics == NULL)
+                               goto out;
+
+                       if (cYAML_create_number(statistics, "send_count",
                                                lpni_stats->iel_send_count)
                            == NULL)
                                goto out;
 
-                       if (cYAML_create_number(peer_ni, "recv_count",
+                       if (cYAML_create_number(statistics, "recv_count",
                                                lpni_stats->iel_recv_count)
                            == NULL)
                                goto out;
 
-                       if (cYAML_create_number(peer_ni, "drop_count",
+                       if (cYAML_create_number(statistics, "drop_count",
                                                lpni_stats->iel_drop_count)
                            == NULL)
                                goto out;
 
-                       if (cYAML_create_number(peer_ni, "refcount",
-                                               lpni_cri->cr_refcount) == NULL)
-                               goto out;
+                       if (detail < 2)
+                               continue;
+
+                       for (k = 0; k < 3; k++) {
+                               struct lnet_ioctl_comm_count *counts;
+
+                               msg_statistics = cYAML_create_object(peer_ni,
+                                                (char *) gmsg_stat_names[k]);
+                               if (msg_statistics == NULL)
+                                       goto out;
+
+                               counts = get_counts(msg_stats, k);
+                               if (counts == NULL)
+                                       goto out;
+
+                               if (!add_msg_stats_to_yaml_blk(msg_statistics,
+                                                              counts))
+                                       goto out;
+                       }
+
                }
        }
 
@@ -2669,27 +2799,19 @@ static void add_to_global(struct cYAML *show_rc, struct cYAML *node,
        free(root);
 }
 
-int lustre_lnet_show_max_intf(int seq_no, struct cYAML **show_rc,
-                             struct cYAML **err_rc)
+static int build_global_yaml_entry(char *err_str, int err_len, int seq_no,
+                                  char *name, __u32 value,
+                                  struct cYAML **show_rc,
+                                  struct cYAML **err_rc, int err)
 {
        int rc = LUSTRE_CFG_RC_OUT_OF_MEM;
-       char val[LNET_MAX_STR_LEN];
-       int max_intf;
-       char err_str[LNET_MAX_STR_LEN];
        struct cYAML *root = NULL, *global = NULL;
 
-       snprintf(err_str, sizeof(err_str), "\"out of memory\"");
-
-       rc = read_sysfs_file(modparam_path, "lnet_interfaces_max", val,
-                            1, LNET_MAX_STR_LEN);
-       if (rc) {
-               snprintf(err_str, sizeof(err_str),
-                        "\"cannot get max interfaces: %d\"", rc);
+       if (err) {
+               rc = err;
                goto out;
        }
 
-       max_intf = atoi(val);
-
        root = cYAML_create_object(NULL, NULL);
        if (root == NULL)
                goto out;
@@ -2698,68 +2820,17 @@ int lustre_lnet_show_max_intf(int seq_no, struct cYAML **show_rc,
        if (global == NULL)
                goto out;
 
-       if (cYAML_create_number(global, "max_intf",
-                               max_intf) == NULL)
+       if (cYAML_create_number(global, name,
+                               value) == NULL)
                goto out;
 
        if (show_rc == NULL)
                cYAML_print_tree(root);
 
-       snprintf(err_str, sizeof(err_str), "\"success\"");
-out:
-       if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR)
-               cYAML_free_tree(root);
-       else if (show_rc != NULL && *show_rc != NULL)
-               add_to_global(*show_rc, global, root);
-       else
-               *show_rc = root;
-
-       cYAML_build_error(rc, seq_no, SHOW_CMD, "global", err_str, err_rc);
-
-       return rc;
-}
-
-int lustre_lnet_show_discovery(int seq_no, struct cYAML **show_rc,
-                              struct cYAML **err_rc)
-{
-       int rc = LUSTRE_CFG_RC_OUT_OF_MEM;
-       char val[LNET_MAX_STR_LEN];
-       __u32 discovery;
-       char err_str[LNET_MAX_STR_LEN];
-       struct cYAML *root = NULL, *global = NULL;
-
-       snprintf(err_str, sizeof(err_str), "\"out of memory\"");
+       snprintf(err_str, err_len, "\"success\"");
 
-       rc = read_sysfs_file(modparam_path, "lnet_peer_discovery_disabled", val,
-                            1, sizeof(val));
-       if (rc) {
-               snprintf(err_str, sizeof(err_str),
-                        "\"cannot get discovery value: %d\"", rc);
-               goto out;
-       }
-
-       /*
-        * the sysfs parameter read indicates if discovery is disabled,
-        * but we report if discovery is enabled.
-        */
-       discovery = !atoi(val);
-
-       root = cYAML_create_object(NULL, NULL);
-       if (root == NULL)
-               goto out;
-
-       global = cYAML_create_object(root, "global");
-       if (global == NULL)
-               goto out;
-
-       if (cYAML_create_number(global, "discovery",
-                               discovery) == NULL)
-               goto out;
-
-       if (show_rc == NULL)
-               cYAML_print_tree(root);
+       rc = LUSTRE_CFG_RC_NO_ERR;
 
-       snprintf(err_str, sizeof(err_str), "\"success\"");
 out:
        if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR) {
                cYAML_free_tree(root);
@@ -2774,61 +2845,92 @@ out:
        return rc;
 }
 
-int lustre_lnet_show_numa_range(int seq_no, struct cYAML **show_rc,
-                               struct cYAML **err_rc)
+static int ioctl_show_global_values(int ioc, int seq_no, char *name,
+                                   struct cYAML **show_rc,
+                                   struct cYAML **err_rc)
 {
        struct lnet_ioctl_set_value data;
        int rc;
-       int l_errno;
+       int l_errno = 0;
        char err_str[LNET_MAX_STR_LEN];
-       struct cYAML *root = NULL, *global = NULL;
 
        snprintf(err_str, sizeof(err_str), "\"out of memory\"");
 
        LIBCFS_IOC_INIT_V2(data, sv_hdr);
 
-       rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_NUMA_RANGE, &data);
+       rc = l_ioctl(LNET_DEV_ID, ioc, &data);
        if (rc != 0) {
-               l_errno = errno;
+               l_errno = -errno;
                snprintf(err_str,
                         sizeof(err_str),
-                        "\"cannot get numa range: %s\"",
-                        strerror(l_errno));
-               rc = -l_errno;
-               goto out;
+                        "\"cannot get %s: %s\"",
+                        name, strerror(l_errno));
        }
 
-       rc = LUSTRE_CFG_RC_OUT_OF_MEM;
+       return build_global_yaml_entry(err_str, sizeof(err_str), seq_no, name,
+                                      data.sv_value, show_rc, err_rc, l_errno);
+}
 
-       root = cYAML_create_object(NULL, NULL);
-       if (root == NULL)
-               goto out;
+int lustre_lnet_show_max_intf(int seq_no, struct cYAML **show_rc,
+                             struct cYAML **err_rc)
+{
+       int rc = LUSTRE_CFG_RC_OUT_OF_MEM;
+       char val[LNET_MAX_STR_LEN];
+       int max_intf = -1, l_errno = 0;
+       char err_str[LNET_MAX_STR_LEN];
 
-       global = cYAML_create_object(root, "global");
-       if (global == NULL)
-               goto out;
+       snprintf(err_str, sizeof(err_str), "\"out of memory\"");
 
-       if (cYAML_create_number(global, "numa_range",
-                               data.sv_value) == NULL)
-               goto out;
+       rc = read_sysfs_file(modparam_path, "lnet_interfaces_max", val,
+                            1, sizeof(val));
+       if (rc) {
+               l_errno = -errno;
+               snprintf(err_str, sizeof(err_str),
+                        "\"cannot get max interfaces: %d\"", rc);
+       } else {
+               max_intf = atoi(val);
+       }
 
-       if (show_rc == NULL)
-               cYAML_print_tree(root);
+       return build_global_yaml_entry(err_str, sizeof(err_str), seq_no,
+                                      "max_intf", max_intf, show_rc,
+                                      err_rc, l_errno);
+}
 
-       snprintf(err_str, sizeof(err_str), "\"success\"");
-       rc = LUSTRE_CFG_RC_NO_ERR;
-out:
-       if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR) {
-               cYAML_free_tree(root);
-       } else if (show_rc != NULL && *show_rc != NULL) {
-               add_to_global(*show_rc, global, root);
+int lustre_lnet_show_discovery(int seq_no, struct cYAML **show_rc,
+                              struct cYAML **err_rc)
+{
+       int rc = LUSTRE_CFG_RC_OUT_OF_MEM;
+       char val[LNET_MAX_STR_LEN];
+       int discovery = -1, l_errno = 0;
+       char err_str[LNET_MAX_STR_LEN];
+
+       snprintf(err_str, sizeof(err_str), "\"out of memory\"");
+
+       rc = read_sysfs_file(modparam_path, "lnet_peer_discovery_disabled", val,
+                            1, sizeof(val));
+       if (rc) {
+               l_errno = -errno;
+               snprintf(err_str, sizeof(err_str),
+                        "\"cannot get discovery setting: %d\"", rc);
        } else {
-               *show_rc = root;
+               /*
+                * The kernel stores a discovery disabled value. User space
+                * shows whether discovery is enabled. So the value must be
+                * inverted.
+                */
+               discovery = !atoi(val);
        }
 
-       cYAML_build_error(rc, seq_no, SHOW_CMD, "global", err_str, err_rc);
+       return build_global_yaml_entry(err_str, sizeof(err_str), seq_no,
+                                      "discovery", discovery, show_rc,
+                                      err_rc, l_errno);
+}
 
-       return rc;
+int lustre_lnet_show_numa_range(int seq_no, struct cYAML **show_rc,
+                               struct cYAML **err_rc)
+{
+       return ioctl_show_global_values(IOC_LIBCFS_GET_NUMA_RANGE, seq_no,
+                                       "numa_range", show_rc, err_rc);
 }
 
 int lustre_lnet_show_stats(int seq_no, struct cYAML **show_rc,
@@ -3590,6 +3692,41 @@ static int handle_yaml_show_stats(struct cYAML *tree, struct cYAML **show_rc,
                                      show_rc, err_rc);
 }
 
+static int handle_yaml_config_numa(struct cYAML *tree, struct cYAML **show_rc,
+                                 struct cYAML **err_rc)
+{
+       struct cYAML *seq_no, *range;
+
+       seq_no = cYAML_get_object_item(tree, "seq_no");
+       range = cYAML_get_object_item(tree, "range");
+
+       return lustre_lnet_config_numa_range(range ? range->cy_valueint : -1,
+                                            seq_no ? seq_no->cy_valueint : -1,
+                                            err_rc);
+}
+
+static int handle_yaml_del_numa(struct cYAML *tree, struct cYAML **show_rc,
+                              struct cYAML **err_rc)
+{
+       struct cYAML *seq_no;
+
+       seq_no = cYAML_get_object_item(tree, "seq_no");
+
+       return lustre_lnet_config_numa_range(0, seq_no ? seq_no->cy_valueint : -1,
+                                            err_rc);
+}
+
+static int handle_yaml_show_numa(struct cYAML *tree, struct cYAML **show_rc,
+                               struct cYAML **err_rc)
+{
+       struct cYAML *seq_no;
+
+       seq_no = cYAML_get_object_item(tree, "seq_no");
+
+       return lustre_lnet_show_numa_range(seq_no ? seq_no->cy_valueint : -1,
+                                          show_rc, err_rc);
+}
+
 static int handle_yaml_config_global_settings(struct cYAML *tree,
                                              struct cYAML **show_rc,
                                              struct cYAML **err_rc)
@@ -3699,6 +3836,21 @@ static int handle_yaml_ping(struct cYAML *tree, struct cYAML **show_rc,
                                    show_rc, err_rc);
 }
 
+static int handle_yaml_discover(struct cYAML *tree, struct cYAML **show_rc,
+                               struct cYAML **err_rc)
+{
+       struct cYAML *seq_no, *nid, *force;
+
+       seq_no = cYAML_get_object_item(tree, "seq_no");
+       nid = cYAML_get_object_item(tree, "primary nid");
+       force = cYAML_get_object_item(tree, "force");
+
+       return lustre_lnet_discover_nid((nid) ? nid->cy_valuestring : NULL,
+                                       (force) ? force->cy_valueint : 0,
+                                       (seq_no) ? seq_no->cy_valueint : -1,
+                                       show_rc, err_rc);
+}
+
 static int handle_yaml_no_op()
 {
        return LUSTRE_CFG_RC_NO_ERR;
@@ -3718,7 +3870,9 @@ static struct lookup_cmd_hdlr_tbl lookup_config_tbl[] = {
        { .name = "buffers",    .cb = handle_yaml_config_buffers },
        { .name = "statistics", .cb = handle_yaml_no_op },
        { .name = "global",     .cb = handle_yaml_config_global_settings},
+       { .name = "numa",       .cb = handle_yaml_config_numa },
        { .name = "ping",       .cb = handle_yaml_no_op },
+       { .name = "discover",   .cb = handle_yaml_no_op },
        { .name = NULL } };
 
 static struct lookup_cmd_hdlr_tbl lookup_del_tbl[] = {
@@ -3730,7 +3884,9 @@ static struct lookup_cmd_hdlr_tbl lookup_del_tbl[] = {
        { .name = "buffers",    .cb = handle_yaml_no_op },
        { .name = "statistics", .cb = handle_yaml_no_op },
        { .name = "global",     .cb = handle_yaml_del_global_settings},
+       { .name = "numa",       .cb = handle_yaml_del_numa },
        { .name = "ping",       .cb = handle_yaml_no_op },
+       { .name = "discover",   .cb = handle_yaml_no_op },
        { .name = NULL } };
 
 static struct lookup_cmd_hdlr_tbl lookup_show_tbl[] = {
@@ -3742,7 +3898,9 @@ static struct lookup_cmd_hdlr_tbl lookup_show_tbl[] = {
        { .name = "buffers",    .cb = handle_yaml_show_routing },
        { .name = "statistics", .cb = handle_yaml_show_stats },
        { .name = "global",     .cb = handle_yaml_show_global_settings},
+       { .name = "numa",       .cb = handle_yaml_show_numa },
        { .name = "ping",       .cb = handle_yaml_no_op },
+       { .name = "discover",   .cb = handle_yaml_no_op },
        { .name = NULL } };
 
 static struct lookup_cmd_hdlr_tbl lookup_exec_tbl[] = {
@@ -3754,7 +3912,9 @@ static struct lookup_cmd_hdlr_tbl lookup_exec_tbl[] = {
        { .name = "buffers",    .cb = handle_yaml_no_op },
        { .name = "statistics", .cb = handle_yaml_no_op },
        { .name = "global",     .cb = handle_yaml_no_op },
+       { .name = "numa",       .cb = handle_yaml_no_op },
        { .name = "ping",       .cb = handle_yaml_ping },
+       { .name = "discover",   .cb = handle_yaml_discover },
        { .name = NULL } };
 
 static cmd_handler_t lookup_fn(char *key,