Whamcloud - gitweb
LU-16998 lnet: Error when missing discover arg
[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_set_max_recovery_ping_interval(int argc, char **argv);
64 static int jt_reset_stats(int argc, char **argv);
65 static int jt_add_peer_nid(int argc, char **argv);
66 static int jt_del_peer_nid(int argc, char **argv);
67 static int jt_set_max_intf(int argc, char **argv);
68 static int jt_set_discovery(int argc, char **argv);
69 static int jt_set_drop_asym_route(int argc, char **argv);
70 static int jt_list_peer(int argc, char **argv);
71 static int jt_add_udsp(int argc, char **argv);
72 static int jt_del_udsp(int argc, char **argv);
73 /*static int jt_show_peer(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 static int jt_setup_mrrouting(int argc, char **argv);
94 static int jt_calc_cpt_of_nid(int argc, char **argv);
95 static int jt_show_peer_debug_info(int argc, char **argv);
96
97 command_t cmd_list[] = {
98         {"lnet", jt_lnet, 0, "lnet {configure | unconfigure} [--all]"},
99         {"route", jt_route, 0, "route {add | del | show | help}"},
100         {"net", jt_net, 0, "net {add | del | show | set | help}"},
101         {"routing", jt_routing, 0, "routing {show | help}"},
102         {"set", jt_set, 0, "set {tiny_buffers | small_buffers | large_buffers"
103                            " | routing | numa_range | max_interfaces"
104                            " | discovery | drop_asym_route | retry_count"
105                            " | transaction_timeout | health_sensitivity"
106                            " | recovery_interval | router_sensitivity"
107                            " | response_tracking | recovery_limit}"},
108         {"import", jt_import, 0, "import FILE.yaml"},
109         {"export", jt_export, 0, "export FILE.yaml"},
110         {"stats", jt_stats, 0, "stats {show | help}"},
111         {"debug", jt_debug, 0, "debug {recovery {local | peer} | peer}"},
112         {"global", jt_global, 0, "global {show | help}"},
113         {"peer", jt_peers, 0, "peer {add | del | show | list | set | help}"},
114         {"ping", jt_ping, 0, "ping nid,[nid,...]"},
115         {"discover", jt_discover, 0, "discover nid[,nid,...]"},
116         {"service-id", jt_calc_service_id, 0, "Calculate IB Lustre service ID\n"},
117         {"udsp", jt_udsp, 0, "udsp {add | del | help}"},
118         {"setup-mrrouting", jt_setup_mrrouting, 0,
119          "setup linux routing tables\n"},
120         {"cpt-of-nid", jt_calc_cpt_of_nid, 0, "Calculate the CPT associated with NID\n"
121          "\t--nid: NID to calculate the CPT of\n"
122          "\t--ncpt: Number of CPTs to consider in the calculation\n"},
123         { 0, 0, 0, NULL }
124 };
125
126 command_t lnet_cmds[] = {
127         {"configure", jt_config_lnet, 0, "configure lnet\n"
128          "\t--all: load NI configuration from module parameters\n"},
129         {"unconfigure", jt_unconfig_lnet, 0, "unconfigure lnet\n"},
130         { 0, 0, 0, NULL }
131 };
132
133 command_t route_cmds[] = {
134         {"add", jt_add_route, 0, "add a route\n"
135          "\t--net: net name (e.g. tcp0)\n"
136          "\t--gateway: gateway nid (e.g. 10.1.1.2@tcp)\n"
137          "\t--hop|hop-count: number to final destination (1 <= hops <= 255)\n"
138          "\t--priority: priority of route (0 - highest prio\n"
139          "\t--health_sensitivity: gateway health sensitivity (>= 1)\n"},
140         {"del", jt_del_route, 0, "delete a route\n"
141          "\t--net: net name (e.g. tcp0)\n"
142          "\t--gateway: gateway nid (e.g. 10.1.1.2@tcp)\n"},
143         {"show", jt_show_route, 0, "show routes\n"
144          "\t--net: net name (e.g. tcp0) to filter on\n"
145          "\t--gateway: gateway nid (e.g. 10.1.1.2@tcp) to filter on\n"
146          "\t--hop|hop-count: number to final destination (1 <= hops <= 255) to filter on\n"
147          "\t--priority: priority of route (0 - highest prio to filter on\n"
148          "\t--verbose: display detailed output per route\n"},
149         { 0, 0, 0, NULL }
150 };
151
152 command_t net_cmds[] = {
153         {"add", jt_add_ni, 0, "add a network\n"
154          "\t--net: net name (e.g. tcp0)\n"
155          "\t--if: physical interface (e.g. eth0)\n"
156          "\t--ip2net: specify networks based on IP address patterns\n"
157          "\t--peer-timeout: time to wait before declaring a peer dead\n"
158          "\t--peer-credits: define the max number of inflight messages\n"
159          "\t--peer-buffer-credits: the number of buffer credits per peer\n"
160          "\t--credits: Network Interface credits\n"
161          "\t--cpt: CPU Partitions configured net uses (e.g. [0,1]\n"
162          "\t--conns-per-peer: number of connections per peer\n"
163          "\t--skip-mr-route-setup: do not add linux route for the ni\n"
164          "\t--auth-key: Network authorization key (kfilnd only)\n"
165          "\t--traffic-class: Traffic class (kfilnd only)\n"},
166         {"del", jt_del_ni, 0, "delete a network\n"
167          "\t--net: net name (e.g. tcp0)\n"
168          "\t--if: physical interface (e.g. eth0)\n"},
169         {"show", jt_show_net, 0, "show networks\n"
170          "\t--net: net name (e.g. tcp0) to filter on\n"
171          "\t--verbose: display detailed output per network."
172                        " Optional argument of '2' outputs more stats\n"},
173         {"set", jt_set_ni_value, 0, "set local NI specific parameter\n"
174          "\t--nid: NI NID to set the\n"
175          "\t--health: specify health value to set\n"
176          "\t--conns-per-peer: number of connections per peer\n"
177          "\t--all: set all NIs value to the one specified\n"},
178         { 0, 0, 0, NULL }
179 };
180
181 command_t routing_cmds[] = {
182         {"show", jt_show_routing, 0, "show routing information\n"},
183         { 0, 0, 0, NULL }
184 };
185
186 command_t stats_cmds[] = {
187         {"show", jt_show_stats, 0, "show LNET statistics\n"},
188         {"reset", jt_reset_stats, 0, "reset LNET statistics\n"},
189         { 0, 0, 0, NULL }
190 };
191
192 command_t debug_cmds[] = {
193         {"recovery", jt_show_recovery, 0, "list recovery queues\n"
194                 "\t--local : list local recovery queue\n"
195                 "\t--peer : list peer recovery queue\n"},
196         {"peer", jt_show_peer_debug_info, 0, "show peer debug info\n"
197                 "\t--nid: peer's NID\n"},
198         { 0, 0, 0, NULL }
199 };
200
201 command_t global_cmds[] = {
202         {"show", jt_show_global, 0, "show global variables\n"},
203         { 0, 0, 0, NULL }
204 };
205
206 command_t set_cmds[] = {
207         {"tiny_buffers", jt_set_tiny, 0, "set tiny routing buffers\n"
208          "\tVALUE must be greater than 0\n"},
209         {"small_buffers", jt_set_small, 0, "set small routing buffers\n"
210          "\tVALUE must be greater than 0\n"},
211         {"large_buffers", jt_set_large, 0, "set large routing buffers\n"
212          "\tVALUE must be greater than 0\n"},
213         {"routing", jt_set_routing, 0, "enable/disable routing\n"
214          "\t0 - disable routing\n"
215          "\t1 - enable routing\n"},
216         {"numa_range", jt_set_numa, 0, "set NUMA range for NI selection\n"
217          "\tVALUE must be at least 0\n"},
218         {"max_interfaces", jt_set_max_intf, 0, "set the default value for "
219                 "max interfaces\n"
220          "\tValue must be greater than 16\n"},
221         {"discovery", jt_set_discovery, 0, "enable/disable peer discovery\n"
222          "\t0 - disable peer discovery\n"
223          "\t1 - enable peer discovery (default)\n"},
224         {"drop_asym_route", jt_set_drop_asym_route, 0,
225          "drop/accept asymmetrical route messages\n"
226          "\t0 - accept asymmetrical route messages (default)\n"
227          "\t1 - drop asymmetrical route messages\n"},
228         {"retry_count", jt_set_retry_count, 0, "number of retries\n"
229          "\t0 - turn of retries\n"
230          "\t>0 - number of retries\n"},
231         {"transaction_timeout", jt_set_transaction_to, 0, "Message/Response timeout\n"
232          "\t>0 - timeout in seconds\n"},
233         {"health_sensitivity", jt_set_hsensitivity, 0, "sensitivity to failure\n"
234          "\t0 - turn off health evaluation\n"
235          "\t>0 - sensitivity value not more than 1000\n"},
236         {"recovery_interval", jt_set_recov_intrv, 0, "interval to ping in seconds (at least 1)\n"
237          "\t>0 - time in seconds between pings\n"},
238         {"router_sensitivity", jt_set_rtr_sensitivity, 0, "router sensitivity %\n"
239          "\t100 - router interfaces need to be fully healthy to be used\n"
240          "\t<100 - router interfaces can be used even if not healthy\n"},
241         {"response_tracking", jt_set_response_tracking, 0,
242          "Set the behavior of response tracking\n"
243          "\t0 - Only LNet pings and discovery pushes utilize response tracking\n"
244          "\t1 - GETs are eligible for response tracking\n"
245          "\t2 - PUTs are eligible for response tracking\n"
246          "\t3 - Both PUTs and GETs are eligible for response tracking (default)\n"
247          "\tNote: Regardless of the value of the response_tracking parameter LNet\n"
248          "\t      pings and discovery pushes always utilize response tracking\n"},
249         {"recovery_limit", jt_set_recovery_limit, 0,
250          "Set how long LNet will attempt to recover unhealthy interfaces.\n"
251          "\t0 - Recover indefinitely (default)\n"
252          "\t>0 - Recover for the specified number of seconds.\n"},
253         {"max_recovery_ping_interval", jt_set_max_recovery_ping_interval, 0,
254          "maximum recovery ping interval\n"
255          "\t>0 - maximum recovery ping interval in seconds\n"},
256         { 0, 0, 0, NULL }
257 };
258
259 command_t peer_cmds[] = {
260         {"add", jt_add_peer_nid, 0, "add a peer NID\n"
261          "\t--prim_nid: Primary NID of the peer.\n"
262          "\t--nid: one or more peer NIDs\n"
263          "\t--non_mr: create this peer as not Multi-Rail capable\n"
264          "\t--ip2nets: specify a range of nids per peer\n"
265          "\t--lock_prim: lock primary nid\n"},
266         {"del", jt_del_peer_nid, 0, "delete a peer NID\n"
267          "\t--prim_nid: Primary NID of the peer.\n"
268          "\t--nid: list of NIDs to remove. If none provided,\n"
269          "\t       peer is deleted\n"
270          "\t--ip2nets: specify a range of nids per peer\n"
271          "\t--force: force-delete locked primary NID\n"},
272         {"show", jt_show_peer, 0, "show peer information\n"
273          "\t--nid: NID of peer to filter on.\n"
274          "\t--verbose: display detailed output per peer."
275                        " Optional argument of '2' outputs more stats\n"},
276         {"list", jt_list_peer, 0, "list all peers\n"},
277         {"set", jt_set_peer_ni_value, 0, "set peer ni specific parameter\n"
278          "\t--nid: Peer NI NID to set the\n"
279          "\t--health: specify health value to set\n"
280          "\t--all: set all peer_nis values to the one specified\n"
281          "\t--state: set peer state (DANGEROUS: for test/debug only)"},
282         { 0, 0, 0, NULL }
283 };
284
285 command_t udsp_cmds[] = {
286         {"add", jt_add_udsp, 0, "add a udsp\n"
287          "\t--src nid|net: ip2nets syntax specifying the local NID or network to match.\n"
288          "\t--dst nid:     ip2nets syntax specifying the remote NID to match.\n"
289          "\t--rte nid:     ip2nets syntax specifying the router NID to match.\n"
290          "\t--priority p:  Assign priority value p where p >= 0.\n"
291          "\t               Note: 0 is the highest priority.\n"
292          "\t--idx n:       Insert the rule in the n'th position on the list of rules.\n"
293          "\t               By default, rules are appended to the end of the rule list.\n"},
294         {"del", jt_del_udsp, 0, "delete a udsp\n"
295          "\t--all:   Delete all rules.\n"
296          "\t--idx n: Delete the rule at index n.\n"},
297         {"show", jt_show_udsp, 0, "show udsps\n"
298          "\t--idx n: Show the rule at at index n.\n"
299          "\t         By default, all rules are shown.\n"},
300         { 0, 0, 0, NULL }
301 };
302
303 static int parse_long(const char *number, long int *value)
304 {
305         char *end;
306
307         if (!number)
308                 return -1;
309
310         *value = strtol(number,  &end, 0);
311         if (end != NULL && *end != 0)
312                 return -1;
313
314         return 0;
315 }
316
317 static int jt_setup_mrrouting(int argc, char **argv)
318 {
319         int rc;
320         struct cYAML *err_rc = NULL;
321
322         rc = lustre_lnet_setup_mrrouting(&err_rc);
323
324         if (rc != LUSTRE_CFG_RC_NO_ERR)
325                 cYAML_print_tree2file(stderr, err_rc);
326
327         cYAML_free_tree(err_rc);
328
329         return rc;
330 }
331
332 static inline void print_help(const command_t cmds[], const char *cmd_type,
333                               const char *pc_name)
334 {
335         const command_t *cmd;
336
337         for (cmd = cmds; cmd->pc_name; cmd++) {
338                 if (pc_name != NULL &&
339                     strcmp(cmd->pc_name, pc_name) == 0) {
340                         printf("%s %s: %s\n", cmd_type, cmd->pc_name,
341                                cmd->pc_help);
342                         return;
343                 } else if (pc_name != NULL) {
344                         continue;
345                 }
346                 printf("%s %s: %s\n", cmd_type, cmd->pc_name, cmd->pc_help);
347         }
348 }
349
350 static int check_cmd(const command_t *cmd_list, const char *cmd,
351                      const char *sub_cmd, const int min_args,
352                      int argc, char **argv)
353 {
354         int opt;
355         int rc = 0;
356         optind = 0;
357         opterr = 0;
358
359         const char *const short_options = "h";
360         static const struct option long_options[] = {
361                 { .name = "help", .has_arg = no_argument, .val = 'h' },
362                 { .name = NULL }
363         };
364
365         if (argc < min_args) {
366                 print_help(cmd_list, cmd, sub_cmd);
367                 rc = -1;
368                 goto out;
369         } else if (argc > 2) {
370                 return 0;
371         }
372
373         while ((opt = getopt_long(argc, argv, short_options,
374                                   long_options, NULL)) != -1) {
375                 switch (opt) {
376                 case 'h':
377                         print_help(cmd_list, cmd, sub_cmd);
378                         rc = 1;
379                         break;
380                 default:
381                         rc = 0;
382                         break;
383                 }
384         }
385
386 out:
387         opterr = 1;
388         optind = 0;
389         return rc;
390 }
391
392 static int jt_set_response_tracking(int argc, char **argv)
393 {
394         long int value;
395         int rc;
396         struct cYAML *err_rc = NULL;
397
398         rc = check_cmd(set_cmds, "set", "response_tracking", 2, argc, argv);
399         if (rc)
400                 return rc;
401
402         rc = parse_long(argv[1], &value);
403         if (rc != 0) {
404                 cYAML_build_error(-1, -1, "parser", "set",
405                                   "cannot parse response_tracking value",
406                                   &err_rc);
407                 cYAML_print_tree2file(stderr, err_rc);
408                 cYAML_free_tree(err_rc);
409                 return -1;
410         }
411
412         rc = lustre_lnet_config_response_tracking(value, -1, &err_rc);
413         if (rc != LUSTRE_CFG_RC_NO_ERR)
414                 cYAML_print_tree2file(stderr, err_rc);
415
416         cYAML_free_tree(err_rc);
417
418         return rc;
419 }
420
421 static int jt_calc_service_id(int argc, char **argv)
422 {
423         int rc;
424         __u64 service_id;
425
426         rc = lustre_lnet_calc_service_id(&service_id);
427         if (rc != LUSTRE_CFG_RC_NO_ERR)
428                 return rc;
429
430         /* cYAML currently doesn't support printing hex values.
431          * Therefore just print it locally here
432          */
433         printf("service_id:\n    value: 0x%llx\n",
434                (unsigned long long)(service_id));
435
436         return rc;
437 }
438
439 static int jt_calc_cpt_of_nid(int argc, char **argv)
440 {
441         int rc, opt;
442         int cpt;
443         long int ncpts = -1;
444         char *nid = NULL;
445         struct cYAML *err_rc = NULL;
446         const char *const short_options = "n:c:h";
447         static const struct option long_options[] = {
448         { .name = "nid",       .has_arg = required_argument, .val = 'n' },
449         { .name = "ncpt",     .has_arg = required_argument, .val = 'c' },
450         { .name = NULL } };
451
452         rc = check_cmd(cmd_list, "", "cpt-of-nid", 0, argc, argv);
453         if (rc)
454                 return rc;
455
456         while ((opt = getopt_long(argc, argv, short_options,
457                                    long_options, NULL)) != -1) {
458                 switch (opt) {
459                 case 'n':
460                         nid = optarg;
461                         break;
462                 case 'c':
463                         rc = parse_long(optarg, &ncpts);
464                         if (rc != 0) {
465                                 cYAML_build_error(-1, -1, "cpt", "get",
466                                                 "cannot parse input", &err_rc);
467                                 cYAML_print_tree2file(stderr, err_rc);
468                                 cYAML_free_tree(err_rc);
469                                 return -1;
470                         }
471                         break;
472                 case '?':
473                         print_help(cmd_list, "", "cpt-of-nid");
474                 default:
475                         return 0;
476                 }
477         }
478
479         cpt = lustre_lnet_calc_cpt_of_nid(nid, ncpts);
480         if (cpt < 0)
481                 return -1;
482
483         printf("cpt:\n    value: %d\n", cpt);
484
485         return 0;
486 }
487
488 static int jt_set_recovery_limit(int argc, char **argv)
489 {
490         long int value;
491         int rc;
492         struct cYAML *err_rc = NULL;
493
494         rc = check_cmd(set_cmds, "set", "recovery_limit", 2, argc, argv);
495         if (rc)
496                 return rc;
497
498         rc = parse_long(argv[1], &value);
499         if (rc != 0) {
500                 cYAML_build_error(-1, -1, "parser", "set",
501                                   "cannot parse recovery_limit value",
502                                   &err_rc);
503                 cYAML_print_tree2file(stderr, err_rc);
504                 cYAML_free_tree(err_rc);
505                 return -1;
506         }
507
508         rc = lustre_lnet_config_recovery_limit(value, -1, &err_rc);
509         if (rc != LUSTRE_CFG_RC_NO_ERR)
510                 cYAML_print_tree2file(stderr, err_rc);
511
512         cYAML_free_tree(err_rc);
513
514         return rc;
515 }
516
517 static int jt_set_max_intf(int argc, char **argv)
518 {
519         long int value;
520         int rc;
521         struct cYAML *err_rc = NULL;
522
523         rc = check_cmd(set_cmds, "set", "max_interfaces", 2, argc, argv);
524         if (rc)
525                 return rc;
526
527         rc = parse_long(argv[1], &value);
528         if (rc != 0) {
529                 cYAML_build_error(-1, -1, "parser", "set",
530                                   "cannot parse max_interfaces value", &err_rc);
531                 cYAML_print_tree2file(stderr, err_rc);
532                 cYAML_free_tree(err_rc);
533                 return -1;
534         }
535
536         rc = lustre_lnet_config_max_intf(value, -1, &err_rc);
537         if (rc != LUSTRE_CFG_RC_NO_ERR)
538                 cYAML_print_tree2file(stderr, err_rc);
539
540         cYAML_free_tree(err_rc);
541
542         return rc;
543 }
544
545 static int jt_set_numa(int argc, char **argv)
546 {
547         long int value;
548         int rc;
549         struct cYAML *err_rc = NULL;
550
551         rc = check_cmd(set_cmds, "set", "numa_range", 2, argc, argv);
552         if (rc)
553                 return rc;
554
555         rc = parse_long(argv[1], &value);
556         if (rc != 0) {
557                 cYAML_build_error(-1, -1, "parser", "set",
558                                   "cannot parse numa_range value", &err_rc);
559                 cYAML_print_tree2file(stderr, err_rc);
560                 cYAML_free_tree(err_rc);
561                 return -1;
562         }
563
564         rc = lustre_lnet_config_numa_range(value, -1, &err_rc);
565         if (rc != LUSTRE_CFG_RC_NO_ERR)
566                 cYAML_print_tree2file(stderr, err_rc);
567
568         cYAML_free_tree(err_rc);
569
570         return rc;
571 }
572
573 static int jt_set_recov_intrv(int argc, char **argv)
574 {
575         long int value;
576         int rc;
577         struct cYAML *err_rc = NULL;
578
579         rc = check_cmd(set_cmds, "set", "recovery_interval", 2, argc, argv);
580         if (rc)
581                 return rc;
582
583         rc = parse_long(argv[1], &value);
584         if (rc != 0) {
585                 cYAML_build_error(-1, -1, "parser", "set",
586                                   "cannot parse recovery interval value", &err_rc);
587                 cYAML_print_tree2file(stderr, err_rc);
588                 cYAML_free_tree(err_rc);
589                 return -1;
590         }
591
592         rc = lustre_lnet_config_recov_intrv(value, -1, &err_rc);
593         if (rc != LUSTRE_CFG_RC_NO_ERR)
594                 cYAML_print_tree2file(stderr, err_rc);
595
596         cYAML_free_tree(err_rc);
597
598         return rc;
599 }
600
601 static int jt_set_rtr_sensitivity(int argc, char **argv)
602 {
603         long int value;
604         int rc;
605         struct cYAML *err_rc = NULL;
606
607         rc = check_cmd(set_cmds, "set", "router_sensitivity", 2, argc, argv);
608         if (rc)
609                 return rc;
610
611         rc = parse_long(argv[1], &value);
612         if (rc != 0) {
613                 cYAML_build_error(-1, -1, "parser", "set",
614                                   "cannot parse router sensitivity value", &err_rc);
615                 cYAML_print_tree2file(stderr, err_rc);
616                 cYAML_free_tree(err_rc);
617                 return -1;
618         }
619
620         rc = lustre_lnet_config_rtr_sensitivity(value, -1, &err_rc);
621         if (rc != LUSTRE_CFG_RC_NO_ERR)
622                 cYAML_print_tree2file(stderr, err_rc);
623
624         cYAML_free_tree(err_rc);
625
626         return rc;
627 }
628
629 static int jt_set_hsensitivity(int argc, char **argv)
630 {
631         long int value;
632         int rc;
633         struct cYAML *err_rc = NULL;
634
635         rc = check_cmd(set_cmds, "set", "health_sensitivity", 2, argc, argv);
636         if (rc)
637                 return rc;
638
639         rc = parse_long(argv[1], &value);
640         if (rc != 0) {
641                 cYAML_build_error(-1, -1, "parser", "set",
642                                   "cannot parse health sensitivity value", &err_rc);
643                 cYAML_print_tree2file(stderr, err_rc);
644                 cYAML_free_tree(err_rc);
645                 return -1;
646         }
647
648         rc = lustre_lnet_config_hsensitivity(value, -1, &err_rc);
649         if (rc != LUSTRE_CFG_RC_NO_ERR)
650                 cYAML_print_tree2file(stderr, err_rc);
651
652         cYAML_free_tree(err_rc);
653
654         return rc;
655 }
656
657 static int jt_reset_stats(int argc, char **argv)
658 {
659         int rc;
660         struct cYAML *err_rc = NULL;
661
662         rc = check_cmd(stats_cmds, "stats", "reset", 0, argc, argv);
663         if (rc)
664                 return rc;
665
666         rc = lustre_lnet_reset_stats(-1, &err_rc);
667         if (rc != LUSTRE_CFG_RC_NO_ERR)
668                 cYAML_print_tree2file(stderr, err_rc);
669
670         cYAML_free_tree(err_rc);
671
672         return rc;
673 }
674
675 static int jt_set_transaction_to(int argc, char **argv)
676 {
677         long int value;
678         int rc;
679         struct cYAML *err_rc = NULL;
680
681         rc = check_cmd(set_cmds, "set", "transaction_timeout", 2, argc, argv);
682         if (rc)
683                 return rc;
684
685         rc = parse_long(argv[1], &value);
686         if (rc != 0) {
687                 cYAML_build_error(-1, -1, "parser", "set",
688                                   "cannot parse transaction timeout value", &err_rc);
689                 cYAML_print_tree2file(stderr, err_rc);
690                 cYAML_free_tree(err_rc);
691                 return -1;
692         }
693
694         rc = lustre_lnet_config_transaction_to(value, -1, &err_rc);
695         if (rc != LUSTRE_CFG_RC_NO_ERR)
696                 cYAML_print_tree2file(stderr, err_rc);
697
698         cYAML_free_tree(err_rc);
699
700         return rc;
701 }
702
703 static int jt_set_retry_count(int argc, char **argv)
704 {
705         long int value;
706         int rc;
707         struct cYAML *err_rc = NULL;
708
709         rc = check_cmd(set_cmds, "set", "retry_count", 2, argc, argv);
710         if (rc)
711                 return rc;
712
713         rc = parse_long(argv[1], &value);
714         if (rc != 0) {
715                 cYAML_build_error(-1, -1, "parser", "set",
716                                   "cannot parse retry_count value", &err_rc);
717                 cYAML_print_tree2file(stderr, err_rc);
718                 cYAML_free_tree(err_rc);
719                 return -1;
720         }
721
722         rc = lustre_lnet_config_retry_count(value, -1, &err_rc);
723         if (rc != LUSTRE_CFG_RC_NO_ERR)
724                 cYAML_print_tree2file(stderr, err_rc);
725
726         cYAML_free_tree(err_rc);
727
728         return rc;
729 }
730
731 static int jt_set_discovery(int argc, char **argv)
732 {
733         long int value;
734         int rc;
735         struct cYAML *err_rc = NULL;
736
737         rc = check_cmd(set_cmds, "set", "discovery", 2, argc, argv);
738         if (rc)
739                 return rc;
740
741         rc = parse_long(argv[1], &value);
742         if (rc != 0) {
743                 cYAML_build_error(-1, -1, "parser", "set",
744                                   "cannot parse discovery value", &err_rc);
745                 cYAML_print_tree2file(stderr, err_rc);
746                 cYAML_free_tree(err_rc);
747                 return -1;
748         }
749
750         rc = lustre_lnet_config_discovery(value, -1, &err_rc);
751         if (rc != LUSTRE_CFG_RC_NO_ERR)
752                 cYAML_print_tree2file(stderr, err_rc);
753
754         cYAML_free_tree(err_rc);
755
756         return rc;
757 }
758
759 static int jt_set_drop_asym_route(int argc, char **argv)
760 {
761         long int value;
762         int rc;
763         struct cYAML *err_rc = NULL;
764
765         rc = check_cmd(set_cmds, "set", "drop_asym_route", 2, argc, argv);
766         if (rc)
767                 return rc;
768
769         rc = parse_long(argv[1], &value);
770         if (rc != 0) {
771                 cYAML_build_error(-1, -1, "parser", "set",
772                                   "cannot parse drop_asym_route value",
773                                   &err_rc);
774                 cYAML_print_tree2file(stderr, err_rc);
775                 cYAML_free_tree(err_rc);
776                 return -1;
777         }
778
779         rc = lustre_lnet_config_drop_asym_route(value, -1, &err_rc);
780         if (rc != LUSTRE_CFG_RC_NO_ERR)
781                 cYAML_print_tree2file(stderr, err_rc);
782
783         cYAML_free_tree(err_rc);
784
785         return rc;
786 }
787
788 static int jt_set_tiny(int argc, char **argv)
789 {
790         long int value;
791         int rc;
792         struct cYAML *err_rc = NULL;
793
794         rc = check_cmd(set_cmds, "set", "tiny_buffers", 2, argc, argv);
795         if (rc)
796                 return rc;
797
798         rc = parse_long(argv[1], &value);
799         if (rc != 0) {
800                 cYAML_build_error(-1, -1, "parser", "set",
801                                   "cannot parse tiny_buffers value", &err_rc);
802                 cYAML_print_tree2file(stderr, err_rc);
803                 cYAML_free_tree(err_rc);
804                 return -1;
805         }
806
807         rc = lustre_lnet_config_buffers(value, -1, -1, -1, &err_rc);
808         if (rc != LUSTRE_CFG_RC_NO_ERR)
809                 cYAML_print_tree2file(stderr, err_rc);
810
811         cYAML_free_tree(err_rc);
812
813         return rc;
814 }
815
816 static int jt_set_small(int argc, char **argv)
817 {
818         long int value;
819         int rc;
820         struct cYAML *err_rc = NULL;
821
822         rc = check_cmd(set_cmds, "set", "small_buffers", 2, argc, argv);
823         if (rc)
824                 return rc;
825
826         rc = parse_long(argv[1], &value);
827         if (rc != 0) {
828                 cYAML_build_error(-1, -1, "parser", "set",
829                                   "cannot parse small_buffers value", &err_rc);
830                 cYAML_print_tree2file(stderr, err_rc);
831                 cYAML_free_tree(err_rc);
832                 return -1;
833         }
834
835         rc = lustre_lnet_config_buffers(-1, value, -1, -1, &err_rc);
836         if (rc != LUSTRE_CFG_RC_NO_ERR)
837                 cYAML_print_tree2file(stderr, err_rc);
838
839         cYAML_free_tree(err_rc);
840
841         return rc;
842 }
843
844 static int jt_set_large(int argc, char **argv)
845 {
846         long int value;
847         int rc;
848         struct cYAML *err_rc = NULL;
849
850         rc = check_cmd(set_cmds, "set", "large_buffers", 2, argc, argv);
851         if (rc)
852                 return rc;
853
854         rc = parse_long(argv[1], &value);
855         if (rc != 0) {
856                 cYAML_build_error(-1, -1, "parser", "set",
857                                   "cannot parse large_buffers value", &err_rc);
858                 cYAML_print_tree2file(stderr, err_rc);
859                 cYAML_free_tree(err_rc);
860                 return -1;
861         }
862
863         rc = lustre_lnet_config_buffers(-1, -1, value, -1, &err_rc);
864         if (rc != LUSTRE_CFG_RC_NO_ERR)
865                 cYAML_print_tree2file(stderr, err_rc);
866
867         cYAML_free_tree(err_rc);
868
869         return rc;
870 }
871
872 static int jt_set_routing(int argc, char **argv)
873 {
874         long int value;
875         struct cYAML *err_rc = NULL;
876         int rc;
877
878         rc = check_cmd(set_cmds, "set", "routing", 2, argc, argv);
879         if (rc)
880                 return rc;
881
882         rc = parse_long(argv[1], &value);
883         if (rc != 0 || (value != 0 && value != 1)) {
884                 cYAML_build_error(-1, -1, "parser", "set",
885                                   "cannot parse routing value.\n"
886                                   "must be 0 for disable or 1 for enable",
887                                   &err_rc);
888                 cYAML_print_tree2file(stderr, err_rc);
889                 cYAML_free_tree(err_rc);
890                 return -1;
891         }
892
893         rc = lustre_lnet_enable_routing(value, -1, &err_rc);
894
895         if (rc != LUSTRE_CFG_RC_NO_ERR)
896                 cYAML_print_tree2file(stderr, err_rc);
897
898         cYAML_free_tree(err_rc);
899
900         return rc;
901 }
902
903 static int jt_set_max_recovery_ping_interval(int argc, char **argv)
904 {
905         long int value;
906         int rc;
907         struct cYAML *err_rc = NULL;
908
909         rc = check_cmd(set_cmds, "set", "maximum recovery_interval", 2, argc, argv);
910         if (rc)
911                 return rc;
912
913         rc = parse_long(argv[1], &value);
914         if (rc != 0) {
915                 cYAML_build_error(-1, -1, "parser", "set",
916                                   "cannot parse maximum recovery interval value",
917                                   &err_rc);
918                 cYAML_print_tree2file(stderr, err_rc);
919                 cYAML_free_tree(err_rc);
920                 return -1;
921         }
922
923         rc = lustre_lnet_config_max_recovery_ping_interval(value, -1, &err_rc);
924         if (rc != LUSTRE_CFG_RC_NO_ERR)
925                 cYAML_print_tree2file(stderr, err_rc);
926
927         cYAML_free_tree(err_rc);
928
929         return rc;
930 }
931
932 static void yaml_lnet_print_error(int op, char *cmd, const char *errstr)
933 {
934         char errcode[INT_STRING_LEN];
935         yaml_emitter_t log;
936         yaml_event_t event;
937         const char *flag;
938         int rc;
939
940         snprintf(errcode, sizeof(errcode), "%d", errno);
941
942         yaml_emitter_initialize(&log);
943         yaml_emitter_set_indent(&log, 6);
944         yaml_emitter_set_output_file(&log, stderr);
945
946         yaml_emitter_open(&log);
947         yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
948         rc = yaml_emitter_emit(&log, &event);
949         if (rc == 0)
950                 goto emitter_error;
951
952         yaml_mapping_start_event_initialize(&event, NULL,
953                                             (yaml_char_t *)YAML_MAP_TAG,
954                                             1, YAML_ANY_MAPPING_STYLE);
955         rc = yaml_emitter_emit(&log, &event);
956         if (rc == 0)
957                 goto emitter_error;
958
959         switch (op) {
960         case NLM_F_CREATE:
961                 flag = "add";
962                 break;
963         case NLM_F_REPLACE:
964                 flag = "set";
965                 break;
966         case 0:
967                 flag = "del";
968                 break;
969         case NLM_F_DUMP:
970         default:
971                 flag = "show";
972                 break;
973         }
974
975         yaml_scalar_event_initialize(&event, NULL,
976                                      (yaml_char_t *)YAML_STR_TAG,
977                                      (yaml_char_t *)flag,
978                                      strlen(flag), 1, 0,
979                                      YAML_PLAIN_SCALAR_STYLE);
980         rc = yaml_emitter_emit(&log, &event);
981         if (rc == 0)
982                 goto emitter_error;
983
984         yaml_sequence_start_event_initialize(&event, NULL,
985                                              (yaml_char_t *)YAML_SEQ_TAG,
986                                              1, YAML_ANY_SEQUENCE_STYLE);
987         rc = yaml_emitter_emit(&log, &event);
988         if (rc == 0)
989                 goto emitter_error;
990
991         yaml_mapping_start_event_initialize(&event, NULL,
992                                             (yaml_char_t *)YAML_MAP_TAG,
993                                             1, YAML_ANY_MAPPING_STYLE);
994         rc = yaml_emitter_emit(&log, &event);
995         if (rc == 0)
996                 goto emitter_error;
997
998         yaml_scalar_event_initialize(&event, NULL,
999                                      (yaml_char_t *)YAML_STR_TAG,
1000                                      (yaml_char_t *)cmd,
1001                                      strlen(cmd),
1002                                      1, 0, YAML_PLAIN_SCALAR_STYLE);
1003         rc = yaml_emitter_emit(&log, &event);
1004         if (rc == 0)
1005                 goto emitter_error;
1006
1007         yaml_scalar_event_initialize(&event, NULL,
1008                                      (yaml_char_t *)YAML_STR_TAG,
1009                                      (yaml_char_t *)"",
1010                                      strlen(""),
1011                                      1, 0, YAML_PLAIN_SCALAR_STYLE);
1012         rc = yaml_emitter_emit(&log, &event);
1013         if (rc == 0)
1014                 goto emitter_error;
1015
1016         yaml_scalar_event_initialize(&event, NULL,
1017                                      (yaml_char_t *)YAML_STR_TAG,
1018                                      (yaml_char_t *)"errno",
1019                                      strlen("errno"), 1, 0,
1020                                      YAML_PLAIN_SCALAR_STYLE);
1021         rc = yaml_emitter_emit(&log, &event);
1022         if (rc == 0)
1023                 goto emitter_error;
1024
1025         yaml_scalar_event_initialize(&event, NULL,
1026                                      (yaml_char_t *)YAML_INT_TAG,
1027                                      (yaml_char_t *)errcode,
1028                                      strlen(errcode), 1, 0,
1029                                      YAML_PLAIN_SCALAR_STYLE);
1030         rc = yaml_emitter_emit(&log, &event);
1031         if (rc == 0)
1032                 goto emitter_error;
1033
1034
1035         yaml_scalar_event_initialize(&event, NULL,
1036                                      (yaml_char_t *)YAML_STR_TAG,
1037                                      (yaml_char_t *)"descr",
1038                                      strlen("descr"), 1, 0,
1039                                      YAML_PLAIN_SCALAR_STYLE);
1040         rc = yaml_emitter_emit(&log, &event);
1041         if (rc == 0)
1042                 goto emitter_error;
1043
1044         yaml_scalar_event_initialize(&event, NULL,
1045                                      (yaml_char_t *)YAML_STR_TAG,
1046                                      (yaml_char_t *)errstr,
1047                                      strlen(errstr), 1, 0,
1048                                      YAML_DOUBLE_QUOTED_SCALAR_STYLE);
1049         rc = yaml_emitter_emit(&log, &event);
1050         if (rc == 0)
1051                 goto emitter_error;
1052
1053         yaml_mapping_end_event_initialize(&event);
1054         rc = yaml_emitter_emit(&log, &event);
1055         if (rc == 0)
1056                 goto emitter_error;
1057
1058         yaml_sequence_end_event_initialize(&event);
1059         rc = yaml_emitter_emit(&log, &event);
1060         if (rc == 0)
1061                 goto emitter_error;
1062
1063         yaml_mapping_end_event_initialize(&event);
1064         rc = yaml_emitter_emit(&log, &event);
1065         if (rc == 0)
1066                 goto emitter_error;
1067
1068         yaml_document_end_event_initialize(&event, 0);
1069         rc = yaml_emitter_emit(&log, &event);
1070         if (rc == 0)
1071                 goto emitter_error;
1072
1073         rc = yaml_emitter_close(&log);
1074 emitter_error:
1075         if (rc == 0)
1076                 yaml_emitter_log_error(&log, stdout);
1077         yaml_emitter_delete(&log);
1078 }
1079
1080 static int jt_config_lnet(int argc, char **argv)
1081 {
1082         struct cYAML *err_rc = NULL;
1083         bool load_mod_params = false;
1084         int rc, opt;
1085
1086         const char *const short_options = "a";
1087         static const struct option long_options[] = {
1088                 { .name = "all",  .has_arg = no_argument, .val = 'a' },
1089                 { .name = NULL }
1090         };
1091
1092         rc = check_cmd(lnet_cmds, "lnet", "configure", 0, argc, argv);
1093         if (rc)
1094                 return rc;
1095
1096         while ((opt = getopt_long(argc, argv, short_options,
1097                                    long_options, NULL)) != -1) {
1098                 switch (opt) {
1099                 case 'a':
1100                         load_mod_params = true;
1101                         break;
1102                 default:
1103                         return 0;
1104                 }
1105         }
1106
1107         rc = lustre_lnet_config_ni_system(LNET_CONFIGURE, load_mod_params,
1108                                           -1, &err_rc);
1109
1110         if (rc != LUSTRE_CFG_RC_NO_ERR)
1111                 cYAML_print_tree2file(stderr, err_rc);
1112
1113         cYAML_free_tree(err_rc);
1114
1115         return rc;
1116 }
1117
1118 static int jt_unconfig_lnet(int argc, char **argv)
1119 {
1120         struct cYAML *err_rc = NULL;
1121         int rc;
1122
1123         rc = check_cmd(lnet_cmds, "lnet", "unconfigure", 0, argc, argv);
1124         if (rc)
1125                 return rc;
1126
1127         rc = lustre_lnet_config_ni_system(LNET_UNCONFIGURE, 0, -1, &err_rc);
1128
1129         if (rc != LUSTRE_CFG_RC_NO_ERR)
1130                 cYAML_print_tree2file(stderr, err_rc);
1131
1132         cYAML_free_tree(err_rc);
1133
1134         return rc;
1135 }
1136
1137 static int yaml_lnet_route(char *nw, char *gw, int hops, int prio, int sen,
1138                            int version, int flags)
1139 {
1140         struct nl_sock *sk = NULL;
1141         const char *msg = NULL;
1142         yaml_emitter_t output;
1143         yaml_parser_t reply;
1144         yaml_event_t event;
1145         int rc;
1146
1147         /* Create Netlink emitter to send request to kernel */
1148         sk = nl_socket_alloc();
1149         if (!sk)
1150                 return -EOPNOTSUPP;
1151
1152         /* Setup parser to receive Netlink packets */
1153         rc = yaml_parser_initialize(&reply);
1154         if (rc == 0) {
1155                 nl_socket_free(sk);
1156                 return -EOPNOTSUPP;
1157         }
1158
1159         rc = yaml_parser_set_input_netlink(&reply, sk, false);
1160         if (rc == 0) {
1161                 msg = yaml_parser_get_reader_error(&reply);
1162                 goto free_reply;
1163         }
1164
1165         /* Create Netlink emitter to send request to kernel */
1166         rc = yaml_emitter_initialize(&output);
1167         if (rc == 0) {
1168                 msg = "failed to initialize emitter";
1169                 goto free_reply;
1170         }
1171
1172         rc = yaml_emitter_set_output_netlink(&output, sk, LNET_GENL_NAME,
1173                                              version, LNET_CMD_ROUTES, flags);
1174         if (rc == 0)
1175                 goto emitter_error;
1176
1177         yaml_emitter_open(&output);
1178         yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
1179         rc = yaml_emitter_emit(&output, &event);
1180         if (rc == 0)
1181                 goto emitter_error;
1182
1183         yaml_mapping_start_event_initialize(&event, NULL,
1184                                             (yaml_char_t *)YAML_MAP_TAG,
1185                                             1, YAML_ANY_MAPPING_STYLE);
1186         rc = yaml_emitter_emit(&output, &event);
1187         if (rc == 0)
1188                 goto emitter_error;
1189
1190         yaml_scalar_event_initialize(&event, NULL,
1191                                      (yaml_char_t *)YAML_STR_TAG,
1192                                      (yaml_char_t *)"route",
1193                                      strlen("route"), 1, 0,
1194                                      YAML_PLAIN_SCALAR_STYLE);
1195         rc = yaml_emitter_emit(&output, &event);
1196         if (rc == 0)
1197                 goto emitter_error;
1198
1199         if (nw || gw || hops != -1 || prio != -1) {
1200                 char num[INT_STRING_LEN];
1201
1202                 yaml_sequence_start_event_initialize(&event, NULL,
1203                                                      (yaml_char_t *)YAML_SEQ_TAG,
1204                                                      1,
1205                                                      YAML_BLOCK_SEQUENCE_STYLE);
1206                 rc = yaml_emitter_emit(&output, &event);
1207                 if (rc == 0)
1208                         goto emitter_error;
1209
1210                 if (nw) {
1211                         yaml_mapping_start_event_initialize(&event, NULL,
1212                                                             (yaml_char_t *)YAML_MAP_TAG,
1213                                                             1,
1214                                                             YAML_BLOCK_MAPPING_STYLE);
1215                         rc = yaml_emitter_emit(&output, &event);
1216                         if (rc == 0)
1217                                 goto emitter_error;
1218
1219                         yaml_scalar_event_initialize(&event, NULL,
1220                                                      (yaml_char_t *)YAML_STR_TAG,
1221                                                      (yaml_char_t *)"net",
1222                                                      strlen("net"), 1, 0,
1223                                                      YAML_PLAIN_SCALAR_STYLE);
1224                         rc = yaml_emitter_emit(&output, &event);
1225                         if (rc == 0)
1226                                 goto emitter_error;
1227
1228                         yaml_scalar_event_initialize(&event, NULL,
1229                                                      (yaml_char_t *)YAML_STR_TAG,
1230                                                      (yaml_char_t *)nw,
1231                                                      strlen(nw), 1, 0,
1232                                                      YAML_PLAIN_SCALAR_STYLE);
1233                         rc = yaml_emitter_emit(&output, &event);
1234                         if (rc == 0)
1235                                 goto emitter_error;
1236
1237                         yaml_mapping_end_event_initialize(&event);
1238                         rc = yaml_emitter_emit(&output, &event);
1239                         if (rc == 0)
1240                                 goto emitter_error;
1241                 }
1242
1243                 if (gw) {
1244                         yaml_mapping_start_event_initialize(&event, NULL,
1245                                                             (yaml_char_t *)YAML_MAP_TAG,
1246                                                             1,
1247                                                             YAML_BLOCK_MAPPING_STYLE);
1248                         rc = yaml_emitter_emit(&output, &event);
1249                         if (rc == 0)
1250                                 goto emitter_error;
1251
1252                         yaml_scalar_event_initialize(&event, NULL,
1253                                                      (yaml_char_t *)YAML_STR_TAG,
1254                                                      (yaml_char_t *)"gateway",
1255                                                      strlen("gateway"), 1, 0,
1256                                                      YAML_PLAIN_SCALAR_STYLE);
1257                         rc = yaml_emitter_emit(&output, &event);
1258                         if (rc == 0)
1259                                 goto emitter_error;
1260
1261                         yaml_scalar_event_initialize(&event, NULL,
1262                                                      (yaml_char_t *)YAML_STR_TAG,
1263                                                      (yaml_char_t *)gw,
1264                                                      strlen(gw), 1, 0,
1265                                                      YAML_PLAIN_SCALAR_STYLE);
1266                         rc = yaml_emitter_emit(&output, &event);
1267                         if (rc == 0)
1268                                 goto emitter_error;
1269
1270                         yaml_mapping_end_event_initialize(&event);
1271                         rc = yaml_emitter_emit(&output, &event);
1272                         if (rc == 0)
1273                                 goto emitter_error;
1274                 }
1275
1276                 if (hops != -1) {
1277                         yaml_mapping_start_event_initialize(&event, NULL,
1278                                                             (yaml_char_t *)YAML_MAP_TAG,
1279                                                             1,
1280                                                             YAML_BLOCK_MAPPING_STYLE);
1281                         rc = yaml_emitter_emit(&output, &event);
1282                         if (rc == 0)
1283                                 goto emitter_error;
1284
1285                         yaml_scalar_event_initialize(&event, NULL,
1286                                                      (yaml_char_t *)YAML_STR_TAG,
1287                                                      (yaml_char_t *)"hop",
1288                                                      strlen("hop"), 1, 0,
1289                                                      YAML_PLAIN_SCALAR_STYLE);
1290                         rc = yaml_emitter_emit(&output, &event);
1291                         if (rc == 0)
1292                                 goto emitter_error;
1293
1294                         snprintf(num, sizeof(num), "%d", hops);
1295                         yaml_scalar_event_initialize(&event, NULL,
1296                                                      (yaml_char_t *)YAML_INT_TAG,
1297                                                      (yaml_char_t *)num,
1298                                                      strlen(num), 1, 0,
1299                                                      YAML_PLAIN_SCALAR_STYLE);
1300                         rc = yaml_emitter_emit(&output, &event);
1301                         if (rc == 0)
1302                                 goto emitter_error;
1303
1304                         yaml_mapping_end_event_initialize(&event);
1305                         rc = yaml_emitter_emit(&output, &event);
1306                         if (rc == 0)
1307                                 goto emitter_error;
1308                 }
1309
1310                 if (prio != -1) {
1311                         yaml_mapping_start_event_initialize(&event, NULL,
1312                                                             (yaml_char_t *)YAML_MAP_TAG,
1313                                                             1,
1314                                                             YAML_BLOCK_MAPPING_STYLE);
1315                         rc = yaml_emitter_emit(&output, &event);
1316                         if (rc == 0)
1317                                 goto emitter_error;
1318
1319                         yaml_scalar_event_initialize(&event, NULL,
1320                                                      (yaml_char_t *)YAML_STR_TAG,
1321                                                      (yaml_char_t *)"priority",
1322                                                      strlen("priority"), 1, 0,
1323                                                      YAML_PLAIN_SCALAR_STYLE);
1324                         rc = yaml_emitter_emit(&output, &event);
1325                         if (rc == 0)
1326                                 goto emitter_error;
1327
1328                         snprintf(num, sizeof(num), "%d", prio);
1329                         yaml_scalar_event_initialize(&event, NULL,
1330                                                      (yaml_char_t *)YAML_INT_TAG,
1331                                                      (yaml_char_t *)num,
1332                                                      strlen(num), 1, 0,
1333                                                      YAML_PLAIN_SCALAR_STYLE);
1334                         rc = yaml_emitter_emit(&output, &event);
1335                         if (rc == 0)
1336                                 goto emitter_error;
1337
1338                         yaml_mapping_end_event_initialize(&event);
1339                         rc = yaml_emitter_emit(&output, &event);
1340                         if (rc == 0)
1341                                 goto emitter_error;
1342                 }
1343
1344                 if (sen != -1) {
1345                         yaml_mapping_start_event_initialize(&event, NULL,
1346                                                             (yaml_char_t *)YAML_MAP_TAG,
1347                                                             1,
1348                                                             YAML_BLOCK_MAPPING_STYLE);
1349                         rc = yaml_emitter_emit(&output, &event);
1350                         if (rc == 0)
1351                                 goto emitter_error;
1352
1353                         yaml_scalar_event_initialize(&event, NULL,
1354                                                      (yaml_char_t *)YAML_STR_TAG,
1355                                                      (yaml_char_t *)"health_sensitivity",
1356                                                      strlen("health_sensitivity"),
1357                                                      1, 0,
1358                                                      YAML_PLAIN_SCALAR_STYLE);
1359                         rc = yaml_emitter_emit(&output, &event);
1360                         if (rc == 0)
1361                                 goto emitter_error;
1362
1363                         snprintf(num, sizeof(num), "%d", sen);
1364                         yaml_scalar_event_initialize(&event, NULL,
1365                                                      (yaml_char_t *)YAML_INT_TAG,
1366                                                      (yaml_char_t *)num,
1367                                                      strlen(num), 1, 0,
1368                                                      YAML_PLAIN_SCALAR_STYLE);
1369                         rc = yaml_emitter_emit(&output, &event);
1370                         if (rc == 0)
1371                                 goto emitter_error;
1372
1373                         yaml_mapping_end_event_initialize(&event);
1374                         rc = yaml_emitter_emit(&output, &event);
1375                         if (rc == 0)
1376                                 goto emitter_error;
1377                 }
1378
1379                 yaml_sequence_end_event_initialize(&event);
1380                 rc = yaml_emitter_emit(&output, &event);
1381                 if (rc == 0)
1382                         goto emitter_error;
1383         } else {
1384                 yaml_scalar_event_initialize(&event, NULL,
1385                                              (yaml_char_t *)YAML_STR_TAG,
1386                                              (yaml_char_t *)"",
1387                                              strlen(""), 1, 0,
1388                                              YAML_PLAIN_SCALAR_STYLE);
1389                 rc = yaml_emitter_emit(&output, &event);
1390                 if (rc == 0)
1391                         goto emitter_error;
1392         }
1393
1394         yaml_mapping_end_event_initialize(&event);
1395         rc = yaml_emitter_emit(&output, &event);
1396         if (rc == 0)
1397                 goto emitter_error;
1398
1399         yaml_document_end_event_initialize(&event, 0);
1400         rc = yaml_emitter_emit(&output, &event);
1401         if (rc == 0)
1402                 goto emitter_error;
1403
1404         rc = yaml_emitter_close(&output);
1405 emitter_error:
1406         if (rc == 0) {
1407                 yaml_emitter_log_error(&output, stderr);
1408                 rc = -EINVAL;
1409         } else {
1410                 yaml_document_t errmsg;
1411
1412                 rc = yaml_parser_load(&reply, &errmsg);
1413                 if (rc == 1 && flags == NLM_F_DUMP) {
1414                         yaml_emitter_t debug;
1415
1416                         rc = yaml_emitter_initialize(&debug);
1417                         if (rc == 1) {
1418                                 yaml_emitter_set_indent(&debug, 6);
1419                                 yaml_emitter_set_output_file(&debug,
1420                                                              stdout);
1421                                 rc = yaml_emitter_dump(&debug, &errmsg);
1422                         }
1423                         yaml_emitter_delete(&debug);
1424                 } else {
1425                         msg = yaml_parser_get_reader_error(&reply);
1426                         /* If we didn't find any routes just be silent */
1427                         if (msg && strcmp(msg, "No routes found") == 0)
1428                                 rc = 1;
1429                 }
1430                 yaml_document_delete(&errmsg);
1431         }
1432         yaml_emitter_delete(&output);
1433 free_reply:
1434         if (rc == 0) {
1435                 yaml_lnet_print_error(flags, "route", msg);
1436                 rc = -EINVAL;
1437         }
1438         yaml_parser_delete(&reply);
1439         nl_socket_free(sk);
1440
1441         return rc == 1 ? 0 : rc;
1442 }
1443
1444 static int jt_add_route(int argc, char **argv)
1445 {
1446         char *network = NULL, *gateway = NULL;
1447         long int hop = -1, prio = -1, sen = -1;
1448         struct cYAML *err_rc = NULL;
1449         int rc, opt;
1450
1451         const char *const short_options = "n:g:c:p:";
1452         static const struct option long_options[] = {
1453         { .name = "net",       .has_arg = required_argument, .val = 'n' },
1454         { .name = "gateway",   .has_arg = required_argument, .val = 'g' },
1455         { .name = "hop",       .has_arg = required_argument, .val = 'c' },
1456         { .name = "hop-count", .has_arg = required_argument, .val = 'c' },
1457         { .name = "priority",  .has_arg = required_argument, .val = 'p' },
1458         { .name = "health_sensitivity",  .has_arg = required_argument, .val = 's' },
1459         { .name = NULL } };
1460
1461         rc = check_cmd(route_cmds, "route", "add", 0, argc, argv);
1462         if (rc)
1463                 return rc;
1464
1465         while ((opt = getopt_long(argc, argv, short_options,
1466                                    long_options, NULL)) != -1) {
1467                 switch (opt) {
1468                 case 'n':
1469                         network = optarg;
1470                         break;
1471                 case 'g':
1472                         gateway = optarg;
1473                         break;
1474                 case 'c':
1475                         rc = parse_long(optarg, &hop);
1476                         if (rc != 0) {
1477                                 /* ignore option */
1478                                 hop = -1;
1479                                 continue;
1480                         }
1481                         break;
1482                 case 'p':
1483                         rc = parse_long(optarg, &prio);
1484                         if (rc != 0) {
1485                                 /* ingore option */
1486                                 prio = -1;
1487                                 continue;
1488                         }
1489                         break;
1490                 case 's':
1491                         rc = parse_long(optarg, &sen);
1492                         if (rc != 0) {
1493                                 /* ingore option */
1494                                 sen = -1;
1495                                 continue;
1496                         }
1497                         break;
1498
1499                 case '?':
1500                         print_help(route_cmds, "route", "add");
1501                 default:
1502                         return 0;
1503                 }
1504         }
1505
1506         rc = lustre_lnet_config_route(network, gateway, hop, prio, sen, -1,
1507                                       &err_rc);
1508
1509         if (rc != LUSTRE_CFG_RC_NO_ERR)
1510                 cYAML_print_tree2file(stderr, err_rc);
1511
1512         cYAML_free_tree(err_rc);
1513
1514         return rc;
1515 }
1516
1517 static int yaml_add_ni_tunables(yaml_emitter_t *output,
1518                                 struct lnet_ioctl_config_lnd_tunables *tunables,
1519                                 struct lnet_dlc_network_descr *nw_descr)
1520 {
1521         yaml_event_t event;
1522         char num[23];
1523         int rc;
1524
1525         if (tunables->lt_cmn.lct_peer_timeout < 0 &&
1526             tunables->lt_cmn.lct_peer_tx_credits <= 0 &&
1527             tunables->lt_cmn.lct_peer_rtr_credits <= 0 &&
1528             tunables->lt_cmn.lct_max_tx_credits <= 0)
1529                 goto skip_general_settings;
1530
1531         yaml_scalar_event_initialize(&event, NULL,
1532                                      (yaml_char_t *)YAML_STR_TAG,
1533                                      (yaml_char_t *)"tunables",
1534                                      strlen("tunables"), 1, 0,
1535                                      YAML_PLAIN_SCALAR_STYLE);
1536         rc = yaml_emitter_emit(output, &event);
1537         if (rc == 0)
1538                 goto error;
1539
1540         yaml_mapping_start_event_initialize(&event, NULL,
1541                                             (yaml_char_t *)YAML_MAP_TAG,
1542                                             1, YAML_ANY_MAPPING_STYLE);
1543         rc = yaml_emitter_emit(output, &event);
1544         if (rc == 0)
1545                 goto error;
1546
1547         if (tunables->lt_cmn.lct_peer_timeout >= 0) {
1548                 yaml_scalar_event_initialize(&event, NULL,
1549                                              (yaml_char_t *)YAML_STR_TAG,
1550                                              (yaml_char_t *)"peer_timeout",
1551                                              strlen("peer_timeout"), 1, 0,
1552                                              YAML_PLAIN_SCALAR_STYLE);
1553                 rc = yaml_emitter_emit(output, &event);
1554                 if (rc == 0)
1555                         goto error;
1556
1557                 snprintf(num, sizeof(num), "%u",
1558                          tunables->lt_cmn.lct_peer_timeout);
1559                 yaml_scalar_event_initialize(&event, NULL,
1560                                              (yaml_char_t *)YAML_INT_TAG,
1561                                              (yaml_char_t *)num,
1562                                              strlen(num), 1, 0,
1563                                              YAML_PLAIN_SCALAR_STYLE);
1564                 rc = yaml_emitter_emit(output, &event);
1565                 if (rc == 0)
1566                         goto error;
1567         }
1568
1569         if (tunables->lt_cmn.lct_peer_tx_credits > 0) {
1570                 yaml_scalar_event_initialize(&event, NULL,
1571                                              (yaml_char_t *)YAML_STR_TAG,
1572                                              (yaml_char_t *)"peer_credits",
1573                                              strlen("peer_credits"), 1, 0,
1574                                              YAML_PLAIN_SCALAR_STYLE);
1575                 rc = yaml_emitter_emit(output, &event);
1576                 if (rc == 0)
1577                         goto error;
1578
1579                 snprintf(num, sizeof(num), "%u",
1580                          tunables->lt_cmn.lct_peer_tx_credits);
1581                 yaml_scalar_event_initialize(&event, NULL,
1582                                              (yaml_char_t *)YAML_INT_TAG,
1583                                              (yaml_char_t *)num,
1584                                              strlen(num), 1, 0,
1585                                              YAML_PLAIN_SCALAR_STYLE);
1586                 rc = yaml_emitter_emit(output, &event);
1587                 if (rc == 0)
1588                         goto error;
1589         }
1590
1591         if (tunables->lt_cmn.lct_peer_rtr_credits > 0) {
1592                 yaml_scalar_event_initialize(&event, NULL,
1593                                              (yaml_char_t *)YAML_STR_TAG,
1594                                              (yaml_char_t *)"peer_buffer_credits",
1595                                              strlen("peer_buffer_credits"), 1, 0,
1596                                              YAML_PLAIN_SCALAR_STYLE);
1597                 rc = yaml_emitter_emit(output, &event);
1598                 if (rc == 0)
1599                         goto error;
1600
1601                 snprintf(num, sizeof(num), "%u",
1602                          tunables->lt_cmn.lct_peer_rtr_credits);
1603                 yaml_scalar_event_initialize(&event, NULL,
1604                                              (yaml_char_t *)YAML_INT_TAG,
1605                                              (yaml_char_t *)num,
1606                                              strlen(num), 1, 0,
1607                                              YAML_PLAIN_SCALAR_STYLE);
1608                 rc = yaml_emitter_emit(output, &event);
1609                 if (rc == 0)
1610                         goto error;
1611         }
1612
1613         if (tunables->lt_cmn.lct_max_tx_credits > 0) {
1614                 yaml_scalar_event_initialize(&event, NULL,
1615                                              (yaml_char_t *)YAML_STR_TAG,
1616                                              (yaml_char_t *)"credits",
1617                                              strlen("credits"), 1, 0,
1618                                              YAML_PLAIN_SCALAR_STYLE);
1619                 rc = yaml_emitter_emit(output, &event);
1620                 if (rc == 0)
1621                         goto error;
1622
1623                 snprintf(num, sizeof(num), "%u",
1624                          tunables->lt_cmn.lct_max_tx_credits);
1625                 yaml_scalar_event_initialize(&event, NULL,
1626                                              (yaml_char_t *)YAML_INT_TAG,
1627                                              (yaml_char_t *)num,
1628                                              strlen(num), 1, 0,
1629                                              YAML_PLAIN_SCALAR_STYLE);
1630                 rc = yaml_emitter_emit(output, &event);
1631                 if (rc == 0)
1632                         goto error;
1633         }
1634
1635         yaml_mapping_end_event_initialize(&event);
1636         rc = yaml_emitter_emit(output, &event);
1637         if (rc == 0)
1638                 goto error;
1639
1640 skip_general_settings:
1641         if (tunables->lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer > 0 ||
1642 #ifdef HAVE_KFILND
1643             tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_auth_key > 0 ||
1644             tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_traffic_class_str[0] ||
1645 #endif
1646             tunables->lt_tun.lnd_tun_u.lnd_o2ib.lnd_conns_per_peer > 0) {
1647                 yaml_scalar_event_initialize(&event, NULL,
1648                                              (yaml_char_t *)YAML_STR_TAG,
1649                                              (yaml_char_t *)"lnd tunables",
1650                                              strlen("lnd tunables"), 1, 0,
1651                                              YAML_PLAIN_SCALAR_STYLE);
1652                 rc = yaml_emitter_emit(output, &event);
1653                 if (rc == 0)
1654                         goto error;
1655
1656                 yaml_mapping_start_event_initialize(&event, NULL,
1657                                                     (yaml_char_t *)YAML_MAP_TAG,
1658                                                     1, YAML_ANY_MAPPING_STYLE);
1659                 rc = yaml_emitter_emit(output, &event);
1660                 if (rc == 0)
1661                         goto error;
1662 #ifdef HAVE_KFILND
1663                 if (tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_auth_key > 0) {
1664                         yaml_scalar_event_initialize(&event, NULL,
1665                                                      (yaml_char_t *)YAML_STR_TAG,
1666                                                      (yaml_char_t *)"auth_key",
1667                                                      strlen("auth_key"), 1, 0,
1668                                                      YAML_PLAIN_SCALAR_STYLE);
1669                         rc = yaml_emitter_emit(output, &event);
1670                         if (rc == 0)
1671                                 goto error;
1672
1673                         snprintf(num, sizeof(num), "%u",
1674                                  tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_auth_key);
1675
1676                         yaml_scalar_event_initialize(&event, NULL,
1677                                                      (yaml_char_t *)YAML_INT_TAG,
1678                                                      (yaml_char_t *)num,
1679                                                      strlen(num), 1, 0,
1680                                                      YAML_PLAIN_SCALAR_STYLE);
1681                         rc = yaml_emitter_emit(output, &event);
1682                         if (rc == 0)
1683                                 goto error;
1684                 }
1685
1686                 if (tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_traffic_class_str[0]) {
1687                         char *tc = &tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_traffic_class_str[0];
1688
1689                         yaml_scalar_event_initialize(&event, NULL,
1690                                                      (yaml_char_t *)YAML_STR_TAG,
1691                                                      (yaml_char_t *)"traffic_class",
1692                                                      strlen("traffic_class"), 1, 0,
1693                                                      YAML_PLAIN_SCALAR_STYLE);
1694                         rc = yaml_emitter_emit(output, &event);
1695                         if (rc == 0)
1696                                 goto error;
1697
1698                         yaml_scalar_event_initialize(&event, NULL,
1699                                                      (yaml_char_t *)YAML_INT_TAG,
1700                                                      (yaml_char_t *)tc,
1701                                                      strlen(tc), 1, 0,
1702                                                      YAML_PLAIN_SCALAR_STYLE);
1703
1704                         rc = yaml_emitter_emit(output, &event);
1705                         if (rc == 0)
1706                                 goto error;
1707                 }
1708 #endif
1709                 if (tunables->lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer > 0 ||
1710                     tunables->lt_tun.lnd_tun_u.lnd_o2ib.lnd_conns_per_peer > 0) {
1711                         int cpp = 0;
1712
1713                         yaml_scalar_event_initialize(&event, NULL,
1714                                                      (yaml_char_t *)YAML_STR_TAG,
1715                                                      (yaml_char_t *)"conns_per_peer",
1716                                                      strlen("conns_per_peer"), 1, 0,
1717                                                      YAML_PLAIN_SCALAR_STYLE);
1718                         rc = yaml_emitter_emit(output, &event);
1719                         if (rc == 0)
1720                                 goto error;
1721
1722                         if (LNET_NETTYP(nw_descr->nw_id) == SOCKLND)
1723                                 cpp = tunables->lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer;
1724                         else if (LNET_NETTYP(nw_descr->nw_id) == O2IBLND)
1725                                 cpp = tunables->lt_tun.lnd_tun_u.lnd_o2ib.lnd_conns_per_peer;
1726                         snprintf(num, sizeof(num), "%u", cpp);
1727
1728                         yaml_scalar_event_initialize(&event, NULL,
1729                                                      (yaml_char_t *)YAML_INT_TAG,
1730                                                      (yaml_char_t *)num,
1731                                                      strlen(num), 1, 0,
1732                                                      YAML_PLAIN_SCALAR_STYLE);
1733                         rc = yaml_emitter_emit(output, &event);
1734                         if (rc == 0)
1735                                 goto error;
1736                 }
1737
1738                 yaml_mapping_end_event_initialize(&event);
1739                 rc = yaml_emitter_emit(output, &event);
1740         }
1741 error:
1742         return rc;
1743 }
1744
1745 static int yaml_lnet_config_ni(char *net_id, char *ip2net,
1746                                struct lnet_dlc_network_descr *nw_descr,
1747                                struct lnet_ioctl_config_lnd_tunables *tunables,
1748                                struct cfs_expr_list *global_cpts,
1749                                int flags)
1750 {
1751         struct lnet_dlc_intf_descr *intf;
1752         struct nl_sock *sk = NULL;
1753         yaml_emitter_t output;
1754         yaml_parser_t reply;
1755         yaml_event_t event;
1756         int rc;
1757
1758         if (!ip2net && (!nw_descr || nw_descr->nw_id == 0)) {
1759                 fprintf(stdout, "missing mandatory parameters in NI config: '%s'",
1760                         (!nw_descr) ? "network , interface" :
1761                         (nw_descr->nw_id == 0) ? "network" : "interface");
1762                 return -EINVAL;
1763         }
1764
1765         if ((flags == NLM_F_CREATE) && list_empty(&nw_descr->nw_intflist)) {
1766                 fprintf(stdout, "creating a local NI needs at least one interface");
1767                 return -EINVAL;
1768         }
1769
1770         /* Create Netlink emitter to send request to kernel */
1771         sk = nl_socket_alloc();
1772         if (!sk)
1773                 return -EOPNOTSUPP;
1774
1775         /* Setup parser to receive Netlink packets */
1776         rc = yaml_parser_initialize(&reply);
1777         if (rc == 0) {
1778                 nl_socket_free(sk);
1779                 return -EOPNOTSUPP;
1780         }
1781
1782         rc = yaml_parser_set_input_netlink(&reply, sk, false);
1783         if (rc == 0)
1784                 goto free_reply;
1785
1786         /* Create Netlink emitter to send request to kernel */
1787         rc = yaml_emitter_initialize(&output);
1788         if (rc == 0)
1789                 goto free_reply;
1790
1791         rc = yaml_emitter_set_output_netlink(&output, sk, LNET_GENL_NAME,
1792                                              LNET_GENL_VERSION, LNET_CMD_NETS,
1793                                              flags);
1794         if (rc == 0)
1795                 goto emitter_error;
1796
1797         yaml_emitter_open(&output);
1798         yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
1799         rc = yaml_emitter_emit(&output, &event);
1800         if (rc == 0)
1801                 goto emitter_error;
1802
1803         yaml_mapping_start_event_initialize(&event, NULL,
1804                                             (yaml_char_t *)YAML_MAP_TAG,
1805                                             1, YAML_ANY_MAPPING_STYLE);
1806         rc = yaml_emitter_emit(&output, &event);
1807         if (rc == 0)
1808                 goto emitter_error;
1809
1810         yaml_scalar_event_initialize(&event, NULL,
1811                                      (yaml_char_t *)YAML_STR_TAG,
1812                                      (yaml_char_t *)"net",
1813                                      strlen("net"), 1, 0,
1814                                      YAML_PLAIN_SCALAR_STYLE);
1815         rc = yaml_emitter_emit(&output, &event);
1816         if (rc == 0)
1817                 goto emitter_error;
1818
1819         if (net_id || ip2net) {
1820                 char *key = net_id ? "net type" : "ip2net";
1821                 char *value = net_id ? net_id : ip2net;
1822
1823                 yaml_sequence_start_event_initialize(&event, NULL,
1824                                                      (yaml_char_t *)YAML_SEQ_TAG,
1825                                                      1, YAML_ANY_SEQUENCE_STYLE);
1826                 rc = yaml_emitter_emit(&output, &event);
1827                 if (rc == 0)
1828                         goto emitter_error;
1829
1830                 yaml_mapping_start_event_initialize(&event, NULL,
1831                                                     (yaml_char_t *)YAML_MAP_TAG,
1832                                                     1, YAML_ANY_MAPPING_STYLE);
1833                 rc = yaml_emitter_emit(&output, &event);
1834                 if (rc == 0)
1835                         goto emitter_error;
1836
1837                 yaml_scalar_event_initialize(&event, NULL,
1838                                              (yaml_char_t *)YAML_STR_TAG,
1839                                              (yaml_char_t *)key,
1840                                              strlen(key),
1841                                              1, 0, YAML_PLAIN_SCALAR_STYLE);
1842                 rc = yaml_emitter_emit(&output, &event);
1843                 if (rc == 0)
1844                         goto emitter_error;
1845
1846                 yaml_scalar_event_initialize(&event, NULL,
1847                                              (yaml_char_t *)YAML_STR_TAG,
1848                                              (yaml_char_t *)value,
1849                                              strlen(value), 1, 0,
1850                                              YAML_PLAIN_SCALAR_STYLE);
1851                 rc = yaml_emitter_emit(&output, &event);
1852                 if (rc == 0)
1853                         goto emitter_error;
1854         } else {
1855                 yaml_scalar_event_initialize(&event, NULL,
1856                                              (yaml_char_t *)YAML_STR_TAG,
1857                                              (yaml_char_t *)"",
1858                                              strlen(""), 1, 0,
1859                                              YAML_PLAIN_SCALAR_STYLE);
1860                 rc = yaml_emitter_emit(&output, &event);
1861                 if (rc == 0)
1862                         goto emitter_error;
1863
1864                 goto no_net_id;
1865         }
1866
1867         if (list_empty(&nw_descr->nw_intflist))
1868                 goto skip_intf;
1869
1870         yaml_scalar_event_initialize(&event, NULL,
1871                                      (yaml_char_t *)YAML_STR_TAG,
1872                                      (yaml_char_t *)"local NI(s)",
1873                                      strlen("local NI(s)"), 1, 0,
1874                                      YAML_PLAIN_SCALAR_STYLE);
1875         rc = yaml_emitter_emit(&output, &event);
1876         if (rc == 0)
1877                 goto emitter_error;
1878
1879         yaml_sequence_start_event_initialize(&event, NULL,
1880                                              (yaml_char_t *)YAML_SEQ_TAG,
1881                                              1, YAML_ANY_SEQUENCE_STYLE);
1882         rc = yaml_emitter_emit(&output, &event);
1883         if (rc == 0)
1884                 goto emitter_error;
1885
1886         list_for_each_entry(intf, &nw_descr->nw_intflist,
1887                             intf_on_network) {
1888                 yaml_mapping_start_event_initialize(&event, NULL,
1889                                                     (yaml_char_t *)YAML_MAP_TAG,
1890                                                     1, YAML_ANY_MAPPING_STYLE);
1891                 rc = yaml_emitter_emit(&output, &event);
1892                 if (rc == 0)
1893                         goto emitter_error;
1894
1895                 yaml_scalar_event_initialize(&event, NULL,
1896                                              (yaml_char_t *)YAML_STR_TAG,
1897                                              (yaml_char_t *)"interfaces",
1898                                              strlen("interfaces"), 1, 0,
1899                                              YAML_PLAIN_SCALAR_STYLE);
1900                 rc = yaml_emitter_emit(&output, &event);
1901                 if (rc == 0)
1902                         goto emitter_error;
1903
1904                 yaml_mapping_start_event_initialize(&event, NULL,
1905                                                     (yaml_char_t *)YAML_MAP_TAG,
1906                                                     1, YAML_ANY_MAPPING_STYLE);
1907                 rc = yaml_emitter_emit(&output, &event);
1908                 if (rc == 0)
1909                         goto emitter_error;
1910
1911                 yaml_scalar_event_initialize(&event, NULL,
1912                                              (yaml_char_t *)YAML_STR_TAG,
1913                                              (yaml_char_t *)"0",
1914                                              strlen("0"), 1, 0,
1915                                              YAML_PLAIN_SCALAR_STYLE);
1916                 rc = yaml_emitter_emit(&output, &event);
1917                 if (rc == 0)
1918                         goto emitter_error;
1919
1920                 yaml_scalar_event_initialize(&event, NULL,
1921                                              (yaml_char_t *)YAML_STR_TAG,
1922                                              (yaml_char_t *)intf->intf_name,
1923                                              strlen(intf->intf_name), 1, 0,
1924                                              YAML_PLAIN_SCALAR_STYLE);
1925                 rc = yaml_emitter_emit(&output, &event);
1926                 if (rc == 0)
1927                         goto emitter_error;
1928
1929                 yaml_mapping_end_event_initialize(&event);
1930                 rc = yaml_emitter_emit(&output, &event);
1931                 if (rc == 0)
1932                         goto emitter_error;
1933
1934                 if (tunables) {
1935                         rc = yaml_add_ni_tunables(&output, tunables, nw_descr);
1936                         if (rc == 0)
1937                                 goto emitter_error;
1938                 }
1939
1940                 if (global_cpts) {
1941                         __u32 *cpt_array;
1942                         int count, i;
1943
1944                         yaml_scalar_event_initialize(&event, NULL,
1945                                                      (yaml_char_t *)YAML_STR_TAG,
1946                                                      (yaml_char_t *)"CPT",
1947                                                      strlen("CPT"), 1, 0,
1948                                                      YAML_PLAIN_SCALAR_STYLE);
1949                         rc = yaml_emitter_emit(&output, &event);
1950                         if (rc == 0)
1951                                 goto emitter_error;
1952
1953                         yaml_sequence_start_event_initialize(&event, NULL,
1954                                                              (yaml_char_t *)YAML_SEQ_TAG,
1955                                                              1,
1956                                                              YAML_FLOW_SEQUENCE_STYLE);
1957                         rc = yaml_emitter_emit(&output, &event);
1958                         if (rc == 0)
1959                                 goto emitter_error;
1960
1961                         count = cfs_expr_list_values(global_cpts,
1962                                                      LNET_MAX_SHOW_NUM_CPT,
1963                                                      &cpt_array);
1964                         for (i = 0; i < count; i++) {
1965                                 char core[23];
1966
1967                                 snprintf(core, sizeof(core), "%u", cpt_array[i]);
1968                                 yaml_scalar_event_initialize(&event, NULL,
1969                                                              (yaml_char_t *)YAML_STR_TAG,
1970                                                              (yaml_char_t *)core,
1971                                                              strlen(core), 1, 0,
1972                                                              YAML_PLAIN_SCALAR_STYLE);
1973                                 rc = yaml_emitter_emit(&output, &event);
1974                                 if (rc == 0)
1975                                         goto emitter_error;
1976                         }
1977
1978                         yaml_sequence_end_event_initialize(&event);
1979                         rc = yaml_emitter_emit(&output, &event);
1980                         if (rc == 0)
1981                                 goto emitter_error;
1982
1983                         cfs_expr_list_free(global_cpts);
1984                         free(cpt_array);
1985                 }
1986
1987                 yaml_mapping_end_event_initialize(&event);
1988                 rc = yaml_emitter_emit(&output, &event);
1989                 if (rc == 0)
1990                         goto emitter_error;
1991         }
1992
1993         yaml_sequence_end_event_initialize(&event);
1994         rc = yaml_emitter_emit(&output, &event);
1995         if (rc == 0)
1996                 goto emitter_error;
1997 skip_intf:
1998         yaml_mapping_end_event_initialize(&event);
1999         rc = yaml_emitter_emit(&output, &event);
2000         if (rc == 0)
2001                 goto emitter_error;
2002
2003         yaml_sequence_end_event_initialize(&event);
2004         rc = yaml_emitter_emit(&output, &event);
2005         if (rc == 0)
2006                 goto emitter_error;
2007 no_net_id:
2008         yaml_mapping_end_event_initialize(&event);
2009         rc = yaml_emitter_emit(&output, &event);
2010         if (rc == 0)
2011                 goto emitter_error;
2012
2013         yaml_document_end_event_initialize(&event, 0);
2014         rc = yaml_emitter_emit(&output, &event);
2015         if (rc == 0)
2016                 goto emitter_error;
2017
2018         rc = yaml_emitter_close(&output);
2019 emitter_error:
2020         if (rc == 0) {
2021                 yaml_emitter_log_error(&output, stderr);
2022                 rc = -EINVAL;
2023         } else {
2024                 yaml_document_t errmsg;
2025
2026                 rc = yaml_parser_load(&reply, &errmsg);
2027         }
2028         yaml_emitter_delete(&output);
2029 free_reply:
2030         if (rc == 0) {
2031                 yaml_lnet_print_error(flags, "net",
2032                                       yaml_parser_get_reader_error(&reply));
2033                 rc = -EINVAL;
2034         }
2035         yaml_parser_delete(&reply);
2036         nl_socket_free(sk);
2037
2038         return rc == 1 ? 0 : rc;
2039 }
2040
2041 static int jt_add_ni(int argc, char **argv)
2042 {
2043         char *ip2net = NULL;
2044         long int pto = -1, pc = -1, pbc = -1, cre = -1, cpp = -1, auth_key = -1;
2045         char *traffic_class = NULL;
2046         struct cYAML *err_rc = NULL;
2047         int rc, opt, cpt_rc = -1;
2048         struct lnet_dlc_network_descr nw_descr;
2049         struct cfs_expr_list *global_cpts = NULL;
2050         struct lnet_ioctl_config_lnd_tunables tunables;
2051         bool found = false;
2052         bool skip_mr_route_setup = false;
2053         const char *const short_options = "a:b:c:i:k:m:n:p:r:s:t:T:";
2054         static const struct option long_options[] = {
2055         { .name = "auth-key",     .has_arg = required_argument, .val = 'a' },
2056         { .name = "peer-buffer-credits",
2057                                   .has_arg = required_argument, .val = 'b' },
2058         { .name = "peer-credits", .has_arg = required_argument, .val = 'c' },
2059         { .name = "if",           .has_arg = required_argument, .val = 'i' },
2060         { .name = "skip-mr-route-setup",
2061                                   .has_arg = no_argument, .val = 'k' },
2062         { .name = "conns-per-peer",
2063                                   .has_arg = required_argument, .val = 'm' },
2064         { .name = "net",          .has_arg = required_argument, .val = 'n' },
2065         { .name = "ip2net",       .has_arg = required_argument, .val = 'p' },
2066         { .name = "credits",      .has_arg = required_argument, .val = 'r' },
2067         { .name = "cpt",          .has_arg = required_argument, .val = 's' },
2068         { .name = "peer-timeout", .has_arg = required_argument, .val = 't' },
2069         { .name = "traffic-class", .has_arg = required_argument, .val = 'T' },
2070         { .name = NULL } };
2071         char *net_id = NULL;
2072
2073         memset(&tunables, 0, sizeof(tunables));
2074         lustre_lnet_init_nw_descr(&nw_descr);
2075
2076         rc = check_cmd(net_cmds, "net", "add", 0, argc, argv);
2077         if (rc)
2078                 return rc;
2079
2080         while ((opt = getopt_long(argc, argv, short_options,
2081                                    long_options, NULL)) != -1) {
2082                 switch (opt) {
2083                 case 'a':
2084                         rc = parse_long(optarg, &auth_key);
2085                         if (rc != 0) {
2086                                 /* ignore option */
2087                                 auth_key = -1;
2088                                 continue;
2089                         }
2090                         break;
2091                 case 'b':
2092                         rc = parse_long(optarg, &pbc);
2093                         if (rc != 0) {
2094                                 /* ignore option */
2095                                 pbc = -1;
2096                                 continue;
2097                         }
2098                         break;
2099                 case 'c':
2100                         rc = parse_long(optarg, &pc);
2101                         if (rc != 0) {
2102                                 /* ignore option */
2103                                 pc = -1;
2104                                 continue;
2105                         }
2106                         break;
2107                 case 'i':
2108                         rc = lustre_lnet_parse_interfaces(optarg, &nw_descr);
2109                         if (rc != 0) {
2110                                 cYAML_build_error(-1, -1, "ni", "add",
2111                                                 "bad interface list",
2112                                                 &err_rc);
2113                                 goto failed;
2114                         }
2115                         break;
2116                 case 'k':
2117                         skip_mr_route_setup = true;
2118                         break;
2119                 case 'm':
2120                         rc = parse_long(optarg, &cpp);
2121                         if (rc != 0) {
2122                                 /* ignore option */
2123                                 cpp = -1;
2124                                 continue;
2125                         }
2126                         break;
2127
2128                 case 'n':
2129                         nw_descr.nw_id = libcfs_str2net(optarg);
2130                         net_id = optarg;
2131                         break;
2132                 case 'p':
2133                         ip2net = optarg;
2134                         break;
2135                 case 'r':
2136                         rc = parse_long(optarg, &cre);
2137                         if (rc != 0) {
2138                                 /* ignore option */
2139                                 cre = -1;
2140                                 continue;
2141                         }
2142                         break;
2143                 case 's':
2144                         cpt_rc = cfs_expr_list_parse(optarg,
2145                                                      strlen(optarg), 0,
2146                                                      UINT_MAX, &global_cpts);
2147                         break;
2148                 case 't':
2149                         rc = parse_long(optarg, &pto);
2150                         if (rc != 0) {
2151                                 /* ignore option */
2152                                 pto = -1;
2153                                 continue;
2154                         }
2155                         break;
2156                 case 'T':
2157                         traffic_class = optarg;
2158                         if (strlen(traffic_class) == 0 ||
2159                             strlen(traffic_class) >= LNET_MAX_STR_LEN) {
2160                                 cYAML_build_error(-1, -1, "ni", "add",
2161                                                   "Invalid traffic-class argument",
2162                                                   &err_rc);
2163                                 rc = LUSTRE_CFG_RC_BAD_PARAM;
2164                                 goto failed;
2165                         }
2166                         break;
2167                 case '?':
2168                         print_help(net_cmds, "net", "add");
2169                 default:
2170                         return 0;
2171                 }
2172         }
2173 #ifdef HAVE_KFILND
2174         if (auth_key > 0 && LNET_NETTYP(nw_descr.nw_id) == KFILND) {
2175                 tunables.lt_tun.lnd_tun_u.lnd_kfi.lnd_auth_key = auth_key;
2176                 found = true;
2177         }
2178
2179         if (traffic_class && LNET_NETTYP(nw_descr.nw_id) == KFILND &&
2180             strlen(traffic_class) < LNET_MAX_STR_LEN) {
2181                 strcpy(&tunables.lt_tun.lnd_tun_u.lnd_kfi.lnd_traffic_class_str[0],
2182                        traffic_class);
2183                 found = true;
2184         }
2185 #endif
2186
2187         if (LNET_NETTYP(nw_descr.nw_id) == SOCKLND && (cpp > -1)) {
2188                 tunables.lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer = cpp;
2189                 found = true;
2190         } else if (LNET_NETTYP(nw_descr.nw_id) == O2IBLND && (cpp > -1)) {
2191                 tunables.lt_tun.lnd_tun_u.lnd_o2ib.lnd_conns_per_peer = cpp;
2192                 found = true;
2193         }
2194
2195         if (pto >= 0 || pc > 0 || pbc > 0 || cre > 0 || cpp > -1) {
2196                 tunables.lt_cmn.lct_peer_timeout = pto;
2197                 tunables.lt_cmn.lct_peer_tx_credits = pc;
2198                 tunables.lt_cmn.lct_peer_rtr_credits = pbc;
2199                 tunables.lt_cmn.lct_max_tx_credits = cre;
2200                 found = true;
2201         }
2202
2203         if (found && LNET_NETTYP(nw_descr.nw_id) == O2IBLND)
2204                 tunables.lt_tun.lnd_tun_u.lnd_o2ib.lnd_map_on_demand = UINT_MAX;
2205
2206         rc = yaml_lnet_config_ni(net_id, ip2net, &nw_descr,
2207                                  found ? &tunables : NULL,
2208                                  (cpt_rc == 0) ? global_cpts : NULL,
2209                                  NLM_F_CREATE);
2210         if (rc <= 0) {
2211                 if (rc == -EOPNOTSUPP)
2212                         goto old_api;
2213                 if (global_cpts != NULL)
2214                         cfs_expr_list_free(global_cpts);
2215                 if (rc == 0 && !skip_mr_route_setup)
2216                         rc = lustre_lnet_setup_mrrouting(&err_rc);
2217                 return rc;
2218         }
2219 old_api:
2220         rc = lustre_lnet_config_ni(&nw_descr,
2221                                    (cpt_rc == 0) ? global_cpts: NULL,
2222                                    ip2net, (found) ? &tunables : NULL,
2223                                    cpp, &err_rc);
2224
2225         if (global_cpts != NULL)
2226                 cfs_expr_list_free(global_cpts);
2227
2228 failed:
2229         if (rc != LUSTRE_CFG_RC_NO_ERR)
2230                 cYAML_print_tree2file(stderr, err_rc);
2231
2232         cYAML_free_tree(err_rc);
2233
2234         if (rc == LUSTRE_CFG_RC_NO_ERR && !skip_mr_route_setup) {
2235                 err_rc = NULL;
2236                 rc = lustre_lnet_setup_mrrouting(&err_rc);
2237
2238                 if (rc != LUSTRE_CFG_RC_NO_ERR)
2239                         cYAML_print_tree2file(stderr, err_rc);
2240
2241                 cYAML_free_tree(err_rc);
2242         }
2243
2244         return rc;
2245 }
2246
2247 static int jt_del_route(int argc, char **argv)
2248 {
2249         char *network = NULL, *gateway = NULL;
2250         struct cYAML *err_rc = NULL;
2251         int rc, opt;
2252
2253         const char *const short_options = "n:g:";
2254         static const struct option long_options[] = {
2255                 { .name = "net",     .has_arg = required_argument, .val = 'n' },
2256                 { .name = "gateway", .has_arg = required_argument, .val = 'g' },
2257                 { .name = NULL } };
2258
2259         rc = check_cmd(route_cmds, "route", "del", 0, argc, argv);
2260         if (rc)
2261                 return rc;
2262
2263         while ((opt = getopt_long(argc, argv, short_options,
2264                                    long_options, NULL)) != -1) {
2265                 switch (opt) {
2266                 case 'n':
2267                         network = optarg;
2268                         break;
2269                 case 'g':
2270                         gateway = optarg;
2271                         break;
2272                 case '?':
2273                         print_help(route_cmds, "route", "del");
2274                 default:
2275                         return 0;
2276                 }
2277         }
2278
2279         rc = lustre_lnet_del_route(network, gateway, -1, &err_rc);
2280
2281         if (rc != LUSTRE_CFG_RC_NO_ERR)
2282                 cYAML_print_tree2file(stderr, err_rc);
2283
2284         cYAML_free_tree(err_rc);
2285
2286         return rc;
2287 }
2288
2289 static int jt_del_ni(int argc, char **argv)
2290 {
2291         struct cYAML *err_rc = NULL;
2292         int rc, opt;
2293         struct lnet_dlc_network_descr nw_descr;
2294         const char *const short_options = "n:i:";
2295         static const struct option long_options[] = {
2296         { .name = "net",        .has_arg = required_argument,   .val = 'n' },
2297         { .name = "if",         .has_arg = required_argument,   .val = 'i' },
2298         { .name = NULL } };
2299         char *net_id = NULL;
2300
2301         rc = check_cmd(net_cmds, "net", "del", 0, argc, argv);
2302         if (rc)
2303                 return rc;
2304
2305         lustre_lnet_init_nw_descr(&nw_descr);
2306
2307         while ((opt = getopt_long(argc, argv, short_options,
2308                                    long_options, NULL)) != -1) {
2309                 switch (opt) {
2310                 case 'n':
2311                         nw_descr.nw_id = libcfs_str2net(optarg);
2312                         net_id = optarg;
2313                         break;
2314                 case 'i':
2315                         rc = lustre_lnet_parse_interfaces(optarg, &nw_descr);
2316                         if (rc != 0) {
2317                                 cYAML_build_error(-1, -1, "ni", "add",
2318                                                 "bad interface list",
2319                                                 &err_rc);
2320                                 goto out;
2321                         }
2322                         break;
2323                 case '?':
2324                         print_help(net_cmds, "net", "del");
2325                 default:
2326                         return 0;
2327                 }
2328         }
2329
2330         rc = yaml_lnet_config_ni(net_id, NULL, &nw_descr, NULL, NULL, 0);
2331         if (rc <= 0) {
2332                 if (rc != -EOPNOTSUPP)
2333                         return rc;
2334         }
2335
2336         rc = lustre_lnet_del_ni(&nw_descr, -1, &err_rc);
2337 out:
2338         if (rc != LUSTRE_CFG_RC_NO_ERR)
2339                 cYAML_print_tree2file(stderr, err_rc);
2340
2341         cYAML_free_tree(err_rc);
2342
2343         return rc;
2344 }
2345
2346 static int jt_show_route(int argc, char **argv)
2347 {
2348         char *network = NULL, *gateway = NULL;
2349         long int hop = -1, prio = -1;
2350         int detail = 0, rc, opt;
2351         struct cYAML *err_rc = NULL, *show_rc = NULL;
2352         const char *const short_options = "c:n:g:p:v";
2353         static const struct option long_options[] = {
2354                 { .name = "net",       .has_arg = required_argument, .val = 'n' },
2355                 { .name = "gateway",   .has_arg = required_argument, .val = 'g' },
2356                 { .name = "hop-count", .has_arg = required_argument, .val = 'c' },
2357                 { .name = "hop",       .has_arg = required_argument, .val = 'c' },
2358                 { .name = "priority",  .has_arg = required_argument, .val = 'p' },
2359                 { .name = "verbose",   .has_arg = no_argument,       .val = 'v' },
2360                 { .name = NULL }
2361         };
2362
2363         rc = check_cmd(route_cmds, "route", "show", 0, argc, argv);
2364         if (rc)
2365                 return rc;
2366
2367         while ((opt = getopt_long(argc, argv, short_options,
2368                                    long_options, NULL)) != -1) {
2369                 switch (opt) {
2370                 case 'n':
2371                         network = optarg;
2372                         break;
2373                 case 'g':
2374                         gateway = optarg;
2375                         break;
2376                 case 'c':
2377                         rc = parse_long(optarg, &hop);
2378                         if (rc != 0) {
2379                                 /* ignore option */
2380                                 hop = -1;
2381                                 continue;
2382                         }
2383                         break;
2384                 case 'p':
2385                         rc = parse_long(optarg, &prio);
2386                         if (rc != 0) {
2387                                 /* ignore option */
2388                                 prio = -1;
2389                                 continue;
2390                         }
2391                         break;
2392                 case 'v':
2393                         detail = 1;
2394                         break;
2395                 case '?':
2396                         print_help(route_cmds, "route", "show");
2397                 default:
2398                         return 0;
2399                 }
2400         }
2401
2402         rc = yaml_lnet_route(network, gateway, hop, prio, -1,
2403                              detail, NLM_F_DUMP);
2404         if (rc <= 0) {
2405                 if (rc == -EOPNOTSUPP)
2406                         goto old_api;
2407                 return rc;
2408         }
2409 old_api:
2410         rc = lustre_lnet_show_route(network, gateway, hop, prio,
2411                                     detail ? 1 : 0, -1,
2412                                     &show_rc, &err_rc, false);
2413
2414         if (rc != LUSTRE_CFG_RC_NO_ERR)
2415                 cYAML_print_tree2file(stderr, err_rc);
2416         else if (show_rc)
2417                 cYAML_print_tree(show_rc);
2418
2419         cYAML_free_tree(err_rc);
2420         cYAML_free_tree(show_rc);
2421
2422         return rc;
2423 }
2424
2425 static int set_value_helper(int argc, char **argv,
2426                             int (*cb)(int, bool, char*, int, struct cYAML**))
2427 {
2428         char *nid = NULL;
2429         long int healthv = -1;
2430         bool all = false;
2431         long int state = -1;
2432         int rc, opt;
2433         struct cYAML *err_rc = NULL;
2434
2435         const char *const short_options = "t:n:s:a";
2436         static const struct option long_options[] = {
2437                 { .name = "nid", .has_arg = required_argument, .val = 'n' },
2438                 { .name = "health", .has_arg = required_argument, .val = 't' },
2439                 { .name = "state", .has_arg = required_argument, .val = 's' },
2440                 { .name = "all", .has_arg = no_argument, .val = 'a' },
2441                 { .name = NULL } };
2442
2443         rc = check_cmd(net_cmds, "net", "set", 0, argc, argv);
2444         if (rc)
2445                 return rc;
2446
2447         while ((opt = getopt_long(argc, argv, short_options,
2448                                    long_options, NULL)) != -1) {
2449                 switch (opt) {
2450                 case 'n':
2451                         nid = optarg;
2452                         break;
2453                 case 't':
2454                         if (parse_long(optarg, &healthv) != 0)
2455                                 healthv = -1;
2456                         break;
2457                 case 's':
2458                         if (parse_long(optarg, &state) != 0)
2459                                 state = -1;
2460                         break;
2461                 case 'a':
2462                         all = true;
2463                         break;
2464                 default:
2465                         return 0;
2466                 }
2467         }
2468
2469         if (state > -1)
2470                 rc = lustre_lnet_set_peer_state(state, nid, -1, &err_rc);
2471         else
2472                 rc = cb(healthv, all, nid, -1, &err_rc);
2473
2474         if (rc != LUSTRE_CFG_RC_NO_ERR)
2475                 cYAML_print_tree2file(stderr, err_rc);
2476
2477         cYAML_free_tree(err_rc);
2478
2479         return rc;
2480 }
2481
2482 static int jt_set_ni_value(int argc, char **argv)
2483 {
2484         char *nid = NULL;
2485         long int healthv = -1, cpp = -1;
2486         bool all = false;
2487         int rc, opt;
2488         struct cYAML *err_rc = NULL;
2489
2490         const char *const short_options = "a:m:n:t:";
2491         static const struct option long_options[] = {
2492         { .name = "all",            .has_arg = no_argument,       .val = 'a' },
2493         { .name = "conns-per-peer", .has_arg = required_argument, .val = 'm' },
2494         { .name = "nid",            .has_arg = required_argument, .val = 'n' },
2495         { .name = "health",         .has_arg = required_argument, .val = 't' },
2496         { .name = NULL } };
2497
2498         rc = check_cmd(net_cmds, "net", "set", 0, argc, argv);
2499         if (rc)
2500                 return rc;
2501
2502         while ((opt = getopt_long(argc, argv, short_options,
2503                                    long_options, NULL)) != -1) {
2504                 switch (opt) {
2505                 case 'a':
2506                         all = true;
2507                         break;
2508                 case 'm':
2509                         rc = parse_long(optarg, &cpp);
2510                         if (rc != 0) {
2511                                 /* ignore option */
2512                                 cpp = -1;
2513                                 continue;
2514                         }
2515                         break;
2516                 case 'n':
2517                         nid = optarg;
2518                         break;
2519                 case 't':
2520                         if (parse_long(optarg, &healthv) != 0) {
2521                                 /* ignore option */
2522                                 healthv = -1;
2523                                 continue;
2524                         }
2525                         break;
2526                 default:
2527                         return 0;
2528                 }
2529         }
2530
2531         if (cpp > -1)
2532                 rc = lustre_lnet_config_ni_conns_per_peer(cpp, all, nid,
2533                                                           -1, &err_rc);
2534         if (healthv > -1)
2535                 rc = lustre_lnet_config_ni_healthv(healthv, all, nid,
2536                                                    -1, &err_rc);
2537
2538         if (rc != LUSTRE_CFG_RC_NO_ERR)
2539                 cYAML_print_tree2file(stderr, err_rc);
2540
2541         cYAML_free_tree(err_rc);
2542
2543         return rc;
2544 }
2545
2546 static int jt_set_peer_ni_value(int argc, char **argv)
2547 {
2548         return set_value_helper(argc, argv, lustre_lnet_config_peer_ni_healthv);
2549 }
2550
2551 static int jt_show_recovery(int argc, char **argv)
2552 {
2553         int rc, opt;
2554         struct cYAML *err_rc = NULL, *show_rc = NULL;
2555         const char *const short_options = "lp";
2556         static const struct option long_options[] = {
2557                 { .name = "local", .has_arg = no_argument, .val = 'l' },
2558                 { .name = "peer", .has_arg = no_argument, .val = 'p' },
2559                 { .name = NULL } };
2560
2561         rc = check_cmd(debug_cmds, "debug", "recovery", 0, argc, argv);
2562         if (rc)
2563                 return rc;
2564
2565         while ((opt = getopt_long(argc, argv, short_options,
2566                                    long_options, NULL)) != -1) {
2567                 switch (opt) {
2568                 case 'l':
2569                         rc = lustre_lnet_show_local_ni_recovq(-1, &show_rc, &err_rc);
2570                         break;
2571                 case 'p':
2572                         rc = lustre_lnet_show_peer_ni_recovq(-1, &show_rc, &err_rc);
2573                         break;
2574                 default:
2575                         return 0;
2576                 }
2577         }
2578
2579         if (rc != LUSTRE_CFG_RC_NO_ERR)
2580                 cYAML_print_tree2file(stderr, err_rc);
2581         else if (show_rc)
2582                 cYAML_print_tree(show_rc);
2583
2584         cYAML_free_tree(err_rc);
2585         cYAML_free_tree(show_rc);
2586
2587         return rc;
2588 }
2589
2590 static int jt_show_peer_debug_info(int argc, char **argv)
2591 {
2592         int rc, opt;
2593         struct cYAML *err_rc = NULL;
2594         char *peer_nid = optarg;
2595         const char *const short_opts = "k";
2596         const struct option long_opts[] = {
2597         { .name = "nid", .has_arg = required_argument, .val = 'k' },
2598         { .name = NULL } };
2599
2600         rc = check_cmd(debug_cmds, "debug", "peer", 0, argc, argv);
2601
2602         if (rc)
2603                 return rc;
2604
2605         while ((opt = getopt_long(argc, argv, short_opts,
2606                                    long_opts, NULL)) != -1) {
2607                 switch (opt) {
2608                 case 'k':
2609                         peer_nid = optarg;
2610                         break;
2611                 default:
2612                         return 0;
2613                 }
2614         }
2615
2616         rc = lustre_lnet_show_peer_debug_info(peer_nid, -1, &err_rc);
2617
2618         if (rc != LUSTRE_CFG_RC_NO_ERR)
2619                 cYAML_print_tree2file(stderr, err_rc);
2620
2621         cYAML_free_tree(err_rc);
2622
2623         return rc;
2624 }
2625
2626 static int jt_show_net(int argc, char **argv)
2627 {
2628         char *network = NULL;
2629         int rc, opt;
2630         struct cYAML *err_rc = NULL, *show_rc = NULL;
2631         long int detail = 0;
2632
2633         const char *const short_options = "n:v";
2634         static const struct option long_options[] = {
2635                 { .name = "net",     .has_arg = required_argument, .val = 'n' },
2636                 { .name = "verbose", .has_arg = optional_argument, .val = 'v' },
2637                 { .name = NULL } };
2638
2639         rc = check_cmd(net_cmds, "net", "show", 0, argc, argv);
2640         if (rc)
2641                 return rc;
2642
2643         while ((opt = getopt_long(argc, argv, short_options,
2644                                    long_options, NULL)) != -1) {
2645                 switch (opt) {
2646                 case 'n':
2647                         network = optarg;
2648                         break;
2649                 case 'v':
2650                         if ((!optarg) && (argv[optind] != NULL) &&
2651                             (argv[optind][0] != '-')) {
2652                                 if (parse_long(argv[optind++], &detail) != 0)
2653                                         detail = 1;
2654                         } else {
2655                                 detail = 1;
2656                         }
2657                         break;
2658                 case '?':
2659                         print_help(net_cmds, "net", "show");
2660                 default:
2661                         return 0;
2662                 }
2663         }
2664
2665         rc = lustre_lnet_show_net(network, (int) detail, -1, &show_rc, &err_rc,
2666                                   false);
2667
2668         if (rc != LUSTRE_CFG_RC_NO_ERR)
2669                 cYAML_print_tree2file(stderr, err_rc);
2670         else if (show_rc)
2671                 cYAML_print_tree(show_rc);
2672
2673         cYAML_free_tree(err_rc);
2674         cYAML_free_tree(show_rc);
2675
2676         return rc;
2677 }
2678
2679 static int jt_show_routing(int argc, char **argv)
2680 {
2681         struct cYAML *err_rc = NULL, *show_rc = NULL;
2682         int rc;
2683
2684         rc = check_cmd(routing_cmds, "routing", "show", 0, argc, argv);
2685         if (rc)
2686                 return rc;
2687
2688         rc = lustre_lnet_show_routing(-1, &show_rc, &err_rc, false);
2689
2690         if (rc != LUSTRE_CFG_RC_NO_ERR)
2691                 cYAML_print_tree2file(stderr, err_rc);
2692         else if (show_rc)
2693                 cYAML_print_tree(show_rc);
2694
2695         cYAML_free_tree(err_rc);
2696         cYAML_free_tree(show_rc);
2697
2698         return rc;
2699 }
2700
2701 static int jt_show_stats(int argc, char **argv)
2702 {
2703         int rc;
2704         struct cYAML *show_rc = NULL, *err_rc = NULL;
2705
2706         rc = check_cmd(stats_cmds, "stats", "show", 0, argc, argv);
2707         if (rc)
2708                 return rc;
2709
2710         rc = lustre_lnet_show_stats(-1, &show_rc, &err_rc);
2711
2712         if (rc != LUSTRE_CFG_RC_NO_ERR)
2713                 cYAML_print_tree2file(stderr, err_rc);
2714         else if (show_rc)
2715                 cYAML_print_tree(show_rc);
2716
2717         cYAML_free_tree(err_rc);
2718         cYAML_free_tree(show_rc);
2719
2720         return rc;
2721 }
2722
2723 static int jt_show_udsp(int argc, char **argv)
2724 {
2725         long int idx = -1;
2726         int rc, opt;
2727         struct cYAML *err_rc = NULL, *show_rc = NULL;
2728
2729         const char *const short_options = "i:";
2730         static const struct option long_options[] = {
2731                 { .name = "idx", .has_arg = required_argument, .val = 'i' },
2732                 { .name = NULL }
2733         };
2734
2735         rc = check_cmd(udsp_cmds, "udsp", "show", 0, argc, argv);
2736         if (rc)
2737                 return rc;
2738
2739         while ((opt = getopt_long(argc, argv, short_options,
2740                                    long_options, NULL)) != -1) {
2741                 switch (opt) {
2742                 case 'i':
2743                         rc = parse_long(optarg, &idx);
2744                         if (rc != 0 || idx < -1) {
2745                                 printf("Invalid index \"%s\"\n", optarg);
2746                                 return -EINVAL;
2747                         }
2748                         break;
2749                 case '?':
2750                         print_help(net_cmds, "net", "show");
2751                 default:
2752                         return 0;
2753                 }
2754         }
2755
2756         rc = lustre_lnet_show_udsp(idx, -1, &show_rc, &err_rc);
2757
2758         if (rc != LUSTRE_CFG_RC_NO_ERR)
2759                 cYAML_print_tree2file(stderr, err_rc);
2760         else if (show_rc)
2761                 cYAML_print_tree(show_rc);
2762
2763         cYAML_free_tree(err_rc);
2764         cYAML_free_tree(show_rc);
2765
2766         return rc;
2767 }
2768
2769 static int jt_show_global(int argc, char **argv)
2770 {
2771         int rc;
2772         struct cYAML *show_rc = NULL, *err_rc = NULL;
2773
2774         rc = check_cmd(global_cmds, "global", "show", 0, argc, argv);
2775         if (rc)
2776                 return rc;
2777
2778         rc = lustre_lnet_show_numa_range(-1, &show_rc, &err_rc);
2779         if (rc != LUSTRE_CFG_RC_NO_ERR) {
2780                 cYAML_print_tree2file(stderr, err_rc);
2781                 goto out;
2782         }
2783
2784         rc = lustre_lnet_show_max_intf(-1, &show_rc, &err_rc);
2785         if (rc != LUSTRE_CFG_RC_NO_ERR) {
2786                 cYAML_print_tree2file(stderr, err_rc);
2787                 goto out;
2788         }
2789
2790         rc = lustre_lnet_show_discovery(-1, &show_rc, &err_rc);
2791         if (rc != LUSTRE_CFG_RC_NO_ERR) {
2792                 cYAML_print_tree2file(stderr, err_rc);
2793                 goto out;
2794         }
2795
2796         rc = lustre_lnet_show_drop_asym_route(-1, &show_rc, &err_rc);
2797         if (rc != LUSTRE_CFG_RC_NO_ERR) {
2798                 cYAML_print_tree2file(stderr, err_rc);
2799                 goto out;
2800         }
2801
2802         rc = lustre_lnet_show_retry_count(-1, &show_rc, &err_rc);
2803         if (rc != LUSTRE_CFG_RC_NO_ERR) {
2804                 cYAML_print_tree2file(stderr, err_rc);
2805                 goto out;
2806         }
2807
2808         rc = lustre_lnet_show_transaction_to(-1, &show_rc, &err_rc);
2809         if (rc != LUSTRE_CFG_RC_NO_ERR) {
2810                 cYAML_print_tree2file(stderr, err_rc);
2811                 goto out;
2812         }
2813
2814         rc = lustre_lnet_show_hsensitivity(-1, &show_rc, &err_rc);
2815         if (rc != LUSTRE_CFG_RC_NO_ERR) {
2816                 cYAML_print_tree2file(stderr, err_rc);
2817                 goto out;
2818         }
2819
2820         rc = lustre_lnet_show_recov_intrv(-1, &show_rc, &err_rc);
2821         if (rc != LUSTRE_CFG_RC_NO_ERR) {
2822                 cYAML_print_tree2file(stderr, err_rc);
2823                 goto out;
2824         }
2825
2826         rc = lustre_lnet_show_rtr_sensitivity(-1, &show_rc, &err_rc);
2827         if (rc != LUSTRE_CFG_RC_NO_ERR) {
2828                 cYAML_print_tree2file(stderr, err_rc);
2829                 goto out;
2830         }
2831
2832         rc = lustre_lnet_show_lnd_timeout(-1, &show_rc, &err_rc);
2833         if (rc != LUSTRE_CFG_RC_NO_ERR) {
2834                 cYAML_print_tree2file(stderr, err_rc);
2835                 goto out;
2836         }
2837
2838         rc = lustre_lnet_show_response_tracking(-1, &show_rc, &err_rc);
2839         if (rc != LUSTRE_CFG_RC_NO_ERR) {
2840                 cYAML_print_tree2file(stderr, err_rc);
2841                 goto out;
2842         }
2843
2844         rc = lustre_lnet_show_recovery_limit(-1, &show_rc, &err_rc);
2845         if (rc != LUSTRE_CFG_RC_NO_ERR) {
2846                 cYAML_print_tree2file(stderr, err_rc);
2847                 goto out;
2848         }
2849
2850         rc = lustre_lnet_show_max_recovery_ping_interval(-1, &show_rc, &err_rc);
2851         if (rc != LUSTRE_CFG_RC_NO_ERR) {
2852                 cYAML_print_tree2file(stderr, err_rc);
2853                 goto out;
2854         }
2855
2856         if (show_rc)
2857                 cYAML_print_tree(show_rc);
2858
2859 out:
2860         cYAML_free_tree(err_rc);
2861         cYAML_free_tree(show_rc);
2862
2863         return rc;
2864 }
2865
2866 static int jt_lnet(int argc, char **argv)
2867 {
2868         int rc;
2869
2870         rc = check_cmd(lnet_cmds, "lnet", NULL, 2, argc, argv);
2871         if (rc)
2872                 return rc;
2873
2874         return cfs_parser(argc, argv, lnet_cmds);
2875 }
2876
2877 static int jt_route(int argc, char **argv)
2878 {
2879         int rc;
2880
2881         rc = check_cmd(route_cmds, "route", NULL, 2, argc, argv);
2882         if (rc)
2883                 return rc;
2884
2885         return cfs_parser(argc, argv, route_cmds);
2886 }
2887
2888 static int jt_net(int argc, char **argv)
2889 {
2890         int rc;
2891
2892         rc = check_cmd(net_cmds, "net", NULL, 2, argc, argv);
2893         if (rc)
2894                 return rc;
2895
2896         return cfs_parser(argc, argv, net_cmds);
2897 }
2898
2899 static int jt_routing(int argc, char **argv)
2900 {
2901         int rc;
2902
2903         rc = check_cmd(routing_cmds, "routing", NULL, 2, argc, argv);
2904         if (rc)
2905                 return rc;
2906
2907         return cfs_parser(argc, argv, routing_cmds);
2908 }
2909
2910 static int jt_stats(int argc, char **argv)
2911 {
2912         int rc;
2913
2914         rc = check_cmd(stats_cmds, "stats", NULL, 2, argc, argv);
2915         if (rc)
2916                 return rc;
2917
2918         return cfs_parser(argc, argv, stats_cmds);
2919 }
2920
2921 static int jt_debug(int argc, char **argv)
2922 {
2923         int rc;
2924
2925         rc = check_cmd(debug_cmds, "debug", NULL, 2, argc, argv);
2926         if (rc)
2927                 return rc;
2928
2929         return cfs_parser(argc, argv, debug_cmds);
2930 }
2931
2932 static int jt_global(int argc, char **argv)
2933 {
2934         int rc;
2935
2936         rc = check_cmd(global_cmds, "global", NULL, 2, argc, argv);
2937         if (rc)
2938                 return rc;
2939
2940         return cfs_parser(argc, argv, global_cmds);
2941 }
2942
2943 static int jt_peers(int argc, char **argv)
2944 {
2945         int rc;
2946
2947         rc = check_cmd(peer_cmds, "peer", NULL, 2, argc, argv);
2948         if (rc)
2949                 return rc;
2950
2951         return cfs_parser(argc, argv, peer_cmds);
2952 }
2953
2954 static int jt_set(int argc, char **argv)
2955 {
2956         int rc;
2957
2958         rc = check_cmd(set_cmds, "set", NULL, 2, argc, argv);
2959         if (rc)
2960                 return rc;
2961
2962         return cfs_parser(argc, argv, set_cmds);
2963 }
2964
2965 static int jt_udsp(int argc, char **argv)
2966 {
2967         int rc;
2968
2969         rc = check_cmd(udsp_cmds, "udsp", NULL, 2, argc, argv);
2970         if (rc)
2971                 return rc;
2972
2973         return cfs_parser(argc, argv, udsp_cmds);
2974 }
2975
2976 static int jt_import(int argc, char **argv)
2977 {
2978         char *file = NULL;
2979         struct cYAML *err_rc = NULL;
2980         struct cYAML *show_rc = NULL;
2981         int rc = 0, return_rc = 0, opt, opt_found = 0;
2982         char cmd = 'a';
2983
2984         const char *const short_options = "adseh";
2985         static const struct option long_options[] = {
2986                 { .name = "add",  .has_arg = no_argument, .val = 'a' },
2987                 { .name = "del",  .has_arg = no_argument, .val = 'd' },
2988                 { .name = "show", .has_arg = no_argument, .val = 's' },
2989                 { .name = "exec", .has_arg = no_argument, .val = 'e' },
2990                 { .name = "help", .has_arg = no_argument, .val = 'h' },
2991                 { .name = NULL } };
2992
2993         while ((opt = getopt_long(argc, argv, short_options,
2994                                    long_options, NULL)) != -1) {
2995                 opt_found = 1;
2996                 switch (opt) {
2997                 case 'a':
2998                         cmd = opt;
2999                         break;
3000                 case 'd':
3001                 case 's':
3002                         cmd = opt;
3003                         break;
3004                 case 'e':
3005                         cmd = opt;
3006                         break;
3007                 case 'h':
3008                         printf("import FILE\n"
3009                                "import < FILE : import a file\n"
3010                                "\t--add: add configuration\n"
3011                                "\t--del: delete configuration\n"
3012                                "\t--show: show configuration\n"
3013                                "\t--exec: execute command\n"
3014                                "\t--help: display this help\n"
3015                                "If no command option is given then --add"
3016                                " is assumed by default\n");
3017                         return 0;
3018                 default:
3019                         return 0;
3020                 }
3021         }
3022
3023         /* grab the file name if one exists */
3024         if (opt_found && argc == 3)
3025                 file = argv[2];
3026         else if (!opt_found && argc == 2)
3027                 file = argv[1];
3028
3029         switch (cmd) {
3030         case 'a':
3031                 rc = lustre_yaml_config(file, &err_rc);
3032                 return_rc = lustre_yaml_exec(file, &show_rc, &err_rc);
3033                 cYAML_print_tree(show_rc);
3034                 cYAML_free_tree(show_rc);
3035                 break;
3036         case 'd':
3037                 rc = lustre_yaml_del(file, &err_rc);
3038                 break;
3039         case 's':
3040                 rc = lustre_yaml_show(file, &show_rc, &err_rc);
3041                 cYAML_print_tree(show_rc);
3042                 cYAML_free_tree(show_rc);
3043                 break;
3044         case 'e':
3045                 rc = lustre_yaml_exec(file, &show_rc, &err_rc);
3046                 cYAML_print_tree(show_rc);
3047                 cYAML_free_tree(show_rc);
3048                 break;
3049         }
3050
3051         if (rc || return_rc) {
3052                 cYAML_print_tree2file(stderr, err_rc);
3053                 cYAML_free_tree(err_rc);
3054         }
3055
3056         return rc;
3057 }
3058
3059 static int jt_export(int argc, char **argv)
3060 {
3061         struct cYAML *show_rc = NULL;
3062         struct cYAML *err_rc = NULL;
3063         int rc;
3064         FILE *f = NULL;
3065         int opt;
3066         bool backup = false;
3067         char *file = NULL;
3068
3069         const char *const short_options = "bh";
3070         static const struct option long_options[] = {
3071                 { .name = "backup", .has_arg = no_argument, .val = 'b' },
3072                 { .name = "help", .has_arg = no_argument, .val = 'h' },
3073                 { .name = NULL } };
3074
3075         while ((opt = getopt_long(argc, argv, short_options,
3076                                    long_options, NULL)) != -1) {
3077                 switch (opt) {
3078                 case 'b':
3079                         backup = true;
3080                         break;
3081                 case 'h':
3082                 default:
3083                         printf("export > FILE.yaml : export configuration\n"
3084                                "\t--backup: export only what's necessary for reconfig\n"
3085                                "\t--help: display this help\n");
3086                         return 0;
3087                 }
3088         }
3089
3090         if (backup && argc >= 3)
3091                 file = argv[2];
3092         else if (!backup && argc >= 2)
3093                 file = argv[1];
3094         else
3095                 f = stdout;
3096
3097         if (file) {
3098                 f = fopen(file, "w");
3099                 if (f == NULL)
3100                         return -1;
3101         }
3102
3103         rc = lustre_lnet_show_net(NULL, 2, -1, &show_rc, &err_rc, backup);
3104         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3105                 cYAML_print_tree2file(stderr, err_rc);
3106                 cYAML_free_tree(err_rc);
3107                 err_rc = NULL;
3108         }
3109
3110         rc = lustre_lnet_show_route(NULL, NULL, -1, -1, 1, -1, &show_rc,
3111                                     &err_rc, backup);
3112         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3113                 cYAML_print_tree2file(stderr, err_rc);
3114                 cYAML_free_tree(err_rc);
3115                 err_rc = NULL;
3116         }
3117
3118         rc = lustre_lnet_show_routing(-1, &show_rc, &err_rc, backup);
3119         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3120                 cYAML_print_tree2file(stderr, err_rc);
3121                 cYAML_free_tree(err_rc);
3122                 err_rc = NULL;
3123         }
3124
3125         rc = lustre_lnet_show_peer(NULL, 2, -1, &show_rc, &err_rc, backup);
3126         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3127                 cYAML_print_tree2file(stderr, err_rc);
3128                 cYAML_free_tree(err_rc);
3129                 err_rc = NULL;
3130         }
3131
3132         rc = lustre_lnet_show_numa_range(-1, &show_rc, &err_rc);
3133         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3134                 cYAML_print_tree2file(stderr, err_rc);
3135                 cYAML_free_tree(err_rc);
3136                 err_rc = NULL;
3137         }
3138
3139         rc = lustre_lnet_show_max_intf(-1, &show_rc, &err_rc);
3140         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3141                 cYAML_print_tree2file(stderr, err_rc);
3142                 cYAML_free_tree(err_rc);
3143                 err_rc = NULL;
3144         }
3145
3146         rc = lustre_lnet_show_discovery(-1, &show_rc, &err_rc);
3147         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3148                 cYAML_print_tree2file(stderr, err_rc);
3149                 cYAML_free_tree(err_rc);
3150                 err_rc = NULL;
3151         }
3152
3153         rc = lustre_lnet_show_drop_asym_route(-1, &show_rc, &err_rc);
3154         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3155                 cYAML_print_tree2file(stderr, err_rc);
3156                 cYAML_free_tree(err_rc);
3157                 err_rc = NULL;
3158         }
3159
3160         rc = lustre_lnet_show_retry_count(-1, &show_rc, &err_rc);
3161         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3162                 cYAML_print_tree2file(stderr, err_rc);
3163                 err_rc = NULL;
3164         }
3165
3166         rc = lustre_lnet_show_transaction_to(-1, &show_rc, &err_rc);
3167         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3168                 cYAML_print_tree2file(stderr, err_rc);
3169                 err_rc = NULL;
3170         }
3171
3172         rc = lustre_lnet_show_hsensitivity(-1, &show_rc, &err_rc);
3173         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3174                 cYAML_print_tree2file(stderr, err_rc);
3175                 err_rc = NULL;
3176         }
3177
3178         rc = lustre_lnet_show_recov_intrv(-1, &show_rc, &err_rc);
3179         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3180                 cYAML_print_tree2file(stderr, err_rc);
3181                 err_rc = NULL;
3182         }
3183
3184         rc = lustre_lnet_show_rtr_sensitivity(-1, &show_rc, &err_rc);
3185         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3186                 cYAML_print_tree2file(stderr, err_rc);
3187                 err_rc = NULL;
3188         }
3189
3190         rc = lustre_lnet_show_lnd_timeout(-1, &show_rc, &err_rc);
3191         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3192                 cYAML_print_tree2file(stderr, err_rc);
3193                 err_rc = NULL;
3194         }
3195
3196         rc = lustre_lnet_show_response_tracking(-1, &show_rc, &err_rc);
3197         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3198                 cYAML_print_tree2file(stderr, err_rc);
3199                 cYAML_free_tree(err_rc);
3200                 err_rc = NULL;
3201         }
3202
3203         rc = lustre_lnet_show_recovery_limit(-1, &show_rc, &err_rc);
3204         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3205                 cYAML_print_tree2file(stderr, err_rc);
3206                 cYAML_free_tree(err_rc);
3207                 err_rc = NULL;
3208         }
3209
3210         rc = lustre_lnet_show_max_recovery_ping_interval(-1, &show_rc, &err_rc);
3211         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3212                 cYAML_print_tree2file(stderr, err_rc);
3213                 cYAML_free_tree(err_rc);
3214                 err_rc = NULL;
3215         }
3216
3217         rc = lustre_lnet_show_udsp(-1, -1, &show_rc, &err_rc);
3218         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3219                 cYAML_print_tree2file(stderr, err_rc);
3220                 cYAML_free_tree(err_rc);
3221                 err_rc = NULL;
3222         }
3223
3224         if (show_rc != NULL) {
3225                 cYAML_print_tree2file(f, show_rc);
3226                 cYAML_free_tree(show_rc);
3227         }
3228
3229         if (argc >= 2)
3230                 fclose(f);
3231
3232         return 0;
3233 }
3234
3235 static int jt_peer_nid_common(int argc, char **argv, int cmd)
3236 {
3237         int rc = LUSTRE_CFG_RC_NO_ERR, opt;
3238         bool is_mr = true;
3239         char *prim_nid = NULL, *nidstr = NULL;
3240         char err_str[LNET_MAX_STR_LEN] = "Error";
3241         struct cYAML *err_rc = NULL;
3242         int force_lock = 0;
3243
3244         const char *const short_opts = "k:m:n:f:l";
3245         const struct option long_opts[] = {
3246         { .name = "prim_nid",   .has_arg = required_argument,   .val = 'k' },
3247         { .name = "non_mr",     .has_arg = no_argument,         .val = 'm' },
3248         { .name = "nid",        .has_arg = required_argument,   .val = 'n' },
3249         { .name = "force",      .has_arg = no_argument,         .val = 'f' },
3250         { .name = "lock_prim",  .has_arg = no_argument,         .val = 'l' },
3251         { .name = NULL } };
3252
3253         rc = check_cmd(peer_cmds, "peer", "add", 2, argc, argv);
3254         if (rc)
3255                 return rc;
3256
3257         while ((opt = getopt_long(argc, argv, short_opts,
3258                                   long_opts, NULL)) != -1) {
3259                 switch (opt) {
3260                 case 'k':
3261                         prim_nid = optarg;
3262                         break;
3263                 case 'n':
3264                         nidstr = optarg;
3265                         break;
3266                 case 'm':
3267                         if (cmd == LNETCTL_DEL_CMD) {
3268                                 rc = LUSTRE_CFG_RC_BAD_PARAM;
3269                                 snprintf(err_str, LNET_MAX_STR_LEN,
3270                                          "Unrecognized option '-%c'", opt);
3271                                 goto build_error;
3272                         }
3273                         is_mr = false;
3274                         break;
3275                 case 'f':
3276                         if (cmd == LNETCTL_ADD_CMD) {
3277                                 rc = LUSTRE_CFG_RC_BAD_PARAM;
3278                                 snprintf(err_str, LNET_MAX_STR_LEN,
3279                                          "Unrecognized option '-%c'", opt);
3280                         }
3281                         force_lock = 1;
3282                         break;
3283                 case 'l':
3284                         if (cmd == LNETCTL_DEL_CMD) {
3285                                 rc = LUSTRE_CFG_RC_BAD_PARAM;
3286                                 snprintf(err_str, LNET_MAX_STR_LEN,
3287                                          "Unrecognized option '-%c'", opt);
3288                         }
3289                         force_lock = 1;
3290                         break;
3291                 case '?':
3292                         print_help(peer_cmds, "peer",
3293                                    cmd == LNETCTL_ADD_CMD ? "add" : "del");
3294                 default:
3295                         return 0;
3296                 }
3297         }
3298
3299         rc = lustre_lnet_modify_peer(prim_nid, nidstr, is_mr, cmd,
3300                                      force_lock, -1, &err_rc);
3301         if (rc != LUSTRE_CFG_RC_NO_ERR)
3302                 goto out;
3303
3304 build_error:
3305         cYAML_build_error(rc, -1, "peer",
3306                           cmd == LNETCTL_ADD_CMD ? "add" : "del",
3307                           err_str, &err_rc);
3308
3309 out:
3310         if (rc != LUSTRE_CFG_RC_NO_ERR)
3311                 cYAML_print_tree2file(stderr, err_rc);
3312
3313         cYAML_free_tree(err_rc);
3314
3315         return rc;
3316 }
3317
3318 static int jt_add_peer_nid(int argc, char **argv)
3319 {
3320         return jt_peer_nid_common(argc, argv, LNETCTL_ADD_CMD);
3321 }
3322
3323 static int jt_del_peer_nid(int argc, char **argv)
3324 {
3325         return jt_peer_nid_common(argc, argv, LNETCTL_DEL_CMD);
3326 }
3327
3328 static int jt_show_peer(int argc, char **argv)
3329 {
3330         char *nid = NULL;
3331         int rc, opt;
3332         struct cYAML *err_rc = NULL, *show_rc = NULL;
3333         long int detail = 0;
3334
3335         const char *const short_opts = "hn:v::";
3336         const struct option long_opts[] = {
3337         { .name = "help",       .has_arg = no_argument,         .val = 'h' },
3338         { .name = "nid",        .has_arg = required_argument,   .val = 'n' },
3339         { .name = "verbose",    .has_arg = optional_argument,   .val = 'v' },
3340         { .name = NULL } };
3341
3342         rc = check_cmd(peer_cmds, "peer", "show", 1, argc, argv);
3343         if (rc)
3344                 return rc;
3345
3346         while ((opt = getopt_long(argc, argv, short_opts,
3347                                   long_opts, NULL)) != -1) {
3348                 switch (opt) {
3349                 case 'n':
3350                         nid = optarg;
3351                         break;
3352                 case 'v':
3353                         if ((!optarg) && (argv[optind] != NULL) &&
3354                             (argv[optind][0] != '-')) {
3355                                 if (parse_long(argv[optind++], &detail) != 0)
3356                                         detail = 1;
3357                         } else {
3358                                 detail = 1;
3359                         }
3360                         break;
3361                 case '?':
3362                         print_help(peer_cmds, "peer", "show");
3363                 default:
3364                         return 0;
3365                 }
3366         }
3367
3368         rc = lustre_lnet_show_peer(nid, (int) detail, -1, &show_rc, &err_rc,
3369                                    false);
3370
3371         if (rc != LUSTRE_CFG_RC_NO_ERR)
3372                 cYAML_print_tree2file(stderr, err_rc);
3373         else if (show_rc)
3374                 cYAML_print_tree(show_rc);
3375
3376         cYAML_free_tree(err_rc);
3377         cYAML_free_tree(show_rc);
3378
3379         return rc;
3380 }
3381
3382 static int jt_list_peer(int argc, char **argv)
3383 {
3384         int rc;
3385         struct cYAML *err_rc = NULL, *list_rc = NULL;
3386
3387         rc = check_cmd(peer_cmds, "peer", "list", 0, argc, argv);
3388         if (rc)
3389                 return rc;
3390
3391         rc = lustre_lnet_list_peer(-1, &list_rc, &err_rc);
3392
3393         if (rc != LUSTRE_CFG_RC_NO_ERR)
3394                 cYAML_print_tree2file(stderr, err_rc);
3395         else if (list_rc)
3396                 cYAML_print_tree(list_rc);
3397
3398         cYAML_free_tree(err_rc);
3399         cYAML_free_tree(list_rc);
3400
3401         return rc;
3402 }
3403
3404 static int jt_ping(int argc, char **argv)
3405 {
3406         struct cYAML *err_rc = NULL;
3407         struct cYAML *show_rc = NULL;
3408         int timeout = 1000;
3409         int rc = 0, opt;
3410         char *src_nidstr = NULL;
3411
3412         const char *const short_options = "hs:t:";
3413         const struct option long_options[] = {
3414         { .name = "help",       .has_arg = no_argument,         .val = 'h' },
3415         { .name = "timeout",    .has_arg = required_argument,   .val = 't' },
3416         { .name = "source",     .has_arg = required_argument,   .val = 's' },
3417         { .name = NULL } };
3418
3419         while ((opt = getopt_long(argc, argv, short_options,
3420                                   long_options, NULL)) != -1) {
3421                 switch (opt) {
3422                 case 's':
3423                         src_nidstr = optarg;
3424                         break;
3425                 case 't':
3426                         timeout = 1000 * atol(optarg);
3427                         break;
3428                 case 'h':
3429                         printf("ping nid[,nid,...]\n"
3430                                "\t --source: source nid\n"
3431                                "\t --timeout: ping timeout\n"
3432                                "\t --help: display this help\n");
3433                         return 0;
3434                 default:
3435                         return 0;
3436                 }
3437         }
3438
3439         for (; optind < argc; optind++)
3440                 rc = lustre_lnet_ping_nid(argv[optind], src_nidstr, timeout, -1,
3441                                           &show_rc, &err_rc);
3442
3443         if (show_rc)
3444                 cYAML_print_tree(show_rc);
3445
3446         if (err_rc)
3447                 cYAML_print_tree2file(stderr, err_rc);
3448
3449         cYAML_free_tree(err_rc);
3450         cYAML_free_tree(show_rc);
3451
3452         return rc;
3453 }
3454
3455 static int jt_discover(int argc, char **argv)
3456 {
3457         struct cYAML *err_rc = NULL;
3458         struct cYAML *show_rc = NULL;
3459         int force = 0;
3460         int rc = 0, opt;
3461
3462         const char *const short_options = "fh";
3463         const struct option long_options[] = {
3464                 { .name = "force",      .has_arg = no_argument, .val = 'f' },
3465                 { .name = "help",       .has_arg = no_argument, .val = 'h' },
3466                 { .name = NULL } };
3467
3468         while ((opt = getopt_long(argc, argv, short_options,
3469                                   long_options, NULL)) != -1) {
3470                 switch (opt) {
3471                 case 'f':
3472                         force = 1;
3473                         break;
3474                 case 'h':
3475                         printf("discover nid[,nid,...]\n"
3476                                "\t --force: force discovery\n"
3477                                "\t --help: display this help\n");
3478                         return 0;
3479                 default:
3480                         return 0;
3481                 }
3482         }
3483
3484         if (optind == argc) {
3485                 printf("Missing nid argument\n");
3486                 return -1;
3487         }
3488
3489         for (; optind < argc; optind++)
3490                 rc = lustre_lnet_discover_nid(argv[optind], force, -1, &show_rc,
3491                                               &err_rc);
3492
3493         if (show_rc)
3494                 cYAML_print_tree(show_rc);
3495
3496         if (err_rc)
3497                 cYAML_print_tree2file(stderr, err_rc);
3498
3499         cYAML_free_tree(err_rc);
3500         cYAML_free_tree(show_rc);
3501
3502         return rc;
3503 }
3504
3505 static int jt_add_udsp(int argc, char **argv)
3506 {
3507         char *src = NULL, *dst = NULL, *rte = NULL;
3508         struct cYAML *err_rc = NULL;
3509         union lnet_udsp_action udsp_action;
3510         long int idx = -1, priority = -1;
3511         int opt, rc = 0;
3512         char *action_type = "pref";
3513
3514         const char *const short_options = "s:d:r:p:i:";
3515         static const struct option long_options[] = {
3516         { .name = "src",         .has_arg = required_argument, .val = 's' },
3517         { .name = "dst",         .has_arg = required_argument, .val = 'd' },
3518         { .name = "rte",         .has_arg = required_argument, .val = 'r' },
3519         { .name = "priority",    .has_arg = required_argument, .val = 'p' },
3520         { .name = "idx",         .has_arg = required_argument, .val = 'i' },
3521         { .name = NULL } };
3522
3523         rc = check_cmd(udsp_cmds, "udsp", "add", 0, argc, argv);
3524         if (rc)
3525                 return rc;
3526
3527         while ((opt = getopt_long(argc, argv, short_options,
3528                                   long_options, NULL)) != -1) {
3529                 switch (opt) {
3530                 case 's':
3531                         src = optarg;
3532                         break;
3533                 case 'd':
3534                         dst = optarg;
3535                         break;
3536                 case 'r':
3537                         rte = optarg;
3538                         break;
3539                 case 'p':
3540                         rc = parse_long(optarg, &priority);
3541                         if (rc != 0 || priority < 0) {
3542                                 printf("Invalid priority \"%s\"\n", optarg);
3543                                 return -EINVAL;
3544                         }
3545                         action_type = "priority";
3546                         udsp_action.udsp_priority = priority;
3547                         break;
3548                 case 'i':
3549                         rc = parse_long(optarg, &idx);
3550                         if (rc != 0 || idx < 0) {
3551                                 printf("Invalid index \"%s\"\n", optarg);
3552                                 return -EINVAL;
3553                         }
3554                         break;
3555                 case '?':
3556                         print_help(udsp_cmds, "udsp", "add");
3557                 default:
3558                         return 0;
3559                 }
3560         }
3561
3562         if (!(src || dst || rte)) {
3563                 print_help(udsp_cmds, "udsp", "add");
3564                 return 0;
3565         }
3566
3567         rc = lustre_lnet_add_udsp(src, dst, rte, action_type, &udsp_action,
3568                                   idx, -1, &err_rc);
3569
3570         if (rc != LUSTRE_CFG_RC_NO_ERR)
3571                 cYAML_print_tree2file(stderr, err_rc);
3572
3573         cYAML_free_tree(err_rc);
3574
3575         return rc;
3576 }
3577
3578 static int jt_del_udsp(int argc, char **argv)
3579 {
3580         struct cYAML *err_rc = NULL;
3581         long int idx = -2;
3582         int opt, rc = 0;
3583         bool all = false;
3584
3585         const char *const short_options = "ai:";
3586         static const struct option long_options[] = {
3587         { .name = "all",        .has_arg = no_argument, .val = 'a' },
3588         { .name = "idx",        .has_arg = required_argument, .val = 'i' },
3589         { .name = NULL } };
3590
3591         rc = check_cmd(udsp_cmds, "udsp", "del", 0, argc, argv);
3592         if (rc)
3593                 return rc;
3594
3595         while ((opt = getopt_long(argc, argv, short_options,
3596                                   long_options, NULL)) != -1) {
3597                 switch (opt) {
3598                 case 'a':
3599                         all = true;
3600                         break;
3601                 case 'i':
3602                         rc = parse_long(optarg, &idx);
3603                         if (rc != 0 || idx < -1) {
3604                                 printf("Invalid index \"%s\"\n", optarg);
3605                                 return -EINVAL;
3606                         }
3607                         break;
3608                 case '?':
3609                         print_help(udsp_cmds, "udsp", "del");
3610                 default:
3611                         return 0;
3612                 }
3613         }
3614
3615         if (all && idx != -2) {
3616                 printf("Cannot combine --all with --idx\n");
3617                 return -EINVAL;
3618         } else if (all) {
3619                 idx = -1;
3620         } else if (idx == -2) {
3621                 printf("Must specify --idx or --all\n");
3622                 return -EINVAL;
3623         }
3624
3625         rc = lustre_lnet_del_udsp(idx, -1, &err_rc);
3626         if (rc != LUSTRE_CFG_RC_NO_ERR)
3627                 cYAML_print_tree2file(stderr, err_rc);
3628
3629         cYAML_free_tree(err_rc);
3630
3631         return rc;
3632 }
3633
3634 int main(int argc, char **argv)
3635 {
3636         int rc = 0;
3637         struct cYAML *err_rc = NULL;
3638
3639         rc = lustre_lnet_config_lib_init();
3640         if (rc < 0) {
3641                 cYAML_build_error(-1, -1, "lnetctl", "startup",
3642                                   "cannot register LNet device", &err_rc);
3643                 cYAML_print_tree2file(stderr, err_rc);
3644                 return rc;
3645         }
3646
3647         return cfs_parser(argc, argv, cmd_list);
3648 }