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>
37 #include <asm/byteorder.h>
39 #include <portals/api-support.h>
40 #include <portals/ptlctl.h>
41 #include <portals/list.h>
42 #include <portals/lib-types.h>
45 unsigned int portal_debug;
46 unsigned int portal_printk;
47 unsigned int portal_stack;
50 static unsigned int g_nal = 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[] = {
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) ? -1 : 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_port (int *port, char *str)
136 *port = strtol (str, &end, 0);
138 if (*end == 0 && /* parsed whole string */
139 *port > 0 && *port < 65536) /* minimal sanity check */
146 ptl_parse_time (time_t *t, char *str)
152 *t = strtol (str, &end, 0);
153 if (*end == 0) /* parsed whole string */
156 memset (&tm, 0, sizeof (tm));
157 n = sscanf (str, "%d-%d-%d-%d:%d:%d",
158 &tm.tm_year, &tm.tm_mon, &tm.tm_mday,
159 &tm.tm_hour, &tm.tm_min, &tm.tm_sec);
163 tm.tm_mon--; /* convert to 0 == Jan */
164 tm.tm_year -= 1900; /* y2k quirk */
165 tm.tm_isdst = -1; /* dunno if it's daylight savings... */
168 if (*t == (time_t)-1)
175 ptl_parse_ipaddr (__u32 *ipaddrp, char *str)
183 if (!strcmp (str, "_all_"))
189 if (sscanf (str, "%d.%d.%d.%d", &a, &b, &c, &d) == 4 &&
190 (a & ~0xff) == 0 && (b & ~0xff) == 0 &&
191 (c & ~0xff) == 0 && (d & ~0xff) == 0)
193 *ipaddrp = (a<<24)|(b<<16)|(c<<8)|d;
197 if ((('a' <= str[0] && str[0] <= 'z') ||
198 ('A' <= str[0] && str[0] <= 'Z')) &&
199 (he = ptl_gethostbyname (str)) != NULL)
201 __u32 addr = *(__u32 *)he->h_addr;
203 *ipaddrp = ntohl(addr); /* HOST byte order */
211 ptl_ipaddr_2_str (__u32 ipaddr, char *str)
216 net_ip = htonl (ipaddr);
217 he = gethostbyaddr (&net_ip, sizeof (net_ip), AF_INET);
221 sprintf (str, "%d.%d.%d.%d",
222 (ipaddr >> 24) & 0xff, (ipaddr >> 16) & 0xff,
223 (ipaddr >> 8) & 0xff, ipaddr & 0xff);
228 ptl_parse_nid (ptl_nid_t *nidp, char *str)
233 if (!strcmp (str, "_all_")) {
238 if (ptl_parse_ipaddr (&ipaddr, str) == 0) {
239 *nidp = (ptl_nid_t)ipaddr;
243 if (sscanf (str, "%li", &lval) == 1)
245 *nidp = (ptl_nid_t)lval;
249 if (sscanf (str, "%lx", &lval) == 1)
251 *nidp = (ptl_nid_t)lval;
259 ptl_nid2str (char *buffer, ptl_nid_t nid)
261 __u32 addr = htonl((__u32)nid); /* back to NETWORK byte order */
262 struct hostent *he = gethostbyaddr ((const char *)&addr, sizeof (addr), AF_INET);
265 strcpy (buffer, he->h_name);
267 sprintf (buffer, LPX64, nid);
275 fprintf (stderr, "Error: you must run the 'network' command first.\n");
282 int g_nal_is_compatible (char *cmd, ...)
287 if (!g_nal_is_set ())
293 nal = va_arg (ap, int);
294 } while (nal != 0 && nal != g_nal);
302 /* Don't complain verbosely if we've not been passed a command
303 * name to complain about! */
304 fprintf (stderr, "Command %s not compatible with nal %s\n",
305 cmd, nal2name (g_nal));
311 sock_write (int cfd, void *buffer, int nob)
315 int rc = write (cfd, buffer, nob);
327 fprintf (stderr, "Unexpected zero sock_write\n");
332 buffer = (char *)buffer + nob;
339 sock_read (int cfd, void *buffer, int nob)
343 int rc = read (cfd, buffer, nob);
353 if (rc == 0) /* EOF */
355 errno = ECONNABORTED;
360 buffer = (char *)buffer + nob;
366 int ptl_initialize(int argc, char **argv)
368 register_ioc_dev(PORTALS_DEV_ID, PORTALS_DEV_PATH);
373 int jt_ptl_network(int argc, char **argv)
379 (nal = ptl_name2nal (argv[1])) >= 0) {
384 fprintf(stderr, "usage: %s \n", argv[0]);
385 for (entry = nalnames; entry->name != NULL; entry++)
386 fprintf (stderr, "%s%s", entry == nalnames ? "<" : "|", entry->name);
387 fprintf(stderr, ">\n");
392 jt_ptl_print_autoconnects (int argc, char **argv)
394 struct portal_ioctl_data data;
399 if (!g_nal_is_compatible (argv[0], SOCKNAL, 0))
402 for (index = 0;;index++) {
403 PORTAL_IOC_INIT (data);
404 data.ioc_nal = g_nal;
405 data.ioc_nal_cmd = NAL_CMD_GET_AUTOCONN;
406 data.ioc_count = index;
408 rc = l_ioctl (PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
412 printf (LPX64"@%s:%d #%d buffer %d nonagle %s xchg %s "
413 "affinity %s eager %s share %d\n",
414 data.ioc_nid, ptl_ipaddr_2_str (data.ioc_id, buffer),
415 data.ioc_misc, data.ioc_count, data.ioc_size,
416 (data.ioc_flags & 1) ? "on" : "off",
417 (data.ioc_flags & 2) ? "on" : "off",
418 (data.ioc_flags & 4) ? "on" : "off",
419 (data.ioc_flags & 8) ? "on" : "off",
424 printf ("<no autoconnect routes>\n");
429 jt_ptl_add_autoconnect (int argc, char **argv)
431 struct portal_ioctl_data data;
435 int xchange_nids = 0;
436 int irq_affinity = 0;
441 if (argc < 4 || argc > 5) {
442 fprintf (stderr, "usage: %s nid ipaddr port [ixse]\n", argv[0]);
446 if (!g_nal_is_compatible (argv[0], SOCKNAL, 0))
449 if (ptl_parse_nid (&nid, argv[1]) != 0 ||
450 nid == PTL_NID_ANY) {
451 fprintf (stderr, "Can't parse NID: %s\n", argv[1]);
455 if (ptl_parse_ipaddr (&ip, argv[2]) != 0) {
456 fprintf (stderr, "Can't parse ip addr: %s\n", argv[2]);
460 if (ptl_parse_port (&port, argv[3]) != 0) {
461 fprintf (stderr, "Can't parse port: %s\n", argv[3]);
466 char *opts = argv[4];
483 fprintf (stderr, "Can't parse options: %s\n",
489 PORTAL_IOC_INIT (data);
490 data.ioc_nal = g_nal;
491 data.ioc_nal_cmd = NAL_CMD_ADD_AUTOCONN;
494 data.ioc_misc = port;
495 /* only passing one buffer size! */
496 data.ioc_size = MAX (g_socket_rxmem, g_socket_txmem);
497 data.ioc_flags = (g_socket_nonagle ? 0x01 : 0) |
498 (xchange_nids ? 0x02 : 0) |
499 (irq_affinity ? 0x04 : 0) |
503 rc = l_ioctl (PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
505 fprintf (stderr, "failed to enable autoconnect: %s\n",
514 jt_ptl_del_autoconnect (int argc, char **argv)
516 struct portal_ioctl_data data;
517 ptl_nid_t nid = PTL_NID_ANY;
524 fprintf (stderr, "usage: %s [nid] [ipaddr] [sk]\n",
529 if (!g_nal_is_compatible (argv[0], SOCKNAL, 0))
533 ptl_parse_nid (&nid, argv[1]) != 0) {
534 fprintf (stderr, "Can't parse nid: %s\n", argv[1]);
539 ptl_parse_ipaddr (&ip, argv[2]) != 0) {
540 fprintf (stderr, "Can't parse ip addr: %s\n", argv[2]);
545 char *opts = argv[3];
556 fprintf (stderr, "Can't parse flags: %s\n",
562 PORTAL_IOC_INIT (data);
563 data.ioc_nal = g_nal;
564 data.ioc_nal_cmd = NAL_CMD_DEL_AUTOCONN;
567 data.ioc_flags = (share ? 1 : 0) |
570 rc = l_ioctl (PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
572 fprintf (stderr, "failed to remove autoconnect route: %s\n",
581 jt_ptl_print_connections (int argc, char **argv)
583 struct portal_ioctl_data data;
588 if (!g_nal_is_compatible (argv[0], SOCKNAL, 0))
591 for (index = 0;;index++) {
592 PORTAL_IOC_INIT (data);
593 data.ioc_nal = g_nal;
594 data.ioc_nal_cmd = NAL_CMD_GET_CONN;
595 data.ioc_count = index;
597 rc = l_ioctl (PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
601 printf (LPX64"@%s:%d\n",
603 ptl_ipaddr_2_str (data.ioc_id, buffer),
608 printf ("<no connections>\n");
613 exchange_nids (int cfd, ptl_nid_t my_nid, ptl_nid_t *peer_nid)
617 ptl_magicversion_t *hmv = (ptl_magicversion_t *)&hdr.dest_nid;
619 LASSERT (sizeof (*hmv) == sizeof (hdr.dest_nid));
621 memset (&hdr, 0, sizeof (hdr));
623 hmv->magic = __cpu_to_le32 (PORTALS_PROTO_MAGIC);
624 hmv->version_major = __cpu_to_le16 (PORTALS_PROTO_VERSION_MAJOR);
625 hmv->version_minor = __cpu_to_le16 (PORTALS_PROTO_VERSION_MINOR);
627 hdr.src_nid = __cpu_to_le64 (my_nid);
628 hdr.type = __cpu_to_le32 (PTL_MSG_HELLO);
630 /* Assume there's sufficient socket buffering for a portals HELLO header */
631 rc = sock_write (cfd, &hdr, sizeof (hdr));
633 perror ("Can't send initial HELLO");
637 /* First few bytes down the wire are the portals protocol magic and
638 * version, no matter what protocol version we're running. */
640 rc = sock_read (cfd, hmv, sizeof (*hmv));
642 perror ("Can't read from peer");
646 if (hmv->magic != __cpu_to_le32 (PORTALS_PROTO_MAGIC)) {
647 fprintf (stderr, "Bad magic %#08x (%#08x expected)\n",
648 __le32_to_cpu (hmv->magic), PORTALS_PROTO_MAGIC);
652 if (hmv->version_major != __cpu_to_le16 (PORTALS_PROTO_VERSION_MAJOR) ||
653 hmv->version_minor != __cpu_to_le16 (PORTALS_PROTO_VERSION_MINOR)) {
654 fprintf (stderr, "Incompatible protocol version %d.%d (%d.%d expected)\n",
655 __le16_to_cpu (hmv->version_major),
656 __le16_to_cpu (hmv->version_minor),
657 PORTALS_PROTO_VERSION_MAJOR,
658 PORTALS_PROTO_VERSION_MINOR);
661 /* version 0 sends magic/version as the dest_nid of a 'hello' header,
662 * so read the rest of it in now... */
663 LASSERT (PORTALS_PROTO_VERSION_MAJOR == 0);
664 rc = sock_read (cfd, hmv + 1, sizeof (hdr) - sizeof (*hmv));
666 perror ("Can't read rest of HELLO hdr");
670 /* ...and check we got what we expected */
671 if (hdr.type != __cpu_to_le32 (PTL_MSG_HELLO) ||
672 PTL_HDR_LENGTH (&hdr) != __cpu_to_le32 (0)) {
673 fprintf (stderr, "Expecting a HELLO hdr with 0 payload,"
674 " but got type %d with %d payload\n",
675 __le32_to_cpu (hdr.type),
676 __le32_to_cpu (PTL_HDR_LENGTH (&hdr)));
680 *peer_nid = __le64_to_cpu (hdr.src_nid);
684 int jt_ptl_connect(int argc, char **argv)
687 struct portal_ioctl_data data;
688 struct sockaddr_in srvaddr;
696 int xchange_nids = 0;
702 fprintf(stderr, "usage: %s ip port [xi]\n", argv[0]);
706 if (!g_nal_is_compatible (argv[0], SOCKNAL, TOENAL, 0))
709 rc = ptl_parse_ipaddr (&ipaddr, argv[1]);
711 fprintf(stderr, "Can't parse hostname: %s\n", argv[1]);
715 if (ptl_parse_port (&port, argv[2]) != 0) {
716 fprintf (stderr, "Can't parse port: %s\n", argv[2]);
721 for (flag = argv[3]; *flag != 0; flag++)
733 fprintf (stderr, "unrecognised flag '%c'\n",
738 memset(&srvaddr, 0, sizeof(srvaddr));
739 srvaddr.sin_family = AF_INET;
740 srvaddr.sin_port = htons(port);
741 srvaddr.sin_addr.s_addr = htonl(ipaddr);
743 fd = socket(PF_INET, SOCK_STREAM, 0);
745 fprintf(stderr, "socket() failed: %s\n", strerror(errno));
749 if (g_socket_nonagle)
752 if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &o, sizeof (o)) != 0) {
753 fprintf(stderr, "cannot disable nagle: %s\n", strerror(errno));
758 if (g_socket_rxmem != 0) {
760 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &o, sizeof (o)) != 0) {
761 fprintf(stderr, "cannot set receive buffer size: %s\n", strerror(errno));
766 if (g_socket_txmem != 0) {
768 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &o, sizeof (o)) != 0) {
769 fprintf(stderr, "cannot set send buffer size: %s\n", strerror(errno));
774 rc = connect(fd, (struct sockaddr *)&srvaddr, sizeof(srvaddr));
776 fprintf(stderr, "connect() failed: %s\n", strerror(errno));
780 olen = sizeof (txmem);
781 if (getsockopt (fd, SOL_SOCKET, SO_SNDBUF, &txmem, &olen) != 0)
782 fprintf (stderr, "Can't get send buffer size: %s\n", strerror (errno));
783 olen = sizeof (rxmem);
784 if (getsockopt (fd, SOL_SOCKET, SO_RCVBUF, &rxmem, &olen) != 0)
785 fprintf (stderr, "Can't get receive buffer size: %s\n", strerror (errno));
786 olen = sizeof (nonagle);
787 if (getsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &nonagle, &olen) != 0)
788 fprintf (stderr, "Can't get nagle: %s\n", strerror (errno));
793 PORTAL_IOC_INIT (data);
794 data.ioc_nal = g_nal;
795 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_GET_NID, &data);
797 fprintf (stderr, "failed to get my nid: %s\n",
803 rc = exchange_nids (fd, data.ioc_nid, &peer_nid);
809 printf("Connected host: %s NID "LPX64" snd: %d rcv: %d nagle: %s\n", argv[1],
810 peer_nid, txmem, rxmem, nonagle ? "Disabled" : "Enabled");
812 PORTAL_IOC_INIT(data);
814 data.ioc_nal = g_nal;
815 data.ioc_nal_cmd = NAL_CMD_REGISTER_PEER_FD;
816 data.ioc_nid = peer_nid;
817 data.ioc_flags = bind_irq;
819 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
821 fprintf(stderr, "failed to register fd with portals: %s\n",
827 printf("Connection to "LPX64" registered with socknal\n", peer_nid);
831 fprintf(stderr, "close failed: %d\n", rc);
836 int jt_ptl_disconnect(int argc, char **argv)
838 struct portal_ioctl_data data;
839 ptl_nid_t nid = PTL_NID_ANY;
844 fprintf(stderr, "usage: %s [nid] [ipaddr]\n", argv[0]);
848 if (!g_nal_is_compatible (NULL, SOCKNAL, TOENAL, 0))
852 ptl_parse_nid (&nid, argv[1]) != 0) {
853 fprintf (stderr, "Can't parse nid %s\n", argv[1]);
858 ptl_parse_ipaddr (&ipaddr, argv[2]) != 0) {
859 fprintf (stderr, "Can't parse ip addr %s\n", argv[2]);
863 PORTAL_IOC_INIT(data);
864 data.ioc_nal = g_nal;
865 data.ioc_nal_cmd = NAL_CMD_CLOSE_CONNECTION;
867 data.ioc_id = ipaddr;
869 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
871 fprintf(stderr, "failed to remove connection: %s\n",
879 int jt_ptl_push_connection (int argc, char **argv)
881 struct portal_ioctl_data data;
883 ptl_nid_t nid = PTL_NID_ANY;
887 fprintf(stderr, "usage: %s [nid] [ip]\n", argv[0]);
891 if (!g_nal_is_compatible (argv[0], SOCKNAL, TOENAL, 0))
895 ptl_parse_nid (&nid, argv[1]) != 0) {
896 fprintf(stderr, "Can't parse nid: %s\n", argv[1]);
901 ptl_parse_ipaddr (&ipaddr, argv[2]) != 0) {
902 fprintf(stderr, "Can't parse ipaddr: %s\n", argv[2]);
905 PORTAL_IOC_INIT(data);
906 data.ioc_nal = g_nal;
907 data.ioc_nal_cmd = NAL_CMD_PUSH_CONNECTION;
909 data.ioc_id = ipaddr;
911 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
913 fprintf(stderr, "failed to push connection: %s\n",
922 jt_ptl_print_active_txs (int argc, char **argv)
924 struct portal_ioctl_data data;
928 if (!g_nal_is_compatible (argv[0], QSWNAL, 0))
931 for (index = 0;;index++) {
932 PORTAL_IOC_INIT (data);
933 data.ioc_nal = g_nal;
934 data.ioc_nal_cmd = NAL_CMD_GET_TXDESC;
935 data.ioc_count = index;
937 rc = l_ioctl (PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
941 printf ("%p: %5s payload %6d bytes to "LPX64" via "LPX64" by pid %6d: %s,%s,%s\n",
943 data.ioc_count == PTL_MSG_ACK ? "ACK" :
944 data.ioc_count == PTL_MSG_PUT ? "PUT" :
945 data.ioc_count == PTL_MSG_GET ? "GET" :
946 data.ioc_count == PTL_MSG_REPLY ? "REPLY" : "<wierd message>",
951 (data.ioc_flags & 1) ? "delayed" : "active",
952 (data.ioc_flags & 2) ? "forwarding" : "sending",
953 (data.ioc_flags & 4) ? "nblk" : "normal");
957 printf ("<no active descs>\n");
961 int jt_ptl_ping(int argc, char **argv)
968 struct portal_ioctl_data data;
971 fprintf(stderr, "usage: %s nid [count] [size] [timeout (secs)]\n", argv[0]);
978 if (ptl_parse_nid (&nid, argv[1]) != 0)
980 fprintf (stderr, "Can't parse nid \"%s\"\n", argv[1]);
986 count = atol(argv[2]);
988 if (count < 0 || count > 20000)
990 fprintf(stderr, "are you insane? %ld is a crazy count.\n", count);
999 timeout = atol (argv[4]);
1001 PORTAL_IOC_INIT (data);
1002 data.ioc_count = count;
1003 data.ioc_size = size;
1005 data.ioc_nal = g_nal;
1006 data.ioc_timeout = timeout;
1008 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_PING, &data);
1010 fprintf(stderr, "failed to start pinger: %s\n",
1017 int jt_ptl_shownid(int argc, char **argv)
1019 struct portal_ioctl_data data;
1023 fprintf(stderr, "usage: %s\n", argv[0]);
1027 if (!g_nal_is_set())
1030 PORTAL_IOC_INIT (data);
1031 data.ioc_nal = g_nal;
1032 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_GET_NID, &data);
1034 fprintf(stderr, "getting my NID failed: %s\n",
1037 printf(LPX64"\n", data.ioc_nid);
1041 int jt_ptl_mynid(int argc, char **argv)
1044 char hostname[1024];
1046 struct portal_ioctl_data data;
1050 fprintf(stderr, "usage: %s [NID]\n", argv[0]);
1051 fprintf(stderr, "NID defaults to the primary IP address of the machine.\n");
1055 if (!g_nal_is_set())
1060 else if (gethostname(hostname, sizeof(hostname)) != 0) {
1061 fprintf(stderr, "gethostname failed: %s\n",
1068 rc = ptl_parse_nid (&mynid, nidstr);
1070 fprintf (stderr, "Can't convert '%s' into a NID\n", nidstr);
1074 PORTAL_IOC_INIT(data);
1075 data.ioc_nid = mynid;
1076 data.ioc_nal = g_nal;
1077 data.ioc_nal_cmd = NAL_CMD_REGISTER_MYNID;
1079 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
1081 fprintf(stderr, "setting my NID failed: %s\n",
1084 printf("registered my nid "LPX64" (%s)\n", mynid, hostname);
1089 jt_ptl_fail_nid (int argc, char **argv)
1093 unsigned int threshold;
1094 struct portal_ioctl_data data;
1096 if (argc < 2 || argc > 3)
1098 fprintf (stderr, "usage: %s nid|\"_all_\" [count (0 == mend)]\n", argv[0]);
1102 if (!g_nal_is_set())
1105 if (!strcmp (argv[1], "_all_"))
1107 else if (ptl_parse_nid (&nid, argv[1]) != 0)
1109 fprintf (stderr, "Can't parse nid \"%s\"\n", argv[1]);
1114 threshold = PTL_MD_THRESH_INF;
1115 else if (sscanf (argv[2], "%i", &threshold) != 1) {
1116 fprintf (stderr, "Can't parse count \"%s\"\n", argv[2]);
1120 PORTAL_IOC_INIT (data);
1121 data.ioc_nal = g_nal;
1123 data.ioc_count = threshold;
1125 rc = l_ioctl (PORTALS_DEV_ID, IOC_PORTAL_FAIL_NID, &data);
1127 fprintf (stderr, "IOC_PORTAL_FAIL_NID failed: %s\n",
1130 printf ("%s %s\n", threshold == 0 ? "Unfailing" : "Failing", argv[1]);
1136 jt_ptl_rxmem (int argc, char **argv)
1142 if (Parser_size (&size, argv[1]) != 0 || size < 0)
1144 fprintf (stderr, "Can't parse size %s\n", argv[1]);
1148 g_socket_rxmem = size;
1150 printf ("Socket rmem = %d\n", g_socket_rxmem);
1155 jt_ptl_txmem (int argc, char **argv)
1161 if (Parser_size (&size, argv[1]) != 0 || size < 0)
1163 fprintf (stderr, "Can't parse size %s\n", argv[1]);
1166 g_socket_txmem = size;
1168 printf ("Socket txmem = %d\n", g_socket_txmem);
1173 jt_ptl_nagle (int argc, char **argv)
1179 if (Parser_bool (&enable, argv[1]) != 0)
1181 fprintf (stderr, "Can't parse boolean %s\n", argv[1]);
1184 g_socket_nonagle = !enable;
1186 printf ("Nagle %s\n", g_socket_nonagle ? "disabled" : "enabled");
1191 jt_ptl_add_route (int argc, char **argv)
1193 struct portal_ioctl_data data;
1196 ptl_nid_t gateway_nid;
1201 fprintf (stderr, "usage: %s gateway target [target]\n", argv[0]);
1205 if (!g_nal_is_set())
1208 if (ptl_parse_nid (&gateway_nid, argv[1]) != 0)
1210 fprintf (stderr, "Can't parse gateway NID \"%s\"\n", argv[1]);
1214 if (ptl_parse_nid (&nid1, argv[2]) != 0)
1216 fprintf (stderr, "Can't parse first target NID \"%s\"\n", argv[2]);
1222 else if (ptl_parse_nid (&nid2, argv[3]) != 0)
1224 fprintf (stderr, "Can't parse second target NID \"%s\"\n", argv[4]);
1228 PORTAL_IOC_INIT(data);
1229 data.ioc_nid = gateway_nid;
1230 data.ioc_nal = g_nal;
1231 data.ioc_nid2 = MIN (nid1, nid2);
1232 data.ioc_nid3 = MAX (nid1, nid2);
1234 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_ADD_ROUTE, &data);
1237 fprintf (stderr, "IOC_PORTAL_ADD_ROUTE failed: %s\n", strerror (errno));
1245 jt_ptl_del_route (int argc, char **argv)
1247 struct portal_ioctl_data data;
1249 ptl_nid_t nid1 = PTL_NID_ANY;
1250 ptl_nid_t nid2 = PTL_NID_ANY;
1255 fprintf (stderr, "usage: %s targetNID\n", argv[0]);
1259 if (!g_nal_is_set())
1262 if (ptl_parse_nid (&nid, argv[1]) != 0)
1264 fprintf (stderr, "Can't parse gateway NID \"%s\"\n", argv[1]);
1269 ptl_parse_nid (&nid1, argv[2]) != 0)
1271 fprintf (stderr, "Can't parse target NID \"%s\"\n", argv[2]);
1278 if (ptl_parse_nid (&nid2, argv[3]) != 0) {
1279 fprintf (stderr, "Can't parse target NID \"%s\"\n", argv[3]);
1284 ptl_nid_t tmp = nid1;
1291 PORTAL_IOC_INIT(data);
1292 data.ioc_nal = g_nal;
1294 data.ioc_nid2 = nid1;
1295 data.ioc_nid3 = nid2;
1297 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_DEL_ROUTE, &data);
1300 fprintf (stderr, "IOC_PORTAL_DEL_ROUTE ("LPX64") failed: %s\n", nid, strerror (errno));
1308 jt_ptl_notify_router (int argc, char **argv)
1310 struct portal_ioctl_data data;
1319 fprintf (stderr, "usage: %s targetNID <up/down> [<time>]\n",
1324 if (ptl_parse_nid (&nid, argv[1]) != 0)
1326 fprintf (stderr, "Can't parse target NID \"%s\"\n", argv[1]);
1330 if (Parser_bool (&enable, argv[2]) != 0) {
1331 fprintf (stderr, "Can't parse boolean %s\n", argv[2]);
1335 gettimeofday(&now, NULL);
1339 } else if (ptl_parse_time (&when, argv[3]) != 0) {
1340 fprintf(stderr, "Can't parse time %s\n"
1341 "Please specify either 'YYYY-MM-DD-HH:MM:SS'\n"
1342 "or an absolute unix time in seconds\n", argv[3]);
1344 } else if (when > now.tv_sec) {
1345 fprintf (stderr, "%s specifies a time in the future\n",
1350 PORTAL_IOC_INIT(data);
1351 data.ioc_nal = g_nal;
1353 data.ioc_flags = enable;
1354 /* Yeuch; 'cept I need a __u64 on 64 bit machines... */
1355 data.ioc_nid3 = (__u64)when;
1357 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_NOTIFY_ROUTER, &data);
1360 fprintf (stderr, "IOC_PORTAL_NOTIFY_ROUTER ("LPX64") failed: %s\n",
1361 nid, strerror (errno));
1369 jt_ptl_print_routes (int argc, char **argv)
1371 char buffer[3][128];
1372 struct portal_ioctl_data data;
1376 ptl_nid_t gateway_nid;
1381 for (index = 0;;index++)
1383 PORTAL_IOC_INIT(data);
1384 data.ioc_count = index;
1386 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_GET_ROUTE, &data);
1390 gateway_nal = data.ioc_nal;
1391 gateway_nid = data.ioc_nid;
1392 nid1 = data.ioc_nid2;
1393 nid2 = data.ioc_nid3;
1394 alive = data.ioc_flags;
1396 printf ("%8s %18s : %s - %s, %s\n",
1397 nal2name (gateway_nal),
1398 ptl_nid2str (buffer[0], gateway_nid),
1399 ptl_nid2str (buffer[1], nid1),
1400 ptl_nid2str (buffer[2], nid2),
1401 alive ? "up" : "down");
1407 lwt_control(int enable, int clear)
1409 struct portal_ioctl_data data;
1412 PORTAL_IOC_INIT(data);
1413 data.ioc_flags = enable;
1414 data.ioc_misc = clear;
1416 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_LWT_CONTROL, &data);
1420 fprintf(stderr, "IOC_PORTAL_LWT_CONTROL failed: %s\n",
1426 lwt_snapshot(int *ncpu, int *totalsize, lwt_event_t *events, int size)
1428 struct portal_ioctl_data data;
1431 PORTAL_IOC_INIT(data);
1432 data.ioc_pbuf1 = (char *)events;
1433 data.ioc_plen1 = size;
1435 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_LWT_SNAPSHOT, &data);
1437 fprintf(stderr, "IOC_PORTAL_LWT_SNAPSHOT failed: %s\n",
1442 LASSERT (data.ioc_count != 0);
1443 LASSERT (data.ioc_misc != 0);
1446 *ncpu = data.ioc_count;
1448 if (totalsize != NULL)
1449 *totalsize = data.ioc_misc;
1455 lwt_get_string(char *kstr)
1458 struct portal_ioctl_data data;
1462 /* FIXME: this could maintain a symbol table since we expect to be
1463 * looking up the same strings all the time... */
1465 PORTAL_IOC_INIT(data);
1466 data.ioc_pbuf1 = kstr;
1467 data.ioc_plen1 = 1; /* non-zero just to fool portal_ioctl_is_invalid() */
1468 data.ioc_pbuf2 = NULL;
1471 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_LWT_LOOKUP_STRING, &data);
1473 fprintf(stderr, "IOC_PORTAL_LWT_LOOKUP_STRING failed: %s\n",
1478 size = data.ioc_count;
1479 ustr = (char *)malloc(size);
1481 fprintf(stderr, "Can't allocate string storage of size %d\n",
1486 PORTAL_IOC_INIT(data);
1487 data.ioc_pbuf1 = kstr;
1488 data.ioc_plen1 = 1; /* non-zero just to fool portal_ioctl_is_invalid() */
1489 data.ioc_pbuf2 = ustr;
1490 data.ioc_plen2 = size;
1492 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_LWT_LOOKUP_STRING, &data);
1494 fprintf(stderr, "IOC_PORTAL_LWT_LOOKUP_STRING failed: %s\n",
1499 LASSERT(strlen(ustr) == size - 1);
1504 lwt_put_string(char *ustr)
1510 lwt_print(FILE *f, cycles_t t0, cycles_t tlast, double mhz, int cpu, lwt_event_t *e)
1513 char *where = lwt_get_string(e->lwte_where);
1518 sprintf(whenstr, LPD64, e->lwte_when - t0);
1520 fprintf(f, "%#010lx %#010lx %#010lx %#010lx: %#010lx %1d %10.6f %10.2f %s\n",
1521 e->lwte_p1, e->lwte_p2, e->lwte_p3, e->lwte_p4,
1522 (long)e->lwte_task, cpu, (e->lwte_when - t0) / (mhz * 1000000.0),
1523 (t0 == e->lwte_when) ? 0.0 : (e->lwte_when - tlast) / mhz,
1526 lwt_put_string(where);
1532 get_cycles_per_usec ()
1534 FILE *f = fopen ("/proc/cpuinfo", "r");
1539 while (fgets (line, sizeof (line), f) != NULL)
1540 if (sscanf (line, "cpu MHz : %lf", &mhz) == 1) {
1547 fprintf (stderr, "Can't read/parse /proc/cpuinfo\n");
1552 jt_ptl_lwt(int argc, char **argv)
1557 int nevents_per_cpu;
1558 lwt_event_t *events;
1559 lwt_event_t *cpu_event[MAX_CPUS + 1];
1560 lwt_event_t *next_event[MAX_CPUS];
1561 lwt_event_t *first_event[MAX_CPUS];
1572 (strcmp(argv[1], "start") &&
1573 strcmp(argv[1], "stop"))) {
1576 " %s stop [fname]\n", argv[0], argv[0]);
1580 if (!strcmp(argv[1], "start")) {
1582 if (lwt_control(0, 0) != 0)
1586 if (lwt_control(0, 1) != 0)
1590 if (lwt_control(1, 0) != 0)
1596 if (lwt_snapshot(&ncpus, &totalspace, NULL, 0) != 0)
1599 if (ncpus > MAX_CPUS) {
1600 fprintf(stderr, "Too many cpus: %d (%d)\n", ncpus, MAX_CPUS);
1604 events = (lwt_event_t *)malloc(totalspace);
1605 if (events == NULL) {
1606 fprintf(stderr, "Can't allocate %d\n", totalspace);
1610 if (lwt_control(0, 0) != 0) { /* disable */
1615 if (lwt_snapshot(NULL, NULL, events, totalspace)) {
1621 f = fopen (argv[2], "w");
1623 fprintf(stderr, "Can't open %s for writing: %s\n", argv[2], strerror (errno));
1629 mhz = get_cycles_per_usec();
1631 /* carve events into per-cpu slices */
1632 nevents_per_cpu = totalspace / (ncpus * sizeof(lwt_event_t));
1633 for (cpu = 0; cpu <= ncpus; cpu++)
1634 cpu_event[cpu] = &events[cpu * nevents_per_cpu];
1636 /* find the earliest event on each cpu */
1637 for (cpu = 0; cpu < ncpus; cpu++) {
1638 first_event[cpu] = NULL;
1640 for (e = cpu_event[cpu]; e < cpu_event[cpu + 1]; e++) {
1642 if (e->lwte_where == NULL) /* not an event */
1645 if (first_event[cpu] == NULL ||
1646 first_event[cpu]->lwte_when > e->lwte_when)
1647 first_event[cpu] = e;
1650 next_event[cpu] = first_event[cpu];
1654 for (cpu = 0; cpu < ncpus; cpu++) {
1655 e = first_event[cpu];
1656 if (e == NULL) /* no events this cpu */
1659 if (e == cpu_event[cpu])
1660 e = cpu_event[cpu + 1] - 1;
1664 /* If there's an event immediately before the first one, this
1665 * cpu wrapped its event buffer */
1666 if (e->lwte_where == NULL)
1669 /* We should only start outputting events from the most recent
1670 * first event in any wrapped cpu. Events before this time on
1671 * other cpus won't have any events from this CPU to interleave
1673 if (t0 < first_event[cpu]->lwte_when)
1674 t0 = first_event[cpu]->lwte_when;
1678 /* find which cpu has the next event */
1680 for (i = 0; i < ncpus; i++) {
1682 if (next_event[i] == NULL) /* this cpu exhausted */
1686 next_event[i]->lwte_when < next_event[cpu]->lwte_when)
1690 if (cpu < 0) /* all cpus exhausted */
1694 /* no wrapped cpus and this is he first ever event */
1695 t0 = next_event[cpu]->lwte_when;
1698 if (t0 <= next_event[cpu]->lwte_when) {
1699 /* on or after the first event */
1700 rc = lwt_print(f, t0, tlast, mhz, cpu, next_event[cpu]);
1705 tlast = next_event[cpu]->lwte_when;
1708 if (next_event[cpu] == cpu_event[cpu + 1])
1709 next_event[cpu] = cpu_event[cpu];
1711 if (next_event[cpu]->lwte_where == NULL ||
1712 next_event[cpu] == first_event[cpu])
1713 next_event[cpu] = NULL;