#define IOC_LIBCFS_GET_LOCAL_NI_MSG_STATS _IOWR(IOC_LIBCFS_TYPE, 101, IOCTL_CONFIG_SIZE)
#define IOC_LIBCFS_SET_HEALHV _IOWR(IOC_LIBCFS_TYPE, 102, IOCTL_CONFIG_SIZE)
#define IOC_LIBCFS_GET_LOCAL_HSTATS _IOWR(IOC_LIBCFS_TYPE, 103, IOCTL_CONFIG_SIZE)
-#define IOC_LIBCFS_MAX_NR 103
+#define IOC_LIBCFS_GET_RECOVERY_QUEUE _IOWR(IOC_LIBCFS_TYPE, 104, IOCTL_CONFIG_SIZE)
+#define IOC_LIBCFS_MAX_NR 104
extern int libcfs_ioctl_data_adjust(struct libcfs_ioctl_data *data);
#define MAX_NUM_SHOW_ENTRIES 32
#define LNET_MAX_STR_LEN 128
#define LNET_MAX_SHOW_NUM_CPT 128
+#define LNET_MAX_SHOW_NUM_NID 128
#define LNET_UNDEFINED_HOPS ((__u32) -1)
/*
lnet_nid_t rh_nid;
};
+struct lnet_ioctl_recovery_list {
+ struct libcfs_ioctl_hdr rlst_hdr;
+ enum lnet_health_type rlst_type;
+ int rlst_num_nids;
+ lnet_nid_t rlst_nid_array[LNET_MAX_SHOW_NUM_NID];
+};
+
struct lnet_ioctl_set_value {
struct libcfs_ioctl_hdr sv_hdr;
__u32 sv_value;
return rc;
}
+static int
+lnet_get_local_ni_recovery_list(struct lnet_ioctl_recovery_list *list)
+{
+ struct lnet_ni *ni;
+ int i = 0;
+
+ lnet_net_lock(LNET_LOCK_EX);
+ list_for_each_entry(ni, &the_lnet.ln_mt_localNIRecovq, ni_recovery) {
+ list->rlst_nid_array[i] = ni->ni_nid;
+ i++;
+ if (i >= LNET_MAX_SHOW_NUM_NID)
+ break;
+ }
+ lnet_net_unlock(LNET_LOCK_EX);
+ list->rlst_num_nids = i;
+
+ return 0;
+}
+
+static int
+lnet_get_peer_ni_recovery_list(struct lnet_ioctl_recovery_list *list)
+{
+ struct lnet_peer_ni *lpni;
+ int i = 0;
+
+ lnet_net_lock(LNET_LOCK_EX);
+ list_for_each_entry(lpni, &the_lnet.ln_mt_peerNIRecovq, lpni_recovery) {
+ list->rlst_nid_array[i] = lpni->lpni_nid;
+ i++;
+ if (i >= LNET_MAX_SHOW_NUM_NID)
+ break;
+ }
+ lnet_net_unlock(LNET_LOCK_EX);
+ list->rlst_num_nids = i;
+
+ return 0;
+}
+
/**
* LNet ioctl handler.
*
return rc;
}
+ case IOC_LIBCFS_GET_RECOVERY_QUEUE: {
+ struct lnet_ioctl_recovery_list *list = arg;
+ if (list->rlst_hdr.ioc_len < sizeof(*list))
+ return -EINVAL;
+
+ mutex_lock(&the_lnet.ln_api_mutex);
+ if (list->rlst_type == LNET_HEALTH_TYPE_LOCAL_NI)
+ rc = lnet_get_local_ni_recovery_list(list);
+ else
+ rc = lnet_get_peer_ni_recovery_list(list);
+ mutex_unlock(&the_lnet.ln_api_mutex);
+ return rc;
+ }
+
case IOC_LIBCFS_ADD_PEER_NI: {
struct lnet_ioctl_peer_cfg *cfg = arg;
err_rc, l_errno);
}
+int show_recovery_queue(enum lnet_health_type type, char *name, int seq_no,
+ struct cYAML **show_rc, struct cYAML **err_rc)
+{
+ struct lnet_ioctl_recovery_list nid_list;
+ struct cYAML *root = NULL, *nids = NULL;
+ int rc, i;
+ char err_str[LNET_MAX_STR_LEN];
+
+ snprintf(err_str, sizeof(err_str), "failed to print recovery queue\n");
+
+ LIBCFS_IOC_INIT_V2(nid_list, rlst_hdr);
+ nid_list.rlst_type = type;
+
+ rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_RECOVERY_QUEUE, &nid_list);
+ if (rc) {
+ rc = errno;
+ goto out;
+ }
+
+ root = cYAML_create_object(NULL, NULL);
+ if (root == NULL)
+ goto out;
+
+ nids = cYAML_create_object(root, name);
+ if (nids == NULL)
+ goto out;
+
+ rc = -EINVAL;
+
+ for (i = 0; i < nid_list.rlst_num_nids; i++) {
+ char nidenum[LNET_MAX_STR_LEN];
+ snprintf(nidenum, sizeof(nidenum), "nid-%d", i);
+ if (!cYAML_create_string(nids, nidenum,
+ libcfs_nid2str(nid_list.rlst_nid_array[i])))
+ goto out;
+ }
+
+ snprintf(err_str, sizeof(err_str), "success\n");
+
+ rc = 0;
+
+out:
+ if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR) {
+ cYAML_free_tree(root);
+ } else if (show_rc != NULL && *show_rc != NULL) {
+ struct cYAML *show_node;
+ /* find the net node, if one doesn't exist
+ * then insert one. Otherwise add to the one there
+ */
+ show_node = cYAML_get_object_item(*show_rc, name);
+ if (show_node != NULL && cYAML_is_sequence(show_node)) {
+ cYAML_insert_child(show_node, nids);
+ free(nids);
+ free(root);
+ } else if (show_node == NULL) {
+ cYAML_insert_sibling((*show_rc)->cy_child,
+ nids);
+ free(root);
+ } else {
+ cYAML_free_tree(root);
+ }
+ } else {
+ *show_rc = root;
+ }
+
+ cYAML_build_error(rc, seq_no, SHOW_CMD, name, err_str, err_rc);
+
+ return rc;
+}
+
+int lustre_lnet_show_local_ni_recovq(int seq_no, struct cYAML **show_rc,
+ struct cYAML **err_rc)
+{
+ return show_recovery_queue(LNET_HEALTH_TYPE_LOCAL_NI, "local NI recovery",
+ seq_no, show_rc, err_rc);
+}
+
+int lustre_lnet_show_peer_ni_recovq(int seq_no, struct cYAML **show_rc,
+ struct cYAML **err_rc)
+{
+ return show_recovery_queue(LNET_HEALTH_TYPE_PEER_NI, "peer NI recovery",
+ seq_no, show_rc, err_rc);
+}
+
int lustre_lnet_show_max_intf(int seq_no, struct cYAML **show_rc,
struct cYAML **err_rc)
{
int lustre_lnet_show_retry_count(int seq_no, struct cYAML **show_rc,
struct cYAML **err_rc);
+int lustre_lnet_show_local_ni_recovq(int seq_no, struct cYAML **show_rc,
+ struct cYAML **err_rc);
+
+int lustre_lnet_show_peer_ni_recovq(int seq_no, struct cYAML **show_rc,
+ struct cYAML **err_rc);
+
/*
* lustre_lnet_config_max_intf
* Sets the maximum number of interfaces per node. this tunable is
static int jt_show_routing(int argc, char **argv);
static int jt_show_stats(int argc, char **argv);
static int jt_show_peer(int argc, char **argv);
+static int jt_show_recovery(int argc, char **argv);
static int jt_show_global(int argc, char **argv);
static int jt_set_tiny(int argc, char **argv);
static int jt_set_small(int argc, char **argv);
static int jt_net(int argc, char **argv);
static int jt_routing(int argc, char **argv);
static int jt_set(int argc, char **argv);
+static int jt_debug(int argc, char **argv);
static int jt_stats(int argc, char **argv);
static int jt_global(int argc, char **argv);
static int jt_peers(int argc, char **argv);
{"import", jt_import, 0, "import FILE.yaml"},
{"export", jt_export, 0, "export FILE.yaml"},
{"stats", jt_stats, 0, "stats {show | help}"},
+ {"debug", jt_debug, 0, "debug recovery {local | peer}"},
{"global", jt_global, 0, "global {show | help}"},
{"peer", jt_peers, 0, "peer {add | del | show | help}"},
{"ping", jt_ping, 0, "ping nid,[nid,...]"},
{ 0, 0, 0, NULL }
};
+command_t debug_cmds[] = {
+ {"recovery", jt_show_recovery, 0, "list recovery queues\n"
+ "\t--local : list local recovery queue\n"
+ "\t--peer : list peer recovery queue\n"},
+ { 0, 0, 0, NULL }
+};
+
command_t global_cmds[] = {
{"show", jt_show_global, 0, "show global variables\n"},
{ 0, 0, 0, NULL }
return set_value_helper(argc, argv, lustre_lnet_config_peer_ni_healthv);
}
+static int jt_show_recovery(int argc, char **argv)
+{
+ int rc, opt;
+ struct cYAML *err_rc = NULL, *show_rc = NULL;
+
+ const char *const short_options = "lp";
+ static const struct option long_options[] = {
+ { .name = "local", .has_arg = no_argument, .val = 'l' },
+ { .name = "peer", .has_arg = no_argument, .val = 'p' },
+ { .name = NULL } };
+
+ rc = check_cmd(debug_cmds, "recovery", NULL, 0, argc, argv);
+ if (rc)
+ return rc;
+
+ while ((opt = getopt_long(argc, argv, short_options,
+ long_options, NULL)) != -1) {
+ switch (opt) {
+ case 'l':
+ rc = lustre_lnet_show_local_ni_recovq(-1, &show_rc, &err_rc);
+ break;
+ case 'p':
+ rc = lustre_lnet_show_peer_ni_recovq(-1, &show_rc, &err_rc);
+ break;
+ default:
+ return 0;
+ }
+ }
+
+ if (rc != LUSTRE_CFG_RC_NO_ERR)
+ cYAML_print_tree2file(stderr, err_rc);
+ else if (show_rc)
+ cYAML_print_tree(show_rc);
+
+ cYAML_free_tree(err_rc);
+ cYAML_free_tree(show_rc);
+
+ return rc;
+}
+
static int jt_show_net(int argc, char **argv)
{
char *network = NULL;
return Parser_execarg(argc - 1, &argv[1], stats_cmds);
}
+static int jt_debug(int argc, char **argv)
+{
+ int rc;
+
+ rc = check_cmd(debug_cmds, "recovery", NULL, 2, argc, argv);
+ if (rc)
+ return rc;
+
+ return Parser_execarg(argc - 1, &argv[1], debug_cmds);
+}
+
static int jt_global(int argc, char **argv)
{
int rc;