void lnet_finalize(struct lnet_msg *msg, int rc);
void lnet_drop_message(struct lnet_ni *ni, int cpt, void *private,
- unsigned int nob);
+ unsigned int nob, __u32 msg_type);
void lnet_drop_delayed_msg_list(struct list_head *head, char *reason);
void lnet_recv_delayed_msg_list(struct list_head *head);
return false;
}
+void lnet_incr_stats(struct lnet_element_stats *stats, lnet_msg_type_t msg_type,
+ enum lnet_stats_type stats_type);
+
+__u32 lnet_sum_stats(struct lnet_element_stats *stats,
+ enum lnet_stats_type stats_type);
+
+void lnet_usr_translate_stats(struct lnet_ioctl_element_msg_stats *msg_stats,
+ struct lnet_element_stats *stats);
+
#endif
LNET_NI_STATE_DELETING
};
+enum lnet_stats_type {
+ LNET_STATS_TYPE_SEND = 0,
+ LNET_STATS_TYPE_RECV,
+ LNET_STATS_TYPE_DROP
+};
+
+struct lnet_comm_count {
+ atomic_t co_get_count;
+ atomic_t co_put_count;
+ atomic_t co_reply_count;
+ atomic_t co_ack_count;
+ atomic_t co_hello_count;
+};
+
struct lnet_element_stats {
- atomic_t send_count;
- atomic_t recv_count;
- atomic_t drop_count;
+ struct lnet_comm_count el_send_stats;
+ struct lnet_comm_count el_recv_stats;
+ struct lnet_comm_count el_drop_stats;
};
struct lnet_net {
#define IOC_LIBCFS_SET_NUMA_RANGE _IOWR(IOC_LIBCFS_TYPE, 98, IOCTL_CONFIG_SIZE)
#define IOC_LIBCFS_GET_NUMA_RANGE _IOWR(IOC_LIBCFS_TYPE, 99, IOCTL_CONFIG_SIZE)
#define IOC_LIBCFS_GET_PEER_LIST _IOWR(IOC_LIBCFS_TYPE, 100, IOCTL_CONFIG_SIZE)
-#define IOC_LIBCFS_MAX_NR 100
+#define IOC_LIBCFS_GET_LOCAL_NI_MSG_STATS _IOWR(IOC_LIBCFS_TYPE, 101, IOCTL_CONFIG_SIZE)
+#define IOC_LIBCFS_MAX_NR 101
extern int libcfs_ioctl_data_adjust(struct libcfs_ioctl_data *data);
memcpy(&tun->lt_cmn, &ni->ni_net->net_tunables, sizeof(tun->lt_cmn));
if (stats) {
- stats->iel_send_count = atomic_read(&ni->ni_stats.send_count);
- stats->iel_recv_count = atomic_read(&ni->ni_stats.recv_count);
+ stats->iel_send_count = lnet_sum_stats(&ni->ni_stats,
+ LNET_STATS_TYPE_SEND);
+ stats->iel_recv_count = lnet_sum_stats(&ni->ni_stats,
+ LNET_STATS_TYPE_RECV);
+ stats->iel_drop_count = lnet_sum_stats(&ni->ni_stats,
+ LNET_STATS_TYPE_DROP);
}
/*
return rc;
}
+int lnet_get_ni_stats(struct lnet_ioctl_element_msg_stats *msg_stats)
+{
+ struct lnet_ni *ni;
+ int cpt;
+ int rc = -ENOENT;
+
+ if (!msg_stats)
+ return -EINVAL;
+
+ cpt = lnet_net_lock_current();
+
+ ni = lnet_get_ni_idx_locked(msg_stats->im_idx);
+
+ if (ni) {
+ lnet_usr_translate_stats(msg_stats, &ni->ni_stats);
+ rc = 0;
+ }
+
+ lnet_net_unlock(cpt);
+
+ return rc;
+}
+
static int lnet_add_net_common(struct lnet_net *net,
struct lnet_ioctl_config_lnd_tunables *tun)
{
__u32 tun_size;
cfg_ni = arg;
+
/* get the tunables if they are available */
if (cfg_ni->lic_cfg_hdr.ioc_len <
- sizeof(*cfg_ni) + sizeof(*stats)+ sizeof(*tun))
+ sizeof(*cfg_ni) + sizeof(*stats) + sizeof(*tun))
return -EINVAL;
stats = (struct lnet_ioctl_element_stats *)
return rc;
}
+ case IOC_LIBCFS_GET_LOCAL_NI_MSG_STATS: {
+ struct lnet_ioctl_element_msg_stats *msg_stats = arg;
+
+ if (msg_stats->im_hdr.ioc_len != sizeof(*msg_stats))
+ return -EINVAL;
+
+ mutex_lock(&the_lnet.ln_api_mutex);
+ rc = lnet_get_ni_stats(msg_stats);
+ mutex_unlock(&the_lnet.ln_api_mutex);
+
+ return rc;
+ }
+
case IOC_LIBCFS_GET_NET: {
size_t total = sizeof(*config) +
sizeof(struct lnet_ioctl_net_config);
module_param(local_nid_dist_zero, int, 0444);
MODULE_PARM_DESC(local_nid_dist_zero, "Reserved");
+static inline struct lnet_comm_count *
+get_stats_counts(struct lnet_element_stats *stats,
+ enum lnet_stats_type stats_type)
+{
+ switch (stats_type) {
+ case LNET_STATS_TYPE_SEND:
+ return &stats->el_send_stats;
+ case LNET_STATS_TYPE_RECV:
+ return &stats->el_recv_stats;
+ case LNET_STATS_TYPE_DROP:
+ return &stats->el_drop_stats;
+ default:
+ CERROR("Unknown stats type\n");
+ }
+
+ return NULL;
+}
+
+void lnet_incr_stats(struct lnet_element_stats *stats, lnet_msg_type_t msg_type,
+ enum lnet_stats_type stats_type)
+{
+ struct lnet_comm_count *counts = get_stats_counts(stats, stats_type);
+ if (!counts)
+ return;
+
+ switch (msg_type) {
+ case LNET_MSG_ACK:
+ atomic_inc(&counts->co_ack_count);
+ break;
+ case LNET_MSG_PUT:
+ atomic_inc(&counts->co_put_count);
+ break;
+ case LNET_MSG_GET:
+ atomic_inc(&counts->co_get_count);
+ break;
+ case LNET_MSG_REPLY:
+ atomic_inc(&counts->co_reply_count);
+ break;
+ case LNET_MSG_HELLO:
+ atomic_inc(&counts->co_hello_count);
+ break;
+ default:
+ CERROR("There is a BUG in the code. Unknown message type\n");
+ break;
+ }
+}
+
+__u32 lnet_sum_stats(struct lnet_element_stats *stats,
+ enum lnet_stats_type stats_type)
+{
+ struct lnet_comm_count *counts = get_stats_counts(stats, stats_type);
+ if (!counts)
+ return 0;
+
+ return (atomic_read(&counts->co_ack_count) +
+ atomic_read(&counts->co_put_count) +
+ atomic_read(&counts->co_get_count) +
+ atomic_read(&counts->co_reply_count) +
+ atomic_read(&counts->co_hello_count));
+}
+
+static inline void assign_stats(struct lnet_ioctl_comm_count *msg_stats,
+ struct lnet_comm_count *counts)
+{
+ msg_stats->ico_get_count = atomic_read(&counts->co_get_count);
+ msg_stats->ico_put_count = atomic_read(&counts->co_put_count);
+ msg_stats->ico_reply_count = atomic_read(&counts->co_reply_count);
+ msg_stats->ico_ack_count = atomic_read(&counts->co_ack_count);
+ msg_stats->ico_hello_count = atomic_read(&counts->co_hello_count);
+}
+
+void lnet_usr_translate_stats(struct lnet_ioctl_element_msg_stats *msg_stats,
+ struct lnet_element_stats *stats)
+{
+ struct lnet_comm_count *counts;
+
+ LASSERT(msg_stats);
+ LASSERT(stats);
+
+ counts = get_stats_counts(stats, LNET_STATS_TYPE_SEND);
+ if (!counts)
+ return;
+ assign_stats(&msg_stats->im_send_stats, counts);
+
+ counts = get_stats_counts(stats, LNET_STATS_TYPE_RECV);
+ if (!counts)
+ return;
+ assign_stats(&msg_stats->im_recv_stats, counts);
+
+ counts = get_stats_counts(stats, LNET_STATS_TYPE_DROP);
+ if (!counts)
+ return;
+ assign_stats(&msg_stats->im_drop_stats, counts);
+}
+
int
lnet_fail_nid(lnet_nid_t nid, unsigned int threshold)
{
the_lnet.ln_counters[cpt]->drop_length += msg->msg_len;
lnet_net_unlock(cpt);
if (msg->msg_txpeer)
- atomic_inc(&msg->msg_txpeer->lpni_stats.drop_count);
+ lnet_incr_stats(&msg->msg_txpeer->lpni_stats,
+ msg->msg_type,
+ LNET_STATS_TYPE_DROP);
if (msg->msg_txni)
- atomic_inc(&msg->msg_txni->ni_stats.drop_count);
+ lnet_incr_stats(&msg->msg_txni->ni_stats,
+ msg->msg_type,
+ LNET_STATS_TYPE_DROP);
CNETERR("Dropping message for %s: peer not alive\n",
libcfs_id2str(msg->msg_target));
}
void
-lnet_drop_message(struct lnet_ni *ni, int cpt, void *private, unsigned int nob)
+lnet_drop_message(struct lnet_ni *ni, int cpt, void *private, unsigned int nob,
+ __u32 msg_type)
{
lnet_net_lock(cpt);
+ lnet_incr_stats(&ni->ni_stats, msg_type, LNET_STATS_TYPE_DROP);
the_lnet.ln_counters[cpt]->drop_count++;
the_lnet.ln_counters[cpt]->drop_length += nob;
lnet_net_unlock(cpt);
lnet_finalize(msg, rc);
drop:
- lnet_drop_message(ni, cpt, private, payload_length);
+ lnet_drop_message(ni, cpt, private, payload_length, type);
return 0;
}
EXPORT_SYMBOL(lnet_parse);
* until that's done */
lnet_drop_message(msg->msg_rxni, msg->msg_rx_cpt,
- msg->msg_private, msg->msg_len);
+ msg->msg_private, msg->msg_len,
+ msg->msg_type);
/*
* NB: message will not generate event because w/o attached MD,
* but we still should give error code so lnet_msg_decommit()
cpt = lnet_cpt_of_nid(peer_id.nid, ni);
lnet_net_lock(cpt);
+ lnet_incr_stats(&ni->ni_stats, LNET_MSG_GET, LNET_STATS_TYPE_DROP);
the_lnet.ln_counters[cpt]->drop_count++;
the_lnet.ln_counters[cpt]->drop_length += getmd->md_length;
lnet_net_unlock(cpt);
incr_stats:
if (msg->msg_txpeer)
- atomic_inc(&msg->msg_txpeer->lpni_stats.send_count);
+ lnet_incr_stats(&msg->msg_txpeer->lpni_stats,
+ msg->msg_type,
+ LNET_STATS_TYPE_SEND);
if (msg->msg_txni)
- atomic_inc(&msg->msg_txni->ni_stats.send_count);
+ lnet_incr_stats(&msg->msg_txni->ni_stats,
+ msg->msg_type,
+ LNET_STATS_TYPE_SEND);
out:
lnet_return_tx_credits_locked(msg);
msg->msg_tx_committed = 0;
incr_stats:
if (msg->msg_rxpeer)
- atomic_inc(&msg->msg_rxpeer->lpni_stats.recv_count);
+ lnet_incr_stats(&msg->msg_rxpeer->lpni_stats,
+ msg->msg_type,
+ LNET_STATS_TYPE_RECV);
if (msg->msg_rxni)
- atomic_inc(&msg->msg_rxni->ni_stats.recv_count);
+ lnet_incr_stats(&msg->msg_rxni->ni_stats,
+ msg->msg_type,
+ LNET_STATS_TYPE_RECV);
if (ev->type == LNET_EVENT_PUT || ev->type == LNET_EVENT_REPLY)
counters->recv_length += msg->msg_wanted;
}
}
- lnet_drop_message(ni, cpt, msg->msg_private, msg->msg_len);
+ lnet_drop_message(ni, cpt, msg->msg_private, msg->msg_len,
+ msg->msg_type);
lnet_finalize(msg, rc);
}
}
void __user *bulk)
{
struct lnet_ioctl_element_stats *lpni_stats;
+ struct lnet_ioctl_element_msg_stats *lpni_msg_stats;
struct lnet_peer_ni_credit_info *lpni_info;
struct lnet_peer_ni *lpni;
struct lnet_peer *lp;
goto out;
}
- size = sizeof(nid) + sizeof(*lpni_info) + sizeof(*lpni_stats);
+ size = sizeof(nid) + sizeof(*lpni_info) + sizeof(*lpni_stats)
+ + sizeof(*lpni_msg_stats);
size *= lp->lp_nnis;
if (size > *sizep) {
*sizep = size;
LIBCFS_ALLOC(lpni_stats, sizeof(*lpni_stats));
if (!lpni_stats)
goto out_free_info;
+ LIBCFS_ALLOC(lpni_msg_stats, sizeof(*lpni_msg_stats));
+ if (!lpni_msg_stats)
+ goto out_free_stats;
+
lpni = NULL;
rc = -EFAULT;
while ((lpni = lnet_get_next_peer_ni_locked(lp, NULL, lpni)) != NULL) {
nid = lpni->lpni_nid;
if (copy_to_user(bulk, &nid, sizeof(nid)))
- goto out_free_stats;
+ goto out_free_msg_stats;
bulk += sizeof(nid);
memset(lpni_info, 0, sizeof(*lpni_info));
lpni_info->cr_peer_min_tx_credits = lpni->lpni_mintxcredits;
lpni_info->cr_peer_tx_qnob = lpni->lpni_txqnob;
if (copy_to_user(bulk, lpni_info, sizeof(*lpni_info)))
- goto out_free_stats;
+ goto out_free_msg_stats;
bulk += sizeof(*lpni_info);
memset(lpni_stats, 0, sizeof(*lpni_stats));
- lpni_stats->iel_send_count =
- atomic_read(&lpni->lpni_stats.send_count);
- lpni_stats->iel_recv_count =
- atomic_read(&lpni->lpni_stats.recv_count);
- lpni_stats->iel_drop_count =
- atomic_read(&lpni->lpni_stats.drop_count);
+ lpni_stats->iel_send_count = lnet_sum_stats(&lpni->lpni_stats,
+ LNET_STATS_TYPE_SEND);
+ lpni_stats->iel_recv_count = lnet_sum_stats(&lpni->lpni_stats,
+ LNET_STATS_TYPE_RECV);
+ lpni_stats->iel_drop_count = lnet_sum_stats(&lpni->lpni_stats,
+ LNET_STATS_TYPE_DROP);
if (copy_to_user(bulk, lpni_stats, sizeof(*lpni_stats)))
- goto out_free_stats;
+ goto out_free_msg_stats;
bulk += sizeof(*lpni_stats);
+ lnet_usr_translate_stats(lpni_msg_stats, &lpni->lpni_stats);
+ if (copy_to_user(bulk, lpni_msg_stats, sizeof(*lpni_msg_stats)))
+ goto out_free_msg_stats;
+ bulk += sizeof(*lpni_msg_stats);
}
rc = 0;
+out_free_msg_stats:
+ LIBCFS_FREE(lpni_msg_stats, sizeof(*lpni_msg_stats));
out_free_stats:
LIBCFS_FREE(lpni_stats, sizeof(*lpni_stats));
out_free_info:
#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.
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)
{
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;
if (detail) {
char *limit;
+ int k;
statistics = cYAML_create_object(item, "statistics");
if (statistics == NULL)
== 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;
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;
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)
== 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;
+ }
+
}
}
"\t--if: physical interface (e.g. eth0)\n"},
{"show", jt_show_net, 0, "show networks\n"
"\t--net: net name (e.g. tcp0) to filter on\n"
- "\t--verbose: display detailed output per network\n"},
+ "\t--verbose: display detailed output per network."
+ "optional argument of 2 outputs more stats\n"},
{ 0, 0, 0, NULL }
};
"\t peer is deleted\n"},
{"show", jt_show_peer, 0, "show peer information\n"
"\t--nid: NID of peer to filter on.\n"
- "\t--verbose: Include extended statistics\n"},
+ "\t--verbose: display detailed output per peer."
+ "optional argument of 2 outputs more stats\n"},
{"list", jt_list_peer, 0, "list all peers\n"},
{ 0, 0, 0, NULL }
};
static int jt_show_net(int argc, char **argv)
{
char *network = NULL;
- int detail = 0, rc, opt;
+ int rc, opt;
struct cYAML *err_rc = NULL, *show_rc = NULL;
+ long int detail = 0;
const char *const short_options = "n:vh";
static const struct option long_options[] = {
{ .name = "net", .has_arg = required_argument, .val = 'n' },
- { .name = "verbose", .has_arg = no_argument, .val = 'v' },
+ { .name = "verbose", .has_arg = optional_argument, .val = 'v' },
{ .name = "help", .has_arg = no_argument, .val = 'h' },
{ .name = NULL } };
network = optarg;
break;
case 'v':
- detail = 1;
+ if ((!optarg) && (argv[optind] != NULL) &&
+ (argv[optind][0] != '-')) {
+ if (parse_long(argv[optind++], &detail) != 0)
+ detail = 1;
+ } else {
+ detail = 1;
+ }
break;
case 'h':
print_help(net_cmds, "net", "show");
}
}
- rc = lustre_lnet_show_net(network, detail, -1, &show_rc, &err_rc);
+ rc = lustre_lnet_show_net(network, (int) detail, -1, &show_rc, &err_rc);
if (rc != LUSTRE_CFG_RC_NO_ERR)
cYAML_print_tree2file(stderr, err_rc);
} else
f = stdout;
- rc = lustre_lnet_show_net(NULL, 1, -1, &show_rc, &err_rc);
+ rc = lustre_lnet_show_net(NULL, 2, -1, &show_rc, &err_rc);
if (rc != LUSTRE_CFG_RC_NO_ERR) {
cYAML_print_tree2file(stderr, err_rc);
cYAML_free_tree(err_rc);
err_rc = NULL;
}
- rc = lustre_lnet_show_peer(NULL, 1, -1, &show_rc, &err_rc);
+ rc = lustre_lnet_show_peer(NULL, 2, -1, &show_rc, &err_rc);
if (rc != LUSTRE_CFG_RC_NO_ERR) {
cYAML_print_tree2file(stderr, err_rc);
cYAML_free_tree(err_rc);
char *nid = NULL;
int rc, opt;
struct cYAML *err_rc = NULL, *show_rc = NULL;
- int detail = 0;
+ long int detail = 0;
- const char *const short_options = "n:vh";
+ const char *const short_options = "n:v::h";
const struct option long_options[] = {
{ "nid", 1, NULL, 'n' },
- { "verbose", 0, NULL, 'v' },
+ { "verbose", 2, NULL, 'v' },
{ "help", 0, NULL, 'h' },
{ NULL, 0, NULL, 0 },
};
nid = optarg;
break;
case 'v':
- detail = 1;
+ if ((!optarg) && (argv[optind] != NULL) &&
+ (argv[optind][0] != '-')) {
+ if (parse_long(argv[optind++], &detail) != 0)
+ detail = 1;
+ } else {
+ detail = 1;
+ }
break;
case 'h':
print_help(peer_cmds, "peer", "show");
}
}
- rc = lustre_lnet_show_peer(nid, detail, -1, &show_rc, &err_rc);
+ rc = lustre_lnet_show_peer(nid, (int) detail, -1, &show_rc, &err_rc);
if (rc != LUSTRE_CFG_RC_NO_ERR)
cYAML_print_tree2file(stderr, err_rc);