Whamcloud - gitweb
eb189b2e49458ad32a8f63a0788cea3db710e0db
[fs/lustre-release.git] / lnet / utils / lnetctl.c
1 /*
2  * LGPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as
8  * published by the Free Software Foundation; either version 2.1 of the
9  * License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
18  *
19  * LGPL HEADER END
20  *
21  * Copyright (c) 2013, Intel Corporation.
22  *
23  * Author:
24  *   Amir Shehata <amir.shehata@intel.com>
25  */
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <lnet/lnetctl.h>
30 #include <libcfs/libcfsutil.h>
31 #include "cyaml/cyaml.h"
32 #include "lnetconfig/liblnetconfig.h"
33
34 #define LNET_CONFIGURE          true
35 #define LNET_UNCONFIGURE        false
36
37 static int jt_config_lnet(int argc, char **argv);
38 static int jt_unconfig_lnet(int argc, char **argv);
39 static int jt_add_route(int argc, char **argv);
40 static int jt_add_net(int argc, char **argv);
41 static int jt_set_routing(int argc, char **argv);
42 static int jt_del_route(int argc, char **argv);
43 static int jt_del_net(int argc, char **argv);
44 static int jt_show_route(int argc, char **argv);
45 static int jt_show_net(int argc, char **argv);
46 static int jt_show_routing(int argc, char **argv);
47 static int jt_show_stats(int argc, char **argv);
48 static int jt_show_peer_credits(int argc, char **argv);
49 static int jt_set_tiny(int argc, char **argv);
50 static int jt_set_small(int argc, char **argv);
51 static int jt_set_large(int argc, char **argv);
52
53 command_t lnet_cmds[] = {
54         {"configure", jt_config_lnet, 0, "configure lnet\n"
55          "\t--all: load NI configuration from module parameters\n"},
56         {"unconfigure", jt_unconfig_lnet, 0, "unconfigure lnet\n"},
57         { 0, 0, 0, NULL }
58 };
59
60 command_t route_cmds[] = {
61         {"add", jt_add_route, 0, "add a route\n"
62          "\t--net: net name (e.g. tcp0)\n"
63          "\t--gateway: gateway nid (e.g. 10.1.1.2@tcp)\n"
64          "\t--hop: number to final destination (1 < hops < 255)\n"
65          "\t--priority: priority of route (0 - highest prio\n"},
66         {"del", jt_del_route, 0, "delete a route\n"
67          "\t--net: net name (e.g. tcp0)\n"
68          "\t--gateway: gateway nid (e.g. 10.1.1.2@tcp)\n"},
69         {"show", jt_show_route, 0, "show routes\n"
70          "\t--net: net name (e.g. tcp0) to filter on\n"
71          "\t--gateway: gateway nid (e.g. 10.1.1.2@tcp) to filter on\n"
72          "\t--hop: number to final destination (1 < hops < 255) to filter on\n"
73          "\t--priority: priority of route (0 - highest prio to filter on\n"
74          "\t--vebose: display detailed output per route\n"},
75         { 0, 0, 0, NULL }
76 };
77
78 command_t net_cmds[] = {
79         {"add", jt_add_net, 0, "add a network\n"
80          "\t--net: net name (e.g. tcp0)\n"
81          "\t--if: physical interface (e.g. eth0)\n"
82          "\t--ip2net: specify networks based on IP address patterns\n"
83          "\t--peer-timeout: time to wait before declaring a peer dead\n"
84          "\t--peer-credits: define the max number of inflight messages\n"
85          "\t--peer-buffer-credits: the number of buffer credits per peer\n"
86          "\t--credits: Network Interface credits\n"
87          "\t--cpt: CPU Partitions configured net uses (e.g. [0,1]\n"},
88         {"del", jt_del_net, 0, "delete a network\n"
89          "\t--net: net name (e.g. tcp0)\n"},
90         {"show", jt_show_net, 0, "show networks\n"
91          "\t--net: net name (e.g. tcp0) to filter on\n"
92          "\t--verbose: display detailed output per network\n"},
93         { 0, 0, 0, NULL }
94 };
95
96 command_t routing_cmds[] = {
97         {"show", jt_show_routing, 0, "show routing information\n"},
98         { 0, 0, 0, NULL }
99 };
100
101 command_t stats_cmds[] = {
102         {"show", jt_show_stats, 0, "show LNET statistics\n"},
103         { 0, 0, 0, NULL }
104 };
105
106 command_t credits_cmds[] = {
107         {"show", jt_show_peer_credits, 0, "show peer credits\n"},
108         { 0, 0, 0, NULL }
109 };
110
111 command_t set_cmds[] = {
112         {"tiny_buffers", jt_set_tiny, 0, "set tiny routing buffers\n"
113          "\tVALUE must be greater than 0\n"},
114         {"small_buffers", jt_set_small, 0, "set small routing buffers\n"
115          "\tVALUE must be greater than 0\n"},
116         {"large_buffers", jt_set_large, 0, "set large routing buffers\n"
117          "\tVALUE must be greater than 0\n"},
118         {"routing", jt_set_routing, 0, "enable/disable routing\n"
119          "\t0 - disable routing\n"
120          "\t1 - enable routing\n"},
121         { 0, 0, 0, NULL }
122 };
123
124 static inline void print_help(const command_t cmds[], const char *cmd_type,
125                               const char *pc_name)
126 {
127         const command_t *cmd;
128
129         for (cmd = cmds; cmd->pc_name; cmd++) {
130                 if (pc_name != NULL &&
131                     strcmp(cmd->pc_name, pc_name) == 0) {
132                         printf("%s %s: %s\n", cmd_type, cmd->pc_name,
133                                cmd->pc_help);
134                         return;
135                 } else if (pc_name != NULL) {
136                         continue;
137                 }
138                 printf("%s %s: %s\n", cmd_type, cmd->pc_name, cmd->pc_help);
139         }
140 }
141
142 static int parse_long(const char *number, long int *value)
143 {
144         char *end;
145
146         *value = strtol(number,  &end, 0);
147         if (end != NULL && *end != 0)
148                 return -1;
149
150         return 0;
151 }
152
153 static int handle_help(const command_t *cmd_list, const char *cmd,
154                        const char *sub_cmd, int argc, char **argv)
155 {
156         int opt;
157         int rc = -1;
158         optind = 0;
159         opterr = 0;
160
161         const char *const short_options = "h";
162         const struct option long_options[] = {
163                 { "help", 0, NULL, 'h' },
164                 { NULL, 0, NULL, 0 },
165         };
166
167         while ((opt = getopt_long(argc, argv, short_options,
168                                   long_options, NULL)) != -1) {
169                 switch (opt) {
170                 case 'h':
171                         print_help(cmd_list, cmd, sub_cmd);
172                         rc = 0;
173                         break;
174                 default:
175                         rc = -1;
176                         break;
177                 }
178         }
179
180         opterr = 1;
181         optind = 0;
182         return rc;
183 }
184
185 static int jt_set_tiny(int argc, char **argv)
186 {
187         long int value;
188         int rc;
189         struct cYAML *err_rc = NULL;
190
191         if (handle_help(set_cmds, "set", "tiny_buffers", argc, argv) == 0)
192                 return 0;
193
194         rc = parse_long(argv[1], &value);
195         if (rc != 0) {
196                 cYAML_build_error(-1, -1, "parser", "set",
197                                   "cannot parse tiny_buffers value", &err_rc);
198                 cYAML_print_tree2file(stderr, err_rc);
199                 cYAML_free_tree(err_rc);
200                 return -1;
201         }
202
203         rc = lustre_lnet_config_buffers(value, -1, -1, -1, &err_rc);
204         if (rc != LUSTRE_CFG_RC_NO_ERR)
205                 cYAML_print_tree2file(stderr, err_rc);
206
207         cYAML_free_tree(err_rc);
208
209         return rc;
210 }
211
212 static int jt_set_small(int argc, char **argv)
213 {
214         long int value;
215         int rc;
216         struct cYAML *err_rc = NULL;
217
218         if (handle_help(set_cmds, "set", "small_buffers", argc, argv) == 0)
219                 return 0;
220
221         rc = parse_long(argv[1], &value);
222         if (rc != 0) {
223                 cYAML_build_error(-1, -1, "parser", "set",
224                                   "cannot parse small_buffers value", &err_rc);
225                 cYAML_print_tree2file(stderr, err_rc);
226                 cYAML_free_tree(err_rc);
227                 return -1;
228         }
229
230         rc = lustre_lnet_config_buffers(-1, value, -1, -1, &err_rc);
231         if (rc != LUSTRE_CFG_RC_NO_ERR)
232                 cYAML_print_tree2file(stderr, err_rc);
233
234         cYAML_free_tree(err_rc);
235
236         return rc;
237 }
238
239 static int jt_set_large(int argc, char **argv)
240 {
241         long int value;
242         int rc;
243         struct cYAML *err_rc = NULL;
244
245         if (handle_help(set_cmds, "set", "large_buffers", argc, argv) == 0)
246                 return 0;
247
248         rc = parse_long(argv[1], &value);
249         if (rc != 0) {
250                 cYAML_build_error(-1, -1, "parser", "set",
251                                   "cannot parse large_buffers value", &err_rc);
252                 cYAML_print_tree2file(stderr, err_rc);
253                 cYAML_free_tree(err_rc);
254                 return -1;
255         }
256
257         rc = lustre_lnet_config_buffers(-1, -1, value, -1, &err_rc);
258         if (rc != LUSTRE_CFG_RC_NO_ERR)
259                 cYAML_print_tree2file(stderr, err_rc);
260
261         cYAML_free_tree(err_rc);
262
263         return rc;
264 }
265
266 static int jt_set_routing(int argc, char **argv)
267 {
268         long int value;
269         struct cYAML *err_rc = NULL;
270         int rc;
271
272         if (handle_help(set_cmds, "set", "routing", argc, argv) == 0)
273                 return 0;
274
275         rc = parse_long(argv[1], &value);
276         if (rc != 0 || (value != 0 && value != 1)) {
277                 cYAML_build_error(-1, -1, "parser", "set",
278                                   "cannot parse routing value.\n"
279                                   "must be 0 for disable or 1 for enable",
280                                   &err_rc);
281                 cYAML_print_tree2file(stderr, err_rc);
282                 cYAML_free_tree(err_rc);
283                 return -1;
284         }
285
286         rc = lustre_lnet_enable_routing(value, -1, &err_rc);
287
288         if (rc != LUSTRE_CFG_RC_NO_ERR)
289                 cYAML_print_tree2file(stderr, err_rc);
290
291         cYAML_free_tree(err_rc);
292
293         return rc;
294 }
295
296 static int jt_config_lnet(int argc, char **argv)
297 {
298         struct cYAML *err_rc = NULL;
299         bool load_mod_params = false;
300         int rc, opt;
301         optind = 0;
302
303         const char *const short_options = "ah";
304         const struct option long_options[] = {
305                 { "all", 0, NULL, 'a' },
306                 { "help", 0, NULL, 'h' },
307                 { NULL, 0, NULL, 0 },
308         };
309
310         while ((opt = getopt_long(argc, argv, short_options,
311                                    long_options, NULL)) != -1) {
312                 switch (opt) {
313                 case 'a':
314                         load_mod_params = true;
315                         break;
316                 case 'h':
317                         print_help(lnet_cmds, "lnet", "configure");
318                         return 0;
319                 default:
320                         return 0;
321                 }
322         }
323
324         rc = lustre_lnet_config_ni_system(LNET_CONFIGURE, load_mod_params,
325                                           -1, &err_rc);
326
327         if (rc != LUSTRE_CFG_RC_NO_ERR)
328                 cYAML_print_tree2file(stderr, err_rc);
329
330         cYAML_free_tree(err_rc);
331
332         return rc;
333 }
334
335 static int jt_unconfig_lnet(int argc, char **argv)
336 {
337         struct cYAML *err_rc = NULL;
338         int rc;
339         optind = 0;
340
341         if (handle_help(lnet_cmds, "lnet", "unconfigure", argc, argv) == 0)
342                 return 0;
343
344         rc = lustre_lnet_config_ni_system(LNET_UNCONFIGURE, 0, -1, &err_rc);
345
346         if (rc != LUSTRE_CFG_RC_NO_ERR)
347                 cYAML_print_tree2file(stderr, err_rc);
348
349         cYAML_free_tree(err_rc);
350
351         return rc;
352 }
353 static int jt_add_route(int argc, char **argv)
354 {
355         char *network = NULL, *gateway = NULL;
356         long int hop = -1, prio = -1;
357         struct cYAML *err_rc = NULL;
358         int rc, opt;
359         optind = 0;
360
361         const char *const short_options = "n:g:c:p:h";
362         const struct option long_options[] = {
363                 { "net", 1, NULL, 'n' },
364                 { "gateway", 1, NULL, 'g' },
365                 { "hop-count", 1, NULL, 'c' },
366                 { "priority", 1, NULL, 'p' },
367                 { "help", 0, NULL, 'h' },
368                 { NULL, 0, NULL, 0 },
369         };
370
371         while ((opt = getopt_long(argc, argv, short_options,
372                                    long_options, NULL)) != -1) {
373                 switch (opt) {
374                 case 'n':
375                         network = optarg;
376                         break;
377                 case 'g':
378                         gateway = optarg;
379                         break;
380                 case 'c':
381                         rc = parse_long(optarg, &hop);
382                         if (rc != 0) {
383                                 /* ignore option */
384                                 hop = -1;
385                                 continue;
386                         }
387                         break;
388                 case 'p':
389                         rc = parse_long(optarg, &prio);
390                         if (rc != 0) {
391                                 /* ingore option */
392                                 prio = -1;
393                                 continue;
394                         }
395                         break;
396                 case 'h':
397                         print_help(route_cmds, "route", "add");
398                         return 0;
399                 default:
400                         return 0;
401                 }
402         }
403
404         rc = lustre_lnet_config_route(network, gateway, hop, prio, -1, &err_rc);
405
406         if (rc != LUSTRE_CFG_RC_NO_ERR)
407                 cYAML_print_tree2file(stderr, err_rc);
408
409         cYAML_free_tree(err_rc);
410
411         return rc;
412 }
413
414 static int jt_add_net(int argc, char **argv)
415 {
416         char *network = NULL, *intf = NULL, *ip2net = NULL, *cpt = NULL;
417         long int pto = -1, pc = -1, pbc = -1, cre = -1;
418         struct cYAML *err_rc = NULL;
419         int rc, opt;
420         optind = 0;
421
422         const char *const short_options = "n:i:p:t:c:b:r:s:h";
423         const struct option long_options[] = {
424                 { "net", 1, NULL, 'n' },
425                 { "if", 1, NULL, 'i' },
426                 { "ip2net", 1, NULL, 'p' },
427                 { "peer-timeout", 1, NULL, 't' },
428                 { "peer-credits", 1, NULL, 'c' },
429                 { "peer-buffer-credits", 1, NULL, 'b' },
430                 { "credits", 1, NULL, 'r' },
431                 { "cpt", 1, NULL, 's' },
432                 { "help", 0, NULL, 'h' },
433                 { NULL, 0, NULL, 0 },
434         };
435
436         while ((opt = getopt_long(argc, argv, short_options,
437                                    long_options, NULL)) != -1) {
438                 switch (opt) {
439                 case 'n':
440                         network = optarg;
441                         break;
442                 case 'i':
443                         intf = optarg;
444                         break;
445                 case 'p':
446                         ip2net = optarg;
447                         break;
448                 case 't':
449                         rc = parse_long(optarg, &pto);
450                         if (rc != 0) {
451                                 /* ignore option */
452                                 pto = -1;
453                                 continue;
454                         }
455                         break;
456                 case 'c':
457                         rc = parse_long(optarg, &pc);
458                         if (rc != 0) {
459                                 /* ignore option */
460                                 pc = -1;
461                                 continue;
462                         }
463                         break;
464                 case 'b':
465                         rc = parse_long(optarg, &pbc);
466                         if (rc != 0) {
467                                 /* ignore option */
468                                 pbc = -1;
469                                 continue;
470                         }
471                         break;
472                 case 'r':
473                         rc = parse_long(optarg, &cre);
474                         if (rc != 0) {
475                                 /* ignore option */
476                                 cre = -1;
477                                 continue;
478                         }
479                         break;
480                 case 's':
481                         cpt = optarg;
482                         break;
483                 case 'h':
484                         print_help(net_cmds, "net", "add");
485                         return 0;
486                 default:
487                         return 0;
488                 }
489         }
490
491         rc = lustre_lnet_config_net(network, intf, ip2net, pto, pc, pbc,
492                                     cre, cpt, -1, &err_rc);
493
494         if (rc != LUSTRE_CFG_RC_NO_ERR)
495                 cYAML_print_tree2file(stderr, err_rc);
496
497         cYAML_free_tree(err_rc);
498
499         return rc;
500 }
501
502 static int jt_del_route(int argc, char **argv)
503 {
504         char *network = NULL, *gateway = NULL;
505         struct cYAML *err_rc = NULL;
506         int rc, opt;
507         optind = 0;
508
509         const char *const short_options = "n:g:h";
510         const struct option long_options[] = {
511                 { "net", 1, NULL, 'n' },
512                 { "gateway", 1, NULL, 'g' },
513                 { "help", 0, NULL, 'h' },
514                 { NULL, 0, NULL, 0 },
515         };
516
517         while ((opt = getopt_long(argc, argv, short_options,
518                                    long_options, NULL)) != -1) {
519                 switch (opt) {
520                 case 'n':
521                         network = optarg;
522                         break;
523                 case 'g':
524                         gateway = optarg;
525                         break;
526                 case 'h':
527                         print_help(route_cmds, "route", "del");
528                         return 0;
529                 default:
530                         return 0;
531                 }
532         }
533
534         rc = lustre_lnet_del_route(network, gateway, -1, &err_rc);
535
536         if (rc != LUSTRE_CFG_RC_NO_ERR)
537                 cYAML_print_tree2file(stderr, err_rc);
538
539         cYAML_free_tree(err_rc);
540
541         return rc;
542 }
543
544 static int jt_del_net(int argc, char **argv)
545 {
546         char *network = NULL;
547         struct cYAML *err_rc = NULL;
548         int rc, opt;
549         optind = 0;
550
551         const char *const short_options = "n:h";
552         const struct option long_options[] = {
553                 { "net", 1, NULL, 'n' },
554                 { "help", 0, NULL, 'h' },
555                 { NULL, 0, NULL, 0 },
556         };
557
558         while ((opt = getopt_long(argc, argv, short_options,
559                                    long_options, NULL)) != -1) {
560                 switch (opt) {
561                 case 'n':
562                         network = optarg;
563                         break;
564                 case 'h':
565                         print_help(net_cmds, "net", "del");
566                         return 0;
567                 default:
568                         return 0;
569                 }
570         }
571
572         rc = lustre_lnet_del_net(network, -1, &err_rc);
573
574         if (rc != LUSTRE_CFG_RC_NO_ERR)
575                 cYAML_print_tree2file(stderr, err_rc);
576
577         cYAML_free_tree(err_rc);
578
579         return rc;
580 }
581
582 static int jt_show_route(int argc, char **argv)
583 {
584         char *network = NULL, *gateway = NULL;
585         long int hop = -1, prio = -1;
586         int detail = 0, rc, opt;
587         struct cYAML *err_rc = NULL, *show_rc = NULL;
588         optind = 0;
589
590         const char *const short_options = "n:g:h:p:vh";
591         const struct option long_options[] = {
592                 { "net", 1, NULL, 'n' },
593                 { "gateway", 1, NULL, 'g' },
594                 { "hop-count", 1, NULL, 'c' },
595                 { "priority", 1, NULL, 'p' },
596                 { "verbose", 0, NULL, 'v' },
597                 { "help", 0, NULL, 'h' },
598                 { NULL, 0, NULL, 0 },
599         };
600
601         while ((opt = getopt_long(argc, argv, short_options,
602                                    long_options, NULL)) != -1) {
603                 switch (opt) {
604                 case 'n':
605                         network = optarg;
606                         break;
607                 case 'g':
608                         gateway = optarg;
609                         break;
610                 case 'c':
611                         rc = parse_long(optarg, &hop);
612                         if (rc != 0) {
613                                 /* ignore option */
614                                 hop = -1;
615                                 continue;
616                         }
617                         break;
618                 case 'p':
619                         rc = parse_long(optarg, &prio);
620                         if (rc != 0) {
621                                 /* ignore option */
622                                 prio = -1;
623                                 continue;
624                         }
625                         break;
626                 case 'v':
627                         detail = 1;
628                         break;
629                 case 'h':
630                         print_help(route_cmds, "route", "show");
631                         return 0;
632                 default:
633                         return 0;
634                 }
635         }
636
637         rc = lustre_lnet_show_route(network, gateway, hop, prio, detail, -1,
638                                     &show_rc, &err_rc);
639
640         if (rc != LUSTRE_CFG_RC_NO_ERR)
641                 cYAML_print_tree2file(stderr, err_rc);
642         else if (show_rc)
643                 cYAML_print_tree(show_rc);
644
645         cYAML_free_tree(err_rc);
646         cYAML_free_tree(show_rc);
647
648         return rc;
649 }
650
651 static int jt_show_net(int argc, char **argv)
652 {
653         char *network = NULL;
654         int detail = 0, rc, opt;
655         struct cYAML *err_rc = NULL, *show_rc = NULL;
656         optind = 0;
657
658         const char *const short_options = "n:vh";
659         const struct option long_options[] = {
660                 { "net", 1, NULL, 'n' },
661                 { "verbose", 0, NULL, 'v' },
662                 { "help", 0, NULL, 'h' },
663                 { NULL, 0, NULL, 0 },
664         };
665
666         while ((opt = getopt_long(argc, argv, short_options,
667                                    long_options, NULL)) != -1) {
668                 switch (opt) {
669                 case 'n':
670                         network = optarg;
671                         break;
672                 case 'v':
673                         detail = 1;
674                         break;
675                 case 'h':
676                         print_help(net_cmds, "net", "show");
677                         return 0;
678                 default:
679                         return 0;
680                 }
681         }
682
683         rc = lustre_lnet_show_net(network, detail, -1, &show_rc, &err_rc);
684
685         if (rc != LUSTRE_CFG_RC_NO_ERR)
686                 cYAML_print_tree2file(stderr, err_rc);
687         else if (show_rc)
688                 cYAML_print_tree(show_rc);
689
690         cYAML_free_tree(err_rc);
691         cYAML_free_tree(show_rc);
692
693         return rc;
694 }
695
696 static int jt_show_routing(int argc, char **argv)
697 {
698         struct cYAML *err_rc = NULL, *show_rc = NULL;
699         int rc;
700
701         if (handle_help(routing_cmds, "routing", "show", argc, argv) == 0)
702                 return 0;
703
704         rc = lustre_lnet_show_routing(-1, &show_rc, &err_rc);
705
706         if (rc != LUSTRE_CFG_RC_NO_ERR)
707                 cYAML_print_tree2file(stderr, err_rc);
708         else if (show_rc)
709                 cYAML_print_tree(show_rc);
710
711         cYAML_free_tree(err_rc);
712         cYAML_free_tree(show_rc);
713
714         return rc;
715 }
716
717 static int jt_show_stats(int argc, char **argv)
718 {
719         int rc;
720         struct cYAML *show_rc = NULL, *err_rc = NULL;
721
722         if (handle_help(stats_cmds, "stats", "show", argc, argv) == 0)
723                 return 0;
724
725         rc = lustre_lnet_show_stats(-1, &show_rc, &err_rc);
726
727         if (rc != LUSTRE_CFG_RC_NO_ERR)
728                 cYAML_print_tree2file(stderr, err_rc);
729         else if (show_rc)
730                 cYAML_print_tree(show_rc);
731
732         cYAML_free_tree(err_rc);
733         cYAML_free_tree(show_rc);
734
735         return rc;
736 }
737
738 static int jt_show_peer_credits(int argc, char **argv)
739 {
740         int rc;
741         struct cYAML *show_rc = NULL, *err_rc = NULL;
742         optind = 0;
743
744         if (handle_help(credits_cmds, "peer_credits", "show", argc, argv) == 0)
745                 return 0;
746
747         rc = lustre_lnet_show_peer_credits(-1, &show_rc, &err_rc);
748
749         if (rc != LUSTRE_CFG_RC_NO_ERR)
750                 cYAML_print_tree2file(stderr, err_rc);
751         else if (show_rc)
752                 cYAML_print_tree(show_rc);
753
754         cYAML_free_tree(err_rc);
755         cYAML_free_tree(show_rc);
756
757         return rc;
758 }
759
760 static inline int jt_lnet(int argc, char **argv)
761 {
762         if (argc < 2)
763                 return CMD_HELP;
764
765         if (argc == 2 &&
766             handle_help(lnet_cmds, "lnet", NULL, argc, argv) == 0)
767                 return 0;
768
769         return Parser_execarg(argc - 1, &argv[1], lnet_cmds);
770 }
771
772 static inline int jt_route(int argc, char **argv)
773 {
774         if (argc < 2)
775                 return CMD_HELP;
776
777         if (argc == 2 &&
778             handle_help(route_cmds, "route", NULL, argc, argv) == 0)
779                 return 0;
780
781         return Parser_execarg(argc - 1, &argv[1], route_cmds);
782 }
783
784 static inline int jt_net(int argc, char **argv)
785 {
786         if (argc < 2)
787                 return CMD_HELP;
788
789         if (argc == 2 &&
790             handle_help(net_cmds, "net", NULL, argc, argv) == 0)
791                 return 0;
792
793         return Parser_execarg(argc - 1, &argv[1], net_cmds);
794 }
795
796 static inline int jt_routing(int argc, char **argv)
797 {
798         if (argc < 2)
799                 return CMD_HELP;
800
801         if (argc == 2 &&
802             handle_help(routing_cmds, "routing", NULL, argc, argv) == 0)
803                 return 0;
804
805         return Parser_execarg(argc - 1, &argv[1], routing_cmds);
806 }
807
808 static inline int jt_stats(int argc, char **argv)
809 {
810         if (argc < 2)
811                 return CMD_HELP;
812
813         if (argc == 2 &&
814             handle_help(stats_cmds, "stats", NULL, argc, argv) == 0)
815                 return 0;
816
817         return Parser_execarg(argc - 1, &argv[1], stats_cmds);
818 }
819
820 static inline int jt_peer_credits(int argc, char **argv)
821 {
822         if (argc < 2)
823                 return CMD_HELP;
824
825         if (argc == 2 &&
826             handle_help(credits_cmds, "peer_credits", NULL, argc, argv) == 0)
827                 return 0;
828
829         return Parser_execarg(argc - 1, &argv[1], credits_cmds);
830 }
831
832 static inline int jt_set(int argc, char **argv)
833 {
834         if (argc < 2)
835                 return CMD_HELP;
836
837         if (argc == 2  &&
838             handle_help(set_cmds, "set", NULL, argc, argv) == 0)
839                 return 0;
840
841         return Parser_execarg(argc - 1, &argv[1], set_cmds);
842 }
843
844 static int jt_import(int argc, char **argv)
845 {
846         char *file = NULL;
847         struct cYAML *err_rc = NULL;
848         struct cYAML *show_rc = NULL;
849         int rc = 0, opt, opt_found = 0;
850         optind = 0;
851         char cmd = 'a';
852
853         const char *const short_options = "adsh";
854         const struct option long_options[] = {
855                 { "add", 0, NULL, 'a' },
856                 { "del", 0, NULL, 'd' },
857                 { "show", 0, NULL, 's' },
858                 { "help", 0, NULL, 'h' },
859                 { NULL, 0, NULL, 0 },
860         };
861
862         while ((opt = getopt_long(argc, argv, short_options,
863                                    long_options, NULL)) != -1) {
864                 opt_found = 1;
865                 switch (opt) {
866                 case 'a':
867                 case 'd':
868                 case 's':
869                         cmd = opt;
870                         break;
871                 case 'h':
872                         printf("import FILE\n"
873                                "import < FILE : import a file\n"
874                                "\t--add: add configuration\n"
875                                "\t--del: delete configuration\n"
876                                "\t--show: show configuration\n"
877                                "\t--help: display this help\n"
878                                "If no command option is given then --add"
879                                " is assumed by default\n");
880                         return 0;
881                 default:
882                         return 0;
883                 }
884         }
885
886         /* grab the file name if one exists */
887         if (opt_found && argc == 3)
888                 file = argv[2];
889         else if (!opt_found && argc == 2)
890                 file = argv[1];
891
892         switch (cmd) {
893         case 'a':
894                 rc = lustre_yaml_config(file, &err_rc);
895                 break;
896         case 'd':
897                 rc = lustre_yaml_del(file, &err_rc);
898                 break;
899         case 's':
900                 rc = lustre_yaml_show(file, &show_rc, &err_rc);
901                 cYAML_print_tree(show_rc);
902                 cYAML_free_tree(show_rc);
903                 break;
904         }
905
906         if (rc != LUSTRE_CFG_RC_NO_ERR)
907                 cYAML_print_tree2file(stderr, err_rc);
908
909         cYAML_free_tree(err_rc);
910
911         return rc;
912 }
913
914 static int jt_export(int argc, char **argv)
915 {
916         struct cYAML *show_rc = NULL;
917         struct cYAML *err_rc = NULL;
918         int rc, opt;
919         FILE *f = NULL;
920         optind = 0;
921
922         const char *const short_options = "h";
923         const struct option long_options[] = {
924                 { "help", 0, NULL, 'h' },
925                 { NULL, 0, NULL, 0 },
926         };
927
928         while ((opt = getopt_long(argc, argv, short_options,
929                                    long_options, NULL)) != -1) {
930                 switch (opt) {
931                 case 'h':
932                         printf("export FILE\n"
933                                "export > FILE : export configuration\n"
934                                "\t--help: display this help\n");
935                         return 0;
936                 default:
937                         return 0;
938                 }
939         }
940
941         if (argc >= 2) {
942                 f = fopen(argv[1], "w");
943                 if (f == NULL)
944                         return -1;
945         } else
946                 f = stdout;
947
948         rc = lustre_lnet_show_net(NULL, 1, -1, &show_rc, &err_rc);
949         if (rc != LUSTRE_CFG_RC_NO_ERR) {
950                 cYAML_print_tree2file(stderr, err_rc);
951                 cYAML_free_tree(err_rc);
952         }
953
954         rc = lustre_lnet_show_route(NULL, NULL, -1, -1, 1, -1, &show_rc,
955                                     &err_rc);
956         if (rc != LUSTRE_CFG_RC_NO_ERR) {
957                 cYAML_print_tree2file(stderr, err_rc);
958                 cYAML_free_tree(err_rc);
959         }
960
961         rc = lustre_lnet_show_routing(-1, &show_rc, &err_rc);
962         if (rc != LUSTRE_CFG_RC_NO_ERR) {
963                 cYAML_print_tree2file(stderr, err_rc);
964                 cYAML_free_tree(err_rc);
965         }
966
967         if (show_rc != NULL) {
968                 cYAML_print_tree2file(f, show_rc);
969                 cYAML_free_tree(show_rc);
970         }
971
972         if (argc >= 2)
973                 fclose(f);
974
975         return 0;
976 }
977
978 command_t list[] = {
979         {"lnet", jt_lnet, 0, "lnet {configure | unconfigure} [--all]"},
980         {"route", jt_route, 0, "route {add | del | show | help}"},
981         {"net", jt_net, 0, "net {add | del | show | help}"},
982         {"routing", jt_routing, 0, "routing {show | help}"},
983         {"set", jt_set, 0, "set {tiny_buffers | small_buffers | large_buffers"
984                            " | routing}"},
985         {"import", jt_import, 0, "import {--add | --del | --show | "
986                                  "--help} FILE.yaml"},
987         {"export", jt_export, 0, "export {--help} FILE.yaml"},
988         {"stats", jt_stats, 0, "stats {show | help}"},
989         {"peer_credits", jt_peer_credits, 0, "stats {show | help}"},
990         {"help", Parser_help, 0, "help"},
991         {"exit", Parser_quit, 0, "quit"},
992         {"quit", Parser_quit, 0, "quit"},
993         { 0, 0, 0, NULL }
994 };
995
996 int main(int argc, char **argv)
997 {
998         int rc = 0;
999         struct cYAML *err_rc = NULL;
1000
1001         rc = lustre_lnet_config_lib_init();
1002         if (rc < 0) {
1003                 cYAML_build_error(-1, -1, "lnetctl", "startup",
1004                                   "cannot register LNet device", &err_rc);
1005                 cYAML_print_tree2file(stderr, err_rc);
1006                 return rc;
1007         }
1008
1009         rc = libcfs_arch_init();
1010         if (rc < 0) {
1011                 cYAML_build_error(-1, -1, "lnetctl", "startup",
1012                                   "cannot initialize libcfs", &err_rc);
1013                 cYAML_print_tree2file(stderr, err_rc);
1014                 return rc;
1015         }
1016
1017         Parser_init("lnetctl > ", list);
1018         if (argc > 1) {
1019                 rc = Parser_execarg(argc - 1, &argv[1], list);
1020                 goto errorout;
1021         }
1022
1023         Parser_commands();
1024
1025 errorout:
1026         libcfs_arch_cleanup();
1027         return rc;
1028 }