Whamcloud - gitweb
LU-2675 lnet: assume a kernel build
[fs/lustre-release.git] / lnet / utils / portals.c
1 /*
2  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
3  *
4  * Copyright (c) 2013, 2014, Intel Corporation.
5  *
6  *   This file is part of Portals, http://www.sf.net/projects/lustre/
7  *
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.
11  *
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.
16  *
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.
20  *
21  */
22
23 #include <libcfs/libcfsutil.h>
24 #include <lnet/nidstr.h>
25 #include <lnet/lnetctl.h>
26 #include <lnet/socklnd.h>
27 #include <lnet/lib-dlc.h>
28 #include <getopt.h>
29 #include <netdb.h>
30
31 unsigned int libcfs_debug;
32 unsigned int libcfs_printk = D_CANTMASK;
33
34 static int   g_net_set;
35 static __u32 g_net;
36
37 #define IOC_BUF_SIZE    8192
38 static char local_buf[IOC_BUF_SIZE];
39 static char *ioc_buf = local_buf;
40
41 /* Convert a string boolean to an int; "enable" -> 1 */
42 int
43 lnet_parse_bool (int *b, char *str)
44 {
45         if (!strcasecmp (str, "no") ||
46             !strcasecmp (str, "n") ||
47             !strcasecmp (str, "off") ||
48             !strcasecmp (str, "down") ||
49             !strcasecmp (str, "disable"))
50         {
51                 *b = 0;
52                 return (0);
53         }
54
55         if (!strcasecmp (str, "yes") ||
56             !strcasecmp (str, "y") ||
57             !strcasecmp (str, "on") ||
58             !strcasecmp (str, "up") ||
59             !strcasecmp (str, "enable"))
60         {
61                 *b = 1;
62                 return (0);
63         }
64
65         return (-1);
66 }
67
68 int
69 lnet_parse_port (int *port, char *str)
70 {
71         char      *end;
72
73         *port = strtol (str, &end, 0);
74
75         if (*end == 0 &&                        /* parsed whole string */
76             *port > 0 && *port < 65536)         /* minimal sanity check */
77                 return (0);
78
79         return (-1);
80 }
81
82 #ifdef HAVE_GETHOSTBYNAME
83 static struct hostent *
84 ptl_gethostbyname(char * hname) {
85         struct hostent *he;
86         he = gethostbyname(hname);
87         if (!he) {
88                 switch(h_errno) {
89                 case HOST_NOT_FOUND:
90                 case NO_ADDRESS:
91                         fprintf(stderr, "Unable to resolve hostname: %s\n",
92                                 hname);
93                         break;
94                 default:
95                         fprintf(stderr, "gethostbyname error for %s: %s\n",
96                                 hname, strerror(h_errno));
97                         break;
98                 }
99                 return NULL;
100         }
101         return he;
102 }
103 #endif
104
105 int
106 lnet_parse_ipquad (__u32 *ipaddrp, char *str)
107 {
108         int             a;
109         int             b;
110         int             c;
111         int             d;
112
113         if (sscanf (str, "%d.%d.%d.%d", &a, &b, &c, &d) == 4 &&
114             (a & ~0xff) == 0 && (b & ~0xff) == 0 &&
115             (c & ~0xff) == 0 && (d & ~0xff) == 0)
116         {
117                 *ipaddrp = (a<<24)|(b<<16)|(c<<8)|d;
118                 return (0);
119         }
120
121         return (-1);
122 }
123
124 int
125 lnet_parse_ipaddr (__u32 *ipaddrp, char *str)
126 {
127 #ifdef HAVE_GETHOSTBYNAME
128         struct hostent *he;
129 #endif
130
131         if (!strcmp (str, "_all_")) {
132                 *ipaddrp = 0;
133                 return (0);
134         }
135
136         if (lnet_parse_ipquad(ipaddrp, str) == 0)
137                 return (0);
138
139 #ifdef HAVE_GETHOSTBYNAME
140         if ((('a' <= str[0] && str[0] <= 'z') ||
141              ('A' <= str[0] && str[0] <= 'Z')) &&
142              (he = ptl_gethostbyname (str)) != NULL) {
143                 __u32 addr = *(__u32 *)he->h_addr;
144
145                 *ipaddrp = ntohl(addr);         /* HOST byte order */
146                 return (0);
147         }
148 #endif
149
150         return (-1);
151 }
152
153 char *
154 ptl_ipaddr_2_str(__u32 ipaddr, char *str, size_t strsize, int lookup)
155 {
156 #ifdef HAVE_GETHOSTBYNAME
157         __u32           net_ip;
158         struct hostent *he;
159
160         if (lookup) {
161                 net_ip = htonl (ipaddr);
162                 he = gethostbyaddr (&net_ip, sizeof (net_ip), AF_INET);
163                 if (he != NULL) {
164                         strlcpy(str, he->h_name, strsize);
165                         return (str);
166                 }
167         }
168 #endif
169
170         sprintf (str, "%d.%d.%d.%d",
171                  (ipaddr >> 24) & 0xff, (ipaddr >> 16) & 0xff,
172                  (ipaddr >> 8) & 0xff, ipaddr & 0xff);
173         return (str);
174 }
175
176 int
177 lnet_parse_time (time_t *t, char *str)
178 {
179         char          *end;
180         int            n;
181         struct tm      tm;
182
183         *t = strtol (str, &end, 0);
184         if (*end == 0) /* parsed whole string */
185                 return (0);
186
187         memset (&tm, 0, sizeof (tm));
188         n = sscanf (str, "%d-%d-%d-%d:%d:%d",
189                     &tm.tm_year, &tm.tm_mon, &tm.tm_mday,
190                     &tm.tm_hour, &tm.tm_min, &tm.tm_sec);
191         if (n != 6)
192                 return (-1);
193
194         tm.tm_mon--;                    /* convert to 0 == Jan */
195         tm.tm_year -= 1900;             /* y2k quirk */
196         tm.tm_isdst = -1;               /* dunno if it's daylight savings... */
197
198         *t = mktime (&tm);
199         if (*t == (time_t)-1)
200                 return (-1);
201
202         return (0);
203 }
204
205 int
206 lnet_parse_nid(char *nid_str, lnet_process_id_t *id_ptr)
207 {
208         id_ptr->pid = LNET_PID_ANY;
209         id_ptr->nid = libcfs_str2nid(nid_str);
210         if (id_ptr->nid == LNET_NID_ANY) {
211                 fprintf (stderr, "Can't parse nid \"%s\"\n", nid_str);
212                 return -1;
213         }
214
215         return 0;
216 }
217
218 int g_net_is_set (char *cmd)
219 {
220         if (g_net_set)
221                 return 1;
222
223         if (cmd != NULL)
224                 fprintf(stderr,
225                         "You must run the 'network' command before '%s'.\n",
226                         cmd);
227         return 0;
228 }
229
230 int g_net_is_compatible (char *cmd, ...)
231 {
232         va_list       ap;
233         int           nal;
234
235         if (!g_net_is_set(cmd))
236                 return 0;
237
238         va_start(ap, cmd);
239
240         do {
241                 nal = va_arg (ap, int);
242                 if (nal == LNET_NETTYP(g_net)) {
243                         va_end (ap);
244                         return 1;
245                 }
246         } while (nal != 0);
247
248         va_end (ap);
249
250         if (cmd != NULL)
251                 fprintf (stderr,
252                          "Command %s not compatible with %s NAL\n",
253                          cmd,
254                          libcfs_lnd2str(LNET_NETTYP(g_net)));
255         return 0;
256 }
257
258 int ptl_initialize(int argc, char **argv)
259 {
260         register_ioc_dev(LNET_DEV_ID, LNET_DEV_PATH,
261                          LNET_DEV_MAJOR, LNET_DEV_MINOR);
262         return 0;
263 }
264
265
266 int jt_ptl_network(int argc, char **argv)
267 {
268         struct libcfs_ioctl_data data;
269         __u32                    net = LNET_NIDNET(LNET_NID_ANY);
270         int                      rc;
271
272         if (argc < 2) {
273                 fprintf(stderr, "usage: %s <net>|up|down\n", argv[0]);
274                 return 0;
275         }
276
277         if (!strcmp(argv[1], "unconfigure") ||
278             !strcmp(argv[1], "down")) {
279                 LIBCFS_IOC_INIT(data);
280                 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_UNCONFIGURE, &data);
281
282                 if (rc == 0) {
283                         printf ("LNET ready to unload\n");
284                         return 0;
285                 }
286
287                 if (errno == EBUSY)
288                         fprintf(stderr, "LNET busy\n");
289                 else
290                         fprintf(stderr, "LNET unconfigure error %d: %s\n",
291                                 errno, strerror(errno));
292                 return -1;
293         }
294
295         if (!strcmp(argv[1], "configure") ||
296             !strcmp(argv[1], "up")) {
297                 LIBCFS_IOC_INIT(data);
298                 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_CONFIGURE, &data);
299
300                 if (rc == 0) {
301                         printf ("LNET configured\n");
302                         return 0;
303                 }
304
305                 fprintf(stderr, "LNET configure error %d: %s\n",
306                         errno, strerror(errno));
307                 return -1;
308         }
309
310         net = libcfs_str2net(argv[1]);
311         if (net == LNET_NIDNET(LNET_NID_ANY)) {
312                 fprintf(stderr, "Can't parse net %s\n", argv[1]);
313                 return -1;
314         }
315
316         if (LNET_NETTYP(net) == CIBLND    ||
317             LNET_NETTYP(net) == OPENIBLND ||
318             LNET_NETTYP(net) == IIBLND    ||
319             LNET_NETTYP(net) == VIBLND) {
320                 fprintf(stderr, "Net %s obsoleted\n", libcfs_lnd2str(net));
321                 return -1;
322         }
323
324         g_net_set = 1;
325         g_net = net;
326         return 0;
327 }
328
329 int
330 jt_ptl_list_nids(int argc, char **argv)
331 {
332         struct libcfs_ioctl_data data;
333         int                      all = 0, return_nid = 0;
334         int                      count;
335         int                      rc;
336
337         all = (argc == 2) && (strcmp(argv[1], "all") == 0);
338         /* Hack to pass back value */
339         return_nid = (argc == 2) && (argv[1][0] == 1);
340
341         if ((argc > 2) && !(all || return_nid)) {
342                 fprintf(stderr, "usage: %s [all]\n", argv[0]);
343                 return 0;
344         }
345
346         for (count = 0;; count++) {
347                 LIBCFS_IOC_INIT (data);
348                 data.ioc_count = count;
349                 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_NI, &data);
350
351                 if (rc < 0) {
352                         if ((count > 0) && (errno == ENOENT))
353                                 /* We found them all */
354                                 break;
355                         fprintf(stderr,"IOC_LIBCFS_GET_NI error %d: %s\n",
356                                 errno, strerror(errno));
357                         return -1;
358                 }
359
360                 if (all || (LNET_NETTYP(LNET_NIDNET(data.ioc_nid)) != LOLND)) {
361                         printf("%s\n", libcfs_nid2str(data.ioc_nid));
362                         if (return_nid) {
363                                 *(__u64 *)(argv[1]) = data.ioc_nid;
364                                 return_nid--;
365                         }
366                 }
367         }
368
369         return 0;
370 }
371
372 int
373 jt_ptl_which_nid (int argc, char **argv)
374 {
375         struct libcfs_ioctl_data data;
376         int          best_dist = 0;
377         int          best_order = 0;
378         lnet_nid_t   best_nid = LNET_NID_ANY;
379         int          dist;
380         int          order;
381         lnet_nid_t   nid;
382         char        *nidstr;
383         int          rc;
384         int          i;
385
386         if (argc < 2) {
387                 fprintf(stderr, "usage: %s NID [NID...]\n", argv[0]);
388                 return 0;
389         }
390
391         for (i = 1; i < argc; i++) {
392                 nidstr = argv[i];
393                 nid = libcfs_str2nid(nidstr);
394                 if (nid == LNET_NID_ANY) {
395                         fprintf(stderr, "Can't parse NID %s\n", nidstr);
396                         return -1;
397                 }
398
399                 LIBCFS_IOC_INIT(data);
400                 data.ioc_nid = nid;
401
402                 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_LNET_DIST, &data);
403                 if (rc != 0) {
404                         fprintf(stderr, "Can't get distance to %s: %s\n",
405                                 nidstr, strerror(errno));
406                         return -1;
407                 }
408
409                 dist = data.ioc_u32[0];
410                 order = data.ioc_u32[1];
411
412                 if (dist < 0) {
413                         if (dist == -EHOSTUNREACH)
414                                 continue;
415
416                         fprintf(stderr, "Unexpected distance to %s: %d\n",
417                                 nidstr, dist);
418                         return -1;
419                 }
420
421                 if (best_nid == LNET_NID_ANY ||
422                     dist < best_dist ||
423                     (dist == best_dist && order < best_order)) {
424                         best_dist = dist;
425                         best_order = order;
426                         best_nid = nid;
427                 }
428         }
429
430         if (best_nid == LNET_NID_ANY) {
431                 fprintf(stderr, "No reachable NID\n");
432                 return -1;
433         }
434
435         printf("%s\n", libcfs_nid2str(best_nid));
436         return 0;
437 }
438
439 int
440 jt_ptl_print_interfaces (int argc, char **argv)
441 {
442         struct libcfs_ioctl_data data;
443         char                     buffer[3][HOST_NAME_MAX + 1];
444         int                      index;
445         int                      rc;
446
447         if (!g_net_is_compatible (argv[0], SOCKLND, 0))
448                 return -1;
449
450         for (index = 0;;index++) {
451                 LIBCFS_IOC_INIT(data);
452                 data.ioc_net   = g_net;
453                 data.ioc_count = index;
454
455                 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_INTERFACE, &data);
456                 if (rc != 0)
457                         break;
458
459                 printf ("%s: (%s/%s) npeer %d nroute %d\n",
460                         ptl_ipaddr_2_str(data.ioc_u32[0], buffer[2],
461                                          sizeof(buffer[2]), 1),
462                         ptl_ipaddr_2_str(data.ioc_u32[0], buffer[0],
463                                          sizeof(buffer[0]), 0),
464                         ptl_ipaddr_2_str(data.ioc_u32[1], buffer[1],
465                                          sizeof(buffer[1]), 0),
466                         data.ioc_u32[2], data.ioc_u32[3]);
467         }
468
469         if (index == 0) {
470                 if (errno == ENOENT) {
471                         printf ("<no interfaces>\n");
472                 } else {
473                         fprintf(stderr, "Error getting interfaces: %s: "
474                                 "check dmesg.\n",
475                                 strerror(errno));
476                 }
477         }
478
479         return 0;
480 }
481
482 int
483 jt_ptl_add_interface (int argc, char **argv)
484 {
485         struct libcfs_ioctl_data data;
486         __u32                    ipaddr;
487         int                      rc;
488         __u32                    netmask = 0xffffff00;
489         int                      i;
490         int                      count;
491         char                    *end;
492
493         if (argc < 2 || argc > 3) {
494                 fprintf (stderr, "usage: %s ipaddr [netmask]\n", argv[0]);
495                 return 0;
496         }
497
498         if (!g_net_is_compatible(argv[0], SOCKLND, 0))
499                 return -1;
500
501         if (lnet_parse_ipaddr(&ipaddr, argv[1]) != 0) {
502                 fprintf (stderr, "Can't parse ip: %s\n", argv[1]);
503                 return -1;
504         }
505
506         if (argc > 2 ) {
507                 count = strtol(argv[2], &end, 0);
508                 if (count > 0 && count < 32 && *end == 0) {
509                         netmask = 0;
510                         for (i = count; i > 0; i--)
511                                 netmask = netmask|(1<<(32-i));
512                 } else if (lnet_parse_ipquad(&netmask, argv[2]) != 0) {
513                         fprintf (stderr, "Can't parse netmask: %s\n", argv[2]);
514                         return -1;
515                 }
516         }
517
518         LIBCFS_IOC_INIT(data);
519         data.ioc_net    = g_net;
520         data.ioc_u32[0] = ipaddr;
521         data.ioc_u32[1] = netmask;
522
523         rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_ADD_INTERFACE, &data);
524         if (rc != 0) {
525                 fprintf (stderr, "failed to add interface: %s\n",
526                          strerror (errno));
527                 return -1;
528         }
529
530         return 0;
531 }
532
533 int
534 jt_ptl_del_interface (int argc, char **argv)
535 {
536         struct libcfs_ioctl_data data;
537         int                      rc;
538         __u32                    ipaddr = 0;
539
540         if (argc > 2) {
541                 fprintf (stderr, "usage: %s [ipaddr]\n", argv[0]);
542                 return 0;
543         }
544
545         if (!g_net_is_compatible(argv[0], SOCKLND, 0))
546                 return -1;
547
548         if (argc == 2 &&
549             lnet_parse_ipaddr(&ipaddr, argv[1]) != 0) {
550                 fprintf (stderr, "Can't parse ip: %s\n", argv[1]);
551                 return -1;
552         }
553
554         LIBCFS_IOC_INIT(data);
555         data.ioc_net    = g_net;
556         data.ioc_u32[0] = ipaddr;
557
558         rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_DEL_INTERFACE, &data);
559         if (rc != 0) {
560                 fprintf (stderr, "failed to delete interface: %s\n",
561                          strerror (errno));
562                 return -1;
563         }
564
565         return 0;
566 }
567
568 int
569 jt_ptl_print_peers (int argc, char **argv)
570 {
571         struct libcfs_ioctl_data data;
572         lnet_process_id_t        id;
573         char                     buffer[2][HOST_NAME_MAX + 1];
574         int                      index;
575         int                      rc;
576
577         if (!g_net_is_compatible (argv[0], SOCKLND, RALND, MXLND,
578                                   O2IBLND, GNILND, 0))
579                 return -1;
580
581         for (index = 0;;index++) {
582                 LIBCFS_IOC_INIT(data);
583                 data.ioc_net     = g_net;
584                 data.ioc_count   = index;
585
586                 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_PEER, &data);
587                 if (rc != 0)
588                         break;
589
590                 if (g_net_is_compatible(NULL, SOCKLND, 0)) {
591                         id.nid = data.ioc_nid;
592                         id.pid = data.ioc_u32[4];
593                         printf ("%-20s [%d]%s->%s:%d #%d\n",
594                                 libcfs_id2str(id), 
595                                 data.ioc_count, /* persistence */
596                                 /* my ip */
597                                 ptl_ipaddr_2_str(data.ioc_u32[2], buffer[0],
598                                                  sizeof(buffer[0]), 1),
599                                 /* peer ip */
600                                 ptl_ipaddr_2_str(data.ioc_u32[0], buffer[1],
601                                                  sizeof(buffer[1]), 1),
602                                 data.ioc_u32[1], /* peer port */
603                                 data.ioc_u32[3]); /* conn_count */
604                 } else if (g_net_is_compatible(NULL, RALND, 0)) {
605                         printf ("%-20s [%d]@%s:%d\n",
606                                 libcfs_nid2str(data.ioc_nid), /* peer nid */
607                                 data.ioc_count,   /* peer persistence */
608                                 /* peer ip */
609                                 ptl_ipaddr_2_str(data.ioc_u32[0], buffer[1],
610                                                  sizeof(buffer[1]), 1),
611                                 data.ioc_u32[1]); /* peer port */
612                 } else if (g_net_is_compatible(NULL, GNILND, 0)) {
613                         int disconn = data.ioc_flags >> 16;
614                         char *state;
615
616                         if (disconn)
617                                 state = "D";
618                         else
619                                 state = data.ioc_flags & 0xffff ? "C" : "U";
620
621                         printf ("%-20s (%d) %s [%d] "LPU64" "
622                                 "sq %d/%d tx %d/%d/%d\n",
623                                 libcfs_nid2str(data.ioc_nid), /* peer nid */
624                                 data.ioc_net, /* gemini device id */
625                                 state, /* peer is Connecting, Up, or Down */
626                                 data.ioc_count,   /* peer refcount */
627                                 data.ioc_u64[0], /* peerstamp */
628                                 data.ioc_u32[2], data.ioc_u32[3], /* tx and rx seq */
629                                 /* fmaq, nfma, nrdma */
630                                 data.ioc_u32[0], data.ioc_u32[1], data.ioc_u32[4]
631                                 );
632                 } else {
633                         printf ("%-20s [%d]\n",
634                                 libcfs_nid2str(data.ioc_nid), data.ioc_count);
635                 }
636         }
637
638         if (index == 0) {
639                 if (errno == ENOENT) {
640                         printf ("<no peers>\n");
641                 } else {
642                         fprintf(stderr, "Error getting peer list: %s: "
643                                 "check dmesg.\n",
644                                 strerror(errno));
645                 }
646         }
647         return 0;
648 }
649
650 int
651 jt_ptl_add_peer (int argc, char **argv)
652 {
653         struct libcfs_ioctl_data data;
654         lnet_nid_t               nid;
655         __u32                    ip = 0;
656         int                      port = 0;
657         int                      rc;
658
659         if (!g_net_is_compatible (argv[0], SOCKLND, RALND,
660                                   GNILND, 0))
661                 return -1;
662
663         if (argc != 4) {
664                 fprintf (stderr, "usage(tcp,ra,gni): %s nid ipaddr port\n",
665                          argv[0]);
666                 return 0;
667         }
668
669         nid = libcfs_str2nid(argv[1]);
670         if (nid == LNET_NID_ANY) {
671                 fprintf (stderr, "Can't parse NID: %s\n", argv[1]);
672                 return -1;
673         }
674
675         if (lnet_parse_ipaddr (&ip, argv[2]) != 0) {
676                 fprintf (stderr, "Can't parse ip addr: %s\n", argv[2]);
677                 return -1;
678         }
679
680         if (lnet_parse_port (&port, argv[3]) != 0) {
681                 fprintf (stderr, "Can't parse port: %s\n", argv[3]);
682                 return -1;
683         }
684
685         LIBCFS_IOC_INIT(data);
686         data.ioc_net    = g_net;
687         data.ioc_nid    = nid;
688         data.ioc_u32[0] = ip;
689         data.ioc_u32[1] = port;
690
691         rc = l_ioctl (LNET_DEV_ID, IOC_LIBCFS_ADD_PEER, &data);
692         if (rc != 0) {
693                 fprintf (stderr, "failed to add peer: %s\n",
694                          strerror (errno));
695                 return -1;
696         }
697
698         return 0;
699 }
700
701 int
702 jt_ptl_del_peer (int argc, char **argv)
703 {
704         struct libcfs_ioctl_data data;
705         lnet_nid_t               nid = LNET_NID_ANY;
706         lnet_pid_t               pid = LNET_PID_ANY;
707         __u32                    ip = 0;
708         int                      rc;
709
710         if (!g_net_is_compatible (argv[0], SOCKLND, RALND, MXLND,
711                                   O2IBLND, GNILND, 0))
712                 return -1;
713
714         if (g_net_is_compatible(NULL, SOCKLND, 0)) {
715                 if (argc > 3) {
716                         fprintf (stderr, "usage: %s [nid] [ipaddr]\n",
717                                  argv[0]);
718                         return 0;
719                 }
720         } else if (argc > 2) {
721                 fprintf (stderr, "usage: %s [nid]\n", argv[0]);
722                 return 0;
723         }
724
725         if (argc > 1 &&
726             !libcfs_str2anynid(&nid, argv[1])) {
727                 fprintf (stderr, "Can't parse nid: %s\n", argv[1]);
728                 return -1;
729         }
730
731         if (g_net_is_compatible(NULL, SOCKLND, 0)) {
732                 if (argc > 2 &&
733                     lnet_parse_ipaddr (&ip, argv[2]) != 0) {
734                         fprintf (stderr, "Can't parse ip addr: %s\n",
735                                  argv[2]);
736                         return -1;
737                 }
738         }
739
740         LIBCFS_IOC_INIT(data);
741         data.ioc_net    = g_net;
742         data.ioc_nid    = nid;
743         data.ioc_u32[0] = ip;
744         data.ioc_u32[1] = pid;
745
746         rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_DEL_PEER, &data);
747         if (rc != 0) {
748                 fprintf (stderr, "failed to remove peer: %s\n",
749                          strerror (errno));
750                 return -1;
751         }
752
753         return 0;
754 }
755
756 int
757 jt_ptl_print_connections (int argc, char **argv)
758 {
759         struct libcfs_ioctl_data data;
760         lnet_process_id_t        id;
761         char                     buffer[2][HOST_NAME_MAX + 1];
762         int                      index;
763         int                      rc;
764
765         if (!g_net_is_compatible (argv[0], SOCKLND, RALND, MXLND, O2IBLND,
766                                   GNILND, 0))
767                 return -1;
768
769         for (index = 0; ; index++) {
770                 LIBCFS_IOC_INIT(data);
771                 data.ioc_net     = g_net;
772                 data.ioc_count   = index;
773
774                 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_CONN, &data);
775                 if (rc != 0)
776                         break;
777
778                 if (g_net_is_compatible (NULL, SOCKLND, 0)) {
779                         id.nid = data.ioc_nid;
780                         id.pid = data.ioc_u32[6];
781                         printf ("%-20s %s[%d]%s->%s:%d %d/%d %s\n",
782                                 libcfs_id2str(id),
783                                 (data.ioc_u32[3] == SOCKLND_CONN_ANY) ? "A" :
784                                 (data.ioc_u32[3] == SOCKLND_CONN_CONTROL) ? "C" :
785                                 (data.ioc_u32[3] == SOCKLND_CONN_BULK_IN) ? "I" :
786                                 (data.ioc_u32[3] == SOCKLND_CONN_BULK_OUT) ? "O" : "?",
787                                 data.ioc_u32[4], /* scheduler */
788                                 /* local IP addr */
789                                 ptl_ipaddr_2_str(data.ioc_u32[2], buffer[0],
790                                                  sizeof(buffer[0]), 1),
791                                 /* remote IP addr */
792                                 ptl_ipaddr_2_str(data.ioc_u32[0], buffer[1],
793                                                  sizeof(buffer[1]), 1),
794                                 data.ioc_u32[1],         /* remote port */
795                                 data.ioc_count, /* tx buffer size */
796                                 data.ioc_u32[5], /* rx buffer size */
797                                 data.ioc_flags ? "nagle" : "nonagle");
798                 } else if (g_net_is_compatible (NULL, RALND, 0)) {
799                         printf ("%-20s [%d]\n",
800                                 libcfs_nid2str(data.ioc_nid),
801                                 data.ioc_u32[0] /* device id */);
802                 } else if (g_net_is_compatible (NULL, O2IBLND, 0)) {
803                         printf ("%s mtu %d\n",
804                                 libcfs_nid2str(data.ioc_nid),
805                                 data.ioc_u32[0]); /* path MTU */
806                 } else if (g_net_is_compatible (NULL, GNILND, 0)) {
807                         printf ("%-20s [%d]\n",
808                                 libcfs_nid2str(data.ioc_nid),
809                                 data.ioc_u32[0] /* device id */);
810                 } else {
811                         printf ("%s\n", libcfs_nid2str(data.ioc_nid));
812                 }
813         }
814
815         if (index == 0) {
816                 if (errno == ENOENT) {
817                         printf ("<no connections>\n");
818                 } else {
819                         fprintf(stderr, "Error getting connection list: %s: "
820                                 "check dmesg.\n",
821                                 strerror(errno));
822                 }
823         }
824         return 0;
825 }
826
827 int jt_ptl_disconnect(int argc, char **argv)
828 {
829         struct libcfs_ioctl_data data;
830         lnet_nid_t               nid = LNET_NID_ANY;
831         __u32                    ipaddr = 0;
832         int                      rc;
833
834         if (argc > 3) {
835                 fprintf(stderr, "usage: %s [nid] [ipaddr]\n", argv[0]);
836                 return 0;
837         }
838
839         if (!g_net_is_compatible (NULL, SOCKLND, RALND, MXLND, O2IBLND,
840                                   GNILND, 0))
841                 return 0;
842
843         if (argc >= 2 &&
844             !libcfs_str2anynid(&nid, argv[1])) {
845                 fprintf (stderr, "Can't parse nid %s\n", argv[1]);
846                 return -1;
847         }
848
849         if (g_net_is_compatible (NULL, SOCKLND, 0) &&
850             argc >= 3 &&
851             lnet_parse_ipaddr (&ipaddr, argv[2]) != 0) {
852                 fprintf (stderr, "Can't parse ip addr %s\n", argv[2]);
853                 return -1;
854         }
855
856         LIBCFS_IOC_INIT(data);
857         data.ioc_net     = g_net;
858         data.ioc_nid     = nid;
859         data.ioc_u32[0]  = ipaddr;
860
861         rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_CLOSE_CONNECTION, &data);
862         if (rc != 0) {
863                 fprintf(stderr, "failed to remove connection: %s\n",
864                         strerror(errno));
865                 return -1;
866         }
867
868         return 0;
869 }
870
871 int jt_ptl_push_connection (int argc, char **argv)
872 {
873         struct libcfs_ioctl_data data;
874         int                      rc;
875         lnet_nid_t               nid = LNET_NID_ANY;
876
877         if (argc > 2) {
878                 fprintf(stderr, "usage: %s [nid]\n", argv[0]);
879                 return 0;
880         }
881
882         if (!g_net_is_compatible (argv[0], SOCKLND, GNILND, 0))
883                 return -1;
884
885         if (argc > 1 &&
886             !libcfs_str2anynid(&nid, argv[1])) {
887                 fprintf(stderr, "Can't parse nid: %s\n", argv[1]);
888                 return -1;
889         }
890
891         LIBCFS_IOC_INIT(data);
892         data.ioc_net     = g_net;
893         data.ioc_nid     = nid;
894
895         rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_PUSH_CONNECTION, &data);
896         if (rc != 0) {
897                 fprintf(stderr, "failed to push connection: %s\n",
898                         strerror(errno));
899                 return -1;
900         }
901
902         return 0;
903 }
904
905 int
906 jt_ptl_print_active_txs (int argc, char **argv)
907 {
908         struct libcfs_ioctl_data data;
909         int                      index;
910         int                      rc;
911
912         if (!g_net_is_compatible (argv[0], QSWLND, 0))
913                 return -1;
914
915         for (index = 0;;index++) {
916                 LIBCFS_IOC_INIT(data);
917                 data.ioc_net   = g_net;
918                 data.ioc_count = index;
919
920                 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_TXDESC, &data);
921                 if (rc != 0)
922                         break;
923
924                 printf ("type %u payload %6d to %s via %s by pid %6d: "
925                         "%s, %s, state %d\n",
926                         data.ioc_u32[0],
927                         data.ioc_count,
928                         libcfs_nid2str(data.ioc_nid),
929                         libcfs_nid2str(data.ioc_u64[0]),
930                         data.ioc_u32[1],
931                         (data.ioc_flags & 1) ? "delayed" : "immediate",
932                         (data.ioc_flags & 2) ? "nblk"    : "normal",
933                         data.ioc_flags >> 2);
934         }
935
936         if (index == 0) {
937                 if (errno == ENOENT) {
938                         printf ("<no active descs>\n");
939                 } else {
940                         fprintf(stderr, "Error getting active transmits list: "
941                                 "%s: check dmesg.\n",
942                                 strerror(errno));
943                 }
944         }
945         return 0;
946 }
947
948 int jt_ptl_ping(int argc, char **argv)
949 {
950         int                      rc;
951         int                      timeout;
952         lnet_process_id_t        id;
953         lnet_process_id_t        ids[16];
954         int                      maxids = sizeof(ids)/sizeof(ids[0]);
955         struct libcfs_ioctl_data data;
956         char                    *sep;
957         int                      i;
958
959         if (argc < 2) {
960                 fprintf(stderr, "usage: %s id [timeout (secs)]\n", argv[0]);
961                 return 0;
962         }
963
964         sep = strchr(argv[1], '-');
965         if (sep == NULL) {
966                 rc = lnet_parse_nid(argv[1], &id);
967                 if (rc != 0)
968                         return -1;
969         } else {
970                 char   *end;
971
972                 if (argv[1][0] == 'u' ||
973                     argv[1][0] == 'U')
974                         id.pid = strtoul(&argv[1][1], &end, 0) | LNET_PID_USERFLAG;
975                 else
976                         id.pid = strtoul(argv[1], &end, 0);
977
978                 if (end != sep) { /* assuming '-' is part of hostname */
979                         rc = lnet_parse_nid(argv[1], &id);
980                         if (rc != 0)
981                                 return -1;
982                 } else {
983                         id.nid = libcfs_str2nid(sep + 1);
984
985                         if (id.nid == LNET_NID_ANY) {
986                                 fprintf(stderr,
987                                         "Can't parse process id \"%s\"\n",
988                                         argv[1]);
989                                 return -1;
990                         }
991                 }
992         }
993
994         if (argc > 2)
995                 timeout = 1000 * atol(argv[2]);
996         else
997                 timeout = 1000;                 /* default 1 second timeout */
998
999         LIBCFS_IOC_INIT (data);
1000         data.ioc_nid     = id.nid;
1001         data.ioc_u32[0]  = id.pid;
1002         data.ioc_u32[1]  = timeout;
1003         data.ioc_plen1   = sizeof(ids);
1004         data.ioc_pbuf1   = (char *)ids;
1005
1006         rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_PING, &data);
1007         if (rc != 0) {
1008                 fprintf(stderr, "failed to ping %s: %s\n",
1009                         id.pid == LNET_PID_ANY ?
1010                         libcfs_nid2str(id.nid) : libcfs_id2str(id),
1011                         strerror(errno));
1012                 return -1;
1013         }
1014
1015         for (i = 0; i < data.ioc_count && i < maxids; i++)
1016                 printf("%s\n", libcfs_id2str(ids[i]));
1017
1018         if (data.ioc_count > maxids)
1019                 printf("%d out of %d ids listed\n", maxids, data.ioc_count);
1020
1021         return 0;
1022 }
1023
1024 int jt_ptl_mynid(int argc, char **argv)
1025 {
1026         struct libcfs_ioctl_data data;
1027         lnet_nid_t               nid;
1028         int rc;
1029
1030         if (argc != 2) {
1031                 fprintf(stderr, "usage: %s NID\n", argv[0]);
1032                 return 0;
1033         }
1034
1035         nid = libcfs_str2nid(argv[1]);
1036         if (nid == LNET_NID_ANY) {
1037                 fprintf(stderr, "Can't parse NID '%s'\n", argv[1]);
1038                 return -1;
1039         }
1040
1041         LIBCFS_IOC_INIT(data);
1042         data.ioc_net = LNET_NIDNET(nid);
1043         data.ioc_nid = nid;
1044
1045         rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_REGISTER_MYNID, &data);
1046         if (rc < 0)
1047                 fprintf(stderr, "setting my NID failed: %s\n",
1048                        strerror(errno));
1049         else
1050                 printf("registered my nid %s\n", libcfs_nid2str(nid));
1051
1052         return 0;
1053 }
1054
1055 int
1056 jt_ptl_fail_nid (int argc, char **argv)
1057 {
1058         int                      rc;
1059         lnet_nid_t               nid;
1060         int                      threshold;
1061         struct libcfs_ioctl_data data;
1062
1063         if (argc < 2 || argc > 3)
1064         {
1065                 fprintf (stderr, "usage: %s nid|\"*\" [count (0 == mend)]\n", argv[0]);
1066                 return (0);
1067         }
1068
1069         if (!libcfs_str2anynid(&nid, argv[1]))
1070         {
1071                 fprintf (stderr, "Can't parse nid \"%s\"\n", argv[1]);
1072                 return (-1);
1073         }
1074
1075         if (argc < 3) {
1076                 threshold = LNET_MD_THRESH_INF;
1077         } else if (sscanf(argv[2], "%i", &threshold) != 1) {
1078                 fprintf (stderr, "Can't parse count \"%s\"\n", argv[2]);
1079                 return (-1);
1080         }
1081
1082         LIBCFS_IOC_INIT (data);
1083         data.ioc_nid = nid;
1084         data.ioc_count = threshold;
1085
1086         rc = l_ioctl (LNET_DEV_ID, IOC_LIBCFS_FAIL_NID, &data);
1087         if (rc < 0)
1088                 fprintf (stderr, "IOC_LIBCFS_FAIL_NID failed: %s\n",
1089                          strerror (errno));
1090         else
1091                 printf ("%s %s\n", threshold == 0 ? "Unfailing" : "Failing", argv[1]);
1092
1093         return (0);
1094 }
1095
1096 int
1097 jt_ptl_add_route (int argc, char **argv)
1098 {
1099         struct lnet_ioctl_config_data data;
1100         lnet_nid_t               gateway_nid;
1101         unsigned int             hops = 1;
1102         unsigned int             priority = 0;
1103         char                    *end;
1104         int                      rc;
1105
1106         if (argc < 2 || argc > 4) {
1107                 fprintf(stderr, "usage: %s gateway [hopcount [priority]]\n",
1108                         argv[0]);
1109                 return -1;
1110         }
1111
1112         if (g_net_is_set(argv[0]) == 0)
1113                 return -1;
1114
1115         gateway_nid = libcfs_str2nid(argv[1]);
1116         if (gateway_nid == LNET_NID_ANY) {
1117                 fprintf(stderr, "Can't parse gateway NID \"%s\"\n", argv[1]);
1118                 return -1;
1119         }
1120
1121         if (argc > 2) {
1122                 hops = strtoul(argv[2], &end, 0);
1123                 if (hops == 0 || hops >= 256 || (end != NULL && *end != 0)) {
1124                         fprintf(stderr, "Can't parse hopcount \"%s\"\n",
1125                                 argv[2]);
1126                         return -1;
1127                 }
1128                 if (argc == 4) {
1129                         priority = strtoul(argv[3], &end, 0);
1130                         if (end != NULL && *end != 0) {
1131                                 fprintf(stderr,
1132                                         "Can't parse priority \"%s\"\n",
1133                                         argv[3]);
1134                                 return -1;
1135                         }
1136                 }
1137         }
1138
1139         LIBCFS_IOC_INIT_V2(data, cfg_hdr);
1140         data.cfg_net = g_net;
1141         data.cfg_config_u.cfg_route.rtr_hop = hops;
1142         data.cfg_nid = gateway_nid;
1143         data.cfg_config_u.cfg_route.rtr_priority = priority;
1144
1145         rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_ADD_ROUTE, &data);
1146         if (rc != 0) {
1147                 fprintf(stderr, "IOC_LIBCFS_ADD_ROUTE failed: %s\n",
1148                         strerror(errno));
1149                 return -1;
1150         }
1151
1152         return 0;
1153 }
1154
1155 int
1156 jt_ptl_del_route (int argc, char **argv)
1157 {
1158         struct lnet_ioctl_config_data data;
1159         lnet_nid_t               nid;
1160         int                      rc;
1161
1162         if (argc != 2) {
1163                 fprintf(stderr, "usage: %s gatewayNID\n", argv[0]);
1164                 return 0;
1165         }
1166
1167         if (libcfs_str2anynid(&nid, argv[1]) == 0) {
1168                 fprintf(stderr, "Can't parse gateway NID "
1169                         "\"%s\"\n", argv[1]);
1170                 return -1;
1171         }
1172
1173         LIBCFS_IOC_INIT_V2(data, cfg_hdr);
1174         data.cfg_net = g_net_set ? g_net : LNET_NIDNET(LNET_NID_ANY);
1175         data.cfg_nid = nid;
1176
1177         rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_DEL_ROUTE, &data);
1178         if (rc != 0) {
1179                 fprintf(stderr, "IOC_LIBCFS_DEL_ROUTE (%s) failed: %s\n",
1180                         libcfs_nid2str(nid), strerror(errno));
1181                 return -1;
1182         }
1183
1184         return 0;
1185 }
1186
1187 int
1188 jt_ptl_notify_router (int argc, char **argv)
1189 {
1190         struct libcfs_ioctl_data data;
1191         int                      enable;
1192         lnet_nid_t               nid;
1193         int                      rc;
1194         struct timeval           now;
1195         time_t                   when;
1196
1197         if (argc < 3)
1198         {
1199                 fprintf (stderr, "usage: %s targetNID <up/down> [<time>]\n", 
1200                          argv[0]);
1201                 return (0);
1202         }
1203
1204         nid = libcfs_str2nid(argv[1]);
1205         if (nid == LNET_NID_ANY) {
1206                 fprintf (stderr, "Can't parse target NID \"%s\"\n", argv[1]);
1207                 return (-1);
1208         }
1209
1210         if (lnet_parse_bool (&enable, argv[2]) != 0) {
1211                 fprintf (stderr, "Can't parse boolean %s\n", argv[2]);
1212                 return (-1);
1213         }
1214
1215         gettimeofday(&now, NULL);
1216
1217         if (argc < 4) {
1218                 when = now.tv_sec;
1219         } else if (lnet_parse_time (&when, argv[3]) != 0) {
1220                 fprintf(stderr, "Can't parse time %s\n"
1221                         "Please specify either 'YYYY-MM-DD-HH:MM:SS'\n"
1222                         "or an absolute unix time in seconds\n", argv[3]);
1223                 return (-1);
1224         } else if (when > now.tv_sec) {
1225                 fprintf (stderr, "%s specifies a time in the future\n",
1226                          argv[3]);
1227                 return (-1);
1228         }
1229
1230         LIBCFS_IOC_INIT(data);
1231         data.ioc_nid = nid;
1232         data.ioc_flags = enable;
1233         /* Yeuch; 'cept I need a __u64 on 64 bit machines... */
1234         data.ioc_u64[0] = (__u64)when;
1235
1236         rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_NOTIFY_ROUTER, &data);
1237         if (rc != 0) {
1238                 fprintf (stderr, "IOC_LIBCFS_NOTIFY_ROUTER (%s) failed: %s\n",
1239                          libcfs_nid2str(nid), strerror (errno));
1240                 return (-1);
1241         }
1242
1243         return (0);
1244 }
1245
1246 int
1247 jt_ptl_print_routes (int argc, char **argv)
1248 {
1249         struct lnet_ioctl_config_data  data;
1250         int                       rc;
1251         int                       index;
1252         __u32                     net;
1253         lnet_nid_t                nid;
1254         unsigned int              hops;
1255         int                       alive;
1256         unsigned int              pri;
1257
1258         for (index = 0; ; index++) {
1259                 LIBCFS_IOC_INIT_V2(data, cfg_hdr);
1260                 data.cfg_count = index;
1261
1262                 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_ROUTE, &data);
1263                 if (rc != 0)
1264                         break;
1265
1266                 net     = data.cfg_net;
1267                 hops    = data.cfg_config_u.cfg_route.rtr_hop;
1268                 nid     = data.cfg_nid;
1269                 alive   = data.cfg_config_u.cfg_route.rtr_flags;
1270                 pri     = data.cfg_config_u.cfg_route.rtr_priority;
1271
1272                 printf("net %18s hops %u gw %32s %s pri %u\n",
1273                        libcfs_net2str(net), hops,
1274                        libcfs_nid2str(nid), alive ? "up" : "down", pri);
1275         }
1276
1277         if (errno != ENOENT)
1278                 fprintf(stderr, "Error getting routes: %s: check dmesg.\n",
1279                         strerror(errno));
1280
1281         return 0;
1282 }
1283
1284 static int
1285 fault_attr_nid_parse(char *str, lnet_nid_t *nid_p)
1286 {
1287         lnet_nid_t nid;
1288         __u32      net;
1289         int        rc = 0;
1290
1291         /* NB: can't support range ipaddress except * and *@net */
1292         if (strlen(str) > 2 && str[0] == '*' && str[1] == '@') {
1293                 net = libcfs_str2net(str + 2);
1294                 if (net == LNET_NIDNET(LNET_NID_ANY))
1295                         goto failed;
1296
1297                 nid = LNET_MKNID(net, LNET_NIDADDR(LNET_NID_ANY));
1298         } else {
1299                 rc = libcfs_str2anynid(&nid, str);
1300                 if (!rc)
1301                         goto failed;
1302         }
1303
1304         *nid_p = nid;
1305         return 0;
1306 failed:
1307         fprintf(stderr, "Invalid NID : %s\n", str);
1308         return -1;
1309 }
1310
1311 static int
1312 fault_attr_msg_parse(char *msg_str, __u32 *mask_p)
1313 {
1314         if (!strcasecmp(msg_str, "put")) {
1315                 *mask_p |= LNET_PUT_BIT;
1316                 return 0;
1317
1318         } else if (!strcasecmp(msg_str, "ack")) {
1319                 *mask_p |= LNET_ACK_BIT;
1320                 return 0;
1321
1322         } else if (!strcasecmp(msg_str, "get")) {
1323                 *mask_p |= LNET_GET_BIT;
1324                 return 0;
1325
1326         } else if (!strcasecmp(msg_str, "reply")) {
1327                 *mask_p |= LNET_REPLY_BIT;
1328                 return 0;
1329         }
1330
1331         fprintf(stderr, "unknown message type %s\n", msg_str);
1332         return -1;
1333 }
1334
1335 static int
1336 fault_attr_ptl_parse(char *ptl_str, __u64 *mask_p)
1337 {
1338         unsigned long rc = strtoul(optarg, NULL, 0);
1339
1340         if (rc >= 64) {
1341                 fprintf(stderr, "invalid portal: %lu\n", rc);
1342                 return -1;
1343         }
1344
1345         *mask_p |= (1ULL << rc);
1346         return 0;
1347 }
1348
1349 static int
1350 fault_simul_rule_add(__u32 opc, char *name, int argc, char **argv)
1351 {
1352         struct libcfs_ioctl_data  data = {{0}};
1353         struct lnet_fault_attr    attr;
1354         char                     *optstr;
1355         int                       rc;
1356
1357         static struct option opts[] = {
1358                 {"source",      required_argument,      0,      's'},
1359                 {"dest",        required_argument,      0,      'd'},
1360                 {"rate",        required_argument,      0,      'r'},
1361                 {"interval",    required_argument,      0,      'i'},
1362                 {"latency",     required_argument,      0,      'l'},
1363                 {"portal",      required_argument,      0,      'p'},
1364                 {"message",     required_argument,      0,      'm'},
1365                 {0, 0, 0, 0}
1366         };
1367
1368         if (argc == 1) {
1369                 fprintf(stderr, "Failed, please provide source, destination "
1370                                 "and rate of rule\n");
1371                 return -1;
1372         }
1373
1374         optstr = opc == LNET_CTL_DROP_ADD ? "s:d:r:i:p:m:" : "s:d:r:l:p:m:";
1375         memset(&attr, 0, sizeof(attr));
1376         while (1) {
1377                 char c = getopt_long(argc, argv, optstr, opts, NULL);
1378
1379                 if (c == -1)
1380                         break;
1381
1382                 switch (c) {
1383                 case 's': /* source NID/NET */
1384                         rc = fault_attr_nid_parse(optarg, &attr.fa_src);
1385                         if (rc != 0)
1386                                 goto getopt_failed;
1387                         break;
1388
1389                 case 'd': /* dest NID/NET */
1390                         rc = fault_attr_nid_parse(optarg, &attr.fa_dst);
1391                         if (rc != 0)
1392                                 goto getopt_failed;
1393                         break;
1394
1395                 case 'r': /* drop rate */
1396                         if (opc == LNET_CTL_DROP_ADD)
1397                                 attr.u.drop.da_rate = strtoul(optarg, NULL, 0);
1398                         else
1399                                 attr.u.delay.la_rate = strtoul(optarg, NULL, 0);
1400                         break;
1401
1402                 case 'i': /* time interval (# seconds) for message drop */
1403                         if (opc == LNET_CTL_DROP_ADD)
1404                                 attr.u.drop.da_interval = strtoul(optarg,
1405                                                                   NULL, 0);
1406                         else
1407                                 attr.u.delay.la_interval = strtoul(optarg,
1408                                                                    NULL, 0);
1409                         break;
1410
1411                 case 'l': /* seconds to wait before activating rule */
1412                         attr.u.delay.la_latency = strtoul(optarg, NULL, 0);
1413                         break;
1414
1415                 case 'p': /* portal to filter */
1416                         rc = fault_attr_ptl_parse(optarg, &attr.fa_ptl_mask);
1417                         if (rc != 0)
1418                                 goto getopt_failed;
1419                         break;
1420
1421                 case 'm': /* message types to filter */
1422                         rc = fault_attr_msg_parse(optarg, &attr.fa_msg_mask);
1423                         if (rc != 0)
1424                                 goto getopt_failed;
1425                         break;
1426
1427                 default:
1428                         fprintf(stderr, "error: %s: option '%s' "
1429                                 "unrecognized\n", argv[0], argv[optind - 1]);
1430                         goto getopt_failed;
1431                 }
1432         }
1433         optind = 1;
1434
1435         if (opc == LNET_CTL_DROP_ADD) {
1436                 /* NB: drop rate and interval are exclusive to each other */
1437                 if (!((attr.u.drop.da_rate == 0) ^
1438                       (attr.u.drop.da_interval == 0))) {
1439                         fprintf(stderr,
1440                                 "please provide either drop rate or interval "
1441                                 "but not both at the same time.\n");
1442                         return -1;
1443                 }
1444         } else if (opc == LNET_CTL_DELAY_ADD) {
1445                 if (!((attr.u.delay.la_rate == 0) ^
1446                       (attr.u.delay.la_interval == 0))) {
1447                         fprintf(stderr,
1448                                 "please provide either delay rate or interval "
1449                                 "but not both at the same time.\n");
1450                         return -1;
1451                 }
1452
1453                 if (attr.u.delay.la_latency == 0) {
1454                         fprintf(stderr, "latency cannot be zero\n");
1455                         return -1;
1456                 }
1457         }
1458
1459         if (attr.fa_src == 0 || attr.fa_dst == 0) {
1460                 fprintf(stderr, "Please provide both source and destination "
1461                                 "of %s rule\n", name);
1462                 return -1;
1463         }
1464
1465         data.ioc_flags = opc;
1466         data.ioc_inllen1 = sizeof(attr);
1467         data.ioc_inlbuf1 = (char *)&attr;
1468         if (libcfs_ioctl_pack(&data, &ioc_buf, IOC_BUF_SIZE) != 0) {
1469                 fprintf(stderr, "libcfs_ioctl_pack failed\n");
1470                 return -1;
1471         }
1472
1473         rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_LNET_FAULT, ioc_buf);
1474         if (rc != 0) {
1475                 fprintf(stderr, "add %s rule %s->%s failed: %s\n",
1476                         name, libcfs_nid2str(attr.fa_src),
1477                         libcfs_nid2str(attr.fa_dst), strerror(errno));
1478                 return -1;
1479         }
1480
1481         printf("Added %s rule %s->%s (1/%d)\n",
1482                name, libcfs_nid2str(attr.fa_src), libcfs_nid2str(attr.fa_dst),
1483                opc == LNET_CTL_DROP_ADD ?
1484                attr.u.drop.da_rate : attr.u.delay.la_rate);
1485         return 0;
1486
1487 getopt_failed:
1488         optind = 1;
1489         return -1;
1490 }
1491
1492 int
1493 jt_ptl_drop_add(int argc, char **argv)
1494 {
1495         return fault_simul_rule_add(LNET_CTL_DROP_ADD, "drop", argc, argv);
1496 }
1497
1498 int
1499 jt_ptl_delay_add(int argc, char **argv)
1500 {
1501         return fault_simul_rule_add(LNET_CTL_DELAY_ADD, "delay", argc, argv);
1502 }
1503
1504 static int
1505 fault_simul_rule_del(__u32 opc, char *name, int argc, char **argv)
1506 {
1507         struct libcfs_ioctl_data data = {{0}};
1508         struct lnet_fault_attr   attr;
1509         bool                     all = false;
1510         int                      rc;
1511
1512         static struct option opts[] = {
1513                 {"source",      required_argument,      0,      's'},
1514                 {"dest",        required_argument,      0,      'd'},
1515                 {"all",         no_argument,            0,      'a'},
1516                 {0, 0, 0, 0}
1517         };
1518
1519         if (argc == 1) {
1520                 fprintf(stderr, "Failed, please provide source and "
1521                                 "destination of rule\n");
1522                 return -1;
1523         }
1524
1525         memset(&attr, 0, sizeof(attr));
1526         while (1) {
1527                 char c = getopt_long(argc, argv, "s:d:a", opts, NULL);
1528
1529                 if (c == -1 || all)
1530                         break;
1531
1532                 switch (c) {
1533                 case 's':
1534                         rc = fault_attr_nid_parse(optarg, &attr.fa_src);
1535                         if (rc != 0)
1536                                 goto getopt_failed;
1537                         break;
1538                 case 'd':
1539                         rc = fault_attr_nid_parse(optarg, &attr.fa_dst);
1540                         if (rc != 0)
1541                                 goto getopt_failed;
1542                         break;
1543                 case 'a':
1544                         attr.fa_src = attr.fa_dst = 0;
1545                         all = true;
1546                         break;
1547                 default:
1548                         fprintf(stderr, "error: %s: option '%s' "
1549                                 "unrecognized\n", argv[0], argv[optind - 1]);
1550                         goto getopt_failed;
1551                 }
1552         }
1553         optind = 1;
1554
1555         data.ioc_flags = opc;
1556         data.ioc_inllen1 = sizeof(attr);
1557         data.ioc_inlbuf1 = (char *)&attr;
1558         if (libcfs_ioctl_pack(&data, &ioc_buf, IOC_BUF_SIZE) != 0) {
1559                 fprintf(stderr, "libcfs_ioctl_pack failed\n");
1560                 return -1;
1561         }
1562
1563         rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_LNET_FAULT, ioc_buf);
1564         if (rc != 0) {
1565                 fprintf(stderr, "remove %s rule %s->%s failed: %s\n", name,
1566                         all ? "all" : libcfs_nid2str(attr.fa_src),
1567                         all ? "all" : libcfs_nid2str(attr.fa_dst),
1568                         strerror(errno));
1569                 return -1;
1570         }
1571
1572         libcfs_ioctl_unpack(&data, ioc_buf);
1573         printf("Removed %d %s rules\n", data.ioc_count, name);
1574         return 0;
1575
1576 getopt_failed:
1577         optind = 1;
1578         return -1;
1579 }
1580
1581 int
1582 jt_ptl_drop_del(int argc, char **argv)
1583 {
1584         return fault_simul_rule_del(LNET_CTL_DROP_DEL, "drop", argc, argv);
1585 }
1586
1587 int
1588 jt_ptl_delay_del(int argc, char **argv)
1589 {
1590         return fault_simul_rule_del(LNET_CTL_DELAY_DEL, "delay", argc, argv);
1591 }
1592
1593 static int
1594 fault_simul_rule_reset(__u32 opc, char *name, int argc, char **argv)
1595 {
1596         struct libcfs_ioctl_data   data = {{0}};
1597         int                        rc;
1598
1599         LIBCFS_IOC_INIT(data);
1600         data.ioc_flags = opc;
1601
1602         rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_LNET_FAULT, &data);
1603         if (rc != 0) {
1604                 fprintf(stderr, "failed to reset %s stats: %s\n",
1605                         name, strerror(errno));
1606                 return -1;
1607         }
1608         return 0;
1609 }
1610
1611 int
1612 jt_ptl_drop_reset(int argc, char **argv)
1613 {
1614         return fault_simul_rule_reset(LNET_CTL_DROP_RESET, "drop", argc, argv);
1615 }
1616
1617 int
1618 jt_ptl_delay_reset(int argc, char **argv)
1619 {
1620         return fault_simul_rule_reset(LNET_CTL_DELAY_RESET, "delay",
1621                                       argc, argv);
1622 }
1623
1624 static int
1625 fault_simul_rule_list(__u32 opc, char *name, int argc, char **argv)
1626 {
1627         struct libcfs_ioctl_data data = {{0}};
1628         struct lnet_fault_attr   attr;
1629         struct lnet_fault_stat   stat;
1630         int                      pos;
1631
1632         printf("LNet %s rules:\n", name);
1633         for (pos = 0;; pos++) {
1634                 int             rc;
1635
1636                 memset(&attr, 0, sizeof(attr));
1637                 memset(&stat, 0, sizeof(stat));
1638
1639                 data.ioc_count = pos;
1640                 data.ioc_flags = opc;
1641                 data.ioc_inllen1 = sizeof(attr);
1642                 data.ioc_inlbuf1 = (char *)&attr;
1643                 data.ioc_inllen2 = sizeof(stat);
1644                 data.ioc_inlbuf2 = (char *)&stat;
1645                 if (libcfs_ioctl_pack(&data, &ioc_buf, IOC_BUF_SIZE) != 0) {
1646                         fprintf(stderr, "libcfs_ioctl_pack failed\n");
1647                         return -1;
1648                 }
1649
1650                 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_LNET_FAULT, ioc_buf);
1651                 if (rc != 0)
1652                         break;
1653
1654                 libcfs_ioctl_unpack(&data, ioc_buf);
1655
1656                 if (opc == LNET_CTL_DROP_LIST) {
1657                         printf("%s->%s (1/%d | %d) ptl "LPX64", msg %x, "
1658                                LPU64"/"LPU64", PUT "LPU64", ACK "LPU64", GET "
1659                                LPU64", REP "LPU64"\n",
1660                                libcfs_nid2str(attr.fa_src),
1661                                libcfs_nid2str(attr.fa_dst),
1662                                attr.u.drop.da_rate, attr.u.drop.da_interval,
1663                                attr.fa_ptl_mask, attr.fa_msg_mask,
1664                                stat.u.drop.ds_dropped, stat.fs_count,
1665                                stat.fs_put, stat.fs_ack,
1666                                stat.fs_get, stat.fs_reply);
1667
1668                 } else if (opc == LNET_CTL_DELAY_LIST) {
1669                         printf("%s->%s (1/%d | %d, latency %d) ptl "LPX64
1670                                ", msg %x, "LPU64"/"LPU64", PUT "LPU64
1671                                ", ACK "LPU64", GET "LPU64", REP "LPU64"\n",
1672                                libcfs_nid2str(attr.fa_src),
1673                                libcfs_nid2str(attr.fa_dst),
1674                                attr.u.delay.la_rate, attr.u.delay.la_interval,
1675                                attr.u.delay.la_latency,
1676                                attr.fa_ptl_mask, attr.fa_msg_mask,
1677                                stat.u.delay.ls_delayed, stat.fs_count,
1678                                stat.fs_put, stat.fs_ack, stat.fs_get,
1679                                stat.fs_reply);
1680                 }
1681         }
1682         printf("found total %d\n", pos);
1683
1684         return 0;
1685 }
1686
1687 int
1688 jt_ptl_drop_list(int argc, char **argv)
1689 {
1690         return fault_simul_rule_list(LNET_CTL_DROP_LIST, "drop", argc, argv);
1691 }
1692
1693 int
1694 jt_ptl_delay_list(int argc, char **argv)
1695 {
1696         return fault_simul_rule_list(LNET_CTL_DELAY_LIST, "delay", argc, argv);
1697 }
1698
1699 double
1700 get_cycles_per_usec ()
1701 {
1702         FILE      *f = fopen ("/proc/cpuinfo", "r");
1703         double     mhz;
1704         char      line[64];
1705
1706         if (f != NULL) {
1707                 while (fgets (line, sizeof (line), f) != NULL)
1708                         if (sscanf (line, "cpu MHz : %lf", &mhz) == 1) {
1709                                 fclose (f);
1710                                 return (mhz);
1711                         }
1712                 fclose (f);
1713         }
1714
1715         fprintf (stderr, "Can't read/parse /proc/cpuinfo\n");
1716         return (1000.0);
1717 }
1718
1719 int jt_ptl_memhog(int argc, char **argv)
1720 {
1721         static int                gfp = 0;        /* sticky! */
1722
1723         struct libcfs_ioctl_data  data;
1724         int                       rc;
1725         int                       count;
1726         char                     *end;
1727
1728         if (argc < 2)  {
1729                 fprintf(stderr, "usage: %s <npages> [<GFP flags>]\n", argv[0]);
1730                 return 0;
1731         }
1732
1733         count = strtol(argv[1], &end, 0);
1734         if (count < 0 || *end != 0) {
1735                 fprintf(stderr, "Can't parse page count '%s'\n", argv[1]);
1736                 return -1;
1737         }
1738
1739         if (argc >= 3) {
1740                 rc = strtol(argv[2], &end, 0);
1741                 if (*end != 0) {
1742                         fprintf(stderr, "Can't parse gfp flags '%s'\n", argv[2]);
1743                         return -1;
1744                 }
1745                 gfp = rc;
1746         }
1747
1748         LIBCFS_IOC_INIT(data);
1749         data.ioc_count = count;
1750         data.ioc_flags = gfp;
1751         rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_MEMHOG, &data);
1752
1753         if (rc != 0) {
1754                 fprintf(stderr, "memhog %d failed: %s\n", count, strerror(errno));
1755                 return -1;
1756         }
1757
1758         printf("memhog %d OK\n", count);
1759         return 0;
1760 }
1761
1762 int jt_ptl_testprotocompat(int argc, char **argv)
1763 {
1764         struct libcfs_ioctl_data  data;
1765         int                       rc;
1766         int                       flags;
1767         char                     *end;
1768
1769         if (argc < 2)  {
1770                 fprintf(stderr, "usage: %s <number>\n", argv[0]);
1771                 return 0;
1772         }
1773
1774         flags = strtol(argv[1], &end, 0);
1775         if (flags < 0 || *end != 0) {
1776                 fprintf(stderr, "Can't parse flags '%s'\n", argv[1]);
1777                 return -1;
1778         }
1779
1780         LIBCFS_IOC_INIT(data);
1781         data.ioc_flags = flags;
1782         rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_TESTPROTOCOMPAT, &data);
1783
1784         if (rc != 0) {
1785                 fprintf(stderr, "test proto compat %x failed: %s\n",
1786                         flags, strerror(errno));
1787                 return -1;
1788         }
1789
1790         printf("test proto compat %x OK\n", flags);
1791         return 0;
1792 }
1793
1794