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