Whamcloud - gitweb
LU-12815 socklnd: allow dynamic setting of conns_per_peer
[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) 2014, 2017, Intel Corporation.
22  *
23  * Author:
24  *   Amir Shehata <amir.shehata@intel.com>
25  */
26 #include <getopt.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <limits.h>
31 #include <libcfs/util/ioctl.h>
32 #include <libcfs/util/parser.h>
33 #include "lnetconfig/cyaml.h"
34 #include "lnetconfig/liblnetconfig.h"
35
36 #define LNET_CONFIGURE          true
37 #define LNET_UNCONFIGURE        false
38
39 static int jt_config_lnet(int argc, char **argv);
40 static int jt_unconfig_lnet(int argc, char **argv);
41 static int jt_add_route(int argc, char **argv);
42 static int jt_add_ni(int argc, char **argv);
43 static int jt_set_routing(int argc, char **argv);
44 static int jt_del_route(int argc, char **argv);
45 static int jt_del_ni(int argc, char **argv);
46 static int jt_show_route(int argc, char **argv);
47 static int jt_show_net(int argc, char **argv);
48 static int jt_show_routing(int argc, char **argv);
49 static int jt_show_stats(int argc, char **argv);
50 static int jt_show_peer(int argc, char **argv);
51 static int jt_show_recovery(int argc, char **argv);
52 static int jt_show_global(int argc, char **argv);
53 static int jt_show_udsp(int argc, char **argv);
54 static int jt_set_tiny(int argc, char **argv);
55 static int jt_set_small(int argc, char **argv);
56 static int jt_set_large(int argc, char **argv);
57 static int jt_set_numa(int argc, char **argv);
58 static int jt_set_retry_count(int argc, char **argv);
59 static int jt_set_transaction_to(int argc, char **argv);
60 static int jt_set_recov_intrv(int argc, char **argv);
61 static int jt_set_rtr_sensitivity(int argc, char **argv);
62 static int jt_set_hsensitivity(int argc, char **argv);
63 static int jt_reset_stats(int argc, char **argv);
64 static int jt_add_peer_nid(int argc, char **argv);
65 static int jt_del_peer_nid(int argc, char **argv);
66 static int jt_set_max_intf(int argc, char **argv);
67 static int jt_set_discovery(int argc, char **argv);
68 static int jt_set_drop_asym_route(int argc, char **argv);
69 static int jt_list_peer(int argc, char **argv);
70 static int jt_add_udsp(int argc, char **argv);
71 static int jt_del_udsp(int argc, char **argv);
72 /*static int jt_show_peer(int argc, char **argv);*/
73 static int lnetctl_list_commands(int argc, char **argv);
74 static int jt_import(int argc, char **argv);
75 static int jt_export(int argc, char **argv);
76 static int jt_ping(int argc, char **argv);
77 static int jt_discover(int argc, char **argv);
78 static int jt_lnet(int argc, char **argv);
79 static int jt_route(int argc, char **argv);
80 static int jt_net(int argc, char **argv);
81 static int jt_routing(int argc, char **argv);
82 static int jt_set(int argc, char **argv);
83 static int jt_debug(int argc, char **argv);
84 static int jt_stats(int argc, char **argv);
85 static int jt_global(int argc, char **argv);
86 static int jt_peers(int argc, char **argv);
87 static int jt_set_ni_value(int argc, char **argv);
88 static int jt_set_peer_ni_value(int argc, char **argv);
89 static int jt_calc_service_id(int argc, char **argv);
90 static int jt_set_response_tracking(int argc, char **argv);
91 static int jt_set_recovery_limit(int argc, char **argv);
92 static int jt_udsp(int argc, char **argv);
93
94 command_t cmd_list[] = {
95         {"lnet", jt_lnet, 0, "lnet {configure | unconfigure} [--all]"},
96         {"route", jt_route, 0, "route {add | del | show | help}"},
97         {"net", jt_net, 0, "net {add | del | show | set | help}"},
98         {"routing", jt_routing, 0, "routing {show | help}"},
99         {"set", jt_set, 0, "set {tiny_buffers | small_buffers | large_buffers"
100                            " | routing | numa_range | max_interfaces"
101                            " | discovery | drop_asym_route | retry_count"
102                            " | transaction_timeout | health_sensitivity"
103                            " | recovery_interval | router_sensitivity"
104                            " | response_tracking | recovery_limit}"},
105         {"import", jt_import, 0, "import FILE.yaml"},
106         {"export", jt_export, 0, "export FILE.yaml"},
107         {"stats", jt_stats, 0, "stats {show | help}"},
108         {"debug", jt_debug, 0, "debug recovery {local | peer}"},
109         {"global", jt_global, 0, "global {show | help}"},
110         {"peer", jt_peers, 0, "peer {add | del | show | list | set | help}"},
111         {"ping", jt_ping, 0, "ping nid,[nid,...]"},
112         {"discover", jt_discover, 0, "discover nid[,nid,...]"},
113         {"service-id", jt_calc_service_id, 0, "Calculate IB Lustre service ID\n"},
114         {"udsp", jt_udsp, 0, "udsp {add | del | help}"},
115         {"help", Parser_help, 0, "help"},
116         {"exit", Parser_quit, 0, "quit"},
117         {"quit", Parser_quit, 0, "quit"},
118         {"--list-commands", lnetctl_list_commands, 0, "list commands"},
119         { 0, 0, 0, NULL }
120 };
121
122 command_t lnet_cmds[] = {
123         {"configure", jt_config_lnet, 0, "configure lnet\n"
124          "\t--all: load NI configuration from module parameters\n"},
125         {"unconfigure", jt_unconfig_lnet, 0, "unconfigure lnet\n"},
126         { 0, 0, 0, NULL }
127 };
128
129 command_t route_cmds[] = {
130         {"add", jt_add_route, 0, "add a route\n"
131          "\t--net: net name (e.g. tcp0)\n"
132          "\t--gateway: gateway nid (e.g. 10.1.1.2@tcp)\n"
133          "\t--hop: number to final destination (1 < hops < 255)\n"
134          "\t--priority: priority of route (0 - highest prio\n"
135          "\t--health_sensitivity: gateway health sensitivity (>= 1)\n"},
136         {"del", jt_del_route, 0, "delete a route\n"
137          "\t--net: net name (e.g. tcp0)\n"
138          "\t--gateway: gateway nid (e.g. 10.1.1.2@tcp)\n"},
139         {"show", jt_show_route, 0, "show routes\n"
140          "\t--net: net name (e.g. tcp0) to filter on\n"
141          "\t--gateway: gateway nid (e.g. 10.1.1.2@tcp) to filter on\n"
142          "\t--hop: number to final destination (1 < hops < 255) to filter on\n"
143          "\t--priority: priority of route (0 - highest prio to filter on\n"
144          "\t--health_sensitivity: gateway health sensitivity (>= 1)\n"
145          "\t--verbose: display detailed output per route\n"},
146         { 0, 0, 0, NULL }
147 };
148
149 command_t net_cmds[] = {
150         {"add", jt_add_ni, 0, "add a network\n"
151          "\t--net: net name (e.g. tcp0)\n"
152          "\t--if: physical interface (e.g. eth0)\n"
153          "\t--ip2net: specify networks based on IP address patterns\n"
154          "\t--peer-timeout: time to wait before declaring a peer dead\n"
155          "\t--peer-credits: define the max number of inflight messages\n"
156          "\t--peer-buffer-credits: the number of buffer credits per peer\n"
157          "\t--credits: Network Interface credits\n"
158          "\t--cpt: CPU Partitions configured net uses (e.g. [0,1]\n"
159          "\t--conns-per-peer: number of connections per peer\n"},
160         {"del", jt_del_ni, 0, "delete a network\n"
161          "\t--net: net name (e.g. tcp0)\n"
162          "\t--if: physical interface (e.g. eth0)\n"},
163         {"show", jt_show_net, 0, "show networks\n"
164          "\t--net: net name (e.g. tcp0) to filter on\n"
165          "\t--verbose: display detailed output per network."
166                        " Optional argument of '2' outputs more stats\n"},
167         {"set", jt_set_ni_value, 0, "set local NI specific parameter\n"
168          "\t--nid: NI NID to set the\n"
169          "\t--health: specify health value to set\n"
170          "\t--conns-per-peer: number of connections per peer\n"
171          "\t--all: set all NIs value to the one specified\n"},
172         { 0, 0, 0, NULL }
173 };
174
175 command_t routing_cmds[] = {
176         {"show", jt_show_routing, 0, "show routing information\n"},
177         { 0, 0, 0, NULL }
178 };
179
180 command_t stats_cmds[] = {
181         {"show", jt_show_stats, 0, "show LNET statistics\n"},
182         {"reset", jt_reset_stats, 0, "reset LNET statistics\n"},
183         { 0, 0, 0, NULL }
184 };
185
186 command_t debug_cmds[] = {
187         {"recovery", jt_show_recovery, 0, "list recovery queues\n"
188                 "\t--local : list local recovery queue\n"
189                 "\t--peer : list peer recovery queue\n"},
190         { 0, 0, 0, NULL }
191 };
192
193 command_t global_cmds[] = {
194         {"show", jt_show_global, 0, "show global variables\n"},
195         { 0, 0, 0, NULL }
196 };
197
198 command_t set_cmds[] = {
199         {"tiny_buffers", jt_set_tiny, 0, "set tiny routing buffers\n"
200          "\tVALUE must be greater than 0\n"},
201         {"small_buffers", jt_set_small, 0, "set small routing buffers\n"
202          "\tVALUE must be greater than 0\n"},
203         {"large_buffers", jt_set_large, 0, "set large routing buffers\n"
204          "\tVALUE must be greater than 0\n"},
205         {"routing", jt_set_routing, 0, "enable/disable routing\n"
206          "\t0 - disable routing\n"
207          "\t1 - enable routing\n"},
208         {"numa_range", jt_set_numa, 0, "set NUMA range for NI selection\n"
209          "\tVALUE must be at least 0\n"},
210         {"max_interfaces", jt_set_max_intf, 0, "set the default value for "
211                 "max interfaces\n"
212          "\tValue must be greater than 16\n"},
213         {"discovery", jt_set_discovery, 0, "enable/disable peer discovery\n"
214          "\t0 - disable peer discovery\n"
215          "\t1 - enable peer discovery (default)\n"},
216         {"drop_asym_route", jt_set_drop_asym_route, 0,
217          "drop/accept asymmetrical route messages\n"
218          "\t0 - accept asymmetrical route messages (default)\n"
219          "\t1 - drop asymmetrical route messages\n"},
220         {"retry_count", jt_set_retry_count, 0, "number of retries\n"
221          "\t0 - turn of retries\n"
222          "\t>0 - number of retries\n"},
223         {"transaction_timeout", jt_set_transaction_to, 0, "Message/Response timeout\n"
224          "\t>0 - timeout in seconds\n"},
225         {"health_sensitivity", jt_set_hsensitivity, 0, "sensitivity to failure\n"
226          "\t0 - turn off health evaluation\n"
227          "\t>0 - sensitivity value not more than 1000\n"},
228         {"recovery_interval", jt_set_recov_intrv, 0, "interval to ping in seconds (at least 1)\n"
229          "\t>0 - time in seconds between pings\n"},
230         {"router_sensitivity", jt_set_rtr_sensitivity, 0, "router sensitivity %\n"
231          "\t100 - router interfaces need to be fully healthy to be used\n"
232          "\t<100 - router interfaces can be used even if not healthy\n"},
233         {"response_tracking", jt_set_response_tracking, 0,
234          "Set the behavior of response tracking\n"
235          "\t0 - Only LNet pings and discovery pushes utilize response tracking\n"
236          "\t1 - GETs are eligible for response tracking\n"
237          "\t2 - PUTs are eligible for response tracking\n"
238          "\t3 - Both PUTs and GETs are eligible for response tracking (default)\n"
239          "\tNote: Regardless of the value of the response_tracking parameter LNet\n"
240          "\t      pings and discovery pushes always utilize response tracking\n"},
241         {"recovery_limit", jt_set_recovery_limit, 0,
242          "Set how long LNet will attempt to recover unhealthy interfaces.\n"
243          "\t0 - Recover indefinitely (default)\n"
244          "\t>0 - Recover for the specified number of seconds.\n"},
245         { 0, 0, 0, NULL }
246 };
247
248 command_t peer_cmds[] = {
249         {"add", jt_add_peer_nid, 0, "add a peer NID\n"
250          "\t--prim_nid: Primary NID of the peer.\n"
251          "\t--nid: one or more peer NIDs\n"
252          "\t--non_mr: create this peer as not Multi-Rail capable\n"
253          "\t--ip2nets: specify a range of nids per peer"},
254         {"del", jt_del_peer_nid, 0, "delete a peer NID\n"
255          "\t--prim_nid: Primary NID of the peer.\n"
256          "\t--nid: list of NIDs to remove. If none provided,\n"
257          "\t       peer is deleted\n"
258          "\t--ip2nets: specify a range of nids per peer"},
259         {"show", jt_show_peer, 0, "show peer information\n"
260          "\t--nid: NID of peer to filter on.\n"
261          "\t--verbose: display detailed output per peer."
262                        " Optional argument of '2' outputs more stats\n"},
263         {"list", jt_list_peer, 0, "list all peers\n"},
264         {"set", jt_set_peer_ni_value, 0, "set peer ni specific parameter\n"
265          "\t--nid: Peer NI NID to set the\n"
266          "\t--health: specify health value to set\n"
267          "\t--all: set all peer_nis values to the one specified\n"},
268         { 0, 0, 0, NULL }
269 };
270
271 command_t udsp_cmds[] = {
272         {"add", jt_add_udsp, 0, "add a udsp\n"
273          "\t--src: ip2nets syntax specifying the local NID to match\n"
274          "\t--dst: ip2nets syntax specifying the remote NID to match\n"
275          "\t--rte: ip2nets syntax specifying the router NID to match\n"
276          "\t--priority: priority value (0 - highest priority)\n"
277          "\t--idx: index of where to insert the rule.\n"
278          "\t       By default, appends to the end of the rule list.\n"},
279         {"del", jt_del_udsp, 0, "delete a udsp\n"
280         "\t--idx: index of the Policy.\n"},
281         {"show", jt_show_udsp, 0, "show udsps\n"
282          "\t --idx: index of the policy to show.\n"},
283         { 0, 0, 0, NULL }
284 };
285
286 static int jt_calc_service_id(int argc, char **argv)
287 {
288         int rc;
289         __u64 service_id;
290
291         rc = lustre_lnet_calc_service_id(&service_id);
292         if (rc != LUSTRE_CFG_RC_NO_ERR)
293                 return rc;
294
295         /*
296          * cYAML currently doesn't support printing hex values.
297          * Therefore just print it locally here
298          */
299         printf("service id:\n    value: 0x%jx\n", (uintmax_t)service_id);
300
301         return rc;
302 }
303
304 static inline void print_help(const command_t cmds[], const char *cmd_type,
305                               const char *pc_name)
306 {
307         const command_t *cmd;
308
309         for (cmd = cmds; cmd->pc_name; cmd++) {
310                 if (pc_name != NULL &&
311                     strcmp(cmd->pc_name, pc_name) == 0) {
312                         printf("%s %s: %s\n", cmd_type, cmd->pc_name,
313                                cmd->pc_help);
314                         return;
315                 } else if (pc_name != NULL) {
316                         continue;
317                 }
318                 printf("%s %s: %s\n", cmd_type, cmd->pc_name, cmd->pc_help);
319         }
320 }
321
322 static int parse_long(const char *number, long int *value)
323 {
324         char *end;
325
326         if (!number)
327                 return -1;
328
329         *value = strtol(number,  &end, 0);
330         if (end != NULL && *end != 0)
331                 return -1;
332
333         return 0;
334 }
335
336 static int check_cmd(const command_t *cmd_list, const char *cmd,
337                      const char *sub_cmd, const int min_args,
338                      int argc, char **argv)
339 {
340         int opt;
341         int rc = 0;
342         optind = 0;
343         opterr = 0;
344
345         const char *const short_options = "h";
346         static const struct option long_options[] = {
347                 { .name = "help", .has_arg = no_argument, .val = 'h' },
348                 { .name = NULL }
349         };
350
351         if (argc < min_args) {
352                 print_help(cmd_list, cmd, sub_cmd);
353                 rc = -1;
354                 goto out;
355         } else if (argc > 2) {
356                 return 0;
357         }
358
359         while ((opt = getopt_long(argc, argv, short_options,
360                                   long_options, NULL)) != -1) {
361                 switch (opt) {
362                 case 'h':
363                         print_help(cmd_list, cmd, sub_cmd);
364                         rc = 1;
365                         break;
366                 default:
367                         rc = 0;
368                         break;
369                 }
370         }
371
372 out:
373         opterr = 1;
374         optind = 0;
375         return rc;
376 }
377
378 static int jt_set_response_tracking(int argc, char **argv)
379 {
380         long int value;
381         int rc;
382         struct cYAML *err_rc = NULL;
383
384         rc = check_cmd(set_cmds, "set", "response_tracking", 2, argc, argv);
385         if (rc)
386                 return rc;
387
388         rc = parse_long(argv[1], &value);
389         if (rc != 0) {
390                 cYAML_build_error(-1, -1, "parser", "set",
391                                   "cannot parse response_tracking value",
392                                   &err_rc);
393                 cYAML_print_tree2file(stderr, err_rc);
394                 cYAML_free_tree(err_rc);
395                 return -1;
396         }
397
398         rc = lustre_lnet_config_response_tracking(value, -1, &err_rc);
399         if (rc != LUSTRE_CFG_RC_NO_ERR)
400                 cYAML_print_tree2file(stderr, err_rc);
401
402         cYAML_free_tree(err_rc);
403
404         return rc;
405 }
406
407 static int jt_set_recovery_limit(int argc, char **argv)
408 {
409         long int value;
410         int rc;
411         struct cYAML *err_rc = NULL;
412
413         rc = check_cmd(set_cmds, "set", "recovery_limit", 2, argc, argv);
414         if (rc)
415                 return rc;
416
417         rc = parse_long(argv[1], &value);
418         if (rc != 0) {
419                 cYAML_build_error(-1, -1, "parser", "set",
420                                   "cannot parse recovery_limit value",
421                                   &err_rc);
422                 cYAML_print_tree2file(stderr, err_rc);
423                 cYAML_free_tree(err_rc);
424                 return -1;
425         }
426
427         rc = lustre_lnet_config_recovery_limit(value, -1, &err_rc);
428         if (rc != LUSTRE_CFG_RC_NO_ERR)
429                 cYAML_print_tree2file(stderr, err_rc);
430
431         cYAML_free_tree(err_rc);
432
433         return rc;
434 }
435
436 static int jt_set_max_intf(int argc, char **argv)
437 {
438         long int value;
439         int rc;
440         struct cYAML *err_rc = NULL;
441
442         rc = check_cmd(set_cmds, "set", "max_interfaces", 2, argc, argv);
443         if (rc)
444                 return rc;
445
446         rc = parse_long(argv[1], &value);
447         if (rc != 0) {
448                 cYAML_build_error(-1, -1, "parser", "set",
449                                   "cannot parse max_interfaces value", &err_rc);
450                 cYAML_print_tree2file(stderr, err_rc);
451                 cYAML_free_tree(err_rc);
452                 return -1;
453         }
454
455         rc = lustre_lnet_config_max_intf(value, -1, &err_rc);
456         if (rc != LUSTRE_CFG_RC_NO_ERR)
457                 cYAML_print_tree2file(stderr, err_rc);
458
459         cYAML_free_tree(err_rc);
460
461         return rc;
462 }
463
464 static int jt_set_numa(int argc, char **argv)
465 {
466         long int value;
467         int rc;
468         struct cYAML *err_rc = NULL;
469
470         rc = check_cmd(set_cmds, "set", "numa_range", 2, argc, argv);
471         if (rc)
472                 return rc;
473
474         rc = parse_long(argv[1], &value);
475         if (rc != 0) {
476                 cYAML_build_error(-1, -1, "parser", "set",
477                                   "cannot parse numa_range value", &err_rc);
478                 cYAML_print_tree2file(stderr, err_rc);
479                 cYAML_free_tree(err_rc);
480                 return -1;
481         }
482
483         rc = lustre_lnet_config_numa_range(value, -1, &err_rc);
484         if (rc != LUSTRE_CFG_RC_NO_ERR)
485                 cYAML_print_tree2file(stderr, err_rc);
486
487         cYAML_free_tree(err_rc);
488
489         return rc;
490 }
491
492 static int jt_set_recov_intrv(int argc, char **argv)
493 {
494         long int value;
495         int rc;
496         struct cYAML *err_rc = NULL;
497
498         rc = check_cmd(set_cmds, "set", "recovery_interval", 2, argc, argv);
499         if (rc)
500                 return rc;
501
502         rc = parse_long(argv[1], &value);
503         if (rc != 0) {
504                 cYAML_build_error(-1, -1, "parser", "set",
505                                   "cannot parse recovery interval value", &err_rc);
506                 cYAML_print_tree2file(stderr, err_rc);
507                 cYAML_free_tree(err_rc);
508                 return -1;
509         }
510
511         rc = lustre_lnet_config_recov_intrv(value, -1, &err_rc);
512         if (rc != LUSTRE_CFG_RC_NO_ERR)
513                 cYAML_print_tree2file(stderr, err_rc);
514
515         cYAML_free_tree(err_rc);
516
517         return rc;
518 }
519
520 static int jt_set_rtr_sensitivity(int argc, char **argv)
521 {
522         long int value;
523         int rc;
524         struct cYAML *err_rc = NULL;
525
526         rc = check_cmd(set_cmds, "set", "router_sensitivity", 2, argc, argv);
527         if (rc)
528                 return rc;
529
530         rc = parse_long(argv[1], &value);
531         if (rc != 0) {
532                 cYAML_build_error(-1, -1, "parser", "set",
533                                   "cannot parse router sensitivity value", &err_rc);
534                 cYAML_print_tree2file(stderr, err_rc);
535                 cYAML_free_tree(err_rc);
536                 return -1;
537         }
538
539         rc = lustre_lnet_config_rtr_sensitivity(value, -1, &err_rc);
540         if (rc != LUSTRE_CFG_RC_NO_ERR)
541                 cYAML_print_tree2file(stderr, err_rc);
542
543         cYAML_free_tree(err_rc);
544
545         return rc;
546 }
547
548 static int jt_set_hsensitivity(int argc, char **argv)
549 {
550         long int value;
551         int rc;
552         struct cYAML *err_rc = NULL;
553
554         rc = check_cmd(set_cmds, "set", "health_sensitivity", 2, argc, argv);
555         if (rc)
556                 return rc;
557
558         rc = parse_long(argv[1], &value);
559         if (rc != 0) {
560                 cYAML_build_error(-1, -1, "parser", "set",
561                                   "cannot parse health sensitivity value", &err_rc);
562                 cYAML_print_tree2file(stderr, err_rc);
563                 cYAML_free_tree(err_rc);
564                 return -1;
565         }
566
567         rc = lustre_lnet_config_hsensitivity(value, -1, &err_rc);
568         if (rc != LUSTRE_CFG_RC_NO_ERR)
569                 cYAML_print_tree2file(stderr, err_rc);
570
571         cYAML_free_tree(err_rc);
572
573         return rc;
574 }
575
576 static int jt_reset_stats(int argc, char **argv)
577 {
578         int rc;
579         struct cYAML *err_rc = NULL;
580
581         rc = check_cmd(stats_cmds, "stats", "reset", 0, argc, argv);
582         if (rc)
583                 return rc;
584
585         rc = lustre_lnet_reset_stats(-1, &err_rc);
586         if (rc != LUSTRE_CFG_RC_NO_ERR)
587                 cYAML_print_tree2file(stderr, err_rc);
588
589         cYAML_free_tree(err_rc);
590
591         return rc;
592 }
593
594 static int jt_set_transaction_to(int argc, char **argv)
595 {
596         long int value;
597         int rc;
598         struct cYAML *err_rc = NULL;
599
600         rc = check_cmd(set_cmds, "set", "transaction_timeout", 2, argc, argv);
601         if (rc)
602                 return rc;
603
604         rc = parse_long(argv[1], &value);
605         if (rc != 0) {
606                 cYAML_build_error(-1, -1, "parser", "set",
607                                   "cannot parse transaction timeout value", &err_rc);
608                 cYAML_print_tree2file(stderr, err_rc);
609                 cYAML_free_tree(err_rc);
610                 return -1;
611         }
612
613         rc = lustre_lnet_config_transaction_to(value, -1, &err_rc);
614         if (rc != LUSTRE_CFG_RC_NO_ERR)
615                 cYAML_print_tree2file(stderr, err_rc);
616
617         cYAML_free_tree(err_rc);
618
619         return rc;
620 }
621
622 static int jt_set_retry_count(int argc, char **argv)
623 {
624         long int value;
625         int rc;
626         struct cYAML *err_rc = NULL;
627
628         rc = check_cmd(set_cmds, "set", "retry_count", 2, argc, argv);
629         if (rc)
630                 return rc;
631
632         rc = parse_long(argv[1], &value);
633         if (rc != 0) {
634                 cYAML_build_error(-1, -1, "parser", "set",
635                                   "cannot parse retry_count value", &err_rc);
636                 cYAML_print_tree2file(stderr, err_rc);
637                 cYAML_free_tree(err_rc);
638                 return -1;
639         }
640
641         rc = lustre_lnet_config_retry_count(value, -1, &err_rc);
642         if (rc != LUSTRE_CFG_RC_NO_ERR)
643                 cYAML_print_tree2file(stderr, err_rc);
644
645         cYAML_free_tree(err_rc);
646
647         return rc;
648 }
649
650 static int jt_set_discovery(int argc, char **argv)
651 {
652         long int value;
653         int rc;
654         struct cYAML *err_rc = NULL;
655
656         rc = check_cmd(set_cmds, "set", "discovery", 2, argc, argv);
657         if (rc)
658                 return rc;
659
660         rc = parse_long(argv[1], &value);
661         if (rc != 0) {
662                 cYAML_build_error(-1, -1, "parser", "set",
663                                   "cannot parse discovery value", &err_rc);
664                 cYAML_print_tree2file(stderr, err_rc);
665                 cYAML_free_tree(err_rc);
666                 return -1;
667         }
668
669         rc = lustre_lnet_config_discovery(value, -1, &err_rc);
670         if (rc != LUSTRE_CFG_RC_NO_ERR)
671                 cYAML_print_tree2file(stderr, err_rc);
672
673         cYAML_free_tree(err_rc);
674
675         return rc;
676 }
677
678 static int jt_set_drop_asym_route(int argc, char **argv)
679 {
680         long int value;
681         int rc;
682         struct cYAML *err_rc = NULL;
683
684         rc = check_cmd(set_cmds, "set", "drop_asym_route", 2, argc, argv);
685         if (rc)
686                 return rc;
687
688         rc = parse_long(argv[1], &value);
689         if (rc != 0) {
690                 cYAML_build_error(-1, -1, "parser", "set",
691                                   "cannot parse drop_asym_route value",
692                                   &err_rc);
693                 cYAML_print_tree2file(stderr, err_rc);
694                 cYAML_free_tree(err_rc);
695                 return -1;
696         }
697
698         rc = lustre_lnet_config_drop_asym_route(value, -1, &err_rc);
699         if (rc != LUSTRE_CFG_RC_NO_ERR)
700                 cYAML_print_tree2file(stderr, err_rc);
701
702         cYAML_free_tree(err_rc);
703
704         return rc;
705 }
706
707 static int jt_set_tiny(int argc, char **argv)
708 {
709         long int value;
710         int rc;
711         struct cYAML *err_rc = NULL;
712
713         rc = check_cmd(set_cmds, "set", "tiny_buffers", 2, argc, argv);
714         if (rc)
715                 return rc;
716
717         rc = parse_long(argv[1], &value);
718         if (rc != 0) {
719                 cYAML_build_error(-1, -1, "parser", "set",
720                                   "cannot parse tiny_buffers value", &err_rc);
721                 cYAML_print_tree2file(stderr, err_rc);
722                 cYAML_free_tree(err_rc);
723                 return -1;
724         }
725
726         rc = lustre_lnet_config_buffers(value, -1, -1, -1, &err_rc);
727         if (rc != LUSTRE_CFG_RC_NO_ERR)
728                 cYAML_print_tree2file(stderr, err_rc);
729
730         cYAML_free_tree(err_rc);
731
732         return rc;
733 }
734
735 static int jt_set_small(int argc, char **argv)
736 {
737         long int value;
738         int rc;
739         struct cYAML *err_rc = NULL;
740
741         rc = check_cmd(set_cmds, "set", "small_buffers", 2, argc, argv);
742         if (rc)
743                 return rc;
744
745         rc = parse_long(argv[1], &value);
746         if (rc != 0) {
747                 cYAML_build_error(-1, -1, "parser", "set",
748                                   "cannot parse small_buffers value", &err_rc);
749                 cYAML_print_tree2file(stderr, err_rc);
750                 cYAML_free_tree(err_rc);
751                 return -1;
752         }
753
754         rc = lustre_lnet_config_buffers(-1, value, -1, -1, &err_rc);
755         if (rc != LUSTRE_CFG_RC_NO_ERR)
756                 cYAML_print_tree2file(stderr, err_rc);
757
758         cYAML_free_tree(err_rc);
759
760         return rc;
761 }
762
763 static int jt_set_large(int argc, char **argv)
764 {
765         long int value;
766         int rc;
767         struct cYAML *err_rc = NULL;
768
769         rc = check_cmd(set_cmds, "set", "large_buffers", 2, argc, argv);
770         if (rc)
771                 return rc;
772
773         rc = parse_long(argv[1], &value);
774         if (rc != 0) {
775                 cYAML_build_error(-1, -1, "parser", "set",
776                                   "cannot parse large_buffers value", &err_rc);
777                 cYAML_print_tree2file(stderr, err_rc);
778                 cYAML_free_tree(err_rc);
779                 return -1;
780         }
781
782         rc = lustre_lnet_config_buffers(-1, -1, value, -1, &err_rc);
783         if (rc != LUSTRE_CFG_RC_NO_ERR)
784                 cYAML_print_tree2file(stderr, err_rc);
785
786         cYAML_free_tree(err_rc);
787
788         return rc;
789 }
790
791 static int jt_set_routing(int argc, char **argv)
792 {
793         long int value;
794         struct cYAML *err_rc = NULL;
795         int rc;
796
797         rc = check_cmd(set_cmds, "set", "routing", 2, argc, argv);
798         if (rc)
799                 return rc;
800
801         rc = parse_long(argv[1], &value);
802         if (rc != 0 || (value != 0 && value != 1)) {
803                 cYAML_build_error(-1, -1, "parser", "set",
804                                   "cannot parse routing value.\n"
805                                   "must be 0 for disable or 1 for enable",
806                                   &err_rc);
807                 cYAML_print_tree2file(stderr, err_rc);
808                 cYAML_free_tree(err_rc);
809                 return -1;
810         }
811
812         rc = lustre_lnet_enable_routing(value, -1, &err_rc);
813
814         if (rc != LUSTRE_CFG_RC_NO_ERR)
815                 cYAML_print_tree2file(stderr, err_rc);
816
817         cYAML_free_tree(err_rc);
818
819         return rc;
820 }
821
822 static int jt_config_lnet(int argc, char **argv)
823 {
824         struct cYAML *err_rc = NULL;
825         bool load_mod_params = false;
826         int rc, opt;
827
828         const char *const short_options = "a";
829         static const struct option long_options[] = {
830                 { .name = "all",  .has_arg = no_argument, .val = 'a' },
831                 { .name = NULL }
832         };
833
834         rc = check_cmd(lnet_cmds, "lnet", "configure", 0, argc, argv);
835         if (rc)
836                 return rc;
837
838         while ((opt = getopt_long(argc, argv, short_options,
839                                    long_options, NULL)) != -1) {
840                 switch (opt) {
841                 case 'a':
842                         load_mod_params = true;
843                         break;
844                 default:
845                         return 0;
846                 }
847         }
848
849         rc = lustre_lnet_config_ni_system(LNET_CONFIGURE, load_mod_params,
850                                           -1, &err_rc);
851
852         if (rc != LUSTRE_CFG_RC_NO_ERR)
853                 cYAML_print_tree2file(stderr, err_rc);
854
855         cYAML_free_tree(err_rc);
856
857         return rc;
858 }
859
860 static int jt_unconfig_lnet(int argc, char **argv)
861 {
862         struct cYAML *err_rc = NULL;
863         int rc;
864
865         rc = check_cmd(lnet_cmds, "lnet", "unconfigure", 0, argc, argv);
866         if (rc)
867                 return rc;
868
869         rc = lustre_lnet_config_ni_system(LNET_UNCONFIGURE, 0, -1, &err_rc);
870
871         if (rc != LUSTRE_CFG_RC_NO_ERR)
872                 cYAML_print_tree2file(stderr, err_rc);
873
874         cYAML_free_tree(err_rc);
875
876         return rc;
877 }
878 static int jt_add_route(int argc, char **argv)
879 {
880         char *network = NULL, *gateway = NULL;
881         long int hop = -1, prio = -1, sen = -1;
882         struct cYAML *err_rc = NULL;
883         int rc, opt;
884
885         const char *const short_options = "n:g:c:p:";
886         static const struct option long_options[] = {
887         { .name = "net",       .has_arg = required_argument, .val = 'n' },
888         { .name = "gateway",   .has_arg = required_argument, .val = 'g' },
889         { .name = "hop-count", .has_arg = required_argument, .val = 'c' },
890         { .name = "priority",  .has_arg = required_argument, .val = 'p' },
891         { .name = "health_sensitivity",  .has_arg = required_argument, .val = 's' },
892         { .name = NULL } };
893
894         rc = check_cmd(route_cmds, "route", "add", 0, argc, argv);
895         if (rc)
896                 return rc;
897
898         while ((opt = getopt_long(argc, argv, short_options,
899                                    long_options, NULL)) != -1) {
900                 switch (opt) {
901                 case 'n':
902                         network = optarg;
903                         break;
904                 case 'g':
905                         gateway = optarg;
906                         break;
907                 case 'c':
908                         rc = parse_long(optarg, &hop);
909                         if (rc != 0) {
910                                 /* ignore option */
911                                 hop = -1;
912                                 continue;
913                         }
914                         break;
915                 case 'p':
916                         rc = parse_long(optarg, &prio);
917                         if (rc != 0) {
918                                 /* ingore option */
919                                 prio = -1;
920                                 continue;
921                         }
922                         break;
923                 case 's':
924                         rc = parse_long(optarg, &sen);
925                         if (rc != 0) {
926                                 /* ingore option */
927                                 sen = -1;
928                                 continue;
929                         }
930                         break;
931
932                 case '?':
933                         print_help(route_cmds, "route", "add");
934                 default:
935                         return 0;
936                 }
937         }
938
939         rc = lustre_lnet_config_route(network, gateway, hop, prio, sen, -1,
940                                       &err_rc);
941
942         if (rc != LUSTRE_CFG_RC_NO_ERR)
943                 cYAML_print_tree2file(stderr, err_rc);
944
945         cYAML_free_tree(err_rc);
946
947         return rc;
948 }
949
950 static int jt_add_ni(int argc, char **argv)
951 {
952         char *ip2net = NULL;
953         long int pto = -1, pc = -1, pbc = -1, cre = -1, cpp = -1;
954         struct cYAML *err_rc = NULL;
955         int rc, opt, cpt_rc = -1;
956         struct lnet_dlc_network_descr nw_descr;
957         struct cfs_expr_list *global_cpts = NULL;
958         struct lnet_ioctl_config_lnd_tunables tunables;
959         bool found = false;
960
961         memset(&tunables, 0, sizeof(tunables));
962         lustre_lnet_init_nw_descr(&nw_descr);
963
964         const char *const short_options = "b:c:i:m:n:p:r:s:t:";
965         static const struct option long_options[] = {
966         { .name = "peer-buffer-credits",
967                                   .has_arg = required_argument, .val = 'b' },
968         { .name = "peer-credits", .has_arg = required_argument, .val = 'c' },
969         { .name = "if",           .has_arg = required_argument, .val = 'i' },
970         { .name = "conns-per-peer",
971                                   .has_arg = required_argument, .val = 'm' },
972         { .name = "net",          .has_arg = required_argument, .val = 'n' },
973         { .name = "ip2net",       .has_arg = required_argument, .val = 'p' },
974         { .name = "credits",      .has_arg = required_argument, .val = 'r' },
975         { .name = "cpt",          .has_arg = required_argument, .val = 's' },
976         { .name = "peer-timeout", .has_arg = required_argument, .val = 't' },
977         { .name = NULL } };
978
979         rc = check_cmd(net_cmds, "net", "add", 0, argc, argv);
980         if (rc)
981                 return rc;
982
983         while ((opt = getopt_long(argc, argv, short_options,
984                                    long_options, NULL)) != -1) {
985                 switch (opt) {
986                 case 'b':
987                         rc = parse_long(optarg, &pbc);
988                         if (rc != 0) {
989                                 /* ignore option */
990                                 pbc = -1;
991                                 continue;
992                         }
993                         break;
994                 case 'c':
995                         rc = parse_long(optarg, &pc);
996                         if (rc != 0) {
997                                 /* ignore option */
998                                 pc = -1;
999                                 continue;
1000                         }
1001                         break;
1002                 case 'i':
1003                         rc = lustre_lnet_parse_interfaces(optarg, &nw_descr);
1004                         if (rc != 0) {
1005                                 cYAML_build_error(-1, -1, "ni", "add",
1006                                                 "bad interface list",
1007                                                 &err_rc);
1008                                 goto failed;
1009                         }
1010                         break;
1011                 case 'm':
1012                         rc = parse_long(optarg, &cpp);
1013                         if (rc != 0) {
1014                                 /* ignore option */
1015                                 cpp = -1;
1016                                 continue;
1017                         }
1018                         break;
1019
1020                 case 'n':
1021                         nw_descr.nw_id = libcfs_str2net(optarg);
1022                         break;
1023                 case 'p':
1024                         ip2net = optarg;
1025                         break;
1026                 case 'r':
1027                         rc = parse_long(optarg, &cre);
1028                         if (rc != 0) {
1029                                 /* ignore option */
1030                                 cre = -1;
1031                                 continue;
1032                         }
1033                         break;
1034                 case 's':
1035                         cpt_rc = cfs_expr_list_parse(optarg,
1036                                                      strlen(optarg), 0,
1037                                                      UINT_MAX, &global_cpts);
1038                         break;
1039                 case 't':
1040                         rc = parse_long(optarg, &pto);
1041                         if (rc != 0) {
1042                                 /* ignore option */
1043                                 pto = -1;
1044                                 continue;
1045                         }
1046                         break;
1047                 case '?':
1048                         print_help(net_cmds, "net", "add");
1049                 default:
1050                         return 0;
1051                 }
1052         }
1053
1054         if (pto > 0 || pc > 0 || pbc > 0 || cre > 0 || cpp > -1) {
1055                 tunables.lt_cmn.lct_peer_timeout = pto;
1056                 tunables.lt_cmn.lct_peer_tx_credits = pc;
1057                 tunables.lt_cmn.lct_peer_rtr_credits = pbc;
1058                 tunables.lt_cmn.lct_max_tx_credits = cre;
1059                 found = true;
1060         }
1061
1062         rc = lustre_lnet_config_ni(&nw_descr,
1063                                    (cpt_rc == 0) ? global_cpts: NULL,
1064                                    ip2net, (found) ? &tunables : NULL,
1065                                    cpp, -1, &err_rc);
1066
1067         if (global_cpts != NULL)
1068                 cfs_expr_list_free(global_cpts);
1069
1070 failed:
1071         if (rc != LUSTRE_CFG_RC_NO_ERR)
1072                 cYAML_print_tree2file(stderr, err_rc);
1073
1074         cYAML_free_tree(err_rc);
1075
1076         return rc;
1077 }
1078
1079 static int jt_del_route(int argc, char **argv)
1080 {
1081         char *network = NULL, *gateway = NULL;
1082         struct cYAML *err_rc = NULL;
1083         int rc, opt;
1084
1085         const char *const short_options = "n:g:";
1086         static const struct option long_options[] = {
1087                 { .name = "net",     .has_arg = required_argument, .val = 'n' },
1088                 { .name = "gateway", .has_arg = required_argument, .val = 'g' },
1089                 { .name = NULL } };
1090
1091         rc = check_cmd(route_cmds, "route", "del", 0, argc, argv);
1092         if (rc)
1093                 return rc;
1094
1095         while ((opt = getopt_long(argc, argv, short_options,
1096                                    long_options, NULL)) != -1) {
1097                 switch (opt) {
1098                 case 'n':
1099                         network = optarg;
1100                         break;
1101                 case 'g':
1102                         gateway = optarg;
1103                         break;
1104                 case '?':
1105                         print_help(route_cmds, "route", "del");
1106                 default:
1107                         return 0;
1108                 }
1109         }
1110
1111         rc = lustre_lnet_del_route(network, gateway, -1, &err_rc);
1112
1113         if (rc != LUSTRE_CFG_RC_NO_ERR)
1114                 cYAML_print_tree2file(stderr, err_rc);
1115
1116         cYAML_free_tree(err_rc);
1117
1118         return rc;
1119 }
1120
1121 static int jt_del_ni(int argc, char **argv)
1122 {
1123         struct cYAML *err_rc = NULL;
1124         int rc, opt;
1125         struct lnet_dlc_network_descr nw_descr;
1126
1127         lustre_lnet_init_nw_descr(&nw_descr);
1128
1129         const char *const short_options = "n:i:";
1130         static const struct option long_options[] = {
1131         { .name = "net",        .has_arg = required_argument,   .val = 'n' },
1132         { .name = "if",         .has_arg = required_argument,   .val = 'i' },
1133         { .name = NULL } };
1134
1135         rc = check_cmd(net_cmds, "net", "del", 0, argc, argv);
1136         if (rc)
1137                 return rc;
1138
1139         while ((opt = getopt_long(argc, argv, short_options,
1140                                    long_options, NULL)) != -1) {
1141                 switch (opt) {
1142                 case 'n':
1143                         nw_descr.nw_id = libcfs_str2net(optarg);
1144                         break;
1145                 case 'i':
1146                         rc = lustre_lnet_parse_interfaces(optarg, &nw_descr);
1147                         if (rc != 0) {
1148                                 cYAML_build_error(-1, -1, "ni", "add",
1149                                                 "bad interface list",
1150                                                 &err_rc);
1151                                 goto out;
1152                         }
1153                         break;
1154                 case '?':
1155                         print_help(net_cmds, "net", "del");
1156                 default:
1157                         return 0;
1158                 }
1159         }
1160
1161         rc = lustre_lnet_del_ni(&nw_descr, -1, &err_rc);
1162
1163 out:
1164         if (rc != LUSTRE_CFG_RC_NO_ERR)
1165                 cYAML_print_tree2file(stderr, err_rc);
1166
1167         cYAML_free_tree(err_rc);
1168
1169         return rc;
1170 }
1171
1172 static int jt_show_route(int argc, char **argv)
1173 {
1174         char *network = NULL, *gateway = NULL;
1175         long int hop = -1, prio = -1;
1176         int detail = 0, rc, opt;
1177         struct cYAML *err_rc = NULL, *show_rc = NULL;
1178
1179         const char *const short_options = "n:g:h:p:v";
1180         static const struct option long_options[] = {
1181         { .name = "net",       .has_arg = required_argument, .val = 'n' },
1182         { .name = "gateway",   .has_arg = required_argument, .val = 'g' },
1183         { .name = "hop-count", .has_arg = required_argument, .val = 'c' },
1184         { .name = "priority",  .has_arg = required_argument, .val = 'p' },
1185         { .name = "verbose",   .has_arg = no_argument,       .val = 'v' },
1186         { .name = NULL } };
1187
1188         rc = check_cmd(route_cmds, "route", "show", 0, argc, argv);
1189         if (rc)
1190                 return rc;
1191
1192         while ((opt = getopt_long(argc, argv, short_options,
1193                                    long_options, NULL)) != -1) {
1194                 switch (opt) {
1195                 case 'n':
1196                         network = optarg;
1197                         break;
1198                 case 'g':
1199                         gateway = optarg;
1200                         break;
1201                 case 'c':
1202                         rc = parse_long(optarg, &hop);
1203                         if (rc != 0) {
1204                                 /* ignore option */
1205                                 hop = -1;
1206                                 continue;
1207                         }
1208                         break;
1209                 case 'p':
1210                         rc = parse_long(optarg, &prio);
1211                         if (rc != 0) {
1212                                 /* ignore option */
1213                                 prio = -1;
1214                                 continue;
1215                         }
1216                         break;
1217                 case 'v':
1218                         detail = 1;
1219                         break;
1220                 case '?':
1221                         print_help(route_cmds, "route", "show");
1222                 default:
1223                         return 0;
1224                 }
1225         }
1226
1227         rc = lustre_lnet_show_route(network, gateway, hop, prio, detail, -1,
1228                                     &show_rc, &err_rc, false);
1229
1230         if (rc != LUSTRE_CFG_RC_NO_ERR)
1231                 cYAML_print_tree2file(stderr, err_rc);
1232         else if (show_rc)
1233                 cYAML_print_tree(show_rc);
1234
1235         cYAML_free_tree(err_rc);
1236         cYAML_free_tree(show_rc);
1237
1238         return rc;
1239 }
1240
1241 static int set_value_helper(int argc, char **argv,
1242                             int (*cb)(int, bool, char*, int, struct cYAML**))
1243 {
1244         char *nid = NULL;
1245         long int healthv = -1;
1246         bool all = false;
1247         int rc, opt;
1248         struct cYAML *err_rc = NULL;
1249
1250         const char *const short_options = "t:n:a";
1251         static const struct option long_options[] = {
1252                 { .name = "nid", .has_arg = required_argument, .val = 'n' },
1253                 { .name = "health", .has_arg = required_argument, .val = 't' },
1254                 { .name = "all", .has_arg = no_argument, .val = 'a' },
1255                 { .name = NULL } };
1256
1257         rc = check_cmd(net_cmds, "net", "set", 0, argc, argv);
1258         if (rc)
1259                 return rc;
1260
1261         while ((opt = getopt_long(argc, argv, short_options,
1262                                    long_options, NULL)) != -1) {
1263                 switch (opt) {
1264                 case 'n':
1265                         nid = optarg;
1266                         break;
1267                 case 't':
1268                         if (parse_long(optarg, &healthv) != 0)
1269                                 healthv = -1;
1270                         break;
1271                 case 'a':
1272                         all = true;
1273                         break;
1274                 default:
1275                         return 0;
1276                 }
1277         }
1278
1279         rc = cb(healthv, all, nid, -1, &err_rc);
1280
1281         if (rc != LUSTRE_CFG_RC_NO_ERR)
1282                 cYAML_print_tree2file(stderr, err_rc);
1283
1284         cYAML_free_tree(err_rc);
1285
1286         return rc;
1287 }
1288
1289 static int jt_set_ni_value(int argc, char **argv)
1290 {
1291         char *nid = NULL;
1292         long int healthv = -1, cpp = -1;
1293         bool all = false;
1294         int rc, opt;
1295         struct cYAML *err_rc = NULL;
1296
1297         const char *const short_options = "a:m:n:t:";
1298         static const struct option long_options[] = {
1299         { .name = "all",            .has_arg = no_argument,       .val = 'a' },
1300         { .name = "conns-per-peer", .has_arg = required_argument, .val = 'm' },
1301         { .name = "nid",            .has_arg = required_argument, .val = 'n' },
1302         { .name = "health",         .has_arg = required_argument, .val = 't' },
1303         { .name = NULL } };
1304
1305         rc = check_cmd(net_cmds, "net", "set", 0, argc, argv);
1306         if (rc)
1307                 return rc;
1308
1309         while ((opt = getopt_long(argc, argv, short_options,
1310                                    long_options, NULL)) != -1) {
1311                 switch (opt) {
1312                 case 'a':
1313                         all = true;
1314                         break;
1315                 case 'm':
1316                         rc = parse_long(optarg, &cpp);
1317                         if (rc != 0) {
1318                                 /* ignore option */
1319                                 cpp = -1;
1320                                 continue;
1321                         }
1322                         break;
1323                 case 'n':
1324                         nid = optarg;
1325                         break;
1326                 case 't':
1327                         if (parse_long(optarg, &healthv) != 0) {
1328                                 /* ignore option */
1329                                 healthv = -1;
1330                                 continue;
1331                         }
1332                         break;
1333                 default:
1334                         return 0;
1335                 }
1336         }
1337
1338         if (cpp > -1)
1339                 rc = lustre_lnet_config_ni_conns_per_peer(cpp, all, nid,
1340                                                           -1, &err_rc);
1341         if (healthv > -1)
1342                 rc = lustre_lnet_config_ni_healthv(healthv, all, nid,
1343                                                    -1, &err_rc);
1344
1345         if (rc != LUSTRE_CFG_RC_NO_ERR)
1346                 cYAML_print_tree2file(stderr, err_rc);
1347
1348         cYAML_free_tree(err_rc);
1349
1350         return rc;
1351 }
1352
1353 static int jt_set_peer_ni_value(int argc, char **argv)
1354 {
1355         return set_value_helper(argc, argv, lustre_lnet_config_peer_ni_healthv);
1356 }
1357
1358 static int jt_show_recovery(int argc, char **argv)
1359 {
1360         int rc, opt;
1361         struct cYAML *err_rc = NULL, *show_rc = NULL;
1362
1363         const char *const short_options = "lp";
1364         static const struct option long_options[] = {
1365                 { .name = "local", .has_arg = no_argument, .val = 'l' },
1366                 { .name = "peer", .has_arg = no_argument, .val = 'p' },
1367                 { .name = NULL } };
1368
1369         rc = check_cmd(debug_cmds, "recovery", NULL, 0, argc, argv);
1370         if (rc)
1371                 return rc;
1372
1373         while ((opt = getopt_long(argc, argv, short_options,
1374                                    long_options, NULL)) != -1) {
1375                 switch (opt) {
1376                 case 'l':
1377                         rc = lustre_lnet_show_local_ni_recovq(-1, &show_rc, &err_rc);
1378                         break;
1379                 case 'p':
1380                         rc = lustre_lnet_show_peer_ni_recovq(-1, &show_rc, &err_rc);
1381                         break;
1382                 default:
1383                         return 0;
1384                 }
1385         }
1386
1387         if (rc != LUSTRE_CFG_RC_NO_ERR)
1388                 cYAML_print_tree2file(stderr, err_rc);
1389         else if (show_rc)
1390                 cYAML_print_tree(show_rc);
1391
1392         cYAML_free_tree(err_rc);
1393         cYAML_free_tree(show_rc);
1394
1395         return rc;
1396 }
1397
1398 static int jt_show_net(int argc, char **argv)
1399 {
1400         char *network = NULL;
1401         int rc, opt;
1402         struct cYAML *err_rc = NULL, *show_rc = NULL;
1403         long int detail = 0;
1404
1405         const char *const short_options = "n:v";
1406         static const struct option long_options[] = {
1407                 { .name = "net",     .has_arg = required_argument, .val = 'n' },
1408                 { .name = "verbose", .has_arg = optional_argument, .val = 'v' },
1409                 { .name = NULL } };
1410
1411         rc = check_cmd(net_cmds, "net", "show", 0, argc, argv);
1412         if (rc)
1413                 return rc;
1414
1415         while ((opt = getopt_long(argc, argv, short_options,
1416                                    long_options, NULL)) != -1) {
1417                 switch (opt) {
1418                 case 'n':
1419                         network = optarg;
1420                         break;
1421                 case 'v':
1422                         if ((!optarg) && (argv[optind] != NULL) &&
1423                             (argv[optind][0] != '-')) {
1424                                 if (parse_long(argv[optind++], &detail) != 0)
1425                                         detail = 1;
1426                         } else {
1427                                 detail = 1;
1428                         }
1429                         break;
1430                 case '?':
1431                         print_help(net_cmds, "net", "show");
1432                 default:
1433                         return 0;
1434                 }
1435         }
1436
1437         rc = lustre_lnet_show_net(network, (int) detail, -1, &show_rc, &err_rc,
1438                                   false);
1439
1440         if (rc != LUSTRE_CFG_RC_NO_ERR)
1441                 cYAML_print_tree2file(stderr, err_rc);
1442         else if (show_rc)
1443                 cYAML_print_tree(show_rc);
1444
1445         cYAML_free_tree(err_rc);
1446         cYAML_free_tree(show_rc);
1447
1448         return rc;
1449 }
1450
1451 static int jt_show_routing(int argc, char **argv)
1452 {
1453         struct cYAML *err_rc = NULL, *show_rc = NULL;
1454         int rc;
1455
1456         rc = check_cmd(routing_cmds, "routing", "show", 0, argc, argv);
1457         if (rc)
1458                 return rc;
1459
1460         rc = lustre_lnet_show_routing(-1, &show_rc, &err_rc, false);
1461
1462         if (rc != LUSTRE_CFG_RC_NO_ERR)
1463                 cYAML_print_tree2file(stderr, err_rc);
1464         else if (show_rc)
1465                 cYAML_print_tree(show_rc);
1466
1467         cYAML_free_tree(err_rc);
1468         cYAML_free_tree(show_rc);
1469
1470         return rc;
1471 }
1472
1473 static int jt_show_stats(int argc, char **argv)
1474 {
1475         int rc;
1476         struct cYAML *show_rc = NULL, *err_rc = NULL;
1477
1478         rc = check_cmd(stats_cmds, "stats", "show", 0, argc, argv);
1479         if (rc)
1480                 return rc;
1481
1482         rc = lustre_lnet_show_stats(-1, &show_rc, &err_rc);
1483
1484         if (rc != LUSTRE_CFG_RC_NO_ERR)
1485                 cYAML_print_tree2file(stderr, err_rc);
1486         else if (show_rc)
1487                 cYAML_print_tree(show_rc);
1488
1489         cYAML_free_tree(err_rc);
1490         cYAML_free_tree(show_rc);
1491
1492         return rc;
1493 }
1494
1495 static int jt_show_udsp(int argc, char **argv)
1496 {
1497         int idx = -1;
1498         int rc, opt;
1499         struct cYAML *err_rc = NULL, *show_rc = NULL;
1500
1501         const char *const short_options = "i:";
1502         static const struct option long_options[] = {
1503                 { .name = "idx", .has_arg = required_argument, .val = 'i' },
1504                 { .name = NULL }
1505         };
1506
1507         rc = check_cmd(udsp_cmds, "udsp", "show", 0, argc, argv);
1508         if (rc)
1509                 return rc;
1510
1511         while ((opt = getopt_long(argc, argv, short_options,
1512                                    long_options, NULL)) != -1) {
1513                 switch (opt) {
1514                 case 'i':
1515                         idx = atoi(optarg);
1516                         break;
1517                 case '?':
1518                         print_help(net_cmds, "net", "show");
1519                 default:
1520                         return 0;
1521                 }
1522         }
1523
1524         rc = lustre_lnet_show_udsp(idx, -1, &show_rc, &err_rc);
1525
1526         if (rc != LUSTRE_CFG_RC_NO_ERR)
1527                 cYAML_print_tree2file(stderr, err_rc);
1528         else if (show_rc)
1529                 cYAML_print_tree(show_rc);
1530
1531         cYAML_free_tree(err_rc);
1532         cYAML_free_tree(show_rc);
1533
1534         return rc;
1535 }
1536
1537 static int jt_show_global(int argc, char **argv)
1538 {
1539         int rc;
1540         struct cYAML *show_rc = NULL, *err_rc = NULL;
1541
1542         rc = check_cmd(global_cmds, "global", "show", 0, argc, argv);
1543         if (rc)
1544                 return rc;
1545
1546         rc = lustre_lnet_show_numa_range(-1, &show_rc, &err_rc);
1547         if (rc != LUSTRE_CFG_RC_NO_ERR) {
1548                 cYAML_print_tree2file(stderr, err_rc);
1549                 goto out;
1550         }
1551
1552         rc = lustre_lnet_show_max_intf(-1, &show_rc, &err_rc);
1553         if (rc != LUSTRE_CFG_RC_NO_ERR) {
1554                 cYAML_print_tree2file(stderr, err_rc);
1555                 goto out;
1556         }
1557
1558         rc = lustre_lnet_show_discovery(-1, &show_rc, &err_rc);
1559         if (rc != LUSTRE_CFG_RC_NO_ERR) {
1560                 cYAML_print_tree2file(stderr, err_rc);
1561                 goto out;
1562         }
1563
1564         rc = lustre_lnet_show_drop_asym_route(-1, &show_rc, &err_rc);
1565         if (rc != LUSTRE_CFG_RC_NO_ERR) {
1566                 cYAML_print_tree2file(stderr, err_rc);
1567                 goto out;
1568         }
1569
1570         rc = lustre_lnet_show_retry_count(-1, &show_rc, &err_rc);
1571         if (rc != LUSTRE_CFG_RC_NO_ERR) {
1572                 cYAML_print_tree2file(stderr, err_rc);
1573                 goto out;
1574         }
1575
1576         rc = lustre_lnet_show_transaction_to(-1, &show_rc, &err_rc);
1577         if (rc != LUSTRE_CFG_RC_NO_ERR) {
1578                 cYAML_print_tree2file(stderr, err_rc);
1579                 goto out;
1580         }
1581
1582         rc = lustre_lnet_show_hsensitivity(-1, &show_rc, &err_rc);
1583         if (rc != LUSTRE_CFG_RC_NO_ERR) {
1584                 cYAML_print_tree2file(stderr, err_rc);
1585                 goto out;
1586         }
1587
1588         rc = lustre_lnet_show_recov_intrv(-1, &show_rc, &err_rc);
1589         if (rc != LUSTRE_CFG_RC_NO_ERR) {
1590                 cYAML_print_tree2file(stderr, err_rc);
1591                 goto out;
1592         }
1593
1594         rc = lustre_lnet_show_rtr_sensitivity(-1, &show_rc, &err_rc);
1595         if (rc != LUSTRE_CFG_RC_NO_ERR) {
1596                 cYAML_print_tree2file(stderr, err_rc);
1597                 goto out;
1598         }
1599
1600         rc = lustre_lnet_show_lnd_timeout(-1, &show_rc, &err_rc);
1601         if (rc != LUSTRE_CFG_RC_NO_ERR) {
1602                 cYAML_print_tree2file(stderr, err_rc);
1603                 goto out;
1604         }
1605
1606         rc = lustre_lnet_show_response_tracking(-1, &show_rc, &err_rc);
1607         if (rc != LUSTRE_CFG_RC_NO_ERR) {
1608                 cYAML_print_tree2file(stderr, err_rc);
1609                 goto out;
1610         }
1611
1612         rc = lustre_lnet_show_recovery_limit(-1, &show_rc, &err_rc);
1613         if (rc != LUSTRE_CFG_RC_NO_ERR) {
1614                 cYAML_print_tree2file(stderr, err_rc);
1615                 goto out;
1616         }
1617
1618         if (show_rc)
1619                 cYAML_print_tree(show_rc);
1620
1621 out:
1622         cYAML_free_tree(err_rc);
1623         cYAML_free_tree(show_rc);
1624
1625         return rc;
1626 }
1627
1628 static int jt_lnet(int argc, char **argv)
1629 {
1630         int rc;
1631
1632         rc = check_cmd(lnet_cmds, "lnet", NULL, 2, argc, argv);
1633         if (rc)
1634                 return rc;
1635
1636         return Parser_execarg(argc - 1, &argv[1], lnet_cmds);
1637 }
1638
1639 static int jt_route(int argc, char **argv)
1640 {
1641         int rc;
1642
1643         rc = check_cmd(route_cmds, "route", NULL, 2, argc, argv);
1644         if (rc)
1645                 return rc;
1646
1647         return Parser_execarg(argc - 1, &argv[1], route_cmds);
1648 }
1649
1650 static int jt_net(int argc, char **argv)
1651 {
1652         int rc;
1653
1654         rc = check_cmd(net_cmds, "net", NULL, 2, argc, argv);
1655         if (rc)
1656                 return rc;
1657
1658         return Parser_execarg(argc - 1, &argv[1], net_cmds);
1659 }
1660
1661 static int jt_routing(int argc, char **argv)
1662 {
1663         int rc;
1664
1665         rc = check_cmd(routing_cmds, "routing", NULL, 2, argc, argv);
1666         if (rc)
1667                 return rc;
1668
1669         return Parser_execarg(argc - 1, &argv[1], routing_cmds);
1670 }
1671
1672 static int jt_stats(int argc, char **argv)
1673 {
1674         int rc;
1675
1676         rc = check_cmd(stats_cmds, "stats", NULL, 2, argc, argv);
1677         if (rc)
1678                 return rc;
1679
1680         return Parser_execarg(argc - 1, &argv[1], stats_cmds);
1681 }
1682
1683 static int jt_debug(int argc, char **argv)
1684 {
1685         int rc;
1686
1687         rc = check_cmd(debug_cmds, "recovery", NULL, 2, argc, argv);
1688         if (rc)
1689                 return rc;
1690
1691         return Parser_execarg(argc - 1, &argv[1], debug_cmds);
1692 }
1693
1694 static int jt_global(int argc, char **argv)
1695 {
1696         int rc;
1697
1698         rc = check_cmd(global_cmds, "global", NULL, 2, argc, argv);
1699         if (rc)
1700                 return rc;
1701
1702         return Parser_execarg(argc - 1, &argv[1], global_cmds);
1703 }
1704
1705 static int jt_peers(int argc, char **argv)
1706 {
1707         int rc;
1708
1709         rc = check_cmd(peer_cmds, "peer", NULL, 2, argc, argv);
1710         if (rc)
1711                 return rc;
1712
1713         return Parser_execarg(argc - 1, &argv[1], peer_cmds);
1714 }
1715
1716 static int jt_set(int argc, char **argv)
1717 {
1718         int rc;
1719
1720         rc = check_cmd(set_cmds, "set", NULL, 2, argc, argv);
1721         if (rc)
1722                 return rc;
1723
1724         return Parser_execarg(argc - 1, &argv[1], set_cmds);
1725 }
1726
1727 static int jt_udsp(int argc, char **argv)
1728 {
1729         int rc;
1730
1731         rc = check_cmd(udsp_cmds, "udsp", NULL, 2, argc, argv);
1732         if (rc)
1733                 return rc;
1734
1735         return Parser_execarg(argc - 1, &argv[1], udsp_cmds);
1736 }
1737
1738 static int jt_import(int argc, char **argv)
1739 {
1740         char *file = NULL;
1741         struct cYAML *err_rc = NULL;
1742         struct cYAML *show_rc = NULL;
1743         int rc = 0, return_rc = 0, opt, opt_found = 0;
1744         char cmd = 'a';
1745
1746         const char *const short_options = "adseh";
1747         static const struct option long_options[] = {
1748                 { .name = "add",  .has_arg = no_argument, .val = 'a' },
1749                 { .name = "del",  .has_arg = no_argument, .val = 'd' },
1750                 { .name = "show", .has_arg = no_argument, .val = 's' },
1751                 { .name = "exec", .has_arg = no_argument, .val = 'e' },
1752                 { .name = "help", .has_arg = no_argument, .val = 'h' },
1753                 { .name = NULL } };
1754
1755         while ((opt = getopt_long(argc, argv, short_options,
1756                                    long_options, NULL)) != -1) {
1757                 opt_found = 1;
1758                 switch (opt) {
1759                 case 'a':
1760                         cmd = opt;
1761                         break;
1762                 case 'd':
1763                 case 's':
1764                         cmd = opt;
1765                         break;
1766                 case 'e':
1767                         cmd = opt;
1768                         break;
1769                 case 'h':
1770                         printf("import FILE\n"
1771                                "import < FILE : import a file\n"
1772                                "\t--add: add configuration\n"
1773                                "\t--del: delete configuration\n"
1774                                "\t--show: show configuration\n"
1775                                "\t--exec: execute command\n"
1776                                "\t--help: display this help\n"
1777                                "If no command option is given then --add"
1778                                " is assumed by default\n");
1779                         return 0;
1780                 default:
1781                         return 0;
1782                 }
1783         }
1784
1785         /* grab the file name if one exists */
1786         if (opt_found && argc == 3)
1787                 file = argv[2];
1788         else if (!opt_found && argc == 2)
1789                 file = argv[1];
1790
1791         switch (cmd) {
1792         case 'a':
1793                 rc = lustre_yaml_config(file, &err_rc);
1794                 return_rc = lustre_yaml_exec(file, &show_rc, &err_rc);
1795                 cYAML_print_tree(show_rc);
1796                 cYAML_free_tree(show_rc);
1797                 break;
1798         case 'd':
1799                 rc = lustre_yaml_del(file, &err_rc);
1800                 break;
1801         case 's':
1802                 rc = lustre_yaml_show(file, &show_rc, &err_rc);
1803                 cYAML_print_tree(show_rc);
1804                 cYAML_free_tree(show_rc);
1805                 break;
1806         case 'e':
1807                 rc = lustre_yaml_exec(file, &show_rc, &err_rc);
1808                 cYAML_print_tree(show_rc);
1809                 cYAML_free_tree(show_rc);
1810                 break;
1811         }
1812
1813         if (rc || return_rc) {
1814                 cYAML_print_tree2file(stderr, err_rc);
1815                 cYAML_free_tree(err_rc);
1816         }
1817
1818         return rc;
1819 }
1820
1821 static int jt_export(int argc, char **argv)
1822 {
1823         struct cYAML *show_rc = NULL;
1824         struct cYAML *err_rc = NULL;
1825         int rc;
1826         FILE *f = NULL;
1827         int opt;
1828         bool backup = false;
1829         char *file = NULL;
1830
1831         const char *const short_options = "bh";
1832         static const struct option long_options[] = {
1833                 { .name = "backup", .has_arg = no_argument, .val = 'b' },
1834                 { .name = "help", .has_arg = no_argument, .val = 'h' },
1835                 { .name = NULL } };
1836
1837         while ((opt = getopt_long(argc, argv, short_options,
1838                                    long_options, NULL)) != -1) {
1839                 switch (opt) {
1840                 case 'b':
1841                         backup = true;
1842                         break;
1843                 case 'h':
1844                 default:
1845                         printf("export > FILE.yaml : export configuration\n"
1846                                "\t--backup: export only what's necessary for reconfig\n"
1847                                "\t--help: display this help\n");
1848                         return 0;
1849                 }
1850         }
1851
1852         if (backup && argc >= 3)
1853                 file = argv[2];
1854         else if (!backup && argc >= 2)
1855                 file = argv[1];
1856         else
1857                 f = stdout;
1858
1859         if (file) {
1860                 f = fopen(file, "w");
1861                 if (f == NULL)
1862                         return -1;
1863         }
1864
1865         rc = lustre_lnet_show_net(NULL, 2, -1, &show_rc, &err_rc, backup);
1866         if (rc != LUSTRE_CFG_RC_NO_ERR) {
1867                 cYAML_print_tree2file(stderr, err_rc);
1868                 cYAML_free_tree(err_rc);
1869                 err_rc = NULL;
1870         }
1871
1872         rc = lustre_lnet_show_route(NULL, NULL, -1, -1, 1, -1, &show_rc,
1873                                     &err_rc, backup);
1874         if (rc != LUSTRE_CFG_RC_NO_ERR) {
1875                 cYAML_print_tree2file(stderr, err_rc);
1876                 cYAML_free_tree(err_rc);
1877                 err_rc = NULL;
1878         }
1879
1880         rc = lustre_lnet_show_routing(-1, &show_rc, &err_rc, backup);
1881         if (rc != LUSTRE_CFG_RC_NO_ERR) {
1882                 cYAML_print_tree2file(stderr, err_rc);
1883                 cYAML_free_tree(err_rc);
1884                 err_rc = NULL;
1885         }
1886
1887         rc = lustre_lnet_show_peer(NULL, 2, -1, &show_rc, &err_rc, backup);
1888         if (rc != LUSTRE_CFG_RC_NO_ERR) {
1889                 cYAML_print_tree2file(stderr, err_rc);
1890                 cYAML_free_tree(err_rc);
1891                 err_rc = NULL;
1892         }
1893
1894         rc = lustre_lnet_show_numa_range(-1, &show_rc, &err_rc);
1895         if (rc != LUSTRE_CFG_RC_NO_ERR) {
1896                 cYAML_print_tree2file(stderr, err_rc);
1897                 cYAML_free_tree(err_rc);
1898                 err_rc = NULL;
1899         }
1900
1901         rc = lustre_lnet_show_max_intf(-1, &show_rc, &err_rc);
1902         if (rc != LUSTRE_CFG_RC_NO_ERR) {
1903                 cYAML_print_tree2file(stderr, err_rc);
1904                 cYAML_free_tree(err_rc);
1905                 err_rc = NULL;
1906         }
1907
1908         rc = lustre_lnet_show_discovery(-1, &show_rc, &err_rc);
1909         if (rc != LUSTRE_CFG_RC_NO_ERR) {
1910                 cYAML_print_tree2file(stderr, err_rc);
1911                 cYAML_free_tree(err_rc);
1912                 err_rc = NULL;
1913         }
1914
1915         rc = lustre_lnet_show_drop_asym_route(-1, &show_rc, &err_rc);
1916         if (rc != LUSTRE_CFG_RC_NO_ERR) {
1917                 cYAML_print_tree2file(stderr, err_rc);
1918                 cYAML_free_tree(err_rc);
1919                 err_rc = NULL;
1920         }
1921
1922         rc = lustre_lnet_show_retry_count(-1, &show_rc, &err_rc);
1923         if (rc != LUSTRE_CFG_RC_NO_ERR) {
1924                 cYAML_print_tree2file(stderr, err_rc);
1925                 err_rc = NULL;
1926         }
1927
1928         rc = lustre_lnet_show_transaction_to(-1, &show_rc, &err_rc);
1929         if (rc != LUSTRE_CFG_RC_NO_ERR) {
1930                 cYAML_print_tree2file(stderr, err_rc);
1931                 err_rc = NULL;
1932         }
1933
1934         rc = lustre_lnet_show_hsensitivity(-1, &show_rc, &err_rc);
1935         if (rc != LUSTRE_CFG_RC_NO_ERR) {
1936                 cYAML_print_tree2file(stderr, err_rc);
1937                 err_rc = NULL;
1938         }
1939
1940         rc = lustre_lnet_show_recov_intrv(-1, &show_rc, &err_rc);
1941         if (rc != LUSTRE_CFG_RC_NO_ERR) {
1942                 cYAML_print_tree2file(stderr, err_rc);
1943                 err_rc = NULL;
1944         }
1945
1946         rc = lustre_lnet_show_rtr_sensitivity(-1, &show_rc, &err_rc);
1947         if (rc != LUSTRE_CFG_RC_NO_ERR) {
1948                 cYAML_print_tree2file(stderr, err_rc);
1949                 err_rc = NULL;
1950         }
1951
1952         rc = lustre_lnet_show_lnd_timeout(-1, &show_rc, &err_rc);
1953         if (rc != LUSTRE_CFG_RC_NO_ERR) {
1954                 cYAML_print_tree2file(stderr, err_rc);
1955                 err_rc = NULL;
1956         }
1957
1958         rc = lustre_lnet_show_response_tracking(-1, &show_rc, &err_rc);
1959         if (rc != LUSTRE_CFG_RC_NO_ERR) {
1960                 cYAML_print_tree2file(stderr, err_rc);
1961                 cYAML_free_tree(err_rc);
1962                 err_rc = NULL;
1963         }
1964
1965         rc = lustre_lnet_show_recovery_limit(-1, &show_rc, &err_rc);
1966         if (rc != LUSTRE_CFG_RC_NO_ERR) {
1967                 cYAML_print_tree2file(stderr, err_rc);
1968                 cYAML_free_tree(err_rc);
1969                 err_rc = NULL;
1970         }
1971
1972         rc = lustre_lnet_show_udsp(-1, -1, &show_rc, &err_rc);
1973         if (rc != LUSTRE_CFG_RC_NO_ERR) {
1974                 cYAML_print_tree2file(stderr, err_rc);
1975                 cYAML_free_tree(err_rc);
1976                 err_rc = NULL;
1977         }
1978
1979         if (show_rc != NULL) {
1980                 cYAML_print_tree2file(f, show_rc);
1981                 cYAML_free_tree(show_rc);
1982         }
1983
1984         if (argc >= 2)
1985                 fclose(f);
1986
1987         return 0;
1988 }
1989
1990 static int jt_peer_nid_common(int argc, char **argv, int cmd)
1991 {
1992         int rc = LUSTRE_CFG_RC_NO_ERR, opt;
1993         bool is_mr = true;
1994         char *prim_nid = NULL, *nidstr = NULL;
1995         char err_str[LNET_MAX_STR_LEN] = "Error";
1996         struct cYAML *err_rc = NULL;
1997
1998         const char *const short_opts = "k:mn:";
1999         const struct option long_opts[] = {
2000         { .name = "prim_nid",   .has_arg = required_argument,   .val = 'k' },
2001         { .name = "non_mr",     .has_arg = no_argument,         .val = 'm' },
2002         { .name = "nid",        .has_arg = required_argument,   .val = 'n' },
2003         { .name = NULL } };
2004
2005         rc = check_cmd(peer_cmds, "peer", "add", 2, argc, argv);
2006         if (rc)
2007                 return rc;
2008
2009         while ((opt = getopt_long(argc, argv, short_opts,
2010                                   long_opts, NULL)) != -1) {
2011                 switch (opt) {
2012                 case 'k':
2013                         prim_nid = optarg;
2014                         break;
2015                 case 'n':
2016                         nidstr = optarg;
2017                         break;
2018                 case 'm':
2019                         if (cmd == LNETCTL_DEL_CMD) {
2020                                 rc = LUSTRE_CFG_RC_BAD_PARAM;
2021                                 snprintf(err_str, LNET_MAX_STR_LEN,
2022                                          "Unrecognized option '-%c'", opt);
2023                                 goto build_error;
2024                         }
2025                         is_mr = false;
2026                         break;
2027                 case '?':
2028                         print_help(peer_cmds, "peer",
2029                                    cmd == LNETCTL_ADD_CMD ? "add" : "del");
2030                 default:
2031                         return 0;
2032                 }
2033         }
2034
2035         rc = lustre_lnet_modify_peer(prim_nid, nidstr, is_mr, cmd,
2036                                      -1, &err_rc);
2037         if (rc != LUSTRE_CFG_RC_NO_ERR)
2038                 goto out;
2039
2040 build_error:
2041         cYAML_build_error(rc, -1, "peer",
2042                           cmd == LNETCTL_ADD_CMD ? "add" : "del",
2043                           err_str, &err_rc);
2044
2045 out:
2046         if (rc != LUSTRE_CFG_RC_NO_ERR)
2047                 cYAML_print_tree2file(stderr, err_rc);
2048
2049         cYAML_free_tree(err_rc);
2050
2051         return rc;
2052 }
2053
2054 static int jt_add_peer_nid(int argc, char **argv)
2055 {
2056         return jt_peer_nid_common(argc, argv, LNETCTL_ADD_CMD);
2057 }
2058
2059 static int jt_del_peer_nid(int argc, char **argv)
2060 {
2061         return jt_peer_nid_common(argc, argv, LNETCTL_DEL_CMD);
2062 }
2063
2064 static int jt_show_peer(int argc, char **argv)
2065 {
2066         char *nid = NULL;
2067         int rc, opt;
2068         struct cYAML *err_rc = NULL, *show_rc = NULL;
2069         long int detail = 0;
2070
2071         const char *const short_opts = "hn:v::";
2072         const struct option long_opts[] = {
2073         { .name = "help",       .has_arg = no_argument,         .val = 'h' },
2074         { .name = "nid",        .has_arg = required_argument,   .val = 'n' },
2075         { .name = "verbose",    .has_arg = optional_argument,   .val = 'v' },
2076         { .name = NULL } };
2077
2078         rc = check_cmd(peer_cmds, "peer", "show", 1, argc, argv);
2079         if (rc)
2080                 return rc;
2081
2082         while ((opt = getopt_long(argc, argv, short_opts,
2083                                   long_opts, NULL)) != -1) {
2084                 switch (opt) {
2085                 case 'n':
2086                         nid = optarg;
2087                         break;
2088                 case 'v':
2089                         if ((!optarg) && (argv[optind] != NULL) &&
2090                             (argv[optind][0] != '-')) {
2091                                 if (parse_long(argv[optind++], &detail) != 0)
2092                                         detail = 1;
2093                         } else {
2094                                 detail = 1;
2095                         }
2096                         break;
2097                 case '?':
2098                         print_help(peer_cmds, "peer", "show");
2099                 default:
2100                         return 0;
2101                 }
2102         }
2103
2104         rc = lustre_lnet_show_peer(nid, (int) detail, -1, &show_rc, &err_rc,
2105                                    false);
2106
2107         if (rc != LUSTRE_CFG_RC_NO_ERR)
2108                 cYAML_print_tree2file(stderr, err_rc);
2109         else if (show_rc)
2110                 cYAML_print_tree(show_rc);
2111
2112         cYAML_free_tree(err_rc);
2113         cYAML_free_tree(show_rc);
2114
2115         return rc;
2116 }
2117
2118 static int jt_list_peer(int argc, char **argv)
2119 {
2120         int rc;
2121         struct cYAML *err_rc = NULL, *list_rc = NULL;
2122
2123         rc = check_cmd(peer_cmds, "peer", "list", 0, argc, argv);
2124         if (rc)
2125                 return rc;
2126
2127         rc = lustre_lnet_list_peer(-1, &list_rc, &err_rc);
2128
2129         if (rc != LUSTRE_CFG_RC_NO_ERR)
2130                 cYAML_print_tree2file(stderr, err_rc);
2131         else if (list_rc)
2132                 cYAML_print_tree(list_rc);
2133
2134         cYAML_free_tree(err_rc);
2135         cYAML_free_tree(list_rc);
2136
2137         return rc;
2138 }
2139
2140 static int jt_ping(int argc, char **argv)
2141 {
2142         struct cYAML *err_rc = NULL;
2143         struct cYAML *show_rc = NULL;
2144         int timeout = 1000;
2145         int rc = 0, opt;
2146
2147         const char *const short_options = "ht:";
2148         const struct option long_options[] = {
2149         { .name = "help",       .has_arg = no_argument,         .val = 'h' },
2150         { .name = "timeout",    .has_arg = required_argument,   .val = 't' },
2151         { .name = NULL } };
2152
2153         while ((opt = getopt_long(argc, argv, short_options,
2154                                   long_options, NULL)) != -1) {
2155                 switch (opt) {
2156                 case 't':
2157                         timeout = 1000 * atol(optarg);
2158                         break;
2159                 case 'h':
2160                         printf("ping nid[,nid,...]\n"
2161                                "\t --timeout: ping timeout\n"
2162                                "\t --help: display this help\n");
2163                         return 0;
2164                 default:
2165                         return 0;
2166                 }
2167         }
2168
2169         for (; optind < argc; optind++)
2170                 rc = lustre_lnet_ping_nid(argv[optind], timeout, -1, &show_rc, &err_rc);
2171
2172         if (show_rc)
2173                 cYAML_print_tree(show_rc);
2174
2175         if (err_rc)
2176                 cYAML_print_tree2file(stderr, err_rc);
2177
2178         cYAML_free_tree(err_rc);
2179         cYAML_free_tree(show_rc);
2180
2181         return rc;
2182 }
2183
2184 static int jt_discover(int argc, char **argv)
2185 {
2186         struct cYAML *err_rc = NULL;
2187         struct cYAML *show_rc = NULL;
2188         int force = 0;
2189         int rc = 0, opt;
2190
2191         const char *const short_options = "fh";
2192         const struct option long_options[] = {
2193                 { .name = "force",      .has_arg = no_argument, .val = 'f' },
2194                 { .name = "help",       .has_arg = no_argument, .val = 'h' },
2195                 { .name = NULL } };
2196
2197         while ((opt = getopt_long(argc, argv, short_options,
2198                                   long_options, NULL)) != -1) {
2199                 switch (opt) {
2200                 case 'f':
2201                         force = 1;
2202                         break;
2203                 case 'h':
2204                         printf("discover nid[,nid,...]\n"
2205                                "\t --force: force discovery\n"
2206                                "\t --help: display this help\n");
2207                         return 0;
2208                 default:
2209                         return 0;
2210                 }
2211         }
2212
2213         for (; optind < argc; optind++)
2214                 rc = lustre_lnet_discover_nid(argv[optind], force, -1, &show_rc,
2215                                               &err_rc);
2216
2217         if (show_rc)
2218                 cYAML_print_tree(show_rc);
2219
2220         if (err_rc)
2221                 cYAML_print_tree2file(stderr, err_rc);
2222
2223         cYAML_free_tree(err_rc);
2224         cYAML_free_tree(show_rc);
2225
2226         return rc;
2227 }
2228
2229 static int jt_add_udsp(int argc, char **argv)
2230 {
2231         char *src = NULL, *dst = NULL, *rte = NULL;
2232         struct cYAML *err_rc = NULL;
2233         union lnet_udsp_action udsp_action;
2234         long int idx = -1, priority = -1;
2235         int opt, rc = 0;
2236         char *action_type = "pref";
2237
2238         const char *const short_options = "s:d:r:p:i:";
2239         static const struct option long_options[] = {
2240         { .name = "src",         .has_arg = required_argument, .val = 's' },
2241         { .name = "dst",         .has_arg = required_argument, .val = 'd' },
2242         { .name = "rte",         .has_arg = required_argument, .val = 'r' },
2243         { .name = "priority",    .has_arg = required_argument, .val = 'p' },
2244         { .name = "idx",         .has_arg = required_argument, .val = 'i' },
2245         { .name = NULL } };
2246
2247         rc = check_cmd(udsp_cmds, "udsp", "add", 0, argc, argv);
2248         if (rc)
2249                 return rc;
2250
2251         while ((opt = getopt_long(argc, argv, short_options,
2252                                   long_options, NULL)) != -1) {
2253                 switch (opt) {
2254                 case 's':
2255                         src = optarg;
2256                         break;
2257                 case 'd':
2258                         dst = optarg;
2259                         break;
2260                 case 'r':
2261                         rte = optarg;
2262                         break;
2263                 case 'p':
2264                         rc = parse_long(optarg, &priority);
2265                         if (rc != 0)
2266                                 priority = -1;
2267                         action_type = "priority";
2268                         udsp_action.udsp_priority = priority;
2269                         break;
2270                 case 'i':
2271                         rc = parse_long(optarg, &idx);
2272                         if (rc != 0)
2273                                 idx = 0;
2274                         break;
2275                 case '?':
2276                         print_help(udsp_cmds, "udsp", "add");
2277                 default:
2278                         return 0;
2279                 }
2280         }
2281
2282         rc = lustre_lnet_add_udsp(src, dst, rte, action_type, &udsp_action,
2283                                   idx, -1, &err_rc);
2284
2285         if (rc != LUSTRE_CFG_RC_NO_ERR)
2286                 cYAML_print_tree2file(stderr, err_rc);
2287
2288         cYAML_free_tree(err_rc);
2289
2290         return rc;
2291 }
2292
2293 static int jt_del_udsp(int argc, char **argv)
2294 {
2295         struct cYAML *err_rc = NULL;
2296         long int idx = 0;
2297         int opt, rc = 0;
2298
2299         const char *const short_options = "i:";
2300         static const struct option long_options[] = {
2301         { .name = "idx",        .has_arg = required_argument, .val = 'i' },
2302         { .name = NULL } };
2303
2304         rc = check_cmd(udsp_cmds, "udsp", "del", 0, argc, argv);
2305         if (rc)
2306                 return rc;
2307
2308         while ((opt = getopt_long(argc, argv, short_options,
2309                                   long_options, NULL)) != -1) {
2310                 switch (opt) {
2311                 case 'i':
2312                         rc = parse_long(optarg, &idx);
2313                         if (rc != 0)
2314                                 idx = 0;
2315                         break;
2316                 case '?':
2317                         print_help(udsp_cmds, "udsp", "add");
2318                 default:
2319                         return 0;
2320                 }
2321         }
2322
2323         rc = lustre_lnet_del_udsp(idx, -1, &err_rc);
2324         if (rc != LUSTRE_CFG_RC_NO_ERR)
2325                 cYAML_print_tree2file(stderr, err_rc);
2326
2327         cYAML_free_tree(err_rc);
2328
2329         return rc;
2330 }
2331
2332 static int lnetctl_list_commands(int argc, char **argv)
2333 {
2334         char buffer[81] = ""; /* 80 printable chars + terminating NUL */
2335
2336         Parser_list_commands(cmd_list, buffer, sizeof(buffer), NULL, 0, 4);
2337
2338         return 0;
2339 }
2340
2341 int main(int argc, char **argv)
2342 {
2343         int rc = 0;
2344         struct cYAML *err_rc = NULL;
2345
2346         rc = lustre_lnet_config_lib_init();
2347         if (rc < 0) {
2348                 cYAML_build_error(-1, -1, "lnetctl", "startup",
2349                                   "cannot register LNet device", &err_rc);
2350                 cYAML_print_tree2file(stderr, err_rc);
2351                 return rc;
2352         }
2353
2354         Parser_init("lnetctl > ", cmd_list);
2355         if (argc > 1) {
2356                 rc = Parser_execarg(argc - 1, &argv[1], cmd_list);
2357                 goto errorout;
2358         }
2359
2360         Parser_commands();
2361
2362 errorout:
2363         return rc;
2364 }