1 // SPDX-License-Identifier: LGPL-2.0
4 * Copyright (c) 2014, 2017, Intel Corporation.
8 * This file is part of Lustre, http://www.lustre.org/
10 * Author: Amir Shehata <amir.shehata@intel.com>
19 #include <libcfs/util/ioctl.h>
20 #include <libcfs/util/parser.h>
21 #include "lnetconfig/cyaml.h"
22 #include "lnetconfig/liblnetconfig.h"
24 #define LNET_CONFIGURE true
25 #define LNET_UNCONFIGURE false
27 static int jt_config_lnet(int argc, char **argv);
28 static int jt_unconfig_lnet(int argc, char **argv);
29 static int jt_add_route(int argc, char **argv);
30 static int jt_add_ni(int argc, char **argv);
31 static int jt_set_routing(int argc, char **argv);
32 static int jt_del_route(int argc, char **argv);
33 static int jt_del_ni(int argc, char **argv);
34 static int jt_show_route(int argc, char **argv);
35 static int jt_show_net(int argc, char **argv);
36 static int jt_show_routing(int argc, char **argv);
37 static int jt_show_stats(int argc, char **argv);
38 static int jt_show_peer(int argc, char **argv);
39 static int jt_show_recovery(int argc, char **argv);
40 static int jt_show_global(int argc, char **argv);
41 static int jt_show_udsp(int argc, char **argv);
42 static int jt_set_tiny(int argc, char **argv);
43 static int jt_set_small(int argc, char **argv);
44 static int jt_set_large(int argc, char **argv);
45 static int jt_set_numa(int argc, char **argv);
46 static int jt_set_retry_count(int argc, char **argv);
47 static int jt_set_transaction_to(int argc, char **argv);
48 static int jt_set_recov_intrv(int argc, char **argv);
49 static int jt_set_rtr_sensitivity(int argc, char **argv);
50 static int jt_set_hsensitivity(int argc, char **argv);
51 static int jt_set_max_recovery_ping_interval(int argc, char **argv);
52 static int jt_reset_stats(int argc, char **argv);
53 static int jt_add_peer_nid(int argc, char **argv);
54 static int jt_del_peer_nid(int argc, char **argv);
55 static int jt_set_max_intf(int argc, char **argv);
56 static int jt_set_discovery(int argc, char **argv);
57 static int jt_set_drop_asym_route(int argc, char **argv);
58 static int jt_list_peer(int argc, char **argv);
59 static int jt_add_udsp(int argc, char **argv);
60 static int jt_del_udsp(int argc, char **argv);
61 /*static int jt_show_peer(int argc, char **argv);*/
62 static int jt_import(int argc, char **argv);
63 static int jt_export(int argc, char **argv);
64 static int jt_ping(int argc, char **argv);
65 static int jt_discover(int argc, char **argv);
66 static int jt_lnet(int argc, char **argv);
67 static int jt_route(int argc, char **argv);
68 static int jt_net(int argc, char **argv);
69 static int jt_routing(int argc, char **argv);
70 static int jt_set(int argc, char **argv);
71 static int jt_debug(int argc, char **argv);
72 static int jt_stats(int argc, char **argv);
73 static int jt_global(int argc, char **argv);
74 static int jt_peers(int argc, char **argv);
75 static int jt_set_ni_value(int argc, char **argv);
76 static int jt_set_peer_ni_value(int argc, char **argv);
77 static int jt_calc_service_id(int argc, char **argv);
78 static int jt_set_response_tracking(int argc, char **argv);
79 static int jt_set_recovery_limit(int argc, char **argv);
80 static int jt_udsp(int argc, char **argv);
81 static int jt_setup_mrrouting(int argc, char **argv);
82 static int jt_calc_cpt_of_nid(int argc, char **argv);
83 static int jt_show_peer_debug_info(int argc, char **argv);
85 command_t cmd_list[] = {
86 {"lnet", jt_lnet, 0, "lnet {configure | unconfigure} [--all]"},
87 {"route", jt_route, 0, "route {add | del | show | help}"},
88 {"net", jt_net, 0, "net {add | del | show | set | help}"},
89 {"routing", jt_routing, 0, "routing {show | help}"},
90 {"set", jt_set, 0, "set {tiny_buffers | small_buffers | large_buffers"
91 " | routing | numa_range | max_interfaces"
92 " | discovery | drop_asym_route | retry_count"
93 " | transaction_timeout | health_sensitivity"
94 " | recovery_interval | router_sensitivity"
95 " | response_tracking | recovery_limit}"},
96 {"import", jt_import, 0, "import FILE.yaml"},
97 {"export", jt_export, 0, "export FILE.yaml"},
98 {"stats", jt_stats, 0, "stats {show | help}"},
99 {"debug", jt_debug, 0, "debug {recovery {local | peer} | peer}"},
100 {"global", jt_global, 0, "global {show | help}"},
101 {"peer", jt_peers, 0, "peer {add | del | show | list | set | help}"},
102 {"ping", jt_ping, 0, "ping nid,[nid,...]"},
103 {"discover", jt_discover, 0, "discover nid[,nid,...]"},
104 {"service-id", jt_calc_service_id, 0, "Calculate IB Lustre service ID\n"},
105 {"udsp", jt_udsp, 0, "udsp {add | del | help}"},
106 {"setup-mrrouting", jt_setup_mrrouting, 0,
107 "setup linux routing tables\n"},
108 {"cpt-of-nid", jt_calc_cpt_of_nid, 0,
109 "Calculate the CPTs associated with NIDs\n"
110 " usage:\n\tlnetctl cpt-of-nid nid[ nid ...]\n"},
114 command_t lnet_cmds[] = {
115 {"configure", jt_config_lnet, 0, "configure lnet\n"
116 "\t--all: load NI configuration from module parameters\n"},
117 {"unconfigure", jt_unconfig_lnet, 0, "unconfigure lnet\n"},
121 command_t route_cmds[] = {
122 {"add", jt_add_route, 0, "add a route\n"
123 "\t--net: net name (e.g. tcp0)\n"
124 "\t--gateway: gateway nid (e.g. 10.1.1.2@tcp)\n"
125 "\t--hop|hop-count: number to final destination (1 <= hops <= 255)\n"
126 "\t--priority: priority of route (0 - highest prio\n"
127 "\t--health_sensitivity: gateway health sensitivity (>= 1)\n"},
128 {"del", jt_del_route, 0, "delete a route\n"
129 "\t--net: net name (e.g. tcp0)\n"
130 "\t--gateway: gateway nid (e.g. 10.1.1.2@tcp)\n"},
131 {"show", jt_show_route, 0, "show routes\n"
132 "\t--net: net name (e.g. tcp0) to filter on\n"
133 "\t--gateway: gateway nid (e.g. 10.1.1.2@tcp) to filter on\n"
134 "\t--hop|hop-count: number to final destination (1 <= hops <= 255) to filter on\n"
135 "\t--priority: priority of route (0 - highest prio to filter on\n"
136 "\t--verbose: display detailed output per route\n"},
140 command_t net_cmds[] = {
141 {"add", jt_add_ni, 0, "add a network\n"
142 "\t--net: net name (e.g. tcp0)\n"
143 "\t--if: physical interface (e.g. eth0)\n"
144 "\t--ip2net: specify networks based on IP address patterns\n"
145 "\t--peer-timeout: time to wait before declaring a peer dead\n"
146 "\t--peer-credits: define the max number of inflight messages\n"
147 "\t--peer-buffer-credits: the number of buffer credits per peer\n"
148 "\t--credits: Network Interface credits\n"
149 "\t--cpt: CPU Partitions configured net uses (e.g. [0,1]\n"
150 "\t--conns-per-peer: number of connections per peer\n"
151 "\t--skip-mr-route-setup: do not add linux route for the ni\n"
152 "\t--auth-key: Network authorization key (kfilnd only)\n"
153 "\t--traffic-class: Traffic class (kfilnd only)\n"},
154 {"del", jt_del_ni, 0, "delete a network\n"
155 "\t--net: net name (e.g. tcp0)\n"
156 "\t--if: physical interface (e.g. eth0)\n"},
157 {"show", jt_show_net, 0, "show networks\n"
158 "\t--net: net name (e.g. tcp0) to filter on\n"
159 "\t--verbose: display detailed output per network."
160 " Optional argument of '2' outputs more stats\n"},
161 {"set", jt_set_ni_value, 0, "set local NI specific parameter\n"
162 "\t--nid: NI NID to set the\n"
163 "\t--health: specify health value to set\n"
164 "\t--conns-per-peer: number of connections per peer\n"
165 "\t--all: set all NIs value to the one specified\n"},
169 command_t routing_cmds[] = {
170 {"show", jt_show_routing, 0, "show routing information\n"},
174 command_t stats_cmds[] = {
175 {"show", jt_show_stats, 0, "show LNET statistics\n"},
176 {"reset", jt_reset_stats, 0, "reset LNET statistics\n"},
180 command_t debug_cmds[] = {
181 {"recovery", jt_show_recovery, 0, "list recovery queues\n"
182 "\t--local : list local recovery queue\n"
183 "\t--peer : list peer recovery queue\n"},
184 {"peer", jt_show_peer_debug_info, 0, "show peer debug info\n"
185 "\t--nid: peer's NID\n"},
189 command_t global_cmds[] = {
190 {"show", jt_show_global, 0, "show global variables\n"},
194 command_t set_cmds[] = {
195 {"tiny_buffers", jt_set_tiny, 0, "set tiny routing buffers\n"
196 "\tVALUE must be greater than 0\n"},
197 {"small_buffers", jt_set_small, 0, "set small routing buffers\n"
198 "\tVALUE must be greater than 0\n"},
199 {"large_buffers", jt_set_large, 0, "set large routing buffers\n"
200 "\tVALUE must be greater than 0\n"},
201 {"routing", jt_set_routing, 0, "enable/disable routing\n"
202 "\t0 - disable routing\n"
203 "\t1 - enable routing\n"},
204 {"numa_range", jt_set_numa, 0, "set NUMA range for NI selection\n"
205 "\tVALUE must be at least 0\n"},
206 {"max_interfaces", jt_set_max_intf, 0, "set the default value for "
208 "\tValue must be greater than 16\n"},
209 {"discovery", jt_set_discovery, 0, "enable/disable peer discovery\n"
210 "\t0 - disable peer discovery\n"
211 "\t1 - enable peer discovery (default)\n"},
212 {"drop_asym_route", jt_set_drop_asym_route, 0,
213 "drop/accept asymmetrical route messages\n"
214 "\t0 - accept asymmetrical route messages (default)\n"
215 "\t1 - drop asymmetrical route messages\n"},
216 {"retry_count", jt_set_retry_count, 0, "number of retries\n"
217 "\t0 - turn of retries\n"
218 "\t>0 - number of retries\n"},
219 {"transaction_timeout", jt_set_transaction_to, 0, "Message/Response timeout\n"
220 "\t>0 - timeout in seconds\n"},
221 {"health_sensitivity", jt_set_hsensitivity, 0, "sensitivity to failure\n"
222 "\t0 - turn off health evaluation\n"
223 "\t>0 - sensitivity value not more than 1000\n"},
224 {"recovery_interval", jt_set_recov_intrv, 0, "interval to ping in seconds (at least 1)\n"
225 "\t>0 - time in seconds between pings\n"},
226 {"router_sensitivity", jt_set_rtr_sensitivity, 0, "router sensitivity %\n"
227 "\t100 - router interfaces need to be fully healthy to be used\n"
228 "\t<100 - router interfaces can be used even if not healthy\n"},
229 {"response_tracking", jt_set_response_tracking, 0,
230 "Set the behavior of response tracking\n"
231 "\t0 - Only LNet pings and discovery pushes utilize response tracking\n"
232 "\t1 - GETs are eligible for response tracking\n"
233 "\t2 - PUTs are eligible for response tracking\n"
234 "\t3 - Both PUTs and GETs are eligible for response tracking (default)\n"
235 "\tNote: Regardless of the value of the response_tracking parameter LNet\n"
236 "\t pings and discovery pushes always utilize response tracking\n"},
237 {"recovery_limit", jt_set_recovery_limit, 0,
238 "Set how long LNet will attempt to recover unhealthy interfaces.\n"
239 "\t0 - Recover indefinitely (default)\n"
240 "\t>0 - Recover for the specified number of seconds.\n"},
241 {"max_recovery_ping_interval", jt_set_max_recovery_ping_interval, 0,
242 "maximum recovery ping interval\n"
243 "\t>0 - maximum recovery ping interval in seconds\n"},
247 command_t peer_cmds[] = {
248 {"add", jt_add_peer_nid, 0, "add a peer NID\n"
249 "\t--prim_nid: Primary NID of the peer.\n"
250 "\t--nid: one or more peer NIDs\n"
251 "\t--non_mr: create this peer as not Multi-Rail capable\n"
252 "\t--ip2nets: specify a range of nids per peer\n"
253 "\t--lock_prim: lock primary nid\n"},
254 {"del", jt_del_peer_nid, 0, "delete a peer NID\n"
255 "\t--prim_nid: Primary NID of the peer.\n"
256 "\t--nid: list of NIDs to remove. If none provided,\n"
257 "\t peer is deleted\n"
258 "\t--ip2nets: specify a range of nids per peer\n"
259 "\t--force: force-delete locked primary NID\n"},
260 {"show", jt_show_peer, 0, "show peer information\n"
261 "\t--nid: NID of peer to filter on.\n"
262 "\t--verbose: display detailed output per peer."
263 " Optional argument of '2' outputs more stats\n"},
264 {"list", jt_list_peer, 0, "list all peers\n"},
265 {"set", jt_set_peer_ni_value, 0, "set peer ni specific parameter\n"
266 "\t--nid: Peer NI NID to set the\n"
267 "\t--health: specify health value to set\n"
268 "\t--all: set all peer_nis values to the one specified\n"
269 "\t--state: set peer state (DANGEROUS: for test/debug only)"},
273 command_t udsp_cmds[] = {
274 {"add", jt_add_udsp, 0, "add a udsp\n"
275 "\t--src nid|net: ip2nets syntax specifying the local NID or network to match.\n"
276 "\t--dst nid: ip2nets syntax specifying the remote NID to match.\n"
277 "\t--rte nid: ip2nets syntax specifying the router NID to match.\n"
278 "\t--priority p: Assign priority value p where p >= 0.\n"
279 "\t Note: 0 is the highest priority.\n"
280 "\t--idx n: Insert the rule in the n'th position on the list of rules.\n"
281 "\t By default, rules are appended to the end of the rule list.\n"},
282 {"del", jt_del_udsp, 0, "delete a udsp\n"
283 "\t--all: Delete all rules.\n"
284 "\t--idx n: Delete the rule at index n.\n"},
285 {"show", jt_show_udsp, 0, "show udsps\n"
286 "\t--idx n: Show the rule at at index n.\n"
287 "\t By default, all rules are shown.\n"},
291 static int parse_long(const char *number, long int *value)
298 *value = strtol(number, &end, 0);
299 if (end != NULL && *end != 0)
305 static int jt_setup_mrrouting(int argc, char **argv)
308 struct cYAML *err_rc = NULL;
310 rc = lustre_lnet_setup_mrrouting(&err_rc);
312 if (rc != LUSTRE_CFG_RC_NO_ERR)
313 cYAML_print_tree2file(stderr, err_rc);
315 cYAML_free_tree(err_rc);
320 static inline void print_help(const command_t cmds[], const char *cmd_type,
323 const command_t *cmd;
325 for (cmd = cmds; cmd->pc_name; cmd++) {
326 if (pc_name != NULL &&
327 strcmp(cmd->pc_name, pc_name) == 0) {
328 printf("%s %s: %s\n", cmd_type, cmd->pc_name,
331 } else if (pc_name != NULL) {
334 printf("%s %s: %s\n", cmd_type, cmd->pc_name, cmd->pc_help);
338 static int check_cmd(const command_t *cmd_list, const char *cmd,
339 const char *sub_cmd, const int min_args,
340 int argc, char **argv)
347 const char *const short_options = "h";
348 static const struct option long_options[] = {
349 { .name = "help", .has_arg = no_argument, .val = 'h' },
353 if (argc < min_args) {
354 print_help(cmd_list, cmd, sub_cmd);
355 rc = LUSTRE_CFG_RC_BAD_PARAM;
357 } else if (argc > 2) {
361 while ((opt = getopt_long(argc, argv, short_options,
362 long_options, NULL)) != -1) {
365 print_help(cmd_list, cmd, sub_cmd);
380 static int jt_set_response_tracking(int argc, char **argv)
384 struct cYAML *err_rc = NULL;
386 rc = check_cmd(set_cmds, "set", "response_tracking", 2, argc, argv);
390 rc = parse_long(argv[1], &value);
392 cYAML_build_error(-1, -1, "parser", "set",
393 "cannot parse response_tracking value",
395 cYAML_print_tree2file(stderr, err_rc);
396 cYAML_free_tree(err_rc);
400 rc = lustre_lnet_config_response_tracking(value, -1, &err_rc);
401 if (rc != LUSTRE_CFG_RC_NO_ERR)
402 cYAML_print_tree2file(stderr, err_rc);
404 cYAML_free_tree(err_rc);
409 static int jt_calc_service_id(int argc, char **argv)
414 rc = lustre_lnet_calc_service_id(&service_id);
415 if (rc != LUSTRE_CFG_RC_NO_ERR)
418 /* cYAML currently doesn't support printing hex values.
419 * Therefore just print it locally here
421 printf("service_id:\n value: 0x%llx\n",
422 (unsigned long long)(service_id));
427 static int jt_set_recovery_limit(int argc, char **argv)
431 struct cYAML *err_rc = NULL;
433 rc = check_cmd(set_cmds, "set", "recovery_limit", 2, argc, argv);
437 rc = parse_long(argv[1], &value);
439 cYAML_build_error(-1, -1, "parser", "set",
440 "cannot parse recovery_limit value",
442 cYAML_print_tree2file(stderr, err_rc);
443 cYAML_free_tree(err_rc);
447 rc = lustre_lnet_config_recovery_limit(value, -1, &err_rc);
448 if (rc != LUSTRE_CFG_RC_NO_ERR)
449 cYAML_print_tree2file(stderr, err_rc);
451 cYAML_free_tree(err_rc);
456 static int jt_set_max_intf(int argc, char **argv)
460 struct cYAML *err_rc = NULL;
462 rc = check_cmd(set_cmds, "set", "max_interfaces", 2, argc, argv);
466 rc = parse_long(argv[1], &value);
468 cYAML_build_error(-1, -1, "parser", "set",
469 "cannot parse max_interfaces value", &err_rc);
470 cYAML_print_tree2file(stderr, err_rc);
471 cYAML_free_tree(err_rc);
475 rc = lustre_lnet_config_max_intf(value, -1, &err_rc);
476 if (rc != LUSTRE_CFG_RC_NO_ERR)
477 cYAML_print_tree2file(stderr, err_rc);
479 cYAML_free_tree(err_rc);
484 static int jt_set_numa(int argc, char **argv)
488 struct cYAML *err_rc = NULL;
490 rc = check_cmd(set_cmds, "set", "numa_range", 2, argc, argv);
494 rc = parse_long(argv[1], &value);
496 cYAML_build_error(-1, -1, "parser", "set",
497 "cannot parse numa_range value", &err_rc);
498 cYAML_print_tree2file(stderr, err_rc);
499 cYAML_free_tree(err_rc);
503 rc = lustre_lnet_config_numa_range(value, -1, &err_rc);
504 if (rc != LUSTRE_CFG_RC_NO_ERR)
505 cYAML_print_tree2file(stderr, err_rc);
507 cYAML_free_tree(err_rc);
512 static int jt_set_recov_intrv(int argc, char **argv)
516 struct cYAML *err_rc = NULL;
518 rc = check_cmd(set_cmds, "set", "recovery_interval", 2, argc, argv);
522 rc = parse_long(argv[1], &value);
524 cYAML_build_error(-1, -1, "parser", "set",
525 "cannot parse recovery interval value", &err_rc);
526 cYAML_print_tree2file(stderr, err_rc);
527 cYAML_free_tree(err_rc);
531 rc = lustre_lnet_config_recov_intrv(value, -1, &err_rc);
532 if (rc != LUSTRE_CFG_RC_NO_ERR)
533 cYAML_print_tree2file(stderr, err_rc);
535 cYAML_free_tree(err_rc);
540 static int jt_set_rtr_sensitivity(int argc, char **argv)
544 struct cYAML *err_rc = NULL;
546 rc = check_cmd(set_cmds, "set", "router_sensitivity", 2, argc, argv);
550 rc = parse_long(argv[1], &value);
552 cYAML_build_error(-1, -1, "parser", "set",
553 "cannot parse router sensitivity value", &err_rc);
554 cYAML_print_tree2file(stderr, err_rc);
555 cYAML_free_tree(err_rc);
559 rc = lustre_lnet_config_rtr_sensitivity(value, -1, &err_rc);
560 if (rc != LUSTRE_CFG_RC_NO_ERR)
561 cYAML_print_tree2file(stderr, err_rc);
563 cYAML_free_tree(err_rc);
568 static int jt_set_hsensitivity(int argc, char **argv)
572 struct cYAML *err_rc = NULL;
574 rc = check_cmd(set_cmds, "set", "health_sensitivity", 2, argc, argv);
578 rc = parse_long(argv[1], &value);
580 cYAML_build_error(-1, -1, "parser", "set",
581 "cannot parse health sensitivity value", &err_rc);
582 cYAML_print_tree2file(stderr, err_rc);
583 cYAML_free_tree(err_rc);
587 rc = lustre_lnet_config_hsensitivity(value, -1, &err_rc);
588 if (rc != LUSTRE_CFG_RC_NO_ERR)
589 cYAML_print_tree2file(stderr, err_rc);
591 cYAML_free_tree(err_rc);
596 static int jt_reset_stats(int argc, char **argv)
599 struct cYAML *err_rc = NULL;
601 rc = check_cmd(stats_cmds, "stats", "reset", 0, argc, argv);
605 rc = lustre_lnet_reset_stats(-1, &err_rc);
606 if (rc != LUSTRE_CFG_RC_NO_ERR)
607 cYAML_print_tree2file(stderr, err_rc);
609 cYAML_free_tree(err_rc);
614 static int jt_set_transaction_to(int argc, char **argv)
618 struct cYAML *err_rc = NULL;
620 rc = check_cmd(set_cmds, "set", "transaction_timeout", 2, argc, argv);
624 rc = parse_long(argv[1], &value);
626 cYAML_build_error(-1, -1, "parser", "set",
627 "cannot parse transaction timeout value", &err_rc);
628 cYAML_print_tree2file(stderr, err_rc);
629 cYAML_free_tree(err_rc);
633 rc = lustre_lnet_config_transaction_to(value, -1, &err_rc);
634 if (rc != LUSTRE_CFG_RC_NO_ERR)
635 cYAML_print_tree2file(stderr, err_rc);
637 cYAML_free_tree(err_rc);
642 static int jt_set_retry_count(int argc, char **argv)
646 struct cYAML *err_rc = NULL;
648 rc = check_cmd(set_cmds, "set", "retry_count", 2, argc, argv);
652 rc = parse_long(argv[1], &value);
654 cYAML_build_error(-1, -1, "parser", "set",
655 "cannot parse retry_count value", &err_rc);
656 cYAML_print_tree2file(stderr, err_rc);
657 cYAML_free_tree(err_rc);
661 rc = lustre_lnet_config_retry_count(value, -1, &err_rc);
662 if (rc != LUSTRE_CFG_RC_NO_ERR)
663 cYAML_print_tree2file(stderr, err_rc);
665 cYAML_free_tree(err_rc);
670 static int jt_set_discovery(int argc, char **argv)
674 struct cYAML *err_rc = NULL;
676 rc = check_cmd(set_cmds, "set", "discovery", 2, argc, argv);
680 rc = parse_long(argv[1], &value);
682 cYAML_build_error(-1, -1, "parser", "set",
683 "cannot parse discovery value", &err_rc);
684 cYAML_print_tree2file(stderr, err_rc);
685 cYAML_free_tree(err_rc);
689 rc = lustre_lnet_config_discovery(value, -1, &err_rc);
690 if (rc != LUSTRE_CFG_RC_NO_ERR)
691 cYAML_print_tree2file(stderr, err_rc);
693 cYAML_free_tree(err_rc);
698 static int jt_set_drop_asym_route(int argc, char **argv)
702 struct cYAML *err_rc = NULL;
704 rc = check_cmd(set_cmds, "set", "drop_asym_route", 2, argc, argv);
708 rc = parse_long(argv[1], &value);
710 cYAML_build_error(-1, -1, "parser", "set",
711 "cannot parse drop_asym_route value",
713 cYAML_print_tree2file(stderr, err_rc);
714 cYAML_free_tree(err_rc);
718 rc = lustre_lnet_config_drop_asym_route(value, -1, &err_rc);
719 if (rc != LUSTRE_CFG_RC_NO_ERR)
720 cYAML_print_tree2file(stderr, err_rc);
722 cYAML_free_tree(err_rc);
727 static int jt_set_tiny(int argc, char **argv)
731 struct cYAML *err_rc = NULL;
733 rc = check_cmd(set_cmds, "set", "tiny_buffers", 2, argc, argv);
737 rc = parse_long(argv[1], &value);
739 cYAML_build_error(-1, -1, "parser", "set",
740 "cannot parse tiny_buffers value", &err_rc);
741 cYAML_print_tree2file(stderr, err_rc);
742 cYAML_free_tree(err_rc);
746 rc = lustre_lnet_config_buffers(value, -1, -1, -1, &err_rc);
747 if (rc != LUSTRE_CFG_RC_NO_ERR)
748 cYAML_print_tree2file(stderr, err_rc);
750 cYAML_free_tree(err_rc);
755 static int jt_set_small(int argc, char **argv)
759 struct cYAML *err_rc = NULL;
761 rc = check_cmd(set_cmds, "set", "small_buffers", 2, argc, argv);
765 rc = parse_long(argv[1], &value);
767 cYAML_build_error(-1, -1, "parser", "set",
768 "cannot parse small_buffers value", &err_rc);
769 cYAML_print_tree2file(stderr, err_rc);
770 cYAML_free_tree(err_rc);
774 rc = lustre_lnet_config_buffers(-1, value, -1, -1, &err_rc);
775 if (rc != LUSTRE_CFG_RC_NO_ERR)
776 cYAML_print_tree2file(stderr, err_rc);
778 cYAML_free_tree(err_rc);
783 static int jt_set_large(int argc, char **argv)
787 struct cYAML *err_rc = NULL;
789 rc = check_cmd(set_cmds, "set", "large_buffers", 2, argc, argv);
793 rc = parse_long(argv[1], &value);
795 cYAML_build_error(-1, -1, "parser", "set",
796 "cannot parse large_buffers value", &err_rc);
797 cYAML_print_tree2file(stderr, err_rc);
798 cYAML_free_tree(err_rc);
802 rc = lustre_lnet_config_buffers(-1, -1, value, -1, &err_rc);
803 if (rc != LUSTRE_CFG_RC_NO_ERR)
804 cYAML_print_tree2file(stderr, err_rc);
806 cYAML_free_tree(err_rc);
811 static int jt_set_routing(int argc, char **argv)
814 struct cYAML *err_rc = NULL;
817 rc = check_cmd(set_cmds, "set", "routing", 2, argc, argv);
821 rc = parse_long(argv[1], &value);
822 if (rc != 0 || (value != 0 && value != 1)) {
823 cYAML_build_error(-1, -1, "parser", "set",
824 "cannot parse routing value.\n"
825 "must be 0 for disable or 1 for enable",
827 cYAML_print_tree2file(stderr, err_rc);
828 cYAML_free_tree(err_rc);
832 rc = lustre_lnet_enable_routing(value, -1, &err_rc);
834 if (rc != LUSTRE_CFG_RC_NO_ERR)
835 cYAML_print_tree2file(stderr, err_rc);
837 cYAML_free_tree(err_rc);
842 static int jt_set_max_recovery_ping_interval(int argc, char **argv)
846 struct cYAML *err_rc = NULL;
848 rc = check_cmd(set_cmds, "set", "maximum recovery_interval", 2, argc, argv);
852 rc = parse_long(argv[1], &value);
854 cYAML_build_error(-1, -1, "parser", "set",
855 "cannot parse maximum recovery interval value",
857 cYAML_print_tree2file(stderr, err_rc);
858 cYAML_free_tree(err_rc);
862 rc = lustre_lnet_config_max_recovery_ping_interval(value, -1, &err_rc);
863 if (rc != LUSTRE_CFG_RC_NO_ERR)
864 cYAML_print_tree2file(stderr, err_rc);
866 cYAML_free_tree(err_rc);
871 static void yaml_lnet_print_error(int op, char *cmd, const char *errstr)
873 char errcode[INT_STRING_LEN];
879 snprintf(errcode, sizeof(errcode), "%d", errno);
881 yaml_emitter_initialize(&log);
882 yaml_emitter_set_indent(&log, LNET_DEFAULT_INDENT);
883 yaml_emitter_set_output_file(&log, stderr);
885 yaml_emitter_open(&log);
886 yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
887 rc = yaml_emitter_emit(&log, &event);
891 yaml_mapping_start_event_initialize(&event, NULL,
892 (yaml_char_t *)YAML_MAP_TAG,
893 1, YAML_ANY_MAPPING_STYLE);
894 rc = yaml_emitter_emit(&log, &event);
917 yaml_scalar_event_initialize(&event, NULL,
918 (yaml_char_t *)YAML_STR_TAG,
921 YAML_PLAIN_SCALAR_STYLE);
922 rc = yaml_emitter_emit(&log, &event);
926 yaml_sequence_start_event_initialize(&event, NULL,
927 (yaml_char_t *)YAML_SEQ_TAG,
928 1, YAML_ANY_SEQUENCE_STYLE);
929 rc = yaml_emitter_emit(&log, &event);
933 yaml_mapping_start_event_initialize(&event, NULL,
934 (yaml_char_t *)YAML_MAP_TAG,
935 1, YAML_ANY_MAPPING_STYLE);
936 rc = yaml_emitter_emit(&log, &event);
940 yaml_scalar_event_initialize(&event, NULL,
941 (yaml_char_t *)YAML_STR_TAG,
944 1, 0, YAML_PLAIN_SCALAR_STYLE);
945 rc = yaml_emitter_emit(&log, &event);
949 yaml_scalar_event_initialize(&event, NULL,
950 (yaml_char_t *)YAML_STR_TAG,
953 1, 0, YAML_PLAIN_SCALAR_STYLE);
954 rc = yaml_emitter_emit(&log, &event);
958 yaml_scalar_event_initialize(&event, NULL,
959 (yaml_char_t *)YAML_STR_TAG,
960 (yaml_char_t *)"errno",
961 strlen("errno"), 1, 0,
962 YAML_PLAIN_SCALAR_STYLE);
963 rc = yaml_emitter_emit(&log, &event);
967 yaml_scalar_event_initialize(&event, NULL,
968 (yaml_char_t *)YAML_INT_TAG,
969 (yaml_char_t *)errcode,
970 strlen(errcode), 1, 0,
971 YAML_PLAIN_SCALAR_STYLE);
972 rc = yaml_emitter_emit(&log, &event);
977 yaml_scalar_event_initialize(&event, NULL,
978 (yaml_char_t *)YAML_STR_TAG,
979 (yaml_char_t *)"descr",
980 strlen("descr"), 1, 0,
981 YAML_PLAIN_SCALAR_STYLE);
982 rc = yaml_emitter_emit(&log, &event);
986 yaml_scalar_event_initialize(&event, NULL,
987 (yaml_char_t *)YAML_STR_TAG,
988 (yaml_char_t *)errstr,
989 strlen(errstr), 1, 0,
990 YAML_DOUBLE_QUOTED_SCALAR_STYLE);
991 rc = yaml_emitter_emit(&log, &event);
995 yaml_mapping_end_event_initialize(&event);
996 rc = yaml_emitter_emit(&log, &event);
1000 yaml_sequence_end_event_initialize(&event);
1001 rc = yaml_emitter_emit(&log, &event);
1005 yaml_mapping_end_event_initialize(&event);
1006 rc = yaml_emitter_emit(&log, &event);
1010 yaml_document_end_event_initialize(&event, 0);
1011 rc = yaml_emitter_emit(&log, &event);
1015 rc = yaml_emitter_close(&log);
1018 yaml_emitter_log_error(&log, stdout);
1019 yaml_emitter_delete(&log);
1022 static int yaml_lnet_cpt_of_nid_display(yaml_parser_t *reply)
1024 yaml_document_t results;
1025 yaml_emitter_t output;
1028 rc = yaml_parser_load(reply, &results);
1030 yaml_lnet_print_error(NLM_F_DUMP, "cpt-of-nid",
1031 yaml_parser_get_reader_error(reply));
1032 yaml_document_delete(&results);
1036 rc = yaml_emitter_initialize(&output);
1038 yaml_emitter_set_output_file(&output, stdout);
1040 rc = yaml_emitter_dump(&output, &results);
1043 yaml_document_delete(&results);
1045 yaml_emitter_log_error(&output, stderr);
1048 yaml_emitter_delete(&output);
1053 static int yaml_lnet_cpt_of_nid(int start, int end, char **nids)
1055 struct nl_sock *sk = NULL;
1056 yaml_emitter_t request;
1057 yaml_parser_t reply;
1061 /* Create Netlink emitter to send request to kernel */
1062 sk = nl_socket_alloc();
1066 /* Setup parser to receive Netlink packets */
1067 rc = yaml_parser_initialize(&reply);
1073 rc = yaml_parser_set_input_netlink(&reply, sk, false);
1077 /* Create Netlink emitter to send request to kernel */
1078 rc = yaml_emitter_initialize(&request);
1082 rc = yaml_emitter_set_output_netlink(&request, sk, LNET_GENL_NAME,
1084 LNET_CMD_CPT_OF_NID, NLM_F_DUMP);
1088 yaml_emitter_open(&request);
1089 yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
1090 rc = yaml_emitter_emit(&request, &event);
1094 yaml_mapping_start_event_initialize(&event, NULL,
1095 (yaml_char_t *)YAML_MAP_TAG,
1096 1, YAML_ANY_MAPPING_STYLE);
1097 rc = yaml_emitter_emit(&request, &event);
1101 yaml_scalar_event_initialize(&event, NULL,
1102 (yaml_char_t *)YAML_STR_TAG,
1103 (yaml_char_t *)"cpt-of-nid",
1104 strlen("cpt-of-nid"), 1, 0,
1105 YAML_PLAIN_SCALAR_STYLE);
1106 rc = yaml_emitter_emit(&request, &event);
1110 yaml_mapping_start_event_initialize(&event, NULL,
1111 (yaml_char_t *)YAML_MAP_TAG,
1112 1, YAML_ANY_MAPPING_STYLE);
1113 rc = yaml_emitter_emit(&request, &event);
1117 yaml_scalar_event_initialize(&event, NULL,
1118 (yaml_char_t *)YAML_STR_TAG,
1119 (yaml_char_t *)"nids",
1120 strlen("nids"), 1, 0,
1121 YAML_PLAIN_SCALAR_STYLE);
1122 rc = yaml_emitter_emit(&request, &event);
1126 yaml_sequence_start_event_initialize(&event, NULL,
1127 (yaml_char_t *)YAML_SEQ_TAG,
1128 1, YAML_FLOW_SEQUENCE_STYLE);
1129 rc = yaml_emitter_emit(&request, &event);
1133 for (i = start; i < end; i++) {
1134 yaml_scalar_event_initialize(&event, NULL,
1135 (yaml_char_t *)YAML_STR_TAG,
1136 (yaml_char_t *)nids[i],
1137 strlen(nids[i]), 1, 0,
1138 YAML_PLAIN_SCALAR_STYLE);
1139 rc = yaml_emitter_emit(&request, &event);
1144 yaml_sequence_end_event_initialize(&event);
1145 rc = yaml_emitter_emit(&request, &event);
1149 yaml_mapping_end_event_initialize(&event);
1150 rc = yaml_emitter_emit(&request, &event);
1154 yaml_mapping_end_event_initialize(&event);
1155 rc = yaml_emitter_emit(&request, &event);
1159 yaml_document_end_event_initialize(&event, 0);
1160 rc = yaml_emitter_emit(&request, &event);
1164 rc = yaml_emitter_close(&request);
1167 yaml_emitter_log_error(&request, stderr);
1170 rc = yaml_lnet_cpt_of_nid_display(&reply);
1172 yaml_emitter_delete(&request);
1175 yaml_lnet_print_error(NLM_F_DUMP, "cpt-of-nid",
1176 yaml_parser_get_reader_error(&reply));
1180 yaml_parser_delete(&reply);
1183 return rc == 1 ? 0 : rc;
1186 static int jt_calc_cpt_of_nid(int argc, char **argv)
1189 const char *const short_options = "h";
1190 static const struct option long_options[] = {
1191 { .name = "help", .val = 'h' },
1194 rc = check_cmd(cmd_list, "", "cpt-of-nid", 2, argc, argv);
1198 while ((opt = getopt_long(argc, argv, short_options,
1199 long_options, NULL)) != -1) {
1203 print_help(cmd_list, "", "cpt-of-nid");
1209 rc = yaml_lnet_cpt_of_nid(optind, argc, argv);
1210 if (rc == -EOPNOTSUPP)
1211 printf("Operation not supported\n");
1216 static int jt_config_lnet(int argc, char **argv)
1218 struct cYAML *err_rc = NULL;
1219 bool load_mod_params = false;
1222 const char *const short_options = "a";
1223 static const struct option long_options[] = {
1224 { .name = "all", .has_arg = no_argument, .val = 'a' },
1228 rc = check_cmd(lnet_cmds, "lnet", "configure", 0, argc, argv);
1232 while ((opt = getopt_long(argc, argv, short_options,
1233 long_options, NULL)) != -1) {
1236 load_mod_params = true;
1243 rc = lustre_lnet_config_ni_system(LNET_CONFIGURE, load_mod_params,
1246 if (rc != LUSTRE_CFG_RC_NO_ERR)
1247 cYAML_print_tree2file(stderr, err_rc);
1249 cYAML_free_tree(err_rc);
1254 static int jt_unconfig_lnet(int argc, char **argv)
1256 struct cYAML *err_rc = NULL;
1259 rc = check_cmd(lnet_cmds, "lnet", "unconfigure", 0, argc, argv);
1263 rc = lustre_lnet_config_ni_system(LNET_UNCONFIGURE, 0, -1, &err_rc);
1265 if (rc != LUSTRE_CFG_RC_NO_ERR)
1266 cYAML_print_tree2file(stderr, err_rc);
1268 cYAML_free_tree(err_rc);
1273 static int yaml_lnet_router_gateways(yaml_emitter_t *output, const char *nw,
1274 const char *gw, int hops, int prio,
1277 char num[INT_STRING_LEN];
1281 yaml_mapping_start_event_initialize(&event, NULL,
1282 (yaml_char_t *)YAML_MAP_TAG, 1,
1283 YAML_BLOCK_MAPPING_STYLE);
1284 rc = yaml_emitter_emit(output, &event);
1289 yaml_scalar_event_initialize(&event, NULL,
1290 (yaml_char_t *)YAML_STR_TAG,
1291 (yaml_char_t *)"net",
1292 strlen("net"), 1, 0,
1293 YAML_PLAIN_SCALAR_STYLE);
1294 rc = yaml_emitter_emit(output, &event);
1298 yaml_scalar_event_initialize(&event, NULL,
1299 (yaml_char_t *)YAML_STR_TAG,
1302 YAML_PLAIN_SCALAR_STYLE);
1303 rc = yaml_emitter_emit(output, &event);
1309 yaml_scalar_event_initialize(&event, NULL,
1310 (yaml_char_t *)YAML_STR_TAG,
1311 (yaml_char_t *)"gateway",
1312 strlen("gateway"), 1, 0,
1313 YAML_PLAIN_SCALAR_STYLE);
1314 rc = yaml_emitter_emit(output, &event);
1318 yaml_scalar_event_initialize(&event, NULL,
1319 (yaml_char_t *)YAML_STR_TAG,
1322 YAML_PLAIN_SCALAR_STYLE);
1323 rc = yaml_emitter_emit(output, &event);
1329 yaml_scalar_event_initialize(&event, NULL,
1330 (yaml_char_t *)YAML_STR_TAG,
1331 (yaml_char_t *)"hop",
1332 strlen("hop"), 1, 0,
1333 YAML_PLAIN_SCALAR_STYLE);
1334 rc = yaml_emitter_emit(output, &event);
1338 snprintf(num, sizeof(num), "%d", hops);
1339 yaml_scalar_event_initialize(&event, NULL,
1340 (yaml_char_t *)YAML_INT_TAG,
1343 YAML_PLAIN_SCALAR_STYLE);
1344 rc = yaml_emitter_emit(output, &event);
1350 yaml_scalar_event_initialize(&event, NULL,
1351 (yaml_char_t *)YAML_STR_TAG,
1352 (yaml_char_t *)"priority",
1353 strlen("priority"), 1, 0,
1354 YAML_PLAIN_SCALAR_STYLE);
1355 rc = yaml_emitter_emit(output, &event);
1359 snprintf(num, sizeof(num), "%d", prio);
1360 yaml_scalar_event_initialize(&event, NULL,
1361 (yaml_char_t *)YAML_INT_TAG,
1364 YAML_PLAIN_SCALAR_STYLE);
1365 rc = yaml_emitter_emit(output, &event);
1371 yaml_scalar_event_initialize(&event, NULL,
1372 (yaml_char_t *)YAML_STR_TAG,
1373 (yaml_char_t *)"health_sensitivity",
1374 strlen("health_sensitivity"),
1376 YAML_PLAIN_SCALAR_STYLE);
1377 rc = yaml_emitter_emit(output, &event);
1381 snprintf(num, sizeof(num), "%d", sen);
1382 yaml_scalar_event_initialize(&event, NULL,
1383 (yaml_char_t *)YAML_INT_TAG,
1386 YAML_PLAIN_SCALAR_STYLE);
1387 rc = yaml_emitter_emit(output, &event);
1392 yaml_mapping_end_event_initialize(&event);
1393 rc = yaml_emitter_emit(output, &event);
1398 static int yaml_lnet_route(char *nw, char *gw, int hops, int prio, int sen,
1399 int version, int flags)
1401 struct nid_node head, *entry;
1402 struct nl_sock *sk = NULL;
1403 const char *msg = NULL;
1404 yaml_emitter_t output;
1405 yaml_parser_t reply;
1409 if (!(flags & NLM_F_DUMP) && (!nw || !gw)) {
1410 fprintf(stdout, "missing mandatory parameters:'%s'\n",
1411 (!nw && !gw) ? "net , gateway" :
1412 !nw ? "net" : "gateway");
1416 /* Create Netlink emitter to send request to kernel */
1417 sk = nl_socket_alloc();
1421 /* Setup parser to receive Netlink packets */
1422 rc = yaml_parser_initialize(&reply);
1428 rc = yaml_parser_set_input_netlink(&reply, sk, false);
1430 msg = yaml_parser_get_reader_error(&reply);
1434 /* Create Netlink emitter to send request to kernel */
1435 rc = yaml_emitter_initialize(&output);
1437 msg = "failed to initialize emitter";
1441 rc = yaml_emitter_set_output_netlink(&output, sk, LNET_GENL_NAME,
1442 version, LNET_CMD_ROUTES, flags);
1446 yaml_emitter_open(&output);
1447 yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
1448 rc = yaml_emitter_emit(&output, &event);
1452 yaml_mapping_start_event_initialize(&event, NULL,
1453 (yaml_char_t *)YAML_MAP_TAG,
1454 1, YAML_ANY_MAPPING_STYLE);
1455 rc = yaml_emitter_emit(&output, &event);
1459 yaml_scalar_event_initialize(&event, NULL,
1460 (yaml_char_t *)YAML_STR_TAG,
1461 (yaml_char_t *)"route",
1462 strlen("route"), 1, 0,
1463 YAML_PLAIN_SCALAR_STYLE);
1464 rc = yaml_emitter_emit(&output, &event);
1468 /* NLM_F_DUMP can have no arguments */
1470 NL_INIT_LIST_HEAD(&head.children);
1471 nl_init_list_head(&head.list);
1473 rc = lustre_lnet_parse_nid_range(&head, gw, &msg);
1475 lustre_lnet_free_list(&head);
1476 yaml_emitter_delete(&output);
1483 yaml_sequence_start_event_initialize(&event, NULL,
1484 (yaml_char_t *)YAML_SEQ_TAG,
1486 YAML_BLOCK_SEQUENCE_STYLE);
1487 rc = yaml_emitter_emit(&output, &event);
1491 if (!nl_list_empty(&head.children)) {
1492 nl_list_for_each_entry(entry, &head.children, list) {
1493 const char *nid = entry->nidstr;
1495 rc = yaml_lnet_router_gateways(&output, nw, nid,
1501 rc = yaml_lnet_router_gateways(&output, nw, NULL, hops,
1507 yaml_sequence_end_event_initialize(&event);
1508 rc = yaml_emitter_emit(&output, &event);
1512 yaml_scalar_event_initialize(&event, NULL,
1513 (yaml_char_t *)YAML_STR_TAG,
1516 YAML_PLAIN_SCALAR_STYLE);
1517 rc = yaml_emitter_emit(&output, &event);
1522 yaml_mapping_end_event_initialize(&event);
1523 rc = yaml_emitter_emit(&output, &event);
1527 yaml_document_end_event_initialize(&event, 0);
1528 rc = yaml_emitter_emit(&output, &event);
1532 rc = yaml_emitter_close(&output);
1535 yaml_emitter_log_error(&output, stderr);
1538 yaml_document_t errmsg;
1540 rc = yaml_parser_load(&reply, &errmsg);
1541 if (rc == 1 && (flags & NLM_F_DUMP)) {
1542 yaml_emitter_t debug;
1544 rc = yaml_emitter_initialize(&debug);
1546 yaml_emitter_set_indent(&debug,
1547 LNET_DEFAULT_INDENT);
1548 yaml_emitter_set_output_file(&debug,
1550 rc = yaml_emitter_dump(&debug, &errmsg);
1552 yaml_emitter_delete(&debug);
1554 msg = yaml_parser_get_reader_error(&reply);
1555 /* If we didn't find any routes just be silent */
1556 if (msg && strcmp(msg, "No routes found") == 0)
1559 yaml_document_delete(&errmsg);
1561 yaml_emitter_delete(&output);
1564 yaml_lnet_print_error(flags, "route", msg);
1567 yaml_parser_delete(&reply);
1570 return rc == 1 ? 0 : rc;
1573 static int jt_add_route(int argc, char **argv)
1575 char *network = NULL, *gateway = NULL;
1576 long int hop = -1, prio = -1, sen = -1;
1577 struct cYAML *err_rc = NULL;
1580 const char *const short_options = "n:g:c:p:";
1581 static const struct option long_options[] = {
1582 { .name = "net", .has_arg = required_argument, .val = 'n' },
1583 { .name = "gateway", .has_arg = required_argument, .val = 'g' },
1584 { .name = "hop", .has_arg = required_argument, .val = 'c' },
1585 { .name = "hop-count", .has_arg = required_argument, .val = 'c' },
1586 { .name = "priority", .has_arg = required_argument, .val = 'p' },
1587 { .name = "health_sensitivity", .has_arg = required_argument, .val = 's' },
1591 rc = check_cmd(route_cmds, "route", "add", 0, argc, argv);
1595 while ((opt = getopt_long(argc, argv, short_options,
1596 long_options, NULL)) != -1) {
1605 rc = parse_long(optarg, &hop);
1613 rc = parse_long(optarg, &prio);
1621 rc = parse_long(optarg, &sen);
1630 print_help(route_cmds, "route", "add");
1636 rc = yaml_lnet_route(network, gateway, hop, prio, sen,
1637 LNET_GENL_VERSION, NLM_F_CREATE);
1639 if (rc == -EOPNOTSUPP)
1644 rc = lustre_lnet_config_route(network, gateway, hop, prio, sen, -1,
1647 if (rc != LUSTRE_CFG_RC_NO_ERR)
1648 cYAML_print_tree2file(stderr, err_rc);
1650 cYAML_free_tree(err_rc);
1655 static int yaml_add_ni_tunables(yaml_emitter_t *output,
1656 struct lnet_ioctl_config_lnd_tunables *tunables,
1657 struct lnet_dlc_network_descr *nw_descr)
1659 char num[INT_STRING_LEN];
1663 if (tunables->lt_cmn.lct_peer_timeout < 0 &&
1664 tunables->lt_cmn.lct_peer_tx_credits <= 0 &&
1665 tunables->lt_cmn.lct_peer_rtr_credits <= 0 &&
1666 tunables->lt_cmn.lct_max_tx_credits <= 0)
1667 goto skip_general_settings;
1669 yaml_scalar_event_initialize(&event, NULL,
1670 (yaml_char_t *)YAML_STR_TAG,
1671 (yaml_char_t *)"tunables",
1672 strlen("tunables"), 1, 0,
1673 YAML_PLAIN_SCALAR_STYLE);
1674 rc = yaml_emitter_emit(output, &event);
1678 yaml_mapping_start_event_initialize(&event, NULL,
1679 (yaml_char_t *)YAML_MAP_TAG,
1680 1, YAML_ANY_MAPPING_STYLE);
1681 rc = yaml_emitter_emit(output, &event);
1685 if (tunables->lt_cmn.lct_peer_timeout >= 0) {
1686 yaml_scalar_event_initialize(&event, NULL,
1687 (yaml_char_t *)YAML_STR_TAG,
1688 (yaml_char_t *)"peer_timeout",
1689 strlen("peer_timeout"), 1, 0,
1690 YAML_PLAIN_SCALAR_STYLE);
1691 rc = yaml_emitter_emit(output, &event);
1695 snprintf(num, sizeof(num), "%u",
1696 tunables->lt_cmn.lct_peer_timeout);
1697 yaml_scalar_event_initialize(&event, NULL,
1698 (yaml_char_t *)YAML_INT_TAG,
1701 YAML_PLAIN_SCALAR_STYLE);
1702 rc = yaml_emitter_emit(output, &event);
1707 if (tunables->lt_cmn.lct_peer_tx_credits > 0) {
1708 yaml_scalar_event_initialize(&event, NULL,
1709 (yaml_char_t *)YAML_STR_TAG,
1710 (yaml_char_t *)"peer_credits",
1711 strlen("peer_credits"), 1, 0,
1712 YAML_PLAIN_SCALAR_STYLE);
1713 rc = yaml_emitter_emit(output, &event);
1717 snprintf(num, sizeof(num), "%u",
1718 tunables->lt_cmn.lct_peer_tx_credits);
1719 yaml_scalar_event_initialize(&event, NULL,
1720 (yaml_char_t *)YAML_INT_TAG,
1723 YAML_PLAIN_SCALAR_STYLE);
1724 rc = yaml_emitter_emit(output, &event);
1729 if (tunables->lt_cmn.lct_peer_rtr_credits > 0) {
1730 yaml_scalar_event_initialize(&event, NULL,
1731 (yaml_char_t *)YAML_STR_TAG,
1732 (yaml_char_t *)"peer_buffer_credits",
1733 strlen("peer_buffer_credits"), 1, 0,
1734 YAML_PLAIN_SCALAR_STYLE);
1735 rc = yaml_emitter_emit(output, &event);
1739 snprintf(num, sizeof(num), "%u",
1740 tunables->lt_cmn.lct_peer_rtr_credits);
1741 yaml_scalar_event_initialize(&event, NULL,
1742 (yaml_char_t *)YAML_INT_TAG,
1745 YAML_PLAIN_SCALAR_STYLE);
1746 rc = yaml_emitter_emit(output, &event);
1751 if (tunables->lt_cmn.lct_max_tx_credits > 0) {
1752 yaml_scalar_event_initialize(&event, NULL,
1753 (yaml_char_t *)YAML_STR_TAG,
1754 (yaml_char_t *)"credits",
1755 strlen("credits"), 1, 0,
1756 YAML_PLAIN_SCALAR_STYLE);
1757 rc = yaml_emitter_emit(output, &event);
1761 snprintf(num, sizeof(num), "%u",
1762 tunables->lt_cmn.lct_max_tx_credits);
1763 yaml_scalar_event_initialize(&event, NULL,
1764 (yaml_char_t *)YAML_INT_TAG,
1767 YAML_PLAIN_SCALAR_STYLE);
1768 rc = yaml_emitter_emit(output, &event);
1773 yaml_mapping_end_event_initialize(&event);
1774 rc = yaml_emitter_emit(output, &event);
1778 skip_general_settings:
1779 if (tunables->lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer > 0 ||
1781 tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_auth_key > 0 ||
1782 tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_traffic_class_str[0] ||
1784 tunables->lt_tun.lnd_tun_u.lnd_o2ib.lnd_conns_per_peer > 0) {
1785 yaml_scalar_event_initialize(&event, NULL,
1786 (yaml_char_t *)YAML_STR_TAG,
1787 (yaml_char_t *)"lnd tunables",
1788 strlen("lnd tunables"), 1, 0,
1789 YAML_PLAIN_SCALAR_STYLE);
1790 rc = yaml_emitter_emit(output, &event);
1794 yaml_mapping_start_event_initialize(&event, NULL,
1795 (yaml_char_t *)YAML_MAP_TAG,
1796 1, YAML_ANY_MAPPING_STYLE);
1797 rc = yaml_emitter_emit(output, &event);
1801 if (tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_auth_key > 0) {
1802 yaml_scalar_event_initialize(&event, NULL,
1803 (yaml_char_t *)YAML_STR_TAG,
1804 (yaml_char_t *)"auth_key",
1805 strlen("auth_key"), 1, 0,
1806 YAML_PLAIN_SCALAR_STYLE);
1807 rc = yaml_emitter_emit(output, &event);
1811 snprintf(num, sizeof(num), "%u",
1812 tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_auth_key);
1814 yaml_scalar_event_initialize(&event, NULL,
1815 (yaml_char_t *)YAML_INT_TAG,
1818 YAML_PLAIN_SCALAR_STYLE);
1819 rc = yaml_emitter_emit(output, &event);
1824 if (tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_traffic_class_str[0]) {
1825 char *tc = &tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_traffic_class_str[0];
1827 yaml_scalar_event_initialize(&event, NULL,
1828 (yaml_char_t *)YAML_STR_TAG,
1829 (yaml_char_t *)"traffic_class",
1830 strlen("traffic_class"), 1, 0,
1831 YAML_PLAIN_SCALAR_STYLE);
1832 rc = yaml_emitter_emit(output, &event);
1836 yaml_scalar_event_initialize(&event, NULL,
1837 (yaml_char_t *)YAML_INT_TAG,
1840 YAML_PLAIN_SCALAR_STYLE);
1842 rc = yaml_emitter_emit(output, &event);
1847 if (tunables->lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer > 0 ||
1848 tunables->lt_tun.lnd_tun_u.lnd_o2ib.lnd_conns_per_peer > 0) {
1851 yaml_scalar_event_initialize(&event, NULL,
1852 (yaml_char_t *)YAML_STR_TAG,
1853 (yaml_char_t *)"conns_per_peer",
1854 strlen("conns_per_peer"), 1, 0,
1855 YAML_PLAIN_SCALAR_STYLE);
1856 rc = yaml_emitter_emit(output, &event);
1860 if (nw_descr->nw_id == LNET_NET_ANY)
1861 cpp = tunables->lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer;
1862 else if (LNET_NETTYP(nw_descr->nw_id) == SOCKLND)
1863 cpp = tunables->lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer;
1864 else if (LNET_NETTYP(nw_descr->nw_id) == O2IBLND)
1865 cpp = tunables->lt_tun.lnd_tun_u.lnd_o2ib.lnd_conns_per_peer;
1866 snprintf(num, sizeof(num), "%u", cpp);
1868 yaml_scalar_event_initialize(&event, NULL,
1869 (yaml_char_t *)YAML_INT_TAG,
1872 YAML_PLAIN_SCALAR_STYLE);
1873 rc = yaml_emitter_emit(output, &event);
1878 yaml_mapping_end_event_initialize(&event);
1879 rc = yaml_emitter_emit(output, &event);
1885 static int yaml_lnet_config_ni(char *net_id, char *ip2net,
1886 struct lnet_dlc_network_descr *nw_descr,
1887 struct lnet_ioctl_config_lnd_tunables *tunables,
1888 int healthv, struct cfs_expr_list *global_cpts,
1889 int version, int flags)
1891 struct lnet_dlc_intf_descr *intf;
1892 struct nl_sock *sk = NULL;
1893 const char *msg = NULL;
1894 yaml_emitter_t output;
1895 yaml_parser_t reply;
1899 if (!(flags & NLM_F_DUMP) && !ip2net && (!nw_descr || nw_descr->nw_id == 0)) {
1900 fprintf(stdout, "missing mandatory parameters in NI config: '%s'\n",
1901 (!nw_descr) ? "network , interface" :
1902 (nw_descr->nw_id == 0) ? "network" : "interface");
1906 if ((flags == NLM_F_CREATE) && !ip2net && list_empty(&nw_descr->nw_intflist)) {
1907 fprintf(stdout, "creating a local NI needs at least one interface\n");
1911 if ((flags == NLM_F_REPLACE) && list_empty(&nw_descr->nw_intflist)) {
1912 fprintf(stdout, "updating a local NI needs at least one address\n");
1916 /* Create Netlink emitter to send request to kernel */
1917 sk = nl_socket_alloc();
1921 /* Setup parser to receive Netlink packets */
1922 rc = yaml_parser_initialize(&reply);
1928 rc = yaml_parser_set_input_netlink(&reply, sk, false);
1930 msg = yaml_parser_get_reader_error(&reply);
1934 /* Create Netlink emitter to send request to kernel */
1935 rc = yaml_emitter_initialize(&output);
1937 msg = "failed to initialize emitter";
1941 rc = yaml_emitter_set_output_netlink(&output, sk, LNET_GENL_NAME,
1942 version, LNET_CMD_NETS, flags);
1946 yaml_emitter_open(&output);
1947 yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
1948 rc = yaml_emitter_emit(&output, &event);
1952 yaml_mapping_start_event_initialize(&event, NULL,
1953 (yaml_char_t *)YAML_MAP_TAG,
1954 1, YAML_ANY_MAPPING_STYLE);
1955 rc = yaml_emitter_emit(&output, &event);
1959 yaml_scalar_event_initialize(&event, NULL,
1960 (yaml_char_t *)YAML_STR_TAG,
1961 (yaml_char_t *)"net",
1962 strlen("net"), 1, 0,
1963 YAML_PLAIN_SCALAR_STYLE);
1964 rc = yaml_emitter_emit(&output, &event);
1968 if (net_id || ip2net) {
1969 char *key = net_id ? "net type" : "ip2net";
1970 char *value = net_id ? net_id : ip2net;
1972 yaml_sequence_start_event_initialize(&event, NULL,
1973 (yaml_char_t *)YAML_SEQ_TAG,
1974 1, YAML_ANY_SEQUENCE_STYLE);
1975 rc = yaml_emitter_emit(&output, &event);
1979 yaml_mapping_start_event_initialize(&event, NULL,
1980 (yaml_char_t *)YAML_MAP_TAG,
1981 1, YAML_ANY_MAPPING_STYLE);
1982 rc = yaml_emitter_emit(&output, &event);
1986 yaml_scalar_event_initialize(&event, NULL,
1987 (yaml_char_t *)YAML_STR_TAG,
1990 1, 0, YAML_PLAIN_SCALAR_STYLE);
1991 rc = yaml_emitter_emit(&output, &event);
1995 yaml_scalar_event_initialize(&event, NULL,
1996 (yaml_char_t *)YAML_STR_TAG,
1997 (yaml_char_t *)value,
1998 strlen(value), 1, 0,
1999 YAML_PLAIN_SCALAR_STYLE);
2000 rc = yaml_emitter_emit(&output, &event);
2004 yaml_scalar_event_initialize(&event, NULL,
2005 (yaml_char_t *)YAML_STR_TAG,
2008 YAML_PLAIN_SCALAR_STYLE);
2009 rc = yaml_emitter_emit(&output, &event);
2016 if (!nw_descr || list_empty(&nw_descr->nw_intflist))
2019 yaml_scalar_event_initialize(&event, NULL,
2020 (yaml_char_t *)YAML_STR_TAG,
2021 (yaml_char_t *)"local NI(s)",
2022 strlen("local NI(s)"), 1, 0,
2023 YAML_PLAIN_SCALAR_STYLE);
2024 rc = yaml_emitter_emit(&output, &event);
2028 yaml_sequence_start_event_initialize(&event, NULL,
2029 (yaml_char_t *)YAML_SEQ_TAG,
2030 1, YAML_ANY_SEQUENCE_STYLE);
2031 rc = yaml_emitter_emit(&output, &event);
2035 list_for_each_entry(intf, &nw_descr->nw_intflist,
2037 yaml_mapping_start_event_initialize(&event, NULL,
2038 (yaml_char_t *)YAML_MAP_TAG,
2039 1, YAML_ANY_MAPPING_STYLE);
2040 rc = yaml_emitter_emit(&output, &event);
2044 /* Use NI addresses instead of interface */
2045 if ((strchr(intf->intf_name, '@') ||
2046 strcmp(intf->intf_name, "<?>") == 0) &&
2047 flags == NLM_F_REPLACE) {
2048 yaml_scalar_event_initialize(&event, NULL,
2049 (yaml_char_t *)YAML_STR_TAG,
2050 (yaml_char_t *)"nid",
2051 strlen("nid"), 1, 0,
2052 YAML_PLAIN_SCALAR_STYLE);
2053 rc = yaml_emitter_emit(&output, &event);
2057 yaml_scalar_event_initialize(&event, NULL,
2058 (yaml_char_t *)YAML_STR_TAG,
2059 (yaml_char_t *)intf->intf_name,
2060 strlen(intf->intf_name), 1, 0,
2061 YAML_PLAIN_SCALAR_STYLE);
2062 rc = yaml_emitter_emit(&output, &event);
2066 yaml_scalar_event_initialize(&event, NULL,
2067 (yaml_char_t *)YAML_STR_TAG,
2068 (yaml_char_t *)"interfaces",
2069 strlen("interfaces"), 1, 0,
2070 YAML_PLAIN_SCALAR_STYLE);
2071 rc = yaml_emitter_emit(&output, &event);
2075 yaml_mapping_start_event_initialize(&event, NULL,
2076 (yaml_char_t *)YAML_MAP_TAG,
2077 1, YAML_ANY_MAPPING_STYLE);
2078 rc = yaml_emitter_emit(&output, &event);
2082 yaml_scalar_event_initialize(&event, NULL,
2083 (yaml_char_t *)YAML_STR_TAG,
2086 YAML_PLAIN_SCALAR_STYLE);
2087 rc = yaml_emitter_emit(&output, &event);
2091 yaml_scalar_event_initialize(&event, NULL,
2092 (yaml_char_t *)YAML_STR_TAG,
2093 (yaml_char_t *)intf->intf_name,
2094 strlen(intf->intf_name), 1, 0,
2095 YAML_PLAIN_SCALAR_STYLE);
2096 rc = yaml_emitter_emit(&output, &event);
2100 yaml_mapping_end_event_initialize(&event);
2101 rc = yaml_emitter_emit(&output, &event);
2107 rc = yaml_add_ni_tunables(&output, tunables, nw_descr);
2112 if (flags == NLM_F_REPLACE && healthv > -1) {
2113 char health[INT_STRING_LEN];
2115 yaml_scalar_event_initialize(&event, NULL,
2116 (yaml_char_t *)YAML_STR_TAG,
2117 (yaml_char_t *)"health stats",
2118 strlen("health stats"), 1, 0,
2119 YAML_PLAIN_SCALAR_STYLE);
2120 rc = yaml_emitter_emit(&output, &event);
2124 /* Setup all mappings for data related to the 'health stats' */
2125 yaml_mapping_start_event_initialize(&event, NULL,
2126 (yaml_char_t *)YAML_MAP_TAG,
2127 1, YAML_BLOCK_MAPPING_STYLE);
2128 rc = yaml_emitter_emit(&output, &event);
2132 yaml_scalar_event_initialize(&event, NULL,
2133 (yaml_char_t *)YAML_STR_TAG,
2134 (yaml_char_t *)"health value",
2135 strlen("health value"), 1, 0,
2136 YAML_PLAIN_SCALAR_STYLE);
2137 rc = yaml_emitter_emit(&output, &event);
2141 snprintf(health, sizeof(health), "%d", healthv);
2142 yaml_scalar_event_initialize(&event, NULL,
2143 (yaml_char_t *)YAML_INT_TAG,
2144 (yaml_char_t *)health,
2145 strlen(health), 1, 0,
2146 YAML_PLAIN_SCALAR_STYLE);
2147 rc = yaml_emitter_emit(&output, &event);
2151 yaml_mapping_end_event_initialize(&event);
2152 rc = yaml_emitter_emit(&output, &event);
2161 yaml_scalar_event_initialize(&event, NULL,
2162 (yaml_char_t *)YAML_STR_TAG,
2163 (yaml_char_t *)"CPT",
2164 strlen("CPT"), 1, 0,
2165 YAML_PLAIN_SCALAR_STYLE);
2166 rc = yaml_emitter_emit(&output, &event);
2170 yaml_sequence_start_event_initialize(&event, NULL,
2171 (yaml_char_t *)YAML_SEQ_TAG,
2173 YAML_FLOW_SEQUENCE_STYLE);
2174 rc = yaml_emitter_emit(&output, &event);
2178 count = cfs_expr_list_values(global_cpts,
2179 LNET_MAX_SHOW_NUM_CPT,
2181 for (i = 0; i < count; i++) {
2182 char core[INT_STRING_LEN];
2184 snprintf(core, sizeof(core), "%u", cpt_array[i]);
2185 yaml_scalar_event_initialize(&event, NULL,
2186 (yaml_char_t *)YAML_STR_TAG,
2187 (yaml_char_t *)core,
2189 YAML_PLAIN_SCALAR_STYLE);
2190 rc = yaml_emitter_emit(&output, &event);
2195 yaml_sequence_end_event_initialize(&event);
2196 rc = yaml_emitter_emit(&output, &event);
2200 cfs_expr_list_free(global_cpts);
2204 yaml_mapping_end_event_initialize(&event);
2205 rc = yaml_emitter_emit(&output, &event);
2210 yaml_sequence_end_event_initialize(&event);
2211 rc = yaml_emitter_emit(&output, &event);
2215 yaml_mapping_end_event_initialize(&event);
2216 rc = yaml_emitter_emit(&output, &event);
2220 yaml_sequence_end_event_initialize(&event);
2221 rc = yaml_emitter_emit(&output, &event);
2225 yaml_mapping_end_event_initialize(&event);
2226 rc = yaml_emitter_emit(&output, &event);
2230 yaml_document_end_event_initialize(&event, 0);
2231 rc = yaml_emitter_emit(&output, &event);
2235 rc = yaml_emitter_close(&output);
2238 yaml_emitter_log_error(&output, stderr);
2241 yaml_document_t errmsg;
2243 rc = yaml_parser_load(&reply, &errmsg);
2244 if (rc == 1 && (flags & NLM_F_DUMP)) {
2245 yaml_emitter_t debug;
2247 rc = yaml_emitter_initialize(&debug);
2249 yaml_emitter_set_indent(&debug,
2250 LNET_DEFAULT_INDENT);
2251 yaml_emitter_set_output_file(&debug, stdout);
2252 rc = yaml_emitter_dump(&debug, &errmsg);
2254 yaml_emitter_delete(&debug);
2256 msg = yaml_parser_get_reader_error(&reply);
2258 yaml_document_delete(&errmsg);
2260 yaml_emitter_delete(&output);
2263 yaml_lnet_print_error(flags, "net", msg);
2266 yaml_parser_delete(&reply);
2269 return rc == 1 ? 0 : rc;
2272 static int jt_add_ni(int argc, char **argv)
2274 char *ip2net = NULL;
2275 long int pto = -1, pc = -1, pbc = -1, cre = -1, cpp = -1, auth_key = -1;
2276 char *traffic_class = NULL;
2277 struct cYAML *err_rc = NULL;
2278 int rc, opt, cpt_rc = -1;
2279 struct lnet_dlc_network_descr nw_descr;
2280 struct cfs_expr_list *global_cpts = NULL;
2281 struct lnet_ioctl_config_lnd_tunables tunables;
2283 bool skip_mr_route_setup = false;
2284 const char *const short_options = "a:b:c:i:k:m:n:p:r:s:t:T:";
2285 static const struct option long_options[] = {
2286 { .name = "auth-key", .has_arg = required_argument, .val = 'a' },
2287 { .name = "peer-buffer-credits",
2288 .has_arg = required_argument, .val = 'b' },
2289 { .name = "peer-credits", .has_arg = required_argument, .val = 'c' },
2290 { .name = "if", .has_arg = required_argument, .val = 'i' },
2291 { .name = "skip-mr-route-setup",
2292 .has_arg = no_argument, .val = 'k' },
2293 { .name = "conns-per-peer",
2294 .has_arg = required_argument, .val = 'm' },
2295 { .name = "net", .has_arg = required_argument, .val = 'n' },
2296 { .name = "ip2net", .has_arg = required_argument, .val = 'p' },
2297 { .name = "credits", .has_arg = required_argument, .val = 'r' },
2298 { .name = "cpt", .has_arg = required_argument, .val = 's' },
2299 { .name = "peer-timeout", .has_arg = required_argument, .val = 't' },
2300 { .name = "traffic-class", .has_arg = required_argument, .val = 'T' },
2302 char *net_id = NULL;
2304 memset(&tunables, 0, sizeof(tunables));
2305 lustre_lnet_init_nw_descr(&nw_descr);
2307 rc = check_cmd(net_cmds, "net", "add", 0, argc, argv);
2311 while ((opt = getopt_long(argc, argv, short_options,
2312 long_options, NULL)) != -1) {
2315 rc = parse_long(optarg, &auth_key);
2323 rc = parse_long(optarg, &pbc);
2331 rc = parse_long(optarg, &pc);
2339 rc = lustre_lnet_parse_interfaces(optarg, &nw_descr);
2341 cYAML_build_error(-1, -1, "ni", "add",
2342 "bad interface list",
2348 skip_mr_route_setup = true;
2351 rc = parse_long(optarg, &cpp);
2360 nw_descr.nw_id = libcfs_str2net(optarg);
2367 rc = parse_long(optarg, &cre);
2375 cpt_rc = cfs_expr_list_parse(optarg,
2377 UINT_MAX, &global_cpts);
2380 rc = parse_long(optarg, &pto);
2388 traffic_class = optarg;
2389 if (strlen(traffic_class) == 0 ||
2390 strlen(traffic_class) >= LNET_MAX_STR_LEN) {
2391 cYAML_build_error(-1, -1, "ni", "add",
2392 "Invalid traffic-class argument",
2394 rc = LUSTRE_CFG_RC_BAD_PARAM;
2399 print_help(net_cmds, "net", "add");
2405 if (auth_key > 0 && LNET_NETTYP(nw_descr.nw_id) == KFILND) {
2406 tunables.lt_tun.lnd_tun_u.lnd_kfi.lnd_auth_key = auth_key;
2410 if (traffic_class && LNET_NETTYP(nw_descr.nw_id) == KFILND &&
2411 strlen(traffic_class) < LNET_MAX_STR_LEN) {
2412 strcpy(&tunables.lt_tun.lnd_tun_u.lnd_kfi.lnd_traffic_class_str[0],
2418 if (LNET_NETTYP(nw_descr.nw_id) == SOCKLND && (cpp > -1)) {
2419 tunables.lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer = cpp;
2421 } else if (LNET_NETTYP(nw_descr.nw_id) == O2IBLND && (cpp > -1)) {
2422 tunables.lt_tun.lnd_tun_u.lnd_o2ib.lnd_conns_per_peer = cpp;
2426 if (pto >= 0 || pc > 0 || pbc > 0 || cre > 0 || cpp > -1) {
2427 tunables.lt_cmn.lct_peer_timeout = pto;
2428 tunables.lt_cmn.lct_peer_tx_credits = pc;
2429 tunables.lt_cmn.lct_peer_rtr_credits = pbc;
2430 tunables.lt_cmn.lct_max_tx_credits = cre;
2434 if (found && LNET_NETTYP(nw_descr.nw_id) == O2IBLND)
2435 tunables.lt_tun.lnd_tun_u.lnd_o2ib.lnd_map_on_demand = UINT_MAX;
2437 rc = yaml_lnet_config_ni(net_id, ip2net, &nw_descr,
2438 found ? &tunables : NULL, -1,
2439 (cpt_rc == 0) ? global_cpts : NULL,
2440 LNET_GENL_VERSION, NLM_F_CREATE);
2442 if (rc == -EOPNOTSUPP)
2444 if (global_cpts != NULL)
2445 cfs_expr_list_free(global_cpts);
2446 if (rc == 0 && !skip_mr_route_setup)
2447 rc = lustre_lnet_setup_mrrouting(&err_rc);
2451 rc = lustre_lnet_config_ni(&nw_descr,
2452 (cpt_rc == 0) ? global_cpts: NULL,
2453 ip2net, (found) ? &tunables : NULL,
2456 if (global_cpts != NULL)
2457 cfs_expr_list_free(global_cpts);
2460 if (rc != LUSTRE_CFG_RC_NO_ERR)
2461 cYAML_print_tree2file(stderr, err_rc);
2463 cYAML_free_tree(err_rc);
2465 if (rc == LUSTRE_CFG_RC_NO_ERR && !skip_mr_route_setup) {
2467 rc = lustre_lnet_setup_mrrouting(&err_rc);
2469 if (rc != LUSTRE_CFG_RC_NO_ERR)
2470 cYAML_print_tree2file(stderr, err_rc);
2472 cYAML_free_tree(err_rc);
2478 static int jt_del_route(int argc, char **argv)
2480 char *network = NULL, *gateway = NULL;
2481 struct cYAML *err_rc = NULL;
2483 const char *const short_options = "n:g:";
2484 static const struct option long_options[] = {
2485 { .name = "net", .has_arg = required_argument, .val = 'n' },
2486 { .name = "gateway", .has_arg = required_argument, .val = 'g' },
2490 rc = check_cmd(route_cmds, "route", "del", 0, argc, argv);
2494 while ((opt = getopt_long(argc, argv, short_options,
2495 long_options, NULL)) != -1) {
2504 print_help(route_cmds, "route", "del");
2510 rc = yaml_lnet_route(network, gateway, -1, -1, -1, LNET_GENL_VERSION,
2513 if (rc == -EOPNOTSUPP)
2518 rc = lustre_lnet_del_route(network, gateway, -1, &err_rc);
2520 if (rc != LUSTRE_CFG_RC_NO_ERR)
2521 cYAML_print_tree2file(stderr, err_rc);
2523 cYAML_free_tree(err_rc);
2528 static int jt_del_ni(int argc, char **argv)
2530 struct cYAML *err_rc = NULL;
2532 struct lnet_dlc_network_descr nw_descr;
2533 const char *const short_options = "n:i:";
2534 static const struct option long_options[] = {
2535 { .name = "net", .has_arg = required_argument, .val = 'n' },
2536 { .name = "if", .has_arg = required_argument, .val = 'i' },
2538 char *net_id = NULL;
2540 rc = check_cmd(net_cmds, "net", "del", 0, argc, argv);
2544 lustre_lnet_init_nw_descr(&nw_descr);
2546 while ((opt = getopt_long(argc, argv, short_options,
2547 long_options, NULL)) != -1) {
2550 nw_descr.nw_id = libcfs_str2net(optarg);
2554 rc = lustre_lnet_parse_interfaces(optarg, &nw_descr);
2556 cYAML_build_error(-1, -1, "ni", "add",
2557 "bad interface list",
2563 print_help(net_cmds, "net", "del");
2569 rc = yaml_lnet_config_ni(net_id, NULL, &nw_descr, NULL, -1, NULL,
2570 LNET_GENL_VERSION, 0);
2572 if (rc != -EOPNOTSUPP)
2576 rc = lustre_lnet_del_ni(&nw_descr, -1, &err_rc);
2578 if (rc != LUSTRE_CFG_RC_NO_ERR)
2579 cYAML_print_tree2file(stderr, err_rc);
2581 cYAML_free_tree(err_rc);
2586 static int jt_show_route(int argc, char **argv)
2588 char *network = NULL, *gateway = NULL;
2589 long int hop = -1, prio = -1;
2590 int detail = 0, rc, opt;
2591 struct cYAML *err_rc = NULL, *show_rc = NULL;
2592 const char *const short_options = "c:n:g:p:v";
2593 static const struct option long_options[] = {
2594 { .name = "net", .has_arg = required_argument, .val = 'n' },
2595 { .name = "gateway", .has_arg = required_argument, .val = 'g' },
2596 { .name = "hop-count", .has_arg = required_argument, .val = 'c' },
2597 { .name = "hop", .has_arg = required_argument, .val = 'c' },
2598 { .name = "priority", .has_arg = required_argument, .val = 'p' },
2599 { .name = "verbose", .has_arg = no_argument, .val = 'v' },
2603 rc = check_cmd(route_cmds, "route", "show", 0, argc, argv);
2607 while ((opt = getopt_long(argc, argv, short_options,
2608 long_options, NULL)) != -1) {
2617 rc = parse_long(optarg, &hop);
2625 rc = parse_long(optarg, &prio);
2636 print_help(route_cmds, "route", "show");
2642 rc = yaml_lnet_route(network, gateway, hop, prio, -1,
2643 detail, NLM_F_DUMP);
2645 if (rc == -EOPNOTSUPP)
2650 rc = lustre_lnet_show_route(network, gateway, hop, prio,
2652 &show_rc, &err_rc, false);
2654 if (rc != LUSTRE_CFG_RC_NO_ERR)
2655 cYAML_print_tree2file(stderr, err_rc);
2657 cYAML_print_tree(show_rc);
2659 cYAML_free_tree(err_rc);
2660 cYAML_free_tree(show_rc);
2665 static int set_value_helper(int argc, char **argv, int cmd,
2666 int (*cb)(int, bool, char*, int, int, struct cYAML**))
2668 char *nidstr = NULL;
2669 long int healthv = -1;
2671 long int state = -1;
2674 struct cYAML *err_rc = NULL;
2675 const char *const short_options = "t:n:m:s:a";
2676 static const struct option long_options[] = {
2677 { .name = "nid", .has_arg = required_argument, .val = 'n' },
2678 { .name = "health", .has_arg = required_argument, .val = 't' },
2679 { .name = "conns-per-peer", .has_arg = required_argument, .val = 'm' },
2680 { .name = "state", .has_arg = required_argument, .val = 's' },
2681 { .name = "all", .has_arg = no_argument, .val = 'a' },
2685 while ((opt = getopt_long(argc, argv, short_options,
2686 long_options, NULL)) != -1) {
2692 if (parse_long(optarg, &healthv) != 0)
2696 if (cmd != LNET_CMD_PEERS ||
2697 parse_long(optarg, &state) != 0)
2701 if (cmd != LNET_CMD_NETS ||
2702 parse_long(optarg, &cpp) != 0)
2714 rc = cb(healthv, all, nidstr, cmd == LNET_CMD_PEERS ? state : cpp, -1,
2716 if (rc != LUSTRE_CFG_RC_NO_ERR)
2717 cYAML_print_tree2file(stderr, err_rc);
2719 cYAML_free_tree(err_rc);
2724 int yaml_lnet_config_ni_healthv(int healthv, bool all, char *nidstr, int cpp,
2725 int seq_no, struct cYAML **err_rc)
2727 struct lnet_ioctl_config_lnd_tunables tunables;
2728 struct lnet_dlc_network_descr nw_descr;
2729 char *net_id = "<255:65535>"; /* LNET_NET_ANY */
2732 /* For NI you can't have both setting all NIDs and a requested NID */
2733 if (!all && !nidstr)
2736 if (cpp == -1 && healthv == -1)
2740 net_id = strchr(nidstr, '@');
2746 lustre_lnet_init_nw_descr(&nw_descr);
2747 nw_descr.nw_id = libcfs_str2net(net_id);
2749 rc = lustre_lnet_parse_interfaces(nidstr ? nidstr : "<?>", &nw_descr);
2750 if (rc != LUSTRE_CFG_RC_NO_ERR)
2753 memset(&tunables, 0, sizeof(tunables));
2754 tunables.lt_cmn.lct_peer_timeout = -1;
2755 if (nw_descr.nw_id == LNET_NET_ANY && cpp > -1)
2756 tunables.lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer = cpp;
2757 else if (LNET_NETTYP(nw_descr.nw_id) == SOCKLND && (cpp > -1))
2758 tunables.lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer = cpp;
2759 else if (LNET_NETTYP(nw_descr.nw_id) == O2IBLND && (cpp > -1))
2760 tunables.lt_tun.lnd_tun_u.lnd_o2ib.lnd_conns_per_peer = cpp;
2762 rc = yaml_lnet_config_ni(net_id, NULL, &nw_descr,
2763 cpp != -1 ? &tunables : NULL, healthv, NULL,
2764 LNET_GENL_VERSION, NLM_F_REPLACE);
2766 if (rc == -EOPNOTSUPP)
2772 rc = lustre_lnet_config_ni_conns_per_peer(cpp, all, nidstr,
2775 rc = lustre_lnet_config_ni_healthv(healthv, all, nidstr,
2780 static int jt_set_ni_value(int argc, char **argv)
2782 int rc = check_cmd(net_cmds, "net", "set", 0, argc, argv);
2787 return set_value_helper(argc, argv, LNET_CMD_NETS,
2788 yaml_lnet_config_ni_healthv);
2791 static int yaml_lnet_peer_display(yaml_parser_t *reply, bool list_only)
2793 yaml_emitter_t debug;
2796 rc = yaml_emitter_initialize(&debug);
2800 yaml_emitter_set_indent(&debug, 6);
2801 yaml_emitter_set_output_file(&debug, stdout);
2810 rc = yaml_parser_parse(reply, &event);
2812 goto report_reply_error;
2814 if (event.type != YAML_SCALAR_EVENT)
2817 value = (char *)event.data.scalar.value;
2818 if (strcmp(value, "peer") == 0) {
2819 yaml_event_delete(&event);
2821 yaml_scalar_event_initialize(&event, NULL,
2822 (yaml_char_t *)YAML_STR_TAG,
2823 (yaml_char_t *)"peer list",
2824 strlen("peer list"),
2826 YAML_PLAIN_SCALAR_STYLE);
2827 } else if (strcmp(value, "primary nid") == 0) {
2828 yaml_event_delete(&event);
2830 yaml_scalar_event_initialize(&event, NULL,
2831 (yaml_char_t *)YAML_STR_TAG,
2832 (yaml_char_t *)"nid",
2835 YAML_PLAIN_SCALAR_STYLE);
2836 rc = yaml_emitter_emit(&debug, &event);
2840 /* Now print NID address */
2841 rc = yaml_parser_parse(reply, &event);
2843 goto report_reply_error;
2845 rc = yaml_emitter_emit(&debug, &event);
2850 while (event.type != YAML_MAPPING_END_EVENT) {
2851 rc = yaml_parser_parse(reply, &event);
2853 goto report_reply_error;
2856 /* we can have map end, seq end, map end or
2857 * just map end event. If we see seq end event
2858 * then skip to next mapping end event
2860 rc = yaml_parser_parse(reply, &event);
2862 goto report_reply_error;
2864 if (event.type == YAML_SEQUENCE_END_EVENT) {
2865 yaml_event_delete(&event);
2867 rc = yaml_parser_parse(reply, &event);
2869 goto report_reply_error;
2873 rc = yaml_emitter_emit(&debug, &event);
2877 done = (event.type == YAML_DOCUMENT_END_EVENT);
2880 yaml_document_t errmsg;
2882 rc = yaml_parser_load(reply, &errmsg);
2884 rc = yaml_emitter_dump(&debug, &errmsg);
2885 yaml_document_delete(&errmsg);
2889 yaml_emitter_log_error(&debug, stderr);
2891 yaml_emitter_delete(&debug);
2896 static int yaml_lnet_peer(char *prim_nid, char *nidstr, bool disable_mr,
2897 int health_value, int state, bool list_only,
2898 int version, int flags)
2900 struct nl_sock *sk = NULL;
2901 const char *msg = NULL;
2902 yaml_emitter_t output;
2903 yaml_parser_t reply;
2907 /* Create Netlink emitter to send request to kernel */
2908 sk = nl_socket_alloc();
2912 /* Setup parser to receive Netlink packets */
2913 rc = yaml_parser_initialize(&reply);
2919 rc = yaml_parser_set_input_netlink(&reply, sk, false);
2921 msg = yaml_parser_get_reader_error(&reply);
2925 /* Create Netlink emitter to send request to kernel */
2926 rc = yaml_emitter_initialize(&output);
2928 msg = "failed to initialize emitter";
2932 rc = yaml_emitter_set_output_netlink(&output, sk, LNET_GENL_NAME,
2933 version, LNET_CMD_PEERS, flags);
2937 yaml_emitter_open(&output);
2938 yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
2939 rc = yaml_emitter_emit(&output, &event);
2943 yaml_mapping_start_event_initialize(&event, NULL,
2944 (yaml_char_t *)YAML_MAP_TAG,
2945 1, YAML_ANY_MAPPING_STYLE);
2946 rc = yaml_emitter_emit(&output, &event);
2950 yaml_scalar_event_initialize(&event, NULL,
2951 (yaml_char_t *)YAML_STR_TAG,
2952 (yaml_char_t *)"peer",
2953 strlen("peer"), 1, 0,
2954 YAML_PLAIN_SCALAR_STYLE);
2955 rc = yaml_emitter_emit(&output, &event);
2960 yaml_sequence_start_event_initialize(&event, NULL,
2961 (yaml_char_t *)YAML_SEQ_TAG,
2963 YAML_BLOCK_SEQUENCE_STYLE);
2964 rc = yaml_emitter_emit(&output, &event);
2968 yaml_mapping_start_event_initialize(&event, NULL,
2969 (yaml_char_t *)YAML_MAP_TAG,
2971 YAML_BLOCK_MAPPING_STYLE);
2972 rc = yaml_emitter_emit(&output, &event);
2976 yaml_scalar_event_initialize(&event, NULL,
2977 (yaml_char_t *)YAML_STR_TAG,
2978 (yaml_char_t *)"primary nid",
2979 strlen("primary nid"), 1, 0,
2980 YAML_PLAIN_SCALAR_STYLE);
2981 rc = yaml_emitter_emit(&output, &event);
2985 yaml_scalar_event_initialize(&event, NULL,
2986 (yaml_char_t *)YAML_STR_TAG,
2987 (yaml_char_t *)prim_nid,
2988 strlen(prim_nid), 1, 0,
2989 YAML_PLAIN_SCALAR_STYLE);
2990 rc = yaml_emitter_emit(&output, &event);
2995 yaml_scalar_event_initialize(&event, NULL,
2996 (yaml_char_t *)YAML_STR_TAG,
2997 (yaml_char_t *)"Multi-Rail",
2998 strlen("Multi-Rail"), 1, 0,
2999 YAML_PLAIN_SCALAR_STYLE);
3000 rc = yaml_emitter_emit(&output, &event);
3004 yaml_scalar_event_initialize(&event, NULL,
3005 (yaml_char_t *)YAML_BOOL_TAG,
3006 (yaml_char_t *)"False",
3007 strlen("False"), 1, 0,
3008 YAML_PLAIN_SCALAR_STYLE);
3009 rc = yaml_emitter_emit(&output, &event);
3015 char peer_state[INT_STRING_LEN];
3017 yaml_scalar_event_initialize(&event, NULL,
3018 (yaml_char_t *)YAML_STR_TAG,
3019 (yaml_char_t *)"peer state",
3020 strlen("peer state"), 1, 0,
3021 YAML_PLAIN_SCALAR_STYLE);
3022 rc = yaml_emitter_emit(&output, &event);
3026 snprintf(peer_state, sizeof(peer_state), "%d", state);
3027 yaml_scalar_event_initialize(&event, NULL,
3028 (yaml_char_t *)YAML_INT_TAG,
3029 (yaml_char_t *)peer_state,
3030 strlen(peer_state), 1, 0,
3031 YAML_PLAIN_SCALAR_STYLE);
3032 rc = yaml_emitter_emit(&output, &event);
3037 if (!nidstr && health_value == -1)
3040 yaml_scalar_event_initialize(&event, NULL,
3041 (yaml_char_t *)YAML_STR_TAG,
3042 (yaml_char_t *)"peer ni",
3043 strlen("peer ni"), 1, 0,
3044 YAML_PLAIN_SCALAR_STYLE);
3045 rc = yaml_emitter_emit(&output, &event);
3049 yaml_sequence_start_event_initialize(&event, NULL,
3050 (yaml_char_t *)YAML_SEQ_TAG,
3051 1, YAML_BLOCK_SEQUENCE_STYLE);
3052 rc = yaml_emitter_emit(&output, &event);
3057 struct nid_node head, *entry;
3060 /* If we have LNET_ANY_NID and its NLM_F_REPLACE we
3061 * treat it as the all flag case for lnetctl peer set
3063 if (strcmp(nidstr, "<?>") == 0) {
3064 yaml_mapping_start_event_initialize(&event, NULL,
3065 (yaml_char_t *)YAML_MAP_TAG,
3066 1, YAML_BLOCK_MAPPING_STYLE);
3067 rc = yaml_emitter_emit(&output, &event);
3071 yaml_scalar_event_initialize(&event, NULL,
3072 (yaml_char_t *)YAML_STR_TAG,
3073 (yaml_char_t *)"nid",
3074 strlen("nid"), 1, 0,
3075 YAML_PLAIN_SCALAR_STYLE);
3076 rc = yaml_emitter_emit(&output, &event);
3080 yaml_scalar_event_initialize(&event, NULL,
3081 (yaml_char_t *)YAML_STR_TAG,
3082 (yaml_char_t *)nidstr,
3083 strlen(nidstr), 1, 0,
3084 YAML_PLAIN_SCALAR_STYLE);
3085 rc = yaml_emitter_emit(&output, &event);
3089 yaml_mapping_end_event_initialize(&event);
3090 rc = yaml_emitter_emit(&output, &event);
3097 NL_INIT_LIST_HEAD(&head.children);
3098 nl_init_list_head(&head.list);
3099 rc = lustre_lnet_parse_nid_range(&head, nidstr, &msg);
3101 fprintf(stdout, "can't parse nidrange: \"%s\"\n", nidstr);
3102 lustre_lnet_free_list(&head);
3103 yaml_emitter_delete(&output);
3109 if (nl_list_empty(&head.children)) {
3110 lustre_lnet_free_list(&head);
3111 yaml_emitter_delete(&output);
3112 msg = "Unable to parse nidlist: did not expand to any nids";
3117 rc = 1; /* one means its working */
3119 nl_list_for_each_entry(entry, &head.children, list) {
3120 char *nid = entry->nidstr;
3122 if (count++ > LNET_MAX_NIDS_PER_PEER) {
3123 lustre_lnet_free_list(&head);
3124 yaml_emitter_delete(&output);
3125 msg = "Unable to parse nidlist: specifies more NIDs than allowed";
3131 yaml_mapping_start_event_initialize(&event, NULL,
3132 (yaml_char_t *)YAML_MAP_TAG,
3133 1, YAML_BLOCK_MAPPING_STYLE);
3134 rc = yaml_emitter_emit(&output, &event);
3138 yaml_scalar_event_initialize(&event, NULL,
3139 (yaml_char_t *)YAML_STR_TAG,
3140 (yaml_char_t *)"nid",
3141 strlen("nid"), 1, 0,
3142 YAML_PLAIN_SCALAR_STYLE);
3143 rc = yaml_emitter_emit(&output, &event);
3147 yaml_scalar_event_initialize(&event, NULL,
3148 (yaml_char_t *)YAML_STR_TAG,
3151 YAML_PLAIN_SCALAR_STYLE);
3152 rc = yaml_emitter_emit(&output, &event);
3156 yaml_mapping_end_event_initialize(&event);
3157 rc = yaml_emitter_emit(&output, &event);
3161 lustre_lnet_free_list(&head);
3164 if (health_value >= 0) {
3165 char health[INT_STRING_LEN];
3167 /* Create the mapping for 'health stats'. The value field for
3168 * the mapping is not provided so its treated as a empty string.
3170 yaml_mapping_start_event_initialize(&event, NULL,
3171 (yaml_char_t *)YAML_MAP_TAG,
3172 1, YAML_BLOCK_MAPPING_STYLE);
3173 rc = yaml_emitter_emit(&output, &event);
3177 yaml_scalar_event_initialize(&event, NULL,
3178 (yaml_char_t *)YAML_STR_TAG,
3179 (yaml_char_t *)"health stats",
3180 strlen("health stats"), 1, 0,
3181 YAML_PLAIN_SCALAR_STYLE);
3182 rc = yaml_emitter_emit(&output, &event);
3186 /* Setup all mappings for data related to the 'health stats' */
3187 yaml_mapping_start_event_initialize(&event, NULL,
3188 (yaml_char_t *)YAML_MAP_TAG,
3189 1, YAML_BLOCK_MAPPING_STYLE);
3190 rc = yaml_emitter_emit(&output, &event);
3194 yaml_scalar_event_initialize(&event, NULL,
3195 (yaml_char_t *)YAML_STR_TAG,
3196 (yaml_char_t *)"health value",
3197 strlen("health value"), 1, 0,
3198 YAML_PLAIN_SCALAR_STYLE);
3199 rc = yaml_emitter_emit(&output, &event);
3203 snprintf(health, sizeof(health), "%d", health_value);
3204 yaml_scalar_event_initialize(&event, NULL,
3205 (yaml_char_t *)YAML_INT_TAG,
3206 (yaml_char_t *)health,
3207 strlen(health), 1, 0,
3208 YAML_PLAIN_SCALAR_STYLE);
3209 rc = yaml_emitter_emit(&output, &event);
3213 yaml_mapping_end_event_initialize(&event);
3214 rc = yaml_emitter_emit(&output, &event);
3218 yaml_mapping_end_event_initialize(&event);
3219 rc = yaml_emitter_emit(&output, &event);
3224 yaml_sequence_end_event_initialize(&event);
3225 rc = yaml_emitter_emit(&output, &event);
3229 yaml_mapping_end_event_initialize(&event);
3230 rc = yaml_emitter_emit(&output, &event);
3234 yaml_sequence_end_event_initialize(&event);
3235 rc = yaml_emitter_emit(&output, &event);
3239 yaml_scalar_event_initialize(&event, NULL,
3240 (yaml_char_t *)YAML_STR_TAG,
3243 YAML_PLAIN_SCALAR_STYLE);
3244 rc = yaml_emitter_emit(&output, &event);
3249 yaml_mapping_end_event_initialize(&event);
3250 rc = yaml_emitter_emit(&output, &event);
3254 yaml_document_end_event_initialize(&event, 0);
3255 rc = yaml_emitter_emit(&output, &event);
3259 rc = yaml_emitter_close(&output);
3262 yaml_emitter_log_error(&output, stderr);
3265 rc = yaml_lnet_peer_display(&reply, list_only);
3267 msg = yaml_parser_get_reader_error(&reply);
3268 /* If we didn't find any peers just be silent */
3269 if (msg && strcmp(msg, "No peers found") == 0)
3274 yaml_emitter_delete(&output);
3277 yaml_lnet_print_error(flags, "peer", msg);
3280 yaml_parser_delete(&reply);
3283 return rc == 1 ? 0 : rc;
3286 int yaml_lnet_config_peer_ni_healthv(int healthv, bool all, char *lpni_nid,
3287 int state, int seq_no, struct cYAML **err_rc)
3291 rc = yaml_lnet_peer(lpni_nid ? lpni_nid : "<?>", all ? "<?>" : NULL,
3292 false, healthv, state, false, LNET_GENL_VERSION,
3295 if (rc == -EOPNOTSUPP)
3301 rc = lustre_lnet_config_peer_ni_healthv(healthv, all, lpni_nid,
3304 rc = lustre_lnet_set_peer_state(state, lpni_nid, -1, err_rc);
3309 static int jt_set_peer_ni_value(int argc, char **argv)
3311 int rc = check_cmd(peer_cmds, "peer", "set", 0, argc, argv);
3316 return set_value_helper(argc, argv, LNET_CMD_PEERS,
3317 yaml_lnet_config_peer_ni_healthv);
3320 static int jt_show_recovery(int argc, char **argv)
3323 struct cYAML *err_rc = NULL, *show_rc = NULL;
3324 const char *const short_options = "lp";
3325 static const struct option long_options[] = {
3326 { .name = "local", .has_arg = no_argument, .val = 'l' },
3327 { .name = "peer", .has_arg = no_argument, .val = 'p' },
3330 rc = check_cmd(debug_cmds, "debug", "recovery", 0, argc, argv);
3334 while ((opt = getopt_long(argc, argv, short_options,
3335 long_options, NULL)) != -1) {
3338 rc = lustre_lnet_show_local_ni_recovq(-1, &show_rc, &err_rc);
3341 rc = lustre_lnet_show_peer_ni_recovq(-1, &show_rc, &err_rc);
3348 if (rc != LUSTRE_CFG_RC_NO_ERR)
3349 cYAML_print_tree2file(stderr, err_rc);
3351 cYAML_print_tree(show_rc);
3353 cYAML_free_tree(err_rc);
3354 cYAML_free_tree(show_rc);
3359 static int jt_show_peer_debug_info(int argc, char **argv)
3362 struct cYAML *err_rc = NULL;
3363 char *peer_nid = optarg;
3364 const char *const short_opts = "k";
3365 const struct option long_opts[] = {
3366 { .name = "nid", .has_arg = required_argument, .val = 'k' },
3369 rc = check_cmd(debug_cmds, "debug", "peer", 0, argc, argv);
3374 while ((opt = getopt_long(argc, argv, short_opts,
3375 long_opts, NULL)) != -1) {
3385 rc = lustre_lnet_show_peer_debug_info(peer_nid, -1, &err_rc);
3387 if (rc != LUSTRE_CFG_RC_NO_ERR)
3388 cYAML_print_tree2file(stderr, err_rc);
3390 cYAML_free_tree(err_rc);
3395 static int jt_show_net(int argc, char **argv)
3397 char *network = NULL;
3399 struct cYAML *err_rc = NULL, *show_rc = NULL;
3400 long int detail = 0;
3401 const char *const short_options = "n:v";
3402 static const struct option long_options[] = {
3403 { .name = "net", .has_arg = required_argument, .val = 'n' },
3404 { .name = "verbose", .has_arg = optional_argument, .val = 'v' },
3407 rc = check_cmd(net_cmds, "net", "show", 0, argc, argv);
3411 while ((opt = getopt_long(argc, argv, short_options,
3412 long_options, NULL)) != -1) {
3418 if ((!optarg) && (argv[optind] != NULL) &&
3419 (argv[optind][0] != '-')) {
3420 if (parse_long(argv[optind++], &detail) != 0)
3427 print_help(net_cmds, "net", "show");
3433 rc = yaml_lnet_config_ni(network, NULL, NULL, NULL, -1, NULL,
3434 detail, NLM_F_DUMP);
3436 if (rc != -EOPNOTSUPP)
3440 rc = lustre_lnet_show_net(network, (int) detail, -1, &show_rc, &err_rc,
3443 if (rc != LUSTRE_CFG_RC_NO_ERR)
3444 cYAML_print_tree2file(stderr, err_rc);
3446 cYAML_print_tree(show_rc);
3448 cYAML_free_tree(err_rc);
3449 cYAML_free_tree(show_rc);
3454 static int jt_show_routing(int argc, char **argv)
3456 struct cYAML *err_rc = NULL, *show_rc = NULL;
3459 rc = check_cmd(routing_cmds, "routing", "show", 0, argc, argv);
3463 rc = lustre_lnet_show_routing(-1, &show_rc, &err_rc, false);
3465 if (rc != LUSTRE_CFG_RC_NO_ERR)
3466 cYAML_print_tree2file(stderr, err_rc);
3468 cYAML_print_tree(show_rc);
3470 cYAML_free_tree(err_rc);
3471 cYAML_free_tree(show_rc);
3476 static int jt_show_stats(int argc, char **argv)
3479 struct cYAML *show_rc = NULL, *err_rc = NULL;
3481 rc = check_cmd(stats_cmds, "stats", "show", 0, argc, argv);
3485 rc = lustre_lnet_show_stats(-1, &show_rc, &err_rc);
3487 if (rc != LUSTRE_CFG_RC_NO_ERR)
3488 cYAML_print_tree2file(stderr, err_rc);
3490 cYAML_print_tree(show_rc);
3492 cYAML_free_tree(err_rc);
3493 cYAML_free_tree(show_rc);
3498 static int jt_show_udsp(int argc, char **argv)
3502 struct cYAML *err_rc = NULL, *show_rc = NULL;
3504 const char *const short_options = "i:";
3505 static const struct option long_options[] = {
3506 { .name = "idx", .has_arg = required_argument, .val = 'i' },
3510 rc = check_cmd(udsp_cmds, "udsp", "show", 0, argc, argv);
3514 while ((opt = getopt_long(argc, argv, short_options,
3515 long_options, NULL)) != -1) {
3518 rc = parse_long(optarg, &idx);
3519 if (rc != 0 || idx < -1) {
3520 printf("Invalid index \"%s\"\n", optarg);
3525 print_help(net_cmds, "net", "show");
3531 rc = lustre_lnet_show_udsp(idx, -1, &show_rc, &err_rc);
3533 if (rc != LUSTRE_CFG_RC_NO_ERR)
3534 cYAML_print_tree2file(stderr, err_rc);
3536 cYAML_print_tree(show_rc);
3538 cYAML_free_tree(err_rc);
3539 cYAML_free_tree(show_rc);
3544 static int jt_show_global(int argc, char **argv)
3547 struct cYAML *show_rc = NULL, *err_rc = NULL;
3549 rc = check_cmd(global_cmds, "global", "show", 0, argc, argv);
3553 rc = lustre_lnet_show_numa_range(-1, &show_rc, &err_rc);
3554 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3555 cYAML_print_tree2file(stderr, err_rc);
3559 rc = lustre_lnet_show_max_intf(-1, &show_rc, &err_rc);
3560 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3561 cYAML_print_tree2file(stderr, err_rc);
3565 rc = lustre_lnet_show_discovery(-1, &show_rc, &err_rc);
3566 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3567 cYAML_print_tree2file(stderr, err_rc);
3571 rc = lustre_lnet_show_drop_asym_route(-1, &show_rc, &err_rc);
3572 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3573 cYAML_print_tree2file(stderr, err_rc);
3577 rc = lustre_lnet_show_retry_count(-1, &show_rc, &err_rc);
3578 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3579 cYAML_print_tree2file(stderr, err_rc);
3583 rc = lustre_lnet_show_transaction_to(-1, &show_rc, &err_rc);
3584 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3585 cYAML_print_tree2file(stderr, err_rc);
3589 rc = lustre_lnet_show_hsensitivity(-1, &show_rc, &err_rc);
3590 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3591 cYAML_print_tree2file(stderr, err_rc);
3595 rc = lustre_lnet_show_recov_intrv(-1, &show_rc, &err_rc);
3596 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3597 cYAML_print_tree2file(stderr, err_rc);
3601 rc = lustre_lnet_show_rtr_sensitivity(-1, &show_rc, &err_rc);
3602 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3603 cYAML_print_tree2file(stderr, err_rc);
3607 rc = lustre_lnet_show_lnd_timeout(-1, &show_rc, &err_rc);
3608 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3609 cYAML_print_tree2file(stderr, err_rc);
3613 rc = lustre_lnet_show_response_tracking(-1, &show_rc, &err_rc);
3614 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3615 cYAML_print_tree2file(stderr, err_rc);
3619 rc = lustre_lnet_show_recovery_limit(-1, &show_rc, &err_rc);
3620 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3621 cYAML_print_tree2file(stderr, err_rc);
3625 rc = lustre_lnet_show_max_recovery_ping_interval(-1, &show_rc, &err_rc);
3626 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3627 cYAML_print_tree2file(stderr, err_rc);
3632 cYAML_print_tree(show_rc);
3635 cYAML_free_tree(err_rc);
3636 cYAML_free_tree(show_rc);
3641 static int jt_lnet(int argc, char **argv)
3645 rc = check_cmd(lnet_cmds, "lnet", NULL, 2, argc, argv);
3649 return cfs_parser(argc, argv, lnet_cmds);
3652 static int jt_route(int argc, char **argv)
3656 rc = check_cmd(route_cmds, "route", NULL, 2, argc, argv);
3660 return cfs_parser(argc, argv, route_cmds);
3663 static int jt_net(int argc, char **argv)
3667 rc = check_cmd(net_cmds, "net", NULL, 2, argc, argv);
3671 return cfs_parser(argc, argv, net_cmds);
3674 static int jt_routing(int argc, char **argv)
3678 rc = check_cmd(routing_cmds, "routing", NULL, 2, argc, argv);
3682 return cfs_parser(argc, argv, routing_cmds);
3685 static int jt_stats(int argc, char **argv)
3689 rc = check_cmd(stats_cmds, "stats", NULL, 2, argc, argv);
3693 return cfs_parser(argc, argv, stats_cmds);
3696 static int jt_debug(int argc, char **argv)
3700 rc = check_cmd(debug_cmds, "debug", NULL, 2, argc, argv);
3704 return cfs_parser(argc, argv, debug_cmds);
3707 static int jt_global(int argc, char **argv)
3711 rc = check_cmd(global_cmds, "global", NULL, 2, argc, argv);
3715 return cfs_parser(argc, argv, global_cmds);
3718 static int jt_peers(int argc, char **argv)
3722 rc = check_cmd(peer_cmds, "peer", NULL, 2, argc, argv);
3726 return cfs_parser(argc, argv, peer_cmds);
3729 static int jt_set(int argc, char **argv)
3733 rc = check_cmd(set_cmds, "set", NULL, 2, argc, argv);
3737 return cfs_parser(argc, argv, set_cmds);
3740 static int jt_udsp(int argc, char **argv)
3744 rc = check_cmd(udsp_cmds, "udsp", NULL, 2, argc, argv);
3748 return cfs_parser(argc, argv, udsp_cmds);
3751 static int jt_import(int argc, char **argv)
3754 struct cYAML *err_rc = NULL;
3755 struct cYAML *show_rc = NULL;
3756 int rc = 0, return_rc = 0, opt, opt_found = 0;
3757 char *yaml_blk = NULL, *buf, cmd = 'a';
3758 bool release = true;
3763 const char *const short_options = "adseh";
3764 static const struct option long_options[] = {
3765 { .name = "add", .has_arg = no_argument, .val = 'a' },
3766 { .name = "del", .has_arg = no_argument, .val = 'd' },
3767 { .name = "show", .has_arg = no_argument, .val = 's' },
3768 { .name = "exec", .has_arg = no_argument, .val = 'e' },
3769 { .name = "help", .has_arg = no_argument, .val = 'h' },
3773 while ((opt = getopt_long(argc, argv, short_options,
3774 long_options, NULL)) != -1) {
3788 printf("import FILE\n"
3789 "import < FILE : import a file\n"
3790 "\t--add: add configuration\n"
3791 "\t--del: delete configuration\n"
3792 "\t--show: show configuration\n"
3793 "\t--exec: execute command\n"
3794 "\t--help: display this help\n"
3795 "If no command option is given then --add"
3796 " is assumed by default\n");
3803 /* grab the file name if one exists */
3804 if (opt_found && argc == 3)
3806 else if (!opt_found && argc == 2)
3809 /* file always takes precedence */
3811 /* Set a file input. */
3812 input = fopen(file, "rb");
3815 snprintf(err_str, sizeof(err_str),
3816 "cannot open '%s': %s", file,
3818 cYAML_build_error(-1, -1, "yaml", "builder",
3827 /* assume that we're getting our input from stdin */
3828 rc = fstat(fileno(input), &st);
3830 snprintf(err_str, sizeof(err_str),
3831 "cannot get file stats '%s': %s", file,
3833 cYAML_build_error(-1, -1, "yaml", "builder",
3839 yaml_blk = buf = malloc(st.st_size);
3842 snprintf(err_str, sizeof(err_str),
3843 "failed to allocate buffer: %s",
3845 cYAML_build_error(-1, -1, "yaml", "builder",
3852 while (fgets(buf, len, input) != NULL) {
3853 char *seq = strstr(buf, "- ");
3859 skip = strspn(seq, " ");
3864 /* PyYAML format has libyaml free the
3875 rc = lustre_yaml_config(yaml_blk, st.st_size, &err_rc);
3876 return_rc = lustre_yaml_exec(yaml_blk, st.st_size, &show_rc,
3878 cYAML_print_tree(show_rc);
3879 cYAML_free_tree(show_rc);
3882 rc = lustre_yaml_del(yaml_blk, st.st_size, &err_rc);
3885 rc = lustre_yaml_show(yaml_blk, st.st_size, &show_rc,
3887 cYAML_print_tree(show_rc);
3888 cYAML_free_tree(show_rc);
3891 rc = lustre_yaml_exec(yaml_blk, st.st_size, &show_rc,
3893 cYAML_print_tree(show_rc);
3894 cYAML_free_tree(show_rc);
3898 if (yaml_blk && release)
3900 if (rc || return_rc) {
3901 cYAML_print_tree2file(stderr, err_rc);
3902 cYAML_free_tree(err_rc);
3908 static int jt_export(int argc, char **argv)
3910 struct cYAML *show_rc = NULL;
3911 struct cYAML *err_rc = NULL;
3915 bool backup = false;
3918 const char *const short_options = "bh";
3919 static const struct option long_options[] = {
3920 { .name = "backup", .has_arg = no_argument, .val = 'b' },
3921 { .name = "help", .has_arg = no_argument, .val = 'h' },
3924 while ((opt = getopt_long(argc, argv, short_options,
3925 long_options, NULL)) != -1) {
3932 printf("export > FILE.yaml : export configuration\n"
3933 "\t--backup: export only what's necessary for reconfig\n"
3934 "\t--help: display this help\n");
3939 if (backup && argc >= 3)
3941 else if (!backup && argc >= 2)
3947 f = fopen(file, "w");
3952 rc = lustre_lnet_show_net(NULL, 2, -1, &show_rc, &err_rc, backup);
3953 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3954 cYAML_print_tree2file(stderr, err_rc);
3955 cYAML_free_tree(err_rc);
3959 rc = lustre_lnet_show_route(NULL, NULL, -1, -1, 1, -1, &show_rc,
3961 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3962 cYAML_print_tree2file(stderr, err_rc);
3963 cYAML_free_tree(err_rc);
3967 rc = lustre_lnet_show_routing(-1, &show_rc, &err_rc, backup);
3968 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3969 cYAML_print_tree2file(stderr, err_rc);
3970 cYAML_free_tree(err_rc);
3974 rc = lustre_lnet_show_peer(NULL, 2, -1, &show_rc, &err_rc, backup);
3975 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3976 cYAML_print_tree2file(stderr, err_rc);
3977 cYAML_free_tree(err_rc);
3981 rc = lustre_lnet_show_numa_range(-1, &show_rc, &err_rc);
3982 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3983 cYAML_print_tree2file(stderr, err_rc);
3984 cYAML_free_tree(err_rc);
3988 rc = lustre_lnet_show_max_intf(-1, &show_rc, &err_rc);
3989 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3990 cYAML_print_tree2file(stderr, err_rc);
3991 cYAML_free_tree(err_rc);
3995 rc = lustre_lnet_show_discovery(-1, &show_rc, &err_rc);
3996 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3997 cYAML_print_tree2file(stderr, err_rc);
3998 cYAML_free_tree(err_rc);
4002 rc = lustre_lnet_show_drop_asym_route(-1, &show_rc, &err_rc);
4003 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4004 cYAML_print_tree2file(stderr, err_rc);
4005 cYAML_free_tree(err_rc);
4009 rc = lustre_lnet_show_retry_count(-1, &show_rc, &err_rc);
4010 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4011 cYAML_print_tree2file(stderr, err_rc);
4015 rc = lustre_lnet_show_transaction_to(-1, &show_rc, &err_rc);
4016 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4017 cYAML_print_tree2file(stderr, err_rc);
4021 rc = lustre_lnet_show_hsensitivity(-1, &show_rc, &err_rc);
4022 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4023 cYAML_print_tree2file(stderr, err_rc);
4027 rc = lustre_lnet_show_recov_intrv(-1, &show_rc, &err_rc);
4028 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4029 cYAML_print_tree2file(stderr, err_rc);
4033 rc = lustre_lnet_show_rtr_sensitivity(-1, &show_rc, &err_rc);
4034 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4035 cYAML_print_tree2file(stderr, err_rc);
4039 rc = lustre_lnet_show_lnd_timeout(-1, &show_rc, &err_rc);
4040 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4041 cYAML_print_tree2file(stderr, err_rc);
4045 rc = lustre_lnet_show_response_tracking(-1, &show_rc, &err_rc);
4046 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4047 cYAML_print_tree2file(stderr, err_rc);
4048 cYAML_free_tree(err_rc);
4052 rc = lustre_lnet_show_recovery_limit(-1, &show_rc, &err_rc);
4053 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4054 cYAML_print_tree2file(stderr, err_rc);
4055 cYAML_free_tree(err_rc);
4059 rc = lustre_lnet_show_max_recovery_ping_interval(-1, &show_rc, &err_rc);
4060 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4061 cYAML_print_tree2file(stderr, err_rc);
4062 cYAML_free_tree(err_rc);
4066 rc = lustre_lnet_show_udsp(-1, -1, &show_rc, &err_rc);
4067 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4068 cYAML_print_tree2file(stderr, err_rc);
4069 cYAML_free_tree(err_rc);
4073 if (show_rc != NULL) {
4074 cYAML_print_tree2file(f, show_rc);
4075 cYAML_free_tree(show_rc);
4084 static int jt_peer_nid_common(int argc, char **argv, int cmd)
4086 int flags = cmd == LNETCTL_ADD_CMD ? NLM_F_CREATE : 0;
4087 int rc = LUSTRE_CFG_RC_NO_ERR, opt;
4089 char *prim_nid = NULL, *nidstr = NULL;
4090 char err_str[LNET_MAX_STR_LEN] = "Error";
4091 struct cYAML *err_rc = NULL;
4093 const char *const short_opts = "k:m:n:f:l";
4094 const struct option long_opts[] = {
4095 { .name = "prim_nid", .has_arg = required_argument, .val = 'k' },
4096 { .name = "non_mr", .has_arg = no_argument, .val = 'm' },
4097 { .name = "nid", .has_arg = required_argument, .val = 'n' },
4098 { .name = "force", .has_arg = no_argument, .val = 'f' },
4099 { .name = "lock_prim", .has_arg = no_argument, .val = 'l' },
4102 rc = check_cmd(peer_cmds, "peer",
4103 cmd == LNETCTL_ADD_CMD ? "add" : "del", 2, argc, argv);
4107 while ((opt = getopt_long(argc, argv, short_opts,
4108 long_opts, NULL)) != -1) {
4117 if (cmd == LNETCTL_DEL_CMD) {
4118 rc = LUSTRE_CFG_RC_BAD_PARAM;
4119 snprintf(err_str, LNET_MAX_STR_LEN,
4120 "Unrecognized option '-%c'", opt);
4126 if (cmd == LNETCTL_ADD_CMD) {
4127 rc = LUSTRE_CFG_RC_BAD_PARAM;
4128 snprintf(err_str, LNET_MAX_STR_LEN,
4129 "Unrecognized option '-%c'", opt);
4132 flags |= NLM_F_EXCL;
4135 if (cmd == LNETCTL_DEL_CMD) {
4136 rc = LUSTRE_CFG_RC_BAD_PARAM;
4137 snprintf(err_str, LNET_MAX_STR_LEN,
4138 "Unrecognized option '-%c'", opt);
4141 flags |= NLM_F_EXCL;
4144 print_help(peer_cmds, "peer",
4145 cmd == LNETCTL_ADD_CMD ? "add" : "del");
4151 rc = yaml_lnet_peer(prim_nid, nidstr, !is_mr, -1, -1, false,
4152 LNET_GENL_VERSION, flags);
4154 if (rc == -EOPNOTSUPP)
4159 rc = lustre_lnet_modify_peer(prim_nid, nidstr, is_mr, cmd,
4160 force_lock, -1, &err_rc);
4161 if (rc != LUSTRE_CFG_RC_NO_ERR)
4165 cYAML_build_error(rc, -1, "peer",
4166 cmd == LNETCTL_ADD_CMD ? "add" : "del",
4170 if (rc != LUSTRE_CFG_RC_NO_ERR)
4171 cYAML_print_tree2file(stderr, err_rc);
4173 cYAML_free_tree(err_rc);
4178 static int jt_add_peer_nid(int argc, char **argv)
4180 return jt_peer_nid_common(argc, argv, LNETCTL_ADD_CMD);
4183 static int jt_del_peer_nid(int argc, char **argv)
4185 return jt_peer_nid_common(argc, argv, LNETCTL_DEL_CMD);
4188 static int jt_show_peer(int argc, char **argv)
4192 struct cYAML *err_rc = NULL, *show_rc = NULL;
4193 long int detail = 0;
4194 const char *const short_opts = "hn:v::";
4195 const struct option long_opts[] = {
4196 { .name = "help", .has_arg = no_argument, .val = 'h' },
4197 { .name = "nid", .has_arg = required_argument, .val = 'n' },
4198 { .name = "verbose", .has_arg = optional_argument, .val = 'v' },
4202 rc = check_cmd(peer_cmds, "peer", "show", 1, argc, argv);
4206 while ((opt = getopt_long(argc, argv, short_opts,
4207 long_opts, NULL)) != -1) {
4213 if ((!optarg) && (argv[optind] != NULL) &&
4214 (argv[optind][0] != '-')) {
4215 if (parse_long(argv[optind++], &detail) != 0)
4222 print_help(peer_cmds, "peer", "show");
4228 rc = yaml_lnet_peer(nid, NULL, false, -1, -1, false, detail,
4231 if (rc == -EOPNOTSUPP)
4236 rc = lustre_lnet_show_peer(nid, (int) detail, -1, &show_rc, &err_rc,
4239 if (rc != LUSTRE_CFG_RC_NO_ERR)
4240 cYAML_print_tree2file(stderr, err_rc);
4242 cYAML_print_tree(show_rc);
4244 cYAML_free_tree(err_rc);
4245 cYAML_free_tree(show_rc);
4250 static int jt_list_peer(int argc, char **argv)
4252 struct cYAML *err_rc = NULL, *list_rc = NULL;
4255 rc = check_cmd(peer_cmds, "peer", "list", 0, argc, argv);
4259 rc = yaml_lnet_peer(NULL, NULL, false, -1, -1, true, 0, NLM_F_DUMP);
4261 if (rc == -EOPNOTSUPP)
4267 rc = lustre_lnet_list_peer(-1, &list_rc, &err_rc);
4268 if (rc != LUSTRE_CFG_RC_NO_ERR)
4269 cYAML_print_tree2file(stderr, err_rc);
4271 cYAML_print_tree(list_rc);
4273 cYAML_free_tree(err_rc);
4274 cYAML_free_tree(list_rc);
4279 static int yaml_lnet_ping_display(yaml_parser_t *reply)
4281 yaml_emitter_t debug;
4286 rc = yaml_emitter_initialize(&debug);
4288 yaml_emitter_set_output_file(&debug, stdout);
4295 rc = yaml_parser_parse(reply, &event);
4297 goto report_reply_error;
4299 if (event.type != YAML_SCALAR_EVENT) {
4300 rc = yaml_emitter_emit(&debug, &event);
4304 done = (event.type == YAML_DOCUMENT_END_EVENT);
4308 if (strcmp((char *)event.data.scalar.value, "errno") == 0) {
4309 rc = yaml_emitter_emit(&debug, &event);
4313 rc = yaml_parser_parse(reply, &event);
4315 goto report_reply_error;
4317 rc = parse_long((char *)event.data.scalar.value,
4320 goto report_reply_error;
4322 rc = yaml_emitter_emit(&debug, &event);
4327 } else if (error != 0 &&
4328 strcmp((char *)event.data.scalar.value,
4330 rc = yaml_emitter_emit(&debug, &event);
4334 rc = yaml_parser_parse(reply, &event);
4336 goto report_reply_error;
4338 if (strncmp((char *)event.data.scalar.value,
4339 "failed to ", strlen("failed to ")) == 0) {
4342 snprintf(err, sizeof(err), "%s: %s",
4343 (char *)event.data.scalar.value,
4345 yaml_scalar_event_initialize(&event, NULL,
4346 (yaml_char_t *)YAML_STR_TAG,
4349 YAML_PLAIN_SCALAR_STYLE);
4351 rc = yaml_emitter_emit(&debug, &event);
4357 rc = yaml_emitter_emit(&debug, &event);
4364 yaml_emitter_log_error(&debug, stderr);
4366 yaml_emitter_delete(&debug);
4368 return rc2 ? rc2 : rc;
4371 static int yaml_lnet_ping(char *group, int timeout, char *src_nidstr,
4372 int start, int end, char **nids, int flags)
4374 struct nl_sock *sk = NULL;
4375 const char *msg = NULL;
4376 yaml_emitter_t output;
4377 yaml_parser_t reply;
4381 /* Create Netlink emitter to send request to kernel */
4382 sk = nl_socket_alloc();
4386 /* Setup parser to receive Netlink packets */
4387 rc = yaml_parser_initialize(&reply);
4393 rc = yaml_parser_set_input_netlink(&reply, sk, false);
4395 msg = yaml_parser_get_reader_error(&reply);
4399 /* Create Netlink emitter to send request to kernel */
4400 rc = yaml_emitter_initialize(&output);
4402 msg = "failed to initialize emitter";
4406 rc = yaml_emitter_set_output_netlink(&output, sk, LNET_GENL_NAME,
4407 LNET_GENL_VERSION, LNET_CMD_PING,
4412 yaml_emitter_open(&output);
4413 yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
4414 rc = yaml_emitter_emit(&output, &event);
4418 yaml_mapping_start_event_initialize(&event, NULL,
4419 (yaml_char_t *)YAML_MAP_TAG,
4420 1, YAML_ANY_MAPPING_STYLE);
4421 rc = yaml_emitter_emit(&output, &event);
4425 yaml_scalar_event_initialize(&event, NULL,
4426 (yaml_char_t *)YAML_STR_TAG,
4427 (yaml_char_t *)group,
4428 strlen(group), 1, 0,
4429 YAML_PLAIN_SCALAR_STYLE);
4430 rc = yaml_emitter_emit(&output, &event);
4434 yaml_mapping_start_event_initialize(&event, NULL,
4435 (yaml_char_t *)YAML_MAP_TAG,
4436 1, YAML_ANY_MAPPING_STYLE);
4437 rc = yaml_emitter_emit(&output, &event);
4441 if (timeout != 1000 || src_nidstr) {
4443 yaml_scalar_event_initialize(&event, NULL,
4444 (yaml_char_t *)YAML_STR_TAG,
4445 (yaml_char_t *)"source",
4446 strlen("source"), 1, 0,
4447 YAML_PLAIN_SCALAR_STYLE);
4448 rc = yaml_emitter_emit(&output, &event);
4452 yaml_scalar_event_initialize(&event, NULL,
4453 (yaml_char_t *)YAML_STR_TAG,
4454 (yaml_char_t *)src_nidstr,
4455 strlen(src_nidstr), 1, 0,
4456 YAML_PLAIN_SCALAR_STYLE);
4457 rc = yaml_emitter_emit(&output, &event);
4462 if (timeout != 1000) {
4465 yaml_scalar_event_initialize(&event, NULL,
4466 (yaml_char_t *)YAML_STR_TAG,
4467 (yaml_char_t *)"timeout",
4468 strlen("timeout"), 1, 0,
4469 YAML_PLAIN_SCALAR_STYLE);
4470 rc = yaml_emitter_emit(&output, &event);
4474 snprintf(time, sizeof(time), "%u", timeout);
4475 yaml_scalar_event_initialize(&event, NULL,
4476 (yaml_char_t *)YAML_INT_TAG,
4477 (yaml_char_t *)time,
4479 YAML_PLAIN_SCALAR_STYLE);
4480 rc = yaml_emitter_emit(&output, &event);
4486 yaml_scalar_event_initialize(&event, NULL,
4487 (yaml_char_t *)YAML_STR_TAG,
4488 (yaml_char_t *)"nids",
4489 strlen("nids"), 1, 0,
4490 YAML_PLAIN_SCALAR_STYLE);
4491 rc = yaml_emitter_emit(&output, &event);
4495 yaml_sequence_start_event_initialize(&event, NULL,
4496 (yaml_char_t *)YAML_SEQ_TAG,
4497 1, YAML_FLOW_SEQUENCE_STYLE);
4498 rc = yaml_emitter_emit(&output, &event);
4502 for (i = start; i < end; i++) {
4503 yaml_scalar_event_initialize(&event, NULL,
4504 (yaml_char_t *)YAML_STR_TAG,
4505 (yaml_char_t *)nids[i],
4506 strlen(nids[i]), 1, 0,
4507 YAML_PLAIN_SCALAR_STYLE);
4508 rc = yaml_emitter_emit(&output, &event);
4513 yaml_sequence_end_event_initialize(&event);
4514 rc = yaml_emitter_emit(&output, &event);
4518 yaml_mapping_end_event_initialize(&event);
4519 rc = yaml_emitter_emit(&output, &event);
4523 yaml_mapping_end_event_initialize(&event);
4524 rc = yaml_emitter_emit(&output, &event);
4528 yaml_document_end_event_initialize(&event, 0);
4529 rc = yaml_emitter_emit(&output, &event);
4533 rc = yaml_emitter_close(&output);
4536 yaml_emitter_log_error(&output, stderr);
4539 rc = yaml_lnet_ping_display(&reply);
4541 msg = yaml_parser_get_reader_error(&reply);
4543 yaml_emitter_delete(&output);
4546 yaml_lnet_print_error(-1, group, msg);
4550 yaml_parser_delete(&reply);
4553 return rc == 1 ? 0 : rc;
4556 static int jt_ping(int argc, char **argv)
4558 struct cYAML *err_rc = NULL;
4559 struct cYAML *show_rc = NULL;
4562 char *src_nidstr = NULL;
4563 const char *const short_options = "hs:t:";
4564 const struct option long_options[] = {
4565 { .name = "help", .has_arg = no_argument, .val = 'h' },
4566 { .name = "timeout", .has_arg = required_argument, .val = 't' },
4567 { .name = "source", .has_arg = required_argument, .val = 's' },
4571 while ((opt = getopt_long(argc, argv, short_options,
4572 long_options, NULL)) != -1) {
4575 src_nidstr = optarg;
4578 timeout = 1000 * atol(optarg);
4581 printf("ping nid[,nid,...]\n"
4582 "\t --source: source nid\n"
4583 "\t --timeout: ping timeout\n"
4584 "\t --help: display this help\n");
4591 rc = yaml_lnet_ping("ping", timeout, src_nidstr, optind, argc,
4594 if (rc != -EOPNOTSUPP)
4598 for (; optind < argc; optind++)
4599 rc = lustre_lnet_ping_nid(argv[optind], src_nidstr, timeout, -1,
4603 cYAML_print_tree(show_rc);
4606 cYAML_print_tree2file(stderr, err_rc);
4608 cYAML_free_tree(err_rc);
4609 cYAML_free_tree(show_rc);
4614 static int jt_discover(int argc, char **argv)
4616 struct cYAML *err_rc = NULL;
4617 struct cYAML *show_rc = NULL;
4618 int flags = NLM_F_CREATE;
4621 const char *const short_options = "fh";
4622 const struct option long_options[] = {
4623 { .name = "force", .has_arg = no_argument, .val = 'f' },
4624 { .name = "help", .has_arg = no_argument, .val = 'h' },
4628 while ((opt = getopt_long(argc, argv, short_options,
4629 long_options, NULL)) != -1) {
4632 /* BSD treats NLM_F_CREATE | NLM_F_EXCL as an add */
4633 flags |= NLM_F_EXCL;
4637 printf("discover nid[,nid,...]\n"
4638 "\t --force: force discovery\n"
4639 "\t --help: display this help\n");
4646 if (optind == argc) {
4647 printf("Missing nid argument\n");
4651 rc = yaml_lnet_ping("discover", 1000, NULL, optind, argc, argv,
4654 if (rc != -EOPNOTSUPP)
4658 for (; optind < argc; optind++)
4659 rc = lustre_lnet_discover_nid(argv[optind], force, -1, &show_rc,
4663 cYAML_print_tree(show_rc);
4666 cYAML_print_tree2file(stderr, err_rc);
4668 cYAML_free_tree(err_rc);
4669 cYAML_free_tree(show_rc);
4674 static int jt_add_udsp(int argc, char **argv)
4676 char *src = NULL, *dst = NULL, *rte = NULL;
4677 struct cYAML *err_rc = NULL;
4678 union lnet_udsp_action udsp_action;
4679 long int idx = -1, priority = -1;
4681 char *action_type = "pref";
4683 const char *const short_options = "s:d:r:p:i:";
4684 static const struct option long_options[] = {
4685 { .name = "src", .has_arg = required_argument, .val = 's' },
4686 { .name = "dst", .has_arg = required_argument, .val = 'd' },
4687 { .name = "rte", .has_arg = required_argument, .val = 'r' },
4688 { .name = "priority", .has_arg = required_argument, .val = 'p' },
4689 { .name = "idx", .has_arg = required_argument, .val = 'i' },
4692 rc = check_cmd(udsp_cmds, "udsp", "add", 0, argc, argv);
4696 while ((opt = getopt_long(argc, argv, short_options,
4697 long_options, NULL)) != -1) {
4709 rc = parse_long(optarg, &priority);
4710 if (rc != 0 || priority < 0) {
4711 printf("Invalid priority \"%s\"\n", optarg);
4714 action_type = "priority";
4715 udsp_action.udsp_priority = priority;
4718 rc = parse_long(optarg, &idx);
4719 if (rc != 0 || idx < 0) {
4720 printf("Invalid index \"%s\"\n", optarg);
4725 print_help(udsp_cmds, "udsp", "add");
4731 if (!(src || dst || rte)) {
4732 print_help(udsp_cmds, "udsp", "add");
4736 rc = lustre_lnet_add_udsp(src, dst, rte, action_type, &udsp_action,
4739 if (rc != LUSTRE_CFG_RC_NO_ERR)
4740 cYAML_print_tree2file(stderr, err_rc);
4742 cYAML_free_tree(err_rc);
4747 static int jt_del_udsp(int argc, char **argv)
4749 struct cYAML *err_rc = NULL;
4754 const char *const short_options = "ai:";
4755 static const struct option long_options[] = {
4756 { .name = "all", .has_arg = no_argument, .val = 'a' },
4757 { .name = "idx", .has_arg = required_argument, .val = 'i' },
4760 rc = check_cmd(udsp_cmds, "udsp", "del", 0, argc, argv);
4764 while ((opt = getopt_long(argc, argv, short_options,
4765 long_options, NULL)) != -1) {
4771 rc = parse_long(optarg, &idx);
4772 if (rc != 0 || idx < -1) {
4773 printf("Invalid index \"%s\"\n", optarg);
4778 print_help(udsp_cmds, "udsp", "del");
4784 if (all && idx != -2) {
4785 printf("Cannot combine --all with --idx\n");
4789 } else if (idx == -2) {
4790 printf("Must specify --idx or --all\n");
4794 rc = lustre_lnet_del_udsp(idx, -1, &err_rc);
4795 if (rc != LUSTRE_CFG_RC_NO_ERR)
4796 cYAML_print_tree2file(stderr, err_rc);
4798 cYAML_free_tree(err_rc);
4803 int main(int argc, char **argv)
4806 struct cYAML *err_rc = NULL;
4808 rc = lustre_lnet_config_lib_init();
4810 cYAML_build_error(-1, -1, "lnetctl", "startup",
4811 "cannot register LNet device", &err_rc);
4812 cYAML_print_tree2file(stderr, err_rc);
4816 return cfs_parser(argc, argv, cmd_list);