#include <string.h>
#include <sys/ioctl.h>
#include <sys/time.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
#include <time.h>
#include <linux/types.h>
#include <linux/lnet/lnetctl.h>
#include <linux/lnet/nidstr.h>
#include <linux/lnet/socklnd.h>
+#include <lnetconfig/liblnetconfig.h>
#include <lustre/lustreapi.h>
+#include <lustre_ioctl_old.h>
+
+#include "obdctl.h"
unsigned int libcfs_debug;
unsigned int libcfs_printk = D_CANTMASK;
static char *ioc_buf = local_buf;
/* Convert a string boolean to an int; "enable" -> 1 */
-int
+static int
lnet_parse_bool (int *b, char *str)
{
if (!strcasecmp(str, "no") ||
return -1;
}
-int
+static int
lnet_parse_port(int *port, char *str)
{
char *end;
return -1;
}
-#ifdef HAVE_GETHOSTBYNAME
-static struct hostent *
-ptl_gethostbyname(char *hname)
-{
- struct hostent *he;
-
- he = gethostbyname(hname);
- if (!he) {
- switch (h_errno) {
- case HOST_NOT_FOUND:
- case NO_ADDRESS:
- fprintf(stderr, "Unable to resolve hostname: %s\n",
- hname);
- break;
- default:
- fprintf(stderr, "gethostbyname error for %s: %s\n",
- hname, strerror(h_errno));
- break;
- }
- return NULL;
- }
- return he;
-}
-#endif
-
-int
+static int
lnet_parse_ipquad(__u32 *ipaddrp, char *str)
{
int a, b, c, d;
return -1;
}
-int
+static int
lnet_parse_ipaddr(__u32 *ipaddrp, char *str)
{
-#ifdef HAVE_GETHOSTBYNAME
- struct hostent *he;
-#endif
+ struct addrinfo *ai = NULL;
+ struct addrinfo *aip = NULL;
+ struct addrinfo hints;
+ int err = 0;
+ int rc = -1;
if (!strcmp(str, "_all_")) {
*ipaddrp = 0;
if (lnet_parse_ipquad(ipaddrp, str) == 0)
return 0;
-#ifdef HAVE_GETHOSTBYNAME
- if ((('a' <= str[0] && str[0] <= 'z') ||
- ('A' <= str[0] && str[0] <= 'Z')) &&
- (he = ptl_gethostbyname(str)) != NULL) {
- __u32 addr = *(__u32 *)he->h_addr;
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_INET;
- *ipaddrp = ntohl(addr); /* HOST byte order */
- return 0;
+ if (('a' <= str[0] && str[0] <= 'z') ||
+ ('A' <= str[0] && str[0] <= 'Z')) {
+ err = getaddrinfo(str, NULL, &hints, &ai);
+ if (err != 0) {
+ fprintf(stderr,
+ "failed to get addrinfo for %s: %s\n",
+ str, gai_strerror(err));
+ return -1;
+ }
+
+ for (aip = ai; aip; aip = aip->ai_next) {
+ if (aip->ai_family == AF_INET && aip->ai_addr) {
+ struct sockaddr_in *sin =
+ (void *)ai->ai_addr;
+
+ __u32 addr = (__u32)sin->sin_addr.s_addr;
+ *ipaddrp = ntohl(addr);
+ break;
+ }
+ }
+ /* FIXME: handle AF_INET6 */
+
+ if (!aip) {
+ fprintf(stderr, "failed to get IP address for %s\n",
+ str);
+ rc = -1;
+ goto out;
+ }
+
+ rc = 0;
+ goto out;
}
-#endif
- return -1;
+out:
+ if (ai != NULL)
+ freeaddrinfo(ai);
+ return rc;
}
-char *
+static char *
ptl_ipaddr_2_str(__u32 ipaddr, char *str, size_t strsize, int lookup)
{
-#ifdef HAVE_GETHOSTBYNAME
- __u32 net_ip;
- struct hostent *he;
+ struct sockaddr_in srcaddr;
if (lookup) {
- net_ip = htonl(ipaddr);
- he = gethostbyaddr(&net_ip, sizeof(net_ip), AF_INET);
- if (he) {
- snprintf(str, strsize, "%s", he->h_name);
- return str;
- }
+ memset(&srcaddr, 0, sizeof(srcaddr));
+ srcaddr.sin_family = AF_INET;
+ srcaddr.sin_addr.s_addr = (in_addr_t)htonl(ipaddr);
+
+ if (getnameinfo((struct sockaddr *)&srcaddr, sizeof(srcaddr),
+ str, strsize, NULL, 0, 0) == 0)
+ goto out;
}
-#endif
- sprintf(str, "%d.%d.%d.%d",
- (ipaddr >> 24) & 0xff, (ipaddr >> 16) & 0xff,
- (ipaddr >> 8) & 0xff, ipaddr & 0xff);
+ snprintf(str, strsize, "%d.%d.%d.%d",
+ (ipaddr >> 24) & 0xff, (ipaddr >> 16) & 0xff,
+ (ipaddr >> 8) & 0xff, ipaddr & 0xff);
+out:
return str;
}
-int
+static int
lnet_parse_time(time_t *t, char *str)
{
char *end;
return 0;
}
-int
-lnet_parse_nid(char *nid_str, struct lnet_process_id *id_ptr)
+static int
+lnet_parse_nid(char *nid_str, struct lnet_processid *id_ptr)
{
id_ptr->pid = LNET_PID_ANY;
- id_ptr->nid = libcfs_str2nid(nid_str);
- if (id_ptr->nid == LNET_NID_ANY) {
- fprintf(stderr, "Can't parse nid \"%s\"\n", nid_str);
+ if (libcfs_strnid(&id_ptr->nid, nid_str) < 0 ||
+ LNET_NID_IS_ANY(&id_ptr->nid)) {
+ fprintf(stderr, "Invalid NID argument \"%s\"\n", nid_str);
return -1;
}
int jt_ptl_network(int argc, char **argv)
{
struct libcfs_ioctl_data data;
- __u32 net = LNET_NIDNET(LNET_NID_ANY);
+ __u32 net = LNET_NET_ANY;
+ const char *msg = NULL;
int rc;
- if (argc != 2) {
- fprintf(stderr, "usage: %s <net>|up|down\n", argv[0]);
+ if (argc > 3) {
+ fprintf(stderr, "usage: %s <net>|up|down [-l]\n", argv[0]);
return -1;
}
if (!strcmp(argv[1], "unconfigure") || !strcmp(argv[1], "down")) {
+ rc = yaml_lnet_configure(0, &msg);
+ if (rc != -EOPNOTSUPP) {
+ switch (rc) {
+ case 0:
+ printf("LNET ready to unload\n");
+ break;
+ case -ENODEV:
+ case -EBUSY:
+ printf("%s\n", msg);
+ break;
+ default:
+ printf("LNET unconfigure error %u: %s\n",
+ -rc, msg ? msg : strerror(-rc));
+ break;
+ }
+ return rc;
+ }
+
LIBCFS_IOC_INIT(data);
rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_UNCONFIGURE, &data);
-
if (rc == 0) {
printf("LNET ready to unload\n");
return 0;
errno, strerror(errno));
return -1;
} else if (!strcmp(argv[1], "configure") || !strcmp(argv[1], "up")) {
+ int flags = NLM_F_CREATE;
+
+ if (argc == 3 && argv[2] && !strcmp(argv[2], "-l"))
+ flags |= NLM_F_REPLACE;
+
+ rc = yaml_lnet_configure(flags, &msg);
+ if (rc != -EOPNOTSUPP) {
+ switch (rc) {
+ case 0:
+ printf("LNET configured\n");
+ break;
+ default:
+ fprintf(stderr, "LNET configure error %u: %s\n",
+ -rc, msg);
+ break;
+ }
+ return rc;
+ }
+
LIBCFS_IOC_INIT(data);
rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_CONFIGURE, &data);
}
net = libcfs_str2net(argv[1]);
- if (net == LNET_NIDNET(LNET_NID_ANY)) {
+ if (net == LNET_NET_ANY) {
fprintf(stderr, "Can't parse net %s\n", argv[1]);
return -1;
}
return 0;
}
+#ifndef IOC_LIBCFS_GET_NI
+#define IOC_LIBCFS_GET_NI _IOWR('e', 50, IOCTL_LIBCFS_TYPE)
+#endif
+
int
jt_ptl_list_nids(int argc, char **argv)
{
- struct libcfs_ioctl_data data;
int all = 0, return_nid = 0;
- int count;
- int rc;
+ yaml_emitter_t request;
+ yaml_parser_t reply;
+ yaml_event_t event;
+ struct nl_sock *sk;
+ bool done = false;
+ int rc = 0;
all = (argc == 2) && (strcmp(argv[1], "all") == 0);
/* Hack to pass back value */
return 0;
}
+ sk = nl_socket_alloc();
+ if (!sk)
+ goto old_api;
+
+ /* Setup parser to receive Netlink packets */
+ rc = yaml_parser_initialize(&reply);
+ if (rc == 0) {
+ yaml_parser_log_error(&reply, stderr, NULL);
+ goto old_api;
+ }
+
+ rc = yaml_parser_set_input_netlink(&reply, sk, false);
+ if (rc == 0) {
+ yaml_parser_log_error(&reply, stderr, NULL);
+ yaml_parser_delete(&reply);
+ goto old_api;
+ }
+
+ /* Create Netlink emitter to send request to kernel */
+ rc = yaml_emitter_initialize(&request);
+ if (rc == 0) {
+ yaml_parser_log_error(&reply, stderr, NULL);
+ yaml_parser_delete(&reply);
+ goto old_api;
+ }
+
+ rc = yaml_emitter_set_output_netlink(&request, sk, LNET_GENL_NAME, 1,
+ LNET_CMD_NETS, NLM_F_DUMP);
+ if (rc == 0) {
+ yaml_emitter_log_error(&request, stderr);
+ yaml_emitter_delete(&request);
+ yaml_parser_delete(&reply);
+ goto old_api;
+ }
+
+ yaml_emitter_open(&request);
+ yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
+ rc = yaml_emitter_emit(&request, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ yaml_mapping_start_event_initialize(&event, NULL,
+ (yaml_char_t *)YAML_MAP_TAG,
+ 1, YAML_ANY_MAPPING_STYLE);
+ rc = yaml_emitter_emit(&request, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ yaml_scalar_event_initialize(&event, NULL,
+ (yaml_char_t *)YAML_STR_TAG,
+ (yaml_char_t *)"net",
+ strlen("net"), 1, 0,
+ YAML_PLAIN_SCALAR_STYLE);
+ rc = yaml_emitter_emit(&request, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ /* no net_id */
+ if (!g_net_set || g_net == LNET_NET_ANY) {
+ yaml_scalar_event_initialize(&event, NULL,
+ (yaml_char_t *)YAML_STR_TAG,
+ (yaml_char_t *)"",
+ strlen(""), 1, 0,
+ YAML_PLAIN_SCALAR_STYLE);
+ rc = yaml_emitter_emit(&request, &event);
+ if (rc == 0)
+ goto emitter_error;
+ } else {
+ char *net_id = libcfs_net2str(g_net);
+
+ yaml_sequence_start_event_initialize(&event, NULL,
+ (yaml_char_t *)YAML_SEQ_TAG,
+ 1, YAML_ANY_SEQUENCE_STYLE);
+ rc = yaml_emitter_emit(&request, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ yaml_mapping_start_event_initialize(&event, NULL,
+ (yaml_char_t *)YAML_MAP_TAG,
+ 1, YAML_ANY_MAPPING_STYLE);
+ rc = yaml_emitter_emit(&request, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ yaml_scalar_event_initialize(&event, NULL,
+ (yaml_char_t *)YAML_STR_TAG,
+ (yaml_char_t *)"net type",
+ strlen("net type"),
+ 1, 0, YAML_PLAIN_SCALAR_STYLE);
+ rc = yaml_emitter_emit(&request, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ yaml_scalar_event_initialize(&event, NULL,
+ (yaml_char_t *)YAML_STR_TAG,
+ (yaml_char_t *)net_id,
+ strlen(net_id), 1, 0,
+ YAML_PLAIN_SCALAR_STYLE);
+ rc = yaml_emitter_emit(&request, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ yaml_mapping_end_event_initialize(&event);
+ rc = yaml_emitter_emit(&request, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ yaml_sequence_end_event_initialize(&event);
+ rc = yaml_emitter_emit(&request, &event);
+ if (rc == 0)
+ goto emitter_error;
+ }
+ yaml_mapping_end_event_initialize(&event);
+ rc = yaml_emitter_emit(&request, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ yaml_document_end_event_initialize(&event, 0);
+ rc = yaml_emitter_emit(&request, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ rc = yaml_emitter_close(&request);
+emitter_error:
+ if (rc == 0) {
+ yaml_emitter_log_error(&request, stderr);
+ rc = -EINVAL;
+ }
+ yaml_emitter_delete(&request);
+
+ while (!done) {
+ rc = yaml_parser_parse(&reply, &event);
+ if (rc == 0)
+ break;
+
+ if (event.type == YAML_SCALAR_EVENT &&
+ strcmp((char *)event.data.scalar.value, "nid") == 0) {
+ char *tmp;
+
+ yaml_event_delete(&event);
+ rc = yaml_parser_parse(&reply, &event);
+ if (rc == 0) {
+ yaml_event_delete(&event);
+ break;
+ }
+
+ tmp = (char *)event.data.scalar.value;
+ if (all || strcmp(tmp, "0@lo") != 0) {
+ printf("%s\n", tmp);
+ if (return_nid) {
+ *(__u64 *)(argv[1]) = libcfs_str2nid(tmp);
+ return_nid--;
+ }
+ }
+ }
+ done = (event.type == YAML_STREAM_END_EVENT);
+ yaml_event_delete(&event);
+ }
+
+ if (rc == 0)
+ yaml_parser_log_error(&reply, stderr, NULL);
+ yaml_parser_delete(&reply);
+old_api: {
+#ifdef IOC_LIBCFS_GET_NI
+ int count;
+
+ if (sk)
+ nl_socket_free(sk);
+ if (rc == 1)
+ return 0;
+
for (count = 0;; count++) {
+ struct libcfs_ioctl_data data;
+
LIBCFS_IOC_INIT(data);
data.ioc_count = count;
rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_NI, &data);
}
}
- return 0;
+#else
+ rc = -1;
+#endif
+ }
+ return rc;
}
int
jt_ptl_which_nid(int argc, char **argv)
{
- struct libcfs_ioctl_data data;
+ struct lnet_nid best_nid = LNET_ANY_NID;
+ yaml_emitter_t request;
+ yaml_parser_t reply;
+ yaml_event_t event;
+ struct nl_sock *sk;
int best_dist = 0;
int best_order = 0;
- lnet_nid_t best_nid = LNET_NID_ANY;
- int dist;
- int order;
- lnet_nid_t nid;
+ bool done = false;
+ int dist = 0;
+ int order = 0;
char *nidstr;
int rc;
int i;
return 0;
}
+ /* Create Netlink emitter to send request to kernel */
+ sk = nl_socket_alloc();
+ if (!sk)
+ goto old_api;
+
+ /* Setup parser to recieve Netlink packets */
+ rc = yaml_parser_initialize(&reply);
+ if (rc == 0)
+ goto old_api;
+
+ rc = yaml_parser_set_input_netlink(&reply, sk, false);
+ if (rc == 0)
+ goto free_reply;
+
+ /* Create Netlink emitter to send request to kernel */
+ rc = yaml_emitter_initialize(&request);
+ if (rc == 0)
+ goto free_reply;
+
+ rc = yaml_emitter_set_output_netlink(&request, sk, LNET_GENL_NAME,
+ LNET_GENL_VERSION,
+ LNET_CMD_PEER_DIST, NLM_F_DUMP);
+ if (rc == 0)
+ goto emitter_error;
+
+ yaml_emitter_open(&request);
+ yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
+ rc = yaml_emitter_emit(&request, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ yaml_mapping_start_event_initialize(&event, NULL,
+ (yaml_char_t *)YAML_MAP_TAG,
+ 1, YAML_ANY_MAPPING_STYLE);
+ rc = yaml_emitter_emit(&request, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ yaml_scalar_event_initialize(&event, NULL,
+ (yaml_char_t *)YAML_STR_TAG,
+ (yaml_char_t *)"peer",
+ strlen("peer"), 1, 0,
+ YAML_PLAIN_SCALAR_STYLE);
+ rc = yaml_emitter_emit(&request, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ yaml_sequence_start_event_initialize(&event, NULL,
+ (yaml_char_t *)YAML_SEQ_TAG,
+ 1, YAML_BLOCK_SEQUENCE_STYLE);
+ rc = yaml_emitter_emit(&request, &event);
+ if (rc == 0)
+ goto emitter_error;
+
for (i = 1; i < argc; i++) {
+ struct lnet_nid nid;
+
nidstr = argv[i];
- nid = libcfs_str2nid(nidstr);
- if (nid == LNET_NID_ANY) {
+ if (strcmp(nidstr, "*") == 0)
+ nidstr = "<?>";
+
+ rc = libcfs_strnid(&nid, nidstr);
+ if (rc < 0 || nid_same(&nid, &LNET_ANY_NID)) {
+ fprintf(stderr, "Can't parse NID %s\n", nidstr);
+ return -1;
+ }
+
+ yaml_scalar_event_initialize(&event, NULL,
+ (yaml_char_t *)YAML_STR_TAG,
+ (yaml_char_t *)nidstr,
+ strlen(nidstr), 1, 0,
+ YAML_PLAIN_SCALAR_STYLE);
+ rc = yaml_emitter_emit(&request, &event);
+ if (rc == 0)
+ goto emitter_error;
+ }
+
+ yaml_sequence_end_event_initialize(&event);
+ rc = yaml_emitter_emit(&request, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ yaml_mapping_end_event_initialize(&event);
+ rc = yaml_emitter_emit(&request, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ yaml_document_end_event_initialize(&event, 0);
+ rc = yaml_emitter_emit(&request, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ rc = yaml_emitter_close(&request);
+emitter_error:
+ if (rc == 0) {
+ yaml_emitter_log_error(&request, stderr);
+ rc = -EINVAL;
+ }
+ yaml_emitter_delete(&request);
+
+ while (!done) {
+ rc = yaml_parser_parse(&reply, &event);
+ if (rc == 0)
+ break;
+
+ if (event.type != YAML_SCALAR_EVENT)
+ goto not_scalar;
+
+
+ if (strcmp((char *)event.data.scalar.value, "nid") == 0) {
+ yaml_event_delete(&event);
+ rc = yaml_parser_parse(&reply, &event);
+ if (rc == 0) {
+ yaml_event_delete(&event);
+ break;
+ }
+
+ nidstr = (char *)event.data.scalar.value;
+
+ if (nid_same(&best_nid, &LNET_ANY_NID) ||
+ dist < best_dist ||
+ (dist == best_dist && order < best_order)) {
+ best_dist = dist;
+ best_order = order;
+ libcfs_strnid(&best_nid, nidstr);
+ }
+ } else if (strcmp((char *)event.data.scalar.value,
+ "distance") == 0) {
+ yaml_event_delete(&event);
+ rc = yaml_parser_parse(&reply, &event);
+ if (rc == 0) {
+ yaml_event_delete(&event);
+ break;
+ }
+
+ dist = strtol((char *)event.data.scalar.value, NULL, 10);
+ } else if (strcmp((char *)event.data.scalar.value,
+ "order") == 0) {
+ yaml_event_delete(&event);
+ rc = yaml_parser_parse(&reply, &event);
+ if (rc == 0) {
+ yaml_event_delete(&event);
+ break;
+ }
+
+ order = strtol((char *)event.data.scalar.value, NULL, 10);
+ }
+not_scalar:
+ done = (event.type == YAML_STREAM_END_EVENT);
+ yaml_event_delete(&event);
+ }
+
+free_reply:
+ if (rc == 0) {
+ /* yaml_* functions return 0 for error */
+ const char *msg = yaml_parser_get_reader_error(&reply);
+
+ fprintf(stderr, "Unexpected distance: %s\n", msg);
+ rc = -1;
+ } else if (rc == 1) {
+ /* yaml_* functions return 1 for success */
+ rc = 0;
+ }
+
+ yaml_parser_delete(&reply);
+ nl_socket_free(sk);
+ goto finished;
+
+old_api:
+ for (i = 1; i < argc; i++) {
+ struct libcfs_ioctl_data data;
+ lnet_nid_t nid4;
+
+ nidstr = argv[i];
+ nid4 = libcfs_str2nid(nidstr);
+ if (nid4 == LNET_NID_ANY) {
fprintf(stderr, "Can't parse NID %s\n", nidstr);
return -1;
}
LIBCFS_IOC_INIT(data);
- data.ioc_nid = nid;
+ data.ioc_nid = nid4;
rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_LNET_DIST, &data);
if (rc != 0) {
return -1;
}
- if (best_nid == LNET_NID_ANY ||
+ if (nid_same(&best_nid, &LNET_ANY_NID) ||
dist < best_dist ||
(dist == best_dist && order < best_order)) {
best_dist = dist;
best_order = order;
- best_nid = nid;
+ lnet_nid4_to_nid(nid4, &best_nid);
}
}
-
- if (best_nid == LNET_NID_ANY) {
+finished:
+ if (nid_same(&best_nid, &LNET_ANY_NID)) {
fprintf(stderr, "No reachable NID\n");
return -1;
}
- printf("%s\n", libcfs_nid2str(best_nid));
+ printf("%s\n", libcfs_nidstr(&best_nid));
return 0;
}
return 0;
}
+#ifndef IOC_LIBCFS_PING_PEER
+#define IOC_LIBCFS_PING_PEER _IOWR('e', 62, IOCTL_LIBCFS_TYPE)
+#endif
+
int jt_ptl_ping(int argc, char **argv)
{
+ bool done = false, print = true;
int rc;
int timeout;
- struct lnet_process_id id;
- struct lnet_process_id ids[16];
- int maxids = sizeof(ids) / sizeof(ids[0]);
- struct libcfs_ioctl_data data;
+ struct lnet_processid id;
+ yaml_emitter_t request;
+ yaml_parser_t reply;
+ yaml_event_t event;
+ struct nl_sock *sk;
char *sep;
- int i;
if (argc < 2) {
fprintf(stderr, "usage: %s id [timeout (secs)]\n", argv[0]);
- return 0;
+ return -EINVAL;
}
sep = strchr(argv[1], '-');
if (!sep) {
rc = lnet_parse_nid(argv[1], &id);
if (rc != 0)
- return -1;
+ return -EINVAL;
} else {
char *end;
if (end != sep) { /* assuming '-' is part of hostname */
rc = lnet_parse_nid(argv[1], &id);
if (rc != 0)
- return -1;
+ return -EINVAL;
} else {
- id.nid = libcfs_str2nid(sep + 1);
-
- if (id.nid == LNET_NID_ANY) {
+ if (libcfs_strnid(&id.nid, (sep + 1)) < 0 ||
+ LNET_NID_IS_ANY(&id.nid)) {
fprintf(stderr,
- "Can't parse process id \"%s\"\n",
+ "Invalid PID argument \"%s\"\n",
argv[1]);
- return -1;
+ return -EINVAL;
}
}
}
if (timeout > 120 * 1000) {
fprintf(stderr, "Timeout %s is to large\n",
argv[2]);
- return -1;
+ return -EINVAL;
}
} else {
timeout = 1000; /* default 1 second timeout */
}
- LIBCFS_IOC_INIT(data);
- data.ioc_nid = id.nid;
- data.ioc_u32[0] = id.pid;
- data.ioc_u32[1] = timeout;
- data.ioc_plen1 = sizeof(ids);
- data.ioc_pbuf1 = (char *)ids;
+ /* Create Netlink emitter to send request to kernel */
+ sk = nl_socket_alloc();
+ if (!sk)
+ goto old_api;
+
+ /* Setup parser to recieve Netlink packets */
+ rc = yaml_parser_initialize(&reply);
+ if (rc == 0)
+ goto old_api;
+
+ rc = yaml_parser_set_input_netlink(&reply, sk, false);
+ if (rc == 0)
+ goto free_reply;
+
+ /* Create Netlink emitter to send request to kernel */
+ rc = yaml_emitter_initialize(&request);
+ if (rc == 0)
+ goto free_reply;
+
+ rc = yaml_emitter_set_output_netlink(&request, sk, LNET_GENL_NAME,
+ LNET_GENL_VERSION, LNET_CMD_PING,
+ NLM_F_DUMP);
+ if (rc == 0)
+ goto emitter_error;
+
+ yaml_emitter_open(&request);
+ yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
+ rc = yaml_emitter_emit(&request, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ yaml_mapping_start_event_initialize(&event, NULL,
+ (yaml_char_t *)YAML_MAP_TAG,
+ 1, YAML_ANY_MAPPING_STYLE);
+ rc = yaml_emitter_emit(&request, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ yaml_scalar_event_initialize(&event, NULL,
+ (yaml_char_t *)YAML_STR_TAG,
+ (yaml_char_t *)"ping",
+ strlen("ping"), 1, 0,
+ YAML_PLAIN_SCALAR_STYLE);
+ rc = yaml_emitter_emit(&request, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ yaml_mapping_start_event_initialize(&event, NULL,
+ (yaml_char_t *)YAML_MAP_TAG,
+ 1, YAML_ANY_MAPPING_STYLE);
+ rc = yaml_emitter_emit(&request, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ if (timeout != 1000) {
+ yaml_scalar_event_initialize(&event, NULL,
+ (yaml_char_t *)YAML_STR_TAG,
+ (yaml_char_t *)"timeout",
+ strlen("timeout"), 1, 0,
+ YAML_PLAIN_SCALAR_STYLE);
+ rc = yaml_emitter_emit(&request, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ yaml_scalar_event_initialize(&event, NULL,
+ (yaml_char_t *)YAML_INT_TAG,
+ (yaml_char_t *)argv[2],
+ strlen(argv[2]), 1, 0,
+ YAML_PLAIN_SCALAR_STYLE);
+ rc = yaml_emitter_emit(&request, &event);
+ if (rc == 0)
+ goto emitter_error;
+ }
+
+ yaml_scalar_event_initialize(&event, NULL,
+ (yaml_char_t *)YAML_STR_TAG,
+ (yaml_char_t *)"nids",
+ strlen("nids"), 1, 0,
+ YAML_PLAIN_SCALAR_STYLE);
+ rc = yaml_emitter_emit(&request, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ yaml_sequence_start_event_initialize(&event, NULL,
+ (yaml_char_t *)YAML_SEQ_TAG,
+ 1, YAML_FLOW_SEQUENCE_STYLE);
+ rc = yaml_emitter_emit(&request, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ /* convert NID to string, in case libcfs_str2nid() did name lookup */
+ yaml_scalar_event_initialize(&event, NULL,
+ (yaml_char_t *)YAML_STR_TAG,
+ (yaml_char_t *)libcfs_nidstr(&id.nid),
+ strlen(libcfs_nidstr(&id.nid)), 1, 0,
+ YAML_PLAIN_SCALAR_STYLE);
+ rc = yaml_emitter_emit(&request, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ yaml_sequence_end_event_initialize(&event);
+ rc = yaml_emitter_emit(&request, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ yaml_mapping_end_event_initialize(&event);
+ rc = yaml_emitter_emit(&request, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ yaml_mapping_end_event_initialize(&event);
+ rc = yaml_emitter_emit(&request, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ yaml_document_end_event_initialize(&event, 0);
+ rc = yaml_emitter_emit(&request, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ rc = yaml_emitter_close(&request);
+emitter_error:
+ if (rc == 0) {
+ yaml_emitter_log_error(&request, stderr);
+ rc = -EINVAL;
+ goto old_api;
+ }
+ yaml_emitter_delete(&request);
+
+ /* Now parse the reply results */
+ while (!done) {
+ rc = yaml_parser_parse(&reply, &event);
+ if (rc == 0)
+ break;
- rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_PING, &data);
+ if (event.type != YAML_SCALAR_EVENT)
+ goto skip;
+
+ if (strcmp((char *)event.data.scalar.value, "nid") == 0) {
+ yaml_event_delete(&event);
+ rc = yaml_parser_parse(&reply, &event);
+ if (rc == 0) {
+ yaml_event_delete(&event);
+ goto free_reply;
+ }
+ if (print) {
+ /* Print 0@lo. Its not sent */
+ printf("12345-0@lo\n");
+ print = false;
+ }
+ printf("%s\n", (char *)event.data.scalar.value);
+ } else if (strcmp((char *)event.data.scalar.value,
+ "errno") == 0) {
+ yaml_event_delete(&event);
+ rc = yaml_parser_parse(&reply, &event);
+ if (rc == 0) {
+ yaml_event_delete(&event);
+ goto free_reply;
+ }
+ rc = strtol((char *)event.data.scalar.value, NULL, 10);
+ fprintf(stdout, "failed to ping %s: %s\n",
+ argv[1], strerror(-rc));
+ break; /* "rc" is clobbered if loop is run again */
+ }
+skip:
+ done = (event.type == YAML_STREAM_END_EVENT);
+ yaml_event_delete(&event);
+ }
+free_reply:
+ if (rc == 0) {
+ /* yaml_* functions return 0 for error */
+ const char *msg = yaml_parser_get_reader_error(&reply);
+
+ rc = errno ? -errno : -EHOSTUNREACH;
+ if (strcmp(msg, "Unspecific failure") != 0) {
+ fprintf(stdout, "failed to ping %s: %s\n",
+ argv[1], msg);
+ } else {
+ fprintf(stdout, "failed to ping %s: %s\n",
+ argv[1], strerror(errno));
+ }
+ } else if (rc == 1) {
+ /* yaml_* functions return 1 for success */
+ rc = 0;
+ }
+ yaml_parser_delete(&reply);
+ nl_socket_free(sk);
+ return rc;
+old_api:
+#ifdef IOC_LIBCFS_PING_PEER
+ {
+ struct lnet_process_id ids[LNET_INTERFACES_MAX_DEFAULT];
+ int maxids = sizeof(ids) / sizeof(ids[0]);
+ struct lnet_ioctl_ping_data ping = { { 0 } };
+ int i;
+
+ if (sk)
+ nl_socket_free(sk);
+
+ LIBCFS_IOC_INIT_V2(ping, ping_hdr);
+ ping.ping_hdr.ioc_len = sizeof(ping);
+ ping.ping_id = lnet_pid_to_pid4(&id);
+ ping.ping_src = LNET_NID_ANY;
+ ping.op_param = timeout;
+ ping.ping_count = maxids;
+ ping.ping_buf = ids;
+
+ rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_PING_PEER, &ping);
if (rc != 0) {
- fprintf(stderr, "failed to ping %s: %s\n",
- id.pid == LNET_PID_ANY ?
- libcfs_nid2str(id.nid) : libcfs_id2str(id),
+ fprintf(stderr, "failed to ping %s: %s\n", argv[1],
strerror(errno));
- return -1;
+ return rc;
}
- for (i = 0; i < data.ioc_count && i < maxids; i++)
+ for (i = 0; i < ping.ping_count && i < maxids; i++)
printf("%s\n", libcfs_id2str(ids[i]));
- if (data.ioc_count > maxids)
- printf("%d out of %d ids listed\n", maxids, data.ioc_count);
-
- return 0;
+ if (ping.ping_count > maxids)
+ printf("%d out of %d ids listed\n", maxids, ping.ping_count);
+ }
+#else
+ rc = -ENOTTY;
+#endif
+ return rc;
}
int jt_ptl_mynid(int argc, char **argv)
return 0;
}
+static int ptl_yaml_route_display(yaml_parser_t *reply)
+{
+ char gw[LNET_MAX_STR_LEN], net[18];
+ bool done = false, alive = false;
+ int hops = -1, prio = -1;
+ yaml_event_t event;
+ int rc;
+
+ /* Now parse the reply results */
+ while (!done) {
+ char *value;
+
+ rc = yaml_parser_parse(reply, &event);
+ if (rc == 0)
+ break;
+
+ if (event.type == YAML_SEQUENCE_END_EVENT) {
+ printf("net %18s hops %d gw %32.128s %s pri %u\n",
+ net, hops, gw, alive ? "up" : "down",
+ prio);
+ memset(net, '\0', sizeof(net));
+ memset(gw, '\0', sizeof(gw));
+ prio = -1;
+ hops = -1;
+ }
+
+ if (event.type != YAML_SCALAR_EVENT)
+ goto skip;
+
+ value = (char *)event.data.scalar.value;
+ if (strcmp(value, "net") == 0) {
+ yaml_event_delete(&event);
+ rc = yaml_parser_parse(reply, &event);
+ if (rc == 0) {
+ yaml_event_delete(&event);
+ goto free_reply;
+ }
+
+ value = (char *)event.data.scalar.value;
+ strncpy(net, value, sizeof(net) - 1);
+ } else if (strcmp(value, "gateway") == 0) {
+ yaml_event_delete(&event);
+ rc = yaml_parser_parse(reply, &event);
+ if (rc == 0) {
+ yaml_event_delete(&event);
+ goto free_reply;
+ }
+
+ value = (char *)event.data.scalar.value;
+ strncpy(gw, value, sizeof(gw) - 1);
+ } else if (strcmp(value, "state") == 0) {
+ yaml_event_delete(&event);
+ rc = yaml_parser_parse(reply, &event);
+ if (rc == 0) {
+ yaml_event_delete(&event);
+ goto free_reply;
+ }
+
+ value = (char *)event.data.scalar.value;
+ if (strcmp(value, "up") == 0) {
+ alive = true;
+ } else if (strcmp(value, "down") == 0) {
+ alive = false;
+ }
+ } else if (strcmp(value, "hop") == 0) {
+ yaml_event_delete(&event);
+ rc = yaml_parser_parse(reply, &event);
+ if (rc == 0) {
+ yaml_event_delete(&event);
+ goto free_reply;
+ }
+
+ value = (char *)event.data.scalar.value;
+ hops = strtol(value, NULL, 10);
+ } else if (strcmp(value, "priority") == 0) {
+ yaml_event_delete(&event);
+ rc = yaml_parser_parse(reply, &event);
+ if (rc == 0) {
+ yaml_event_delete(&event);
+ goto free_reply;
+ }
+
+ value = (char *)event.data.scalar.value;
+ prio = strtol(value, NULL, 10);
+ }
+skip:
+ done = (event.type == YAML_STREAM_END_EVENT);
+ yaml_event_delete(&event);
+ }
+
+free_reply:
+ return rc;
+}
+
+static int ptl_yaml_route(char *nw, char *gws, int hops, int prio, bool enable,
+ time_t notify_time, int flags, int version)
+{
+ struct nl_sock *sk = NULL;
+ const char *msg = NULL;
+ yaml_emitter_t output;
+ yaml_parser_t reply;
+ yaml_event_t event;
+ int rc;
+
+ sk = nl_socket_alloc();
+ if (!sk)
+ return -EOPNOTSUPP;
+
+ /* Setup parser to receive Netlink packets */
+ rc = yaml_parser_initialize(&reply);
+ if (rc == 0) {
+ nl_socket_free(sk);
+ return -EOPNOTSUPP;
+ }
+
+ rc = yaml_parser_set_input_netlink(&reply, sk, false);
+ if (rc == 0) {
+ msg = yaml_parser_get_reader_error(&reply);
+ goto free_reply;
+ }
+
+ /* Create Netlink emitter to send request to kernel */
+ rc = yaml_emitter_initialize(&output);
+ if (rc == 0) {
+ msg = "failed to initialize emitter";
+ goto free_reply;
+ }
+
+ rc = yaml_emitter_set_output_netlink(&output, sk, LNET_GENL_NAME,
+ version, LNET_CMD_ROUTES, flags);
+ if (rc == 0)
+ goto emitter_error;
+
+ yaml_emitter_open(&output);
+ yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
+ rc = yaml_emitter_emit(&output, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ yaml_mapping_start_event_initialize(&event, NULL,
+ (yaml_char_t *)YAML_MAP_TAG,
+ 1, YAML_ANY_MAPPING_STYLE);
+ rc = yaml_emitter_emit(&output, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ yaml_scalar_event_initialize(&event, NULL,
+ (yaml_char_t *)YAML_STR_TAG,
+ (yaml_char_t *)"route",
+ strlen("route"), 1, 0,
+ YAML_PLAIN_SCALAR_STYLE);
+ rc = yaml_emitter_emit(&output, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ if (nw || gws) {
+ yaml_sequence_start_event_initialize(&event, NULL,
+ (yaml_char_t *)YAML_SEQ_TAG,
+ 1,
+ YAML_BLOCK_SEQUENCE_STYLE);
+ rc = yaml_emitter_emit(&output, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ yaml_mapping_start_event_initialize(&event, NULL,
+ (yaml_char_t *)YAML_MAP_TAG, 1,
+ YAML_BLOCK_MAPPING_STYLE);
+ rc = yaml_emitter_emit(&output, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ if (nw) {
+ yaml_scalar_event_initialize(&event, NULL,
+ (yaml_char_t *)YAML_STR_TAG,
+ (yaml_char_t *)"net",
+ strlen("net"), 1, 0,
+ YAML_PLAIN_SCALAR_STYLE);
+ rc = yaml_emitter_emit(&output, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ yaml_scalar_event_initialize(&event, NULL,
+ (yaml_char_t *)YAML_STR_TAG,
+ (yaml_char_t *)nw,
+ strlen(nw), 1, 0,
+ YAML_PLAIN_SCALAR_STYLE);
+ rc = yaml_emitter_emit(&output, &event);
+ if (rc == 0)
+ goto emitter_error;
+ }
+
+ if (gws) {
+ yaml_scalar_event_initialize(&event, NULL,
+ (yaml_char_t *)YAML_STR_TAG,
+ (yaml_char_t *)"gateway",
+ strlen("gateway"), 1, 0,
+ YAML_PLAIN_SCALAR_STYLE);
+ rc = yaml_emitter_emit(&output, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ yaml_scalar_event_initialize(&event, NULL,
+ (yaml_char_t *)YAML_STR_TAG,
+ (yaml_char_t *)gws,
+ strlen(gws), 1, 0,
+ YAML_PLAIN_SCALAR_STYLE);
+ rc = yaml_emitter_emit(&output, &event);
+ if (rc == 0)
+ goto emitter_error;
+ }
+
+ if (notify_time) {
+ char when[INT_STRING_LEN];
+
+ yaml_scalar_event_initialize(&event, NULL,
+ (yaml_char_t *)YAML_STR_TAG,
+ (yaml_char_t *)"notify_time",
+ strlen("notify_time"), 1, 0,
+ YAML_PLAIN_SCALAR_STYLE);
+ rc = yaml_emitter_emit(&output, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ snprintf(when, sizeof(when), "%ld", notify_time);
+ yaml_scalar_event_initialize(&event, NULL,
+ (yaml_char_t *)YAML_INT_TAG,
+ (yaml_char_t *)when,
+ strlen(when), 1, 0,
+ YAML_PLAIN_SCALAR_STYLE);
+ rc = yaml_emitter_emit(&output, &event);
+ if (rc == 0)
+ goto emitter_error;
+ }
+
+ yaml_scalar_event_initialize(&event, NULL,
+ (yaml_char_t *)YAML_STR_TAG,
+ (yaml_char_t *)"state",
+ strlen("state"), 1, 0,
+ YAML_PLAIN_SCALAR_STYLE);
+ rc = yaml_emitter_emit(&output, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ if (enable)
+ yaml_scalar_event_initialize(&event, NULL,
+ (yaml_char_t *)YAML_STR_TAG,
+ (yaml_char_t *)"up",
+ strlen("up"), 1, 0,
+ YAML_PLAIN_SCALAR_STYLE);
+ else
+ yaml_scalar_event_initialize(&event, NULL,
+ (yaml_char_t *)YAML_STR_TAG,
+ (yaml_char_t *)"down",
+ strlen("down"), 1, 0,
+ YAML_PLAIN_SCALAR_STYLE);
+
+ rc = yaml_emitter_emit(&output, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ yaml_mapping_end_event_initialize(&event);
+ rc = yaml_emitter_emit(&output, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ yaml_sequence_end_event_initialize(&event);
+ rc = yaml_emitter_emit(&output, &event);
+ if (rc == 0)
+ goto emitter_error;
+ } else {
+ yaml_scalar_event_initialize(&event, NULL,
+ (yaml_char_t *)YAML_STR_TAG,
+ (yaml_char_t *)"",
+ strlen(""), 1, 0,
+ YAML_PLAIN_SCALAR_STYLE);
+ rc = yaml_emitter_emit(&output, &event);
+ if (rc == 0)
+ goto emitter_error;
+ }
+
+ yaml_mapping_end_event_initialize(&event);
+ rc = yaml_emitter_emit(&output, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ yaml_document_end_event_initialize(&event, 0);
+ rc = yaml_emitter_emit(&output, &event);
+ if (rc == 0)
+ goto emitter_error;
+
+ rc = yaml_emitter_close(&output);
+emitter_error:
+ if (rc == 0) {
+ yaml_emitter_log_error(&output, stderr);
+ rc = -EINVAL;
+ } else {
+ if (flags != NLM_F_DUMP) {
+ yaml_document_t errmsg;
+
+ rc = yaml_parser_load(&reply, &errmsg);
+ if (rc == 1) {
+ yaml_emitter_t debug;
+
+ rc = yaml_emitter_initialize(&debug);
+ if (rc == 1) {
+ yaml_emitter_set_indent(&debug,
+ LNET_DEFAULT_INDENT);
+ yaml_emitter_set_output_file(&debug,
+ stdout);
+ rc = yaml_emitter_dump(&debug,
+ &errmsg);
+ } else if (rc == 0) {
+ yaml_emitter_log_error(&debug, stderr);
+ rc = -EINVAL;
+ }
+ yaml_emitter_delete(&debug);
+ }
+ yaml_document_delete(&errmsg);
+ } else {
+ rc = ptl_yaml_route_display(&reply);
+ }
+ if (rc == 0)
+ msg = yaml_parser_get_reader_error(&reply);
+ }
+ yaml_emitter_delete(&output);
+free_reply:
+ if (msg)
+ fprintf(stdout, "%s\n", msg);
+ yaml_parser_delete(&reply);
+ nl_socket_free(sk);
+
+ return rc == 1 ? 0 : rc;
+}
+
int
jt_ptl_add_route(int argc, char **argv)
{
}
}
+ rc = ptl_yaml_route(libcfs_net2str(g_net), argv[1], hops,
+ priority, false, 0, NLM_F_CREATE, LNET_GENL_VERSION);
+ if (rc <= 0) {
+ if (rc == -EOPNOTSUPP)
+ goto old_api;
+ return rc;
+ }
+old_api:
LIBCFS_IOC_INIT_V2(data, cfg_hdr);
data.cfg_net = g_net;
data.cfg_config_u.cfg_route.rtr_hop = hops;
return -1;
}
+ rc = ptl_yaml_route(g_net_set ? libcfs_net2str(g_net) : NULL, argv[1],
+ -1, -1, false, 0, 0, LNET_GENL_VERSION);
+ if (rc <= 0) {
+ if (rc == -EOPNOTSUPP)
+ goto old_api;
+ return rc;
+ }
+old_api:
LIBCFS_IOC_INIT_V2(data, cfg_hdr);
- data.cfg_net = g_net_set ? g_net : LNET_NIDNET(LNET_NID_ANY);
+ data.cfg_net = g_net_set ? g_net : LNET_NET_ANY;
data.cfg_nid = nid;
rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_DEL_ROUTE, &data);
return -1;
}
+ rc = ptl_yaml_route(g_net_set ? libcfs_net2str(g_net) : NULL, argv[1],
+ -1, -1, enable, when, NLM_F_REPLACE, LNET_GENL_VERSION);
+ if (rc <= 0) {
+ if (rc == -EOPNOTSUPP)
+ goto old_api;
+ return rc;
+ }
+old_api:
LIBCFS_IOC_INIT(data);
data.ioc_nid = nid;
data.ioc_flags = enable;
int index;
__u32 net;
lnet_nid_t nid;
- unsigned int hops;
+ int hops;
int alive;
unsigned int pri;
+ rc = ptl_yaml_route(NULL, NULL, -1, -1, false, 0, NLM_F_DUMP,
+ LNET_GENL_VERSION);
+ if (rc <= 0) {
+ if (rc == -EOPNOTSUPP)
+ goto old_api;
+ return rc;
+ }
+old_api:
for (index = 0; ; index++) {
LIBCFS_IOC_INIT_V2(data, cfg_hdr);
data.cfg_count = index;
alive = data.cfg_config_u.cfg_route.rtr_flags & LNET_RT_ALIVE;
pri = data.cfg_config_u.cfg_route.rtr_priority;
- printf("net %18s hops %u gw %32s %s pri %u\n",
+ printf("net %18s hops %d gw %32s %s pri %u\n",
libcfs_net2str(net), hops,
libcfs_nid2str(nid), alive ? "up" : "down", pri);
}
/* NB: can't support range ipaddress except * and *@net */
if (strlen(str) > 2 && str[0] == '*' && str[1] == '@') {
net = libcfs_str2net(str + 2);
- if (net == LNET_NIDNET(LNET_NID_ANY))
+ if (net == LNET_NET_ANY)
goto failed;
nid = LNET_MKNID(net, LNET_NIDADDR(LNET_NID_ANY));
optstr = opc == LNET_CTL_DROP_ADD ? "s:d:o:r:i:p:m:e:nx" : "s:d:o:r:l:p:m:";
memset(&attr, 0, sizeof(attr));
while (1) {
- char c = getopt_long(argc, argv, optstr, opts, NULL);
+ int c = getopt_long(argc, argv, optstr, opts, NULL);
if (c == -1)
break;
memset(&attr, 0, sizeof(attr));
while (1) {
- char c = getopt_long(argc, argv, "s:d:a", opts, NULL);
+ int c = getopt_long(argc, argv, "s:d:a", opts, NULL);
if (c == -1 || all)
break;
return fault_simul_rule_list(LNET_CTL_DELAY_LIST, "delay", argc, argv);
}
-double
-get_cycles_per_usec()
-{
- FILE *f = fopen("/proc/cpuinfo", "r");
- double mhz;
- char line[64];
-
- if (f) {
- while (fgets(line, sizeof(line), f))
- if (sscanf(line, "cpu MHz : %lf", &mhz) == 1) {
- fclose(f);
- return mhz;
- }
- fclose(f);
- }
-
- fprintf(stderr, "Can't read/parse /proc/cpuinfo\n");
- return 1000.0;
-}
-
int jt_ptl_testprotocompat(int argc, char **argv)
{
struct libcfs_ioctl_data data;