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);
301 fprintf (stderr, "Command %s not compatible with nal %s\n",
302 cmd, nal2name (g_nal));
307 sock_write (int cfd, void *buffer, int nob)
311 int rc = write (cfd, buffer, nob);
323 fprintf (stderr, "Unexpected zero sock_write\n");
328 buffer = (char *)buffer + nob;
335 sock_read (int cfd, void *buffer, int nob)
339 int rc = read (cfd, buffer, nob);
349 if (rc == 0) /* EOF */
351 errno = ECONNABORTED;
356 buffer = (char *)buffer + nob;
362 int ptl_initialize(int argc, char **argv)
364 register_ioc_dev(PORTALS_DEV_ID, PORTALS_DEV_PATH);
369 int jt_ptl_network(int argc, char **argv)
375 (nal = ptl_name2nal (argv[1])) >= 0) {
380 fprintf(stderr, "usage: %s \n", argv[0]);
381 for (entry = nalnames; entry->name != NULL; entry++)
382 fprintf (stderr, "%s%s", entry == nalnames ? "<" : "|", entry->name);
383 fprintf(stderr, ">\n");
388 jt_ptl_print_autoconnects (int argc, char **argv)
390 struct portal_ioctl_data data;
395 if (!g_nal_is_compatible (argv[0], SOCKNAL, 0))
398 for (index = 0;;index++) {
399 PORTAL_IOC_INIT (data);
400 data.ioc_nal = g_nal;
401 data.ioc_nal_cmd = NAL_CMD_GET_AUTOCONN;
402 data.ioc_count = index;
404 rc = l_ioctl (PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
408 printf (LPX64"@%s:%d #%d buffer %d nonagle %s xchg %s "
409 "affinity %s eager %s share %d\n",
410 data.ioc_nid, ptl_ipaddr_2_str (data.ioc_id, buffer),
411 data.ioc_misc, data.ioc_count, data.ioc_size,
412 (data.ioc_flags & 1) ? "on" : "off",
413 (data.ioc_flags & 2) ? "on" : "off",
414 (data.ioc_flags & 4) ? "on" : "off",
415 (data.ioc_flags & 8) ? "on" : "off",
420 printf ("<no autoconnect routes>\n");
425 jt_ptl_add_autoconnect (int argc, char **argv)
427 struct portal_ioctl_data data;
431 int xchange_nids = 0;
432 int irq_affinity = 0;
437 if (argc < 4 || argc > 5) {
438 fprintf (stderr, "usage: %s nid ipaddr port [ixse]\n", argv[0]);
442 if (!g_nal_is_compatible (argv[0], SOCKNAL, 0))
445 if (ptl_parse_nid (&nid, argv[1]) != 0 ||
446 nid == PTL_NID_ANY) {
447 fprintf (stderr, "Can't parse NID: %s\n", argv[1]);
451 if (ptl_parse_ipaddr (&ip, argv[2]) != 0) {
452 fprintf (stderr, "Can't parse ip addr: %s\n", argv[2]);
456 if (ptl_parse_port (&port, argv[3]) != 0) {
457 fprintf (stderr, "Can't parse port: %s\n", argv[3]);
462 char *opts = argv[4];
479 fprintf (stderr, "Can't parse options: %s\n",
485 PORTAL_IOC_INIT (data);
486 data.ioc_nal = g_nal;
487 data.ioc_nal_cmd = NAL_CMD_ADD_AUTOCONN;
490 data.ioc_misc = port;
491 /* only passing one buffer size! */
492 data.ioc_size = MAX (g_socket_rxmem, g_socket_txmem);
493 data.ioc_flags = (g_socket_nonagle ? 0x01 : 0) |
494 (xchange_nids ? 0x02 : 0) |
495 (irq_affinity ? 0x04 : 0) |
499 rc = l_ioctl (PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
501 fprintf (stderr, "failed to enable autoconnect: %s\n",
510 jt_ptl_del_autoconnect (int argc, char **argv)
512 struct portal_ioctl_data data;
513 ptl_nid_t nid = PTL_NID_ANY;
520 fprintf (stderr, "usage: %s [nid] [ipaddr] [sk]\n",
525 if (!g_nal_is_compatible (argv[0], SOCKNAL, 0))
529 ptl_parse_nid (&nid, argv[1]) != 0) {
530 fprintf (stderr, "Can't parse nid: %s\n", argv[1]);
535 ptl_parse_ipaddr (&ip, argv[2]) != 0) {
536 fprintf (stderr, "Can't parse ip addr: %s\n", argv[2]);
541 char *opts = argv[3];
552 fprintf (stderr, "Can't parse flags: %s\n",
558 PORTAL_IOC_INIT (data);
559 data.ioc_nal = g_nal;
560 data.ioc_nal_cmd = NAL_CMD_DEL_AUTOCONN;
563 data.ioc_flags = (share ? 1 : 0) |
566 rc = l_ioctl (PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
568 fprintf (stderr, "failed to remove autoconnect route: %s\n",
577 jt_ptl_print_connections (int argc, char **argv)
579 struct portal_ioctl_data data;
584 if (!g_nal_is_compatible (argv[0], SOCKNAL, 0))
587 for (index = 0;;index++) {
588 PORTAL_IOC_INIT (data);
589 data.ioc_nal = g_nal;
590 data.ioc_nal_cmd = NAL_CMD_GET_CONN;
591 data.ioc_count = index;
593 rc = l_ioctl (PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
597 printf (LPX64"@%s:%d\n",
599 ptl_ipaddr_2_str (data.ioc_id, buffer),
604 printf ("<no connections>\n");
609 exchange_nids (int cfd, ptl_nid_t my_nid, ptl_nid_t *peer_nid)
613 ptl_magicversion_t *hmv = (ptl_magicversion_t *)&hdr.dest_nid;
615 LASSERT (sizeof (*hmv) == sizeof (hdr.dest_nid));
617 memset (&hdr, 0, sizeof (hdr));
619 hmv->magic = __cpu_to_le32 (PORTALS_PROTO_MAGIC);
620 hmv->version_major = __cpu_to_le16 (PORTALS_PROTO_VERSION_MAJOR);
621 hmv->version_minor = __cpu_to_le16 (PORTALS_PROTO_VERSION_MINOR);
623 hdr.src_nid = __cpu_to_le64 (my_nid);
624 hdr.type = __cpu_to_le32 (PTL_MSG_HELLO);
626 /* Assume there's sufficient socket buffering for a portals HELLO header */
627 rc = sock_write (cfd, &hdr, sizeof (hdr));
629 perror ("Can't send initial HELLO");
633 /* First few bytes down the wire are the portals protocol magic and
634 * version, no matter what protocol version we're running. */
636 rc = sock_read (cfd, hmv, sizeof (*hmv));
638 perror ("Can't read from peer");
642 if (hmv->magic != __cpu_to_le32 (PORTALS_PROTO_MAGIC)) {
643 fprintf (stderr, "Bad magic %#08x (%#08x expected)\n",
644 __le32_to_cpu (hmv->magic), PORTALS_PROTO_MAGIC);
648 if (hmv->version_major != __cpu_to_le16 (PORTALS_PROTO_VERSION_MAJOR) ||
649 hmv->version_minor != __cpu_to_le16 (PORTALS_PROTO_VERSION_MINOR)) {
650 fprintf (stderr, "Incompatible protocol version %d.%d (%d.%d expected)\n",
651 __le16_to_cpu (hmv->version_major),
652 __le16_to_cpu (hmv->version_minor),
653 PORTALS_PROTO_VERSION_MAJOR,
654 PORTALS_PROTO_VERSION_MINOR);
657 /* version 0 sends magic/version as the dest_nid of a 'hello' header,
658 * so read the rest of it in now... */
659 LASSERT (PORTALS_PROTO_VERSION_MAJOR == 0);
660 rc = sock_read (cfd, hmv + 1, sizeof (hdr) - sizeof (*hmv));
662 perror ("Can't read rest of HELLO hdr");
666 /* ...and check we got what we expected */
667 if (hdr.type != __cpu_to_le32 (PTL_MSG_HELLO) ||
668 PTL_HDR_LENGTH (&hdr) != __cpu_to_le32 (0)) {
669 fprintf (stderr, "Expecting a HELLO hdr with 0 payload,"
670 " but got type %d with %d payload\n",
671 __le32_to_cpu (hdr.type),
672 __le32_to_cpu (PTL_HDR_LENGTH (&hdr)));
676 *peer_nid = __le64_to_cpu (hdr.src_nid);
680 int jt_ptl_connect(int argc, char **argv)
683 struct portal_ioctl_data data;
684 struct sockaddr_in srvaddr;
692 int xchange_nids = 0;
698 fprintf(stderr, "usage: %s ip port [xi]\n", argv[0]);
702 if (!g_nal_is_compatible (argv[0], SOCKNAL, TOENAL, 0))
705 rc = ptl_parse_ipaddr (&ipaddr, argv[1]);
707 fprintf(stderr, "Can't parse hostname: %s\n", argv[1]);
711 if (ptl_parse_port (&port, argv[2]) != 0) {
712 fprintf (stderr, "Can't parse port: %s\n", argv[2]);
717 for (flag = argv[3]; *flag != 0; flag++)
729 fprintf (stderr, "unrecognised flag '%c'\n",
734 memset(&srvaddr, 0, sizeof(srvaddr));
735 srvaddr.sin_family = AF_INET;
736 srvaddr.sin_port = htons(port);
737 srvaddr.sin_addr.s_addr = htonl(ipaddr);
739 fd = socket(PF_INET, SOCK_STREAM, 0);
741 fprintf(stderr, "socket() failed: %s\n", strerror(errno));
745 if (g_socket_nonagle)
748 if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &o, sizeof (o)) != 0) {
749 fprintf(stderr, "cannot disable nagle: %s\n", strerror(errno));
754 if (g_socket_rxmem != 0) {
756 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &o, sizeof (o)) != 0) {
757 fprintf(stderr, "cannot set receive buffer size: %s\n", strerror(errno));
762 if (g_socket_txmem != 0) {
764 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &o, sizeof (o)) != 0) {
765 fprintf(stderr, "cannot set send buffer size: %s\n", strerror(errno));
770 rc = connect(fd, (struct sockaddr *)&srvaddr, sizeof(srvaddr));
772 fprintf(stderr, "connect() failed: %s\n", strerror(errno));
776 olen = sizeof (txmem);
777 if (getsockopt (fd, SOL_SOCKET, SO_SNDBUF, &txmem, &olen) != 0)
778 fprintf (stderr, "Can't get send buffer size: %s\n", strerror (errno));
779 olen = sizeof (rxmem);
780 if (getsockopt (fd, SOL_SOCKET, SO_RCVBUF, &rxmem, &olen) != 0)
781 fprintf (stderr, "Can't get receive buffer size: %s\n", strerror (errno));
782 olen = sizeof (nonagle);
783 if (getsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &nonagle, &olen) != 0)
784 fprintf (stderr, "Can't get nagle: %s\n", strerror (errno));
789 PORTAL_IOC_INIT (data);
790 data.ioc_nal = g_nal;
791 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_GET_NID, &data);
793 fprintf (stderr, "failed to get my nid: %s\n",
799 rc = exchange_nids (fd, data.ioc_nid, &peer_nid);
805 printf("Connected host: %s NID "LPX64" snd: %d rcv: %d nagle: %s\n", argv[1],
806 peer_nid, txmem, rxmem, nonagle ? "Disabled" : "Enabled");
808 PORTAL_IOC_INIT(data);
810 data.ioc_nal = g_nal;
811 data.ioc_nal_cmd = NAL_CMD_REGISTER_PEER_FD;
812 data.ioc_nid = peer_nid;
813 data.ioc_flags = bind_irq;
815 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
817 fprintf(stderr, "failed to register fd with portals: %s\n",
823 printf("Connection to "LPX64" registered with socknal\n", peer_nid);
827 fprintf(stderr, "close failed: %d\n", rc);
832 int jt_ptl_disconnect(int argc, char **argv)
834 struct portal_ioctl_data data;
835 ptl_nid_t nid = PTL_NID_ANY;
840 fprintf(stderr, "usage: %s [nid] [ipaddr]\n", argv[0]);
844 if (!g_nal_is_compatible (argv[0], SOCKNAL, TOENAL, 0))
848 ptl_parse_nid (&nid, argv[1]) != 0) {
849 fprintf (stderr, "Can't parse nid %s\n", argv[1]);
854 ptl_parse_ipaddr (&ipaddr, argv[2]) != 0) {
855 fprintf (stderr, "Can't parse ip addr %s\n", argv[2]);
859 PORTAL_IOC_INIT(data);
860 data.ioc_nal = g_nal;
861 data.ioc_nal_cmd = NAL_CMD_CLOSE_CONNECTION;
863 data.ioc_id = ipaddr;
865 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
867 fprintf(stderr, "failed to remove connection: %s\n",
875 int jt_ptl_push_connection (int argc, char **argv)
877 struct portal_ioctl_data data;
879 ptl_nid_t nid = PTL_NID_ANY;
883 fprintf(stderr, "usage: %s [nid] [ip]\n", argv[0]);
887 if (!g_nal_is_compatible (argv[0], SOCKNAL, TOENAL, 0))
891 ptl_parse_nid (&nid, argv[1]) != 0) {
892 fprintf(stderr, "Can't parse nid: %s\n", argv[1]);
897 ptl_parse_ipaddr (&ipaddr, argv[2]) != 0) {
898 fprintf(stderr, "Can't parse ipaddr: %s\n", argv[2]);
901 PORTAL_IOC_INIT(data);
902 data.ioc_nal = g_nal;
903 data.ioc_nal_cmd = NAL_CMD_PUSH_CONNECTION;
905 data.ioc_id = ipaddr;
907 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
909 fprintf(stderr, "failed to push connection: %s\n",
918 jt_ptl_print_active_txs (int argc, char **argv)
920 struct portal_ioctl_data data;
924 if (!g_nal_is_compatible (argv[0], QSWNAL, 0))
927 for (index = 0;;index++) {
928 PORTAL_IOC_INIT (data);
929 data.ioc_nal = g_nal;
930 data.ioc_nal_cmd = NAL_CMD_GET_TXDESC;
931 data.ioc_count = index;
933 rc = l_ioctl (PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
937 printf ("%p: %5s payload %6d bytes to "LPX64" via "LPX64" by pid %6d: %s,%s,%s\n",
939 data.ioc_count == PTL_MSG_ACK ? "ACK" :
940 data.ioc_count == PTL_MSG_PUT ? "PUT" :
941 data.ioc_count == PTL_MSG_GET ? "GET" :
942 data.ioc_count == PTL_MSG_REPLY ? "REPLY" : "<wierd message>",
947 (data.ioc_flags & 1) ? "delayed" : "active",
948 (data.ioc_flags & 2) ? "forwarding" : "sending",
949 (data.ioc_flags & 4) ? "nblk" : "normal");
953 printf ("<no active descs>\n");
957 int jt_ptl_ping(int argc, char **argv)
964 struct portal_ioctl_data data;
967 fprintf(stderr, "usage: %s nid [count] [size] [timeout (secs)]\n", argv[0]);
974 if (ptl_parse_nid (&nid, argv[1]) != 0)
976 fprintf (stderr, "Can't parse nid \"%s\"\n", argv[1]);
982 count = atol(argv[2]);
984 if (count < 0 || count > 20000)
986 fprintf(stderr, "are you insane? %ld is a crazy count.\n", count);
995 timeout = atol (argv[4]);
997 PORTAL_IOC_INIT (data);
998 data.ioc_count = count;
999 data.ioc_size = size;
1001 data.ioc_nal = g_nal;
1002 data.ioc_timeout = timeout;
1004 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_PING, &data);
1006 fprintf(stderr, "failed to start pinger: %s\n",
1013 int jt_ptl_shownid(int argc, char **argv)
1015 struct portal_ioctl_data data;
1019 fprintf(stderr, "usage: %s\n", argv[0]);
1023 if (!g_nal_is_set())
1026 PORTAL_IOC_INIT (data);
1027 data.ioc_nal = g_nal;
1028 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_GET_NID, &data);
1030 fprintf(stderr, "getting my NID failed: %s\n",
1033 printf(LPX64"\n", data.ioc_nid);
1037 int jt_ptl_mynid(int argc, char **argv)
1040 char hostname[1024];
1042 struct portal_ioctl_data data;
1046 fprintf(stderr, "usage: %s [NID]\n", argv[0]);
1047 fprintf(stderr, "NID defaults to the primary IP address of the machine.\n");
1051 if (!g_nal_is_set())
1056 else if (gethostname(hostname, sizeof(hostname)) != 0) {
1057 fprintf(stderr, "gethostname failed: %s\n",
1064 rc = ptl_parse_nid (&mynid, nidstr);
1066 fprintf (stderr, "Can't convert '%s' into a NID\n", nidstr);
1070 PORTAL_IOC_INIT(data);
1071 data.ioc_nid = mynid;
1072 data.ioc_nal = g_nal;
1073 data.ioc_nal_cmd = NAL_CMD_REGISTER_MYNID;
1075 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
1077 fprintf(stderr, "setting my NID failed: %s\n",
1080 printf("registered my nid "LPX64" (%s)\n", mynid, hostname);
1085 jt_ptl_fail_nid (int argc, char **argv)
1089 unsigned int threshold;
1090 struct portal_ioctl_data data;
1092 if (argc < 2 || argc > 3)
1094 fprintf (stderr, "usage: %s nid|\"_all_\" [count (0 == mend)]\n", argv[0]);
1098 if (!g_nal_is_set())
1101 if (!strcmp (argv[1], "_all_"))
1103 else if (ptl_parse_nid (&nid, argv[1]) != 0)
1105 fprintf (stderr, "Can't parse nid \"%s\"\n", argv[1]);
1110 threshold = PTL_MD_THRESH_INF;
1111 else if (sscanf (argv[2], "%i", &threshold) != 1) {
1112 fprintf (stderr, "Can't parse count \"%s\"\n", argv[2]);
1116 PORTAL_IOC_INIT (data);
1117 data.ioc_nal = g_nal;
1119 data.ioc_count = threshold;
1121 rc = l_ioctl (PORTALS_DEV_ID, IOC_PORTAL_FAIL_NID, &data);
1123 fprintf (stderr, "IOC_PORTAL_FAIL_NID failed: %s\n",
1126 printf ("%s %s\n", threshold == 0 ? "Unfailing" : "Failing", argv[1]);
1132 jt_ptl_rxmem (int argc, char **argv)
1138 if (Parser_size (&size, argv[1]) != 0 || size < 0)
1140 fprintf (stderr, "Can't parse size %s\n", argv[1]);
1144 g_socket_rxmem = size;
1146 printf ("Socket rmem = %d\n", g_socket_rxmem);
1151 jt_ptl_txmem (int argc, char **argv)
1157 if (Parser_size (&size, argv[1]) != 0 || size < 0)
1159 fprintf (stderr, "Can't parse size %s\n", argv[1]);
1162 g_socket_txmem = size;
1164 printf ("Socket txmem = %d\n", g_socket_txmem);
1169 jt_ptl_nagle (int argc, char **argv)
1175 if (Parser_bool (&enable, argv[1]) != 0)
1177 fprintf (stderr, "Can't parse boolean %s\n", argv[1]);
1180 g_socket_nonagle = !enable;
1182 printf ("Nagle %s\n", g_socket_nonagle ? "disabled" : "enabled");
1187 jt_ptl_add_route (int argc, char **argv)
1189 struct portal_ioctl_data data;
1192 ptl_nid_t gateway_nid;
1197 fprintf (stderr, "usage: %s gateway target [target]\n", argv[0]);
1201 if (!g_nal_is_set())
1204 if (ptl_parse_nid (&gateway_nid, argv[1]) != 0)
1206 fprintf (stderr, "Can't parse gateway NID \"%s\"\n", argv[1]);
1210 if (ptl_parse_nid (&nid1, argv[2]) != 0)
1212 fprintf (stderr, "Can't parse first target NID \"%s\"\n", argv[2]);
1218 else if (ptl_parse_nid (&nid2, argv[3]) != 0)
1220 fprintf (stderr, "Can't parse second target NID \"%s\"\n", argv[4]);
1224 PORTAL_IOC_INIT(data);
1225 data.ioc_nid = gateway_nid;
1226 data.ioc_nal = g_nal;
1227 data.ioc_nid2 = MIN (nid1, nid2);
1228 data.ioc_nid3 = MAX (nid1, nid2);
1230 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_ADD_ROUTE, &data);
1233 fprintf (stderr, "IOC_PORTAL_ADD_ROUTE failed: %s\n", strerror (errno));
1241 jt_ptl_del_route (int argc, char **argv)
1243 struct portal_ioctl_data data;
1245 ptl_nid_t nid1 = PTL_NID_ANY;
1246 ptl_nid_t nid2 = PTL_NID_ANY;
1251 fprintf (stderr, "usage: %s targetNID\n", argv[0]);
1255 if (!g_nal_is_set())
1258 if (ptl_parse_nid (&nid, argv[1]) != 0)
1260 fprintf (stderr, "Can't parse gateway NID \"%s\"\n", argv[1]);
1265 ptl_parse_nid (&nid1, argv[2]) != 0)
1267 fprintf (stderr, "Can't parse target NID \"%s\"\n", argv[2]);
1274 if (ptl_parse_nid (&nid2, argv[3]) != 0) {
1275 fprintf (stderr, "Can't parse target NID \"%s\"\n", argv[3]);
1280 ptl_nid_t tmp = nid1;
1287 PORTAL_IOC_INIT(data);
1288 data.ioc_nal = g_nal;
1290 data.ioc_nid2 = nid1;
1291 data.ioc_nid3 = nid2;
1293 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_DEL_ROUTE, &data);
1296 fprintf (stderr, "IOC_PORTAL_DEL_ROUTE ("LPX64") failed: %s\n", nid, strerror (errno));
1304 jt_ptl_notify_router (int argc, char **argv)
1306 struct portal_ioctl_data data;
1315 fprintf (stderr, "usage: %s targetNID <up/down> [<time>]\n",
1320 if (ptl_parse_nid (&nid, argv[1]) != 0)
1322 fprintf (stderr, "Can't parse target NID \"%s\"\n", argv[1]);
1326 if (Parser_bool (&enable, argv[2]) != 0) {
1327 fprintf (stderr, "Can't parse boolean %s\n", argv[2]);
1331 gettimeofday(&now, NULL);
1335 } else if (ptl_parse_time (&when, argv[3]) != 0) {
1336 fprintf(stderr, "Can't parse time %s\n"
1337 "Please specify either 'YYYY-MM-DD HH:MM:SS'\n"
1338 "or an absolute unix time in seconds\n", argv[3]);
1340 } else if (when > now.tv_sec) {
1341 fprintf (stderr, "%s specifies a time in the future\n",
1346 PORTAL_IOC_INIT(data);
1347 data.ioc_nal = g_nal;
1349 data.ioc_flags = enable;
1350 /* Yeuch; 'cept I need a __u64 on 64 bit machines... */
1351 data.ioc_nid3 = (__u64)when;
1353 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_NOTIFY_ROUTER, &data);
1356 fprintf (stderr, "IOC_PORTAL_NOTIFY_ROUTER ("LPX64") failed: %s\n",
1357 nid, strerror (errno));
1365 jt_ptl_print_routes (int argc, char **argv)
1367 char buffer[3][128];
1368 struct portal_ioctl_data data;
1372 ptl_nid_t gateway_nid;
1377 for (index = 0;;index++)
1379 PORTAL_IOC_INIT(data);
1380 data.ioc_count = index;
1382 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_GET_ROUTE, &data);
1386 gateway_nal = data.ioc_nal;
1387 gateway_nid = data.ioc_nid;
1388 nid1 = data.ioc_nid2;
1389 nid2 = data.ioc_nid3;
1390 alive = data.ioc_flags;
1392 printf ("%8s %18s : %s - %s, %s\n",
1393 nal2name (gateway_nal),
1394 ptl_nid2str (buffer[0], gateway_nid),
1395 ptl_nid2str (buffer[1], nid1),
1396 ptl_nid2str (buffer[2], nid2),
1397 alive ? "up" : "down");
1403 lwt_control(int enable, int clear)
1405 struct portal_ioctl_data data;
1408 PORTAL_IOC_INIT(data);
1409 data.ioc_flags = enable;
1410 data.ioc_misc = clear;
1412 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_LWT_CONTROL, &data);
1416 fprintf(stderr, "IOC_PORTAL_LWT_CONTROL failed: %s\n",
1422 lwt_snapshot(int *ncpu, int *totalsize, lwt_event_t *events, int size)
1424 struct portal_ioctl_data data;
1427 PORTAL_IOC_INIT(data);
1428 data.ioc_pbuf1 = (char *)events;
1429 data.ioc_plen1 = size;
1431 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_LWT_SNAPSHOT, &data);
1433 fprintf(stderr, "IOC_PORTAL_LWT_SNAPSHOT failed: %s\n",
1438 LASSERT (data.ioc_count != 0);
1439 LASSERT (data.ioc_misc != 0);
1442 *ncpu = data.ioc_count;
1444 if (totalsize != NULL)
1445 *totalsize = data.ioc_misc;
1451 lwt_get_string(char *kstr)
1454 struct portal_ioctl_data data;
1458 /* FIXME: this could maintain a symbol table since we expect to be
1459 * looking up the same strings all the time... */
1461 PORTAL_IOC_INIT(data);
1462 data.ioc_pbuf1 = kstr;
1463 data.ioc_plen1 = 1; /* non-zero just to fool portal_ioctl_is_invalid() */
1464 data.ioc_pbuf2 = NULL;
1467 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_LWT_LOOKUP_STRING, &data);
1469 fprintf(stderr, "IOC_PORTAL_LWT_LOOKUP_STRING failed: %s\n",
1474 size = data.ioc_count;
1475 ustr = (char *)malloc(size);
1477 fprintf(stderr, "Can't allocate string storage of size %d\n",
1482 PORTAL_IOC_INIT(data);
1483 data.ioc_pbuf1 = kstr;
1484 data.ioc_plen1 = 1; /* non-zero just to fool portal_ioctl_is_invalid() */
1485 data.ioc_pbuf2 = ustr;
1486 data.ioc_plen2 = size;
1488 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_LWT_LOOKUP_STRING, &data);
1490 fprintf(stderr, "IOC_PORTAL_LWT_LOOKUP_STRING failed: %s\n",
1495 LASSERT(strlen(ustr) == size - 1);
1500 lwt_put_string(char *ustr)
1506 lwt_print(FILE *f, cycles_t t0, cycles_t tlast, double mhz, int cpu, lwt_event_t *e)
1509 char *where = lwt_get_string(e->lwte_where);
1514 sprintf(whenstr, LPD64, e->lwte_when - t0);
1516 fprintf(f, "%#010lx %#010lx %#010lx %#010lx: %#010lx %1d %10.6f %10.2f %s\n",
1517 e->lwte_p1, e->lwte_p2, e->lwte_p3, e->lwte_p4,
1518 (long)e->lwte_task, cpu, (e->lwte_when - t0) / (mhz * 1000000.0),
1519 (t0 == e->lwte_when) ? 0.0 : (e->lwte_when - tlast) / mhz,
1522 lwt_put_string(where);
1528 get_cycles_per_usec ()
1530 FILE *f = fopen ("/proc/cpuinfo", "r");
1535 while (fgets (line, sizeof (line), f) != NULL)
1536 if (sscanf (line, "cpu MHz : %lf", &mhz) == 1) {
1543 fprintf (stderr, "Can't read/parse /proc/cpuinfo\n");
1548 jt_ptl_lwt(int argc, char **argv)
1553 int nevents_per_cpu;
1554 lwt_event_t *events;
1555 lwt_event_t *cpu_event[MAX_CPUS + 1];
1556 lwt_event_t *next_event[MAX_CPUS];
1557 lwt_event_t *first_event[MAX_CPUS];
1568 (strcmp(argv[1], "start") &&
1569 strcmp(argv[1], "stop"))) {
1572 " %s stop [fname]\n", argv[0], argv[0]);
1576 if (!strcmp(argv[1], "start")) {
1578 if (lwt_control(0, 0) != 0)
1582 if (lwt_control(0, 1) != 0)
1586 if (lwt_control(1, 0) != 0)
1592 if (lwt_snapshot(&ncpus, &totalspace, NULL, 0) != 0)
1595 if (ncpus > MAX_CPUS) {
1596 fprintf(stderr, "Too many cpus: %d (%d)\n", ncpus, MAX_CPUS);
1600 events = (lwt_event_t *)malloc(totalspace);
1601 if (events == NULL) {
1602 fprintf(stderr, "Can't allocate %d\n", totalspace);
1606 if (lwt_control(0, 0) != 0) { /* disable */
1611 if (lwt_snapshot(NULL, NULL, events, totalspace)) {
1617 f = fopen (argv[2], "w");
1619 fprintf(stderr, "Can't open %s for writing: %s\n", argv[2], strerror (errno));
1625 mhz = get_cycles_per_usec();
1627 /* carve events into per-cpu slices */
1628 nevents_per_cpu = totalspace / (ncpus * sizeof(lwt_event_t));
1629 for (cpu = 0; cpu <= ncpus; cpu++)
1630 cpu_event[cpu] = &events[cpu * nevents_per_cpu];
1632 /* find the earliest event on each cpu */
1633 for (cpu = 0; cpu < ncpus; cpu++) {
1634 first_event[cpu] = NULL;
1636 for (e = cpu_event[cpu]; e < cpu_event[cpu + 1]; e++) {
1638 if (e->lwte_where == NULL) /* not an event */
1641 if (first_event[cpu] == NULL ||
1642 first_event[cpu]->lwte_when > e->lwte_when)
1643 first_event[cpu] = e;
1646 next_event[cpu] = first_event[cpu];
1650 for (cpu = 0; cpu < ncpus; cpu++) {
1651 e = first_event[cpu];
1652 if (e == NULL) /* no events this cpu */
1655 if (e == cpu_event[cpu])
1656 e = cpu_event[cpu + 1] - 1;
1660 /* If there's an event immediately before the first one, this
1661 * cpu wrapped its event buffer */
1662 if (e->lwte_where == NULL)
1665 /* We should only start outputting events from the most recent
1666 * first event in any wrapped cpu. Events before this time on
1667 * other cpus won't have any events from this CPU to interleave
1669 if (t0 < first_event[cpu]->lwte_when)
1670 t0 = first_event[cpu]->lwte_when;
1674 /* find which cpu has the next event */
1676 for (i = 0; i < ncpus; i++) {
1678 if (next_event[i] == NULL) /* this cpu exhausted */
1682 next_event[i]->lwte_when < next_event[cpu]->lwte_when)
1686 if (cpu < 0) /* all cpus exhausted */
1690 /* no wrapped cpus and this is he first ever event */
1691 t0 = next_event[cpu]->lwte_when;
1694 if (t0 <= next_event[cpu]->lwte_when) {
1695 /* on or after the first event */
1696 rc = lwt_print(f, t0, tlast, mhz, cpu, next_event[cpu]);
1701 tlast = next_event[cpu]->lwte_when;
1704 if (next_event[cpu] == cpu_event[cpu + 1])
1705 next_event[cpu] = cpu_event[cpu];
1707 if (next_event[cpu]->lwte_where == NULL ||
1708 next_event[cpu] == first_event[cpu])
1709 next_event[cpu] = NULL;