#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>
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
lnet_parse_ipquad(__u32 *ipaddrp, char *str)
{
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 *
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
-lnet_parse_nid(char *nid_str, struct lnet_process_id *id_ptr)
+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_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];
+ 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];
- nid = libcfs_str2nid(nidstr);
- if (nid == LNET_NID_ANY) {
+ 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;
}
bool done = false, print = true;
int rc;
int timeout;
- struct lnet_process_id id;
+ struct lnet_processid id;
yaml_emitter_t request;
yaml_parser_t reply;
yaml_event_t event;
if (rc != 0)
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 -EINVAL;
}
/* 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_nid2str(id.nid),
- strlen(libcfs_nid2str(id.nid)), 1, 0,
+ (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)
LIBCFS_IOC_INIT_V2(ping, ping_hdr);
ping.ping_hdr.ioc_len = sizeof(ping);
- ping.ping_id = id;
+ ping.ping_id = lnet_pid_to_pid4(&id);
ping.ping_src = LNET_NID_ANY;
ping.op_param = timeout;
ping.ping_count = maxids;