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>
25 #include <sys/socket.h>
26 #include <netinet/tcp.h>
31 #include <sys/ioctl.h>
35 #include <asm/byteorder.h>
37 #include <portals/api-support.h>
38 #include <portals/ptlctl.h>
39 #include <portals/list.h>
40 #include <portals/lib-types.h>
43 unsigned int portal_debug;
44 unsigned int portal_printk;
45 unsigned int portal_stack;
48 static ptl_nid_t g_nid = 0;
49 static unsigned int g_nal = 0;
50 static unsigned short g_port = 0;
52 static int g_socket_txmem = 0;
53 static int g_socket_rxmem = 0;
54 static int g_socket_nonagle = 1;
62 static name2num_t nalnames[] = {
67 {"scimac", SCIMACNAL},
72 name2num_lookup_name (name2num_t *table, char *str)
74 while (table->name != NULL)
75 if (!strcmp (str, table->name))
83 name2num_lookup_num (name2num_t *table, int num)
85 while (table->name != NULL)
86 if (num == table->num)
94 ptl_name2nal (char *str)
96 name2num_t *e = name2num_lookup_name (nalnames, str);
98 return ((e == NULL) ? 0 : e->num);
104 name2num_t *e = name2num_lookup_num (nalnames, nal);
106 return ((e == NULL) ? "???" : e->name);
110 ptl_parse_nid (ptl_nid_t *nidp, char *str)
118 if (sscanf (str, "%d.%d.%d.%d", &a, &b, &c, &d) == 4 &&
119 (a & ~0xff) == 0 && (b & ~0xff) == 0 &&
120 (c & ~0xff) == 0 && (d & ~0xff) == 0)
122 __u32 addr = (a<<24)|(b<<16)|(c<<8)|d;
124 *nidp = (ptl_nid_t)addr;
128 if ((('a' <= str[0] && str[0] <= 'z') ||
129 ('A' <= str[0] && str[0] <= 'Z')) &&
130 (he = gethostbyname (str)) != NULL)
132 __u32 addr = *(__u32 *)he->h_addr;
134 *nidp = (ptl_nid_t)ntohl(addr); /* HOST byte order */
138 if (sscanf (str, "%i", &a) == 1)
140 *nidp = (ptl_nid_t)a;
144 if (sscanf (str, "%x", &a) == 1)
146 *nidp = (ptl_nid_t) a;
154 ptl_nid2str (char *buffer, ptl_nid_t nid)
156 __u32 addr = htonl((__u32)nid); /* back to NETWORK byte order */
157 struct hostent *he = gethostbyaddr ((const char *)&addr, sizeof (addr), AF_INET);
160 strcpy (buffer, he->h_name);
162 sprintf (buffer, "0x"LPX64, nid);
168 sock_write (int cfd, void *buffer, int nob)
172 int rc = write (cfd, buffer, nob);
184 fprintf (stderr, "Unexpected zero sock_write\n");
189 buffer = (char *)buffer + nob;
196 sock_read (int cfd, void *buffer, int nob)
200 int rc = read (cfd, buffer, nob);
210 if (rc == 0) /* EOF */
212 errno = ECONNABORTED;
217 buffer = (char *)buffer + nob;
223 int ptl_initialize(int argc, char **argv)
225 register_ioc_dev(PORTALS_DEV_ID, PORTALS_DEV_PATH);
230 int jt_ptl_network(int argc, char **argv)
235 (nal = ptl_name2nal (argv[1])) == 0)
239 fprintf(stderr, "usage: %s \n", argv[0]);
240 for (entry = nalnames; entry->name != NULL; entry++)
241 fprintf (stderr, "%s%s", entry == nalnames ? "<" : "|", entry->name);
242 fprintf(stderr, ">\n");
251 exchange_nids (int cfd, ptl_nid_t my_nid, ptl_nid_t *peer_nid)
255 ptl_magicversion_t *hmv = (ptl_magicversion_t *)&hdr.dest_nid;
257 LASSERT (sizeof (*hmv) == sizeof (hdr.dest_nid));
259 memset (&hdr, 0, sizeof (hdr));
261 hmv->magic = __cpu_to_le32 (PORTALS_PROTO_MAGIC);
262 hmv->version_major = __cpu_to_le16 (PORTALS_PROTO_VERSION_MAJOR);
263 hmv->version_minor = __cpu_to_le16 (PORTALS_PROTO_VERSION_MINOR);
265 hdr.src_nid = __cpu_to_le64 (my_nid);
266 hdr.type = __cpu_to_le32 (PTL_MSG_HELLO);
268 /* Assume there's sufficient socket buffering for a portals HELLO header */
269 rc = sock_write (cfd, &hdr, sizeof (hdr));
271 perror ("Can't send initial HELLO");
275 /* First few bytes down the wire are the portals protocol magic and
276 * version, no matter what protocol version we're running. */
278 rc = sock_read (cfd, hmv, sizeof (*hmv));
280 perror ("Can't read from peer");
284 if (__cpu_to_le32 (hmv->magic) != PORTALS_PROTO_MAGIC) {
285 fprintf (stderr, "Bad magic %#08x (%#08x expected)\n",
286 __cpu_to_le32 (hmv->magic), PORTALS_PROTO_MAGIC);
290 if (__cpu_to_le16 (hmv->version_major) != PORTALS_PROTO_VERSION_MAJOR ||
291 __cpu_to_le16 (hmv->version_minor) != PORTALS_PROTO_VERSION_MINOR) {
292 fprintf (stderr, "Incompatible protocol version %d.%d (%d.%d expected)\n",
293 __cpu_to_le16 (hmv->version_major),
294 __cpu_to_le16 (hmv->version_minor),
295 PORTALS_PROTO_VERSION_MAJOR,
296 PORTALS_PROTO_VERSION_MINOR);
299 /* version 0 sends magic/version as the dest_nid of a 'hello' header,
300 * so read the rest of it in now... */
301 LASSERT (PORTALS_PROTO_VERSION_MAJOR == 0);
302 rc = sock_read (cfd, hmv + 1, sizeof (hdr) - sizeof (*hmv));
304 perror ("Can't read rest of HELLO hdr");
308 /* ...and check we got what we expected */
309 if (__cpu_to_le32 (hdr.type) != PTL_MSG_HELLO ||
310 __cpu_to_le32 (PTL_HDR_LENGTH (&hdr)) != 0) {
311 fprintf (stderr, "Expecting a HELLO hdr with 0 payload,"
312 " but got type %d with %d payload\n",
313 __cpu_to_le32 (hdr.type),
314 __cpu_to_le32 (PTL_HDR_LENGTH (&hdr)));
318 *peer_nid = __le64_to_cpu (hdr.src_nid);
322 int jt_ptl_connect(int argc, char **argv)
326 fprintf(stderr, "usage: %s <hostname port [xi]> or <elan ID>\n",
331 fprintf(stderr, "Error: you must run the 'network' command "
335 if (g_nal == SOCKNAL || g_nal == TOENAL) {
338 struct portal_ioctl_data data;
339 struct sockaddr_in srvaddr;
346 int xchange_nids = 0;
354 he = gethostbyname(argv[1]);
356 fprintf(stderr, "gethostbyname error: %s\n",
361 g_port = atol(argv[2]);
364 for (flag = argv[3]; *flag != 0; flag++)
376 fprintf (stderr, "unrecognised flag '%c'\n",
381 memset(&srvaddr, 0, sizeof(srvaddr));
382 srvaddr.sin_family = AF_INET;
383 srvaddr.sin_port = htons(g_port);
384 srvaddr.sin_addr.s_addr = *(__u32 *)he->h_addr;
386 fd = socket(PF_INET, SOCK_STREAM, 0);
388 fprintf(stderr, "socket() failed: %s\n",
393 if (g_socket_nonagle)
396 if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &o, sizeof (o)) != 0)
398 fprintf(stderr, "cannot disable nagle: %s\n", strerror(errno));
403 if (g_socket_rxmem != 0)
406 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &o, sizeof (o)) != 0)
408 fprintf(stderr, "cannot set receive buffer size: %s\n", strerror(errno));
413 if (g_socket_txmem != 0)
416 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &o, sizeof (o)) != 0)
418 fprintf(stderr, "cannot set send buffer size: %s\n", strerror(errno));
423 rc = connect(fd, (struct sockaddr *)&srvaddr, sizeof(srvaddr));
425 fprintf(stderr, "connect() failed: %s\n",
430 olen = sizeof (txmem);
431 if (getsockopt (fd, SOL_SOCKET, SO_SNDBUF, &txmem, &olen) != 0)
432 fprintf (stderr, "Can't get send buffer size: %s\n", strerror (errno));
433 olen = sizeof (rxmem);
434 if (getsockopt (fd, SOL_SOCKET, SO_RCVBUF, &rxmem, &olen) != 0)
435 fprintf (stderr, "Can't get receive buffer size: %s\n", strerror (errno));
436 olen = sizeof (nonagle);
437 if (getsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &nonagle, &olen) != 0)
438 fprintf (stderr, "Can't get nagle: %s\n", strerror (errno));
442 PORTAL_IOC_INIT (data);
443 data.ioc_nal = g_nal;
444 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_GET_NID, &data);
447 fprintf (stderr, "failed to get my nid: %s\n",
453 rc = exchange_nids (fd, data.ioc_nid, &peer_nid);
461 peer_nid = ntohl (srvaddr.sin_addr.s_addr); /* HOST byte order */
463 printf("Connected host: %s NID "LPX64" snd: %d rcv: %d nagle: %s\n", argv[1],
464 peer_nid, txmem, rxmem, nonagle ? "Disabled" : "Enabled");
466 PORTAL_IOC_INIT(data);
468 data.ioc_nal = g_nal;
469 data.ioc_nal_cmd = NAL_CMD_REGISTER_PEER_FD;
470 data.ioc_nid = peer_nid;
471 data.ioc_flags = bind_irq;
473 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
475 fprintf(stderr, "failed to register fd with portals: "
476 "%s\n", strerror(errno));
482 printf("Connection to "LPX64" registered with socknal\n", g_nid);
486 fprintf(stderr, "close failed: %d\n", rc);
488 } else if (g_nal == QSWNAL) {
489 g_nid = atoi(argv[1]);
490 } else if (g_nal == GMNAL) {
491 g_nid = atoi(argv[1]);
492 } else if (g_nal == SCIMACNAL) {
494 if(sscanf(argv[1], "%x", &tmpnid) == 1) {
498 fprintf(stderr, "nid %s invalid for SCI nal\n", argv[1]);
503 fprintf(stderr, "This should never happen. Also it is very "
510 int jt_ptl_disconnect(int argc, char **argv)
513 fprintf(stderr, "usage: %s [hostname]\n", argv[0]);
517 fprintf(stderr, "Error: you must run the 'network' command "
521 if (g_nal == SOCKNAL || g_nal == TOENAL) {
523 struct portal_ioctl_data data;
526 PORTAL_IOC_INIT(data);
528 he = gethostbyname(argv[1]);
530 fprintf(stderr, "gethostbyname error: %s\n",
535 data.ioc_nid = ntohl (*(__u32 *)he->h_addr); /* HOST byte order */
538 printf("Disconnecting ALL connections.\n");
539 /* leave ioc_nid zeroed == disconnect all */
541 data.ioc_nal = g_nal;
542 data.ioc_nal_cmd = NAL_CMD_CLOSE_CONNECTION;
543 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
545 fprintf(stderr, "failed to remove connection: %s\n",
549 } else if (g_nal == QSWNAL) {
550 printf("'disconnect' doesn't make any sense for "
552 } else if (g_nal == GMNAL) {
553 printf("'disconnect' doesn't make any sense for "
555 } else if (g_nal == SCIMACNAL) {
556 printf("'disconnect' doesn't make any sense for "
559 fprintf(stderr, "This should never happen. Also it is very "
567 int jt_ptl_push_connection (int argc, char **argv)
570 fprintf(stderr, "usage: %s [hostname]\n", argv[0]);
574 fprintf(stderr, "Error: you must run the 'network' command "
578 if (g_nal == SOCKNAL || g_nal == TOENAL) {
580 struct portal_ioctl_data data;
583 PORTAL_IOC_INIT(data);
585 he = gethostbyname(argv[1]);
587 fprintf(stderr, "gethostbyname error: %s\n",
592 data.ioc_nid = ntohl (*(__u32 *)he->h_addr); /* HOST byte order */
595 printf("Pushing ALL connections.\n");
596 /* leave ioc_nid zeroed == disconnect all */
598 data.ioc_nal = g_nal;
599 data.ioc_nal_cmd = NAL_CMD_PUSH_CONNECTION;
600 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
602 fprintf(stderr, "failed to push connection: %s\n",
606 } else if (g_nal == QSWNAL) {
607 printf("'push' doesn't make any sense for elan.\n");
608 } else if (g_nal == GMNAL) {
609 printf("'push' doesn't make any sense for GM.\n");
610 } else if (g_nal == SCIMACNAL) {
611 printf("'push' doesn't make any sense for SCI.\n");
613 fprintf(stderr, "This should never happen. Also it is very "
621 int jt_ptl_ping(int argc, char **argv)
628 struct portal_ioctl_data data;
631 fprintf(stderr, "usage: %s nid [count] [size] [timeout (secs)]\n", argv[0]);
636 fprintf(stderr, "Error: you must run the 'network' command "
641 if (ptl_parse_nid (&nid, argv[1]) != 0)
643 fprintf (stderr, "Can't parse nid \"%s\"\n", argv[1]);
649 count = atol(argv[2]);
651 if (count < 0 || count > 20000)
653 fprintf(stderr, "are you insane? %ld is a crazy count.\n", count);
662 timeout = atol (argv[4]);
664 PORTAL_IOC_INIT (data);
665 data.ioc_count = count;
666 data.ioc_size = size;
668 data.ioc_nal = g_nal;
669 data.ioc_timeout = timeout;
671 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_PING, &data);
673 fprintf(stderr, "failed to start pinger: %s\n",
680 int jt_ptl_shownid(int argc, char **argv)
682 struct portal_ioctl_data data;
686 fprintf(stderr, "usage: %s\n", argv[0]);
691 fprintf(stderr, "Error: you must run the 'network' command first\n");
695 PORTAL_IOC_INIT (data);
696 data.ioc_nal = g_nal;
697 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_GET_NID, &data);
699 fprintf(stderr, "getting my NID failed: %s\n",
702 printf(LPX64"\n", data.ioc_nid);
706 int jt_ptl_mynid(int argc, char **argv)
711 struct portal_ioctl_data data;
715 fprintf(stderr, "usage: %s [NID]\n", argv[0]);
716 fprintf(stderr, "NID defaults to the primary IP address of the machine.\n");
721 fprintf(stderr, "Error: you must run the 'network' command "
728 else if (gethostname(hostname, sizeof(hostname)) != 0) {
729 fprintf(stderr, "gethostname failed: %s\n",
736 rc = ptl_parse_nid (&mynid, nidstr);
738 fprintf (stderr, "Can't convert '%s' into a NID\n", nidstr);
742 PORTAL_IOC_INIT(data);
743 data.ioc_nid = mynid;
744 data.ioc_nal = g_nal;
745 data.ioc_nal_cmd = NAL_CMD_REGISTER_MYNID;
747 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
749 fprintf(stderr, "setting my NID failed: %s\n",
752 printf("registered my nid "LPX64" (%s)\n", mynid, hostname);
757 jt_ptl_fail_nid (int argc, char **argv)
761 unsigned int threshold;
762 struct portal_ioctl_data data;
764 if (argc < 2 || argc > 3)
766 fprintf (stderr, "usage: %s nid|\"_all_\" [count (0 == mend)]\n", argv[0]);
771 fprintf(stderr, "Error: you must run the 'network' command "
776 if (!strcmp (argv[1], "_all_"))
778 else if (ptl_parse_nid (&nid, argv[1]) != 0)
780 fprintf (stderr, "Can't parse nid \"%s\"\n", argv[1]);
785 threshold = PTL_MD_THRESH_INF;
786 else if (sscanf (argv[2], "%i", &threshold) != 1) {
787 fprintf (stderr, "Can't parse count \"%s\"\n", argv[2]);
791 PORTAL_IOC_INIT (data);
792 data.ioc_nal = g_nal;
794 data.ioc_count = threshold;
796 rc = l_ioctl (PORTALS_DEV_ID, IOC_PORTAL_FAIL_NID, &data);
798 fprintf (stderr, "IOC_PORTAL_FAIL_NID failed: %s\n",
801 printf ("%s %s\n", threshold == 0 ? "Unfailing" : "Failing", argv[1]);
807 jt_ptl_rxmem (int argc, char **argv)
813 if (Parser_size (&size, argv[1]) != 0 || size < 0)
815 fprintf (stderr, "Can't parse size %s\n", argv[1]);
819 g_socket_rxmem = size;
821 printf ("Socket rmem = %d\n", g_socket_rxmem);
826 jt_ptl_txmem (int argc, char **argv)
832 if (Parser_size (&size, argv[1]) != 0 || size < 0)
834 fprintf (stderr, "Can't parse size %s\n", argv[1]);
837 g_socket_txmem = size;
839 printf ("Socket txmem = %d\n", g_socket_txmem);
844 jt_ptl_nagle (int argc, char **argv)
850 if (Parser_bool (&enable, argv[1]) != 0)
852 fprintf (stderr, "Can't parse boolean %s\n", argv[1]);
855 g_socket_nonagle = !enable;
857 printf ("Nagle %s\n", g_socket_nonagle ? "disabled" : "enabled");
862 jt_ptl_add_route (int argc, char **argv)
864 struct portal_ioctl_data data;
867 ptl_nid_t gateway_nid;
872 fprintf (stderr, "usage: %s gateway target [target]\n", argv[0]);
877 fprintf(stderr, "Error: you must run the 'network' command "
882 if (ptl_parse_nid (&gateway_nid, argv[1]) != 0)
884 fprintf (stderr, "Can't parse gateway NID \"%s\"\n", argv[1]);
888 if (ptl_parse_nid (&nid1, argv[2]) != 0)
890 fprintf (stderr, "Can't parse first target NID \"%s\"\n", argv[2]);
896 else if (ptl_parse_nid (&nid2, argv[3]) != 0)
898 fprintf (stderr, "Can't parse second target NID \"%s\"\n", argv[4]);
902 PORTAL_IOC_INIT(data);
903 data.ioc_nid = gateway_nid;
904 data.ioc_nal = g_nal;
905 data.ioc_nid2 = MIN (nid1, nid2);
906 data.ioc_nid3 = MAX (nid1, nid2);
908 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_ADD_ROUTE, &data);
911 fprintf (stderr, "IOC_PORTAL_ADD_ROUTE failed: %s\n", strerror (errno));
919 jt_ptl_del_route (int argc, char **argv)
921 struct portal_ioctl_data data;
927 fprintf (stderr, "usage: %s targetNID\n", argv[0]);
931 if (ptl_parse_nid (&nid, argv[1]) != 0)
933 fprintf (stderr, "Can't parse target NID \"%s\"\n", argv[1]);
937 PORTAL_IOC_INIT(data);
940 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_DEL_ROUTE, &data);
943 fprintf (stderr, "IOC_PORTAL_DEL_ROUTE ("LPX64") failed: %s\n", nid, strerror (errno));
951 jt_ptl_print_routes (int argc, char **argv)
954 struct portal_ioctl_data data;
958 ptl_nid_t gateway_nid;
963 for (index = 0;;index++)
965 PORTAL_IOC_INIT(data);
966 data.ioc_count = index;
968 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_GET_ROUTE, &data);
972 gateway_nal = data.ioc_nal;
973 gateway_nid = data.ioc_nid;
974 nid1 = data.ioc_nid2;
975 nid2 = data.ioc_nid3;
977 printf ("%8s %18s : %s - %s\n",
978 nal2name (gateway_nal),
979 ptl_nid2str (buffer[0], gateway_nid),
980 ptl_nid2str (buffer[1], nid1),
981 ptl_nid2str (buffer[2], nid2));