Whamcloud - gitweb
LU-10391 lnet: handle discovery with Netlink
[fs/lustre-release.git] / lnet / utils / lnetctl.c
1 /*
2  * LGPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as
8  * published by the Free Software Foundation; either version 2.1 of the
9  * License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
18  *
19  * LGPL HEADER END
20  *
21  * Copyright (c) 2014, 2017, Intel Corporation.
22  *
23  * Author:
24  *   Amir Shehata <amir.shehata@intel.com>
25  */
26 #include <getopt.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <limits.h>
31 #include <libcfs/util/ioctl.h>
32 #include <libcfs/util/parser.h>
33 #include "lnetconfig/cyaml.h"
34 #include "lnetconfig/liblnetconfig.h"
35
36 #define LNET_CONFIGURE          true
37 #define LNET_UNCONFIGURE        false
38
39 static int jt_config_lnet(int argc, char **argv);
40 static int jt_unconfig_lnet(int argc, char **argv);
41 static int jt_add_route(int argc, char **argv);
42 static int jt_add_ni(int argc, char **argv);
43 static int jt_set_routing(int argc, char **argv);
44 static int jt_del_route(int argc, char **argv);
45 static int jt_del_ni(int argc, char **argv);
46 static int jt_show_route(int argc, char **argv);
47 static int jt_show_net(int argc, char **argv);
48 static int jt_show_routing(int argc, char **argv);
49 static int jt_show_stats(int argc, char **argv);
50 static int jt_show_peer(int argc, char **argv);
51 static int jt_show_recovery(int argc, char **argv);
52 static int jt_show_global(int argc, char **argv);
53 static int jt_show_udsp(int argc, char **argv);
54 static int jt_set_tiny(int argc, char **argv);
55 static int jt_set_small(int argc, char **argv);
56 static int jt_set_large(int argc, char **argv);
57 static int jt_set_numa(int argc, char **argv);
58 static int jt_set_retry_count(int argc, char **argv);
59 static int jt_set_transaction_to(int argc, char **argv);
60 static int jt_set_recov_intrv(int argc, char **argv);
61 static int jt_set_rtr_sensitivity(int argc, char **argv);
62 static int jt_set_hsensitivity(int argc, char **argv);
63 static int jt_set_max_recovery_ping_interval(int argc, char **argv);
64 static int jt_reset_stats(int argc, char **argv);
65 static int jt_add_peer_nid(int argc, char **argv);
66 static int jt_del_peer_nid(int argc, char **argv);
67 static int jt_set_max_intf(int argc, char **argv);
68 static int jt_set_discovery(int argc, char **argv);
69 static int jt_set_drop_asym_route(int argc, char **argv);
70 static int jt_list_peer(int argc, char **argv);
71 static int jt_add_udsp(int argc, char **argv);
72 static int jt_del_udsp(int argc, char **argv);
73 /*static int jt_show_peer(int argc, char **argv);*/
74 static int jt_import(int argc, char **argv);
75 static int jt_export(int argc, char **argv);
76 static int jt_ping(int argc, char **argv);
77 static int jt_discover(int argc, char **argv);
78 static int jt_lnet(int argc, char **argv);
79 static int jt_route(int argc, char **argv);
80 static int jt_net(int argc, char **argv);
81 static int jt_routing(int argc, char **argv);
82 static int jt_set(int argc, char **argv);
83 static int jt_debug(int argc, char **argv);
84 static int jt_stats(int argc, char **argv);
85 static int jt_global(int argc, char **argv);
86 static int jt_peers(int argc, char **argv);
87 static int jt_set_ni_value(int argc, char **argv);
88 static int jt_set_peer_ni_value(int argc, char **argv);
89 static int jt_calc_service_id(int argc, char **argv);
90 static int jt_set_response_tracking(int argc, char **argv);
91 static int jt_set_recovery_limit(int argc, char **argv);
92 static int jt_udsp(int argc, char **argv);
93 static int jt_setup_mrrouting(int argc, char **argv);
94 static int jt_calc_cpt_of_nid(int argc, char **argv);
95 static int jt_show_peer_debug_info(int argc, char **argv);
96
97 command_t cmd_list[] = {
98         {"lnet", jt_lnet, 0, "lnet {configure | unconfigure} [--all]"},
99         {"route", jt_route, 0, "route {add | del | show | help}"},
100         {"net", jt_net, 0, "net {add | del | show | set | help}"},
101         {"routing", jt_routing, 0, "routing {show | help}"},
102         {"set", jt_set, 0, "set {tiny_buffers | small_buffers | large_buffers"
103                            " | routing | numa_range | max_interfaces"
104                            " | discovery | drop_asym_route | retry_count"
105                            " | transaction_timeout | health_sensitivity"
106                            " | recovery_interval | router_sensitivity"
107                            " | response_tracking | recovery_limit}"},
108         {"import", jt_import, 0, "import FILE.yaml"},
109         {"export", jt_export, 0, "export FILE.yaml"},
110         {"stats", jt_stats, 0, "stats {show | help}"},
111         {"debug", jt_debug, 0, "debug {recovery {local | peer} | peer}"},
112         {"global", jt_global, 0, "global {show | help}"},
113         {"peer", jt_peers, 0, "peer {add | del | show | list | set | help}"},
114         {"ping", jt_ping, 0, "ping nid,[nid,...]"},
115         {"discover", jt_discover, 0, "discover nid[,nid,...]"},
116         {"service-id", jt_calc_service_id, 0, "Calculate IB Lustre service ID\n"},
117         {"udsp", jt_udsp, 0, "udsp {add | del | help}"},
118         {"setup-mrrouting", jt_setup_mrrouting, 0,
119          "setup linux routing tables\n"},
120         {"cpt-of-nid", jt_calc_cpt_of_nid, 0, "Calculate the CPT associated with NID\n"
121          "\t--nid: NID to calculate the CPT of\n"
122          "\t--ncpt: Number of CPTs to consider in the calculation\n"},
123         { 0, 0, 0, NULL }
124 };
125
126 command_t lnet_cmds[] = {
127         {"configure", jt_config_lnet, 0, "configure lnet\n"
128          "\t--all: load NI configuration from module parameters\n"},
129         {"unconfigure", jt_unconfig_lnet, 0, "unconfigure lnet\n"},
130         { 0, 0, 0, NULL }
131 };
132
133 command_t route_cmds[] = {
134         {"add", jt_add_route, 0, "add a route\n"
135          "\t--net: net name (e.g. tcp0)\n"
136          "\t--gateway: gateway nid (e.g. 10.1.1.2@tcp)\n"
137          "\t--hop|hop-count: number to final destination (1 <= hops <= 255)\n"
138          "\t--priority: priority of route (0 - highest prio\n"
139          "\t--health_sensitivity: gateway health sensitivity (>= 1)\n"},
140         {"del", jt_del_route, 0, "delete a route\n"
141          "\t--net: net name (e.g. tcp0)\n"
142          "\t--gateway: gateway nid (e.g. 10.1.1.2@tcp)\n"},
143         {"show", jt_show_route, 0, "show routes\n"
144          "\t--net: net name (e.g. tcp0) to filter on\n"
145          "\t--gateway: gateway nid (e.g. 10.1.1.2@tcp) to filter on\n"
146          "\t--hop|hop-count: number to final destination (1 <= hops <= 255) to filter on\n"
147          "\t--priority: priority of route (0 - highest prio to filter on\n"
148          "\t--verbose: display detailed output per route\n"},
149         { 0, 0, 0, NULL }
150 };
151
152 command_t net_cmds[] = {
153         {"add", jt_add_ni, 0, "add a network\n"
154          "\t--net: net name (e.g. tcp0)\n"
155          "\t--if: physical interface (e.g. eth0)\n"
156          "\t--ip2net: specify networks based on IP address patterns\n"
157          "\t--peer-timeout: time to wait before declaring a peer dead\n"
158          "\t--peer-credits: define the max number of inflight messages\n"
159          "\t--peer-buffer-credits: the number of buffer credits per peer\n"
160          "\t--credits: Network Interface credits\n"
161          "\t--cpt: CPU Partitions configured net uses (e.g. [0,1]\n"
162          "\t--conns-per-peer: number of connections per peer\n"
163          "\t--skip-mr-route-setup: do not add linux route for the ni\n"
164          "\t--auth-key: Network authorization key (kfilnd only)\n"
165          "\t--traffic-class: Traffic class (kfilnd only)\n"},
166         {"del", jt_del_ni, 0, "delete a network\n"
167          "\t--net: net name (e.g. tcp0)\n"
168          "\t--if: physical interface (e.g. eth0)\n"},
169         {"show", jt_show_net, 0, "show networks\n"
170          "\t--net: net name (e.g. tcp0) to filter on\n"
171          "\t--verbose: display detailed output per network."
172                        " Optional argument of '2' outputs more stats\n"},
173         {"set", jt_set_ni_value, 0, "set local NI specific parameter\n"
174          "\t--nid: NI NID to set the\n"
175          "\t--health: specify health value to set\n"
176          "\t--conns-per-peer: number of connections per peer\n"
177          "\t--all: set all NIs value to the one specified\n"},
178         { 0, 0, 0, NULL }
179 };
180
181 command_t routing_cmds[] = {
182         {"show", jt_show_routing, 0, "show routing information\n"},
183         { 0, 0, 0, NULL }
184 };
185
186 command_t stats_cmds[] = {
187         {"show", jt_show_stats, 0, "show LNET statistics\n"},
188         {"reset", jt_reset_stats, 0, "reset LNET statistics\n"},
189         { 0, 0, 0, NULL }
190 };
191
192 command_t debug_cmds[] = {
193         {"recovery", jt_show_recovery, 0, "list recovery queues\n"
194                 "\t--local : list local recovery queue\n"
195                 "\t--peer : list peer recovery queue\n"},
196         {"peer", jt_show_peer_debug_info, 0, "show peer debug info\n"
197                 "\t--nid: peer's NID\n"},
198         { 0, 0, 0, NULL }
199 };
200
201 command_t global_cmds[] = {
202         {"show", jt_show_global, 0, "show global variables\n"},
203         { 0, 0, 0, NULL }
204 };
205
206 command_t set_cmds[] = {
207         {"tiny_buffers", jt_set_tiny, 0, "set tiny routing buffers\n"
208          "\tVALUE must be greater than 0\n"},
209         {"small_buffers", jt_set_small, 0, "set small routing buffers\n"
210          "\tVALUE must be greater than 0\n"},
211         {"large_buffers", jt_set_large, 0, "set large routing buffers\n"
212          "\tVALUE must be greater than 0\n"},
213         {"routing", jt_set_routing, 0, "enable/disable routing\n"
214          "\t0 - disable routing\n"
215          "\t1 - enable routing\n"},
216         {"numa_range", jt_set_numa, 0, "set NUMA range for NI selection\n"
217          "\tVALUE must be at least 0\n"},
218         {"max_interfaces", jt_set_max_intf, 0, "set the default value for "
219                 "max interfaces\n"
220          "\tValue must be greater than 16\n"},
221         {"discovery", jt_set_discovery, 0, "enable/disable peer discovery\n"
222          "\t0 - disable peer discovery\n"
223          "\t1 - enable peer discovery (default)\n"},
224         {"drop_asym_route", jt_set_drop_asym_route, 0,
225          "drop/accept asymmetrical route messages\n"
226          "\t0 - accept asymmetrical route messages (default)\n"
227          "\t1 - drop asymmetrical route messages\n"},
228         {"retry_count", jt_set_retry_count, 0, "number of retries\n"
229          "\t0 - turn of retries\n"
230          "\t>0 - number of retries\n"},
231         {"transaction_timeout", jt_set_transaction_to, 0, "Message/Response timeout\n"
232          "\t>0 - timeout in seconds\n"},
233         {"health_sensitivity", jt_set_hsensitivity, 0, "sensitivity to failure\n"
234          "\t0 - turn off health evaluation\n"
235          "\t>0 - sensitivity value not more than 1000\n"},
236         {"recovery_interval", jt_set_recov_intrv, 0, "interval to ping in seconds (at least 1)\n"
237          "\t>0 - time in seconds between pings\n"},
238         {"router_sensitivity", jt_set_rtr_sensitivity, 0, "router sensitivity %\n"
239          "\t100 - router interfaces need to be fully healthy to be used\n"
240          "\t<100 - router interfaces can be used even if not healthy\n"},
241         {"response_tracking", jt_set_response_tracking, 0,
242          "Set the behavior of response tracking\n"
243          "\t0 - Only LNet pings and discovery pushes utilize response tracking\n"
244          "\t1 - GETs are eligible for response tracking\n"
245          "\t2 - PUTs are eligible for response tracking\n"
246          "\t3 - Both PUTs and GETs are eligible for response tracking (default)\n"
247          "\tNote: Regardless of the value of the response_tracking parameter LNet\n"
248          "\t      pings and discovery pushes always utilize response tracking\n"},
249         {"recovery_limit", jt_set_recovery_limit, 0,
250          "Set how long LNet will attempt to recover unhealthy interfaces.\n"
251          "\t0 - Recover indefinitely (default)\n"
252          "\t>0 - Recover for the specified number of seconds.\n"},
253         {"max_recovery_ping_interval", jt_set_max_recovery_ping_interval, 0,
254          "maximum recovery ping interval\n"
255          "\t>0 - maximum recovery ping interval in seconds\n"},
256         { 0, 0, 0, NULL }
257 };
258
259 command_t peer_cmds[] = {
260         {"add", jt_add_peer_nid, 0, "add a peer NID\n"
261          "\t--prim_nid: Primary NID of the peer.\n"
262          "\t--nid: one or more peer NIDs\n"
263          "\t--non_mr: create this peer as not Multi-Rail capable\n"
264          "\t--ip2nets: specify a range of nids per peer\n"
265          "\t--lock_prim: lock primary nid\n"},
266         {"del", jt_del_peer_nid, 0, "delete a peer NID\n"
267          "\t--prim_nid: Primary NID of the peer.\n"
268          "\t--nid: list of NIDs to remove. If none provided,\n"
269          "\t       peer is deleted\n"
270          "\t--ip2nets: specify a range of nids per peer\n"
271          "\t--force: force-delete locked primary NID\n"},
272         {"show", jt_show_peer, 0, "show peer information\n"
273          "\t--nid: NID of peer to filter on.\n"
274          "\t--verbose: display detailed output per peer."
275                        " Optional argument of '2' outputs more stats\n"},
276         {"list", jt_list_peer, 0, "list all peers\n"},
277         {"set", jt_set_peer_ni_value, 0, "set peer ni specific parameter\n"
278          "\t--nid: Peer NI NID to set the\n"
279          "\t--health: specify health value to set\n"
280          "\t--all: set all peer_nis values to the one specified\n"
281          "\t--state: set peer state (DANGEROUS: for test/debug only)"},
282         { 0, 0, 0, NULL }
283 };
284
285 command_t udsp_cmds[] = {
286         {"add", jt_add_udsp, 0, "add a udsp\n"
287          "\t--src nid|net: ip2nets syntax specifying the local NID or network to match.\n"
288          "\t--dst nid:     ip2nets syntax specifying the remote NID to match.\n"
289          "\t--rte nid:     ip2nets syntax specifying the router NID to match.\n"
290          "\t--priority p:  Assign priority value p where p >= 0.\n"
291          "\t               Note: 0 is the highest priority.\n"
292          "\t--idx n:       Insert the rule in the n'th position on the list of rules.\n"
293          "\t               By default, rules are appended to the end of the rule list.\n"},
294         {"del", jt_del_udsp, 0, "delete a udsp\n"
295          "\t--all:   Delete all rules.\n"
296          "\t--idx n: Delete the rule at index n.\n"},
297         {"show", jt_show_udsp, 0, "show udsps\n"
298          "\t--idx n: Show the rule at at index n.\n"
299          "\t         By default, all rules are shown.\n"},
300         { 0, 0, 0, NULL }
301 };
302
303 static int parse_long(const char *number, long int *value)
304 {
305         char *end;
306
307         if (!number)
308                 return -1;
309
310         *value = strtol(number,  &end, 0);
311         if (end != NULL && *end != 0)
312                 return -1;
313
314         return 0;
315 }
316
317 static int jt_setup_mrrouting(int argc, char **argv)
318 {
319         int rc;
320         struct cYAML *err_rc = NULL;
321
322         rc = lustre_lnet_setup_mrrouting(&err_rc);
323
324         if (rc != LUSTRE_CFG_RC_NO_ERR)
325                 cYAML_print_tree2file(stderr, err_rc);
326
327         cYAML_free_tree(err_rc);
328
329         return rc;
330 }
331
332 static inline void print_help(const command_t cmds[], const char *cmd_type,
333                               const char *pc_name)
334 {
335         const command_t *cmd;
336
337         for (cmd = cmds; cmd->pc_name; cmd++) {
338                 if (pc_name != NULL &&
339                     strcmp(cmd->pc_name, pc_name) == 0) {
340                         printf("%s %s: %s\n", cmd_type, cmd->pc_name,
341                                cmd->pc_help);
342                         return;
343                 } else if (pc_name != NULL) {
344                         continue;
345                 }
346                 printf("%s %s: %s\n", cmd_type, cmd->pc_name, cmd->pc_help);
347         }
348 }
349
350 static int check_cmd(const command_t *cmd_list, const char *cmd,
351                      const char *sub_cmd, const int min_args,
352                      int argc, char **argv)
353 {
354         int opt;
355         int rc = 0;
356         optind = 0;
357         opterr = 0;
358
359         const char *const short_options = "h";
360         static const struct option long_options[] = {
361                 { .name = "help", .has_arg = no_argument, .val = 'h' },
362                 { .name = NULL }
363         };
364
365         if (argc < min_args) {
366                 print_help(cmd_list, cmd, sub_cmd);
367                 rc = -1;
368                 goto out;
369         } else if (argc > 2) {
370                 return 0;
371         }
372
373         while ((opt = getopt_long(argc, argv, short_options,
374                                   long_options, NULL)) != -1) {
375                 switch (opt) {
376                 case 'h':
377                         print_help(cmd_list, cmd, sub_cmd);
378                         rc = 1;
379                         break;
380                 default:
381                         rc = 0;
382                         break;
383                 }
384         }
385
386 out:
387         opterr = 1;
388         optind = 0;
389         return rc;
390 }
391
392 static int jt_set_response_tracking(int argc, char **argv)
393 {
394         long int value;
395         int rc;
396         struct cYAML *err_rc = NULL;
397
398         rc = check_cmd(set_cmds, "set", "response_tracking", 2, argc, argv);
399         if (rc)
400                 return rc;
401
402         rc = parse_long(argv[1], &value);
403         if (rc != 0) {
404                 cYAML_build_error(-1, -1, "parser", "set",
405                                   "cannot parse response_tracking value",
406                                   &err_rc);
407                 cYAML_print_tree2file(stderr, err_rc);
408                 cYAML_free_tree(err_rc);
409                 return -1;
410         }
411
412         rc = lustre_lnet_config_response_tracking(value, -1, &err_rc);
413         if (rc != LUSTRE_CFG_RC_NO_ERR)
414                 cYAML_print_tree2file(stderr, err_rc);
415
416         cYAML_free_tree(err_rc);
417
418         return rc;
419 }
420
421 static int jt_calc_service_id(int argc, char **argv)
422 {
423         int rc;
424         __u64 service_id;
425
426         rc = lustre_lnet_calc_service_id(&service_id);
427         if (rc != LUSTRE_CFG_RC_NO_ERR)
428                 return rc;
429
430         /* cYAML currently doesn't support printing hex values.
431          * Therefore just print it locally here
432          */
433         printf("service_id:\n    value: 0x%llx\n",
434                (unsigned long long)(service_id));
435
436         return rc;
437 }
438
439 static int jt_calc_cpt_of_nid(int argc, char **argv)
440 {
441         int rc, opt;
442         int cpt;
443         long int ncpts = -1;
444         char *nid = NULL;
445         struct cYAML *err_rc = NULL;
446         const char *const short_options = "n:c:h";
447         static const struct option long_options[] = {
448         { .name = "nid",       .has_arg = required_argument, .val = 'n' },
449         { .name = "ncpt",     .has_arg = required_argument, .val = 'c' },
450         { .name = NULL } };
451
452         rc = check_cmd(cmd_list, "", "cpt-of-nid", 0, argc, argv);
453         if (rc)
454                 return rc;
455
456         while ((opt = getopt_long(argc, argv, short_options,
457                                    long_options, NULL)) != -1) {
458                 switch (opt) {
459                 case 'n':
460                         nid = optarg;
461                         break;
462                 case 'c':
463                         rc = parse_long(optarg, &ncpts);
464                         if (rc != 0) {
465                                 cYAML_build_error(-1, -1, "cpt", "get",
466                                                 "cannot parse input", &err_rc);
467                                 cYAML_print_tree2file(stderr, err_rc);
468                                 cYAML_free_tree(err_rc);
469                                 return -1;
470                         }
471                         break;
472                 case '?':
473                         print_help(cmd_list, "", "cpt-of-nid");
474                 default:
475                         return 0;
476                 }
477         }
478
479         cpt = lustre_lnet_calc_cpt_of_nid(nid, ncpts);
480         if (cpt < 0)
481                 return -1;
482
483         printf("cpt:\n    value: %d\n", cpt);
484
485         return 0;
486 }
487
488 static int jt_set_recovery_limit(int argc, char **argv)
489 {
490         long int value;
491         int rc;
492         struct cYAML *err_rc = NULL;
493
494         rc = check_cmd(set_cmds, "set", "recovery_limit", 2, argc, argv);
495         if (rc)
496                 return rc;
497
498         rc = parse_long(argv[1], &value);
499         if (rc != 0) {
500                 cYAML_build_error(-1, -1, "parser", "set",
501                                   "cannot parse recovery_limit value",
502                                   &err_rc);
503                 cYAML_print_tree2file(stderr, err_rc);
504                 cYAML_free_tree(err_rc);
505                 return -1;
506         }
507
508         rc = lustre_lnet_config_recovery_limit(value, -1, &err_rc);
509         if (rc != LUSTRE_CFG_RC_NO_ERR)
510                 cYAML_print_tree2file(stderr, err_rc);
511
512         cYAML_free_tree(err_rc);
513
514         return rc;
515 }
516
517 static int jt_set_max_intf(int argc, char **argv)
518 {
519         long int value;
520         int rc;
521         struct cYAML *err_rc = NULL;
522
523         rc = check_cmd(set_cmds, "set", "max_interfaces", 2, argc, argv);
524         if (rc)
525                 return rc;
526
527         rc = parse_long(argv[1], &value);
528         if (rc != 0) {
529                 cYAML_build_error(-1, -1, "parser", "set",
530                                   "cannot parse max_interfaces value", &err_rc);
531                 cYAML_print_tree2file(stderr, err_rc);
532                 cYAML_free_tree(err_rc);
533                 return -1;
534         }
535
536         rc = lustre_lnet_config_max_intf(value, -1, &err_rc);
537         if (rc != LUSTRE_CFG_RC_NO_ERR)
538                 cYAML_print_tree2file(stderr, err_rc);
539
540         cYAML_free_tree(err_rc);
541
542         return rc;
543 }
544
545 static int jt_set_numa(int argc, char **argv)
546 {
547         long int value;
548         int rc;
549         struct cYAML *err_rc = NULL;
550
551         rc = check_cmd(set_cmds, "set", "numa_range", 2, argc, argv);
552         if (rc)
553                 return rc;
554
555         rc = parse_long(argv[1], &value);
556         if (rc != 0) {
557                 cYAML_build_error(-1, -1, "parser", "set",
558                                   "cannot parse numa_range value", &err_rc);
559                 cYAML_print_tree2file(stderr, err_rc);
560                 cYAML_free_tree(err_rc);
561                 return -1;
562         }
563
564         rc = lustre_lnet_config_numa_range(value, -1, &err_rc);
565         if (rc != LUSTRE_CFG_RC_NO_ERR)
566                 cYAML_print_tree2file(stderr, err_rc);
567
568         cYAML_free_tree(err_rc);
569
570         return rc;
571 }
572
573 static int jt_set_recov_intrv(int argc, char **argv)
574 {
575         long int value;
576         int rc;
577         struct cYAML *err_rc = NULL;
578
579         rc = check_cmd(set_cmds, "set", "recovery_interval", 2, argc, argv);
580         if (rc)
581                 return rc;
582
583         rc = parse_long(argv[1], &value);
584         if (rc != 0) {
585                 cYAML_build_error(-1, -1, "parser", "set",
586                                   "cannot parse recovery interval value", &err_rc);
587                 cYAML_print_tree2file(stderr, err_rc);
588                 cYAML_free_tree(err_rc);
589                 return -1;
590         }
591
592         rc = lustre_lnet_config_recov_intrv(value, -1, &err_rc);
593         if (rc != LUSTRE_CFG_RC_NO_ERR)
594                 cYAML_print_tree2file(stderr, err_rc);
595
596         cYAML_free_tree(err_rc);
597
598         return rc;
599 }
600
601 static int jt_set_rtr_sensitivity(int argc, char **argv)
602 {
603         long int value;
604         int rc;
605         struct cYAML *err_rc = NULL;
606
607         rc = check_cmd(set_cmds, "set", "router_sensitivity", 2, argc, argv);
608         if (rc)
609                 return rc;
610
611         rc = parse_long(argv[1], &value);
612         if (rc != 0) {
613                 cYAML_build_error(-1, -1, "parser", "set",
614                                   "cannot parse router sensitivity value", &err_rc);
615                 cYAML_print_tree2file(stderr, err_rc);
616                 cYAML_free_tree(err_rc);
617                 return -1;
618         }
619
620         rc = lustre_lnet_config_rtr_sensitivity(value, -1, &err_rc);
621         if (rc != LUSTRE_CFG_RC_NO_ERR)
622                 cYAML_print_tree2file(stderr, err_rc);
623
624         cYAML_free_tree(err_rc);
625
626         return rc;
627 }
628
629 static int jt_set_hsensitivity(int argc, char **argv)
630 {
631         long int value;
632         int rc;
633         struct cYAML *err_rc = NULL;
634
635         rc = check_cmd(set_cmds, "set", "health_sensitivity", 2, argc, argv);
636         if (rc)
637                 return rc;
638
639         rc = parse_long(argv[1], &value);
640         if (rc != 0) {
641                 cYAML_build_error(-1, -1, "parser", "set",
642                                   "cannot parse health sensitivity value", &err_rc);
643                 cYAML_print_tree2file(stderr, err_rc);
644                 cYAML_free_tree(err_rc);
645                 return -1;
646         }
647
648         rc = lustre_lnet_config_hsensitivity(value, -1, &err_rc);
649         if (rc != LUSTRE_CFG_RC_NO_ERR)
650                 cYAML_print_tree2file(stderr, err_rc);
651
652         cYAML_free_tree(err_rc);
653
654         return rc;
655 }
656
657 static int jt_reset_stats(int argc, char **argv)
658 {
659         int rc;
660         struct cYAML *err_rc = NULL;
661
662         rc = check_cmd(stats_cmds, "stats", "reset", 0, argc, argv);
663         if (rc)
664                 return rc;
665
666         rc = lustre_lnet_reset_stats(-1, &err_rc);
667         if (rc != LUSTRE_CFG_RC_NO_ERR)
668                 cYAML_print_tree2file(stderr, err_rc);
669
670         cYAML_free_tree(err_rc);
671
672         return rc;
673 }
674
675 static int jt_set_transaction_to(int argc, char **argv)
676 {
677         long int value;
678         int rc;
679         struct cYAML *err_rc = NULL;
680
681         rc = check_cmd(set_cmds, "set", "transaction_timeout", 2, argc, argv);
682         if (rc)
683                 return rc;
684
685         rc = parse_long(argv[1], &value);
686         if (rc != 0) {
687                 cYAML_build_error(-1, -1, "parser", "set",
688                                   "cannot parse transaction timeout value", &err_rc);
689                 cYAML_print_tree2file(stderr, err_rc);
690                 cYAML_free_tree(err_rc);
691                 return -1;
692         }
693
694         rc = lustre_lnet_config_transaction_to(value, -1, &err_rc);
695         if (rc != LUSTRE_CFG_RC_NO_ERR)
696                 cYAML_print_tree2file(stderr, err_rc);
697
698         cYAML_free_tree(err_rc);
699
700         return rc;
701 }
702
703 static int jt_set_retry_count(int argc, char **argv)
704 {
705         long int value;
706         int rc;
707         struct cYAML *err_rc = NULL;
708
709         rc = check_cmd(set_cmds, "set", "retry_count", 2, argc, argv);
710         if (rc)
711                 return rc;
712
713         rc = parse_long(argv[1], &value);
714         if (rc != 0) {
715                 cYAML_build_error(-1, -1, "parser", "set",
716                                   "cannot parse retry_count value", &err_rc);
717                 cYAML_print_tree2file(stderr, err_rc);
718                 cYAML_free_tree(err_rc);
719                 return -1;
720         }
721
722         rc = lustre_lnet_config_retry_count(value, -1, &err_rc);
723         if (rc != LUSTRE_CFG_RC_NO_ERR)
724                 cYAML_print_tree2file(stderr, err_rc);
725
726         cYAML_free_tree(err_rc);
727
728         return rc;
729 }
730
731 static int jt_set_discovery(int argc, char **argv)
732 {
733         long int value;
734         int rc;
735         struct cYAML *err_rc = NULL;
736
737         rc = check_cmd(set_cmds, "set", "discovery", 2, argc, argv);
738         if (rc)
739                 return rc;
740
741         rc = parse_long(argv[1], &value);
742         if (rc != 0) {
743                 cYAML_build_error(-1, -1, "parser", "set",
744                                   "cannot parse discovery value", &err_rc);
745                 cYAML_print_tree2file(stderr, err_rc);
746                 cYAML_free_tree(err_rc);
747                 return -1;
748         }
749
750         rc = lustre_lnet_config_discovery(value, -1, &err_rc);
751         if (rc != LUSTRE_CFG_RC_NO_ERR)
752                 cYAML_print_tree2file(stderr, err_rc);
753
754         cYAML_free_tree(err_rc);
755
756         return rc;
757 }
758
759 static int jt_set_drop_asym_route(int argc, char **argv)
760 {
761         long int value;
762         int rc;
763         struct cYAML *err_rc = NULL;
764
765         rc = check_cmd(set_cmds, "set", "drop_asym_route", 2, argc, argv);
766         if (rc)
767                 return rc;
768
769         rc = parse_long(argv[1], &value);
770         if (rc != 0) {
771                 cYAML_build_error(-1, -1, "parser", "set",
772                                   "cannot parse drop_asym_route value",
773                                   &err_rc);
774                 cYAML_print_tree2file(stderr, err_rc);
775                 cYAML_free_tree(err_rc);
776                 return -1;
777         }
778
779         rc = lustre_lnet_config_drop_asym_route(value, -1, &err_rc);
780         if (rc != LUSTRE_CFG_RC_NO_ERR)
781                 cYAML_print_tree2file(stderr, err_rc);
782
783         cYAML_free_tree(err_rc);
784
785         return rc;
786 }
787
788 static int jt_set_tiny(int argc, char **argv)
789 {
790         long int value;
791         int rc;
792         struct cYAML *err_rc = NULL;
793
794         rc = check_cmd(set_cmds, "set", "tiny_buffers", 2, argc, argv);
795         if (rc)
796                 return rc;
797
798         rc = parse_long(argv[1], &value);
799         if (rc != 0) {
800                 cYAML_build_error(-1, -1, "parser", "set",
801                                   "cannot parse tiny_buffers value", &err_rc);
802                 cYAML_print_tree2file(stderr, err_rc);
803                 cYAML_free_tree(err_rc);
804                 return -1;
805         }
806
807         rc = lustre_lnet_config_buffers(value, -1, -1, -1, &err_rc);
808         if (rc != LUSTRE_CFG_RC_NO_ERR)
809                 cYAML_print_tree2file(stderr, err_rc);
810
811         cYAML_free_tree(err_rc);
812
813         return rc;
814 }
815
816 static int jt_set_small(int argc, char **argv)
817 {
818         long int value;
819         int rc;
820         struct cYAML *err_rc = NULL;
821
822         rc = check_cmd(set_cmds, "set", "small_buffers", 2, argc, argv);
823         if (rc)
824                 return rc;
825
826         rc = parse_long(argv[1], &value);
827         if (rc != 0) {
828                 cYAML_build_error(-1, -1, "parser", "set",
829                                   "cannot parse small_buffers value", &err_rc);
830                 cYAML_print_tree2file(stderr, err_rc);
831                 cYAML_free_tree(err_rc);
832                 return -1;
833         }
834
835         rc = lustre_lnet_config_buffers(-1, value, -1, -1, &err_rc);
836         if (rc != LUSTRE_CFG_RC_NO_ERR)
837                 cYAML_print_tree2file(stderr, err_rc);
838
839         cYAML_free_tree(err_rc);
840
841         return rc;
842 }
843
844 static int jt_set_large(int argc, char **argv)
845 {
846         long int value;
847         int rc;
848         struct cYAML *err_rc = NULL;
849
850         rc = check_cmd(set_cmds, "set", "large_buffers", 2, argc, argv);
851         if (rc)
852                 return rc;
853
854         rc = parse_long(argv[1], &value);
855         if (rc != 0) {
856                 cYAML_build_error(-1, -1, "parser", "set",
857                                   "cannot parse large_buffers value", &err_rc);
858                 cYAML_print_tree2file(stderr, err_rc);
859                 cYAML_free_tree(err_rc);
860                 return -1;
861         }
862
863         rc = lustre_lnet_config_buffers(-1, -1, value, -1, &err_rc);
864         if (rc != LUSTRE_CFG_RC_NO_ERR)
865                 cYAML_print_tree2file(stderr, err_rc);
866
867         cYAML_free_tree(err_rc);
868
869         return rc;
870 }
871
872 static int jt_set_routing(int argc, char **argv)
873 {
874         long int value;
875         struct cYAML *err_rc = NULL;
876         int rc;
877
878         rc = check_cmd(set_cmds, "set", "routing", 2, argc, argv);
879         if (rc)
880                 return rc;
881
882         rc = parse_long(argv[1], &value);
883         if (rc != 0 || (value != 0 && value != 1)) {
884                 cYAML_build_error(-1, -1, "parser", "set",
885                                   "cannot parse routing value.\n"
886                                   "must be 0 for disable or 1 for enable",
887                                   &err_rc);
888                 cYAML_print_tree2file(stderr, err_rc);
889                 cYAML_free_tree(err_rc);
890                 return -1;
891         }
892
893         rc = lustre_lnet_enable_routing(value, -1, &err_rc);
894
895         if (rc != LUSTRE_CFG_RC_NO_ERR)
896                 cYAML_print_tree2file(stderr, err_rc);
897
898         cYAML_free_tree(err_rc);
899
900         return rc;
901 }
902
903 static int jt_set_max_recovery_ping_interval(int argc, char **argv)
904 {
905         long int value;
906         int rc;
907         struct cYAML *err_rc = NULL;
908
909         rc = check_cmd(set_cmds, "set", "maximum recovery_interval", 2, argc, argv);
910         if (rc)
911                 return rc;
912
913         rc = parse_long(argv[1], &value);
914         if (rc != 0) {
915                 cYAML_build_error(-1, -1, "parser", "set",
916                                   "cannot parse maximum recovery interval value",
917                                   &err_rc);
918                 cYAML_print_tree2file(stderr, err_rc);
919                 cYAML_free_tree(err_rc);
920                 return -1;
921         }
922
923         rc = lustre_lnet_config_max_recovery_ping_interval(value, -1, &err_rc);
924         if (rc != LUSTRE_CFG_RC_NO_ERR)
925                 cYAML_print_tree2file(stderr, err_rc);
926
927         cYAML_free_tree(err_rc);
928
929         return rc;
930 }
931
932 static void yaml_lnet_print_error(int op, char *cmd, const char *errstr)
933 {
934         char errcode[INT_STRING_LEN];
935         yaml_emitter_t log;
936         yaml_event_t event;
937         const char *flag;
938         int rc;
939
940         snprintf(errcode, sizeof(errcode), "%d", errno);
941
942         yaml_emitter_initialize(&log);
943         yaml_emitter_set_indent(&log, LNET_DEFAULT_INDENT);
944         yaml_emitter_set_output_file(&log, stderr);
945
946         yaml_emitter_open(&log);
947         yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
948         rc = yaml_emitter_emit(&log, &event);
949         if (rc == 0)
950                 goto emitter_error;
951
952         yaml_mapping_start_event_initialize(&event, NULL,
953                                             (yaml_char_t *)YAML_MAP_TAG,
954                                             1, YAML_ANY_MAPPING_STYLE);
955         rc = yaml_emitter_emit(&log, &event);
956         if (rc == 0)
957                 goto emitter_error;
958
959         switch (op) {
960         case NLM_F_CREATE:
961                 flag = "add";
962                 break;
963         case NLM_F_REPLACE:
964                 flag = "set";
965                 break;
966         case 0:
967                 flag = "del";
968                 break;
969         case -1:
970                 flag = "manage";
971                 break;
972         case NLM_F_DUMP:
973         default:
974                 flag = "show";
975                 break;
976         }
977
978         yaml_scalar_event_initialize(&event, NULL,
979                                      (yaml_char_t *)YAML_STR_TAG,
980                                      (yaml_char_t *)flag,
981                                      strlen(flag), 1, 0,
982                                      YAML_PLAIN_SCALAR_STYLE);
983         rc = yaml_emitter_emit(&log, &event);
984         if (rc == 0)
985                 goto emitter_error;
986
987         yaml_sequence_start_event_initialize(&event, NULL,
988                                              (yaml_char_t *)YAML_SEQ_TAG,
989                                              1, YAML_ANY_SEQUENCE_STYLE);
990         rc = yaml_emitter_emit(&log, &event);
991         if (rc == 0)
992                 goto emitter_error;
993
994         yaml_mapping_start_event_initialize(&event, NULL,
995                                             (yaml_char_t *)YAML_MAP_TAG,
996                                             1, YAML_ANY_MAPPING_STYLE);
997         rc = yaml_emitter_emit(&log, &event);
998         if (rc == 0)
999                 goto emitter_error;
1000
1001         yaml_scalar_event_initialize(&event, NULL,
1002                                      (yaml_char_t *)YAML_STR_TAG,
1003                                      (yaml_char_t *)cmd,
1004                                      strlen(cmd),
1005                                      1, 0, YAML_PLAIN_SCALAR_STYLE);
1006         rc = yaml_emitter_emit(&log, &event);
1007         if (rc == 0)
1008                 goto emitter_error;
1009
1010         yaml_scalar_event_initialize(&event, NULL,
1011                                      (yaml_char_t *)YAML_STR_TAG,
1012                                      (yaml_char_t *)"",
1013                                      strlen(""),
1014                                      1, 0, YAML_PLAIN_SCALAR_STYLE);
1015         rc = yaml_emitter_emit(&log, &event);
1016         if (rc == 0)
1017                 goto emitter_error;
1018
1019         yaml_scalar_event_initialize(&event, NULL,
1020                                      (yaml_char_t *)YAML_STR_TAG,
1021                                      (yaml_char_t *)"errno",
1022                                      strlen("errno"), 1, 0,
1023                                      YAML_PLAIN_SCALAR_STYLE);
1024         rc = yaml_emitter_emit(&log, &event);
1025         if (rc == 0)
1026                 goto emitter_error;
1027
1028         yaml_scalar_event_initialize(&event, NULL,
1029                                      (yaml_char_t *)YAML_INT_TAG,
1030                                      (yaml_char_t *)errcode,
1031                                      strlen(errcode), 1, 0,
1032                                      YAML_PLAIN_SCALAR_STYLE);
1033         rc = yaml_emitter_emit(&log, &event);
1034         if (rc == 0)
1035                 goto emitter_error;
1036
1037
1038         yaml_scalar_event_initialize(&event, NULL,
1039                                      (yaml_char_t *)YAML_STR_TAG,
1040                                      (yaml_char_t *)"descr",
1041                                      strlen("descr"), 1, 0,
1042                                      YAML_PLAIN_SCALAR_STYLE);
1043         rc = yaml_emitter_emit(&log, &event);
1044         if (rc == 0)
1045                 goto emitter_error;
1046
1047         yaml_scalar_event_initialize(&event, NULL,
1048                                      (yaml_char_t *)YAML_STR_TAG,
1049                                      (yaml_char_t *)errstr,
1050                                      strlen(errstr), 1, 0,
1051                                      YAML_DOUBLE_QUOTED_SCALAR_STYLE);
1052         rc = yaml_emitter_emit(&log, &event);
1053         if (rc == 0)
1054                 goto emitter_error;
1055
1056         yaml_mapping_end_event_initialize(&event);
1057         rc = yaml_emitter_emit(&log, &event);
1058         if (rc == 0)
1059                 goto emitter_error;
1060
1061         yaml_sequence_end_event_initialize(&event);
1062         rc = yaml_emitter_emit(&log, &event);
1063         if (rc == 0)
1064                 goto emitter_error;
1065
1066         yaml_mapping_end_event_initialize(&event);
1067         rc = yaml_emitter_emit(&log, &event);
1068         if (rc == 0)
1069                 goto emitter_error;
1070
1071         yaml_document_end_event_initialize(&event, 0);
1072         rc = yaml_emitter_emit(&log, &event);
1073         if (rc == 0)
1074                 goto emitter_error;
1075
1076         rc = yaml_emitter_close(&log);
1077 emitter_error:
1078         if (rc == 0)
1079                 yaml_emitter_log_error(&log, stdout);
1080         yaml_emitter_delete(&log);
1081 }
1082
1083 static int jt_config_lnet(int argc, char **argv)
1084 {
1085         struct cYAML *err_rc = NULL;
1086         bool load_mod_params = false;
1087         int rc, opt;
1088
1089         const char *const short_options = "a";
1090         static const struct option long_options[] = {
1091                 { .name = "all",  .has_arg = no_argument, .val = 'a' },
1092                 { .name = NULL }
1093         };
1094
1095         rc = check_cmd(lnet_cmds, "lnet", "configure", 0, argc, argv);
1096         if (rc)
1097                 return rc;
1098
1099         while ((opt = getopt_long(argc, argv, short_options,
1100                                    long_options, NULL)) != -1) {
1101                 switch (opt) {
1102                 case 'a':
1103                         load_mod_params = true;
1104                         break;
1105                 default:
1106                         return 0;
1107                 }
1108         }
1109
1110         rc = lustre_lnet_config_ni_system(LNET_CONFIGURE, load_mod_params,
1111                                           -1, &err_rc);
1112
1113         if (rc != LUSTRE_CFG_RC_NO_ERR)
1114                 cYAML_print_tree2file(stderr, err_rc);
1115
1116         cYAML_free_tree(err_rc);
1117
1118         return rc;
1119 }
1120
1121 static int jt_unconfig_lnet(int argc, char **argv)
1122 {
1123         struct cYAML *err_rc = NULL;
1124         int rc;
1125
1126         rc = check_cmd(lnet_cmds, "lnet", "unconfigure", 0, argc, argv);
1127         if (rc)
1128                 return rc;
1129
1130         rc = lustre_lnet_config_ni_system(LNET_UNCONFIGURE, 0, -1, &err_rc);
1131
1132         if (rc != LUSTRE_CFG_RC_NO_ERR)
1133                 cYAML_print_tree2file(stderr, err_rc);
1134
1135         cYAML_free_tree(err_rc);
1136
1137         return rc;
1138 }
1139
1140 static int yaml_lnet_router_gateways(yaml_emitter_t *output, const char *nw,
1141                                      const char *gw, int hops, int prio,
1142                                      int sen)
1143 {
1144         char num[INT_STRING_LEN];
1145         yaml_event_t event;
1146         int rc;
1147
1148         yaml_mapping_start_event_initialize(&event, NULL,
1149                                             (yaml_char_t *)YAML_MAP_TAG, 1,
1150                                             YAML_BLOCK_MAPPING_STYLE);
1151         rc = yaml_emitter_emit(output, &event);
1152         if (rc == 0)
1153                 goto emitter_error;
1154
1155         if (nw) {
1156                 yaml_scalar_event_initialize(&event, NULL,
1157                                              (yaml_char_t *)YAML_STR_TAG,
1158                                              (yaml_char_t *)"net",
1159                                              strlen("net"), 1, 0,
1160                                              YAML_PLAIN_SCALAR_STYLE);
1161                 rc = yaml_emitter_emit(output, &event);
1162                 if (rc == 0)
1163                         goto emitter_error;
1164
1165                 yaml_scalar_event_initialize(&event, NULL,
1166                                              (yaml_char_t *)YAML_STR_TAG,
1167                                              (yaml_char_t *)nw,
1168                                              strlen(nw), 1, 0,
1169                                              YAML_PLAIN_SCALAR_STYLE);
1170                 rc = yaml_emitter_emit(output, &event);
1171                 if (rc == 0)
1172                         goto emitter_error;
1173         }
1174
1175         if (gw) {
1176                 yaml_scalar_event_initialize(&event, NULL,
1177                                              (yaml_char_t *)YAML_STR_TAG,
1178                                              (yaml_char_t *)"gateway",
1179                                              strlen("gateway"), 1, 0,
1180                                              YAML_PLAIN_SCALAR_STYLE);
1181                 rc = yaml_emitter_emit(output, &event);
1182                 if (rc == 0)
1183                         goto emitter_error;
1184
1185                 yaml_scalar_event_initialize(&event, NULL,
1186                                              (yaml_char_t *)YAML_STR_TAG,
1187                                              (yaml_char_t *)gw,
1188                                              strlen(gw), 1, 0,
1189                                              YAML_PLAIN_SCALAR_STYLE);
1190                 rc = yaml_emitter_emit(output, &event);
1191                 if (rc == 0)
1192                         goto emitter_error;
1193         }
1194
1195         if (hops != -1) {
1196                 yaml_scalar_event_initialize(&event, NULL,
1197                                              (yaml_char_t *)YAML_STR_TAG,
1198                                              (yaml_char_t *)"hop",
1199                                              strlen("hop"), 1, 0,
1200                                              YAML_PLAIN_SCALAR_STYLE);
1201                 rc = yaml_emitter_emit(output, &event);
1202                 if (rc == 0)
1203                         goto emitter_error;
1204
1205                 snprintf(num, sizeof(num), "%d", hops);
1206                 yaml_scalar_event_initialize(&event, NULL,
1207                                              (yaml_char_t *)YAML_INT_TAG,
1208                                              (yaml_char_t *)num,
1209                                              strlen(num), 1, 0,
1210                                              YAML_PLAIN_SCALAR_STYLE);
1211                 rc = yaml_emitter_emit(output, &event);
1212                 if (rc == 0)
1213                         goto emitter_error;
1214         }
1215
1216         if (prio != -1) {
1217                 yaml_scalar_event_initialize(&event, NULL,
1218                                              (yaml_char_t *)YAML_STR_TAG,
1219                                              (yaml_char_t *)"priority",
1220                                              strlen("priority"), 1, 0,
1221                                              YAML_PLAIN_SCALAR_STYLE);
1222                 rc = yaml_emitter_emit(output, &event);
1223                 if (rc == 0)
1224                         goto emitter_error;
1225
1226                 snprintf(num, sizeof(num), "%d", prio);
1227                 yaml_scalar_event_initialize(&event, NULL,
1228                                              (yaml_char_t *)YAML_INT_TAG,
1229                                              (yaml_char_t *)num,
1230                                              strlen(num), 1, 0,
1231                                              YAML_PLAIN_SCALAR_STYLE);
1232                 rc = yaml_emitter_emit(output, &event);
1233                 if (rc == 0)
1234                         goto emitter_error;
1235         }
1236
1237         if (sen != -1) {
1238                 yaml_scalar_event_initialize(&event, NULL,
1239                                              (yaml_char_t *)YAML_STR_TAG,
1240                                              (yaml_char_t *)"health_sensitivity",
1241                                              strlen("health_sensitivity"),
1242                                              1, 0,
1243                                              YAML_PLAIN_SCALAR_STYLE);
1244                 rc = yaml_emitter_emit(output, &event);
1245                 if (rc == 0)
1246                         goto emitter_error;
1247
1248                 snprintf(num, sizeof(num), "%d", sen);
1249                 yaml_scalar_event_initialize(&event, NULL,
1250                                              (yaml_char_t *)YAML_INT_TAG,
1251                                              (yaml_char_t *)num,
1252                                              strlen(num), 1, 0,
1253                                              YAML_PLAIN_SCALAR_STYLE);
1254                 rc = yaml_emitter_emit(output, &event);
1255                 if (rc == 0)
1256                         goto emitter_error;
1257         }
1258
1259         yaml_mapping_end_event_initialize(&event);
1260         rc = yaml_emitter_emit(output, &event);
1261 emitter_error:
1262         return rc;
1263 }
1264
1265 static int yaml_lnet_route(char *nw, char *gw, int hops, int prio, int sen,
1266                            int version, int flags)
1267 {
1268         struct nid_node head, *entry;
1269         struct nl_sock *sk = NULL;
1270         const char *msg = NULL;
1271         yaml_emitter_t output;
1272         yaml_parser_t reply;
1273         yaml_event_t event;
1274         int rc;
1275
1276         if (!(flags & NLM_F_DUMP) && (!nw || !gw)) {
1277                 fprintf(stdout, "missing mandatory parameters:'%s'\n",
1278                         (!nw && !gw) ? "net , gateway" :
1279                         !nw ? "net" : "gateway");
1280                 return -EINVAL;
1281         }
1282
1283         /* Create Netlink emitter to send request to kernel */
1284         sk = nl_socket_alloc();
1285         if (!sk)
1286                 return -EOPNOTSUPP;
1287
1288         /* Setup parser to receive Netlink packets */
1289         rc = yaml_parser_initialize(&reply);
1290         if (rc == 0) {
1291                 nl_socket_free(sk);
1292                 return -EOPNOTSUPP;
1293         }
1294
1295         rc = yaml_parser_set_input_netlink(&reply, sk, false);
1296         if (rc == 0) {
1297                 msg = yaml_parser_get_reader_error(&reply);
1298                 goto free_reply;
1299         }
1300
1301         /* Create Netlink emitter to send request to kernel */
1302         rc = yaml_emitter_initialize(&output);
1303         if (rc == 0) {
1304                 msg = "failed to initialize emitter";
1305                 goto free_reply;
1306         }
1307
1308         rc = yaml_emitter_set_output_netlink(&output, sk, LNET_GENL_NAME,
1309                                              version, LNET_CMD_ROUTES, flags);
1310         if (rc == 0)
1311                 goto emitter_error;
1312
1313         yaml_emitter_open(&output);
1314         yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
1315         rc = yaml_emitter_emit(&output, &event);
1316         if (rc == 0)
1317                 goto emitter_error;
1318
1319         yaml_mapping_start_event_initialize(&event, NULL,
1320                                             (yaml_char_t *)YAML_MAP_TAG,
1321                                             1, YAML_ANY_MAPPING_STYLE);
1322         rc = yaml_emitter_emit(&output, &event);
1323         if (rc == 0)
1324                 goto emitter_error;
1325
1326         yaml_scalar_event_initialize(&event, NULL,
1327                                      (yaml_char_t *)YAML_STR_TAG,
1328                                      (yaml_char_t *)"route",
1329                                      strlen("route"), 1, 0,
1330                                      YAML_PLAIN_SCALAR_STYLE);
1331         rc = yaml_emitter_emit(&output, &event);
1332         if (rc == 0)
1333                 goto emitter_error;
1334
1335         /* NLM_F_DUMP can have no arguments */
1336         if (nw || gw) {
1337                 NL_INIT_LIST_HEAD(&head.children);
1338                 nl_init_list_head(&head.list);
1339                 if (gw) {
1340                         rc = lustre_lnet_parse_nid_range(&head, gw, &msg);
1341                         if (rc < 0) {
1342                                 lustre_lnet_free_list(&head);
1343                                 yaml_emitter_delete(&output);
1344                                 errno = rc;
1345                                 rc = 0;
1346                                 goto free_reply;
1347                         }
1348                 }
1349
1350                 yaml_sequence_start_event_initialize(&event, NULL,
1351                                                      (yaml_char_t *)YAML_SEQ_TAG,
1352                                                      1,
1353                                                      YAML_BLOCK_SEQUENCE_STYLE);
1354                 rc = yaml_emitter_emit(&output, &event);
1355                 if (rc == 0)
1356                         goto emitter_error;
1357
1358                 if (!nl_list_empty(&head.children)) {
1359                         nl_list_for_each_entry(entry, &head.children, list) {
1360                                 const char *nid = entry->nidstr;
1361
1362                                 rc = yaml_lnet_router_gateways(&output, nw, nid,
1363                                                                hops, prio, sen);
1364                                 if (rc == 0)
1365                                         goto emitter_error;
1366                         }
1367                 } else {
1368                         rc = yaml_lnet_router_gateways(&output, nw, NULL, hops,
1369                                                        prio, sen);
1370                         if (rc == 0)
1371                                 goto emitter_error;
1372                 }
1373
1374                 yaml_sequence_end_event_initialize(&event);
1375                 rc = yaml_emitter_emit(&output, &event);
1376                 if (rc == 0)
1377                         goto emitter_error;
1378         } else {
1379                 yaml_scalar_event_initialize(&event, NULL,
1380                                              (yaml_char_t *)YAML_STR_TAG,
1381                                              (yaml_char_t *)"",
1382                                              strlen(""), 1, 0,
1383                                              YAML_PLAIN_SCALAR_STYLE);
1384                 rc = yaml_emitter_emit(&output, &event);
1385                 if (rc == 0)
1386                         goto emitter_error;
1387         }
1388
1389         yaml_mapping_end_event_initialize(&event);
1390         rc = yaml_emitter_emit(&output, &event);
1391         if (rc == 0)
1392                 goto emitter_error;
1393
1394         yaml_document_end_event_initialize(&event, 0);
1395         rc = yaml_emitter_emit(&output, &event);
1396         if (rc == 0)
1397                 goto emitter_error;
1398
1399         rc = yaml_emitter_close(&output);
1400 emitter_error:
1401         if (rc == 0) {
1402                 yaml_emitter_log_error(&output, stderr);
1403                 rc = -EINVAL;
1404         } else {
1405                 yaml_document_t errmsg;
1406
1407                 rc = yaml_parser_load(&reply, &errmsg);
1408                 if (rc == 1 && (flags & NLM_F_DUMP)) {
1409                         yaml_emitter_t debug;
1410
1411                         rc = yaml_emitter_initialize(&debug);
1412                         if (rc == 1) {
1413                                 yaml_emitter_set_indent(&debug,
1414                                                         LNET_DEFAULT_INDENT);
1415                                 yaml_emitter_set_output_file(&debug,
1416                                                              stdout);
1417                                 rc = yaml_emitter_dump(&debug, &errmsg);
1418                         }
1419                         yaml_emitter_delete(&debug);
1420                 } else {
1421                         msg = yaml_parser_get_reader_error(&reply);
1422                         /* If we didn't find any routes just be silent */
1423                         if (msg && strcmp(msg, "No routes found") == 0)
1424                                 rc = 1;
1425                 }
1426                 yaml_document_delete(&errmsg);
1427         }
1428         yaml_emitter_delete(&output);
1429 free_reply:
1430         if (rc == 0) {
1431                 yaml_lnet_print_error(flags, "route", msg);
1432                 rc = -EINVAL;
1433         }
1434         yaml_parser_delete(&reply);
1435         nl_socket_free(sk);
1436
1437         return rc == 1 ? 0 : rc;
1438 }
1439
1440 static int jt_add_route(int argc, char **argv)
1441 {
1442         char *network = NULL, *gateway = NULL;
1443         long int hop = -1, prio = -1, sen = -1;
1444         struct cYAML *err_rc = NULL;
1445         int rc, opt;
1446
1447         const char *const short_options = "n:g:c:p:";
1448         static const struct option long_options[] = {
1449                 { .name = "net",       .has_arg = required_argument, .val = 'n' },
1450                 { .name = "gateway",   .has_arg = required_argument, .val = 'g' },
1451                 { .name = "hop",       .has_arg = required_argument, .val = 'c' },
1452                 { .name = "hop-count", .has_arg = required_argument, .val = 'c' },
1453                 { .name = "priority",  .has_arg = required_argument, .val = 'p' },
1454                 { .name = "health_sensitivity",  .has_arg = required_argument, .val = 's' },
1455                 { .name = NULL }
1456         };
1457
1458         rc = check_cmd(route_cmds, "route", "add", 0, argc, argv);
1459         if (rc)
1460                 return rc;
1461
1462         while ((opt = getopt_long(argc, argv, short_options,
1463                                    long_options, NULL)) != -1) {
1464                 switch (opt) {
1465                 case 'n':
1466                         network = optarg;
1467                         break;
1468                 case 'g':
1469                         gateway = optarg;
1470                         break;
1471                 case 'c':
1472                         rc = parse_long(optarg, &hop);
1473                         if (rc != 0) {
1474                                 /* ignore option */
1475                                 hop = -1;
1476                                 continue;
1477                         }
1478                         break;
1479                 case 'p':
1480                         rc = parse_long(optarg, &prio);
1481                         if (rc != 0) {
1482                                 /* ingore option */
1483                                 prio = -1;
1484                                 continue;
1485                         }
1486                         break;
1487                 case 's':
1488                         rc = parse_long(optarg, &sen);
1489                         if (rc != 0) {
1490                                 /* ingore option */
1491                                 sen = -1;
1492                                 continue;
1493                         }
1494                         break;
1495
1496                 case '?':
1497                         print_help(route_cmds, "route", "add");
1498                 default:
1499                         return 0;
1500                 }
1501         }
1502
1503         rc = yaml_lnet_route(network, gateway, hop, prio, sen,
1504                              LNET_GENL_VERSION, NLM_F_CREATE);
1505         if (rc <= 0) {
1506                 if (rc == -EOPNOTSUPP)
1507                         goto old_api;
1508                 return rc;
1509         }
1510 old_api:
1511         rc = lustre_lnet_config_route(network, gateway, hop, prio, sen, -1,
1512                                       &err_rc);
1513
1514         if (rc != LUSTRE_CFG_RC_NO_ERR)
1515                 cYAML_print_tree2file(stderr, err_rc);
1516
1517         cYAML_free_tree(err_rc);
1518
1519         return rc;
1520 }
1521
1522 static int yaml_add_ni_tunables(yaml_emitter_t *output,
1523                                 struct lnet_ioctl_config_lnd_tunables *tunables,
1524                                 struct lnet_dlc_network_descr *nw_descr)
1525 {
1526         char num[INT_STRING_LEN];
1527         yaml_event_t event;
1528         int rc;
1529
1530         if (tunables->lt_cmn.lct_peer_timeout < 0 &&
1531             tunables->lt_cmn.lct_peer_tx_credits <= 0 &&
1532             tunables->lt_cmn.lct_peer_rtr_credits <= 0 &&
1533             tunables->lt_cmn.lct_max_tx_credits <= 0)
1534                 goto skip_general_settings;
1535
1536         yaml_scalar_event_initialize(&event, NULL,
1537                                      (yaml_char_t *)YAML_STR_TAG,
1538                                      (yaml_char_t *)"tunables",
1539                                      strlen("tunables"), 1, 0,
1540                                      YAML_PLAIN_SCALAR_STYLE);
1541         rc = yaml_emitter_emit(output, &event);
1542         if (rc == 0)
1543                 goto error;
1544
1545         yaml_mapping_start_event_initialize(&event, NULL,
1546                                             (yaml_char_t *)YAML_MAP_TAG,
1547                                             1, YAML_ANY_MAPPING_STYLE);
1548         rc = yaml_emitter_emit(output, &event);
1549         if (rc == 0)
1550                 goto error;
1551
1552         if (tunables->lt_cmn.lct_peer_timeout >= 0) {
1553                 yaml_scalar_event_initialize(&event, NULL,
1554                                              (yaml_char_t *)YAML_STR_TAG,
1555                                              (yaml_char_t *)"peer_timeout",
1556                                              strlen("peer_timeout"), 1, 0,
1557                                              YAML_PLAIN_SCALAR_STYLE);
1558                 rc = yaml_emitter_emit(output, &event);
1559                 if (rc == 0)
1560                         goto error;
1561
1562                 snprintf(num, sizeof(num), "%u",
1563                          tunables->lt_cmn.lct_peer_timeout);
1564                 yaml_scalar_event_initialize(&event, NULL,
1565                                              (yaml_char_t *)YAML_INT_TAG,
1566                                              (yaml_char_t *)num,
1567                                              strlen(num), 1, 0,
1568                                              YAML_PLAIN_SCALAR_STYLE);
1569                 rc = yaml_emitter_emit(output, &event);
1570                 if (rc == 0)
1571                         goto error;
1572         }
1573
1574         if (tunables->lt_cmn.lct_peer_tx_credits > 0) {
1575                 yaml_scalar_event_initialize(&event, NULL,
1576                                              (yaml_char_t *)YAML_STR_TAG,
1577                                              (yaml_char_t *)"peer_credits",
1578                                              strlen("peer_credits"), 1, 0,
1579                                              YAML_PLAIN_SCALAR_STYLE);
1580                 rc = yaml_emitter_emit(output, &event);
1581                 if (rc == 0)
1582                         goto error;
1583
1584                 snprintf(num, sizeof(num), "%u",
1585                          tunables->lt_cmn.lct_peer_tx_credits);
1586                 yaml_scalar_event_initialize(&event, NULL,
1587                                              (yaml_char_t *)YAML_INT_TAG,
1588                                              (yaml_char_t *)num,
1589                                              strlen(num), 1, 0,
1590                                              YAML_PLAIN_SCALAR_STYLE);
1591                 rc = yaml_emitter_emit(output, &event);
1592                 if (rc == 0)
1593                         goto error;
1594         }
1595
1596         if (tunables->lt_cmn.lct_peer_rtr_credits > 0) {
1597                 yaml_scalar_event_initialize(&event, NULL,
1598                                              (yaml_char_t *)YAML_STR_TAG,
1599                                              (yaml_char_t *)"peer_buffer_credits",
1600                                              strlen("peer_buffer_credits"), 1, 0,
1601                                              YAML_PLAIN_SCALAR_STYLE);
1602                 rc = yaml_emitter_emit(output, &event);
1603                 if (rc == 0)
1604                         goto error;
1605
1606                 snprintf(num, sizeof(num), "%u",
1607                          tunables->lt_cmn.lct_peer_rtr_credits);
1608                 yaml_scalar_event_initialize(&event, NULL,
1609                                              (yaml_char_t *)YAML_INT_TAG,
1610                                              (yaml_char_t *)num,
1611                                              strlen(num), 1, 0,
1612                                              YAML_PLAIN_SCALAR_STYLE);
1613                 rc = yaml_emitter_emit(output, &event);
1614                 if (rc == 0)
1615                         goto error;
1616         }
1617
1618         if (tunables->lt_cmn.lct_max_tx_credits > 0) {
1619                 yaml_scalar_event_initialize(&event, NULL,
1620                                              (yaml_char_t *)YAML_STR_TAG,
1621                                              (yaml_char_t *)"credits",
1622                                              strlen("credits"), 1, 0,
1623                                              YAML_PLAIN_SCALAR_STYLE);
1624                 rc = yaml_emitter_emit(output, &event);
1625                 if (rc == 0)
1626                         goto error;
1627
1628                 snprintf(num, sizeof(num), "%u",
1629                          tunables->lt_cmn.lct_max_tx_credits);
1630                 yaml_scalar_event_initialize(&event, NULL,
1631                                              (yaml_char_t *)YAML_INT_TAG,
1632                                              (yaml_char_t *)num,
1633                                              strlen(num), 1, 0,
1634                                              YAML_PLAIN_SCALAR_STYLE);
1635                 rc = yaml_emitter_emit(output, &event);
1636                 if (rc == 0)
1637                         goto error;
1638         }
1639
1640         yaml_mapping_end_event_initialize(&event);
1641         rc = yaml_emitter_emit(output, &event);
1642         if (rc == 0)
1643                 goto error;
1644
1645 skip_general_settings:
1646         if (tunables->lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer > 0 ||
1647 #ifdef HAVE_KFILND
1648             tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_auth_key > 0 ||
1649             tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_traffic_class_str[0] ||
1650 #endif
1651             tunables->lt_tun.lnd_tun_u.lnd_o2ib.lnd_conns_per_peer > 0) {
1652                 yaml_scalar_event_initialize(&event, NULL,
1653                                              (yaml_char_t *)YAML_STR_TAG,
1654                                              (yaml_char_t *)"lnd tunables",
1655                                              strlen("lnd tunables"), 1, 0,
1656                                              YAML_PLAIN_SCALAR_STYLE);
1657                 rc = yaml_emitter_emit(output, &event);
1658                 if (rc == 0)
1659                         goto error;
1660
1661                 yaml_mapping_start_event_initialize(&event, NULL,
1662                                                     (yaml_char_t *)YAML_MAP_TAG,
1663                                                     1, YAML_ANY_MAPPING_STYLE);
1664                 rc = yaml_emitter_emit(output, &event);
1665                 if (rc == 0)
1666                         goto error;
1667 #ifdef HAVE_KFILND
1668                 if (tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_auth_key > 0) {
1669                         yaml_scalar_event_initialize(&event, NULL,
1670                                                      (yaml_char_t *)YAML_STR_TAG,
1671                                                      (yaml_char_t *)"auth_key",
1672                                                      strlen("auth_key"), 1, 0,
1673                                                      YAML_PLAIN_SCALAR_STYLE);
1674                         rc = yaml_emitter_emit(output, &event);
1675                         if (rc == 0)
1676                                 goto error;
1677
1678                         snprintf(num, sizeof(num), "%u",
1679                                  tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_auth_key);
1680
1681                         yaml_scalar_event_initialize(&event, NULL,
1682                                                      (yaml_char_t *)YAML_INT_TAG,
1683                                                      (yaml_char_t *)num,
1684                                                      strlen(num), 1, 0,
1685                                                      YAML_PLAIN_SCALAR_STYLE);
1686                         rc = yaml_emitter_emit(output, &event);
1687                         if (rc == 0)
1688                                 goto error;
1689                 }
1690
1691                 if (tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_traffic_class_str[0]) {
1692                         char *tc = &tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_traffic_class_str[0];
1693
1694                         yaml_scalar_event_initialize(&event, NULL,
1695                                                      (yaml_char_t *)YAML_STR_TAG,
1696                                                      (yaml_char_t *)"traffic_class",
1697                                                      strlen("traffic_class"), 1, 0,
1698                                                      YAML_PLAIN_SCALAR_STYLE);
1699                         rc = yaml_emitter_emit(output, &event);
1700                         if (rc == 0)
1701                                 goto error;
1702
1703                         yaml_scalar_event_initialize(&event, NULL,
1704                                                      (yaml_char_t *)YAML_INT_TAG,
1705                                                      (yaml_char_t *)tc,
1706                                                      strlen(tc), 1, 0,
1707                                                      YAML_PLAIN_SCALAR_STYLE);
1708
1709                         rc = yaml_emitter_emit(output, &event);
1710                         if (rc == 0)
1711                                 goto error;
1712                 }
1713 #endif
1714                 if (tunables->lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer > 0 ||
1715                     tunables->lt_tun.lnd_tun_u.lnd_o2ib.lnd_conns_per_peer > 0) {
1716                         int cpp = 0;
1717
1718                         yaml_scalar_event_initialize(&event, NULL,
1719                                                      (yaml_char_t *)YAML_STR_TAG,
1720                                                      (yaml_char_t *)"conns_per_peer",
1721                                                      strlen("conns_per_peer"), 1, 0,
1722                                                      YAML_PLAIN_SCALAR_STYLE);
1723                         rc = yaml_emitter_emit(output, &event);
1724                         if (rc == 0)
1725                                 goto error;
1726
1727                         if (LNET_NETTYP(nw_descr->nw_id) == SOCKLND)
1728                                 cpp = tunables->lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer;
1729                         else if (LNET_NETTYP(nw_descr->nw_id) == O2IBLND)
1730                                 cpp = tunables->lt_tun.lnd_tun_u.lnd_o2ib.lnd_conns_per_peer;
1731                         snprintf(num, sizeof(num), "%u", cpp);
1732
1733                         yaml_scalar_event_initialize(&event, NULL,
1734                                                      (yaml_char_t *)YAML_INT_TAG,
1735                                                      (yaml_char_t *)num,
1736                                                      strlen(num), 1, 0,
1737                                                      YAML_PLAIN_SCALAR_STYLE);
1738                         rc = yaml_emitter_emit(output, &event);
1739                         if (rc == 0)
1740                                 goto error;
1741                 }
1742
1743                 yaml_mapping_end_event_initialize(&event);
1744                 rc = yaml_emitter_emit(output, &event);
1745         }
1746 error:
1747         return rc;
1748 }
1749
1750 static int yaml_lnet_config_ni(char *net_id, char *ip2net,
1751                                struct lnet_dlc_network_descr *nw_descr,
1752                                struct lnet_ioctl_config_lnd_tunables *tunables,
1753                                struct cfs_expr_list *global_cpts,
1754                                int version, int flags)
1755 {
1756         struct lnet_dlc_intf_descr *intf;
1757         struct nl_sock *sk = NULL;
1758         const char *msg = NULL;
1759         yaml_emitter_t output;
1760         yaml_parser_t reply;
1761         yaml_event_t event;
1762         int rc;
1763
1764         if (!(flags & NLM_F_DUMP) && !ip2net && (!nw_descr || nw_descr->nw_id == 0)) {
1765                 fprintf(stdout, "missing mandatory parameters in NI config: '%s'",
1766                         (!nw_descr) ? "network , interface" :
1767                         (nw_descr->nw_id == 0) ? "network" : "interface");
1768                 return -EINVAL;
1769         }
1770
1771         if ((flags == NLM_F_CREATE) && !ip2net && list_empty(&nw_descr->nw_intflist)) {
1772                 fprintf(stdout, "creating a local NI needs at least one interface");
1773                 return -EINVAL;
1774         }
1775
1776         /* Create Netlink emitter to send request to kernel */
1777         sk = nl_socket_alloc();
1778         if (!sk)
1779                 return -EOPNOTSUPP;
1780
1781         /* Setup parser to receive Netlink packets */
1782         rc = yaml_parser_initialize(&reply);
1783         if (rc == 0) {
1784                 nl_socket_free(sk);
1785                 return -EOPNOTSUPP;
1786         }
1787
1788         rc = yaml_parser_set_input_netlink(&reply, sk, false);
1789         if (rc == 0) {
1790                 msg = yaml_parser_get_reader_error(&reply);
1791                 goto free_reply;
1792         }
1793
1794         /* Create Netlink emitter to send request to kernel */
1795         rc = yaml_emitter_initialize(&output);
1796         if (rc == 0) {
1797                 msg = "failed to initialize emitter";
1798                 goto free_reply;
1799         }
1800
1801         rc = yaml_emitter_set_output_netlink(&output, sk, LNET_GENL_NAME,
1802                                              version, LNET_CMD_NETS, flags);
1803         if (rc == 0)
1804                 goto emitter_error;
1805
1806         yaml_emitter_open(&output);
1807         yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
1808         rc = yaml_emitter_emit(&output, &event);
1809         if (rc == 0)
1810                 goto emitter_error;
1811
1812         yaml_mapping_start_event_initialize(&event, NULL,
1813                                             (yaml_char_t *)YAML_MAP_TAG,
1814                                             1, YAML_ANY_MAPPING_STYLE);
1815         rc = yaml_emitter_emit(&output, &event);
1816         if (rc == 0)
1817                 goto emitter_error;
1818
1819         yaml_scalar_event_initialize(&event, NULL,
1820                                      (yaml_char_t *)YAML_STR_TAG,
1821                                      (yaml_char_t *)"net",
1822                                      strlen("net"), 1, 0,
1823                                      YAML_PLAIN_SCALAR_STYLE);
1824         rc = yaml_emitter_emit(&output, &event);
1825         if (rc == 0)
1826                 goto emitter_error;
1827
1828         if (net_id || ip2net) {
1829                 char *key = net_id ? "net type" : "ip2net";
1830                 char *value = net_id ? net_id : ip2net;
1831
1832                 yaml_sequence_start_event_initialize(&event, NULL,
1833                                                      (yaml_char_t *)YAML_SEQ_TAG,
1834                                                      1, YAML_ANY_SEQUENCE_STYLE);
1835                 rc = yaml_emitter_emit(&output, &event);
1836                 if (rc == 0)
1837                         goto emitter_error;
1838
1839                 yaml_mapping_start_event_initialize(&event, NULL,
1840                                                     (yaml_char_t *)YAML_MAP_TAG,
1841                                                     1, YAML_ANY_MAPPING_STYLE);
1842                 rc = yaml_emitter_emit(&output, &event);
1843                 if (rc == 0)
1844                         goto emitter_error;
1845
1846                 yaml_scalar_event_initialize(&event, NULL,
1847                                              (yaml_char_t *)YAML_STR_TAG,
1848                                              (yaml_char_t *)key,
1849                                              strlen(key),
1850                                              1, 0, YAML_PLAIN_SCALAR_STYLE);
1851                 rc = yaml_emitter_emit(&output, &event);
1852                 if (rc == 0)
1853                         goto emitter_error;
1854
1855                 yaml_scalar_event_initialize(&event, NULL,
1856                                              (yaml_char_t *)YAML_STR_TAG,
1857                                              (yaml_char_t *)value,
1858                                              strlen(value), 1, 0,
1859                                              YAML_PLAIN_SCALAR_STYLE);
1860                 rc = yaml_emitter_emit(&output, &event);
1861                 if (rc == 0)
1862                         goto emitter_error;
1863         } else {
1864                 yaml_scalar_event_initialize(&event, NULL,
1865                                              (yaml_char_t *)YAML_STR_TAG,
1866                                              (yaml_char_t *)"",
1867                                              strlen(""), 1, 0,
1868                                              YAML_PLAIN_SCALAR_STYLE);
1869                 rc = yaml_emitter_emit(&output, &event);
1870                 if (rc == 0)
1871                         goto emitter_error;
1872
1873                 goto no_net_id;
1874         }
1875
1876         if (!nw_descr || list_empty(&nw_descr->nw_intflist))
1877                 goto skip_intf;
1878
1879         yaml_scalar_event_initialize(&event, NULL,
1880                                      (yaml_char_t *)YAML_STR_TAG,
1881                                      (yaml_char_t *)"local NI(s)",
1882                                      strlen("local NI(s)"), 1, 0,
1883                                      YAML_PLAIN_SCALAR_STYLE);
1884         rc = yaml_emitter_emit(&output, &event);
1885         if (rc == 0)
1886                 goto emitter_error;
1887
1888         yaml_sequence_start_event_initialize(&event, NULL,
1889                                              (yaml_char_t *)YAML_SEQ_TAG,
1890                                              1, YAML_ANY_SEQUENCE_STYLE);
1891         rc = yaml_emitter_emit(&output, &event);
1892         if (rc == 0)
1893                 goto emitter_error;
1894
1895         list_for_each_entry(intf, &nw_descr->nw_intflist,
1896                             intf_on_network) {
1897                 yaml_mapping_start_event_initialize(&event, NULL,
1898                                                     (yaml_char_t *)YAML_MAP_TAG,
1899                                                     1, YAML_ANY_MAPPING_STYLE);
1900                 rc = yaml_emitter_emit(&output, &event);
1901                 if (rc == 0)
1902                         goto emitter_error;
1903
1904                 yaml_scalar_event_initialize(&event, NULL,
1905                                              (yaml_char_t *)YAML_STR_TAG,
1906                                              (yaml_char_t *)"interfaces",
1907                                              strlen("interfaces"), 1, 0,
1908                                              YAML_PLAIN_SCALAR_STYLE);
1909                 rc = yaml_emitter_emit(&output, &event);
1910                 if (rc == 0)
1911                         goto emitter_error;
1912
1913                 yaml_mapping_start_event_initialize(&event, NULL,
1914                                                     (yaml_char_t *)YAML_MAP_TAG,
1915                                                     1, YAML_ANY_MAPPING_STYLE);
1916                 rc = yaml_emitter_emit(&output, &event);
1917                 if (rc == 0)
1918                         goto emitter_error;
1919
1920                 yaml_scalar_event_initialize(&event, NULL,
1921                                              (yaml_char_t *)YAML_STR_TAG,
1922                                              (yaml_char_t *)"0",
1923                                              strlen("0"), 1, 0,
1924                                              YAML_PLAIN_SCALAR_STYLE);
1925                 rc = yaml_emitter_emit(&output, &event);
1926                 if (rc == 0)
1927                         goto emitter_error;
1928
1929                 yaml_scalar_event_initialize(&event, NULL,
1930                                              (yaml_char_t *)YAML_STR_TAG,
1931                                              (yaml_char_t *)intf->intf_name,
1932                                              strlen(intf->intf_name), 1, 0,
1933                                              YAML_PLAIN_SCALAR_STYLE);
1934                 rc = yaml_emitter_emit(&output, &event);
1935                 if (rc == 0)
1936                         goto emitter_error;
1937
1938                 yaml_mapping_end_event_initialize(&event);
1939                 rc = yaml_emitter_emit(&output, &event);
1940                 if (rc == 0)
1941                         goto emitter_error;
1942
1943                 if (tunables) {
1944                         rc = yaml_add_ni_tunables(&output, tunables, nw_descr);
1945                         if (rc == 0)
1946                                 goto emitter_error;
1947                 }
1948
1949                 if (global_cpts) {
1950                         __u32 *cpt_array;
1951                         int count, i;
1952
1953                         yaml_scalar_event_initialize(&event, NULL,
1954                                                      (yaml_char_t *)YAML_STR_TAG,
1955                                                      (yaml_char_t *)"CPT",
1956                                                      strlen("CPT"), 1, 0,
1957                                                      YAML_PLAIN_SCALAR_STYLE);
1958                         rc = yaml_emitter_emit(&output, &event);
1959                         if (rc == 0)
1960                                 goto emitter_error;
1961
1962                         yaml_sequence_start_event_initialize(&event, NULL,
1963                                                              (yaml_char_t *)YAML_SEQ_TAG,
1964                                                              1,
1965                                                              YAML_FLOW_SEQUENCE_STYLE);
1966                         rc = yaml_emitter_emit(&output, &event);
1967                         if (rc == 0)
1968                                 goto emitter_error;
1969
1970                         count = cfs_expr_list_values(global_cpts,
1971                                                      LNET_MAX_SHOW_NUM_CPT,
1972                                                      &cpt_array);
1973                         for (i = 0; i < count; i++) {
1974                                 char core[INT_STRING_LEN];
1975
1976                                 snprintf(core, sizeof(core), "%u", cpt_array[i]);
1977                                 yaml_scalar_event_initialize(&event, NULL,
1978                                                              (yaml_char_t *)YAML_STR_TAG,
1979                                                              (yaml_char_t *)core,
1980                                                              strlen(core), 1, 0,
1981                                                              YAML_PLAIN_SCALAR_STYLE);
1982                                 rc = yaml_emitter_emit(&output, &event);
1983                                 if (rc == 0)
1984                                         goto emitter_error;
1985                         }
1986
1987                         yaml_sequence_end_event_initialize(&event);
1988                         rc = yaml_emitter_emit(&output, &event);
1989                         if (rc == 0)
1990                                 goto emitter_error;
1991
1992                         cfs_expr_list_free(global_cpts);
1993                         free(cpt_array);
1994                 }
1995
1996                 yaml_mapping_end_event_initialize(&event);
1997                 rc = yaml_emitter_emit(&output, &event);
1998                 if (rc == 0)
1999                         goto emitter_error;
2000         }
2001
2002         yaml_sequence_end_event_initialize(&event);
2003         rc = yaml_emitter_emit(&output, &event);
2004         if (rc == 0)
2005                 goto emitter_error;
2006 skip_intf:
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_sequence_end_event_initialize(&event);
2013         rc = yaml_emitter_emit(&output, &event);
2014         if (rc == 0)
2015                 goto emitter_error;
2016 no_net_id:
2017         yaml_mapping_end_event_initialize(&event);
2018         rc = yaml_emitter_emit(&output, &event);
2019         if (rc == 0)
2020                 goto emitter_error;
2021
2022         yaml_document_end_event_initialize(&event, 0);
2023         rc = yaml_emitter_emit(&output, &event);
2024         if (rc == 0)
2025                 goto emitter_error;
2026
2027         rc = yaml_emitter_close(&output);
2028 emitter_error:
2029         if (rc == 0) {
2030                 yaml_emitter_log_error(&output, stderr);
2031                 rc = -EINVAL;
2032         } else {
2033                 yaml_document_t errmsg;
2034
2035                 rc = yaml_parser_load(&reply, &errmsg);
2036                 if (rc == 1 && (flags & NLM_F_DUMP)) {
2037                         yaml_emitter_t debug;
2038
2039                         rc = yaml_emitter_initialize(&debug);
2040                         if (rc == 1) {
2041                                 yaml_emitter_set_indent(&debug,
2042                                                         LNET_DEFAULT_INDENT);
2043                                 yaml_emitter_set_output_file(&debug, stdout);
2044                                 rc = yaml_emitter_dump(&debug, &errmsg);
2045                         }
2046                         yaml_emitter_delete(&debug);
2047                 } else {
2048                         msg = yaml_parser_get_reader_error(&reply);
2049                 }
2050                 yaml_document_delete(&errmsg);
2051         }
2052         yaml_emitter_delete(&output);
2053 free_reply:
2054         if (rc == 0) {
2055                 yaml_lnet_print_error(flags, "net", msg);
2056                 rc = -EINVAL;
2057         }
2058         yaml_parser_delete(&reply);
2059         nl_socket_free(sk);
2060
2061         return rc == 1 ? 0 : rc;
2062 }
2063
2064 static int jt_add_ni(int argc, char **argv)
2065 {
2066         char *ip2net = NULL;
2067         long int pto = -1, pc = -1, pbc = -1, cre = -1, cpp = -1, auth_key = -1;
2068         char *traffic_class = NULL;
2069         struct cYAML *err_rc = NULL;
2070         int rc, opt, cpt_rc = -1;
2071         struct lnet_dlc_network_descr nw_descr;
2072         struct cfs_expr_list *global_cpts = NULL;
2073         struct lnet_ioctl_config_lnd_tunables tunables;
2074         bool found = false;
2075         bool skip_mr_route_setup = false;
2076         const char *const short_options = "a:b:c:i:k:m:n:p:r:s:t:T:";
2077         static const struct option long_options[] = {
2078         { .name = "auth-key",     .has_arg = required_argument, .val = 'a' },
2079         { .name = "peer-buffer-credits",
2080                                   .has_arg = required_argument, .val = 'b' },
2081         { .name = "peer-credits", .has_arg = required_argument, .val = 'c' },
2082         { .name = "if",           .has_arg = required_argument, .val = 'i' },
2083         { .name = "skip-mr-route-setup",
2084                                   .has_arg = no_argument, .val = 'k' },
2085         { .name = "conns-per-peer",
2086                                   .has_arg = required_argument, .val = 'm' },
2087         { .name = "net",          .has_arg = required_argument, .val = 'n' },
2088         { .name = "ip2net",       .has_arg = required_argument, .val = 'p' },
2089         { .name = "credits",      .has_arg = required_argument, .val = 'r' },
2090         { .name = "cpt",          .has_arg = required_argument, .val = 's' },
2091         { .name = "peer-timeout", .has_arg = required_argument, .val = 't' },
2092         { .name = "traffic-class", .has_arg = required_argument, .val = 'T' },
2093         { .name = NULL } };
2094         char *net_id = NULL;
2095
2096         memset(&tunables, 0, sizeof(tunables));
2097         lustre_lnet_init_nw_descr(&nw_descr);
2098
2099         rc = check_cmd(net_cmds, "net", "add", 0, argc, argv);
2100         if (rc)
2101                 return rc;
2102
2103         while ((opt = getopt_long(argc, argv, short_options,
2104                                    long_options, NULL)) != -1) {
2105                 switch (opt) {
2106                 case 'a':
2107                         rc = parse_long(optarg, &auth_key);
2108                         if (rc != 0) {
2109                                 /* ignore option */
2110                                 auth_key = -1;
2111                                 continue;
2112                         }
2113                         break;
2114                 case 'b':
2115                         rc = parse_long(optarg, &pbc);
2116                         if (rc != 0) {
2117                                 /* ignore option */
2118                                 pbc = -1;
2119                                 continue;
2120                         }
2121                         break;
2122                 case 'c':
2123                         rc = parse_long(optarg, &pc);
2124                         if (rc != 0) {
2125                                 /* ignore option */
2126                                 pc = -1;
2127                                 continue;
2128                         }
2129                         break;
2130                 case 'i':
2131                         rc = lustre_lnet_parse_interfaces(optarg, &nw_descr);
2132                         if (rc != 0) {
2133                                 cYAML_build_error(-1, -1, "ni", "add",
2134                                                 "bad interface list",
2135                                                 &err_rc);
2136                                 goto failed;
2137                         }
2138                         break;
2139                 case 'k':
2140                         skip_mr_route_setup = true;
2141                         break;
2142                 case 'm':
2143                         rc = parse_long(optarg, &cpp);
2144                         if (rc != 0) {
2145                                 /* ignore option */
2146                                 cpp = -1;
2147                                 continue;
2148                         }
2149                         break;
2150
2151                 case 'n':
2152                         nw_descr.nw_id = libcfs_str2net(optarg);
2153                         net_id = optarg;
2154                         break;
2155                 case 'p':
2156                         ip2net = optarg;
2157                         break;
2158                 case 'r':
2159                         rc = parse_long(optarg, &cre);
2160                         if (rc != 0) {
2161                                 /* ignore option */
2162                                 cre = -1;
2163                                 continue;
2164                         }
2165                         break;
2166                 case 's':
2167                         cpt_rc = cfs_expr_list_parse(optarg,
2168                                                      strlen(optarg), 0,
2169                                                      UINT_MAX, &global_cpts);
2170                         break;
2171                 case 't':
2172                         rc = parse_long(optarg, &pto);
2173                         if (rc != 0) {
2174                                 /* ignore option */
2175                                 pto = -1;
2176                                 continue;
2177                         }
2178                         break;
2179                 case 'T':
2180                         traffic_class = optarg;
2181                         if (strlen(traffic_class) == 0 ||
2182                             strlen(traffic_class) >= LNET_MAX_STR_LEN) {
2183                                 cYAML_build_error(-1, -1, "ni", "add",
2184                                                   "Invalid traffic-class argument",
2185                                                   &err_rc);
2186                                 rc = LUSTRE_CFG_RC_BAD_PARAM;
2187                                 goto failed;
2188                         }
2189                         break;
2190                 case '?':
2191                         print_help(net_cmds, "net", "add");
2192                 default:
2193                         return 0;
2194                 }
2195         }
2196 #ifdef HAVE_KFILND
2197         if (auth_key > 0 && LNET_NETTYP(nw_descr.nw_id) == KFILND) {
2198                 tunables.lt_tun.lnd_tun_u.lnd_kfi.lnd_auth_key = auth_key;
2199                 found = true;
2200         }
2201
2202         if (traffic_class && LNET_NETTYP(nw_descr.nw_id) == KFILND &&
2203             strlen(traffic_class) < LNET_MAX_STR_LEN) {
2204                 strcpy(&tunables.lt_tun.lnd_tun_u.lnd_kfi.lnd_traffic_class_str[0],
2205                        traffic_class);
2206                 found = true;
2207         }
2208 #endif
2209
2210         if (LNET_NETTYP(nw_descr.nw_id) == SOCKLND && (cpp > -1)) {
2211                 tunables.lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer = cpp;
2212                 found = true;
2213         } else if (LNET_NETTYP(nw_descr.nw_id) == O2IBLND && (cpp > -1)) {
2214                 tunables.lt_tun.lnd_tun_u.lnd_o2ib.lnd_conns_per_peer = cpp;
2215                 found = true;
2216         }
2217
2218         if (pto >= 0 || pc > 0 || pbc > 0 || cre > 0 || cpp > -1) {
2219                 tunables.lt_cmn.lct_peer_timeout = pto;
2220                 tunables.lt_cmn.lct_peer_tx_credits = pc;
2221                 tunables.lt_cmn.lct_peer_rtr_credits = pbc;
2222                 tunables.lt_cmn.lct_max_tx_credits = cre;
2223                 found = true;
2224         }
2225
2226         if (found && LNET_NETTYP(nw_descr.nw_id) == O2IBLND)
2227                 tunables.lt_tun.lnd_tun_u.lnd_o2ib.lnd_map_on_demand = UINT_MAX;
2228
2229         rc = yaml_lnet_config_ni(net_id, ip2net, &nw_descr,
2230                                  found ? &tunables : NULL,
2231                                  (cpt_rc == 0) ? global_cpts : NULL,
2232                                  LNET_GENL_VERSION, NLM_F_CREATE);
2233         if (rc <= 0) {
2234                 if (rc == -EOPNOTSUPP)
2235                         goto old_api;
2236                 if (global_cpts != NULL)
2237                         cfs_expr_list_free(global_cpts);
2238                 if (rc == 0 && !skip_mr_route_setup)
2239                         rc = lustre_lnet_setup_mrrouting(&err_rc);
2240                 return rc;
2241         }
2242 old_api:
2243         rc = lustre_lnet_config_ni(&nw_descr,
2244                                    (cpt_rc == 0) ? global_cpts: NULL,
2245                                    ip2net, (found) ? &tunables : NULL,
2246                                    cpp, &err_rc);
2247
2248         if (global_cpts != NULL)
2249                 cfs_expr_list_free(global_cpts);
2250
2251 failed:
2252         if (rc != LUSTRE_CFG_RC_NO_ERR)
2253                 cYAML_print_tree2file(stderr, err_rc);
2254
2255         cYAML_free_tree(err_rc);
2256
2257         if (rc == LUSTRE_CFG_RC_NO_ERR && !skip_mr_route_setup) {
2258                 err_rc = NULL;
2259                 rc = lustre_lnet_setup_mrrouting(&err_rc);
2260
2261                 if (rc != LUSTRE_CFG_RC_NO_ERR)
2262                         cYAML_print_tree2file(stderr, err_rc);
2263
2264                 cYAML_free_tree(err_rc);
2265         }
2266
2267         return rc;
2268 }
2269
2270 static int jt_del_route(int argc, char **argv)
2271 {
2272         char *network = NULL, *gateway = NULL;
2273         struct cYAML *err_rc = NULL;
2274         int rc, opt;
2275         const char *const short_options = "n:g:";
2276         static const struct option long_options[] = {
2277                 { .name = "net",     .has_arg = required_argument, .val = 'n' },
2278                 { .name = "gateway", .has_arg = required_argument, .val = 'g' },
2279                 { .name = NULL }
2280         };
2281
2282         rc = check_cmd(route_cmds, "route", "del", 0, argc, argv);
2283         if (rc)
2284                 return rc;
2285
2286         while ((opt = getopt_long(argc, argv, short_options,
2287                                    long_options, NULL)) != -1) {
2288                 switch (opt) {
2289                 case 'n':
2290                         network = optarg;
2291                         break;
2292                 case 'g':
2293                         gateway = optarg;
2294                         break;
2295                 case '?':
2296                         print_help(route_cmds, "route", "del");
2297                 default:
2298                         return 0;
2299                 }
2300         }
2301
2302         rc = yaml_lnet_route(network, gateway, -1, -1, -1, LNET_GENL_VERSION,
2303                              0);
2304         if (rc <= 0) {
2305                 if (rc == -EOPNOTSUPP)
2306                         goto old_api;
2307                 return rc;
2308         }
2309 old_api:
2310         rc = lustre_lnet_del_route(network, gateway, -1, &err_rc);
2311
2312         if (rc != LUSTRE_CFG_RC_NO_ERR)
2313                 cYAML_print_tree2file(stderr, err_rc);
2314
2315         cYAML_free_tree(err_rc);
2316
2317         return rc;
2318 }
2319
2320 static int jt_del_ni(int argc, char **argv)
2321 {
2322         struct cYAML *err_rc = NULL;
2323         int rc, opt;
2324         struct lnet_dlc_network_descr nw_descr;
2325         const char *const short_options = "n:i:";
2326         static const struct option long_options[] = {
2327         { .name = "net",        .has_arg = required_argument,   .val = 'n' },
2328         { .name = "if",         .has_arg = required_argument,   .val = 'i' },
2329         { .name = NULL } };
2330         char *net_id = NULL;
2331
2332         rc = check_cmd(net_cmds, "net", "del", 0, argc, argv);
2333         if (rc)
2334                 return rc;
2335
2336         lustre_lnet_init_nw_descr(&nw_descr);
2337
2338         while ((opt = getopt_long(argc, argv, short_options,
2339                                    long_options, NULL)) != -1) {
2340                 switch (opt) {
2341                 case 'n':
2342                         nw_descr.nw_id = libcfs_str2net(optarg);
2343                         net_id = optarg;
2344                         break;
2345                 case 'i':
2346                         rc = lustre_lnet_parse_interfaces(optarg, &nw_descr);
2347                         if (rc != 0) {
2348                                 cYAML_build_error(-1, -1, "ni", "add",
2349                                                 "bad interface list",
2350                                                 &err_rc);
2351                                 goto out;
2352                         }
2353                         break;
2354                 case '?':
2355                         print_help(net_cmds, "net", "del");
2356                 default:
2357                         return 0;
2358                 }
2359         }
2360
2361         rc = yaml_lnet_config_ni(net_id, NULL, &nw_descr, NULL, NULL,
2362                                  LNET_GENL_VERSION, 0);
2363         if (rc <= 0) {
2364                 if (rc != -EOPNOTSUPP)
2365                         return rc;
2366         }
2367
2368         rc = lustre_lnet_del_ni(&nw_descr, -1, &err_rc);
2369 out:
2370         if (rc != LUSTRE_CFG_RC_NO_ERR)
2371                 cYAML_print_tree2file(stderr, err_rc);
2372
2373         cYAML_free_tree(err_rc);
2374
2375         return rc;
2376 }
2377
2378 static int jt_show_route(int argc, char **argv)
2379 {
2380         char *network = NULL, *gateway = NULL;
2381         long int hop = -1, prio = -1;
2382         int detail = 0, rc, opt;
2383         struct cYAML *err_rc = NULL, *show_rc = NULL;
2384         const char *const short_options = "c:n:g:p:v";
2385         static const struct option long_options[] = {
2386                 { .name = "net",       .has_arg = required_argument, .val = 'n' },
2387                 { .name = "gateway",   .has_arg = required_argument, .val = 'g' },
2388                 { .name = "hop-count", .has_arg = required_argument, .val = 'c' },
2389                 { .name = "hop",       .has_arg = required_argument, .val = 'c' },
2390                 { .name = "priority",  .has_arg = required_argument, .val = 'p' },
2391                 { .name = "verbose",   .has_arg = no_argument,       .val = 'v' },
2392                 { .name = NULL }
2393         };
2394
2395         rc = check_cmd(route_cmds, "route", "show", 0, argc, argv);
2396         if (rc)
2397                 return rc;
2398
2399         while ((opt = getopt_long(argc, argv, short_options,
2400                                    long_options, NULL)) != -1) {
2401                 switch (opt) {
2402                 case 'n':
2403                         network = optarg;
2404                         break;
2405                 case 'g':
2406                         gateway = optarg;
2407                         break;
2408                 case 'c':
2409                         rc = parse_long(optarg, &hop);
2410                         if (rc != 0) {
2411                                 /* ignore option */
2412                                 hop = -1;
2413                                 continue;
2414                         }
2415                         break;
2416                 case 'p':
2417                         rc = parse_long(optarg, &prio);
2418                         if (rc != 0) {
2419                                 /* ignore option */
2420                                 prio = -1;
2421                                 continue;
2422                         }
2423                         break;
2424                 case 'v':
2425                         detail = 1;
2426                         break;
2427                 case '?':
2428                         print_help(route_cmds, "route", "show");
2429                 default:
2430                         return 0;
2431                 }
2432         }
2433
2434         rc = yaml_lnet_route(network, gateway, hop, prio, -1,
2435                              detail, NLM_F_DUMP);
2436         if (rc <= 0) {
2437                 if (rc == -EOPNOTSUPP)
2438                         goto old_api;
2439                 return rc;
2440         }
2441 old_api:
2442         rc = lustre_lnet_show_route(network, gateway, hop, prio,
2443                                     detail ? 1 : 0, -1,
2444                                     &show_rc, &err_rc, false);
2445
2446         if (rc != LUSTRE_CFG_RC_NO_ERR)
2447                 cYAML_print_tree2file(stderr, err_rc);
2448         else if (show_rc)
2449                 cYAML_print_tree(show_rc);
2450
2451         cYAML_free_tree(err_rc);
2452         cYAML_free_tree(show_rc);
2453
2454         return rc;
2455 }
2456
2457 static int set_value_helper(int argc, char **argv,
2458                             int (*cb)(int, bool, char*, int, int, struct cYAML**))
2459 {
2460         char *nid = NULL;
2461         long int healthv = -1;
2462         bool all = false;
2463         long int state = -1;
2464         int rc, opt;
2465         struct cYAML *err_rc = NULL;
2466         const char *const short_options = "t:n:s:a";
2467         static const struct option long_options[] = {
2468                 { .name = "nid", .has_arg = required_argument, .val = 'n' },
2469                 { .name = "health", .has_arg = required_argument, .val = 't' },
2470                 { .name = "state", .has_arg = required_argument, .val = 's' },
2471                 { .name = "all", .has_arg = no_argument, .val = 'a' },
2472                 { .name = NULL }
2473         };
2474
2475         while ((opt = getopt_long(argc, argv, short_options,
2476                                   long_options, NULL)) != -1) {
2477                 switch (opt) {
2478                 case 'n':
2479                         nid = optarg;
2480                         break;
2481                 case 't':
2482                         if (parse_long(optarg, &healthv) != 0)
2483                                 healthv = -1;
2484                         break;
2485                 case 's':
2486                         if (parse_long(optarg, &state) != 0)
2487                                 state = -1;
2488                         break;
2489                 case 'a':
2490                         all = true;
2491                         break;
2492                 default:
2493                         return 0;
2494                 }
2495         }
2496
2497         rc = cb(healthv, all, nid, state, -1, &err_rc);
2498         if (rc != LUSTRE_CFG_RC_NO_ERR)
2499                 cYAML_print_tree2file(stderr, err_rc);
2500
2501         cYAML_free_tree(err_rc);
2502
2503         return rc;
2504 }
2505
2506 static int jt_set_ni_value(int argc, char **argv)
2507 {
2508         char *nid = NULL;
2509         long int healthv = -1, cpp = -1;
2510         bool all = false;
2511         int rc, opt;
2512         struct cYAML *err_rc = NULL;
2513
2514         const char *const short_options = "a:m:n:t:";
2515         static const struct option long_options[] = {
2516         { .name = "all",            .has_arg = no_argument,       .val = 'a' },
2517         { .name = "conns-per-peer", .has_arg = required_argument, .val = 'm' },
2518         { .name = "nid",            .has_arg = required_argument, .val = 'n' },
2519         { .name = "health",         .has_arg = required_argument, .val = 't' },
2520         { .name = NULL } };
2521
2522         rc = check_cmd(net_cmds, "net", "set", 0, argc, argv);
2523         if (rc)
2524                 return rc;
2525
2526         while ((opt = getopt_long(argc, argv, short_options,
2527                                    long_options, NULL)) != -1) {
2528                 switch (opt) {
2529                 case 'a':
2530                         all = true;
2531                         break;
2532                 case 'm':
2533                         rc = parse_long(optarg, &cpp);
2534                         if (rc != 0) {
2535                                 /* ignore option */
2536                                 cpp = -1;
2537                                 continue;
2538                         }
2539                         break;
2540                 case 'n':
2541                         nid = optarg;
2542                         break;
2543                 case 't':
2544                         if (parse_long(optarg, &healthv) != 0) {
2545                                 /* ignore option */
2546                                 healthv = -1;
2547                                 continue;
2548                         }
2549                         break;
2550                 default:
2551                         return 0;
2552                 }
2553         }
2554
2555         if (cpp > -1)
2556                 rc = lustre_lnet_config_ni_conns_per_peer(cpp, all, nid,
2557                                                           -1, &err_rc);
2558         if (healthv > -1)
2559                 rc = lustre_lnet_config_ni_healthv(healthv, all, nid,
2560                                                    -1, &err_rc);
2561
2562         if (rc != LUSTRE_CFG_RC_NO_ERR)
2563                 cYAML_print_tree2file(stderr, err_rc);
2564
2565         cYAML_free_tree(err_rc);
2566
2567         return rc;
2568 }
2569
2570 static int yaml_lnet_peer_display(yaml_parser_t *reply, bool list_only)
2571 {
2572         yaml_emitter_t debug;
2573         int rc;
2574
2575         rc = yaml_emitter_initialize(&debug);
2576         if (rc == 0)
2577                 goto out_err;
2578
2579         yaml_emitter_set_indent(&debug, 6);
2580         yaml_emitter_set_output_file(&debug, stdout);
2581
2582         if (list_only) {
2583                 bool done = false;
2584
2585                 while (!done) {
2586                         yaml_event_t event;
2587                         char *value;
2588
2589                         rc = yaml_parser_parse(reply, &event);
2590                         if (rc == 0)
2591                                 goto report_reply_error;
2592
2593                         if (event.type != YAML_SCALAR_EVENT)
2594                                 goto merge_event;
2595
2596                         value = (char *)event.data.scalar.value;
2597                         if (strcmp(value, "peer") == 0) {
2598                                 yaml_event_delete(&event);
2599
2600                                 yaml_scalar_event_initialize(&event, NULL,
2601                                                              (yaml_char_t *)YAML_STR_TAG,
2602                                                              (yaml_char_t *)"peer list",
2603                                                              strlen("peer list"),
2604                                                              1, 0,
2605                                                              YAML_PLAIN_SCALAR_STYLE);
2606                         } else if (strcmp(value, "primary nid") == 0) {
2607                                 yaml_event_delete(&event);
2608
2609                                 yaml_scalar_event_initialize(&event, NULL,
2610                                                              (yaml_char_t *)YAML_STR_TAG,
2611                                                              (yaml_char_t *)"nid",
2612                                                              strlen("nid"),
2613                                                              1, 0,
2614                                                              YAML_PLAIN_SCALAR_STYLE);
2615                                 rc = yaml_emitter_emit(&debug, &event);
2616                                 if (rc == 0)
2617                                         break;
2618
2619                                 /* Now print NID address */
2620                                 rc = yaml_parser_parse(reply, &event);
2621                                 if (rc == 0)
2622                                         goto report_reply_error;
2623
2624                                 rc = yaml_emitter_emit(&debug, &event);
2625                                 if (rc == 0)
2626                                         break;
2627
2628                                 /* skip reset */
2629                                 while (event.type != YAML_MAPPING_END_EVENT) {
2630                                         rc = yaml_parser_parse(reply, &event);
2631                                         if (rc == 0)
2632                                                 goto report_reply_error;
2633                                 }
2634
2635                                 /* we can have map end, seq end, map end or
2636                                  * just map end event. If we see seq end event
2637                                  * then skip to next mapping end event
2638                                  */
2639                                 rc = yaml_parser_parse(reply, &event);
2640                                 if (rc == 0)
2641                                         goto report_reply_error;
2642
2643                                 if (event.type == YAML_SEQUENCE_END_EVENT) {
2644                                         yaml_event_delete(&event);
2645
2646                                         rc = yaml_parser_parse(reply, &event);
2647                                         if (rc == 0)
2648                                                 goto report_reply_error;
2649                                 }
2650                         }
2651 merge_event:
2652                         rc = yaml_emitter_emit(&debug, &event);
2653                         if (rc == 0)
2654                                 break;
2655
2656                         done = (event.type == YAML_DOCUMENT_END_EVENT);
2657                 }
2658         } else {
2659                 yaml_document_t errmsg;
2660
2661                 rc = yaml_parser_load(reply, &errmsg);
2662                 if (rc == 1)
2663                         rc = yaml_emitter_dump(&debug, &errmsg);
2664                 yaml_document_delete(&errmsg);
2665         }
2666 out_err:
2667         if (rc == 0)
2668                 yaml_emitter_log_error(&debug, stderr);
2669 report_reply_error:
2670         yaml_emitter_delete(&debug);
2671
2672         return rc;
2673 }
2674
2675 static int yaml_lnet_peer(char *prim_nid, char *nidstr, bool disable_mr,
2676                           int health_value, int state, bool list_only,
2677                           int version, int flags)
2678 {
2679         struct nl_sock *sk = NULL;
2680         const char *msg = NULL;
2681         yaml_emitter_t output;
2682         yaml_parser_t reply;
2683         yaml_event_t event;
2684         int rc;
2685
2686         /* Create Netlink emitter to send request to kernel */
2687         sk = nl_socket_alloc();
2688         if (!sk)
2689                 return -EOPNOTSUPP;
2690
2691         /* Setup parser to receive Netlink packets */
2692         rc = yaml_parser_initialize(&reply);
2693         if (rc == 0) {
2694                 nl_socket_free(sk);
2695                 return -EOPNOTSUPP;
2696         }
2697
2698         rc = yaml_parser_set_input_netlink(&reply, sk, false);
2699         if (rc == 0) {
2700                 msg = yaml_parser_get_reader_error(&reply);
2701                 goto free_reply;
2702         }
2703
2704         /* Create Netlink emitter to send request to kernel */
2705         rc = yaml_emitter_initialize(&output);
2706         if (rc == 0) {
2707                 msg = "failed to initialize emitter";
2708                 goto free_reply;
2709         }
2710
2711         rc = yaml_emitter_set_output_netlink(&output, sk, LNET_GENL_NAME,
2712                                              version, LNET_CMD_PEERS, flags);
2713         if (rc == 0)
2714                 goto emitter_error;
2715
2716         yaml_emitter_open(&output);
2717         yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
2718         rc = yaml_emitter_emit(&output, &event);
2719         if (rc == 0)
2720                 goto emitter_error;
2721
2722         yaml_mapping_start_event_initialize(&event, NULL,
2723                                             (yaml_char_t *)YAML_MAP_TAG,
2724                                             1, YAML_ANY_MAPPING_STYLE);
2725         rc = yaml_emitter_emit(&output, &event);
2726         if (rc == 0)
2727                 goto emitter_error;
2728
2729         yaml_scalar_event_initialize(&event, NULL,
2730                                      (yaml_char_t *)YAML_STR_TAG,
2731                                      (yaml_char_t *)"peer",
2732                                      strlen("peer"), 1, 0,
2733                                      YAML_PLAIN_SCALAR_STYLE);
2734         rc = yaml_emitter_emit(&output, &event);
2735         if (rc == 0)
2736                 goto emitter_error;
2737
2738         if (prim_nid) {
2739                 yaml_sequence_start_event_initialize(&event, NULL,
2740                                                      (yaml_char_t *)YAML_SEQ_TAG,
2741                                                      1,
2742                                                      YAML_BLOCK_SEQUENCE_STYLE);
2743                 rc = yaml_emitter_emit(&output, &event);
2744                 if (rc == 0)
2745                         goto emitter_error;
2746
2747                 yaml_mapping_start_event_initialize(&event, NULL,
2748                                                     (yaml_char_t *)YAML_MAP_TAG,
2749                                                     1,
2750                                                     YAML_BLOCK_MAPPING_STYLE);
2751                 rc = yaml_emitter_emit(&output, &event);
2752                 if (rc == 0)
2753                         goto emitter_error;
2754
2755                 yaml_scalar_event_initialize(&event, NULL,
2756                                              (yaml_char_t *)YAML_STR_TAG,
2757                                              (yaml_char_t *)"primary nid",
2758                                              strlen("primary nid"), 1, 0,
2759                                              YAML_PLAIN_SCALAR_STYLE);
2760                 rc = yaml_emitter_emit(&output, &event);
2761                 if (rc == 0)
2762                         goto emitter_error;
2763
2764                 yaml_scalar_event_initialize(&event, NULL,
2765                                              (yaml_char_t *)YAML_STR_TAG,
2766                                              (yaml_char_t *)prim_nid,
2767                                              strlen(prim_nid), 1, 0,
2768                                              YAML_PLAIN_SCALAR_STYLE);
2769                 rc = yaml_emitter_emit(&output, &event);
2770                 if (rc == 0)
2771                         goto emitter_error;
2772
2773                 if (disable_mr) {
2774                         yaml_scalar_event_initialize(&event, NULL,
2775                                                      (yaml_char_t *)YAML_STR_TAG,
2776                                                      (yaml_char_t *)"Multi-Rail",
2777                                                      strlen("Multi-Rail"), 1, 0,
2778                                                      YAML_PLAIN_SCALAR_STYLE);
2779                         rc = yaml_emitter_emit(&output, &event);
2780                         if (rc == 0)
2781                                 goto emitter_error;
2782
2783                         yaml_scalar_event_initialize(&event, NULL,
2784                                                      (yaml_char_t *)YAML_BOOL_TAG,
2785                                                      (yaml_char_t *)"False",
2786                                                      strlen("False"), 1, 0,
2787                                                      YAML_PLAIN_SCALAR_STYLE);
2788                         rc = yaml_emitter_emit(&output, &event);
2789                         if (rc == 0)
2790                                 goto emitter_error;
2791                 }
2792
2793                 if (state != -1) {
2794                         char peer_state[INT_STRING_LEN];
2795
2796                         yaml_scalar_event_initialize(&event, NULL,
2797                                                      (yaml_char_t *)YAML_STR_TAG,
2798                                                      (yaml_char_t *)"peer state",
2799                                                      strlen("peer state"), 1, 0,
2800                                                      YAML_PLAIN_SCALAR_STYLE);
2801                         rc = yaml_emitter_emit(&output, &event);
2802                         if (rc == 0)
2803                                 goto emitter_error;
2804
2805                         snprintf(peer_state, sizeof(peer_state), "%d", state);
2806                         yaml_scalar_event_initialize(&event, NULL,
2807                                                      (yaml_char_t *)YAML_INT_TAG,
2808                                                      (yaml_char_t *)peer_state,
2809                                                      strlen(peer_state), 1, 0,
2810                                                      YAML_PLAIN_SCALAR_STYLE);
2811                         rc = yaml_emitter_emit(&output, &event);
2812                         if (rc == 0)
2813                                 goto emitter_error;
2814                 }
2815
2816                 if (!nidstr && health_value == -1)
2817                         goto skip_peer_nis;
2818
2819                 yaml_scalar_event_initialize(&event, NULL,
2820                                              (yaml_char_t *)YAML_STR_TAG,
2821                                              (yaml_char_t *)"peer ni",
2822                                              strlen("peer ni"), 1, 0,
2823                                              YAML_PLAIN_SCALAR_STYLE);
2824                 rc = yaml_emitter_emit(&output, &event);
2825                 if (rc == 0)
2826                         goto emitter_error;
2827
2828                 yaml_sequence_start_event_initialize(&event, NULL,
2829                                                      (yaml_char_t *)YAML_SEQ_TAG,
2830                                                      1, YAML_BLOCK_SEQUENCE_STYLE);
2831                 rc = yaml_emitter_emit(&output, &event);
2832                 if (rc == 0)
2833                         goto emitter_error;
2834
2835                 if (nidstr) {
2836                         struct nid_node head, *entry;
2837                         int count = 0;
2838
2839                         /* If we have LNET_ANY_NID and its NLM_F_REPLACE we
2840                          * treat it as the all flag case for lnetctl peer set
2841                          */
2842                         if (strcmp(nidstr, "<?>") == 0) {
2843                                 yaml_mapping_start_event_initialize(&event, NULL,
2844                                                                     (yaml_char_t *)YAML_MAP_TAG,
2845                                                                     1, YAML_BLOCK_MAPPING_STYLE);
2846                                 rc = yaml_emitter_emit(&output, &event);
2847                                 if (rc == 0)
2848                                         goto emitter_error;
2849
2850                                 yaml_scalar_event_initialize(&event, NULL,
2851                                                              (yaml_char_t *)YAML_STR_TAG,
2852                                                              (yaml_char_t *)"nid",
2853                                                              strlen("nid"), 1, 0,
2854                                                              YAML_PLAIN_SCALAR_STYLE);
2855                                 rc = yaml_emitter_emit(&output, &event);
2856                                 if (rc == 0)
2857                                         goto emitter_error;
2858
2859                                 yaml_scalar_event_initialize(&event, NULL,
2860                                                              (yaml_char_t *)YAML_STR_TAG,
2861                                                              (yaml_char_t *)nidstr,
2862                                                              strlen(nidstr), 1, 0,
2863                                                      YAML_PLAIN_SCALAR_STYLE);
2864                                 rc = yaml_emitter_emit(&output, &event);
2865                                 if (rc == 0)
2866                                         goto emitter_error;
2867
2868                                 yaml_mapping_end_event_initialize(&event);
2869                                 rc = yaml_emitter_emit(&output, &event);
2870                                 if (rc == 0)
2871                                         goto emitter_error;
2872
2873                                 goto handle_health;
2874                         }
2875
2876                         NL_INIT_LIST_HEAD(&head.children);
2877                         nl_init_list_head(&head.list);
2878                         rc = lustre_lnet_parse_nid_range(&head, nidstr, &msg);
2879                         if (rc < 0) {
2880                                 fprintf(stdout, "can't parse nidrange: \"%s\"\n", nidstr);
2881                                 lustre_lnet_free_list(&head);
2882                                 yaml_emitter_delete(&output);
2883                                 errno = rc;
2884                                 rc = 0;
2885                                 goto free_reply;
2886                         }
2887
2888                         if (nl_list_empty(&head.children)) {
2889                                 lustre_lnet_free_list(&head);
2890                                 yaml_emitter_delete(&output);
2891                                 msg = "Unable to parse nidlist: did not expand to any nids";
2892                                 errno = -ENOENT;
2893                                 rc = 0;
2894                                 goto free_reply;
2895                         }
2896                         rc = 1; /* one means its working */
2897
2898                         nl_list_for_each_entry(entry, &head.children, list) {
2899                                 char *nid = entry->nidstr;
2900
2901                                 if (count++ > LNET_MAX_NIDS_PER_PEER) {
2902                                         lustre_lnet_free_list(&head);
2903                                         yaml_emitter_delete(&output);
2904                                         msg = "Unable to parse nidlist: specifies more NIDs than allowed";
2905                                         errno = -E2BIG;
2906                                         rc = 0;
2907                                         goto free_reply;
2908                                 }
2909
2910                                 yaml_mapping_start_event_initialize(&event, NULL,
2911                                                                     (yaml_char_t *)YAML_MAP_TAG,
2912                                                                     1, YAML_BLOCK_MAPPING_STYLE);
2913                                 rc = yaml_emitter_emit(&output, &event);
2914                                 if (rc == 0)
2915                                         goto emitter_error;
2916
2917                                 yaml_scalar_event_initialize(&event, NULL,
2918                                                              (yaml_char_t *)YAML_STR_TAG,
2919                                                              (yaml_char_t *)"nid",
2920                                                              strlen("nid"), 1, 0,
2921                                                              YAML_PLAIN_SCALAR_STYLE);
2922                                 rc = yaml_emitter_emit(&output, &event);
2923                                 if (rc == 0)
2924                                         goto emitter_error;
2925
2926                                 yaml_scalar_event_initialize(&event, NULL,
2927                                                              (yaml_char_t *)YAML_STR_TAG,
2928                                                              (yaml_char_t *)nid,
2929                                                              strlen(nid), 1, 0,
2930                                                      YAML_PLAIN_SCALAR_STYLE);
2931                                 rc = yaml_emitter_emit(&output, &event);
2932                                 if (rc == 0)
2933                                         goto emitter_error;
2934
2935                                 yaml_mapping_end_event_initialize(&event);
2936                                 rc = yaml_emitter_emit(&output, &event);
2937                                 if (rc == 0)
2938                                         goto emitter_error;
2939                         }
2940                         lustre_lnet_free_list(&head);
2941                 }
2942 handle_health:
2943                 if (health_value >= 0) {
2944                         char health[INT_STRING_LEN];
2945
2946                         /* Create the mapping for 'health stats'. The value field for
2947                          * the mapping is not provided so its treated as a empty string.
2948                          */
2949                         yaml_mapping_start_event_initialize(&event, NULL,
2950                                                             (yaml_char_t *)YAML_MAP_TAG,
2951                                                             1, YAML_BLOCK_MAPPING_STYLE);
2952                         rc = yaml_emitter_emit(&output, &event);
2953                         if (rc == 0)
2954                                 goto emitter_error;
2955
2956                         yaml_scalar_event_initialize(&event, NULL,
2957                                                      (yaml_char_t *)YAML_STR_TAG,
2958                                                      (yaml_char_t *)"health stats",
2959                                                      strlen("health stats"), 1, 0,
2960                                                      YAML_PLAIN_SCALAR_STYLE);
2961                         rc = yaml_emitter_emit(&output, &event);
2962                         if (rc == 0)
2963                                 goto emitter_error;
2964
2965                         /* Setup all mappings for data related to the 'health stats' */
2966                         yaml_mapping_start_event_initialize(&event, NULL,
2967                                                             (yaml_char_t *)YAML_MAP_TAG,
2968                                                             1, YAML_BLOCK_MAPPING_STYLE);
2969                         rc = yaml_emitter_emit(&output, &event);
2970                         if (rc == 0)
2971                                 goto emitter_error;
2972
2973                         yaml_scalar_event_initialize(&event, NULL,
2974                                                      (yaml_char_t *)YAML_STR_TAG,
2975                                                      (yaml_char_t *)"health value",
2976                                                      strlen("health value"), 1, 0,
2977                                                      YAML_PLAIN_SCALAR_STYLE);
2978                         rc = yaml_emitter_emit(&output, &event);
2979                         if (rc == 0)
2980                                 goto emitter_error;
2981
2982                         snprintf(health, sizeof(health), "%d", health_value);
2983                         yaml_scalar_event_initialize(&event, NULL,
2984                                                      (yaml_char_t *)YAML_INT_TAG,
2985                                                      (yaml_char_t *)health,
2986                                                      strlen(health), 1, 0,
2987                                                      YAML_PLAIN_SCALAR_STYLE);
2988                         rc = yaml_emitter_emit(&output, &event);
2989                         if (rc == 0)
2990                                 goto emitter_error;
2991
2992                         yaml_mapping_end_event_initialize(&event);
2993                         rc = yaml_emitter_emit(&output, &event);
2994                         if (rc == 0)
2995                                 goto emitter_error;
2996
2997                         yaml_mapping_end_event_initialize(&event);
2998                         rc = yaml_emitter_emit(&output, &event);
2999                         if (rc == 0)
3000                                 goto emitter_error;
3001                 }
3002
3003                 yaml_sequence_end_event_initialize(&event);
3004                 rc = yaml_emitter_emit(&output, &event);
3005                 if (rc == 0)
3006                         goto emitter_error;
3007 skip_peer_nis:
3008                 yaml_mapping_end_event_initialize(&event);
3009                 rc = yaml_emitter_emit(&output, &event);
3010                 if (rc == 0)
3011                         goto emitter_error;
3012
3013                 yaml_sequence_end_event_initialize(&event);
3014                 rc = yaml_emitter_emit(&output, &event);
3015                 if (rc == 0)
3016                         goto emitter_error;
3017         } else {
3018                 yaml_scalar_event_initialize(&event, NULL,
3019                                              (yaml_char_t *)YAML_STR_TAG,
3020                                              (yaml_char_t *)"",
3021                                              strlen(""), 1, 0,
3022                                              YAML_PLAIN_SCALAR_STYLE);
3023                 rc = yaml_emitter_emit(&output, &event);
3024                 if (rc == 0)
3025                         goto emitter_error;
3026         }
3027
3028         yaml_mapping_end_event_initialize(&event);
3029         rc = yaml_emitter_emit(&output, &event);
3030         if (rc == 0)
3031                 goto emitter_error;
3032
3033         yaml_document_end_event_initialize(&event, 0);
3034         rc = yaml_emitter_emit(&output, &event);
3035         if (rc == 0)
3036                 goto emitter_error;
3037
3038         rc = yaml_emitter_close(&output);
3039 emitter_error:
3040         if (rc == 0) {
3041                 yaml_emitter_log_error(&output, stderr);
3042                 rc = -EINVAL;
3043         } else {
3044                 rc = yaml_lnet_peer_display(&reply, list_only);
3045                 if (rc == 0) {
3046                         msg = yaml_parser_get_reader_error(&reply);
3047                         /* If we didn't find any peers just be silent */
3048                         if (msg && strcmp(msg, "No peers found") == 0)
3049                                 rc = 1;
3050                 }
3051
3052         }
3053         yaml_emitter_delete(&output);
3054 free_reply:
3055         if (rc == 0) {
3056                 yaml_lnet_print_error(flags, "peer", msg);
3057                 rc = -EINVAL;
3058         }
3059         yaml_parser_delete(&reply);
3060         nl_socket_free(sk);
3061
3062         return rc == 1 ? 0 : rc;
3063 }
3064
3065 int yaml_lnet_config_peer_ni_healthv(int healthv, bool all, char *lpni_nid,
3066                                      int state, int seq_no, struct cYAML **err_rc)
3067 {
3068         int rc;
3069
3070         rc = yaml_lnet_peer(lpni_nid ? lpni_nid : "<?>", all ? "<?>" : NULL,
3071                             false, healthv, state, false, LNET_GENL_VERSION,
3072                             NLM_F_REPLACE);
3073         if (rc <= 0) {
3074                 if (rc == -EOPNOTSUPP)
3075                         goto old_api;
3076                 return rc;
3077         }
3078 old_api:
3079         if (state == -1)
3080                 rc = lustre_lnet_config_peer_ni_healthv(healthv, all, lpni_nid,
3081                                                         seq_no, err_rc);
3082         else
3083                 rc = lustre_lnet_set_peer_state(state, lpni_nid, -1, err_rc);
3084         if (rc != LUSTRE_CFG_RC_NO_ERR)
3085                 cYAML_print_tree2file(stderr, *err_rc);
3086
3087         cYAML_free_tree(*err_rc);
3088
3089         return rc;
3090 }
3091
3092 static int jt_set_peer_ni_value(int argc, char **argv)
3093 {
3094         int rc = check_cmd(peer_cmds, "peer", "set", 0, argc, argv);
3095
3096         if (rc < 0)
3097                 return rc;
3098
3099         return set_value_helper(argc, argv, yaml_lnet_config_peer_ni_healthv);
3100 }
3101
3102 static int jt_show_recovery(int argc, char **argv)
3103 {
3104         int rc, opt;
3105         struct cYAML *err_rc = NULL, *show_rc = NULL;
3106         const char *const short_options = "lp";
3107         static const struct option long_options[] = {
3108                 { .name = "local", .has_arg = no_argument, .val = 'l' },
3109                 { .name = "peer", .has_arg = no_argument, .val = 'p' },
3110                 { .name = NULL } };
3111
3112         rc = check_cmd(debug_cmds, "debug", "recovery", 0, argc, argv);
3113         if (rc)
3114                 return rc;
3115
3116         while ((opt = getopt_long(argc, argv, short_options,
3117                                    long_options, NULL)) != -1) {
3118                 switch (opt) {
3119                 case 'l':
3120                         rc = lustre_lnet_show_local_ni_recovq(-1, &show_rc, &err_rc);
3121                         break;
3122                 case 'p':
3123                         rc = lustre_lnet_show_peer_ni_recovq(-1, &show_rc, &err_rc);
3124                         break;
3125                 default:
3126                         return 0;
3127                 }
3128         }
3129
3130         if (rc != LUSTRE_CFG_RC_NO_ERR)
3131                 cYAML_print_tree2file(stderr, err_rc);
3132         else if (show_rc)
3133                 cYAML_print_tree(show_rc);
3134
3135         cYAML_free_tree(err_rc);
3136         cYAML_free_tree(show_rc);
3137
3138         return rc;
3139 }
3140
3141 static int jt_show_peer_debug_info(int argc, char **argv)
3142 {
3143         int rc, opt;
3144         struct cYAML *err_rc = NULL;
3145         char *peer_nid = optarg;
3146         const char *const short_opts = "k";
3147         const struct option long_opts[] = {
3148         { .name = "nid", .has_arg = required_argument, .val = 'k' },
3149         { .name = NULL } };
3150
3151         rc = check_cmd(debug_cmds, "debug", "peer", 0, argc, argv);
3152
3153         if (rc)
3154                 return rc;
3155
3156         while ((opt = getopt_long(argc, argv, short_opts,
3157                                    long_opts, NULL)) != -1) {
3158                 switch (opt) {
3159                 case 'k':
3160                         peer_nid = optarg;
3161                         break;
3162                 default:
3163                         return 0;
3164                 }
3165         }
3166
3167         rc = lustre_lnet_show_peer_debug_info(peer_nid, -1, &err_rc);
3168
3169         if (rc != LUSTRE_CFG_RC_NO_ERR)
3170                 cYAML_print_tree2file(stderr, err_rc);
3171
3172         cYAML_free_tree(err_rc);
3173
3174         return rc;
3175 }
3176
3177 static int jt_show_net(int argc, char **argv)
3178 {
3179         char *network = NULL;
3180         int rc, opt;
3181         struct cYAML *err_rc = NULL, *show_rc = NULL;
3182         long int detail = 0;
3183         const char *const short_options = "n:v";
3184         static const struct option long_options[] = {
3185                 { .name = "net",     .has_arg = required_argument, .val = 'n' },
3186                 { .name = "verbose", .has_arg = optional_argument, .val = 'v' },
3187                 { .name = NULL } };
3188
3189         rc = check_cmd(net_cmds, "net", "show", 0, argc, argv);
3190         if (rc)
3191                 return rc;
3192
3193         while ((opt = getopt_long(argc, argv, short_options,
3194                                    long_options, NULL)) != -1) {
3195                 switch (opt) {
3196                 case 'n':
3197                         network = optarg;
3198                         break;
3199                 case 'v':
3200                         if ((!optarg) && (argv[optind] != NULL) &&
3201                             (argv[optind][0] != '-')) {
3202                                 if (parse_long(argv[optind++], &detail) != 0)
3203                                         detail = 1;
3204                         } else {
3205                                 detail = 1;
3206                         }
3207                         break;
3208                 case '?':
3209                         print_help(net_cmds, "net", "show");
3210                 default:
3211                         return 0;
3212                 }
3213         }
3214
3215         rc = yaml_lnet_config_ni(network, NULL, NULL, NULL, NULL,
3216                                  detail, NLM_F_DUMP);
3217         if (rc <= 0) {
3218                 if (rc != -EOPNOTSUPP)
3219                         return rc;
3220         }
3221
3222         rc = lustre_lnet_show_net(network, (int) detail, -1, &show_rc, &err_rc,
3223                                   false);
3224
3225         if (rc != LUSTRE_CFG_RC_NO_ERR)
3226                 cYAML_print_tree2file(stderr, err_rc);
3227         else if (show_rc)
3228                 cYAML_print_tree(show_rc);
3229
3230         cYAML_free_tree(err_rc);
3231         cYAML_free_tree(show_rc);
3232
3233         return rc;
3234 }
3235
3236 static int jt_show_routing(int argc, char **argv)
3237 {
3238         struct cYAML *err_rc = NULL, *show_rc = NULL;
3239         int rc;
3240
3241         rc = check_cmd(routing_cmds, "routing", "show", 0, argc, argv);
3242         if (rc)
3243                 return rc;
3244
3245         rc = lustre_lnet_show_routing(-1, &show_rc, &err_rc, false);
3246
3247         if (rc != LUSTRE_CFG_RC_NO_ERR)
3248                 cYAML_print_tree2file(stderr, err_rc);
3249         else if (show_rc)
3250                 cYAML_print_tree(show_rc);
3251
3252         cYAML_free_tree(err_rc);
3253         cYAML_free_tree(show_rc);
3254
3255         return rc;
3256 }
3257
3258 static int jt_show_stats(int argc, char **argv)
3259 {
3260         int rc;
3261         struct cYAML *show_rc = NULL, *err_rc = NULL;
3262
3263         rc = check_cmd(stats_cmds, "stats", "show", 0, argc, argv);
3264         if (rc)
3265                 return rc;
3266
3267         rc = lustre_lnet_show_stats(-1, &show_rc, &err_rc);
3268
3269         if (rc != LUSTRE_CFG_RC_NO_ERR)
3270                 cYAML_print_tree2file(stderr, err_rc);
3271         else if (show_rc)
3272                 cYAML_print_tree(show_rc);
3273
3274         cYAML_free_tree(err_rc);
3275         cYAML_free_tree(show_rc);
3276
3277         return rc;
3278 }
3279
3280 static int jt_show_udsp(int argc, char **argv)
3281 {
3282         long int idx = -1;
3283         int rc, opt;
3284         struct cYAML *err_rc = NULL, *show_rc = NULL;
3285
3286         const char *const short_options = "i:";
3287         static const struct option long_options[] = {
3288                 { .name = "idx", .has_arg = required_argument, .val = 'i' },
3289                 { .name = NULL }
3290         };
3291
3292         rc = check_cmd(udsp_cmds, "udsp", "show", 0, argc, argv);
3293         if (rc)
3294                 return rc;
3295
3296         while ((opt = getopt_long(argc, argv, short_options,
3297                                    long_options, NULL)) != -1) {
3298                 switch (opt) {
3299                 case 'i':
3300                         rc = parse_long(optarg, &idx);
3301                         if (rc != 0 || idx < -1) {
3302                                 printf("Invalid index \"%s\"\n", optarg);
3303                                 return -EINVAL;
3304                         }
3305                         break;
3306                 case '?':
3307                         print_help(net_cmds, "net", "show");
3308                 default:
3309                         return 0;
3310                 }
3311         }
3312
3313         rc = lustre_lnet_show_udsp(idx, -1, &show_rc, &err_rc);
3314
3315         if (rc != LUSTRE_CFG_RC_NO_ERR)
3316                 cYAML_print_tree2file(stderr, err_rc);
3317         else if (show_rc)
3318                 cYAML_print_tree(show_rc);
3319
3320         cYAML_free_tree(err_rc);
3321         cYAML_free_tree(show_rc);
3322
3323         return rc;
3324 }
3325
3326 static int jt_show_global(int argc, char **argv)
3327 {
3328         int rc;
3329         struct cYAML *show_rc = NULL, *err_rc = NULL;
3330
3331         rc = check_cmd(global_cmds, "global", "show", 0, argc, argv);
3332         if (rc)
3333                 return rc;
3334
3335         rc = lustre_lnet_show_numa_range(-1, &show_rc, &err_rc);
3336         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3337                 cYAML_print_tree2file(stderr, err_rc);
3338                 goto out;
3339         }
3340
3341         rc = lustre_lnet_show_max_intf(-1, &show_rc, &err_rc);
3342         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3343                 cYAML_print_tree2file(stderr, err_rc);
3344                 goto out;
3345         }
3346
3347         rc = lustre_lnet_show_discovery(-1, &show_rc, &err_rc);
3348         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3349                 cYAML_print_tree2file(stderr, err_rc);
3350                 goto out;
3351         }
3352
3353         rc = lustre_lnet_show_drop_asym_route(-1, &show_rc, &err_rc);
3354         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3355                 cYAML_print_tree2file(stderr, err_rc);
3356                 goto out;
3357         }
3358
3359         rc = lustre_lnet_show_retry_count(-1, &show_rc, &err_rc);
3360         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3361                 cYAML_print_tree2file(stderr, err_rc);
3362                 goto out;
3363         }
3364
3365         rc = lustre_lnet_show_transaction_to(-1, &show_rc, &err_rc);
3366         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3367                 cYAML_print_tree2file(stderr, err_rc);
3368                 goto out;
3369         }
3370
3371         rc = lustre_lnet_show_hsensitivity(-1, &show_rc, &err_rc);
3372         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3373                 cYAML_print_tree2file(stderr, err_rc);
3374                 goto out;
3375         }
3376
3377         rc = lustre_lnet_show_recov_intrv(-1, &show_rc, &err_rc);
3378         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3379                 cYAML_print_tree2file(stderr, err_rc);
3380                 goto out;
3381         }
3382
3383         rc = lustre_lnet_show_rtr_sensitivity(-1, &show_rc, &err_rc);
3384         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3385                 cYAML_print_tree2file(stderr, err_rc);
3386                 goto out;
3387         }
3388
3389         rc = lustre_lnet_show_lnd_timeout(-1, &show_rc, &err_rc);
3390         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3391                 cYAML_print_tree2file(stderr, err_rc);
3392                 goto out;
3393         }
3394
3395         rc = lustre_lnet_show_response_tracking(-1, &show_rc, &err_rc);
3396         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3397                 cYAML_print_tree2file(stderr, err_rc);
3398                 goto out;
3399         }
3400
3401         rc = lustre_lnet_show_recovery_limit(-1, &show_rc, &err_rc);
3402         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3403                 cYAML_print_tree2file(stderr, err_rc);
3404                 goto out;
3405         }
3406
3407         rc = lustre_lnet_show_max_recovery_ping_interval(-1, &show_rc, &err_rc);
3408         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3409                 cYAML_print_tree2file(stderr, err_rc);
3410                 goto out;
3411         }
3412
3413         if (show_rc)
3414                 cYAML_print_tree(show_rc);
3415
3416 out:
3417         cYAML_free_tree(err_rc);
3418         cYAML_free_tree(show_rc);
3419
3420         return rc;
3421 }
3422
3423 static int jt_lnet(int argc, char **argv)
3424 {
3425         int rc;
3426
3427         rc = check_cmd(lnet_cmds, "lnet", NULL, 2, argc, argv);
3428         if (rc)
3429                 return rc;
3430
3431         return cfs_parser(argc, argv, lnet_cmds);
3432 }
3433
3434 static int jt_route(int argc, char **argv)
3435 {
3436         int rc;
3437
3438         rc = check_cmd(route_cmds, "route", NULL, 2, argc, argv);
3439         if (rc)
3440                 return rc;
3441
3442         return cfs_parser(argc, argv, route_cmds);
3443 }
3444
3445 static int jt_net(int argc, char **argv)
3446 {
3447         int rc;
3448
3449         rc = check_cmd(net_cmds, "net", NULL, 2, argc, argv);
3450         if (rc)
3451                 return rc;
3452
3453         return cfs_parser(argc, argv, net_cmds);
3454 }
3455
3456 static int jt_routing(int argc, char **argv)
3457 {
3458         int rc;
3459
3460         rc = check_cmd(routing_cmds, "routing", NULL, 2, argc, argv);
3461         if (rc)
3462                 return rc;
3463
3464         return cfs_parser(argc, argv, routing_cmds);
3465 }
3466
3467 static int jt_stats(int argc, char **argv)
3468 {
3469         int rc;
3470
3471         rc = check_cmd(stats_cmds, "stats", NULL, 2, argc, argv);
3472         if (rc)
3473                 return rc;
3474
3475         return cfs_parser(argc, argv, stats_cmds);
3476 }
3477
3478 static int jt_debug(int argc, char **argv)
3479 {
3480         int rc;
3481
3482         rc = check_cmd(debug_cmds, "debug", NULL, 2, argc, argv);
3483         if (rc)
3484                 return rc;
3485
3486         return cfs_parser(argc, argv, debug_cmds);
3487 }
3488
3489 static int jt_global(int argc, char **argv)
3490 {
3491         int rc;
3492
3493         rc = check_cmd(global_cmds, "global", NULL, 2, argc, argv);
3494         if (rc)
3495                 return rc;
3496
3497         return cfs_parser(argc, argv, global_cmds);
3498 }
3499
3500 static int jt_peers(int argc, char **argv)
3501 {
3502         int rc;
3503
3504         rc = check_cmd(peer_cmds, "peer", NULL, 2, argc, argv);
3505         if (rc)
3506                 return rc;
3507
3508         return cfs_parser(argc, argv, peer_cmds);
3509 }
3510
3511 static int jt_set(int argc, char **argv)
3512 {
3513         int rc;
3514
3515         rc = check_cmd(set_cmds, "set", NULL, 2, argc, argv);
3516         if (rc)
3517                 return rc;
3518
3519         return cfs_parser(argc, argv, set_cmds);
3520 }
3521
3522 static int jt_udsp(int argc, char **argv)
3523 {
3524         int rc;
3525
3526         rc = check_cmd(udsp_cmds, "udsp", NULL, 2, argc, argv);
3527         if (rc)
3528                 return rc;
3529
3530         return cfs_parser(argc, argv, udsp_cmds);
3531 }
3532
3533 static int jt_import(int argc, char **argv)
3534 {
3535         char *file = NULL;
3536         struct cYAML *err_rc = NULL;
3537         struct cYAML *show_rc = NULL;
3538         int rc = 0, return_rc = 0, opt, opt_found = 0;
3539         char cmd = 'a';
3540
3541         const char *const short_options = "adseh";
3542         static const struct option long_options[] = {
3543                 { .name = "add",  .has_arg = no_argument, .val = 'a' },
3544                 { .name = "del",  .has_arg = no_argument, .val = 'd' },
3545                 { .name = "show", .has_arg = no_argument, .val = 's' },
3546                 { .name = "exec", .has_arg = no_argument, .val = 'e' },
3547                 { .name = "help", .has_arg = no_argument, .val = 'h' },
3548                 { .name = NULL } };
3549
3550         while ((opt = getopt_long(argc, argv, short_options,
3551                                    long_options, NULL)) != -1) {
3552                 opt_found = 1;
3553                 switch (opt) {
3554                 case 'a':
3555                         cmd = opt;
3556                         break;
3557                 case 'd':
3558                 case 's':
3559                         cmd = opt;
3560                         break;
3561                 case 'e':
3562                         cmd = opt;
3563                         break;
3564                 case 'h':
3565                         printf("import FILE\n"
3566                                "import < FILE : import a file\n"
3567                                "\t--add: add configuration\n"
3568                                "\t--del: delete configuration\n"
3569                                "\t--show: show configuration\n"
3570                                "\t--exec: execute command\n"
3571                                "\t--help: display this help\n"
3572                                "If no command option is given then --add"
3573                                " is assumed by default\n");
3574                         return 0;
3575                 default:
3576                         return 0;
3577                 }
3578         }
3579
3580         /* grab the file name if one exists */
3581         if (opt_found && argc == 3)
3582                 file = argv[2];
3583         else if (!opt_found && argc == 2)
3584                 file = argv[1];
3585
3586         switch (cmd) {
3587         case 'a':
3588                 rc = lustre_yaml_config(file, &err_rc);
3589                 return_rc = lustre_yaml_exec(file, &show_rc, &err_rc);
3590                 cYAML_print_tree(show_rc);
3591                 cYAML_free_tree(show_rc);
3592                 break;
3593         case 'd':
3594                 rc = lustre_yaml_del(file, &err_rc);
3595                 break;
3596         case 's':
3597                 rc = lustre_yaml_show(file, &show_rc, &err_rc);
3598                 cYAML_print_tree(show_rc);
3599                 cYAML_free_tree(show_rc);
3600                 break;
3601         case 'e':
3602                 rc = lustre_yaml_exec(file, &show_rc, &err_rc);
3603                 cYAML_print_tree(show_rc);
3604                 cYAML_free_tree(show_rc);
3605                 break;
3606         }
3607
3608         if (rc || return_rc) {
3609                 cYAML_print_tree2file(stderr, err_rc);
3610                 cYAML_free_tree(err_rc);
3611         }
3612
3613         return rc;
3614 }
3615
3616 static int jt_export(int argc, char **argv)
3617 {
3618         struct cYAML *show_rc = NULL;
3619         struct cYAML *err_rc = NULL;
3620         int rc;
3621         FILE *f = NULL;
3622         int opt;
3623         bool backup = false;
3624         char *file = NULL;
3625
3626         const char *const short_options = "bh";
3627         static const struct option long_options[] = {
3628                 { .name = "backup", .has_arg = no_argument, .val = 'b' },
3629                 { .name = "help", .has_arg = no_argument, .val = 'h' },
3630                 { .name = NULL } };
3631
3632         while ((opt = getopt_long(argc, argv, short_options,
3633                                    long_options, NULL)) != -1) {
3634                 switch (opt) {
3635                 case 'b':
3636                         backup = true;
3637                         break;
3638                 case 'h':
3639                 default:
3640                         printf("export > FILE.yaml : export configuration\n"
3641                                "\t--backup: export only what's necessary for reconfig\n"
3642                                "\t--help: display this help\n");
3643                         return 0;
3644                 }
3645         }
3646
3647         if (backup && argc >= 3)
3648                 file = argv[2];
3649         else if (!backup && argc >= 2)
3650                 file = argv[1];
3651         else
3652                 f = stdout;
3653
3654         if (file) {
3655                 f = fopen(file, "w");
3656                 if (f == NULL)
3657                         return -1;
3658         }
3659
3660         rc = lustre_lnet_show_net(NULL, 2, -1, &show_rc, &err_rc, backup);
3661         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3662                 cYAML_print_tree2file(stderr, err_rc);
3663                 cYAML_free_tree(err_rc);
3664                 err_rc = NULL;
3665         }
3666
3667         rc = lustre_lnet_show_route(NULL, NULL, -1, -1, 1, -1, &show_rc,
3668                                     &err_rc, backup);
3669         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3670                 cYAML_print_tree2file(stderr, err_rc);
3671                 cYAML_free_tree(err_rc);
3672                 err_rc = NULL;
3673         }
3674
3675         rc = lustre_lnet_show_routing(-1, &show_rc, &err_rc, backup);
3676         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3677                 cYAML_print_tree2file(stderr, err_rc);
3678                 cYAML_free_tree(err_rc);
3679                 err_rc = NULL;
3680         }
3681
3682         rc = lustre_lnet_show_peer(NULL, 2, -1, &show_rc, &err_rc, backup);
3683         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3684                 cYAML_print_tree2file(stderr, err_rc);
3685                 cYAML_free_tree(err_rc);
3686                 err_rc = NULL;
3687         }
3688
3689         rc = lustre_lnet_show_numa_range(-1, &show_rc, &err_rc);
3690         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3691                 cYAML_print_tree2file(stderr, err_rc);
3692                 cYAML_free_tree(err_rc);
3693                 err_rc = NULL;
3694         }
3695
3696         rc = lustre_lnet_show_max_intf(-1, &show_rc, &err_rc);
3697         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3698                 cYAML_print_tree2file(stderr, err_rc);
3699                 cYAML_free_tree(err_rc);
3700                 err_rc = NULL;
3701         }
3702
3703         rc = lustre_lnet_show_discovery(-1, &show_rc, &err_rc);
3704         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3705                 cYAML_print_tree2file(stderr, err_rc);
3706                 cYAML_free_tree(err_rc);
3707                 err_rc = NULL;
3708         }
3709
3710         rc = lustre_lnet_show_drop_asym_route(-1, &show_rc, &err_rc);
3711         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3712                 cYAML_print_tree2file(stderr, err_rc);
3713                 cYAML_free_tree(err_rc);
3714                 err_rc = NULL;
3715         }
3716
3717         rc = lustre_lnet_show_retry_count(-1, &show_rc, &err_rc);
3718         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3719                 cYAML_print_tree2file(stderr, err_rc);
3720                 err_rc = NULL;
3721         }
3722
3723         rc = lustre_lnet_show_transaction_to(-1, &show_rc, &err_rc);
3724         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3725                 cYAML_print_tree2file(stderr, err_rc);
3726                 err_rc = NULL;
3727         }
3728
3729         rc = lustre_lnet_show_hsensitivity(-1, &show_rc, &err_rc);
3730         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3731                 cYAML_print_tree2file(stderr, err_rc);
3732                 err_rc = NULL;
3733         }
3734
3735         rc = lustre_lnet_show_recov_intrv(-1, &show_rc, &err_rc);
3736         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3737                 cYAML_print_tree2file(stderr, err_rc);
3738                 err_rc = NULL;
3739         }
3740
3741         rc = lustre_lnet_show_rtr_sensitivity(-1, &show_rc, &err_rc);
3742         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3743                 cYAML_print_tree2file(stderr, err_rc);
3744                 err_rc = NULL;
3745         }
3746
3747         rc = lustre_lnet_show_lnd_timeout(-1, &show_rc, &err_rc);
3748         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3749                 cYAML_print_tree2file(stderr, err_rc);
3750                 err_rc = NULL;
3751         }
3752
3753         rc = lustre_lnet_show_response_tracking(-1, &show_rc, &err_rc);
3754         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3755                 cYAML_print_tree2file(stderr, err_rc);
3756                 cYAML_free_tree(err_rc);
3757                 err_rc = NULL;
3758         }
3759
3760         rc = lustre_lnet_show_recovery_limit(-1, &show_rc, &err_rc);
3761         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3762                 cYAML_print_tree2file(stderr, err_rc);
3763                 cYAML_free_tree(err_rc);
3764                 err_rc = NULL;
3765         }
3766
3767         rc = lustre_lnet_show_max_recovery_ping_interval(-1, &show_rc, &err_rc);
3768         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3769                 cYAML_print_tree2file(stderr, err_rc);
3770                 cYAML_free_tree(err_rc);
3771                 err_rc = NULL;
3772         }
3773
3774         rc = lustre_lnet_show_udsp(-1, -1, &show_rc, &err_rc);
3775         if (rc != LUSTRE_CFG_RC_NO_ERR) {
3776                 cYAML_print_tree2file(stderr, err_rc);
3777                 cYAML_free_tree(err_rc);
3778                 err_rc = NULL;
3779         }
3780
3781         if (show_rc != NULL) {
3782                 cYAML_print_tree2file(f, show_rc);
3783                 cYAML_free_tree(show_rc);
3784         }
3785
3786         if (argc >= 2)
3787                 fclose(f);
3788
3789         return 0;
3790 }
3791
3792 static int jt_peer_nid_common(int argc, char **argv, int cmd)
3793 {
3794         int flags = cmd == LNETCTL_ADD_CMD ? NLM_F_CREATE : 0;
3795         int rc = LUSTRE_CFG_RC_NO_ERR, opt;
3796         bool is_mr = true;
3797         char *prim_nid = NULL, *nidstr = NULL;
3798         char err_str[LNET_MAX_STR_LEN] = "Error";
3799         struct cYAML *err_rc = NULL;
3800         int force_lock = 0;
3801         const char *const short_opts = "k:m:n:f:l";
3802         const struct option long_opts[] = {
3803         { .name = "prim_nid",   .has_arg = required_argument,   .val = 'k' },
3804         { .name = "non_mr",     .has_arg = no_argument,         .val = 'm' },
3805         { .name = "nid",        .has_arg = required_argument,   .val = 'n' },
3806         { .name = "force",      .has_arg = no_argument,         .val = 'f' },
3807         { .name = "lock_prim",  .has_arg = no_argument,         .val = 'l' },
3808         { .name = NULL } };
3809
3810         rc = check_cmd(peer_cmds, "peer",
3811                        cmd == LNETCTL_ADD_CMD ? "add" : "del", 2, argc, argv);
3812         if (rc)
3813                 return rc;
3814
3815         while ((opt = getopt_long(argc, argv, short_opts,
3816                                   long_opts, NULL)) != -1) {
3817                 switch (opt) {
3818                 case 'k':
3819                         prim_nid = optarg;
3820                         break;
3821                 case 'n':
3822                         nidstr = optarg;
3823                         break;
3824                 case 'm':
3825                         if (cmd == LNETCTL_DEL_CMD) {
3826                                 rc = LUSTRE_CFG_RC_BAD_PARAM;
3827                                 snprintf(err_str, LNET_MAX_STR_LEN,
3828                                          "Unrecognized option '-%c'", opt);
3829                                 goto build_error;
3830                         }
3831                         is_mr = false;
3832                         break;
3833                 case 'f':
3834                         if (cmd == LNETCTL_ADD_CMD) {
3835                                 rc = LUSTRE_CFG_RC_BAD_PARAM;
3836                                 snprintf(err_str, LNET_MAX_STR_LEN,
3837                                          "Unrecognized option '-%c'", opt);
3838                         }
3839                         force_lock = 1;
3840                         flags |= NLM_F_EXCL;
3841                         break;
3842                 case 'l':
3843                         if (cmd == LNETCTL_DEL_CMD) {
3844                                 rc = LUSTRE_CFG_RC_BAD_PARAM;
3845                                 snprintf(err_str, LNET_MAX_STR_LEN,
3846                                          "Unrecognized option '-%c'", opt);
3847                         }
3848                         force_lock = 1;
3849                         flags |= NLM_F_EXCL;
3850                         break;
3851                 case '?':
3852                         print_help(peer_cmds, "peer",
3853                                    cmd == LNETCTL_ADD_CMD ? "add" : "del");
3854                 default:
3855                         return 0;
3856                 }
3857         }
3858
3859         rc = yaml_lnet_peer(prim_nid, nidstr, !is_mr, -1, -1, false,
3860                             LNET_GENL_VERSION, flags);
3861         if (rc <= 0) {
3862                 if (rc == -EOPNOTSUPP)
3863                         goto old_api;
3864                 return rc;
3865         }
3866 old_api:
3867         rc = lustre_lnet_modify_peer(prim_nid, nidstr, is_mr, cmd,
3868                                      force_lock, -1, &err_rc);
3869         if (rc != LUSTRE_CFG_RC_NO_ERR)
3870                 goto out;
3871
3872 build_error:
3873         cYAML_build_error(rc, -1, "peer",
3874                           cmd == LNETCTL_ADD_CMD ? "add" : "del",
3875                           err_str, &err_rc);
3876
3877 out:
3878         if (rc != LUSTRE_CFG_RC_NO_ERR)
3879                 cYAML_print_tree2file(stderr, err_rc);
3880
3881         cYAML_free_tree(err_rc);
3882
3883         return rc;
3884 }
3885
3886 static int jt_add_peer_nid(int argc, char **argv)
3887 {
3888         return jt_peer_nid_common(argc, argv, LNETCTL_ADD_CMD);
3889 }
3890
3891 static int jt_del_peer_nid(int argc, char **argv)
3892 {
3893         return jt_peer_nid_common(argc, argv, LNETCTL_DEL_CMD);
3894 }
3895
3896 static int jt_show_peer(int argc, char **argv)
3897 {
3898         char *nid = NULL;
3899         int rc, opt;
3900         struct cYAML *err_rc = NULL, *show_rc = NULL;
3901         long int detail = 0;
3902         const char *const short_opts = "hn:v::";
3903         const struct option long_opts[] = {
3904                 { .name = "help",       .has_arg = no_argument,         .val = 'h' },
3905                 { .name = "nid",        .has_arg = required_argument,   .val = 'n' },
3906                 { .name = "verbose",    .has_arg = optional_argument,   .val = 'v' },
3907                 { .name = NULL }
3908         };
3909
3910         rc = check_cmd(peer_cmds, "peer", "show", 1, argc, argv);
3911         if (rc)
3912                 return rc;
3913
3914         while ((opt = getopt_long(argc, argv, short_opts,
3915                                   long_opts, NULL)) != -1) {
3916                 switch (opt) {
3917                 case 'n':
3918                         nid = optarg;
3919                         break;
3920                 case 'v':
3921                         if ((!optarg) && (argv[optind] != NULL) &&
3922                             (argv[optind][0] != '-')) {
3923                                 if (parse_long(argv[optind++], &detail) != 0)
3924                                         detail = 1;
3925                         } else {
3926                                 detail = 1;
3927                         }
3928                         break;
3929                 case '?':
3930                         print_help(peer_cmds, "peer", "show");
3931                 default:
3932                         return 0;
3933                 }
3934         }
3935
3936         rc = yaml_lnet_peer(nid, NULL, false, -1, -1, false, detail,
3937                             NLM_F_DUMP);
3938         if (rc <= 0) {
3939                 if (rc == -EOPNOTSUPP)
3940                         goto old_api;
3941                 return rc;
3942         }
3943 old_api:
3944         rc = lustre_lnet_show_peer(nid, (int) detail, -1, &show_rc, &err_rc,
3945                                    false);
3946
3947         if (rc != LUSTRE_CFG_RC_NO_ERR)
3948                 cYAML_print_tree2file(stderr, err_rc);
3949         else if (show_rc)
3950                 cYAML_print_tree(show_rc);
3951
3952         cYAML_free_tree(err_rc);
3953         cYAML_free_tree(show_rc);
3954
3955         return rc;
3956 }
3957
3958 static int jt_list_peer(int argc, char **argv)
3959 {
3960         int rc;
3961         struct cYAML *err_rc = NULL, *list_rc = NULL;
3962
3963         rc = check_cmd(peer_cmds, "peer", "list", 0, argc, argv);
3964         if (rc)
3965                 return rc;
3966
3967         rc = yaml_lnet_peer(NULL, NULL, false, -1, -1, true, 0, NLM_F_DUMP);
3968         if (rc <= 0) {
3969                 if (rc == -EOPNOTSUPP)
3970                         goto old_api;
3971                 return rc;
3972         }
3973 old_api:
3974         if (rc != LUSTRE_CFG_RC_NO_ERR)
3975                 cYAML_print_tree2file(stderr, err_rc);
3976         else if (list_rc)
3977                 cYAML_print_tree(list_rc);
3978
3979         cYAML_free_tree(err_rc);
3980         cYAML_free_tree(list_rc);
3981
3982         return rc;
3983 }
3984
3985 static int yaml_lnet_ping_display(yaml_parser_t *reply)
3986 {
3987         yaml_emitter_t debug;
3988         bool done = false;
3989         int rc, rc2 = 0;
3990         long error = 0;
3991
3992         rc = yaml_emitter_initialize(&debug);
3993         if (rc == 1)
3994                 yaml_emitter_set_output_file(&debug, stdout);
3995         if (rc == 0)
3996                 goto emitter_error;
3997
3998         while (!done) {
3999                 yaml_event_t event;
4000
4001                 rc = yaml_parser_parse(reply, &event);
4002                 if (rc == 0)
4003                         goto report_reply_error;
4004
4005                 if (event.type != YAML_SCALAR_EVENT) {
4006                         rc = yaml_emitter_emit(&debug, &event);
4007                         if (rc == 0)
4008                                 goto emitter_error;
4009
4010                         done = (event.type == YAML_DOCUMENT_END_EVENT);
4011                         continue;
4012                 }
4013
4014                 if (strcmp((char *)event.data.scalar.value, "errno") == 0) {
4015                         rc = yaml_emitter_emit(&debug, &event);
4016                         if (rc == 0)
4017                                 goto emitter_error;
4018
4019                         rc = yaml_parser_parse(reply, &event);
4020                         if (rc == 0)
4021                                 goto report_reply_error;
4022
4023                         rc = parse_long((char *)event.data.scalar.value,
4024                                         &error);
4025                         if (rc != 0)
4026                                 goto report_reply_error;
4027
4028                         rc = yaml_emitter_emit(&debug, &event);
4029                         if (rc == 0)
4030                                 goto emitter_error;
4031
4032                         rc2 = -1;
4033                 } else if (error != 0 &&
4034                            strcmp((char *)event.data.scalar.value,
4035                                   "descr") == 0) {
4036                         rc = yaml_emitter_emit(&debug, &event);
4037                         if (rc == 0)
4038                                 goto emitter_error;
4039
4040                         rc = yaml_parser_parse(reply, &event);
4041                         if (rc == 0)
4042                                 goto report_reply_error;
4043
4044                         if (strncmp((char *)event.data.scalar.value,
4045                                     "failed to ", strlen("failed to ")) == 0) {
4046                                 char err[256];
4047
4048                                 snprintf(err, sizeof(err), "%s: %s",
4049                                         (char *)event.data.scalar.value,
4050                                         strerror(-error));
4051                                 yaml_scalar_event_initialize(&event, NULL,
4052                                                              (yaml_char_t *)YAML_STR_TAG,
4053                                                              (yaml_char_t *)err,
4054                                                              strlen(err), 1, 0,
4055                                                              YAML_PLAIN_SCALAR_STYLE);
4056                         }
4057                         rc = yaml_emitter_emit(&debug, &event);
4058                         if (rc == 0)
4059                                 goto emitter_error;
4060
4061                         errno = 0;
4062                 } else {
4063                         rc = yaml_emitter_emit(&debug, &event);
4064                         if (rc == 0)
4065                                 goto emitter_error;
4066                 }
4067         }
4068 emitter_error:
4069         if (rc == 0)
4070                 yaml_emitter_log_error(&debug, stderr);
4071 report_reply_error:
4072         yaml_emitter_delete(&debug);
4073
4074         return rc2 ? rc2 : rc;
4075 }
4076
4077 static int yaml_lnet_ping(char *group, int timeout, char *src_nidstr,
4078                           int start, int end, char **nids, int flags)
4079 {
4080         struct nl_sock *sk = NULL;
4081         const char *msg = NULL;
4082         yaml_emitter_t output;
4083         yaml_parser_t reply;
4084         yaml_event_t event;
4085         int rc, i;
4086
4087         /* Create Netlink emitter to send request to kernel */
4088         sk = nl_socket_alloc();
4089         if (!sk)
4090                 return -EOPNOTSUPP;
4091
4092         /* Setup parser to receive Netlink packets */
4093         rc = yaml_parser_initialize(&reply);
4094         if (rc == 0) {
4095                 nl_socket_free(sk);
4096                 return -EOPNOTSUPP;
4097         }
4098
4099         rc = yaml_parser_set_input_netlink(&reply, sk, false);
4100         if (rc == 0) {
4101                 msg = yaml_parser_get_reader_error(&reply);
4102                 goto free_reply;
4103         }
4104
4105         /* Create Netlink emitter to send request to kernel */
4106         rc = yaml_emitter_initialize(&output);
4107         if (rc == 0) {
4108                 msg = "failed to initialize emitter";
4109                 goto free_reply;
4110         }
4111
4112         rc = yaml_emitter_set_output_netlink(&output, sk, LNET_GENL_NAME,
4113                                              LNET_GENL_VERSION, LNET_CMD_PING,
4114                                              flags);
4115         if (rc == 0)
4116                 goto emitter_error;
4117
4118         yaml_emitter_open(&output);
4119         yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
4120         rc = yaml_emitter_emit(&output, &event);
4121         if (rc == 0)
4122                 goto emitter_error;
4123
4124         yaml_mapping_start_event_initialize(&event, NULL,
4125                                             (yaml_char_t *)YAML_MAP_TAG,
4126                                             1, YAML_ANY_MAPPING_STYLE);
4127         rc = yaml_emitter_emit(&output, &event);
4128         if (rc == 0)
4129                 goto emitter_error;
4130
4131         yaml_scalar_event_initialize(&event, NULL,
4132                                      (yaml_char_t *)YAML_STR_TAG,
4133                                      (yaml_char_t *)group,
4134                                      strlen(group), 1, 0,
4135                                      YAML_PLAIN_SCALAR_STYLE);
4136         rc = yaml_emitter_emit(&output, &event);
4137         if (rc == 0)
4138                 goto emitter_error;
4139
4140         yaml_mapping_start_event_initialize(&event, NULL,
4141                                             (yaml_char_t *)YAML_MAP_TAG,
4142                                             1, YAML_ANY_MAPPING_STYLE);
4143         rc = yaml_emitter_emit(&output, &event);
4144         if (rc == 0)
4145                 goto emitter_error;
4146
4147         if (timeout != 1000 || src_nidstr) {
4148                 if (src_nidstr) {
4149                         yaml_scalar_event_initialize(&event, NULL,
4150                                                      (yaml_char_t *)YAML_STR_TAG,
4151                                                      (yaml_char_t *)"source",
4152                                                      strlen("source"), 1, 0,
4153                                                      YAML_PLAIN_SCALAR_STYLE);
4154                         rc = yaml_emitter_emit(&output, &event);
4155                         if (rc == 0)
4156                                 goto emitter_error;
4157
4158                         yaml_scalar_event_initialize(&event, NULL,
4159                                                      (yaml_char_t *)YAML_STR_TAG,
4160                                                      (yaml_char_t *)src_nidstr,
4161                                                      strlen(src_nidstr), 1, 0,
4162                                                      YAML_PLAIN_SCALAR_STYLE);
4163                         rc = yaml_emitter_emit(&output, &event);
4164                         if (rc == 0)
4165                                 goto emitter_error;
4166                 }
4167
4168                 if (timeout != 1000) {
4169                         char time[23];
4170
4171                         yaml_scalar_event_initialize(&event, NULL,
4172                                                      (yaml_char_t *)YAML_STR_TAG,
4173                                                      (yaml_char_t *)"timeout",
4174                                                      strlen("timeout"), 1, 0,
4175                                                      YAML_PLAIN_SCALAR_STYLE);
4176                         rc = yaml_emitter_emit(&output, &event);
4177                         if (rc == 0)
4178                                 goto emitter_error;
4179
4180                         snprintf(time, sizeof(time), "%u", timeout);
4181                         yaml_scalar_event_initialize(&event, NULL,
4182                                                      (yaml_char_t *)YAML_INT_TAG,
4183                                                      (yaml_char_t *)time,
4184                                                      strlen(time), 1, 0,
4185                                                      YAML_PLAIN_SCALAR_STYLE);
4186                         rc = yaml_emitter_emit(&output, &event);
4187                         if (rc == 0)
4188                                 goto emitter_error;
4189                 }
4190         }
4191
4192         yaml_scalar_event_initialize(&event, NULL,
4193                                      (yaml_char_t *)YAML_STR_TAG,
4194                                      (yaml_char_t *)"nids",
4195                                      strlen("nids"), 1, 0,
4196                                      YAML_PLAIN_SCALAR_STYLE);
4197         rc = yaml_emitter_emit(&output, &event);
4198         if (rc == 0)
4199                 goto emitter_error;
4200
4201         yaml_sequence_start_event_initialize(&event, NULL,
4202                                              (yaml_char_t *)YAML_SEQ_TAG,
4203                                              1, YAML_FLOW_SEQUENCE_STYLE);
4204         rc = yaml_emitter_emit(&output, &event);
4205         if (rc == 0)
4206                 goto emitter_error;
4207
4208         for (i = start; i < end; i++) {
4209                 yaml_scalar_event_initialize(&event, NULL,
4210                                              (yaml_char_t *)YAML_STR_TAG,
4211                                              (yaml_char_t *)nids[i],
4212                                              strlen(nids[i]), 1, 0,
4213                                              YAML_PLAIN_SCALAR_STYLE);
4214                 rc = yaml_emitter_emit(&output, &event);
4215                 if (rc == 0)
4216                         goto emitter_error;
4217         }
4218
4219         yaml_sequence_end_event_initialize(&event);
4220         rc = yaml_emitter_emit(&output, &event);
4221         if (rc == 0)
4222                 goto emitter_error;
4223
4224         yaml_mapping_end_event_initialize(&event);
4225         rc = yaml_emitter_emit(&output, &event);
4226         if (rc == 0)
4227                 goto emitter_error;
4228
4229         yaml_mapping_end_event_initialize(&event);
4230         rc = yaml_emitter_emit(&output, &event);
4231         if (rc == 0)
4232                 goto emitter_error;
4233
4234         yaml_document_end_event_initialize(&event, 0);
4235         rc = yaml_emitter_emit(&output, &event);
4236         if (rc == 0)
4237                 goto emitter_error;
4238
4239         rc = yaml_emitter_close(&output);
4240 emitter_error:
4241         if (rc == 0) {
4242                 yaml_emitter_log_error(&output, stderr);
4243                 rc = -EINVAL;
4244         } else {
4245                 rc = yaml_lnet_ping_display(&reply);
4246                 if (rc == 0)
4247                         msg = yaml_parser_get_reader_error(&reply);
4248         }
4249         yaml_emitter_delete(&output);
4250 free_reply:
4251         if (rc == 0) {
4252                 yaml_lnet_print_error(-1, group, msg);
4253                 rc = -EINVAL;
4254         }
4255
4256         yaml_parser_delete(&reply);
4257         nl_socket_free(sk);
4258
4259         return rc == 1 ? 0 : rc;
4260 }
4261
4262 static int jt_ping(int argc, char **argv)
4263 {
4264         struct cYAML *err_rc = NULL;
4265         struct cYAML *show_rc = NULL;
4266         int timeout = 1000;
4267         int rc = 0, opt;
4268         char *src_nidstr = NULL;
4269
4270         const char *const short_options = "hs:t:";
4271         const struct option long_options[] = {
4272         { .name = "help",       .has_arg = no_argument,         .val = 'h' },
4273         { .name = "timeout",    .has_arg = required_argument,   .val = 't' },
4274         { .name = "source",     .has_arg = required_argument,   .val = 's' },
4275         { .name = NULL } };
4276
4277         while ((opt = getopt_long(argc, argv, short_options,
4278                                   long_options, NULL)) != -1) {
4279                 switch (opt) {
4280                 case 's':
4281                         src_nidstr = optarg;
4282                         break;
4283                 case 't':
4284                         timeout = 1000 * atol(optarg);
4285                         break;
4286                 case 'h':
4287                         printf("ping nid[,nid,...]\n"
4288                                "\t --source: source nid\n"
4289                                "\t --timeout: ping timeout\n"
4290                                "\t --help: display this help\n");
4291                         return 0;
4292                 default:
4293                         return 0;
4294                 }
4295         }
4296
4297         for (; optind < argc; optind++)
4298                 rc = lustre_lnet_ping_nid(argv[optind], src_nidstr, timeout, -1,
4299                                           &show_rc, &err_rc);
4300
4301         if (show_rc)
4302                 cYAML_print_tree(show_rc);
4303
4304         if (err_rc)
4305                 cYAML_print_tree2file(stderr, err_rc);
4306
4307         cYAML_free_tree(err_rc);
4308         cYAML_free_tree(show_rc);
4309
4310         return rc;
4311 }
4312
4313 static int jt_discover(int argc, char **argv)
4314 {
4315         struct cYAML *err_rc = NULL;
4316         struct cYAML *show_rc = NULL;
4317         int flags = NLM_F_CREATE;
4318         int force = 0;
4319         int rc = 0, opt;
4320         const char *const short_options = "fh";
4321         const struct option long_options[] = {
4322                 { .name = "force",      .has_arg = no_argument, .val = 'f' },
4323                 { .name = "help",       .has_arg = no_argument, .val = 'h' },
4324                 { .name = NULL }
4325         };
4326
4327         while ((opt = getopt_long(argc, argv, short_options,
4328                                   long_options, NULL)) != -1) {
4329                 switch (opt) {
4330                 case 'f':
4331                         /* BSD treats NLM_F_CREATE | NLM_F_EXCL as an add */
4332                         flags |= NLM_F_EXCL;
4333                         force = 1;
4334                         break;
4335                 case 'h':
4336                         printf("discover nid[,nid,...]\n"
4337                                "\t --force: force discovery\n"
4338                                "\t --help: display this help\n");
4339                         return 0;
4340                 default:
4341                         return 0;
4342                 }
4343         }
4344
4345         if (optind == argc) {
4346                 printf("Missing nid argument\n");
4347                 return -1;
4348         }
4349
4350         rc = yaml_lnet_ping("discover", 1000, NULL, optind, argc, argv,
4351                             flags);
4352         if (rc <= 0) {
4353                 if (rc != -EOPNOTSUPP)
4354                         return rc;
4355         }
4356
4357         for (; optind < argc; optind++)
4358                 rc = lustre_lnet_discover_nid(argv[optind], force, -1, &show_rc,
4359                                               &err_rc);
4360
4361         if (show_rc)
4362                 cYAML_print_tree(show_rc);
4363
4364         if (err_rc)
4365                 cYAML_print_tree2file(stderr, err_rc);
4366
4367         cYAML_free_tree(err_rc);
4368         cYAML_free_tree(show_rc);
4369
4370         return rc;
4371 }
4372
4373 static int jt_add_udsp(int argc, char **argv)
4374 {
4375         char *src = NULL, *dst = NULL, *rte = NULL;
4376         struct cYAML *err_rc = NULL;
4377         union lnet_udsp_action udsp_action;
4378         long int idx = -1, priority = -1;
4379         int opt, rc = 0;
4380         char *action_type = "pref";
4381
4382         const char *const short_options = "s:d:r:p:i:";
4383         static const struct option long_options[] = {
4384         { .name = "src",         .has_arg = required_argument, .val = 's' },
4385         { .name = "dst",         .has_arg = required_argument, .val = 'd' },
4386         { .name = "rte",         .has_arg = required_argument, .val = 'r' },
4387         { .name = "priority",    .has_arg = required_argument, .val = 'p' },
4388         { .name = "idx",         .has_arg = required_argument, .val = 'i' },
4389         { .name = NULL } };
4390
4391         rc = check_cmd(udsp_cmds, "udsp", "add", 0, argc, argv);
4392         if (rc)
4393                 return rc;
4394
4395         while ((opt = getopt_long(argc, argv, short_options,
4396                                   long_options, NULL)) != -1) {
4397                 switch (opt) {
4398                 case 's':
4399                         src = optarg;
4400                         break;
4401                 case 'd':
4402                         dst = optarg;
4403                         break;
4404                 case 'r':
4405                         rte = optarg;
4406                         break;
4407                 case 'p':
4408                         rc = parse_long(optarg, &priority);
4409                         if (rc != 0 || priority < 0) {
4410                                 printf("Invalid priority \"%s\"\n", optarg);
4411                                 return -EINVAL;
4412                         }
4413                         action_type = "priority";
4414                         udsp_action.udsp_priority = priority;
4415                         break;
4416                 case 'i':
4417                         rc = parse_long(optarg, &idx);
4418                         if (rc != 0 || idx < 0) {
4419                                 printf("Invalid index \"%s\"\n", optarg);
4420                                 return -EINVAL;
4421                         }
4422                         break;
4423                 case '?':
4424                         print_help(udsp_cmds, "udsp", "add");
4425                 default:
4426                         return 0;
4427                 }
4428         }
4429
4430         if (!(src || dst || rte)) {
4431                 print_help(udsp_cmds, "udsp", "add");
4432                 return 0;
4433         }
4434
4435         rc = lustre_lnet_add_udsp(src, dst, rte, action_type, &udsp_action,
4436                                   idx, -1, &err_rc);
4437
4438         if (rc != LUSTRE_CFG_RC_NO_ERR)
4439                 cYAML_print_tree2file(stderr, err_rc);
4440
4441         cYAML_free_tree(err_rc);
4442
4443         return rc;
4444 }
4445
4446 static int jt_del_udsp(int argc, char **argv)
4447 {
4448         struct cYAML *err_rc = NULL;
4449         long int idx = -2;
4450         int opt, rc = 0;
4451         bool all = false;
4452
4453         const char *const short_options = "ai:";
4454         static const struct option long_options[] = {
4455         { .name = "all",        .has_arg = no_argument, .val = 'a' },
4456         { .name = "idx",        .has_arg = required_argument, .val = 'i' },
4457         { .name = NULL } };
4458
4459         rc = check_cmd(udsp_cmds, "udsp", "del", 0, argc, argv);
4460         if (rc)
4461                 return rc;
4462
4463         while ((opt = getopt_long(argc, argv, short_options,
4464                                   long_options, NULL)) != -1) {
4465                 switch (opt) {
4466                 case 'a':
4467                         all = true;
4468                         break;
4469                 case 'i':
4470                         rc = parse_long(optarg, &idx);
4471                         if (rc != 0 || idx < -1) {
4472                                 printf("Invalid index \"%s\"\n", optarg);
4473                                 return -EINVAL;
4474                         }
4475                         break;
4476                 case '?':
4477                         print_help(udsp_cmds, "udsp", "del");
4478                 default:
4479                         return 0;
4480                 }
4481         }
4482
4483         if (all && idx != -2) {
4484                 printf("Cannot combine --all with --idx\n");
4485                 return -EINVAL;
4486         } else if (all) {
4487                 idx = -1;
4488         } else if (idx == -2) {
4489                 printf("Must specify --idx or --all\n");
4490                 return -EINVAL;
4491         }
4492
4493         rc = lustre_lnet_del_udsp(idx, -1, &err_rc);
4494         if (rc != LUSTRE_CFG_RC_NO_ERR)
4495                 cYAML_print_tree2file(stderr, err_rc);
4496
4497         cYAML_free_tree(err_rc);
4498
4499         return rc;
4500 }
4501
4502 int main(int argc, char **argv)
4503 {
4504         int rc = 0;
4505         struct cYAML *err_rc = NULL;
4506
4507         rc = lustre_lnet_config_lib_init();
4508         if (rc < 0) {
4509                 cYAML_build_error(-1, -1, "lnetctl", "startup",
4510                                   "cannot register LNet device", &err_rc);
4511                 cYAML_print_tree2file(stderr, err_rc);
4512                 return rc;
4513         }
4514
4515         return cfs_parser(argc, argv, cmd_list);
4516 }