Whamcloud - gitweb
LU-6001 build: cleanup build scripts after reorganization
[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, O2IBLND, GNILND, 0))
578                 return -1;
579
580         for (index = 0;;index++) {
581                 LIBCFS_IOC_INIT(data);
582                 data.ioc_net     = g_net;
583                 data.ioc_count   = index;
584
585                 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_PEER, &data);
586                 if (rc != 0)
587                         break;
588
589                 if (g_net_is_compatible(NULL, SOCKLND, 0)) {
590                         id.nid = data.ioc_nid;
591                         id.pid = data.ioc_u32[4];
592                         printf ("%-20s [%d]%s->%s:%d #%d\n",
593                                 libcfs_id2str(id),
594                                 data.ioc_count, /* persistence */
595                                 /* my ip */
596                                 ptl_ipaddr_2_str(data.ioc_u32[2], buffer[0],
597                                                  sizeof(buffer[0]), 1),
598                                 /* peer ip */
599                                 ptl_ipaddr_2_str(data.ioc_u32[0], buffer[1],
600                                                  sizeof(buffer[1]), 1),
601                                 data.ioc_u32[1], /* peer port */
602                                 data.ioc_u32[3]); /* conn_count */
603                 } else if (g_net_is_compatible(NULL, GNILND, 0)) {
604                         int disconn = data.ioc_flags >> 16;
605                         char *state;
606
607                         if (disconn)
608                                 state = "D";
609                         else
610                                 state = data.ioc_flags & 0xffff ? "C" : "U";
611
612                         printf ("%-20s (%d) %s [%d] "LPU64" "
613                                 "sq %d/%d tx %d/%d/%d\n",
614                                 libcfs_nid2str(data.ioc_nid), /* peer nid */
615                                 data.ioc_net, /* gemini device id */
616                                 state, /* peer is Connecting, Up, or Down */
617                                 data.ioc_count,   /* peer refcount */
618                                 data.ioc_u64[0], /* peerstamp */
619                                 data.ioc_u32[2], data.ioc_u32[3], /* tx and rx seq */
620                                 /* fmaq, nfma, nrdma */
621                                 data.ioc_u32[0], data.ioc_u32[1], data.ioc_u32[4]
622                                 );
623                 } else {
624                         printf ("%-20s [%d]\n",
625                                 libcfs_nid2str(data.ioc_nid), data.ioc_count);
626                 }
627         }
628
629         if (index == 0) {
630                 if (errno == ENOENT) {
631                         printf ("<no peers>\n");
632                 } else {
633                         fprintf(stderr, "Error getting peer list: %s: "
634                                 "check dmesg.\n",
635                                 strerror(errno));
636                 }
637         }
638         return 0;
639 }
640
641 int
642 jt_ptl_add_peer (int argc, char **argv)
643 {
644         struct libcfs_ioctl_data data;
645         lnet_nid_t               nid;
646         __u32                    ip = 0;
647         int                      port = 0;
648         int                      rc;
649
650         if (!g_net_is_compatible(argv[0], SOCKLND, GNILND, 0))
651                 return -1;
652
653         if (argc != 4) {
654                 fprintf (stderr, "usage(tcp,ra,gni): %s nid ipaddr port\n",
655                          argv[0]);
656                 return 0;
657         }
658
659         nid = libcfs_str2nid(argv[1]);
660         if (nid == LNET_NID_ANY) {
661                 fprintf (stderr, "Can't parse NID: %s\n", argv[1]);
662                 return -1;
663         }
664
665         if (lnet_parse_ipaddr (&ip, argv[2]) != 0) {
666                 fprintf (stderr, "Can't parse ip addr: %s\n", argv[2]);
667                 return -1;
668         }
669
670         if (lnet_parse_port (&port, argv[3]) != 0) {
671                 fprintf (stderr, "Can't parse port: %s\n", argv[3]);
672                 return -1;
673         }
674
675         LIBCFS_IOC_INIT(data);
676         data.ioc_net    = g_net;
677         data.ioc_nid    = nid;
678         data.ioc_u32[0] = ip;
679         data.ioc_u32[1] = port;
680
681         rc = l_ioctl (LNET_DEV_ID, IOC_LIBCFS_ADD_PEER, &data);
682         if (rc != 0) {
683                 fprintf (stderr, "failed to add peer: %s\n",
684                          strerror (errno));
685                 return -1;
686         }
687
688         return 0;
689 }
690
691 int
692 jt_ptl_del_peer (int argc, char **argv)
693 {
694         struct libcfs_ioctl_data data;
695         lnet_nid_t               nid = LNET_NID_ANY;
696         lnet_pid_t               pid = LNET_PID_ANY;
697         __u32                    ip = 0;
698         int                      rc;
699
700         if (!g_net_is_compatible(argv[0], SOCKLND, O2IBLND, GNILND, 0))
701                 return -1;
702
703         if (g_net_is_compatible(NULL, SOCKLND, 0)) {
704                 if (argc > 3) {
705                         fprintf (stderr, "usage: %s [nid] [ipaddr]\n",
706                                  argv[0]);
707                         return 0;
708                 }
709         } else if (argc > 2) {
710                 fprintf (stderr, "usage: %s [nid]\n", argv[0]);
711                 return 0;
712         }
713
714         if (argc > 1 &&
715             !libcfs_str2anynid(&nid, argv[1])) {
716                 fprintf (stderr, "Can't parse nid: %s\n", argv[1]);
717                 return -1;
718         }
719
720         if (g_net_is_compatible(NULL, SOCKLND, 0)) {
721                 if (argc > 2 &&
722                     lnet_parse_ipaddr (&ip, argv[2]) != 0) {
723                         fprintf (stderr, "Can't parse ip addr: %s\n",
724                                  argv[2]);
725                         return -1;
726                 }
727         }
728
729         LIBCFS_IOC_INIT(data);
730         data.ioc_net    = g_net;
731         data.ioc_nid    = nid;
732         data.ioc_u32[0] = ip;
733         data.ioc_u32[1] = pid;
734
735         rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_DEL_PEER, &data);
736         if (rc != 0) {
737                 fprintf (stderr, "failed to remove peer: %s\n",
738                          strerror (errno));
739                 return -1;
740         }
741
742         return 0;
743 }
744
745 int
746 jt_ptl_print_connections (int argc, char **argv)
747 {
748         struct libcfs_ioctl_data data;
749         lnet_process_id_t        id;
750         char                     buffer[2][HOST_NAME_MAX + 1];
751         int                      index;
752         int                      rc;
753
754         if (!g_net_is_compatible(argv[0], SOCKLND, O2IBLND, GNILND, 0))
755                 return -1;
756
757         for (index = 0; ; index++) {
758                 LIBCFS_IOC_INIT(data);
759                 data.ioc_net     = g_net;
760                 data.ioc_count   = index;
761
762                 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_CONN, &data);
763                 if (rc != 0)
764                         break;
765
766                 if (g_net_is_compatible (NULL, SOCKLND, 0)) {
767                         id.nid = data.ioc_nid;
768                         id.pid = data.ioc_u32[6];
769                         printf ("%-20s %s[%d]%s->%s:%d %d/%d %s\n",
770                                 libcfs_id2str(id),
771                                 (data.ioc_u32[3] == SOCKLND_CONN_ANY) ? "A" :
772                                 (data.ioc_u32[3] == SOCKLND_CONN_CONTROL) ? "C" :
773                                 (data.ioc_u32[3] == SOCKLND_CONN_BULK_IN) ? "I" :
774                                 (data.ioc_u32[3] == SOCKLND_CONN_BULK_OUT) ? "O" : "?",
775                                 data.ioc_u32[4], /* scheduler */
776                                 /* local IP addr */
777                                 ptl_ipaddr_2_str(data.ioc_u32[2], buffer[0],
778                                                  sizeof(buffer[0]), 1),
779                                 /* remote IP addr */
780                                 ptl_ipaddr_2_str(data.ioc_u32[0], buffer[1],
781                                                  sizeof(buffer[1]), 1),
782                                 data.ioc_u32[1],         /* remote port */
783                                 data.ioc_count, /* tx buffer size */
784                                 data.ioc_u32[5], /* rx buffer size */
785                                 data.ioc_flags ? "nagle" : "nonagle");
786                 } else if (g_net_is_compatible (NULL, O2IBLND, 0)) {
787                         printf ("%s mtu %d\n",
788                                 libcfs_nid2str(data.ioc_nid),
789                                 data.ioc_u32[0]); /* path MTU */
790                 } else if (g_net_is_compatible (NULL, GNILND, 0)) {
791                         printf ("%-20s [%d]\n",
792                                 libcfs_nid2str(data.ioc_nid),
793                                 data.ioc_u32[0] /* device id */);
794                 } else {
795                         printf ("%s\n", libcfs_nid2str(data.ioc_nid));
796                 }
797         }
798
799         if (index == 0) {
800                 if (errno == ENOENT) {
801                         printf ("<no connections>\n");
802                 } else {
803                         fprintf(stderr, "Error getting connection list: %s: "
804                                 "check dmesg.\n",
805                                 strerror(errno));
806                 }
807         }
808         return 0;
809 }
810
811 int jt_ptl_disconnect(int argc, char **argv)
812 {
813         struct libcfs_ioctl_data data;
814         lnet_nid_t               nid = LNET_NID_ANY;
815         __u32                    ipaddr = 0;
816         int                      rc;
817
818         if (argc > 3) {
819                 fprintf(stderr, "usage: %s [nid] [ipaddr]\n", argv[0]);
820                 return 0;
821         }
822
823         if (!g_net_is_compatible(NULL, SOCKLND, O2IBLND, GNILND, 0))
824                 return 0;
825
826         if (argc >= 2 &&
827             !libcfs_str2anynid(&nid, argv[1])) {
828                 fprintf (stderr, "Can't parse nid %s\n", argv[1]);
829                 return -1;
830         }
831
832         if (g_net_is_compatible (NULL, SOCKLND, 0) &&
833             argc >= 3 &&
834             lnet_parse_ipaddr (&ipaddr, argv[2]) != 0) {
835                 fprintf (stderr, "Can't parse ip addr %s\n", argv[2]);
836                 return -1;
837         }
838
839         LIBCFS_IOC_INIT(data);
840         data.ioc_net     = g_net;
841         data.ioc_nid     = nid;
842         data.ioc_u32[0]  = ipaddr;
843
844         rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_CLOSE_CONNECTION, &data);
845         if (rc != 0) {
846                 fprintf(stderr, "failed to remove connection: %s\n",
847                         strerror(errno));
848                 return -1;
849         }
850
851         return 0;
852 }
853
854 int jt_ptl_push_connection (int argc, char **argv)
855 {
856         struct libcfs_ioctl_data data;
857         int                      rc;
858         lnet_nid_t               nid = LNET_NID_ANY;
859
860         if (argc > 2) {
861                 fprintf(stderr, "usage: %s [nid]\n", argv[0]);
862                 return 0;
863         }
864
865         if (!g_net_is_compatible (argv[0], SOCKLND, GNILND, 0))
866                 return -1;
867
868         if (argc > 1 &&
869             !libcfs_str2anynid(&nid, argv[1])) {
870                 fprintf(stderr, "Can't parse nid: %s\n", argv[1]);
871                 return -1;
872         }
873
874         LIBCFS_IOC_INIT(data);
875         data.ioc_net     = g_net;
876         data.ioc_nid     = nid;
877
878         rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_PUSH_CONNECTION, &data);
879         if (rc != 0) {
880                 fprintf(stderr, "failed to push connection: %s\n",
881                         strerror(errno));
882                 return -1;
883         }
884
885         return 0;
886 }
887
888 int jt_ptl_ping(int argc, char **argv)
889 {
890         int                      rc;
891         int                      timeout;
892         lnet_process_id_t        id;
893         lnet_process_id_t        ids[16];
894         int                      maxids = sizeof(ids)/sizeof(ids[0]);
895         struct libcfs_ioctl_data data;
896         char                    *sep;
897         int                      i;
898
899         if (argc < 2) {
900                 fprintf(stderr, "usage: %s id [timeout (secs)]\n", argv[0]);
901                 return 0;
902         }
903
904         sep = strchr(argv[1], '-');
905         if (sep == NULL) {
906                 rc = lnet_parse_nid(argv[1], &id);
907                 if (rc != 0)
908                         return -1;
909         } else {
910                 char   *end;
911
912                 if (argv[1][0] == 'u' ||
913                     argv[1][0] == 'U')
914                         id.pid = strtoul(&argv[1][1], &end, 0) | LNET_PID_USERFLAG;
915                 else
916                         id.pid = strtoul(argv[1], &end, 0);
917
918                 if (end != sep) { /* assuming '-' is part of hostname */
919                         rc = lnet_parse_nid(argv[1], &id);
920                         if (rc != 0)
921                                 return -1;
922                 } else {
923                         id.nid = libcfs_str2nid(sep + 1);
924
925                         if (id.nid == LNET_NID_ANY) {
926                                 fprintf(stderr,
927                                         "Can't parse process id \"%s\"\n",
928                                         argv[1]);
929                                 return -1;
930                         }
931                 }
932         }
933
934         if (argc > 2)
935                 timeout = 1000 * atol(argv[2]);
936         else
937                 timeout = 1000;                 /* default 1 second timeout */
938
939         LIBCFS_IOC_INIT (data);
940         data.ioc_nid     = id.nid;
941         data.ioc_u32[0]  = id.pid;
942         data.ioc_u32[1]  = timeout;
943         data.ioc_plen1   = sizeof(ids);
944         data.ioc_pbuf1   = (char *)ids;
945
946         rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_PING, &data);
947         if (rc != 0) {
948                 fprintf(stderr, "failed to ping %s: %s\n",
949                         id.pid == LNET_PID_ANY ?
950                         libcfs_nid2str(id.nid) : libcfs_id2str(id),
951                         strerror(errno));
952                 return -1;
953         }
954
955         for (i = 0; i < data.ioc_count && i < maxids; i++)
956                 printf("%s\n", libcfs_id2str(ids[i]));
957
958         if (data.ioc_count > maxids)
959                 printf("%d out of %d ids listed\n", maxids, data.ioc_count);
960
961         return 0;
962 }
963
964 int jt_ptl_mynid(int argc, char **argv)
965 {
966         struct libcfs_ioctl_data data;
967         lnet_nid_t               nid;
968         int rc;
969
970         if (argc != 2) {
971                 fprintf(stderr, "usage: %s NID\n", argv[0]);
972                 return 0;
973         }
974
975         nid = libcfs_str2nid(argv[1]);
976         if (nid == LNET_NID_ANY) {
977                 fprintf(stderr, "Can't parse NID '%s'\n", argv[1]);
978                 return -1;
979         }
980
981         LIBCFS_IOC_INIT(data);
982         data.ioc_net = LNET_NIDNET(nid);
983         data.ioc_nid = nid;
984
985         rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_REGISTER_MYNID, &data);
986         if (rc < 0)
987                 fprintf(stderr, "setting my NID failed: %s\n",
988                        strerror(errno));
989         else
990                 printf("registered my nid %s\n", libcfs_nid2str(nid));
991
992         return 0;
993 }
994
995 int
996 jt_ptl_fail_nid (int argc, char **argv)
997 {
998         int                      rc;
999         lnet_nid_t               nid;
1000         int                      threshold;
1001         struct libcfs_ioctl_data data;
1002
1003         if (argc < 2 || argc > 3)
1004         {
1005                 fprintf (stderr, "usage: %s nid|\"*\" [count (0 == mend)]\n", argv[0]);
1006                 return (0);
1007         }
1008
1009         if (!libcfs_str2anynid(&nid, argv[1]))
1010         {
1011                 fprintf (stderr, "Can't parse nid \"%s\"\n", argv[1]);
1012                 return (-1);
1013         }
1014
1015         if (argc < 3) {
1016                 threshold = LNET_MD_THRESH_INF;
1017         } else if (sscanf(argv[2], "%i", &threshold) != 1) {
1018                 fprintf (stderr, "Can't parse count \"%s\"\n", argv[2]);
1019                 return (-1);
1020         }
1021
1022         LIBCFS_IOC_INIT (data);
1023         data.ioc_nid = nid;
1024         data.ioc_count = threshold;
1025
1026         rc = l_ioctl (LNET_DEV_ID, IOC_LIBCFS_FAIL_NID, &data);
1027         if (rc < 0)
1028                 fprintf (stderr, "IOC_LIBCFS_FAIL_NID failed: %s\n",
1029                          strerror (errno));
1030         else
1031                 printf ("%s %s\n", threshold == 0 ? "Unfailing" : "Failing", argv[1]);
1032
1033         return (0);
1034 }
1035
1036 int
1037 jt_ptl_add_route (int argc, char **argv)
1038 {
1039         struct lnet_ioctl_config_data data;
1040         lnet_nid_t               gateway_nid;
1041         unsigned int             hops = 1;
1042         unsigned int             priority = 0;
1043         char                    *end;
1044         int                      rc;
1045
1046         if (argc < 2 || argc > 4) {
1047                 fprintf(stderr, "usage: %s gateway [hopcount [priority]]\n",
1048                         argv[0]);
1049                 return -1;
1050         }
1051
1052         if (g_net_is_set(argv[0]) == 0)
1053                 return -1;
1054
1055         gateway_nid = libcfs_str2nid(argv[1]);
1056         if (gateway_nid == LNET_NID_ANY) {
1057                 fprintf(stderr, "Can't parse gateway NID \"%s\"\n", argv[1]);
1058                 return -1;
1059         }
1060
1061         if (argc > 2) {
1062                 hops = strtoul(argv[2], &end, 0);
1063                 if (hops == 0 || hops >= 256 || (end != NULL && *end != 0)) {
1064                         fprintf(stderr, "Can't parse hopcount \"%s\"\n",
1065                                 argv[2]);
1066                         return -1;
1067                 }
1068                 if (argc == 4) {
1069                         priority = strtoul(argv[3], &end, 0);
1070                         if (end != NULL && *end != 0) {
1071                                 fprintf(stderr,
1072                                         "Can't parse priority \"%s\"\n",
1073                                         argv[3]);
1074                                 return -1;
1075                         }
1076                 }
1077         }
1078
1079         LIBCFS_IOC_INIT_V2(data, cfg_hdr);
1080         data.cfg_net = g_net;
1081         data.cfg_config_u.cfg_route.rtr_hop = hops;
1082         data.cfg_nid = gateway_nid;
1083         data.cfg_config_u.cfg_route.rtr_priority = priority;
1084
1085         rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_ADD_ROUTE, &data);
1086         if (rc != 0) {
1087                 fprintf(stderr, "IOC_LIBCFS_ADD_ROUTE failed: %s\n",
1088                         strerror(errno));
1089                 return -1;
1090         }
1091
1092         return 0;
1093 }
1094
1095 int
1096 jt_ptl_del_route (int argc, char **argv)
1097 {
1098         struct lnet_ioctl_config_data data;
1099         lnet_nid_t               nid;
1100         int                      rc;
1101
1102         if (argc != 2) {
1103                 fprintf(stderr, "usage: %s gatewayNID\n", argv[0]);
1104                 return 0;
1105         }
1106
1107         if (libcfs_str2anynid(&nid, argv[1]) == 0) {
1108                 fprintf(stderr, "Can't parse gateway NID "
1109                         "\"%s\"\n", argv[1]);
1110                 return -1;
1111         }
1112
1113         LIBCFS_IOC_INIT_V2(data, cfg_hdr);
1114         data.cfg_net = g_net_set ? g_net : LNET_NIDNET(LNET_NID_ANY);
1115         data.cfg_nid = nid;
1116
1117         rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_DEL_ROUTE, &data);
1118         if (rc != 0) {
1119                 fprintf(stderr, "IOC_LIBCFS_DEL_ROUTE (%s) failed: %s\n",
1120                         libcfs_nid2str(nid), strerror(errno));
1121                 return -1;
1122         }
1123
1124         return 0;
1125 }
1126
1127 int
1128 jt_ptl_notify_router (int argc, char **argv)
1129 {
1130         struct libcfs_ioctl_data data;
1131         int                      enable;
1132         lnet_nid_t               nid;
1133         int                      rc;
1134         struct timeval           now;
1135         time_t                   when;
1136
1137         if (argc < 3)
1138         {
1139                 fprintf (stderr, "usage: %s targetNID <up/down> [<time>]\n", 
1140                          argv[0]);
1141                 return (0);
1142         }
1143
1144         nid = libcfs_str2nid(argv[1]);
1145         if (nid == LNET_NID_ANY) {
1146                 fprintf (stderr, "Can't parse target NID \"%s\"\n", argv[1]);
1147                 return (-1);
1148         }
1149
1150         if (lnet_parse_bool (&enable, argv[2]) != 0) {
1151                 fprintf (stderr, "Can't parse boolean %s\n", argv[2]);
1152                 return (-1);
1153         }
1154
1155         gettimeofday(&now, NULL);
1156
1157         if (argc < 4) {
1158                 when = now.tv_sec;
1159         } else if (lnet_parse_time (&when, argv[3]) != 0) {
1160                 fprintf(stderr, "Can't parse time %s\n"
1161                         "Please specify either 'YYYY-MM-DD-HH:MM:SS'\n"
1162                         "or an absolute unix time in seconds\n", argv[3]);
1163                 return (-1);
1164         } else if (when > now.tv_sec) {
1165                 fprintf (stderr, "%s specifies a time in the future\n",
1166                          argv[3]);
1167                 return (-1);
1168         }
1169
1170         LIBCFS_IOC_INIT(data);
1171         data.ioc_nid = nid;
1172         data.ioc_flags = enable;
1173         /* Yeuch; 'cept I need a __u64 on 64 bit machines... */
1174         data.ioc_u64[0] = (__u64)when;
1175
1176         rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_NOTIFY_ROUTER, &data);
1177         if (rc != 0) {
1178                 fprintf (stderr, "IOC_LIBCFS_NOTIFY_ROUTER (%s) failed: %s\n",
1179                          libcfs_nid2str(nid), strerror (errno));
1180                 return (-1);
1181         }
1182
1183         return (0);
1184 }
1185
1186 int
1187 jt_ptl_print_routes (int argc, char **argv)
1188 {
1189         struct lnet_ioctl_config_data  data;
1190         int                       rc;
1191         int                       index;
1192         __u32                     net;
1193         lnet_nid_t                nid;
1194         unsigned int              hops;
1195         int                       alive;
1196         unsigned int              pri;
1197
1198         for (index = 0; ; index++) {
1199                 LIBCFS_IOC_INIT_V2(data, cfg_hdr);
1200                 data.cfg_count = index;
1201
1202                 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_ROUTE, &data);
1203                 if (rc != 0)
1204                         break;
1205
1206                 net     = data.cfg_net;
1207                 hops    = data.cfg_config_u.cfg_route.rtr_hop;
1208                 nid     = data.cfg_nid;
1209                 alive   = data.cfg_config_u.cfg_route.rtr_flags;
1210                 pri     = data.cfg_config_u.cfg_route.rtr_priority;
1211
1212                 printf("net %18s hops %u gw %32s %s pri %u\n",
1213                        libcfs_net2str(net), hops,
1214                        libcfs_nid2str(nid), alive ? "up" : "down", pri);
1215         }
1216
1217         if (errno != ENOENT)
1218                 fprintf(stderr, "Error getting routes: %s: check dmesg.\n",
1219                         strerror(errno));
1220
1221         return 0;
1222 }
1223
1224 static int
1225 fault_attr_nid_parse(char *str, lnet_nid_t *nid_p)
1226 {
1227         lnet_nid_t nid;
1228         __u32      net;
1229         int        rc = 0;
1230
1231         /* NB: can't support range ipaddress except * and *@net */
1232         if (strlen(str) > 2 && str[0] == '*' && str[1] == '@') {
1233                 net = libcfs_str2net(str + 2);
1234                 if (net == LNET_NIDNET(LNET_NID_ANY))
1235                         goto failed;
1236
1237                 nid = LNET_MKNID(net, LNET_NIDADDR(LNET_NID_ANY));
1238         } else {
1239                 rc = libcfs_str2anynid(&nid, str);
1240                 if (!rc)
1241                         goto failed;
1242         }
1243
1244         *nid_p = nid;
1245         return 0;
1246 failed:
1247         fprintf(stderr, "Invalid NID : %s\n", str);
1248         return -1;
1249 }
1250
1251 static int
1252 fault_attr_msg_parse(char *msg_str, __u32 *mask_p)
1253 {
1254         if (!strcasecmp(msg_str, "put")) {
1255                 *mask_p |= LNET_PUT_BIT;
1256                 return 0;
1257
1258         } else if (!strcasecmp(msg_str, "ack")) {
1259                 *mask_p |= LNET_ACK_BIT;
1260                 return 0;
1261
1262         } else if (!strcasecmp(msg_str, "get")) {
1263                 *mask_p |= LNET_GET_BIT;
1264                 return 0;
1265
1266         } else if (!strcasecmp(msg_str, "reply")) {
1267                 *mask_p |= LNET_REPLY_BIT;
1268                 return 0;
1269         }
1270
1271         fprintf(stderr, "unknown message type %s\n", msg_str);
1272         return -1;
1273 }
1274
1275 static int
1276 fault_attr_ptl_parse(char *ptl_str, __u64 *mask_p)
1277 {
1278         unsigned long rc = strtoul(optarg, NULL, 0);
1279
1280         if (rc >= 64) {
1281                 fprintf(stderr, "invalid portal: %lu\n", rc);
1282                 return -1;
1283         }
1284
1285         *mask_p |= (1ULL << rc);
1286         return 0;
1287 }
1288
1289 static int
1290 fault_simul_rule_add(__u32 opc, char *name, int argc, char **argv)
1291 {
1292         struct libcfs_ioctl_data  data = {{0}};
1293         struct lnet_fault_attr    attr;
1294         char                     *optstr;
1295         int                       rc;
1296
1297         static struct option opts[] = {
1298                 {"source",      required_argument,      0,      's'},
1299                 {"dest",        required_argument,      0,      'd'},
1300                 {"rate",        required_argument,      0,      'r'},
1301                 {"interval",    required_argument,      0,      'i'},
1302                 {"latency",     required_argument,      0,      'l'},
1303                 {"portal",      required_argument,      0,      'p'},
1304                 {"message",     required_argument,      0,      'm'},
1305                 {0, 0, 0, 0}
1306         };
1307
1308         if (argc == 1) {
1309                 fprintf(stderr, "Failed, please provide source, destination "
1310                                 "and rate of rule\n");
1311                 return -1;
1312         }
1313
1314         optstr = opc == LNET_CTL_DROP_ADD ? "s:d:r:i:p:m:" : "s:d:r:l:p:m:";
1315         memset(&attr, 0, sizeof(attr));
1316         while (1) {
1317                 char c = getopt_long(argc, argv, optstr, opts, NULL);
1318
1319                 if (c == -1)
1320                         break;
1321
1322                 switch (c) {
1323                 case 's': /* source NID/NET */
1324                         rc = fault_attr_nid_parse(optarg, &attr.fa_src);
1325                         if (rc != 0)
1326                                 goto getopt_failed;
1327                         break;
1328
1329                 case 'd': /* dest NID/NET */
1330                         rc = fault_attr_nid_parse(optarg, &attr.fa_dst);
1331                         if (rc != 0)
1332                                 goto getopt_failed;
1333                         break;
1334
1335                 case 'r': /* drop rate */
1336                         if (opc == LNET_CTL_DROP_ADD)
1337                                 attr.u.drop.da_rate = strtoul(optarg, NULL, 0);
1338                         else
1339                                 attr.u.delay.la_rate = strtoul(optarg, NULL, 0);
1340                         break;
1341
1342                 case 'i': /* time interval (# seconds) for message drop */
1343                         if (opc == LNET_CTL_DROP_ADD)
1344                                 attr.u.drop.da_interval = strtoul(optarg,
1345                                                                   NULL, 0);
1346                         else
1347                                 attr.u.delay.la_interval = strtoul(optarg,
1348                                                                    NULL, 0);
1349                         break;
1350
1351                 case 'l': /* seconds to wait before activating rule */
1352                         attr.u.delay.la_latency = strtoul(optarg, NULL, 0);
1353                         break;
1354
1355                 case 'p': /* portal to filter */
1356                         rc = fault_attr_ptl_parse(optarg, &attr.fa_ptl_mask);
1357                         if (rc != 0)
1358                                 goto getopt_failed;
1359                         break;
1360
1361                 case 'm': /* message types to filter */
1362                         rc = fault_attr_msg_parse(optarg, &attr.fa_msg_mask);
1363                         if (rc != 0)
1364                                 goto getopt_failed;
1365                         break;
1366
1367                 default:
1368                         fprintf(stderr, "error: %s: option '%s' "
1369                                 "unrecognized\n", argv[0], argv[optind - 1]);
1370                         goto getopt_failed;
1371                 }
1372         }
1373         optind = 1;
1374
1375         if (opc == LNET_CTL_DROP_ADD) {
1376                 /* NB: drop rate and interval are exclusive to each other */
1377                 if (!((attr.u.drop.da_rate == 0) ^
1378                       (attr.u.drop.da_interval == 0))) {
1379                         fprintf(stderr,
1380                                 "please provide either drop rate or interval "
1381                                 "but not both at the same time.\n");
1382                         return -1;
1383                 }
1384         } else if (opc == LNET_CTL_DELAY_ADD) {
1385                 if (!((attr.u.delay.la_rate == 0) ^
1386                       (attr.u.delay.la_interval == 0))) {
1387                         fprintf(stderr,
1388                                 "please provide either delay rate or interval "
1389                                 "but not both at the same time.\n");
1390                         return -1;
1391                 }
1392
1393                 if (attr.u.delay.la_latency == 0) {
1394                         fprintf(stderr, "latency cannot be zero\n");
1395                         return -1;
1396                 }
1397         }
1398
1399         if (attr.fa_src == 0 || attr.fa_dst == 0) {
1400                 fprintf(stderr, "Please provide both source and destination "
1401                                 "of %s rule\n", name);
1402                 return -1;
1403         }
1404
1405         data.ioc_flags = opc;
1406         data.ioc_inllen1 = sizeof(attr);
1407         data.ioc_inlbuf1 = (char *)&attr;
1408         if (libcfs_ioctl_pack(&data, &ioc_buf, IOC_BUF_SIZE) != 0) {
1409                 fprintf(stderr, "libcfs_ioctl_pack failed\n");
1410                 return -1;
1411         }
1412
1413         rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_LNET_FAULT, ioc_buf);
1414         if (rc != 0) {
1415                 fprintf(stderr, "add %s rule %s->%s failed: %s\n",
1416                         name, libcfs_nid2str(attr.fa_src),
1417                         libcfs_nid2str(attr.fa_dst), strerror(errno));
1418                 return -1;
1419         }
1420
1421         printf("Added %s rule %s->%s (1/%d)\n",
1422                name, libcfs_nid2str(attr.fa_src), libcfs_nid2str(attr.fa_dst),
1423                opc == LNET_CTL_DROP_ADD ?
1424                attr.u.drop.da_rate : attr.u.delay.la_rate);
1425         return 0;
1426
1427 getopt_failed:
1428         optind = 1;
1429         return -1;
1430 }
1431
1432 int
1433 jt_ptl_drop_add(int argc, char **argv)
1434 {
1435         return fault_simul_rule_add(LNET_CTL_DROP_ADD, "drop", argc, argv);
1436 }
1437
1438 int
1439 jt_ptl_delay_add(int argc, char **argv)
1440 {
1441         return fault_simul_rule_add(LNET_CTL_DELAY_ADD, "delay", argc, argv);
1442 }
1443
1444 static int
1445 fault_simul_rule_del(__u32 opc, char *name, int argc, char **argv)
1446 {
1447         struct libcfs_ioctl_data data = {{0}};
1448         struct lnet_fault_attr   attr;
1449         bool                     all = false;
1450         int                      rc;
1451
1452         static struct option opts[] = {
1453                 {"source",      required_argument,      0,      's'},
1454                 {"dest",        required_argument,      0,      'd'},
1455                 {"all",         no_argument,            0,      'a'},
1456                 {0, 0, 0, 0}
1457         };
1458
1459         if (argc == 1) {
1460                 fprintf(stderr, "Failed, please provide source and "
1461                                 "destination of rule\n");
1462                 return -1;
1463         }
1464
1465         memset(&attr, 0, sizeof(attr));
1466         while (1) {
1467                 char c = getopt_long(argc, argv, "s:d:a", opts, NULL);
1468
1469                 if (c == -1 || all)
1470                         break;
1471
1472                 switch (c) {
1473                 case 's':
1474                         rc = fault_attr_nid_parse(optarg, &attr.fa_src);
1475                         if (rc != 0)
1476                                 goto getopt_failed;
1477                         break;
1478                 case 'd':
1479                         rc = fault_attr_nid_parse(optarg, &attr.fa_dst);
1480                         if (rc != 0)
1481                                 goto getopt_failed;
1482                         break;
1483                 case 'a':
1484                         attr.fa_src = attr.fa_dst = 0;
1485                         all = true;
1486                         break;
1487                 default:
1488                         fprintf(stderr, "error: %s: option '%s' "
1489                                 "unrecognized\n", argv[0], argv[optind - 1]);
1490                         goto getopt_failed;
1491                 }
1492         }
1493         optind = 1;
1494
1495         data.ioc_flags = opc;
1496         data.ioc_inllen1 = sizeof(attr);
1497         data.ioc_inlbuf1 = (char *)&attr;
1498         if (libcfs_ioctl_pack(&data, &ioc_buf, IOC_BUF_SIZE) != 0) {
1499                 fprintf(stderr, "libcfs_ioctl_pack failed\n");
1500                 return -1;
1501         }
1502
1503         rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_LNET_FAULT, ioc_buf);
1504         if (rc != 0) {
1505                 fprintf(stderr, "remove %s rule %s->%s failed: %s\n", name,
1506                         all ? "all" : libcfs_nid2str(attr.fa_src),
1507                         all ? "all" : libcfs_nid2str(attr.fa_dst),
1508                         strerror(errno));
1509                 return -1;
1510         }
1511
1512         libcfs_ioctl_unpack(&data, ioc_buf);
1513         printf("Removed %d %s rules\n", data.ioc_count, name);
1514         return 0;
1515
1516 getopt_failed:
1517         optind = 1;
1518         return -1;
1519 }
1520
1521 int
1522 jt_ptl_drop_del(int argc, char **argv)
1523 {
1524         return fault_simul_rule_del(LNET_CTL_DROP_DEL, "drop", argc, argv);
1525 }
1526
1527 int
1528 jt_ptl_delay_del(int argc, char **argv)
1529 {
1530         return fault_simul_rule_del(LNET_CTL_DELAY_DEL, "delay", argc, argv);
1531 }
1532
1533 static int
1534 fault_simul_rule_reset(__u32 opc, char *name, int argc, char **argv)
1535 {
1536         struct libcfs_ioctl_data   data = {{0}};
1537         int                        rc;
1538
1539         LIBCFS_IOC_INIT(data);
1540         data.ioc_flags = opc;
1541
1542         rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_LNET_FAULT, &data);
1543         if (rc != 0) {
1544                 fprintf(stderr, "failed to reset %s stats: %s\n",
1545                         name, strerror(errno));
1546                 return -1;
1547         }
1548         return 0;
1549 }
1550
1551 int
1552 jt_ptl_drop_reset(int argc, char **argv)
1553 {
1554         return fault_simul_rule_reset(LNET_CTL_DROP_RESET, "drop", argc, argv);
1555 }
1556
1557 int
1558 jt_ptl_delay_reset(int argc, char **argv)
1559 {
1560         return fault_simul_rule_reset(LNET_CTL_DELAY_RESET, "delay",
1561                                       argc, argv);
1562 }
1563
1564 static int
1565 fault_simul_rule_list(__u32 opc, char *name, int argc, char **argv)
1566 {
1567         struct libcfs_ioctl_data data = {{0}};
1568         struct lnet_fault_attr   attr;
1569         struct lnet_fault_stat   stat;
1570         int                      pos;
1571
1572         printf("LNet %s rules:\n", name);
1573         for (pos = 0;; pos++) {
1574                 int             rc;
1575
1576                 memset(&attr, 0, sizeof(attr));
1577                 memset(&stat, 0, sizeof(stat));
1578
1579                 data.ioc_count = pos;
1580                 data.ioc_flags = opc;
1581                 data.ioc_inllen1 = sizeof(attr);
1582                 data.ioc_inlbuf1 = (char *)&attr;
1583                 data.ioc_inllen2 = sizeof(stat);
1584                 data.ioc_inlbuf2 = (char *)&stat;
1585                 if (libcfs_ioctl_pack(&data, &ioc_buf, IOC_BUF_SIZE) != 0) {
1586                         fprintf(stderr, "libcfs_ioctl_pack failed\n");
1587                         return -1;
1588                 }
1589
1590                 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_LNET_FAULT, ioc_buf);
1591                 if (rc != 0)
1592                         break;
1593
1594                 libcfs_ioctl_unpack(&data, ioc_buf);
1595
1596                 if (opc == LNET_CTL_DROP_LIST) {
1597                         printf("%s->%s (1/%d | %d) ptl "LPX64", msg %x, "
1598                                LPU64"/"LPU64", PUT "LPU64", ACK "LPU64", GET "
1599                                LPU64", REP "LPU64"\n",
1600                                libcfs_nid2str(attr.fa_src),
1601                                libcfs_nid2str(attr.fa_dst),
1602                                attr.u.drop.da_rate, attr.u.drop.da_interval,
1603                                attr.fa_ptl_mask, attr.fa_msg_mask,
1604                                stat.u.drop.ds_dropped, stat.fs_count,
1605                                stat.fs_put, stat.fs_ack,
1606                                stat.fs_get, stat.fs_reply);
1607
1608                 } else if (opc == LNET_CTL_DELAY_LIST) {
1609                         printf("%s->%s (1/%d | %d, latency %d) ptl "LPX64
1610                                ", msg %x, "LPU64"/"LPU64", PUT "LPU64
1611                                ", ACK "LPU64", GET "LPU64", REP "LPU64"\n",
1612                                libcfs_nid2str(attr.fa_src),
1613                                libcfs_nid2str(attr.fa_dst),
1614                                attr.u.delay.la_rate, attr.u.delay.la_interval,
1615                                attr.u.delay.la_latency,
1616                                attr.fa_ptl_mask, attr.fa_msg_mask,
1617                                stat.u.delay.ls_delayed, stat.fs_count,
1618                                stat.fs_put, stat.fs_ack, stat.fs_get,
1619                                stat.fs_reply);
1620                 }
1621         }
1622         printf("found total %d\n", pos);
1623
1624         return 0;
1625 }
1626
1627 int
1628 jt_ptl_drop_list(int argc, char **argv)
1629 {
1630         return fault_simul_rule_list(LNET_CTL_DROP_LIST, "drop", argc, argv);
1631 }
1632
1633 int
1634 jt_ptl_delay_list(int argc, char **argv)
1635 {
1636         return fault_simul_rule_list(LNET_CTL_DELAY_LIST, "delay", argc, argv);
1637 }
1638
1639 double
1640 get_cycles_per_usec ()
1641 {
1642         FILE      *f = fopen ("/proc/cpuinfo", "r");
1643         double     mhz;
1644         char      line[64];
1645
1646         if (f != NULL) {
1647                 while (fgets (line, sizeof (line), f) != NULL)
1648                         if (sscanf (line, "cpu MHz : %lf", &mhz) == 1) {
1649                                 fclose (f);
1650                                 return (mhz);
1651                         }
1652                 fclose (f);
1653         }
1654
1655         fprintf (stderr, "Can't read/parse /proc/cpuinfo\n");
1656         return (1000.0);
1657 }
1658
1659 int jt_ptl_memhog(int argc, char **argv)
1660 {
1661         static int                gfp = 0;        /* sticky! */
1662
1663         struct libcfs_ioctl_data  data;
1664         int                       rc;
1665         int                       count;
1666         char                     *end;
1667
1668         if (argc < 2)  {
1669                 fprintf(stderr, "usage: %s <npages> [<GFP flags>]\n", argv[0]);
1670                 return 0;
1671         }
1672
1673         count = strtol(argv[1], &end, 0);
1674         if (count < 0 || *end != 0) {
1675                 fprintf(stderr, "Can't parse page count '%s'\n", argv[1]);
1676                 return -1;
1677         }
1678
1679         if (argc >= 3) {
1680                 rc = strtol(argv[2], &end, 0);
1681                 if (*end != 0) {
1682                         fprintf(stderr, "Can't parse gfp flags '%s'\n", argv[2]);
1683                         return -1;
1684                 }
1685                 gfp = rc;
1686         }
1687
1688         LIBCFS_IOC_INIT(data);
1689         data.ioc_count = count;
1690         data.ioc_flags = gfp;
1691         rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_MEMHOG, &data);
1692
1693         if (rc != 0) {
1694                 fprintf(stderr, "memhog %d failed: %s\n", count, strerror(errno));
1695                 return -1;
1696         }
1697
1698         printf("memhog %d OK\n", count);
1699         return 0;
1700 }
1701
1702 int jt_ptl_testprotocompat(int argc, char **argv)
1703 {
1704         struct libcfs_ioctl_data  data;
1705         int                       rc;
1706         int                       flags;
1707         char                     *end;
1708
1709         if (argc < 2)  {
1710                 fprintf(stderr, "usage: %s <number>\n", argv[0]);
1711                 return 0;
1712         }
1713
1714         flags = strtol(argv[1], &end, 0);
1715         if (flags < 0 || *end != 0) {
1716                 fprintf(stderr, "Can't parse flags '%s'\n", argv[1]);
1717                 return -1;
1718         }
1719
1720         LIBCFS_IOC_INIT(data);
1721         data.ioc_flags = flags;
1722         rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_TESTPROTOCOMPAT, &data);
1723
1724         if (rc != 0) {
1725                 fprintf(stderr, "test proto compat %x failed: %s\n",
1726                         flags, strerror(errno));
1727                 return -1;
1728         }
1729
1730         printf("test proto compat %x OK\n", flags);
1731         return 0;
1732 }
1733
1734