id = genradix_ptr_alloc(&plist->lgpl_list,
plist->lgpl_list_count++,
- GFP_ATOMIC);
+ GFP_KERNEL);
if (!id) {
NL_SET_ERR_MSG(extack,
"failed to allocate NID");
rc = libcfs_strid(id, strim(nid));
if (rc < 0) {
- NL_SET_ERR_MSG(extack, "invalid NID");
+ NL_SET_ERR_MSG(extack, "cannot parse NID");
GOTO(report_err, rc);
}
rc = 0;
return rc;
}
+static const struct ln_key_list ping_err_props_list = {
+ .lkl_maxattr = LNET_ERR_ATTR_MAX,
+ .lkl_list = {
+ [LNET_ERR_ATTR_HDR] = {
+ .lkp_value = "manage",
+ .lkp_key_format = LNKF_SEQUENCE | LNKF_MAPPING,
+ .lkp_data_type = NLA_NUL_STRING,
+ },
+ [LNET_ERR_ATTR_TYPE] = {
+ .lkp_value = "ping",
+ .lkp_data_type = NLA_STRING,
+ },
+ [LNET_ERR_ATTR_ERRNO] = {
+ .lkp_value = "errno",
+ .lkp_data_type = NLA_S16,
+ },
+ [LNET_ERR_ATTR_DESCR] = {
+ .lkp_value = "descr",
+ .lkp_data_type = NLA_STRING,
+ },
+ },
+};
+
static const struct ln_key_list ping_props_list = {
.lkl_maxattr = LNET_PING_ATTR_MAX,
.lkl_list = {
},
};
-static struct ln_key_list ping_peer_ni_list = {
+static const struct ln_key_list ping_peer_ni_list = {
.lkl_maxattr = LNET_PING_PEER_NI_ATTR_MAX,
.lkl_list = {
[LNET_PING_PEER_NI_ATTR_NID] = {
struct netlink_callback *cb)
{
struct lnet_genl_ping_list *plist = lnet_ping_dump_ctx(cb);
- struct genlmsghdr *gnlh = nlmsg_data(cb->nlh);
#ifdef HAVE_NL_PARSE_WITH_EXT_ACK
struct netlink_ext_ack *extack = NULL;
#endif
void *hdr = NULL;
id = genradix_ptr(&plist->lgpl_list, idx++);
- if (nid_is_lo0(&id->nid))
- continue;
rc = lnet_ping(id, &plist->lgpl_src_nid, plist->lgpl_timeout,
&peers, lnet_interfaces_max);
fail = genradix_ptr_alloc(&plist->lgpl_failed,
plist->lgpl_failed_count++,
- GFP_ATOMIC);
+ GFP_KERNEL);
if (!fail) {
NL_SET_ERR_MSG(extack,
"failed to allocate failed NID");
GOTO(send_error, rc);
}
+ memset(fail->lfp_msg, '\0', sizeof(fail->lfp_msg));
+ snprintf(fail->lfp_msg, sizeof(fail->lfp_msg),
+ "failed to ping %s",
+ libcfs_nidstr(&id->nid));
fail->lfp_id = *id;
fail->lfp_errno = rc;
goto cant_reach;
continue;
nid_attr = nla_nest_start(msg, count + 1);
- if (gnlh->version == 1)
+ if (id->pid == LNET_PID_LUSTRE)
idstr = libcfs_nidstr(&result->nid);
else
idstr = libcfs_idstr(result);
genradix_free(&peers.lgpl_list);
}
- for (i = 0; i < plist->lgpl_failed_count; i++) {
- struct lnet_fail_ping *fail;
- void *hdr;
-
- fail = genradix_ptr(&plist->lgpl_failed, i);
+ if (plist->lgpl_failed_count) {
+ int flags = NLM_F_CREATE | NLM_F_REPLACE | NLM_F_MULTI;
+ const struct ln_key_list *fail[] = {
+ &ping_err_props_list, NULL
+ };
- hdr = genlmsg_put(msg, portid, seq, &lnet_family,
- NLM_F_MULTI, LNET_CMD_PING);
- if (!hdr) {
- NL_SET_ERR_MSG(extack, "failed to send failed values");
- genlmsg_cancel(msg, hdr);
- GOTO(send_error, rc = -EMSGSIZE);
+ rc = lnet_genl_send_scalar_list(msg, portid, seq, &lnet_family,
+ flags, LNET_CMD_PING, fail);
+ if (rc < 0) {
+ NL_SET_ERR_MSG(extack,
+ "failed to send new key table");
+ GOTO(send_error, rc);
}
- if (i == 0)
- nla_put_string(msg, LNET_PING_ATTR_HDR, "");
+ for (i = 0; i < plist->lgpl_failed_count; i++) {
+ struct lnet_fail_ping *fail;
+ void *hdr;
- nla_put_string(msg, LNET_PING_ATTR_PRIMARY_NID,
- libcfs_nidstr(&fail->lfp_id.nid));
- nla_put_s16(msg, LNET_PING_ATTR_ERRNO, fail->lfp_errno);
- genlmsg_end(msg, hdr);
+ fail = genradix_ptr(&plist->lgpl_failed, i);
+
+ hdr = genlmsg_put(msg, portid, seq, &lnet_family,
+ NLM_F_MULTI, LNET_CMD_PING);
+ if (!hdr) {
+ NL_SET_ERR_MSG(extack,
+ "failed to send failed values");
+ genlmsg_cancel(msg, hdr);
+ GOTO(send_error, rc = -EMSGSIZE);
+ }
+
+ if (i == 0)
+ nla_put_string(msg, LNET_ERR_ATTR_HDR, "");
+
+ nla_put_string(msg, LNET_ERR_ATTR_TYPE, "\n");
+ nla_put_s16(msg, LNET_ERR_ATTR_ERRNO,
+ fail->lfp_errno);
+ nla_put_string(msg, LNET_ERR_ATTR_DESCR,
+ fail->lfp_msg);
+ genlmsg_end(msg, hdr);
+ }
}
+ genradix_free(&plist->lgpl_list);
rc = 0; /* don't treat it as an error */
plist->lgpl_index = idx;
.name = LNET_GENL_NAME,
.version = LNET_GENL_VERSION,
.module = THIS_MODULE,
+ .parallel_ops = true,
.netnsok = true,
.ops = lnet_genl_ops,
.n_ops = ARRAY_SIZE(lnet_genl_ops),
if (id->pid == LNET_PID_ANY)
id->pid = LNET_PID_LUSTRE;
- id_bytes += lnet_ping_sts_size(&id->nid) * n_ids;
+ id_bytes += n_ids * sizeof(struct lnet_nid);
pbuf = lnet_ping_buffer_alloc(id_bytes, GFP_NOFS);
if (!pbuf)
return -ENOMEM;
for (st = ping_iter_first(&pi, pbuf, &pid.nid);
st;
st = ping_iter_next(&pi, &pid.nid)) {
- id = genradix_ptr_alloc(&plist->lgpl_list, i++, GFP_ATOMIC);
+ id = genradix_ptr_alloc(&plist->lgpl_list, i++, GFP_KERNEL);
if (!id) {
rc = -ENOMEM;
goto fail_ping_buffer_decref;
int timeout = 1000;
int rc = 0, opt;
char *src_nidstr = NULL;
-
const char *const short_options = "hs:t:";
const struct option long_options[] = {
- { .name = "help", .has_arg = no_argument, .val = 'h' },
- { .name = "timeout", .has_arg = required_argument, .val = 't' },
- { .name = "source", .has_arg = required_argument, .val = 's' },
- { .name = NULL } };
+ { .name = "help", .has_arg = no_argument, .val = 'h' },
+ { .name = "timeout", .has_arg = required_argument, .val = 't' },
+ { .name = "source", .has_arg = required_argument, .val = 's' },
+ { .name = NULL }
+ };
while ((opt = getopt_long(argc, argv, short_options,
long_options, NULL)) != -1) {
}
}
+ rc = yaml_lnet_ping("ping", timeout, src_nidstr, optind, argc,
+ argv, NLM_F_DUMP);
+ if (rc <= 0) {
+ if (rc != -EOPNOTSUPP)
+ return rc;
+ }
+
for (; optind < argc; optind++)
rc = lustre_lnet_ping_nid(argv[optind], src_nidstr, timeout, -1,
&show_rc, &err_rc);