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>
41 #include <netinet/in.h>
43 #warning assuming little endian
45 #define __cpu_to_le64(x) ((__u64)(x))
46 #define __le64_to_cpu(x) ((__u64)(x))
47 #define __cpu_to_le32(x) ((__u32)(x))
48 #define __le32_to_cpu(x) ((__u32)(x))
49 #define __cpu_to_le16(x) ((__u16)(x))
50 #define __le16_to_cpu(x) ((__u16)(x))
52 #endif /* __CYGWIN__ */
54 #include <portals/api-support.h>
55 #include <portals/ptlctl.h>
56 #include <portals/list.h>
57 #include <portals/lib-types.h>
58 #include <portals/socknal.h>
61 unsigned int portal_debug;
62 unsigned int portal_printk;
63 unsigned int portal_stack;
64 unsigned int portal_cerror;
66 static unsigned int g_nal = 0;
68 static int g_socket_txmem = 0;
69 static int g_socket_rxmem = 0;
70 static int g_socket_nonagle = 1;
78 static name2num_t nalnames[] = {
84 {"scimac", SCIMACNAL},
88 static cfg_record_cb_t g_record_cb;
91 ptl_set_cfg_record_cb(cfg_record_cb_t cb)
98 pcfg_ioctl(struct portals_cfg *pcfg)
102 if (pcfg->pcfg_nal ==0)
103 pcfg->pcfg_nal = g_nal;
106 rc = g_record_cb(PORTALS_CFG_TYPE, sizeof(*pcfg), pcfg);
108 struct portal_ioctl_data data;
109 PORTAL_IOC_INIT (data);
110 data.ioc_pbuf1 = (char*)pcfg;
111 data.ioc_plen1 = sizeof(*pcfg);
112 /* XXX liblustre hack XXX */
113 data.ioc_nal_cmd = pcfg->pcfg_command;
114 data.ioc_nid = pcfg->pcfg_nid;
116 rc = l_ioctl (PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
125 name2num_lookup_name (name2num_t *table, char *str)
127 while (table->name != NULL)
128 if (!strcmp (str, table->name))
136 name2num_lookup_num (name2num_t *table, int num)
138 while (table->name != NULL)
139 if (num == table->num)
147 ptl_name2nal (char *str)
149 name2num_t *e = name2num_lookup_name (nalnames, str);
151 return ((e == NULL) ? -1 : e->num);
157 name2num_t *e = name2num_lookup_num (nalnames, nal);
159 return ((e == NULL) ? "???" : e->name);
162 static struct hostent *
163 ptl_gethostbyname(char * hname) {
165 he = gethostbyname(hname);
170 fprintf(stderr, "Unable to resolve hostname: %s\n",
174 fprintf(stderr, "gethostbyname error: %s\n",
184 ptl_parse_port (int *port, char *str)
188 *port = strtol (str, &end, 0);
190 if (*end == 0 && /* parsed whole string */
191 *port > 0 && *port < 65536) /* minimal sanity check */
198 ptl_parse_time (time_t *t, char *str)
204 *t = strtol (str, &end, 0);
205 if (*end == 0) /* parsed whole string */
208 memset (&tm, 0, sizeof (tm));
209 n = sscanf (str, "%d-%d-%d-%d:%d:%d",
210 &tm.tm_year, &tm.tm_mon, &tm.tm_mday,
211 &tm.tm_hour, &tm.tm_min, &tm.tm_sec);
215 tm.tm_mon--; /* convert to 0 == Jan */
216 tm.tm_year -= 1900; /* y2k quirk */
217 tm.tm_isdst = -1; /* dunno if it's daylight savings... */
220 if (*t == (time_t)-1)
227 ptl_parse_ipaddr (__u32 *ipaddrp, char *str)
235 if (!strcmp (str, "_all_"))
241 if (sscanf (str, "%d.%d.%d.%d", &a, &b, &c, &d) == 4 &&
242 (a & ~0xff) == 0 && (b & ~0xff) == 0 &&
243 (c & ~0xff) == 0 && (d & ~0xff) == 0)
245 *ipaddrp = (a<<24)|(b<<16)|(c<<8)|d;
249 if ((('a' <= str[0] && str[0] <= 'z') ||
250 ('A' <= str[0] && str[0] <= 'Z')) &&
251 (he = ptl_gethostbyname (str)) != NULL)
253 __u32 addr = *(__u32 *)he->h_addr;
255 *ipaddrp = ntohl(addr); /* HOST byte order */
263 ptl_ipaddr_2_str (__u32 ipaddr, char *str)
268 net_ip = htonl (ipaddr);
269 he = gethostbyaddr (&net_ip, sizeof (net_ip), AF_INET);
273 sprintf (str, "%d.%d.%d.%d",
274 (ipaddr >> 24) & 0xff, (ipaddr >> 16) & 0xff,
275 (ipaddr >> 8) & 0xff, ipaddr & 0xff);
280 ptl_parse_nid (ptl_nid_t *nidp, char *str)
284 unsigned long long ullval;
286 if (!strcmp (str, "_all_")) {
291 if (ptl_parse_ipaddr (&ipaddr, str) == 0) {
292 *nidp = (ptl_nid_t)ipaddr;
296 ullval = strtoull(str, &end, 0);
298 /* parsed whole string */
299 *nidp = (ptl_nid_t)ullval;
307 ptl_nid2str (char *buffer, ptl_nid_t nid)
309 __u32 addr = htonl((__u32)nid); /* back to NETWORK byte order */
310 struct hostent *he = gethostbyaddr ((const char *)&addr, sizeof (addr), AF_INET);
313 strcpy (buffer, he->h_name);
315 sprintf (buffer, LPX64, nid);
323 fprintf (stderr, "Error: you must run the 'network' command first.\n");
330 int g_nal_is_compatible (char *cmd, ...)
335 if (!g_nal_is_set ())
341 nal = va_arg (ap, int);
342 } while (nal != 0 && nal != g_nal);
350 /* Don't complain verbosely if we've not been passed a command
351 * name to complain about! */
352 fprintf (stderr, "Command %s not compatible with nal %s\n",
353 cmd, nal2name (g_nal));
359 sock_write (int cfd, void *buffer, int nob)
363 int rc = write (cfd, buffer, nob);
375 fprintf (stderr, "Unexpected zero sock_write\n");
380 buffer = (char *)buffer + nob;
387 sock_read (int cfd, void *buffer, int nob)
391 int rc = read (cfd, buffer, nob);
401 if (rc == 0) /* EOF */
403 errno = ECONNABORTED;
408 buffer = (char *)buffer + nob;
414 int ptl_initialize(int argc, char **argv)
416 register_ioc_dev(PORTALS_DEV_ID, PORTALS_DEV_PATH);
421 int jt_ptl_network(int argc, char **argv)
427 (nal = ptl_name2nal (argv[1])) >= 0) {
432 fprintf(stderr, "usage: %s \n", argv[0]);
433 for (entry = nalnames; entry->name != NULL; entry++)
434 fprintf (stderr, "%s%s", entry == nalnames ? "<" : "|", entry->name);
435 fprintf(stderr, ">\n");
440 jt_ptl_print_autoconnects (int argc, char **argv)
442 struct portals_cfg pcfg;
447 if (!g_nal_is_compatible (argv[0], SOCKNAL, 0))
450 for (index = 0;;index++) {
451 PCFG_INIT (pcfg, NAL_CMD_GET_AUTOCONN);
452 pcfg.pcfg_count = index;
454 rc = pcfg_ioctl (&pcfg);
458 printf (LPX64"@%s:%d #%d buffer %d "
459 "nonagle %s affinity %s eager %s share %d\n",
460 pcfg.pcfg_nid, ptl_ipaddr_2_str (pcfg.pcfg_id, buffer),
461 pcfg.pcfg_misc, pcfg.pcfg_count, pcfg.pcfg_size,
462 (pcfg.pcfg_flags & 1) ? "on" : "off",
463 (pcfg.pcfg_flags & 2) ? "on" : "off",
464 (pcfg.pcfg_flags & 4) ? "on" : "off",
469 printf ("<no autoconnect routes>\n");
474 jt_ptl_add_autoconnect (int argc, char **argv)
476 struct portals_cfg pcfg;
480 int irq_affinity = 0;
485 if (argc < 4 || argc > 5) {
486 fprintf (stderr, "usage: %s nid ipaddr port [ise]\n", argv[0]);
490 if (!g_nal_is_compatible (argv[0], SOCKNAL, 0))
493 if (ptl_parse_nid (&nid, argv[1]) != 0 ||
494 nid == PTL_NID_ANY) {
495 fprintf (stderr, "Can't parse NID: %s\n", argv[1]);
499 if (ptl_parse_ipaddr (&ip, argv[2]) != 0) {
500 fprintf (stderr, "Can't parse ip addr: %s\n", argv[2]);
504 if (ptl_parse_port (&port, argv[3]) != 0) {
505 fprintf (stderr, "Can't parse port: %s\n", argv[3]);
510 char *opts = argv[4];
524 fprintf (stderr, "Can't parse options: %s\n",
530 PCFG_INIT(pcfg, NAL_CMD_ADD_AUTOCONN);
533 pcfg.pcfg_misc = port;
534 /* only passing one buffer size! */
535 pcfg.pcfg_size = MAX (g_socket_rxmem, g_socket_txmem);
536 pcfg.pcfg_flags = (g_socket_nonagle ? 0x01 : 0) |
537 (irq_affinity ? 0x02 : 0) |
541 rc = pcfg_ioctl (&pcfg);
543 fprintf (stderr, "failed to enable autoconnect: %s\n",
552 jt_ptl_del_autoconnect (int argc, char **argv)
554 struct portals_cfg pcfg;
555 ptl_nid_t nid = PTL_NID_ANY;
562 fprintf (stderr, "usage: %s [nid] [ipaddr] [sk]\n",
567 if (!g_nal_is_compatible (argv[0], SOCKNAL, 0))
571 ptl_parse_nid (&nid, argv[1]) != 0) {
572 fprintf (stderr, "Can't parse nid: %s\n", argv[1]);
577 ptl_parse_ipaddr (&ip, argv[2]) != 0) {
578 fprintf (stderr, "Can't parse ip addr: %s\n", argv[2]);
583 char *opts = argv[3];
594 fprintf (stderr, "Can't parse flags: %s\n",
600 PCFG_INIT(pcfg, NAL_CMD_DEL_AUTOCONN);
603 pcfg.pcfg_flags = (share ? 1 : 0) |
606 rc = pcfg_ioctl (&pcfg);
608 fprintf (stderr, "failed to remove autoconnect route: %s\n",
617 jt_ptl_print_connections (int argc, char **argv)
619 struct portals_cfg pcfg;
624 if (!g_nal_is_compatible (argv[0], SOCKNAL, 0))
627 for (index = 0;;index++) {
628 PCFG_INIT (pcfg, NAL_CMD_GET_CONN);
629 pcfg.pcfg_count = index;
631 rc = pcfg_ioctl (&pcfg);
635 printf (LPX64"@%s:%d:%s\n",
637 ptl_ipaddr_2_str (pcfg.pcfg_id, buffer),
639 (pcfg.pcfg_flags == SOCKNAL_CONN_ANY) ? "A" :
640 (pcfg.pcfg_flags == SOCKNAL_CONN_CONTROL) ? "C" :
641 (pcfg.pcfg_flags == SOCKNAL_CONN_BULK_IN) ? "I" :
642 (pcfg.pcfg_flags == SOCKNAL_CONN_BULK_OUT) ? "O" : "?");
646 printf ("<no connections>\n");
650 int jt_ptl_connect(int argc, char **argv)
652 struct portals_cfg pcfg;
653 struct sockaddr_in srvaddr;
661 int type = SOCKNAL_CONN_ANY;
667 fprintf(stderr, "usage: %s ip port [xibctr]\n", argv[0]);
671 if (!g_nal_is_compatible (argv[0], SOCKNAL, 0))
674 rc = ptl_parse_ipaddr (&ipaddr, argv[1]);
676 fprintf(stderr, "Can't parse hostname: %s\n", argv[1]);
680 if (ptl_parse_port (&port, argv[2]) != 0) {
681 fprintf (stderr, "Can't parse port: %s\n", argv[2]);
686 for (flag = argv[3]; *flag != 0; flag++)
694 if (type != SOCKNAL_CONN_ANY) {
695 fprintf(stderr, "Can't flag type twice\n");
698 type = SOCKNAL_CONN_BULK_IN;
702 if (type != SOCKNAL_CONN_ANY) {
703 fprintf(stderr, "Can't flag type twice\n");
706 type = SOCKNAL_CONN_BULK_OUT;
710 if (type != SOCKNAL_CONN_ANY) {
711 fprintf(stderr, "Can't flag type twice\n");
714 type = SOCKNAL_CONN_CONTROL;
718 fprintf (stderr, "unrecognised flag '%c'\n",
723 memset(&srvaddr, 0, sizeof(srvaddr));
724 srvaddr.sin_family = AF_INET;
725 srvaddr.sin_port = htons(port);
726 srvaddr.sin_addr.s_addr = htonl(ipaddr);
728 fd = socket(PF_INET, SOCK_STREAM, 0);
730 fprintf(stderr, "socket() failed: %s\n", strerror(errno));
734 if (g_socket_nonagle)
737 if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &o, sizeof (o)) != 0) {
738 fprintf(stderr, "cannot disable nagle: %s\n", strerror(errno));
743 if (g_socket_rxmem != 0) {
745 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &o, sizeof (o)) != 0) {
746 fprintf(stderr, "cannot set receive buffer size: %s\n", strerror(errno));
751 if (g_socket_txmem != 0) {
753 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &o, sizeof (o)) != 0) {
754 fprintf(stderr, "cannot set send buffer size: %s\n", strerror(errno));
759 rc = connect(fd, (struct sockaddr *)&srvaddr, sizeof(srvaddr));
761 fprintf(stderr, "connect() failed: %s\n", strerror(errno));
765 olen = sizeof (txmem);
766 if (getsockopt (fd, SOL_SOCKET, SO_SNDBUF, &txmem, &olen) != 0)
767 fprintf (stderr, "Can't get send buffer size: %s\n", strerror (errno));
768 olen = sizeof (rxmem);
769 if (getsockopt (fd, SOL_SOCKET, SO_RCVBUF, &rxmem, &olen) != 0)
770 fprintf (stderr, "Can't get receive buffer size: %s\n", strerror (errno));
771 olen = sizeof (nonagle);
772 if (getsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &nonagle, &olen) != 0)
773 fprintf (stderr, "Can't get nagle: %s\n", strerror (errno));
775 printf("Connected host: %s snd: %d rcv: %d nagle: %s type: %s\n",
776 argv[1], txmem, rxmem, nonagle ? "Disabled" : "Enabled",
777 (type == SOCKNAL_CONN_ANY) ? "A" :
778 (type == SOCKNAL_CONN_CONTROL) ? "C" :
779 (type == SOCKNAL_CONN_BULK_IN) ? "I" :
780 (type == SOCKNAL_CONN_BULK_OUT) ? "O" : "?");
782 PCFG_INIT(pcfg, NAL_CMD_REGISTER_PEER_FD);
783 pcfg.pcfg_nal = g_nal;
785 pcfg.pcfg_flags = bind_irq;
786 pcfg.pcfg_misc = type;
788 rc = pcfg_ioctl(&pcfg);
790 fprintf(stderr, "failed to register fd with portals: %s\n",
796 printf("Connection to %s registered with socknal\n", argv[1]);
800 fprintf(stderr, "close failed: %d\n", rc);
805 int jt_ptl_disconnect(int argc, char **argv)
807 struct portals_cfg pcfg;
808 ptl_nid_t nid = PTL_NID_ANY;
813 fprintf(stderr, "usage: %s [nid] [ipaddr]\n", argv[0]);
817 if (!g_nal_is_compatible (NULL, SOCKNAL, 0))
821 ptl_parse_nid (&nid, argv[1]) != 0) {
822 fprintf (stderr, "Can't parse nid %s\n", argv[1]);
827 ptl_parse_ipaddr (&ipaddr, argv[2]) != 0) {
828 fprintf (stderr, "Can't parse ip addr %s\n", argv[2]);
832 PCFG_INIT(pcfg, NAL_CMD_CLOSE_CONNECTION);
834 pcfg.pcfg_id = ipaddr;
836 rc = pcfg_ioctl(&pcfg);
838 fprintf(stderr, "failed to remove connection: %s\n",
846 int jt_ptl_push_connection (int argc, char **argv)
848 struct portals_cfg pcfg;
850 ptl_nid_t nid = PTL_NID_ANY;
854 fprintf(stderr, "usage: %s [nid] [ip]\n", argv[0]);
858 if (!g_nal_is_compatible (argv[0], SOCKNAL, 0))
862 ptl_parse_nid (&nid, argv[1]) != 0) {
863 fprintf(stderr, "Can't parse nid: %s\n", argv[1]);
868 ptl_parse_ipaddr (&ipaddr, argv[2]) != 0) {
869 fprintf(stderr, "Can't parse ipaddr: %s\n", argv[2]);
872 PCFG_INIT(pcfg, NAL_CMD_PUSH_CONNECTION);
874 pcfg.pcfg_id = ipaddr;
876 rc = pcfg_ioctl(&pcfg);
878 fprintf(stderr, "failed to push connection: %s\n",
887 jt_ptl_print_active_txs (int argc, char **argv)
889 struct portals_cfg pcfg;
893 if (!g_nal_is_compatible (argv[0], QSWNAL, 0))
896 for (index = 0;;index++) {
897 PCFG_INIT(pcfg, NAL_CMD_GET_TXDESC);
898 pcfg.pcfg_count = index;
900 rc = pcfg_ioctl(&pcfg);
904 printf ("%p: %5s payload %6d bytes to "LPX64" via "LPX64" by pid %6d: %s, %s, state %d\n",
906 pcfg.pcfg_count == PTL_MSG_ACK ? "ACK" :
907 pcfg.pcfg_count == PTL_MSG_PUT ? "PUT" :
908 pcfg.pcfg_count == PTL_MSG_GET ? "GET" :
909 pcfg.pcfg_count == PTL_MSG_REPLY ? "REPLY" : "<wierd message>",
914 (pcfg.pcfg_flags & 1) ? "delayed" : "immediate",
915 (pcfg.pcfg_flags & 2) ? "nblk" : "normal",
916 pcfg.pcfg_flags >> 2);
920 printf ("<no active descs>\n");
924 int jt_ptl_ping(int argc, char **argv)
931 struct portal_ioctl_data data;
934 fprintf(stderr, "usage: %s nid [count] [size] [timeout (secs)]\n", argv[0]);
941 if (ptl_parse_nid (&nid, argv[1]) != 0)
943 fprintf (stderr, "Can't parse nid \"%s\"\n", argv[1]);
949 count = atol(argv[2]);
951 if (count < 0 || count > 20000)
953 fprintf(stderr, "are you insane? %ld is a crazy count.\n", count);
962 timeout = atol (argv[4]);
964 PORTAL_IOC_INIT (data);
965 data.ioc_count = count;
966 data.ioc_size = size;
968 data.ioc_nal = g_nal;
969 data.ioc_timeout = timeout;
971 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_PING, &data);
973 fprintf(stderr, "failed to start pinger: %s\n",
980 int jt_ptl_shownid(int argc, char **argv)
982 struct portal_ioctl_data data;
986 fprintf(stderr, "usage: %s\n", argv[0]);
993 PORTAL_IOC_INIT (data);
994 data.ioc_nal = g_nal;
995 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_GET_NID, &data);
997 fprintf(stderr, "getting my NID failed: %s\n",
1000 printf(LPX64"\n", data.ioc_nid);
1004 int jt_ptl_mynid(int argc, char **argv)
1007 char hostname[1024];
1009 struct portals_cfg pcfg;
1013 fprintf(stderr, "usage: %s [NID]\n", argv[0]);
1014 fprintf(stderr, "NID defaults to the primary IP address of the machine.\n");
1018 if (!g_nal_is_set())
1023 else if (gethostname(hostname, sizeof(hostname)) != 0) {
1024 fprintf(stderr, "gethostname failed: %s\n",
1031 rc = ptl_parse_nid (&mynid, nidstr);
1033 fprintf (stderr, "Can't convert '%s' into a NID\n", nidstr);
1037 PCFG_INIT(pcfg, NAL_CMD_REGISTER_MYNID);
1038 pcfg.pcfg_nid = mynid;
1040 rc = pcfg_ioctl(&pcfg);
1042 fprintf(stderr, "setting my NID failed: %s\n",
1045 printf("registered my nid "LPX64" (%s)\n", mynid, hostname);
1050 jt_ptl_fail_nid (int argc, char **argv)
1054 unsigned int threshold;
1055 struct portal_ioctl_data data;
1057 if (argc < 2 || argc > 3)
1059 fprintf (stderr, "usage: %s nid|\"_all_\" [count (0 == mend)]\n", argv[0]);
1063 if (!g_nal_is_set())
1066 if (!strcmp (argv[1], "_all_"))
1068 else if (ptl_parse_nid (&nid, argv[1]) != 0)
1070 fprintf (stderr, "Can't parse nid \"%s\"\n", argv[1]);
1075 threshold = PTL_MD_THRESH_INF;
1076 else if (sscanf (argv[2], "%i", &threshold) != 1) {
1077 fprintf (stderr, "Can't parse count \"%s\"\n", argv[2]);
1081 PORTAL_IOC_INIT (data);
1082 data.ioc_nal = g_nal;
1084 data.ioc_count = threshold;
1086 rc = l_ioctl (PORTALS_DEV_ID, IOC_PORTAL_FAIL_NID, &data);
1088 fprintf (stderr, "IOC_PORTAL_FAIL_NID failed: %s\n",
1091 printf ("%s %s\n", threshold == 0 ? "Unfailing" : "Failing", argv[1]);
1097 jt_ptl_rxmem (int argc, char **argv)
1103 if (Parser_size (&size, argv[1]) != 0 || size < 0)
1105 fprintf (stderr, "Can't parse size %s\n", argv[1]);
1109 g_socket_rxmem = size;
1111 printf ("Socket rmem = %d\n", g_socket_rxmem);
1116 jt_ptl_txmem (int argc, char **argv)
1122 if (Parser_size (&size, argv[1]) != 0 || size < 0)
1124 fprintf (stderr, "Can't parse size %s\n", argv[1]);
1127 g_socket_txmem = size;
1129 printf ("Socket txmem = %d\n", g_socket_txmem);
1134 jt_ptl_nagle (int argc, char **argv)
1140 if (Parser_bool (&enable, argv[1]) != 0)
1142 fprintf (stderr, "Can't parse boolean %s\n", argv[1]);
1145 g_socket_nonagle = !enable;
1147 printf ("Nagle %s\n", g_socket_nonagle ? "disabled" : "enabled");
1152 jt_ptl_add_route (int argc, char **argv)
1154 struct portals_cfg pcfg;
1157 ptl_nid_t gateway_nid;
1162 fprintf (stderr, "usage: %s gateway target [target]\n", argv[0]);
1166 if (!g_nal_is_set())
1169 if (ptl_parse_nid (&gateway_nid, argv[1]) != 0)
1171 fprintf (stderr, "Can't parse gateway NID \"%s\"\n", argv[1]);
1175 if (ptl_parse_nid (&nid1, argv[2]) != 0)
1177 fprintf (stderr, "Can't parse first target NID \"%s\"\n", argv[2]);
1183 else if (ptl_parse_nid (&nid2, argv[3]) != 0)
1185 fprintf (stderr, "Can't parse second target NID \"%s\"\n", argv[4]);
1189 PCFG_INIT(pcfg, NAL_CMD_ADD_ROUTE);
1190 pcfg.pcfg_nid = gateway_nid;
1191 pcfg.pcfg_nal = ROUTER;
1192 pcfg.pcfg_gw_nal = g_nal;
1193 pcfg.pcfg_nid2 = MIN (nid1, nid2);
1194 pcfg.pcfg_nid3 = MAX (nid1, nid2);
1196 rc = pcfg_ioctl(&pcfg);
1199 fprintf (stderr, "NAL_CMD_ADD_ROUTE failed: %s\n", strerror (errno));
1207 jt_ptl_del_route (int argc, char **argv)
1209 struct portals_cfg pcfg;
1211 ptl_nid_t nid1 = PTL_NID_ANY;
1212 ptl_nid_t nid2 = PTL_NID_ANY;
1217 fprintf (stderr, "usage: %s targetNID\n", argv[0]);
1221 if (!g_nal_is_set())
1224 if (ptl_parse_nid (&nid, argv[1]) != 0)
1226 fprintf (stderr, "Can't parse gateway NID \"%s\"\n", argv[1]);
1231 ptl_parse_nid (&nid1, argv[2]) != 0)
1233 fprintf (stderr, "Can't parse target NID \"%s\"\n", argv[2]);
1240 if (ptl_parse_nid (&nid2, argv[3]) != 0) {
1241 fprintf (stderr, "Can't parse target NID \"%s\"\n", argv[3]);
1246 ptl_nid_t tmp = nid1;
1253 PCFG_INIT(pcfg, NAL_CMD_DEL_ROUTE);
1254 pcfg.pcfg_nal = ROUTER;
1255 pcfg.pcfg_gw_nal = g_nal;
1256 pcfg.pcfg_nid = nid;
1257 pcfg.pcfg_nid2 = nid1;
1258 pcfg.pcfg_nid3 = nid2;
1260 rc = pcfg_ioctl(&pcfg);
1263 fprintf (stderr, "NAL_CMD_DEL_ROUTE ("LPX64") failed: %s\n", nid, strerror (errno));
1271 jt_ptl_notify_router (int argc, char **argv)
1273 struct portals_cfg pcfg;
1282 fprintf (stderr, "usage: %s targetNID <up/down> [<time>]\n",
1287 if (ptl_parse_nid (&nid, argv[1]) != 0)
1289 fprintf (stderr, "Can't parse target NID \"%s\"\n", argv[1]);
1293 if (Parser_bool (&enable, argv[2]) != 0) {
1294 fprintf (stderr, "Can't parse boolean %s\n", argv[2]);
1298 gettimeofday(&now, NULL);
1302 } else if (ptl_parse_time (&when, argv[3]) != 0) {
1303 fprintf(stderr, "Can't parse time %s\n"
1304 "Please specify either 'YYYY-MM-DD-HH:MM:SS'\n"
1305 "or an absolute unix time in seconds\n", argv[3]);
1307 } else if (when > now.tv_sec) {
1308 fprintf (stderr, "%s specifies a time in the future\n",
1313 PCFG_INIT(pcfg, NAL_CMD_NOTIFY_ROUTER);
1314 pcfg.pcfg_nal = ROUTER;
1315 pcfg.pcfg_gw_nal = g_nal;
1316 pcfg.pcfg_nid = nid;
1317 pcfg.pcfg_flags = enable;
1318 /* Yeuch; 'cept I need a __u64 on 64 bit machines... */
1319 pcfg.pcfg_nid3 = (__u64)when;
1321 rc = pcfg_ioctl(&pcfg);
1324 fprintf (stderr, "NAL_CMD_NOTIFY_ROUTER ("LPX64") failed: %s\n",
1325 nid, strerror (errno));
1333 jt_ptl_print_routes (int argc, char **argv)
1335 char buffer[3][128];
1336 struct portals_cfg pcfg;
1340 ptl_nid_t gateway_nid;
1345 for (index = 0;;index++)
1347 PCFG_INIT(pcfg, NAL_CMD_GET_ROUTE);
1348 pcfg.pcfg_nal = ROUTER;
1349 pcfg.pcfg_count = index;
1351 rc = pcfg_ioctl(&pcfg);
1355 gateway_nal = pcfg.pcfg_gw_nal;
1356 gateway_nid = pcfg.pcfg_nid;
1357 nid1 = pcfg.pcfg_nid2;
1358 nid2 = pcfg.pcfg_nid3;
1359 alive = pcfg.pcfg_flags;
1361 printf ("%8s %18s : %s - %s, %s\n",
1362 nal2name (gateway_nal),
1363 ptl_nid2str (buffer[0], gateway_nid),
1364 ptl_nid2str (buffer[1], nid1),
1365 ptl_nid2str (buffer[2], nid2),
1366 alive ? "up" : "down");
1372 lwt_control(int enable, int clear)
1374 struct portal_ioctl_data data;
1377 PORTAL_IOC_INIT(data);
1378 data.ioc_flags = enable;
1379 data.ioc_misc = clear;
1381 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_LWT_CONTROL, &data);
1385 fprintf(stderr, "IOC_PORTAL_LWT_CONTROL failed: %s\n",
1391 lwt_snapshot(cycles_t *now, int *ncpu, int *totalsize,
1392 lwt_event_t *events, int size)
1394 struct portal_ioctl_data data;
1397 PORTAL_IOC_INIT(data);
1398 data.ioc_pbuf1 = (char *)events;
1399 data.ioc_plen1 = size;
1401 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_LWT_SNAPSHOT, &data);
1403 fprintf(stderr, "IOC_PORTAL_LWT_SNAPSHOT failed: %s\n",
1408 LASSERT (data.ioc_count != 0);
1409 LASSERT (data.ioc_misc != 0);
1412 *now = data.ioc_nid;
1415 *ncpu = data.ioc_count;
1417 if (totalsize != NULL)
1418 *totalsize = data.ioc_misc;
1424 lwt_get_string(char *kstr)
1427 struct portal_ioctl_data data;
1431 /* FIXME: this could maintain a symbol table since we expect to be
1432 * looking up the same strings all the time... */
1434 PORTAL_IOC_INIT(data);
1435 data.ioc_pbuf1 = kstr;
1436 data.ioc_plen1 = 1; /* non-zero just to fool portal_ioctl_is_invalid() */
1437 data.ioc_pbuf2 = NULL;
1440 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_LWT_LOOKUP_STRING, &data);
1442 fprintf(stderr, "IOC_PORTAL_LWT_LOOKUP_STRING failed: %s\n",
1447 size = data.ioc_count;
1448 ustr = (char *)malloc(size);
1450 fprintf(stderr, "Can't allocate string storage of size %d\n",
1455 PORTAL_IOC_INIT(data);
1456 data.ioc_pbuf1 = kstr;
1457 data.ioc_plen1 = 1; /* non-zero just to fool portal_ioctl_is_invalid() */
1458 data.ioc_pbuf2 = ustr;
1459 data.ioc_plen2 = size;
1461 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_LWT_LOOKUP_STRING, &data);
1463 fprintf(stderr, "IOC_PORTAL_LWT_LOOKUP_STRING failed: %s\n",
1468 LASSERT(strlen(ustr) == size - 1);
1473 lwt_put_string(char *ustr)
1479 lwt_print(FILE *f, cycles_t t0, cycles_t tlast, double mhz, int cpu, lwt_event_t *e)
1482 char *where = lwt_get_string(e->lwte_where);
1487 sprintf(whenstr, LPD64, e->lwte_when - t0);
1489 fprintf(f, "%#010lx %#010lx %#010lx %#010lx: %#010lx %1d %10.6f %10.2f %s\n",
1490 e->lwte_p1, e->lwte_p2, e->lwte_p3, e->lwte_p4,
1491 (long)e->lwte_task, cpu, (e->lwte_when - t0) / (mhz * 1000000.0),
1492 (t0 == e->lwte_when) ? 0.0 : (e->lwte_when - tlast) / mhz,
1495 lwt_put_string(where);
1501 get_cycles_per_usec ()
1503 FILE *f = fopen ("/proc/cpuinfo", "r");
1508 while (fgets (line, sizeof (line), f) != NULL)
1509 if (sscanf (line, "cpu MHz : %lf", &mhz) == 1) {
1516 fprintf (stderr, "Can't read/parse /proc/cpuinfo\n");
1521 jt_ptl_lwt(int argc, char **argv)
1525 int nevents_per_cpu;
1526 lwt_event_t *events;
1527 lwt_event_t *cpu_event[LWT_MAX_CPUS + 1];
1528 lwt_event_t *next_event[LWT_MAX_CPUS];
1529 lwt_event_t *first_event[LWT_MAX_CPUS];
1538 struct timeval tvnow;
1539 int printed_date = 0;
1543 (strcmp(argv[1], "start") &&
1544 strcmp(argv[1], "stop"))) {
1547 " %s stop [fname]\n", argv[0], argv[0]);
1551 if (!strcmp(argv[1], "start")) {
1553 if (lwt_control(0, 0) != 0)
1557 if (lwt_control(0, 1) != 0)
1561 if (lwt_control(1, 0) != 0)
1567 if (lwt_snapshot(NULL, &ncpus, &totalspace, NULL, 0) != 0)
1570 if (ncpus > LWT_MAX_CPUS) {
1571 fprintf(stderr, "Too many cpus: %d (%d)\n",
1572 ncpus, LWT_MAX_CPUS);
1576 events = (lwt_event_t *)malloc(totalspace);
1577 if (events == NULL) {
1578 fprintf(stderr, "Can't allocate %d\n", totalspace);
1582 if (lwt_control(0, 0) != 0) { /* disable */
1587 if (lwt_snapshot(&tnow, NULL, NULL, events, totalspace)) {
1592 /* we want this time to be sampled at snapshot time */
1593 gettimeofday(&tvnow, NULL);
1596 f = fopen (argv[2], "w");
1598 fprintf(stderr, "Can't open %s for writing: %s\n", argv[2], strerror (errno));
1604 mhz = get_cycles_per_usec();
1606 /* carve events into per-cpu slices */
1607 nevents_per_cpu = totalspace / (ncpus * sizeof(lwt_event_t));
1608 for (cpu = 0; cpu <= ncpus; cpu++)
1609 cpu_event[cpu] = &events[cpu * nevents_per_cpu];
1611 /* find the earliest event on each cpu */
1612 for (cpu = 0; cpu < ncpus; cpu++) {
1613 first_event[cpu] = NULL;
1615 for (e = cpu_event[cpu]; e < cpu_event[cpu + 1]; e++) {
1617 if (e->lwte_where == NULL) /* not an event */
1620 if (first_event[cpu] == NULL ||
1621 first_event[cpu]->lwte_when > e->lwte_when)
1622 first_event[cpu] = e;
1625 next_event[cpu] = first_event[cpu];
1629 for (cpu = 0; cpu < ncpus; cpu++) {
1630 e = first_event[cpu];
1631 if (e == NULL) /* no events this cpu */
1634 if (e == cpu_event[cpu])
1635 e = cpu_event[cpu + 1] - 1;
1639 /* If there's an event immediately before the first one, this
1640 * cpu wrapped its event buffer */
1641 if (e->lwte_where == NULL)
1644 /* We should only start outputting events from the most recent
1645 * first event in any wrapped cpu. Events before this time on
1646 * other cpus won't have any events from this CPU to interleave
1648 if (t0 < first_event[cpu]->lwte_when)
1649 t0 = first_event[cpu]->lwte_when;
1653 /* find which cpu has the next event */
1655 for (i = 0; i < ncpus; i++) {
1657 if (next_event[i] == NULL) /* this cpu exhausted */
1661 next_event[i]->lwte_when < next_event[cpu]->lwte_when)
1665 if (cpu < 0) /* all cpus exhausted */
1669 /* no wrapped cpus and this is he first ever event */
1670 t0 = next_event[cpu]->lwte_when;
1673 if (t0 <= next_event[cpu]->lwte_when) {
1674 /* on or after the first event */
1675 if (!printed_date) {
1676 cycles_t du = (tnow - t0) / mhz;
1677 time_t then = tvnow.tv_sec - du/1000000;
1679 if (du % 1000000 > tvnow.tv_usec)
1682 fprintf(f, "%s", ctime(&then));
1686 rc = lwt_print(f, t0, tlast, mhz, cpu, next_event[cpu]);
1691 tlast = next_event[cpu]->lwte_when;
1694 if (next_event[cpu] == cpu_event[cpu + 1])
1695 next_event[cpu] = cpu_event[cpu];
1697 if (next_event[cpu]->lwte_where == NULL ||
1698 next_event[cpu] == first_event[cpu])
1699 next_event[cpu] = NULL;
1709 int jt_ptl_memhog(int argc, char **argv)
1711 static int gfp = 0; /* sticky! */
1713 struct portal_ioctl_data data;
1719 fprintf(stderr, "usage: %s <npages> [<GFP flags>]\n", argv[0]);
1723 count = strtol(argv[1], &end, 0);
1724 if (count < 0 || *end != 0) {
1725 fprintf(stderr, "Can't parse page count '%s'\n", argv[1]);
1730 rc = strtol(argv[2], &end, 0);
1732 fprintf(stderr, "Can't parse gfp flags '%s'\n", argv[2]);
1738 PORTAL_IOC_INIT(data);
1739 data.ioc_count = count;
1740 data.ioc_flags = gfp;
1741 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_MEMHOG, &data);
1744 fprintf(stderr, "memhog %d failed: %s\n", count, strerror(errno));
1748 printf("memhog %d OK\n", count);