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>
40 #include <netinet/in.h>
43 #include <portals/api-support.h>
44 #include <portals/ptlctl.h>
45 #include <portals/list.h>
46 #include <portals/lib-types.h>
47 #include <portals/socknal.h>
50 unsigned int portal_debug;
51 unsigned int portal_printk;
53 static unsigned int g_nal = 0;
60 static name2num_t nalnames[] = {
65 {"openib", OPENIBNAL},
69 static cfg_record_cb_t g_record_cb;
71 /* Convert a string boolean to an int; "enable" -> 1 */
72 int ptl_parse_bool (int *b, char *str) {
73 if (!strcasecmp (str, "no") ||
74 !strcasecmp (str, "n") ||
75 !strcasecmp (str, "off") ||
76 !strcasecmp (str, "down") ||
77 !strcasecmp (str, "disable"))
83 if (!strcasecmp (str, "yes") ||
84 !strcasecmp (str, "y") ||
85 !strcasecmp (str, "on") ||
86 !strcasecmp (str, "up") ||
87 !strcasecmp (str, "enable"))
96 /* Convert human readable size string to and int; "1k" -> 1000 */
97 int ptl_parse_size (int *sizep, char *str) {
101 switch (sscanf (str, "%d%1[gGmMkK]", &size, mod)) {
134 ptl_set_cfg_record_cb(cfg_record_cb_t cb)
141 pcfg_ioctl(struct portals_cfg *pcfg)
145 if (pcfg->pcfg_nal ==0)
146 pcfg->pcfg_nal = g_nal;
149 rc = g_record_cb(PORTALS_CFG_TYPE, sizeof(*pcfg), pcfg);
151 struct portal_ioctl_data data;
152 PORTAL_IOC_INIT (data);
153 data.ioc_pbuf1 = (char*)pcfg;
154 data.ioc_plen1 = sizeof(*pcfg);
155 /* XXX liblustre hack XXX */
156 data.ioc_nal_cmd = pcfg->pcfg_command;
157 data.ioc_nid = pcfg->pcfg_nid;
159 rc = l_ioctl (PORTALS_DEV_ID, IOC_PORTAL_NAL_CMD, &data);
168 name2num_lookup_name (name2num_t *table, char *str)
170 while (table->name != NULL)
171 if (!strcmp (str, table->name))
179 name2num_lookup_num (name2num_t *table, int num)
181 while (table->name != NULL)
182 if (num == table->num)
190 ptl_name2nal (char *str)
192 name2num_t *e = name2num_lookup_name (nalnames, str);
194 return ((e == NULL) ? -1 : e->num);
200 name2num_t *e = name2num_lookup_num (nalnames, nal);
202 return ((e == NULL) ? "???" : e->name);
205 static struct hostent *
206 ptl_gethostbyname(char * hname) {
208 he = gethostbyname(hname);
213 fprintf(stderr, "Unable to resolve hostname: %s\n",
217 fprintf(stderr, "gethostbyname error: %s\n",
227 ptl_parse_port (int *port, char *str)
231 *port = strtol (str, &end, 0);
233 if (*end == 0 && /* parsed whole string */
234 *port > 0 && *port < 65536) /* minimal sanity check */
241 ptl_parse_time (time_t *t, char *str)
247 *t = strtol (str, &end, 0);
248 if (*end == 0) /* parsed whole string */
251 memset (&tm, 0, sizeof (tm));
252 n = sscanf (str, "%d-%d-%d-%d:%d:%d",
253 &tm.tm_year, &tm.tm_mon, &tm.tm_mday,
254 &tm.tm_hour, &tm.tm_min, &tm.tm_sec);
258 tm.tm_mon--; /* convert to 0 == Jan */
259 tm.tm_year -= 1900; /* y2k quirk */
260 tm.tm_isdst = -1; /* dunno if it's daylight savings... */
263 if (*t == (time_t)-1)
270 ptl_parse_ipquad (__u32 *ipaddrp, char *str)
277 if (sscanf (str, "%d.%d.%d.%d", &a, &b, &c, &d) == 4 &&
278 (a & ~0xff) == 0 && (b & ~0xff) == 0 &&
279 (c & ~0xff) == 0 && (d & ~0xff) == 0)
281 *ipaddrp = (a<<24)|(b<<16)|(c<<8)|d;
289 ptl_parse_ipaddr (__u32 *ipaddrp, char *str)
293 if (!strcmp (str, "_all_"))
299 if (ptl_parse_ipquad(ipaddrp, str) == 0)
302 if ((('a' <= str[0] && str[0] <= 'z') ||
303 ('A' <= str[0] && str[0] <= 'Z')) &&
304 (he = ptl_gethostbyname (str)) != NULL)
306 __u32 addr = *(__u32 *)he->h_addr;
308 *ipaddrp = ntohl(addr); /* HOST byte order */
316 ptl_ipaddr_2_str (__u32 ipaddr, char *str, int lookup)
322 net_ip = htonl (ipaddr);
323 he = gethostbyaddr (&net_ip, sizeof (net_ip), AF_INET);
325 strcpy(str, he->h_name);
330 sprintf (str, "%d.%d.%d.%d",
331 (ipaddr >> 24) & 0xff, (ipaddr >> 16) & 0xff,
332 (ipaddr >> 8) & 0xff, ipaddr & 0xff);
337 ptl_parse_nid (ptl_nid_t *nidp, char *str)
341 unsigned long long ullval;
343 if (!strcmp (str, "_all_")) {
348 if (ptl_parse_ipaddr (&ipaddr, str) == 0) {
349 *nidp = (ptl_nid_t)ipaddr;
353 ullval = strtoull(str, &end, 0);
355 /* parsed whole string */
356 *nidp = (ptl_nid_t)ullval;
363 __u64 ptl_nid2u64(ptl_nid_t nid)
365 switch (sizeof (nid)) {
371 fprintf(stderr, "Unexpected sizeof(ptl_nid_t) == %u\n", sizeof(nid));
379 ptl_nid2str (char *buffer, ptl_nid_t nid)
381 __u64 nid64 = ptl_nid2u64(nid);
382 struct hostent *he = 0;
384 /* Don't try to resolve NIDs that are e.g. Elan host IDs. Assume
385 * TCP addresses in the 0.x.x.x subnet are not in use. This can
386 * happen on routers and slows things down a _lot_. Bug 3442. */
387 if (nid & 0xff000000) {
388 __u32 addr = htonl((__u32)nid); /* back to NETWORK byte order */
390 he = gethostbyaddr ((const char *)&addr, sizeof (addr), AF_INET);
394 sprintf(buffer, "%#x:%s", (int)(nid64 >> 32), he->h_name);
396 sprintf(buffer, LPX64, nid64);
404 fprintf (stderr, "Error: you must run the 'network' command first.\n");
411 int g_nal_is_compatible (char *cmd, ...)
416 if (!g_nal_is_set ())
422 nal = va_arg (ap, int);
423 } while (nal != 0 && nal != g_nal);
431 /* Don't complain verbosely if we've not been passed a command
432 * name to complain about! */
433 fprintf (stderr, "Command %s not compatible with nal %s\n",
434 cmd, nal2name (g_nal));
440 sock_write (int cfd, void *buffer, int nob)
444 int rc = write (cfd, buffer, nob);
456 fprintf (stderr, "Unexpected zero sock_write\n");
461 buffer = (char *)buffer + nob;
468 sock_read (int cfd, void *buffer, int nob)
472 int rc = read (cfd, buffer, nob);
482 if (rc == 0) /* EOF */
484 errno = ECONNABORTED;
489 buffer = (char *)buffer + nob;
495 int ptl_initialize(int argc, char **argv)
497 register_ioc_dev(PORTALS_DEV_ID, PORTALS_DEV_PATH);
502 int jt_ptl_network(int argc, char **argv)
508 (nal = ptl_name2nal (argv[1])) >= 0) {
513 fprintf(stderr, "usage: %s \n", argv[0]);
514 for (entry = nalnames; entry->name != NULL; entry++)
515 fprintf (stderr, "%s%s", entry == nalnames ? "<" : "|", entry->name);
516 fprintf(stderr, ">\n");
522 jt_ptl_print_interfaces (int argc, char **argv)
524 struct portals_cfg pcfg;
529 if (!g_nal_is_compatible (argv[0], SOCKNAL, 0))
532 for (index = 0;;index++) {
533 PCFG_INIT (pcfg, NAL_CMD_GET_INTERFACE);
534 pcfg.pcfg_count = index;
536 rc = pcfg_ioctl (&pcfg);
540 printf ("%s: (%s/%s) npeer %d nroute %d\n",
541 ptl_ipaddr_2_str(pcfg.pcfg_id, buffer[2], 1),
542 ptl_ipaddr_2_str(pcfg.pcfg_id, buffer[0], 0),
543 ptl_ipaddr_2_str(pcfg.pcfg_misc, buffer[1], 0),
544 pcfg.pcfg_fd, pcfg.pcfg_count);
548 printf ("<no interfaces>\n");
553 jt_ptl_add_interface (int argc, char **argv)
555 struct portals_cfg pcfg;
558 __u32 netmask = 0xffffff00;
560 if (argc < 2 || argc > 3) {
561 fprintf (stderr, "usage: %s ipaddr [netmask]\n", argv[0]);
565 if (!g_nal_is_compatible(argv[0], SOCKNAL, 0))
568 if (ptl_parse_ipaddr(&ipaddr, argv[1]) != 0) {
569 fprintf (stderr, "Can't parse ip: %s\n", argv[1]);
574 ptl_parse_ipquad(&netmask, argv[2]) != 0) {
575 fprintf (stderr, "Can't parse netmask: %s\n", argv[2]);
579 PCFG_INIT(pcfg, NAL_CMD_ADD_INTERFACE);
580 pcfg.pcfg_id = ipaddr;
581 pcfg.pcfg_misc = netmask;
583 rc = pcfg_ioctl (&pcfg);
585 fprintf (stderr, "failed to add interface: %s\n",
594 jt_ptl_del_interface (int argc, char **argv)
596 struct portals_cfg pcfg;
601 fprintf (stderr, "usage: %s [ipaddr]\n", argv[0]);
605 if (!g_nal_is_compatible(argv[0], SOCKNAL, 0))
609 ptl_parse_ipaddr(&ipaddr, argv[1]) != 0) {
610 fprintf (stderr, "Can't parse ip: %s\n", argv[1]);
614 PCFG_INIT(pcfg, NAL_CMD_DEL_INTERFACE);
615 pcfg.pcfg_id = ipaddr;
617 rc = pcfg_ioctl (&pcfg);
619 fprintf (stderr, "failed to delete interface: %s\n",
628 jt_ptl_print_peers (int argc, char **argv)
630 struct portals_cfg pcfg;
635 if (!g_nal_is_compatible (argv[0], SOCKNAL, OPENIBNAL, 0))
638 for (index = 0;;index++) {
639 PCFG_INIT (pcfg, NAL_CMD_GET_PEER);
640 pcfg.pcfg_count = index;
642 rc = pcfg_ioctl (&pcfg);
646 if (g_nal_is_compatible(NULL, SOCKNAL, 0))
647 printf (LPX64"[%d]%s@%s:%d #%d\n",
648 pcfg.pcfg_nid, pcfg.pcfg_wait,
649 ptl_ipaddr_2_str (pcfg.pcfg_size, buffer[0], 1),
650 ptl_ipaddr_2_str (pcfg.pcfg_id, buffer[1], 1),
651 pcfg.pcfg_misc, pcfg.pcfg_count);
653 printf (LPX64"[%d]\n",
654 pcfg.pcfg_nid, pcfg.pcfg_wait);
658 printf ("<no peers>\n");
663 jt_ptl_add_peer (int argc, char **argv)
665 struct portals_cfg pcfg;
671 if (!g_nal_is_compatible (argv[0], SOCKNAL, OPENIBNAL, 0))
674 if (g_nal_is_compatible(NULL, SOCKNAL, 0)) {
676 fprintf (stderr, "usage(tcp): %s nid ipaddr port\n",
680 } else if (argc != 2) {
681 fprintf (stderr, "usage(openib): %s nid\n", argv[0]);
685 if (ptl_parse_nid (&nid, argv[1]) != 0 ||
686 nid == PTL_NID_ANY) {
687 fprintf (stderr, "Can't parse NID: %s\n", argv[1]);
691 if (g_nal_is_compatible (NULL, SOCKNAL, 0)) {
692 if (ptl_parse_ipaddr (&ip, argv[2]) != 0) {
693 fprintf (stderr, "Can't parse ip addr: %s\n", argv[2]);
697 if (ptl_parse_port (&port, argv[3]) != 0) {
698 fprintf (stderr, "Can't parse port: %s\n", argv[3]);
703 PCFG_INIT(pcfg, NAL_CMD_ADD_PEER);
706 pcfg.pcfg_misc = port;
708 rc = pcfg_ioctl (&pcfg);
710 fprintf (stderr, "failed to add peer: %s\n",
719 jt_ptl_del_peer (int argc, char **argv)
721 struct portals_cfg pcfg;
722 ptl_nid_t nid = PTL_NID_ANY;
724 int single_share = 0;
728 if (!g_nal_is_compatible (argv[0], SOCKNAL, OPENIBNAL, 0))
731 if (g_nal_is_compatible(NULL, SOCKNAL, 0)) {
733 fprintf (stderr, "usage: %s [nid] [ipaddr] [single_share]\n",
737 } else if (argc > 3) {
738 fprintf (stderr, "usage: %s [nid] [single_share]\n", argv[0]);
743 ptl_parse_nid (&nid, argv[1]) != 0) {
744 fprintf (stderr, "Can't parse nid: %s\n", argv[1]);
749 if (g_nal_is_compatible(NULL, SOCKNAL, 0)) {
751 ptl_parse_ipaddr (&ip, argv[argidx]) != 0) {
752 fprintf (stderr, "Can't parse ip addr: %s\n",
760 if (!strcmp (argv[3], "single_share")) {
763 fprintf (stderr, "Unrecognised arg %s'\n", argv[3]);
768 PCFG_INIT(pcfg, NAL_CMD_DEL_PEER);
771 pcfg.pcfg_flags = single_share;
773 rc = pcfg_ioctl (&pcfg);
775 fprintf (stderr, "failed to remove peer: %s\n",
784 jt_ptl_print_connections (int argc, char **argv)
786 struct portals_cfg pcfg;
791 if (!g_nal_is_compatible (argv[0], SOCKNAL, OPENIBNAL, 0))
794 for (index = 0;;index++) {
795 PCFG_INIT (pcfg, NAL_CMD_GET_CONN);
796 pcfg.pcfg_count = index;
798 rc = pcfg_ioctl (&pcfg);
802 if (g_nal_is_compatible (NULL, SOCKNAL, 0))
803 printf ("[%d]%s:"LPX64"@%s:%d:%s %d/%d %s\n",
804 pcfg.pcfg_gw_nal, /* scheduler */
805 ptl_ipaddr_2_str (pcfg.pcfg_fd, buffer[0], 1), /* local IP addr */
807 ptl_ipaddr_2_str (pcfg.pcfg_id, buffer[1], 1), /* remote IP addr */
808 pcfg.pcfg_misc, /* remote port */
809 (pcfg.pcfg_flags == SOCKNAL_CONN_ANY) ? "A" :
810 (pcfg.pcfg_flags == SOCKNAL_CONN_CONTROL) ? "C" :
811 (pcfg.pcfg_flags == SOCKNAL_CONN_BULK_IN) ? "I" :
812 (pcfg.pcfg_flags == SOCKNAL_CONN_BULK_OUT) ? "O" : "?",
813 pcfg.pcfg_count, /* tx buffer size */
814 pcfg.pcfg_size, /* rx buffer size */
815 pcfg.pcfg_wait ? "nagle" : "nonagle");
822 printf ("<no connections>\n");
826 int jt_ptl_connect(int argc, char **argv)
828 struct portals_cfg pcfg;
829 struct sockaddr_in srvaddr;
833 int type = SOCKNAL_CONN_ANY;
837 fprintf(stderr, "usage: %s ip port [type]\n", argv[0]);
841 if (!g_nal_is_compatible (argv[0], SOCKNAL, 0))
844 rc = ptl_parse_ipaddr (&ipaddr, argv[1]);
846 fprintf(stderr, "Can't parse hostname: %s\n", argv[1]);
850 if (ptl_parse_port (&port, argv[2]) != 0) {
851 fprintf (stderr, "Can't parse port: %s\n", argv[2]);
856 for (flag = argv[3]; *flag != 0; flag++)
860 if (type != SOCKNAL_CONN_ANY) {
861 fprintf(stderr, "Can't flag type twice\n");
864 type = SOCKNAL_CONN_BULK_IN;
868 if (type != SOCKNAL_CONN_ANY) {
869 fprintf(stderr, "Can't flag type twice\n");
872 type = SOCKNAL_CONN_BULK_OUT;
876 if (type != SOCKNAL_CONN_ANY) {
877 fprintf(stderr, "Can't flag type twice\n");
880 type = SOCKNAL_CONN_CONTROL;
884 fprintf (stderr, "unrecognised flag '%c'\n",
889 memset(&srvaddr, 0, sizeof(srvaddr));
890 srvaddr.sin_family = AF_INET;
891 srvaddr.sin_port = htons(port);
892 srvaddr.sin_addr.s_addr = htonl(ipaddr);
894 fd = socket(PF_INET, SOCK_STREAM, 0);
896 fprintf(stderr, "socket() failed: %s\n", strerror(errno));
900 rc = connect(fd, (struct sockaddr *)&srvaddr, sizeof(srvaddr));
902 fprintf(stderr, "connect() failed: %s\n", strerror(errno));
906 printf("Connected host: %s type: %s\n",
908 (type == SOCKNAL_CONN_ANY) ? "A" :
909 (type == SOCKNAL_CONN_CONTROL) ? "C" :
910 (type == SOCKNAL_CONN_BULK_IN) ? "I" :
911 (type == SOCKNAL_CONN_BULK_OUT) ? "O" : "?");
913 PCFG_INIT(pcfg, NAL_CMD_REGISTER_PEER_FD);
914 pcfg.pcfg_nal = g_nal;
916 pcfg.pcfg_misc = type;
918 rc = pcfg_ioctl(&pcfg);
920 fprintf(stderr, "failed to register fd with portals: %s\n",
926 printf("Connection to %s registered with socknal\n", argv[1]);
930 fprintf(stderr, "close failed: %d\n", rc);
935 int jt_ptl_disconnect(int argc, char **argv)
937 struct portals_cfg pcfg;
938 ptl_nid_t nid = PTL_NID_ANY;
943 fprintf(stderr, "usage: %s [nid] [ipaddr]\n", argv[0]);
947 if (!g_nal_is_compatible (NULL, SOCKNAL, OPENIBNAL, 0))
951 ptl_parse_nid (&nid, argv[1]) != 0) {
952 fprintf (stderr, "Can't parse nid %s\n", argv[1]);
956 if (g_nal_is_compatible (NULL, SOCKNAL, 0) &&
958 ptl_parse_ipaddr (&ipaddr, argv[2]) != 0) {
959 fprintf (stderr, "Can't parse ip addr %s\n", argv[2]);
963 PCFG_INIT(pcfg, NAL_CMD_CLOSE_CONNECTION);
965 pcfg.pcfg_id = ipaddr;
967 rc = pcfg_ioctl(&pcfg);
969 fprintf(stderr, "failed to remove connection: %s\n",
977 int jt_ptl_push_connection (int argc, char **argv)
979 struct portals_cfg pcfg;
981 ptl_nid_t nid = PTL_NID_ANY;
985 fprintf(stderr, "usage: %s [nid] [ip]\n", argv[0]);
989 if (!g_nal_is_compatible (argv[0], SOCKNAL, 0))
993 ptl_parse_nid (&nid, argv[1]) != 0) {
994 fprintf(stderr, "Can't parse nid: %s\n", argv[1]);
999 ptl_parse_ipaddr (&ipaddr, argv[2]) != 0) {
1000 fprintf(stderr, "Can't parse ipaddr: %s\n", argv[2]);
1003 PCFG_INIT(pcfg, NAL_CMD_PUSH_CONNECTION);
1004 pcfg.pcfg_nid = nid;
1005 pcfg.pcfg_id = ipaddr;
1007 rc = pcfg_ioctl(&pcfg);
1009 fprintf(stderr, "failed to push connection: %s\n",
1018 jt_ptl_print_active_txs (int argc, char **argv)
1020 struct portals_cfg pcfg;
1024 if (!g_nal_is_compatible (argv[0], QSWNAL, 0))
1027 for (index = 0;;index++) {
1028 PCFG_INIT(pcfg, NAL_CMD_GET_TXDESC);
1029 pcfg.pcfg_count = index;
1031 rc = pcfg_ioctl(&pcfg);
1035 printf ("%p: %5s payload %6d bytes to "LPX64" via "LPX64" by pid %6d: %s, %s, state %d\n",
1037 pcfg.pcfg_count == PTL_MSG_ACK ? "ACK" :
1038 pcfg.pcfg_count == PTL_MSG_PUT ? "PUT" :
1039 pcfg.pcfg_count == PTL_MSG_GET ? "GET" :
1040 pcfg.pcfg_count == PTL_MSG_REPLY ? "REPLY" : "<wierd message>",
1045 (pcfg.pcfg_flags & 1) ? "delayed" : "immediate",
1046 (pcfg.pcfg_flags & 2) ? "nblk" : "normal",
1047 pcfg.pcfg_flags >> 2);
1051 printf ("<no active descs>\n");
1055 int jt_ptl_ping(int argc, char **argv)
1062 struct portal_ioctl_data data;
1065 fprintf(stderr, "usage: %s nid [count] [size] [timeout (secs)]\n", argv[0]);
1069 if (!g_nal_is_set())
1072 if (ptl_parse_nid (&nid, argv[1]) != 0)
1074 fprintf (stderr, "Can't parse nid \"%s\"\n", argv[1]);
1080 count = atol(argv[2]);
1082 if (count < 0 || count > 20000)
1084 fprintf(stderr, "are you insane? %ld is a crazy count.\n", count);
1090 size= atol(argv[3]);
1093 timeout = atol (argv[4]);
1095 PORTAL_IOC_INIT (data);
1096 data.ioc_count = count;
1097 data.ioc_size = size;
1099 data.ioc_nal = g_nal;
1100 data.ioc_timeout = timeout;
1102 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_PING, &data);
1104 fprintf(stderr, "failed to start pinger: %s\n",
1111 int jt_ptl_shownid(int argc, char **argv)
1113 struct portal_ioctl_data data;
1117 fprintf(stderr, "usage: %s\n", argv[0]);
1121 if (!g_nal_is_set())
1124 PORTAL_IOC_INIT (data);
1125 data.ioc_nal = g_nal;
1126 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_GET_NID, &data);
1128 fprintf(stderr, "getting my NID failed: %s\n",
1131 printf(LPX64"\n", data.ioc_nid);
1135 int jt_ptl_mynid(int argc, char **argv)
1138 char hostname[1024];
1140 struct portals_cfg pcfg;
1144 fprintf(stderr, "usage: %s [NID]\n", argv[0]);
1145 fprintf(stderr, "NID defaults to the primary IP address of the machine.\n");
1149 if (!g_nal_is_set())
1154 else if (gethostname(hostname, sizeof(hostname)) != 0) {
1155 fprintf(stderr, "gethostname failed: %s\n",
1162 rc = ptl_parse_nid (&mynid, nidstr);
1164 fprintf (stderr, "Can't convert '%s' into a NID\n", nidstr);
1168 PCFG_INIT(pcfg, NAL_CMD_REGISTER_MYNID);
1169 pcfg.pcfg_nid = mynid;
1171 rc = pcfg_ioctl(&pcfg);
1173 fprintf(stderr, "setting my NID failed: %s\n",
1176 printf("registered my nid "LPX64" (%s)\n",
1177 ptl_nid2u64(mynid), hostname);
1182 jt_ptl_fail_nid (int argc, char **argv)
1186 unsigned int threshold;
1187 struct portal_ioctl_data data;
1189 if (argc < 2 || argc > 3)
1191 fprintf (stderr, "usage: %s nid|\"_all_\" [count (0 == mend)]\n", argv[0]);
1195 if (!g_nal_is_set())
1198 if (!strcmp (argv[1], "_all_"))
1200 else if (ptl_parse_nid (&nid, argv[1]) != 0)
1202 fprintf (stderr, "Can't parse nid \"%s\"\n", argv[1]);
1207 threshold = PTL_MD_THRESH_INF;
1208 else if (sscanf (argv[2], "%i", &threshold) != 1) {
1209 fprintf (stderr, "Can't parse count \"%s\"\n", argv[2]);
1213 PORTAL_IOC_INIT (data);
1214 data.ioc_nal = g_nal;
1216 data.ioc_count = threshold;
1218 rc = l_ioctl (PORTALS_DEV_ID, IOC_PORTAL_FAIL_NID, &data);
1220 fprintf (stderr, "IOC_PORTAL_FAIL_NID failed: %s\n",
1223 printf ("%s %s\n", threshold == 0 ? "Unfailing" : "Failing", argv[1]);
1229 jt_ptl_add_route (int argc, char **argv)
1231 struct portals_cfg pcfg;
1234 ptl_nid_t gateway_nid;
1239 fprintf (stderr, "usage: %s gateway target [target]\n", argv[0]);
1243 if (!g_nal_is_set())
1246 if (ptl_parse_nid (&gateway_nid, argv[1]) != 0)
1248 fprintf (stderr, "Can't parse gateway NID \"%s\"\n", argv[1]);
1252 if (ptl_parse_nid (&nid1, argv[2]) != 0)
1254 fprintf (stderr, "Can't parse first target NID \"%s\"\n", argv[2]);
1260 else if (ptl_parse_nid (&nid2, argv[3]) != 0)
1262 fprintf (stderr, "Can't parse second target NID \"%s\"\n", argv[4]);
1266 PCFG_INIT(pcfg, NAL_CMD_ADD_ROUTE);
1267 pcfg.pcfg_nid = gateway_nid;
1268 pcfg.pcfg_nal = ROUTER;
1269 pcfg.pcfg_gw_nal = g_nal;
1270 pcfg.pcfg_nid2 = MIN (nid1, nid2);
1271 pcfg.pcfg_nid3 = MAX (nid1, nid2);
1273 rc = pcfg_ioctl(&pcfg);
1276 fprintf (stderr, "NAL_CMD_ADD_ROUTE failed: %s\n", strerror (errno));
1284 jt_ptl_del_route (int argc, char **argv)
1286 struct portals_cfg pcfg;
1288 ptl_nid_t nid1 = PTL_NID_ANY;
1289 ptl_nid_t nid2 = PTL_NID_ANY;
1294 fprintf (stderr, "usage: %s targetNID\n", argv[0]);
1298 if (!g_nal_is_set())
1301 if (ptl_parse_nid (&nid, argv[1]) != 0)
1303 fprintf (stderr, "Can't parse gateway NID \"%s\"\n", argv[1]);
1308 ptl_parse_nid (&nid1, argv[2]) != 0)
1310 fprintf (stderr, "Can't parse target NID \"%s\"\n", argv[2]);
1317 if (ptl_parse_nid (&nid2, argv[3]) != 0) {
1318 fprintf (stderr, "Can't parse target NID \"%s\"\n", argv[3]);
1323 ptl_nid_t tmp = nid1;
1330 PCFG_INIT(pcfg, NAL_CMD_DEL_ROUTE);
1331 pcfg.pcfg_nal = ROUTER;
1332 pcfg.pcfg_gw_nal = g_nal;
1333 pcfg.pcfg_nid = nid;
1334 pcfg.pcfg_nid2 = nid1;
1335 pcfg.pcfg_nid3 = nid2;
1337 rc = pcfg_ioctl(&pcfg);
1340 fprintf (stderr, "NAL_CMD_DEL_ROUTE ("LPX64") failed: %s\n",
1341 ptl_nid2u64(nid), strerror (errno));
1349 jt_ptl_notify_router (int argc, char **argv)
1351 struct portals_cfg pcfg;
1360 fprintf (stderr, "usage: %s targetNID <up/down> [<time>]\n",
1365 if (ptl_parse_nid (&nid, argv[1]) != 0)
1367 fprintf (stderr, "Can't parse target NID \"%s\"\n", argv[1]);
1371 if (ptl_parse_bool (&enable, argv[2]) != 0) {
1372 fprintf (stderr, "Can't parse boolean %s\n", argv[2]);
1376 gettimeofday(&now, NULL);
1380 } else if (ptl_parse_time (&when, argv[3]) != 0) {
1381 fprintf(stderr, "Can't parse time %s\n"
1382 "Please specify either 'YYYY-MM-DD-HH:MM:SS'\n"
1383 "or an absolute unix time in seconds\n", argv[3]);
1385 } else if (when > now.tv_sec) {
1386 fprintf (stderr, "%s specifies a time in the future\n",
1391 PCFG_INIT(pcfg, NAL_CMD_NOTIFY_ROUTER);
1392 pcfg.pcfg_nal = ROUTER;
1393 pcfg.pcfg_gw_nal = g_nal;
1394 pcfg.pcfg_nid = nid;
1395 pcfg.pcfg_flags = enable;
1396 /* Yeuch; 'cept I need a __u64 on 64 bit machines... */
1397 pcfg.pcfg_nid3 = (__u64)when;
1399 rc = pcfg_ioctl(&pcfg);
1402 fprintf (stderr, "NAL_CMD_NOTIFY_ROUTER ("LPX64") failed: %s\n",
1403 ptl_nid2u64(nid), strerror (errno));
1411 jt_ptl_print_routes (int argc, char **argv)
1413 char buffer[3][128];
1414 struct portals_cfg pcfg;
1418 ptl_nid_t gateway_nid;
1423 for (index = 0;;index++)
1425 PCFG_INIT(pcfg, NAL_CMD_GET_ROUTE);
1426 pcfg.pcfg_nal = ROUTER;
1427 pcfg.pcfg_count = index;
1429 rc = pcfg_ioctl(&pcfg);
1433 gateway_nal = pcfg.pcfg_gw_nal;
1434 gateway_nid = pcfg.pcfg_nid;
1435 nid1 = pcfg.pcfg_nid2;
1436 nid2 = pcfg.pcfg_nid3;
1437 alive = pcfg.pcfg_flags;
1439 printf ("%8s %18s : %s - %s, %s\n",
1440 nal2name (gateway_nal),
1441 ptl_nid2str (buffer[0], gateway_nid),
1442 ptl_nid2str (buffer[1], nid1),
1443 ptl_nid2str (buffer[2], nid2),
1444 alive ? "up" : "down");
1450 lwt_control(int enable, int clear)
1452 struct portal_ioctl_data data;
1455 PORTAL_IOC_INIT(data);
1456 data.ioc_flags = enable;
1457 data.ioc_misc = clear;
1459 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_LWT_CONTROL, &data);
1463 fprintf(stderr, "IOC_PORTAL_LWT_CONTROL failed: %s\n",
1469 lwt_snapshot(cycles_t *now, int *ncpu, int *totalsize,
1470 lwt_event_t *events, int size)
1472 struct portal_ioctl_data data;
1475 PORTAL_IOC_INIT(data);
1476 data.ioc_pbuf1 = (char *)events;
1477 data.ioc_plen1 = size;
1479 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_LWT_SNAPSHOT, &data);
1481 fprintf(stderr, "IOC_PORTAL_LWT_SNAPSHOT failed: %s\n",
1486 /* crappy overloads */
1487 if (data.ioc_nid != sizeof(lwt_event_t) ||
1488 data.ioc_nid2 != offsetof(lwt_event_t, lwte_where)) {
1489 fprintf(stderr,"kernel/user LWT event mismatch %d(%d),%d(%d)\n",
1490 (int)data.ioc_nid, sizeof(lwt_event_t),
1492 (int)offsetof(lwt_event_t, lwte_where));
1496 LASSERT (data.ioc_count != 0);
1497 LASSERT (data.ioc_misc != 0);
1500 *now = data.ioc_nid;
1503 *ncpu = data.ioc_count;
1505 if (totalsize != NULL)
1506 *totalsize = data.ioc_misc;
1512 lwt_get_string(char *kstr)
1515 struct portal_ioctl_data data;
1519 /* FIXME: this could maintain a symbol table since we expect to be
1520 * looking up the same strings all the time... */
1522 PORTAL_IOC_INIT(data);
1523 data.ioc_pbuf1 = kstr;
1524 data.ioc_plen1 = 1; /* non-zero just to fool portal_ioctl_is_invalid() */
1525 data.ioc_pbuf2 = NULL;
1528 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_LWT_LOOKUP_STRING, &data);
1530 fprintf(stderr, "IOC_PORTAL_LWT_LOOKUP_STRING failed: %s\n",
1535 size = data.ioc_count;
1536 ustr = (char *)malloc(size);
1538 fprintf(stderr, "Can't allocate string storage of size %d\n",
1543 PORTAL_IOC_INIT(data);
1544 data.ioc_pbuf1 = kstr;
1545 data.ioc_plen1 = 1; /* non-zero just to fool portal_ioctl_is_invalid() */
1546 data.ioc_pbuf2 = ustr;
1547 data.ioc_plen2 = size;
1549 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_LWT_LOOKUP_STRING, &data);
1551 fprintf(stderr, "IOC_PORTAL_LWT_LOOKUP_STRING failed: %s\n",
1556 LASSERT(strlen(ustr) == size - 1);
1561 lwt_put_string(char *ustr)
1567 lwt_print(FILE *f, cycles_t t0, cycles_t tlast, double mhz, int cpu, lwt_event_t *e)
1569 char *where = lwt_get_string(e->lwte_where);
1574 fprintf(f, "%#010lx %#010lx %#010lx %#010lx: %#010lx %1d %10.6f %10.2f %s\n",
1575 e->lwte_p1, e->lwte_p2, e->lwte_p3, e->lwte_p4,
1576 (long)e->lwte_task, cpu, (e->lwte_when - t0) / (mhz * 1000000.0),
1577 (t0 == e->lwte_when) ? 0.0 : (e->lwte_when - tlast) / mhz,
1580 lwt_put_string(where);
1586 get_cycles_per_usec ()
1588 FILE *f = fopen ("/proc/cpuinfo", "r");
1593 while (fgets (line, sizeof (line), f) != NULL)
1594 if (sscanf (line, "cpu MHz : %lf", &mhz) == 1) {
1601 fprintf (stderr, "Can't read/parse /proc/cpuinfo\n");
1606 jt_ptl_lwt(int argc, char **argv)
1608 const int lwt_max_cpus = 32;
1611 int nevents_per_cpu;
1612 lwt_event_t *events;
1613 lwt_event_t *cpu_event[lwt_max_cpus + 1];
1614 lwt_event_t *next_event[lwt_max_cpus];
1615 lwt_event_t *first_event[lwt_max_cpus];
1624 struct timeval tvnow;
1625 int printed_date = 0;
1630 (strcmp(argv[1], "start") &&
1631 strcmp(argv[1], "stop"))) {
1634 " %s stop [fname]\n", argv[0], argv[0]);
1638 if (!strcmp(argv[1], "start")) {
1640 if (lwt_control(0, 0) != 0)
1644 if (lwt_control(0, 1) != 0)
1648 if (lwt_control(1, 0) != 0)
1654 if (lwt_snapshot(NULL, &ncpus, &totalspace, NULL, 0) != 0)
1657 if (ncpus > lwt_max_cpus) {
1658 fprintf(stderr, "Too many cpus: %d (%d)\n",
1659 ncpus, lwt_max_cpus);
1663 events = (lwt_event_t *)malloc(totalspace);
1664 if (events == NULL) {
1665 fprintf(stderr, "Can't allocate %d\n", totalspace);
1669 if (lwt_control(0, 0) != 0) { /* disable */
1674 if (lwt_snapshot(&tnow, NULL, NULL, events, totalspace)) {
1679 /* we want this time to be sampled at snapshot time */
1680 gettimeofday(&tvnow, NULL);
1683 f = fopen (argv[2], "w");
1685 fprintf(stderr, "Can't open %s for writing: %s\n", argv[2], strerror (errno));
1691 mhz = get_cycles_per_usec();
1693 /* carve events into per-cpu slices */
1694 nevents_per_cpu = totalspace / (ncpus * sizeof(lwt_event_t));
1695 for (cpu = 0; cpu <= ncpus; cpu++)
1696 cpu_event[cpu] = &events[cpu * nevents_per_cpu];
1698 /* find the earliest event on each cpu */
1699 for (cpu = 0; cpu < ncpus; cpu++) {
1700 first_event[cpu] = NULL;
1702 for (e = cpu_event[cpu]; e < cpu_event[cpu + 1]; e++) {
1704 if (e->lwte_where == NULL) /* not an event */
1707 if (first_event[cpu] == NULL ||
1708 first_event[cpu]->lwte_when > e->lwte_when)
1709 first_event[cpu] = e;
1712 next_event[cpu] = first_event[cpu];
1716 for (cpu = 0; cpu < ncpus; cpu++) {
1717 e = first_event[cpu];
1718 if (e == NULL) /* no events this cpu */
1721 if (e == cpu_event[cpu])
1722 e = cpu_event[cpu + 1] - 1;
1726 /* If there's an event immediately before the first one, this
1727 * cpu wrapped its event buffer */
1728 if (e->lwte_where == NULL)
1731 /* We should only start outputting events from the most recent
1732 * first event in any wrapped cpu. Events before this time on
1733 * other cpus won't have any events from this CPU to interleave
1735 if (t0 < first_event[cpu]->lwte_when)
1736 t0 = first_event[cpu]->lwte_when;
1740 /* find which cpu has the next event */
1742 for (i = 0; i < ncpus; i++) {
1744 if (next_event[i] == NULL) /* this cpu exhausted */
1748 next_event[i]->lwte_when < next_event[cpu]->lwte_when)
1752 if (cpu < 0) /* all cpus exhausted */
1756 /* no wrapped cpus and this is he first ever event */
1757 t0 = next_event[cpu]->lwte_when;
1760 if (t0 <= next_event[cpu]->lwte_when) {
1761 /* on or after the first event */
1762 if (!printed_date) {
1763 cycles_t du = (tnow - t0) / mhz;
1764 time_t then = tvnow.tv_sec - du/1000000;
1766 if (du % 1000000 > tvnow.tv_usec)
1769 fprintf(f, "%s", ctime(&then));
1773 rc = lwt_print(f, t0, tlast, mhz, cpu, next_event[cpu]);
1777 if (++nlines % 10000 == 0 && f != stdout) {
1778 /* show some activity... */
1784 tlast = next_event[cpu]->lwte_when;
1787 if (next_event[cpu] == cpu_event[cpu + 1])
1788 next_event[cpu] = cpu_event[cpu];
1790 if (next_event[cpu]->lwte_where == NULL ||
1791 next_event[cpu] == first_event[cpu])
1792 next_event[cpu] = NULL;
1804 int jt_ptl_memhog(int argc, char **argv)
1806 static int gfp = 0; /* sticky! */
1808 struct portal_ioctl_data data;
1814 fprintf(stderr, "usage: %s <npages> [<GFP flags>]\n", argv[0]);
1818 count = strtol(argv[1], &end, 0);
1819 if (count < 0 || *end != 0) {
1820 fprintf(stderr, "Can't parse page count '%s'\n", argv[1]);
1825 rc = strtol(argv[2], &end, 0);
1827 fprintf(stderr, "Can't parse gfp flags '%s'\n", argv[2]);
1833 PORTAL_IOC_INIT(data);
1834 data.ioc_count = count;
1835 data.ioc_flags = gfp;
1836 rc = l_ioctl(PORTALS_DEV_ID, IOC_PORTAL_MEMHOG, &data);
1839 fprintf(stderr, "memhog %d failed: %s\n", count, strerror(errno));
1843 printf("memhog %d OK\n", count);