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>
43 #include <portals/socknal.h>
46 unsigned int portal_debug;
47 unsigned int portal_printk;
48 unsigned int portal_stack;
49 unsigned int portal_cerror;
51 static unsigned int g_nal = 0;
53 static int g_socket_txmem = 0;
54 static int g_socket_rxmem = 0;
55 static int g_socket_nonagle = 1;
63 static name2num_t nalnames[] = {
70 {"scimac", SCIMACNAL},
74 static cfg_record_cb_t g_record_cb;
77 ptl_set_cfg_record_cb(cfg_record_cb_t cb)
84 pcfg_ioctl(struct portals_cfg *pcfg)
88 if (pcfg->pcfg_nal ==0)
89 pcfg->pcfg_nal = g_nal;
92 rc = g_record_cb(PORTALS_CFG_TYPE, sizeof(*pcfg), pcfg);
94 struct portal_ioctl_data data;
95 PORTAL_IOC_INIT (data);
96 data.ioc_pbuf1 = (char*)pcfg;
97 data.ioc_plen1 = sizeof(*pcfg);
99 rc = l_ioctl (PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
108 name2num_lookup_name (name2num_t *table, char *str)
110 while (table->name != NULL)
111 if (!strcmp (str, table->name))
119 name2num_lookup_num (name2num_t *table, int num)
121 while (table->name != NULL)
122 if (num == table->num)
130 ptl_name2nal (char *str)
132 name2num_t *e = name2num_lookup_name (nalnames, str);
134 return ((e == NULL) ? -1 : e->num);
140 name2num_t *e = name2num_lookup_num (nalnames, nal);
142 return ((e == NULL) ? "???" : e->name);
145 static struct hostent *
146 ptl_gethostbyname(char * hname) {
148 he = gethostbyname(hname);
153 fprintf(stderr, "Unable to resolve hostname: %s\n",
157 fprintf(stderr, "gethostbyname error: %s\n",
167 ptl_parse_port (int *port, char *str)
171 *port = strtol (str, &end, 0);
173 if (*end == 0 && /* parsed whole string */
174 *port > 0 && *port < 65536) /* minimal sanity check */
181 ptl_parse_time (time_t *t, char *str)
187 *t = strtol (str, &end, 0);
188 if (*end == 0) /* parsed whole string */
191 memset (&tm, 0, sizeof (tm));
192 n = sscanf (str, "%d-%d-%d-%d:%d:%d",
193 &tm.tm_year, &tm.tm_mon, &tm.tm_mday,
194 &tm.tm_hour, &tm.tm_min, &tm.tm_sec);
198 tm.tm_mon--; /* convert to 0 == Jan */
199 tm.tm_year -= 1900; /* y2k quirk */
200 tm.tm_isdst = -1; /* dunno if it's daylight savings... */
203 if (*t == (time_t)-1)
210 ptl_parse_ipaddr (__u32 *ipaddrp, char *str)
218 if (!strcmp (str, "_all_"))
224 if (sscanf (str, "%d.%d.%d.%d", &a, &b, &c, &d) == 4 &&
225 (a & ~0xff) == 0 && (b & ~0xff) == 0 &&
226 (c & ~0xff) == 0 && (d & ~0xff) == 0)
228 *ipaddrp = (a<<24)|(b<<16)|(c<<8)|d;
232 if ((('a' <= str[0] && str[0] <= 'z') ||
233 ('A' <= str[0] && str[0] <= 'Z')) &&
234 (he = ptl_gethostbyname (str)) != NULL)
236 __u32 addr = *(__u32 *)he->h_addr;
238 *ipaddrp = ntohl(addr); /* HOST byte order */
246 ptl_ipaddr_2_str (__u32 ipaddr, char *str)
251 net_ip = htonl (ipaddr);
252 he = gethostbyaddr (&net_ip, sizeof (net_ip), AF_INET);
256 sprintf (str, "%d.%d.%d.%d",
257 (ipaddr >> 24) & 0xff, (ipaddr >> 16) & 0xff,
258 (ipaddr >> 8) & 0xff, ipaddr & 0xff);
263 ptl_parse_nid (ptl_nid_t *nidp, char *str)
267 unsigned long long ullval;
269 if (!strcmp (str, "_all_")) {
274 if (ptl_parse_ipaddr (&ipaddr, str) == 0) {
275 *nidp = (ptl_nid_t)ipaddr;
279 ullval = strtoull(str, &end, 0);
281 /* parsed whole string */
282 *nidp = (ptl_nid_t)ullval;
290 ptl_nid2str (char *buffer, ptl_nid_t nid)
292 __u32 addr = htonl((__u32)nid); /* back to NETWORK byte order */
293 struct hostent *he = gethostbyaddr ((const char *)&addr, sizeof (addr), AF_INET);
296 strcpy (buffer, he->h_name);
298 sprintf (buffer, LPX64, nid);
306 fprintf (stderr, "Error: you must run the 'network' command first.\n");
313 int g_nal_is_compatible (char *cmd, ...)
318 if (!g_nal_is_set ())
324 nal = va_arg (ap, int);
325 } while (nal != 0 && nal != g_nal);
333 /* Don't complain verbosely if we've not been passed a command
334 * name to complain about! */
335 fprintf (stderr, "Command %s not compatible with nal %s\n",
336 cmd, nal2name (g_nal));
342 sock_write (int cfd, void *buffer, int nob)
346 int rc = write (cfd, buffer, nob);
358 fprintf (stderr, "Unexpected zero sock_write\n");
363 buffer = (char *)buffer + nob;
370 sock_read (int cfd, void *buffer, int nob)
374 int rc = read (cfd, buffer, nob);
384 if (rc == 0) /* EOF */
386 errno = ECONNABORTED;
391 buffer = (char *)buffer + nob;
397 int ptl_initialize(int argc, char **argv)
399 register_ioc_dev(PORTALS_DEV_ID, PORTALS_DEV_PATH);
404 int jt_ptl_network(int argc, char **argv)
410 (nal = ptl_name2nal (argv[1])) >= 0) {
415 fprintf(stderr, "usage: %s \n", argv[0]);
416 for (entry = nalnames; entry->name != NULL; entry++)
417 fprintf (stderr, "%s%s", entry == nalnames ? "<" : "|", entry->name);
418 fprintf(stderr, ">\n");
423 jt_ptl_print_autoconnects (int argc, char **argv)
425 struct portals_cfg pcfg;
430 if (!g_nal_is_compatible (argv[0], SOCKNAL, 0))
433 for (index = 0;;index++) {
434 PCFG_INIT (pcfg, NAL_CMD_GET_AUTOCONN);
435 pcfg.pcfg_count = index;
437 rc = pcfg_ioctl (&pcfg);
441 printf (LPX64"@%s:%d #%d buffer %d "
442 "nonagle %s affinity %s eager %s share %d\n",
443 pcfg.pcfg_nid, ptl_ipaddr_2_str (pcfg.pcfg_id, buffer),
444 pcfg.pcfg_misc, pcfg.pcfg_count, pcfg.pcfg_size,
445 (pcfg.pcfg_flags & 1) ? "on" : "off",
446 (pcfg.pcfg_flags & 2) ? "on" : "off",
447 (pcfg.pcfg_flags & 4) ? "on" : "off",
452 printf ("<no autoconnect routes>\n");
457 jt_ptl_add_autoconnect (int argc, char **argv)
459 struct portals_cfg pcfg;
463 int irq_affinity = 0;
468 if (argc < 4 || argc > 5) {
469 fprintf (stderr, "usage: %s nid ipaddr port [ise]\n", argv[0]);
473 if (!g_nal_is_compatible (argv[0], SOCKNAL, 0))
476 if (ptl_parse_nid (&nid, argv[1]) != 0 ||
477 nid == PTL_NID_ANY) {
478 fprintf (stderr, "Can't parse NID: %s\n", argv[1]);
482 if (ptl_parse_ipaddr (&ip, argv[2]) != 0) {
483 fprintf (stderr, "Can't parse ip addr: %s\n", argv[2]);
487 if (ptl_parse_port (&port, argv[3]) != 0) {
488 fprintf (stderr, "Can't parse port: %s\n", argv[3]);
493 char *opts = argv[4];
507 fprintf (stderr, "Can't parse options: %s\n",
513 PCFG_INIT(pcfg, NAL_CMD_ADD_AUTOCONN);
516 pcfg.pcfg_misc = port;
517 /* only passing one buffer size! */
518 pcfg.pcfg_size = MAX (g_socket_rxmem, g_socket_txmem);
519 pcfg.pcfg_flags = (g_socket_nonagle ? 0x01 : 0) |
520 (irq_affinity ? 0x02 : 0) |
524 rc = pcfg_ioctl (&pcfg);
526 fprintf (stderr, "failed to enable autoconnect: %s\n",
535 jt_ptl_del_autoconnect (int argc, char **argv)
537 struct portals_cfg pcfg;
538 ptl_nid_t nid = PTL_NID_ANY;
545 fprintf (stderr, "usage: %s [nid] [ipaddr] [sk]\n",
550 if (!g_nal_is_compatible (argv[0], SOCKNAL, 0))
554 ptl_parse_nid (&nid, argv[1]) != 0) {
555 fprintf (stderr, "Can't parse nid: %s\n", argv[1]);
560 ptl_parse_ipaddr (&ip, argv[2]) != 0) {
561 fprintf (stderr, "Can't parse ip addr: %s\n", argv[2]);
566 char *opts = argv[3];
577 fprintf (stderr, "Can't parse flags: %s\n",
583 PCFG_INIT(pcfg, NAL_CMD_DEL_AUTOCONN);
586 pcfg.pcfg_flags = (share ? 1 : 0) |
589 rc = pcfg_ioctl (&pcfg);
591 fprintf (stderr, "failed to remove autoconnect route: %s\n",
600 jt_ptl_print_connections (int argc, char **argv)
602 struct portals_cfg pcfg;
607 if (!g_nal_is_compatible (argv[0], SOCKNAL, 0))
610 for (index = 0;;index++) {
611 PCFG_INIT (pcfg, NAL_CMD_GET_CONN);
612 pcfg.pcfg_count = index;
614 rc = pcfg_ioctl (&pcfg);
618 printf (LPX64"@%s:%d:%s\n",
620 ptl_ipaddr_2_str (pcfg.pcfg_id, buffer),
622 (pcfg.pcfg_flags == SOCKNAL_CONN_ANY) ? "A" :
623 (pcfg.pcfg_flags == SOCKNAL_CONN_CONTROL) ? "C" :
624 (pcfg.pcfg_flags == SOCKNAL_CONN_BULK_IN) ? "I" :
625 (pcfg.pcfg_flags == SOCKNAL_CONN_BULK_OUT) ? "O" : "?");
629 printf ("<no connections>\n");
633 int jt_ptl_connect(int argc, char **argv)
635 struct portals_cfg pcfg;
636 struct sockaddr_in srvaddr;
644 int type = SOCKNAL_CONN_ANY;
650 fprintf(stderr, "usage: %s ip port [xibctr]\n", argv[0]);
654 if (!g_nal_is_compatible (argv[0], SOCKNAL, TOENAL, 0))
657 rc = ptl_parse_ipaddr (&ipaddr, argv[1]);
659 fprintf(stderr, "Can't parse hostname: %s\n", argv[1]);
663 if (ptl_parse_port (&port, argv[2]) != 0) {
664 fprintf (stderr, "Can't parse port: %s\n", argv[2]);
669 for (flag = argv[3]; *flag != 0; flag++)
677 if (type != SOCKNAL_CONN_ANY) {
678 fprintf(stderr, "Can't flag type twice\n");
681 type = SOCKNAL_CONN_BULK_IN;
685 if (type != SOCKNAL_CONN_ANY) {
686 fprintf(stderr, "Can't flag type twice\n");
689 type = SOCKNAL_CONN_BULK_OUT;
693 if (type != SOCKNAL_CONN_ANY) {
694 fprintf(stderr, "Can't flag type twice\n");
697 type = SOCKNAL_CONN_CONTROL;
701 fprintf (stderr, "unrecognised flag '%c'\n",
706 memset(&srvaddr, 0, sizeof(srvaddr));
707 srvaddr.sin_family = AF_INET;
708 srvaddr.sin_port = htons(port);
709 srvaddr.sin_addr.s_addr = htonl(ipaddr);
711 fd = socket(PF_INET, SOCK_STREAM, 0);
713 fprintf(stderr, "socket() failed: %s\n", strerror(errno));
717 if (g_socket_nonagle)
720 if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &o, sizeof (o)) != 0) {
721 fprintf(stderr, "cannot disable nagle: %s\n", strerror(errno));
726 if (g_socket_rxmem != 0) {
728 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &o, sizeof (o)) != 0) {
729 fprintf(stderr, "cannot set receive buffer size: %s\n", strerror(errno));
734 if (g_socket_txmem != 0) {
736 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &o, sizeof (o)) != 0) {
737 fprintf(stderr, "cannot set send buffer size: %s\n", strerror(errno));
742 rc = connect(fd, (struct sockaddr *)&srvaddr, sizeof(srvaddr));
744 fprintf(stderr, "connect() failed: %s\n", strerror(errno));
748 olen = sizeof (txmem);
749 if (getsockopt (fd, SOL_SOCKET, SO_SNDBUF, &txmem, &olen) != 0)
750 fprintf (stderr, "Can't get send buffer size: %s\n", strerror (errno));
751 olen = sizeof (rxmem);
752 if (getsockopt (fd, SOL_SOCKET, SO_RCVBUF, &rxmem, &olen) != 0)
753 fprintf (stderr, "Can't get receive buffer size: %s\n", strerror (errno));
754 olen = sizeof (nonagle);
755 if (getsockopt (fd, IPPROTO_TCP, TCP_NODELAY, &nonagle, &olen) != 0)
756 fprintf (stderr, "Can't get nagle: %s\n", strerror (errno));
758 printf("Connected host: %s snd: %d rcv: %d nagle: %s type: %s\n",
759 argv[1], txmem, rxmem, nonagle ? "Disabled" : "Enabled",
760 (type == SOCKNAL_CONN_ANY) ? "A" :
761 (type == SOCKNAL_CONN_CONTROL) ? "C" :
762 (type == SOCKNAL_CONN_BULK_IN) ? "I" :
763 (type == SOCKNAL_CONN_BULK_OUT) ? "O" : "?");
765 PCFG_INIT(pcfg, NAL_CMD_REGISTER_PEER_FD);
766 pcfg.pcfg_nal = g_nal;
768 pcfg.pcfg_flags = bind_irq;
769 pcfg.pcfg_misc = type;
771 rc = pcfg_ioctl(&pcfg);
773 fprintf(stderr, "failed to register fd with portals: %s\n",
779 printf("Connection to %s registered with socknal\n", argv[1]);
783 fprintf(stderr, "close failed: %d\n", rc);
788 int jt_ptl_disconnect(int argc, char **argv)
790 struct portals_cfg pcfg;
791 ptl_nid_t nid = PTL_NID_ANY;
796 fprintf(stderr, "usage: %s [nid] [ipaddr]\n", argv[0]);
800 if (!g_nal_is_compatible (NULL, SOCKNAL, TOENAL, 0))
804 ptl_parse_nid (&nid, argv[1]) != 0) {
805 fprintf (stderr, "Can't parse nid %s\n", argv[1]);
810 ptl_parse_ipaddr (&ipaddr, argv[2]) != 0) {
811 fprintf (stderr, "Can't parse ip addr %s\n", argv[2]);
815 PCFG_INIT(pcfg, NAL_CMD_CLOSE_CONNECTION);
817 pcfg.pcfg_id = ipaddr;
819 rc = pcfg_ioctl(&pcfg);
821 fprintf(stderr, "failed to remove connection: %s\n",
829 int jt_ptl_push_connection (int argc, char **argv)
831 struct portals_cfg pcfg;
833 ptl_nid_t nid = PTL_NID_ANY;
837 fprintf(stderr, "usage: %s [nid] [ip]\n", argv[0]);
841 if (!g_nal_is_compatible (argv[0], SOCKNAL, TOENAL, 0))
845 ptl_parse_nid (&nid, argv[1]) != 0) {
846 fprintf(stderr, "Can't parse nid: %s\n", argv[1]);
851 ptl_parse_ipaddr (&ipaddr, argv[2]) != 0) {
852 fprintf(stderr, "Can't parse ipaddr: %s\n", argv[2]);
855 PCFG_INIT(pcfg, NAL_CMD_PUSH_CONNECTION);
857 pcfg.pcfg_id = ipaddr;
859 rc = pcfg_ioctl(&pcfg);
861 fprintf(stderr, "failed to push connection: %s\n",
870 jt_ptl_print_active_txs (int argc, char **argv)
872 struct portals_cfg pcfg;
876 if (!g_nal_is_compatible (argv[0], QSWNAL, 0))
879 for (index = 0;;index++) {
880 PCFG_INIT(pcfg, NAL_CMD_GET_TXDESC);
881 pcfg.pcfg_count = index;
883 rc = pcfg_ioctl(&pcfg);
887 printf ("%p: %5s payload %6d bytes to "LPX64" via "LPX64" by pid %6d: %s, %s, state %d\n",
889 pcfg.pcfg_count == PTL_MSG_ACK ? "ACK" :
890 pcfg.pcfg_count == PTL_MSG_PUT ? "PUT" :
891 pcfg.pcfg_count == PTL_MSG_GET ? "GET" :
892 pcfg.pcfg_count == PTL_MSG_REPLY ? "REPLY" : "<wierd message>",
897 (pcfg.pcfg_flags & 1) ? "delayed" : "immediate",
898 (pcfg.pcfg_flags & 2) ? "nblk" : "normal",
899 pcfg.pcfg_flags >> 2);
903 printf ("<no active descs>\n");
907 int jt_ptl_ping(int argc, char **argv)
914 struct portal_ioctl_data data;
917 fprintf(stderr, "usage: %s nid [count] [size] [timeout (secs)]\n", argv[0]);
924 if (ptl_parse_nid (&nid, argv[1]) != 0)
926 fprintf (stderr, "Can't parse nid \"%s\"\n", argv[1]);
932 count = atol(argv[2]);
934 if (count < 0 || count > 20000)
936 fprintf(stderr, "are you insane? %ld is a crazy count.\n", count);
945 timeout = atol (argv[4]);
947 PORTAL_IOC_INIT (data);
948 data.ioc_count = count;
949 data.ioc_size = size;
951 data.ioc_nal = g_nal;
952 data.ioc_timeout = timeout;
954 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_PING, &data);
956 fprintf(stderr, "failed to start pinger: %s\n",
963 int jt_ptl_shownid(int argc, char **argv)
965 struct portal_ioctl_data data;
969 fprintf(stderr, "usage: %s\n", argv[0]);
976 PORTAL_IOC_INIT (data);
977 data.ioc_nal = g_nal;
978 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_GET_NID, &data);
980 fprintf(stderr, "getting my NID failed: %s\n",
983 printf(LPX64"\n", data.ioc_nid);
987 int jt_ptl_mynid(int argc, char **argv)
992 struct portals_cfg pcfg;
996 fprintf(stderr, "usage: %s [NID]\n", argv[0]);
997 fprintf(stderr, "NID defaults to the primary IP address of the machine.\n");
1001 if (!g_nal_is_set())
1006 else if (gethostname(hostname, sizeof(hostname)) != 0) {
1007 fprintf(stderr, "gethostname failed: %s\n",
1014 rc = ptl_parse_nid (&mynid, nidstr);
1016 fprintf (stderr, "Can't convert '%s' into a NID\n", nidstr);
1020 PCFG_INIT(pcfg, NAL_CMD_REGISTER_MYNID);
1021 pcfg.pcfg_nid = mynid;
1023 rc = pcfg_ioctl(&pcfg);
1025 fprintf(stderr, "setting my NID failed: %s\n",
1028 printf("registered my nid "LPX64" (%s)\n", mynid, hostname);
1033 jt_ptl_fail_nid (int argc, char **argv)
1037 unsigned int threshold;
1038 struct portal_ioctl_data data;
1040 if (argc < 2 || argc > 3)
1042 fprintf (stderr, "usage: %s nid|\"_all_\" [count (0 == mend)]\n", argv[0]);
1046 if (!g_nal_is_set())
1049 if (!strcmp (argv[1], "_all_"))
1051 else if (ptl_parse_nid (&nid, argv[1]) != 0)
1053 fprintf (stderr, "Can't parse nid \"%s\"\n", argv[1]);
1058 threshold = PTL_MD_THRESH_INF;
1059 else if (sscanf (argv[2], "%i", &threshold) != 1) {
1060 fprintf (stderr, "Can't parse count \"%s\"\n", argv[2]);
1064 PORTAL_IOC_INIT (data);
1065 data.ioc_nal = g_nal;
1067 data.ioc_count = threshold;
1069 rc = l_ioctl (PORTALS_DEV_ID, IOC_PORTAL_FAIL_NID, &data);
1071 fprintf (stderr, "IOC_PORTAL_FAIL_NID failed: %s\n",
1074 printf ("%s %s\n", threshold == 0 ? "Unfailing" : "Failing", argv[1]);
1080 jt_ptl_rxmem (int argc, char **argv)
1086 if (Parser_size (&size, argv[1]) != 0 || size < 0)
1088 fprintf (stderr, "Can't parse size %s\n", argv[1]);
1092 g_socket_rxmem = size;
1094 printf ("Socket rmem = %d\n", g_socket_rxmem);
1099 jt_ptl_txmem (int argc, char **argv)
1105 if (Parser_size (&size, argv[1]) != 0 || size < 0)
1107 fprintf (stderr, "Can't parse size %s\n", argv[1]);
1110 g_socket_txmem = size;
1112 printf ("Socket txmem = %d\n", g_socket_txmem);
1117 jt_ptl_nagle (int argc, char **argv)
1123 if (Parser_bool (&enable, argv[1]) != 0)
1125 fprintf (stderr, "Can't parse boolean %s\n", argv[1]);
1128 g_socket_nonagle = !enable;
1130 printf ("Nagle %s\n", g_socket_nonagle ? "disabled" : "enabled");
1135 jt_ptl_add_route (int argc, char **argv)
1137 struct portals_cfg pcfg;
1140 ptl_nid_t gateway_nid;
1145 fprintf (stderr, "usage: %s gateway target [target]\n", argv[0]);
1149 if (!g_nal_is_set())
1152 if (ptl_parse_nid (&gateway_nid, argv[1]) != 0)
1154 fprintf (stderr, "Can't parse gateway NID \"%s\"\n", argv[1]);
1158 if (ptl_parse_nid (&nid1, argv[2]) != 0)
1160 fprintf (stderr, "Can't parse first target NID \"%s\"\n", argv[2]);
1166 else if (ptl_parse_nid (&nid2, argv[3]) != 0)
1168 fprintf (stderr, "Can't parse second target NID \"%s\"\n", argv[4]);
1172 PCFG_INIT(pcfg, NAL_CMD_ADD_ROUTE);
1173 pcfg.pcfg_nid = gateway_nid;
1174 pcfg.pcfg_nal = ROUTER;
1175 pcfg.pcfg_gw_nal = g_nal;
1176 pcfg.pcfg_nid2 = MIN (nid1, nid2);
1177 pcfg.pcfg_nid3 = MAX (nid1, nid2);
1179 rc = pcfg_ioctl(&pcfg);
1182 fprintf (stderr, "NAL_CMD_ADD_ROUTE failed: %s\n", strerror (errno));
1190 jt_ptl_del_route (int argc, char **argv)
1192 struct portals_cfg pcfg;
1194 ptl_nid_t nid1 = PTL_NID_ANY;
1195 ptl_nid_t nid2 = PTL_NID_ANY;
1200 fprintf (stderr, "usage: %s targetNID\n", argv[0]);
1204 if (!g_nal_is_set())
1207 if (ptl_parse_nid (&nid, argv[1]) != 0)
1209 fprintf (stderr, "Can't parse gateway NID \"%s\"\n", argv[1]);
1214 ptl_parse_nid (&nid1, argv[2]) != 0)
1216 fprintf (stderr, "Can't parse target NID \"%s\"\n", argv[2]);
1223 if (ptl_parse_nid (&nid2, argv[3]) != 0) {
1224 fprintf (stderr, "Can't parse target NID \"%s\"\n", argv[3]);
1229 ptl_nid_t tmp = nid1;
1236 PCFG_INIT(pcfg, NAL_CMD_DEL_ROUTE);
1237 pcfg.pcfg_nal = ROUTER;
1238 pcfg.pcfg_gw_nal = g_nal;
1239 pcfg.pcfg_nid = nid;
1240 pcfg.pcfg_nid2 = nid1;
1241 pcfg.pcfg_nid3 = nid2;
1243 rc = pcfg_ioctl(&pcfg);
1246 fprintf (stderr, "NAL_CMD_DEL_ROUTE ("LPX64") failed: %s\n", nid, strerror (errno));
1254 jt_ptl_notify_router (int argc, char **argv)
1256 struct portals_cfg pcfg;
1265 fprintf (stderr, "usage: %s targetNID <up/down> [<time>]\n",
1270 if (ptl_parse_nid (&nid, argv[1]) != 0)
1272 fprintf (stderr, "Can't parse target NID \"%s\"\n", argv[1]);
1276 if (Parser_bool (&enable, argv[2]) != 0) {
1277 fprintf (stderr, "Can't parse boolean %s\n", argv[2]);
1281 gettimeofday(&now, NULL);
1285 } else if (ptl_parse_time (&when, argv[3]) != 0) {
1286 fprintf(stderr, "Can't parse time %s\n"
1287 "Please specify either 'YYYY-MM-DD-HH:MM:SS'\n"
1288 "or an absolute unix time in seconds\n", argv[3]);
1290 } else if (when > now.tv_sec) {
1291 fprintf (stderr, "%s specifies a time in the future\n",
1296 PCFG_INIT(pcfg, NAL_CMD_NOTIFY_ROUTER);
1297 pcfg.pcfg_nal = ROUTER;
1298 pcfg.pcfg_gw_nal = g_nal;
1299 pcfg.pcfg_nid = nid;
1300 pcfg.pcfg_flags = enable;
1301 /* Yeuch; 'cept I need a __u64 on 64 bit machines... */
1302 pcfg.pcfg_nid3 = (__u64)when;
1304 rc = pcfg_ioctl(&pcfg);
1307 fprintf (stderr, "NAL_CMD_NOTIFY_ROUTER ("LPX64") failed: %s\n",
1308 nid, strerror (errno));
1316 jt_ptl_print_routes (int argc, char **argv)
1318 char buffer[3][128];
1319 struct portals_cfg pcfg;
1323 ptl_nid_t gateway_nid;
1328 for (index = 0;;index++)
1330 PCFG_INIT(pcfg, NAL_CMD_GET_ROUTE);
1331 pcfg.pcfg_nal = ROUTER;
1332 pcfg.pcfg_count = index;
1334 rc = pcfg_ioctl(&pcfg);
1338 gateway_nal = pcfg.pcfg_gw_nal;
1339 gateway_nid = pcfg.pcfg_nid;
1340 nid1 = pcfg.pcfg_nid2;
1341 nid2 = pcfg.pcfg_nid3;
1342 alive = pcfg.pcfg_flags;
1344 printf ("%8s %18s : %s - %s, %s\n",
1345 nal2name (gateway_nal),
1346 ptl_nid2str (buffer[0], gateway_nid),
1347 ptl_nid2str (buffer[1], nid1),
1348 ptl_nid2str (buffer[2], nid2),
1349 alive ? "up" : "down");
1355 lwt_control(int enable, int clear)
1357 struct portal_ioctl_data data;
1360 PORTAL_IOC_INIT(data);
1361 data.ioc_flags = enable;
1362 data.ioc_misc = clear;
1364 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_LWT_CONTROL, &data);
1368 fprintf(stderr, "IOC_PORTAL_LWT_CONTROL failed: %s\n",
1374 lwt_snapshot(cycles_t *now, int *ncpu, int *totalsize,
1375 lwt_event_t *events, int size)
1377 struct portal_ioctl_data data;
1380 PORTAL_IOC_INIT(data);
1381 data.ioc_pbuf1 = (char *)events;
1382 data.ioc_plen1 = size;
1384 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_LWT_SNAPSHOT, &data);
1386 fprintf(stderr, "IOC_PORTAL_LWT_SNAPSHOT failed: %s\n",
1391 LASSERT (data.ioc_count != 0);
1392 LASSERT (data.ioc_misc != 0);
1395 *now = data.ioc_nid;
1398 *ncpu = data.ioc_count;
1400 if (totalsize != NULL)
1401 *totalsize = data.ioc_misc;
1407 lwt_get_string(char *kstr)
1410 struct portal_ioctl_data data;
1414 /* FIXME: this could maintain a symbol table since we expect to be
1415 * looking up the same strings all the time... */
1417 PORTAL_IOC_INIT(data);
1418 data.ioc_pbuf1 = kstr;
1419 data.ioc_plen1 = 1; /* non-zero just to fool portal_ioctl_is_invalid() */
1420 data.ioc_pbuf2 = NULL;
1423 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_LWT_LOOKUP_STRING, &data);
1425 fprintf(stderr, "IOC_PORTAL_LWT_LOOKUP_STRING failed: %s\n",
1430 size = data.ioc_count;
1431 ustr = (char *)malloc(size);
1433 fprintf(stderr, "Can't allocate string storage of size %d\n",
1438 PORTAL_IOC_INIT(data);
1439 data.ioc_pbuf1 = kstr;
1440 data.ioc_plen1 = 1; /* non-zero just to fool portal_ioctl_is_invalid() */
1441 data.ioc_pbuf2 = ustr;
1442 data.ioc_plen2 = size;
1444 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_LWT_LOOKUP_STRING, &data);
1446 fprintf(stderr, "IOC_PORTAL_LWT_LOOKUP_STRING failed: %s\n",
1451 LASSERT(strlen(ustr) == size - 1);
1456 lwt_put_string(char *ustr)
1462 lwt_print(FILE *f, cycles_t t0, cycles_t tlast, double mhz, int cpu, lwt_event_t *e)
1465 char *where = lwt_get_string(e->lwte_where);
1470 sprintf(whenstr, LPD64, e->lwte_when - t0);
1472 fprintf(f, "%#010lx %#010lx %#010lx %#010lx: %#010lx %1d %10.6f %10.2f %s\n",
1473 e->lwte_p1, e->lwte_p2, e->lwte_p3, e->lwte_p4,
1474 (long)e->lwte_task, cpu, (e->lwte_when - t0) / (mhz * 1000000.0),
1475 (t0 == e->lwte_when) ? 0.0 : (e->lwte_when - tlast) / mhz,
1478 lwt_put_string(where);
1484 get_cycles_per_usec ()
1486 FILE *f = fopen ("/proc/cpuinfo", "r");
1491 while (fgets (line, sizeof (line), f) != NULL)
1492 if (sscanf (line, "cpu MHz : %lf", &mhz) == 1) {
1499 fprintf (stderr, "Can't read/parse /proc/cpuinfo\n");
1504 jt_ptl_lwt(int argc, char **argv)
1508 int nevents_per_cpu;
1509 lwt_event_t *events;
1510 lwt_event_t *cpu_event[LWT_MAX_CPUS + 1];
1511 lwt_event_t *next_event[LWT_MAX_CPUS];
1512 lwt_event_t *first_event[LWT_MAX_CPUS];
1521 struct timeval tvnow;
1522 int printed_date = 0;
1526 (strcmp(argv[1], "start") &&
1527 strcmp(argv[1], "stop"))) {
1530 " %s stop [fname]\n", argv[0], argv[0]);
1534 if (!strcmp(argv[1], "start")) {
1536 if (lwt_control(0, 0) != 0)
1540 if (lwt_control(0, 1) != 0)
1544 if (lwt_control(1, 0) != 0)
1550 if (lwt_snapshot(NULL, &ncpus, &totalspace, NULL, 0) != 0)
1553 if (ncpus > LWT_MAX_CPUS) {
1554 fprintf(stderr, "Too many cpus: %d (%d)\n",
1555 ncpus, LWT_MAX_CPUS);
1559 events = (lwt_event_t *)malloc(totalspace);
1560 if (events == NULL) {
1561 fprintf(stderr, "Can't allocate %d\n", totalspace);
1565 if (lwt_control(0, 0) != 0) { /* disable */
1570 if (lwt_snapshot(&tnow, NULL, NULL, events, totalspace)) {
1575 /* we want this time to be sampled at snapshot time */
1576 gettimeofday(&tvnow, NULL);
1579 f = fopen (argv[2], "w");
1581 fprintf(stderr, "Can't open %s for writing: %s\n", argv[2], strerror (errno));
1587 mhz = get_cycles_per_usec();
1589 /* carve events into per-cpu slices */
1590 nevents_per_cpu = totalspace / (ncpus * sizeof(lwt_event_t));
1591 for (cpu = 0; cpu <= ncpus; cpu++)
1592 cpu_event[cpu] = &events[cpu * nevents_per_cpu];
1594 /* find the earliest event on each cpu */
1595 for (cpu = 0; cpu < ncpus; cpu++) {
1596 first_event[cpu] = NULL;
1598 for (e = cpu_event[cpu]; e < cpu_event[cpu + 1]; e++) {
1600 if (e->lwte_where == NULL) /* not an event */
1603 if (first_event[cpu] == NULL ||
1604 first_event[cpu]->lwte_when > e->lwte_when)
1605 first_event[cpu] = e;
1608 next_event[cpu] = first_event[cpu];
1612 for (cpu = 0; cpu < ncpus; cpu++) {
1613 e = first_event[cpu];
1614 if (e == NULL) /* no events this cpu */
1617 if (e == cpu_event[cpu])
1618 e = cpu_event[cpu + 1] - 1;
1622 /* If there's an event immediately before the first one, this
1623 * cpu wrapped its event buffer */
1624 if (e->lwte_where == NULL)
1627 /* We should only start outputting events from the most recent
1628 * first event in any wrapped cpu. Events before this time on
1629 * other cpus won't have any events from this CPU to interleave
1631 if (t0 < first_event[cpu]->lwte_when)
1632 t0 = first_event[cpu]->lwte_when;
1636 /* find which cpu has the next event */
1638 for (i = 0; i < ncpus; i++) {
1640 if (next_event[i] == NULL) /* this cpu exhausted */
1644 next_event[i]->lwte_when < next_event[cpu]->lwte_when)
1648 if (cpu < 0) /* all cpus exhausted */
1652 /* no wrapped cpus and this is he first ever event */
1653 t0 = next_event[cpu]->lwte_when;
1656 if (t0 <= next_event[cpu]->lwte_when) {
1657 /* on or after the first event */
1658 if (!printed_date) {
1659 cycles_t du = (tnow - t0) / mhz;
1660 time_t then = tvnow.tv_sec - du/1000000;
1662 if (du % 1000000 > tvnow.tv_usec)
1665 fprintf(f, "%s", ctime(&then));
1669 rc = lwt_print(f, t0, tlast, mhz, cpu, next_event[cpu]);
1674 tlast = next_event[cpu]->lwte_when;
1677 if (next_event[cpu] == cpu_event[cpu + 1])
1678 next_event[cpu] = cpu_event[cpu];
1680 if (next_event[cpu]->lwte_where == NULL ||
1681 next_event[cpu] == first_event[cpu])
1682 next_event[cpu] = NULL;
1692 int jt_ptl_memhog(int argc, char **argv)
1694 static int gfp = 0; /* sticky! */
1696 struct portal_ioctl_data data;
1702 fprintf(stderr, "usage: %s <npages> [<GFP flags>]\n", argv[0]);
1706 count = strtol(argv[1], &end, 0);
1707 if (count < 0 || *end != 0) {
1708 fprintf(stderr, "Can't parse page count '%s'\n", argv[1]);
1713 rc = strtol(argv[2], &end, 0);
1715 fprintf(stderr, "Can't parse gfp flags '%s'\n", argv[2]);
1721 PORTAL_IOC_INIT(data);
1722 data.ioc_count = count;
1723 data.ioc_flags = gfp;
1724 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_MEMHOG, &data);
1727 fprintf(stderr, "memhog %d failed: %s\n", count, strerror(errno));
1731 printf("memhog %d OK\n", count);