1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2001, 2002 Cluster File Systems, Inc.
6 * This file is part of Portals, http://www.sf.net/projects/lustre/
8 * Portals is free software; you can redistribute it and/or
9 * modify it under the terms of version 2 of the GNU General Public
10 * License as published by the Free Software Foundation.
12 * Portals is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Portals; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include <sys/types.h>
26 #include <sys/socket.h>
27 #include <netinet/tcp.h>
32 #include <sys/ioctl.h>
36 #include <asm/byteorder.h>
38 #include <portals/api-support.h>
39 #include <portals/ptlctl.h>
40 #include <portals/list.h>
41 #include <portals/lib-types.h>
44 unsigned int portal_debug;
45 unsigned int portal_printk;
46 unsigned int portal_stack;
49 static ptl_nid_t g_nid = 0;
50 static unsigned int g_nal = 0;
51 static unsigned short g_port = 0;
53 static int g_socket_txmem = 0;
54 static int g_socket_rxmem = 0;
55 static int g_socket_nonagle = 1;
63 static name2num_t nalnames[] = {
68 {"scimac", SCIMACNAL},
73 name2num_lookup_name (name2num_t *table, char *str)
75 while (table->name != NULL)
76 if (!strcmp (str, table->name))
84 name2num_lookup_num (name2num_t *table, int num)
86 while (table->name != NULL)
87 if (num == table->num)
95 ptl_name2nal (char *str)
97 name2num_t *e = name2num_lookup_name (nalnames, str);
99 return ((e == NULL) ? 0 : e->num);
105 name2num_t *e = name2num_lookup_num (nalnames, nal);
107 return ((e == NULL) ? "???" : e->name);
110 static struct hostent *
111 ptl_gethostbyname(char * hname) {
113 he = gethostbyname(hname);
118 fprintf(stderr, "Unable to resolve hostname: %s\n",
122 fprintf(stderr, "gethostbyname error: %s\n",
132 ptl_parse_nid (ptl_nid_t *nidp, char *str)
140 if (sscanf (str, "%d.%d.%d.%d", &a, &b, &c, &d) == 4 &&
141 (a & ~0xff) == 0 && (b & ~0xff) == 0 &&
142 (c & ~0xff) == 0 && (d & ~0xff) == 0)
144 __u32 addr = (a<<24)|(b<<16)|(c<<8)|d;
146 *nidp = (ptl_nid_t)addr;
150 if ((('a' <= str[0] && str[0] <= 'z') ||
151 ('A' <= str[0] && str[0] <= 'Z')) &&
152 (he = ptl_gethostbyname (str)) != NULL)
154 __u32 addr = *(__u32 *)he->h_addr;
156 *nidp = (ptl_nid_t)ntohl(addr); /* HOST byte order */
160 if (sscanf (str, "%i", &a) == 1)
162 *nidp = (ptl_nid_t)a;
166 if (sscanf (str, "%x", &a) == 1)
168 *nidp = (ptl_nid_t) a;
176 ptl_nid2str (char *buffer, ptl_nid_t nid)
178 __u32 addr = htonl((__u32)nid); /* back to NETWORK byte order */
179 struct hostent *he = gethostbyaddr ((const char *)&addr, sizeof (addr), AF_INET);
182 strcpy (buffer, he->h_name);
184 sprintf (buffer, "0x"LPX64, nid);
190 sock_write (int cfd, void *buffer, int nob)
194 int rc = write (cfd, buffer, nob);
206 fprintf (stderr, "Unexpected zero sock_write\n");
211 buffer = (char *)buffer + nob;
218 sock_read (int cfd, void *buffer, int nob)
222 int rc = read (cfd, buffer, nob);
232 if (rc == 0) /* EOF */
234 errno = ECONNABORTED;
239 buffer = (char *)buffer + nob;
245 int ptl_initialize(int argc, char **argv)
247 register_ioc_dev(PORTALS_DEV_ID, PORTALS_DEV_PATH);
252 int jt_ptl_network(int argc, char **argv)
257 (nal = ptl_name2nal (argv[1])) == 0)
261 fprintf(stderr, "usage: %s \n", argv[0]);
262 for (entry = nalnames; entry->name != NULL; entry++)
263 fprintf (stderr, "%s%s", entry == nalnames ? "<" : "|", entry->name);
264 fprintf(stderr, ">\n");
273 exchange_nids (int cfd, ptl_nid_t my_nid, ptl_nid_t *peer_nid)
277 ptl_magicversion_t *hmv = (ptl_magicversion_t *)&hdr.dest_nid;
279 LASSERT (sizeof (*hmv) == sizeof (hdr.dest_nid));
281 memset (&hdr, 0, sizeof (hdr));
283 hmv->magic = __cpu_to_le32 (PORTALS_PROTO_MAGIC);
284 hmv->version_major = __cpu_to_le16 (PORTALS_PROTO_VERSION_MAJOR);
285 hmv->version_minor = __cpu_to_le16 (PORTALS_PROTO_VERSION_MINOR);
287 hdr.src_nid = __cpu_to_le64 (my_nid);
288 hdr.type = __cpu_to_le32 (PTL_MSG_HELLO);
290 /* Assume there's sufficient socket buffering for a portals HELLO header */
291 rc = sock_write (cfd, &hdr, sizeof (hdr));
293 perror ("Can't send initial HELLO");
297 /* First few bytes down the wire are the portals protocol magic and
298 * version, no matter what protocol version we're running. */
300 rc = sock_read (cfd, hmv, sizeof (*hmv));
302 perror ("Can't read from peer");
306 if (__cpu_to_le32 (hmv->magic) != PORTALS_PROTO_MAGIC) {
307 fprintf (stderr, "Bad magic %#08x (%#08x expected)\n",
308 __cpu_to_le32 (hmv->magic), PORTALS_PROTO_MAGIC);
312 if (__cpu_to_le16 (hmv->version_major) != PORTALS_PROTO_VERSION_MAJOR ||
313 __cpu_to_le16 (hmv->version_minor) != PORTALS_PROTO_VERSION_MINOR) {
314 fprintf (stderr, "Incompatible protocol version %d.%d (%d.%d expected)\n",
315 __cpu_to_le16 (hmv->version_major),
316 __cpu_to_le16 (hmv->version_minor),
317 PORTALS_PROTO_VERSION_MAJOR,
318 PORTALS_PROTO_VERSION_MINOR);
321 /* version 0 sends magic/version as the dest_nid of a 'hello' header,
322 * so read the rest of it in now... */
323 LASSERT (PORTALS_PROTO_VERSION_MAJOR == 0);
324 rc = sock_read (cfd, hmv + 1, sizeof (hdr) - sizeof (*hmv));
326 perror ("Can't read rest of HELLO hdr");
330 /* ...and check we got what we expected */
331 if (__cpu_to_le32 (hdr.type) != PTL_MSG_HELLO ||
332 __cpu_to_le32 (PTL_HDR_LENGTH (&hdr)) != 0) {
333 fprintf (stderr, "Expecting a HELLO hdr with 0 payload,"
334 " but got type %d with %d payload\n",
335 __cpu_to_le32 (hdr.type),
336 __cpu_to_le32 (PTL_HDR_LENGTH (&hdr)));
340 *peer_nid = __le64_to_cpu (hdr.src_nid);
344 int jt_ptl_connect(int argc, char **argv)
348 fprintf(stderr, "usage: %s <hostname port [xi]> or <elan ID>\n",
353 fprintf(stderr, "Error: you must run the 'network' command "
357 if (g_nal == SOCKNAL || g_nal == TOENAL) {
360 struct portal_ioctl_data data;
361 struct sockaddr_in srvaddr;
368 int xchange_nids = 0;
376 he = ptl_gethostbyname(argv[1]);
380 g_port = atol(argv[2]);
383 for (flag = argv[3]; *flag != 0; flag++)
395 fprintf (stderr, "unrecognised flag '%c'\n",
400 memset(&srvaddr, 0, sizeof(srvaddr));
401 srvaddr.sin_family = AF_INET;
402 srvaddr.sin_port = htons(g_port);
403 srvaddr.sin_addr.s_addr = *(__u32 *)he->h_addr;
405 fd = socket(PF_INET, SOCK_STREAM, 0);
407 fprintf(stderr, "socket() failed: %s\n",
412 if (g_socket_nonagle)
415 if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &o, sizeof (o)) != 0)
417 fprintf(stderr, "cannot disable nagle: %s\n", strerror(errno));
422 if (g_socket_rxmem != 0)
425 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &o, sizeof (o)) != 0)
427 fprintf(stderr, "cannot set receive buffer size: %s\n", strerror(errno));
432 if (g_socket_txmem != 0)
435 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &o, sizeof (o)) != 0)
437 fprintf(stderr, "cannot set send buffer size: %s\n", strerror(errno));
442 rc = connect(fd, (struct sockaddr *)&srvaddr, sizeof(srvaddr));
444 fprintf(stderr, "connect() failed: %s\n",
449 olen = sizeof (txmem);
450 if (getsockopt (fd, SOL_SOCKET, SO_SNDBUF, &txmem, &olen) != 0)
451 fprintf (stderr, "Can't get send buffer size: %s\n", strerror (errno));
452 olen = sizeof (rxmem);
453 if (getsockopt (fd, SOL_SOCKET, SO_RCVBUF, &rxmem, &olen) != 0)
454 fprintf (stderr, "Can't get receive buffer size: %s\n", strerror (errno));
455 olen = sizeof (nonagle);
456 if (getsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &nonagle, &olen) != 0)
457 fprintf (stderr, "Can't get nagle: %s\n", strerror (errno));
461 PORTAL_IOC_INIT (data);
462 data.ioc_nal = g_nal;
463 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_GET_NID, &data);
466 fprintf (stderr, "failed to get my nid: %s\n",
472 rc = exchange_nids (fd, data.ioc_nid, &peer_nid);
480 peer_nid = ntohl (srvaddr.sin_addr.s_addr); /* HOST byte order */
482 printf("Connected host: %s NID "LPX64" snd: %d rcv: %d nagle: %s\n", argv[1],
483 peer_nid, txmem, rxmem, nonagle ? "Disabled" : "Enabled");
485 PORTAL_IOC_INIT(data);
487 data.ioc_nal = g_nal;
488 data.ioc_nal_cmd = NAL_CMD_REGISTER_PEER_FD;
489 data.ioc_nid = peer_nid;
490 data.ioc_flags = bind_irq;
492 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
494 fprintf(stderr, "failed to register fd with portals: "
495 "%s\n", strerror(errno));
501 printf("Connection to "LPX64" registered with socknal\n", g_nid);
505 fprintf(stderr, "close failed: %d\n", rc);
507 } else if (g_nal == QSWNAL) {
508 g_nid = atoi(argv[1]);
509 } else if (g_nal == GMNAL) {
510 g_nid = atoi(argv[1]);
511 } else if (g_nal == SCIMACNAL) {
513 if(sscanf(argv[1], "%x", &tmpnid) == 1) {
517 fprintf(stderr, "nid %s invalid for SCI nal\n", argv[1]);
522 fprintf(stderr, "This should never happen. Also it is very "
529 int jt_ptl_disconnect(int argc, char **argv)
532 fprintf(stderr, "usage: %s [hostname]\n", argv[0]);
536 fprintf(stderr, "Error: you must run the 'network' command "
540 if (g_nal == SOCKNAL || g_nal == TOENAL) {
542 struct portal_ioctl_data data;
545 PORTAL_IOC_INIT(data);
547 he = ptl_gethostbyname(argv[1]);
551 data.ioc_nid = ntohl (*(__u32 *)he->h_addr); /* HOST byte order */
554 printf("Disconnecting ALL connections.\n");
555 /* leave ioc_nid zeroed == disconnect all */
557 data.ioc_nal = g_nal;
558 data.ioc_nal_cmd = NAL_CMD_CLOSE_CONNECTION;
559 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
561 fprintf(stderr, "failed to remove connection: %s\n",
565 } else if (g_nal == QSWNAL) {
566 printf("'disconnect' doesn't make any sense for "
568 } else if (g_nal == GMNAL) {
569 printf("'disconnect' doesn't make any sense for "
571 } else if (g_nal == SCIMACNAL) {
572 printf("'disconnect' doesn't make any sense for "
575 fprintf(stderr, "This should never happen. Also it is very "
583 int jt_ptl_push_connection (int argc, char **argv)
586 fprintf(stderr, "usage: %s [hostname]\n", argv[0]);
590 fprintf(stderr, "Error: you must run the 'network' command "
594 if (g_nal == SOCKNAL || g_nal == TOENAL) {
596 struct portal_ioctl_data data;
599 PORTAL_IOC_INIT(data);
601 he = ptl_gethostbyname(argv[1]);
605 data.ioc_nid = ntohl (*(__u32 *)he->h_addr); /* HOST byte order */
608 printf("Pushing ALL connections.\n");
609 /* leave ioc_nid zeroed == disconnect all */
611 data.ioc_nal = g_nal;
612 data.ioc_nal_cmd = NAL_CMD_PUSH_CONNECTION;
613 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
615 fprintf(stderr, "failed to push connection: %s\n",
619 } else if (g_nal == QSWNAL) {
620 printf("'push' doesn't make any sense for elan.\n");
621 } else if (g_nal == GMNAL) {
622 printf("'push' doesn't make any sense for GM.\n");
623 } else if (g_nal == SCIMACNAL) {
624 printf("'push' doesn't make any sense for SCI.\n");
626 fprintf(stderr, "This should never happen. Also it is very "
634 int jt_ptl_ping(int argc, char **argv)
641 struct portal_ioctl_data data;
644 fprintf(stderr, "usage: %s nid [count] [size] [timeout (secs)]\n", argv[0]);
649 fprintf(stderr, "Error: you must run the 'network' command "
654 if (ptl_parse_nid (&nid, argv[1]) != 0)
656 fprintf (stderr, "Can't parse nid \"%s\"\n", argv[1]);
662 count = atol(argv[2]);
664 if (count < 0 || count > 20000)
666 fprintf(stderr, "are you insane? %ld is a crazy count.\n", count);
675 timeout = atol (argv[4]);
677 PORTAL_IOC_INIT (data);
678 data.ioc_count = count;
679 data.ioc_size = size;
681 data.ioc_nal = g_nal;
682 data.ioc_timeout = timeout;
684 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_PING, &data);
686 fprintf(stderr, "failed to start pinger: %s\n",
693 int jt_ptl_shownid(int argc, char **argv)
695 struct portal_ioctl_data data;
699 fprintf(stderr, "usage: %s\n", argv[0]);
704 fprintf(stderr, "Error: you must run the 'network' command first\n");
708 PORTAL_IOC_INIT (data);
709 data.ioc_nal = g_nal;
710 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_GET_NID, &data);
712 fprintf(stderr, "getting my NID failed: %s\n",
715 printf(LPX64"\n", data.ioc_nid);
719 int jt_ptl_mynid(int argc, char **argv)
724 struct portal_ioctl_data data;
728 fprintf(stderr, "usage: %s [NID]\n", argv[0]);
729 fprintf(stderr, "NID defaults to the primary IP address of the machine.\n");
734 fprintf(stderr, "Error: you must run the 'network' command "
741 else if (gethostname(hostname, sizeof(hostname)) != 0) {
742 fprintf(stderr, "gethostname failed: %s\n",
749 rc = ptl_parse_nid (&mynid, nidstr);
751 fprintf (stderr, "Can't convert '%s' into a NID\n", nidstr);
755 PORTAL_IOC_INIT(data);
756 data.ioc_nid = mynid;
757 data.ioc_nal = g_nal;
758 data.ioc_nal_cmd = NAL_CMD_REGISTER_MYNID;
760 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
762 fprintf(stderr, "setting my NID failed: %s\n",
765 printf("registered my nid "LPX64" (%s)\n", mynid, hostname);
770 jt_ptl_fail_nid (int argc, char **argv)
774 unsigned int threshold;
775 struct portal_ioctl_data data;
777 if (argc < 2 || argc > 3)
779 fprintf (stderr, "usage: %s nid|\"_all_\" [count (0 == mend)]\n", argv[0]);
784 fprintf(stderr, "Error: you must run the 'network' command "
789 if (!strcmp (argv[1], "_all_"))
791 else if (ptl_parse_nid (&nid, argv[1]) != 0)
793 fprintf (stderr, "Can't parse nid \"%s\"\n", argv[1]);
798 threshold = PTL_MD_THRESH_INF;
799 else if (sscanf (argv[2], "%i", &threshold) != 1) {
800 fprintf (stderr, "Can't parse count \"%s\"\n", argv[2]);
804 PORTAL_IOC_INIT (data);
805 data.ioc_nal = g_nal;
807 data.ioc_count = threshold;
809 rc = l_ioctl (PORTALS_DEV_ID, IOC_PORTAL_FAIL_NID, &data);
811 fprintf (stderr, "IOC_PORTAL_FAIL_NID failed: %s\n",
814 printf ("%s %s\n", threshold == 0 ? "Unfailing" : "Failing", argv[1]);
820 jt_ptl_rxmem (int argc, char **argv)
826 if (Parser_size (&size, argv[1]) != 0 || size < 0)
828 fprintf (stderr, "Can't parse size %s\n", argv[1]);
832 g_socket_rxmem = size;
834 printf ("Socket rmem = %d\n", g_socket_rxmem);
839 jt_ptl_txmem (int argc, char **argv)
845 if (Parser_size (&size, argv[1]) != 0 || size < 0)
847 fprintf (stderr, "Can't parse size %s\n", argv[1]);
850 g_socket_txmem = size;
852 printf ("Socket txmem = %d\n", g_socket_txmem);
857 jt_ptl_nagle (int argc, char **argv)
863 if (Parser_bool (&enable, argv[1]) != 0)
865 fprintf (stderr, "Can't parse boolean %s\n", argv[1]);
868 g_socket_nonagle = !enable;
870 printf ("Nagle %s\n", g_socket_nonagle ? "disabled" : "enabled");
875 jt_ptl_add_route (int argc, char **argv)
877 struct portal_ioctl_data data;
880 ptl_nid_t gateway_nid;
885 fprintf (stderr, "usage: %s gateway target [target]\n", argv[0]);
890 fprintf(stderr, "Error: you must run the 'network' command "
895 if (ptl_parse_nid (&gateway_nid, argv[1]) != 0)
897 fprintf (stderr, "Can't parse gateway NID \"%s\"\n", argv[1]);
901 if (ptl_parse_nid (&nid1, argv[2]) != 0)
903 fprintf (stderr, "Can't parse first target NID \"%s\"\n", argv[2]);
909 else if (ptl_parse_nid (&nid2, argv[3]) != 0)
911 fprintf (stderr, "Can't parse second target NID \"%s\"\n", argv[4]);
915 PORTAL_IOC_INIT(data);
916 data.ioc_nid = gateway_nid;
917 data.ioc_nal = g_nal;
918 data.ioc_nid2 = MIN (nid1, nid2);
919 data.ioc_nid3 = MAX (nid1, nid2);
921 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_ADD_ROUTE, &data);
924 fprintf (stderr, "IOC_PORTAL_ADD_ROUTE failed: %s\n", strerror (errno));
932 jt_ptl_del_route (int argc, char **argv)
934 struct portal_ioctl_data data;
940 fprintf (stderr, "usage: %s targetNID\n", argv[0]);
944 if (ptl_parse_nid (&nid, argv[1]) != 0)
946 fprintf (stderr, "Can't parse target NID \"%s\"\n", argv[1]);
950 PORTAL_IOC_INIT(data);
953 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_DEL_ROUTE, &data);
956 fprintf (stderr, "IOC_PORTAL_DEL_ROUTE ("LPX64") failed: %s\n", nid, strerror (errno));
964 jt_ptl_print_routes (int argc, char **argv)
967 struct portal_ioctl_data data;
971 ptl_nid_t gateway_nid;
976 for (index = 0;;index++)
978 PORTAL_IOC_INIT(data);
979 data.ioc_count = index;
981 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_GET_ROUTE, &data);
985 gateway_nal = data.ioc_nal;
986 gateway_nid = data.ioc_nid;
987 nid1 = data.ioc_nid2;
988 nid2 = data.ioc_nid3;
990 printf ("%8s %18s : %s - %s\n",
991 nal2name (gateway_nal),
992 ptl_nid2str (buffer[0], gateway_nid),
993 ptl_nid2str (buffer[1], nid1),
994 ptl_nid2str (buffer[2], nid2));