4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as
8 * published by the Free Software Foundation; either version 2.1 of the
9 * License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
21 * Copyright (c) 2014, 2017, Intel Corporation.
24 * Amir Shehata <amir.shehata@intel.com>
32 #include <libcfs/util/ioctl.h>
33 #include <libcfs/util/parser.h>
34 #include "lnetconfig/cyaml.h"
35 #include "lnetconfig/liblnetconfig.h"
37 #define LNET_CONFIGURE true
38 #define LNET_UNCONFIGURE false
40 static int jt_config_lnet(int argc, char **argv);
41 static int jt_unconfig_lnet(int argc, char **argv);
42 static int jt_add_route(int argc, char **argv);
43 static int jt_add_ni(int argc, char **argv);
44 static int jt_set_routing(int argc, char **argv);
45 static int jt_del_route(int argc, char **argv);
46 static int jt_del_ni(int argc, char **argv);
47 static int jt_show_route(int argc, char **argv);
48 static int jt_show_net(int argc, char **argv);
49 static int jt_show_routing(int argc, char **argv);
50 static int jt_show_stats(int argc, char **argv);
51 static int jt_show_peer(int argc, char **argv);
52 static int jt_show_recovery(int argc, char **argv);
53 static int jt_show_global(int argc, char **argv);
54 static int jt_show_udsp(int argc, char **argv);
55 static int jt_set_tiny(int argc, char **argv);
56 static int jt_set_small(int argc, char **argv);
57 static int jt_set_large(int argc, char **argv);
58 static int jt_set_numa(int argc, char **argv);
59 static int jt_set_retry_count(int argc, char **argv);
60 static int jt_set_transaction_to(int argc, char **argv);
61 static int jt_set_recov_intrv(int argc, char **argv);
62 static int jt_set_rtr_sensitivity(int argc, char **argv);
63 static int jt_set_hsensitivity(int argc, char **argv);
64 static int jt_set_max_recovery_ping_interval(int argc, char **argv);
65 static int jt_reset_stats(int argc, char **argv);
66 static int jt_add_peer_nid(int argc, char **argv);
67 static int jt_del_peer_nid(int argc, char **argv);
68 static int jt_set_max_intf(int argc, char **argv);
69 static int jt_set_discovery(int argc, char **argv);
70 static int jt_set_drop_asym_route(int argc, char **argv);
71 static int jt_list_peer(int argc, char **argv);
72 static int jt_add_udsp(int argc, char **argv);
73 static int jt_del_udsp(int argc, char **argv);
74 /*static int jt_show_peer(int argc, char **argv);*/
75 static int jt_import(int argc, char **argv);
76 static int jt_export(int argc, char **argv);
77 static int jt_ping(int argc, char **argv);
78 static int jt_discover(int argc, char **argv);
79 static int jt_lnet(int argc, char **argv);
80 static int jt_route(int argc, char **argv);
81 static int jt_net(int argc, char **argv);
82 static int jt_routing(int argc, char **argv);
83 static int jt_set(int argc, char **argv);
84 static int jt_debug(int argc, char **argv);
85 static int jt_stats(int argc, char **argv);
86 static int jt_global(int argc, char **argv);
87 static int jt_peers(int argc, char **argv);
88 static int jt_set_ni_value(int argc, char **argv);
89 static int jt_set_peer_ni_value(int argc, char **argv);
90 static int jt_calc_service_id(int argc, char **argv);
91 static int jt_set_response_tracking(int argc, char **argv);
92 static int jt_set_recovery_limit(int argc, char **argv);
93 static int jt_udsp(int argc, char **argv);
94 static int jt_setup_mrrouting(int argc, char **argv);
95 static int jt_calc_cpt_of_nid(int argc, char **argv);
96 static int jt_show_peer_debug_info(int argc, char **argv);
98 command_t cmd_list[] = {
99 {"lnet", jt_lnet, 0, "lnet {configure | unconfigure} [--all]"},
100 {"route", jt_route, 0, "route {add | del | show | help}"},
101 {"net", jt_net, 0, "net {add | del | show | set | help}"},
102 {"routing", jt_routing, 0, "routing {show | help}"},
103 {"set", jt_set, 0, "set {tiny_buffers | small_buffers | large_buffers"
104 " | routing | numa_range | max_interfaces"
105 " | discovery | drop_asym_route | retry_count"
106 " | transaction_timeout | health_sensitivity"
107 " | recovery_interval | router_sensitivity"
108 " | response_tracking | recovery_limit}"},
109 {"import", jt_import, 0, "import FILE.yaml"},
110 {"export", jt_export, 0, "export FILE.yaml"},
111 {"stats", jt_stats, 0, "stats {show | help}"},
112 {"debug", jt_debug, 0, "debug {recovery {local | peer} | peer}"},
113 {"global", jt_global, 0, "global {show | help}"},
114 {"peer", jt_peers, 0, "peer {add | del | show | list | set | help}"},
115 {"ping", jt_ping, 0, "ping nid,[nid,...]"},
116 {"discover", jt_discover, 0, "discover nid[,nid,...]"},
117 {"service-id", jt_calc_service_id, 0, "Calculate IB Lustre service ID\n"},
118 {"udsp", jt_udsp, 0, "udsp {add | del | help}"},
119 {"setup-mrrouting", jt_setup_mrrouting, 0,
120 "setup linux routing tables\n"},
121 {"cpt-of-nid", jt_calc_cpt_of_nid, 0,
122 "Calculate the CPTs associated with NIDs\n"
123 " usage:\n\tlnetctl cpt-of-nid nid[ nid ...]\n"},
127 command_t lnet_cmds[] = {
128 {"configure", jt_config_lnet, 0, "configure lnet\n"
129 "\t--all: load NI configuration from module parameters\n"},
130 {"unconfigure", jt_unconfig_lnet, 0, "unconfigure lnet\n"},
134 command_t route_cmds[] = {
135 {"add", jt_add_route, 0, "add a route\n"
136 "\t--net: net name (e.g. tcp0)\n"
137 "\t--gateway: gateway nid (e.g. 10.1.1.2@tcp)\n"
138 "\t--hop|hop-count: number to final destination (1 <= hops <= 255)\n"
139 "\t--priority: priority of route (0 - highest prio\n"
140 "\t--health_sensitivity: gateway health sensitivity (>= 1)\n"},
141 {"del", jt_del_route, 0, "delete a route\n"
142 "\t--net: net name (e.g. tcp0)\n"
143 "\t--gateway: gateway nid (e.g. 10.1.1.2@tcp)\n"},
144 {"show", jt_show_route, 0, "show routes\n"
145 "\t--net: net name (e.g. tcp0) to filter on\n"
146 "\t--gateway: gateway nid (e.g. 10.1.1.2@tcp) to filter on\n"
147 "\t--hop|hop-count: number to final destination (1 <= hops <= 255) to filter on\n"
148 "\t--priority: priority of route (0 - highest prio to filter on\n"
149 "\t--verbose: display detailed output per route\n"},
153 command_t net_cmds[] = {
154 {"add", jt_add_ni, 0, "add a network\n"
155 "\t--net: net name (e.g. tcp0)\n"
156 "\t--if: physical interface (e.g. eth0)\n"
157 "\t--ip2net: specify networks based on IP address patterns\n"
158 "\t--peer-timeout: time to wait before declaring a peer dead\n"
159 "\t--peer-credits: define the max number of inflight messages\n"
160 "\t--peer-buffer-credits: the number of buffer credits per peer\n"
161 "\t--credits: Network Interface credits\n"
162 "\t--cpt: CPU Partitions configured net uses (e.g. [0,1]\n"
163 "\t--conns-per-peer: number of connections per peer\n"
164 "\t--skip-mr-route-setup: do not add linux route for the ni\n"
165 "\t--auth-key: Network authorization key (kfilnd only)\n"
166 "\t--traffic-class: Traffic class (kfilnd only)\n"},
167 {"del", jt_del_ni, 0, "delete a network\n"
168 "\t--net: net name (e.g. tcp0)\n"
169 "\t--if: physical interface (e.g. eth0)\n"},
170 {"show", jt_show_net, 0, "show networks\n"
171 "\t--net: net name (e.g. tcp0) to filter on\n"
172 "\t--verbose: display detailed output per network."
173 " Optional argument of '2' outputs more stats\n"},
174 {"set", jt_set_ni_value, 0, "set local NI specific parameter\n"
175 "\t--nid: NI NID to set the\n"
176 "\t--health: specify health value to set\n"
177 "\t--conns-per-peer: number of connections per peer\n"
178 "\t--all: set all NIs value to the one specified\n"},
182 command_t routing_cmds[] = {
183 {"show", jt_show_routing, 0, "show routing information\n"},
187 command_t stats_cmds[] = {
188 {"show", jt_show_stats, 0, "show LNET statistics\n"},
189 {"reset", jt_reset_stats, 0, "reset LNET statistics\n"},
193 command_t debug_cmds[] = {
194 {"recovery", jt_show_recovery, 0, "list recovery queues\n"
195 "\t--local : list local recovery queue\n"
196 "\t--peer : list peer recovery queue\n"},
197 {"peer", jt_show_peer_debug_info, 0, "show peer debug info\n"
198 "\t--nid: peer's NID\n"},
202 command_t global_cmds[] = {
203 {"show", jt_show_global, 0, "show global variables\n"},
207 command_t set_cmds[] = {
208 {"tiny_buffers", jt_set_tiny, 0, "set tiny routing buffers\n"
209 "\tVALUE must be greater than 0\n"},
210 {"small_buffers", jt_set_small, 0, "set small routing buffers\n"
211 "\tVALUE must be greater than 0\n"},
212 {"large_buffers", jt_set_large, 0, "set large routing buffers\n"
213 "\tVALUE must be greater than 0\n"},
214 {"routing", jt_set_routing, 0, "enable/disable routing\n"
215 "\t0 - disable routing\n"
216 "\t1 - enable routing\n"},
217 {"numa_range", jt_set_numa, 0, "set NUMA range for NI selection\n"
218 "\tVALUE must be at least 0\n"},
219 {"max_interfaces", jt_set_max_intf, 0, "set the default value for "
221 "\tValue must be greater than 16\n"},
222 {"discovery", jt_set_discovery, 0, "enable/disable peer discovery\n"
223 "\t0 - disable peer discovery\n"
224 "\t1 - enable peer discovery (default)\n"},
225 {"drop_asym_route", jt_set_drop_asym_route, 0,
226 "drop/accept asymmetrical route messages\n"
227 "\t0 - accept asymmetrical route messages (default)\n"
228 "\t1 - drop asymmetrical route messages\n"},
229 {"retry_count", jt_set_retry_count, 0, "number of retries\n"
230 "\t0 - turn of retries\n"
231 "\t>0 - number of retries\n"},
232 {"transaction_timeout", jt_set_transaction_to, 0, "Message/Response timeout\n"
233 "\t>0 - timeout in seconds\n"},
234 {"health_sensitivity", jt_set_hsensitivity, 0, "sensitivity to failure\n"
235 "\t0 - turn off health evaluation\n"
236 "\t>0 - sensitivity value not more than 1000\n"},
237 {"recovery_interval", jt_set_recov_intrv, 0, "interval to ping in seconds (at least 1)\n"
238 "\t>0 - time in seconds between pings\n"},
239 {"router_sensitivity", jt_set_rtr_sensitivity, 0, "router sensitivity %\n"
240 "\t100 - router interfaces need to be fully healthy to be used\n"
241 "\t<100 - router interfaces can be used even if not healthy\n"},
242 {"response_tracking", jt_set_response_tracking, 0,
243 "Set the behavior of response tracking\n"
244 "\t0 - Only LNet pings and discovery pushes utilize response tracking\n"
245 "\t1 - GETs are eligible for response tracking\n"
246 "\t2 - PUTs are eligible for response tracking\n"
247 "\t3 - Both PUTs and GETs are eligible for response tracking (default)\n"
248 "\tNote: Regardless of the value of the response_tracking parameter LNet\n"
249 "\t pings and discovery pushes always utilize response tracking\n"},
250 {"recovery_limit", jt_set_recovery_limit, 0,
251 "Set how long LNet will attempt to recover unhealthy interfaces.\n"
252 "\t0 - Recover indefinitely (default)\n"
253 "\t>0 - Recover for the specified number of seconds.\n"},
254 {"max_recovery_ping_interval", jt_set_max_recovery_ping_interval, 0,
255 "maximum recovery ping interval\n"
256 "\t>0 - maximum recovery ping interval in seconds\n"},
260 command_t peer_cmds[] = {
261 {"add", jt_add_peer_nid, 0, "add a peer NID\n"
262 "\t--prim_nid: Primary NID of the peer.\n"
263 "\t--nid: one or more peer NIDs\n"
264 "\t--non_mr: create this peer as not Multi-Rail capable\n"
265 "\t--ip2nets: specify a range of nids per peer\n"
266 "\t--lock_prim: lock primary nid\n"},
267 {"del", jt_del_peer_nid, 0, "delete a peer NID\n"
268 "\t--prim_nid: Primary NID of the peer.\n"
269 "\t--nid: list of NIDs to remove. If none provided,\n"
270 "\t peer is deleted\n"
271 "\t--ip2nets: specify a range of nids per peer\n"
272 "\t--force: force-delete locked primary NID\n"},
273 {"show", jt_show_peer, 0, "show peer information\n"
274 "\t--nid: NID of peer to filter on.\n"
275 "\t--verbose: display detailed output per peer."
276 " Optional argument of '2' outputs more stats\n"},
277 {"list", jt_list_peer, 0, "list all peers\n"},
278 {"set", jt_set_peer_ni_value, 0, "set peer ni specific parameter\n"
279 "\t--nid: Peer NI NID to set the\n"
280 "\t--health: specify health value to set\n"
281 "\t--all: set all peer_nis values to the one specified\n"
282 "\t--state: set peer state (DANGEROUS: for test/debug only)"},
286 command_t udsp_cmds[] = {
287 {"add", jt_add_udsp, 0, "add a udsp\n"
288 "\t--src nid|net: ip2nets syntax specifying the local NID or network to match.\n"
289 "\t--dst nid: ip2nets syntax specifying the remote NID to match.\n"
290 "\t--rte nid: ip2nets syntax specifying the router NID to match.\n"
291 "\t--priority p: Assign priority value p where p >= 0.\n"
292 "\t Note: 0 is the highest priority.\n"
293 "\t--idx n: Insert the rule in the n'th position on the list of rules.\n"
294 "\t By default, rules are appended to the end of the rule list.\n"},
295 {"del", jt_del_udsp, 0, "delete a udsp\n"
296 "\t--all: Delete all rules.\n"
297 "\t--idx n: Delete the rule at index n.\n"},
298 {"show", jt_show_udsp, 0, "show udsps\n"
299 "\t--idx n: Show the rule at at index n.\n"
300 "\t By default, all rules are shown.\n"},
304 static int parse_long(const char *number, long int *value)
311 *value = strtol(number, &end, 0);
312 if (end != NULL && *end != 0)
318 static int jt_setup_mrrouting(int argc, char **argv)
321 struct cYAML *err_rc = NULL;
323 rc = lustre_lnet_setup_mrrouting(&err_rc);
325 if (rc != LUSTRE_CFG_RC_NO_ERR)
326 cYAML_print_tree2file(stderr, err_rc);
328 cYAML_free_tree(err_rc);
333 static inline void print_help(const command_t cmds[], const char *cmd_type,
336 const command_t *cmd;
338 for (cmd = cmds; cmd->pc_name; cmd++) {
339 if (pc_name != NULL &&
340 strcmp(cmd->pc_name, pc_name) == 0) {
341 printf("%s %s: %s\n", cmd_type, cmd->pc_name,
344 } else if (pc_name != NULL) {
347 printf("%s %s: %s\n", cmd_type, cmd->pc_name, cmd->pc_help);
351 static int check_cmd(const command_t *cmd_list, const char *cmd,
352 const char *sub_cmd, const int min_args,
353 int argc, char **argv)
360 const char *const short_options = "h";
361 static const struct option long_options[] = {
362 { .name = "help", .has_arg = no_argument, .val = 'h' },
366 if (argc < min_args) {
367 print_help(cmd_list, cmd, sub_cmd);
368 rc = LUSTRE_CFG_RC_BAD_PARAM;
370 } else if (argc > 2) {
374 while ((opt = getopt_long(argc, argv, short_options,
375 long_options, NULL)) != -1) {
378 print_help(cmd_list, cmd, sub_cmd);
393 static int jt_set_response_tracking(int argc, char **argv)
397 struct cYAML *err_rc = NULL;
399 rc = check_cmd(set_cmds, "set", "response_tracking", 2, argc, argv);
403 rc = parse_long(argv[1], &value);
405 cYAML_build_error(-1, -1, "parser", "set",
406 "cannot parse response_tracking value",
408 cYAML_print_tree2file(stderr, err_rc);
409 cYAML_free_tree(err_rc);
413 rc = lustre_lnet_config_response_tracking(value, -1, &err_rc);
414 if (rc != LUSTRE_CFG_RC_NO_ERR)
415 cYAML_print_tree2file(stderr, err_rc);
417 cYAML_free_tree(err_rc);
422 static int jt_calc_service_id(int argc, char **argv)
427 rc = lustre_lnet_calc_service_id(&service_id);
428 if (rc != LUSTRE_CFG_RC_NO_ERR)
431 /* cYAML currently doesn't support printing hex values.
432 * Therefore just print it locally here
434 printf("service_id:\n value: 0x%llx\n",
435 (unsigned long long)(service_id));
440 static int jt_set_recovery_limit(int argc, char **argv)
444 struct cYAML *err_rc = NULL;
446 rc = check_cmd(set_cmds, "set", "recovery_limit", 2, argc, argv);
450 rc = parse_long(argv[1], &value);
452 cYAML_build_error(-1, -1, "parser", "set",
453 "cannot parse recovery_limit value",
455 cYAML_print_tree2file(stderr, err_rc);
456 cYAML_free_tree(err_rc);
460 rc = lustre_lnet_config_recovery_limit(value, -1, &err_rc);
461 if (rc != LUSTRE_CFG_RC_NO_ERR)
462 cYAML_print_tree2file(stderr, err_rc);
464 cYAML_free_tree(err_rc);
469 static int jt_set_max_intf(int argc, char **argv)
473 struct cYAML *err_rc = NULL;
475 rc = check_cmd(set_cmds, "set", "max_interfaces", 2, argc, argv);
479 rc = parse_long(argv[1], &value);
481 cYAML_build_error(-1, -1, "parser", "set",
482 "cannot parse max_interfaces value", &err_rc);
483 cYAML_print_tree2file(stderr, err_rc);
484 cYAML_free_tree(err_rc);
488 rc = lustre_lnet_config_max_intf(value, -1, &err_rc);
489 if (rc != LUSTRE_CFG_RC_NO_ERR)
490 cYAML_print_tree2file(stderr, err_rc);
492 cYAML_free_tree(err_rc);
497 static int jt_set_numa(int argc, char **argv)
501 struct cYAML *err_rc = NULL;
503 rc = check_cmd(set_cmds, "set", "numa_range", 2, argc, argv);
507 rc = parse_long(argv[1], &value);
509 cYAML_build_error(-1, -1, "parser", "set",
510 "cannot parse numa_range value", &err_rc);
511 cYAML_print_tree2file(stderr, err_rc);
512 cYAML_free_tree(err_rc);
516 rc = lustre_lnet_config_numa_range(value, -1, &err_rc);
517 if (rc != LUSTRE_CFG_RC_NO_ERR)
518 cYAML_print_tree2file(stderr, err_rc);
520 cYAML_free_tree(err_rc);
525 static int jt_set_recov_intrv(int argc, char **argv)
529 struct cYAML *err_rc = NULL;
531 rc = check_cmd(set_cmds, "set", "recovery_interval", 2, argc, argv);
535 rc = parse_long(argv[1], &value);
537 cYAML_build_error(-1, -1, "parser", "set",
538 "cannot parse recovery interval value", &err_rc);
539 cYAML_print_tree2file(stderr, err_rc);
540 cYAML_free_tree(err_rc);
544 rc = lustre_lnet_config_recov_intrv(value, -1, &err_rc);
545 if (rc != LUSTRE_CFG_RC_NO_ERR)
546 cYAML_print_tree2file(stderr, err_rc);
548 cYAML_free_tree(err_rc);
553 static int jt_set_rtr_sensitivity(int argc, char **argv)
557 struct cYAML *err_rc = NULL;
559 rc = check_cmd(set_cmds, "set", "router_sensitivity", 2, argc, argv);
563 rc = parse_long(argv[1], &value);
565 cYAML_build_error(-1, -1, "parser", "set",
566 "cannot parse router sensitivity value", &err_rc);
567 cYAML_print_tree2file(stderr, err_rc);
568 cYAML_free_tree(err_rc);
572 rc = lustre_lnet_config_rtr_sensitivity(value, -1, &err_rc);
573 if (rc != LUSTRE_CFG_RC_NO_ERR)
574 cYAML_print_tree2file(stderr, err_rc);
576 cYAML_free_tree(err_rc);
581 static int jt_set_hsensitivity(int argc, char **argv)
585 struct cYAML *err_rc = NULL;
587 rc = check_cmd(set_cmds, "set", "health_sensitivity", 2, argc, argv);
591 rc = parse_long(argv[1], &value);
593 cYAML_build_error(-1, -1, "parser", "set",
594 "cannot parse health sensitivity value", &err_rc);
595 cYAML_print_tree2file(stderr, err_rc);
596 cYAML_free_tree(err_rc);
600 rc = lustre_lnet_config_hsensitivity(value, -1, &err_rc);
601 if (rc != LUSTRE_CFG_RC_NO_ERR)
602 cYAML_print_tree2file(stderr, err_rc);
604 cYAML_free_tree(err_rc);
609 static int jt_reset_stats(int argc, char **argv)
612 struct cYAML *err_rc = NULL;
614 rc = check_cmd(stats_cmds, "stats", "reset", 0, argc, argv);
618 rc = lustre_lnet_reset_stats(-1, &err_rc);
619 if (rc != LUSTRE_CFG_RC_NO_ERR)
620 cYAML_print_tree2file(stderr, err_rc);
622 cYAML_free_tree(err_rc);
627 static int jt_set_transaction_to(int argc, char **argv)
631 struct cYAML *err_rc = NULL;
633 rc = check_cmd(set_cmds, "set", "transaction_timeout", 2, argc, argv);
637 rc = parse_long(argv[1], &value);
639 cYAML_build_error(-1, -1, "parser", "set",
640 "cannot parse transaction timeout value", &err_rc);
641 cYAML_print_tree2file(stderr, err_rc);
642 cYAML_free_tree(err_rc);
646 rc = lustre_lnet_config_transaction_to(value, -1, &err_rc);
647 if (rc != LUSTRE_CFG_RC_NO_ERR)
648 cYAML_print_tree2file(stderr, err_rc);
650 cYAML_free_tree(err_rc);
655 static int jt_set_retry_count(int argc, char **argv)
659 struct cYAML *err_rc = NULL;
661 rc = check_cmd(set_cmds, "set", "retry_count", 2, argc, argv);
665 rc = parse_long(argv[1], &value);
667 cYAML_build_error(-1, -1, "parser", "set",
668 "cannot parse retry_count value", &err_rc);
669 cYAML_print_tree2file(stderr, err_rc);
670 cYAML_free_tree(err_rc);
674 rc = lustre_lnet_config_retry_count(value, -1, &err_rc);
675 if (rc != LUSTRE_CFG_RC_NO_ERR)
676 cYAML_print_tree2file(stderr, err_rc);
678 cYAML_free_tree(err_rc);
683 static int jt_set_discovery(int argc, char **argv)
687 struct cYAML *err_rc = NULL;
689 rc = check_cmd(set_cmds, "set", "discovery", 2, argc, argv);
693 rc = parse_long(argv[1], &value);
695 cYAML_build_error(-1, -1, "parser", "set",
696 "cannot parse discovery value", &err_rc);
697 cYAML_print_tree2file(stderr, err_rc);
698 cYAML_free_tree(err_rc);
702 rc = lustre_lnet_config_discovery(value, -1, &err_rc);
703 if (rc != LUSTRE_CFG_RC_NO_ERR)
704 cYAML_print_tree2file(stderr, err_rc);
706 cYAML_free_tree(err_rc);
711 static int jt_set_drop_asym_route(int argc, char **argv)
715 struct cYAML *err_rc = NULL;
717 rc = check_cmd(set_cmds, "set", "drop_asym_route", 2, argc, argv);
721 rc = parse_long(argv[1], &value);
723 cYAML_build_error(-1, -1, "parser", "set",
724 "cannot parse drop_asym_route value",
726 cYAML_print_tree2file(stderr, err_rc);
727 cYAML_free_tree(err_rc);
731 rc = lustre_lnet_config_drop_asym_route(value, -1, &err_rc);
732 if (rc != LUSTRE_CFG_RC_NO_ERR)
733 cYAML_print_tree2file(stderr, err_rc);
735 cYAML_free_tree(err_rc);
740 static int jt_set_tiny(int argc, char **argv)
744 struct cYAML *err_rc = NULL;
746 rc = check_cmd(set_cmds, "set", "tiny_buffers", 2, argc, argv);
750 rc = parse_long(argv[1], &value);
752 cYAML_build_error(-1, -1, "parser", "set",
753 "cannot parse tiny_buffers value", &err_rc);
754 cYAML_print_tree2file(stderr, err_rc);
755 cYAML_free_tree(err_rc);
759 rc = lustre_lnet_config_buffers(value, -1, -1, -1, &err_rc);
760 if (rc != LUSTRE_CFG_RC_NO_ERR)
761 cYAML_print_tree2file(stderr, err_rc);
763 cYAML_free_tree(err_rc);
768 static int jt_set_small(int argc, char **argv)
772 struct cYAML *err_rc = NULL;
774 rc = check_cmd(set_cmds, "set", "small_buffers", 2, argc, argv);
778 rc = parse_long(argv[1], &value);
780 cYAML_build_error(-1, -1, "parser", "set",
781 "cannot parse small_buffers value", &err_rc);
782 cYAML_print_tree2file(stderr, err_rc);
783 cYAML_free_tree(err_rc);
787 rc = lustre_lnet_config_buffers(-1, value, -1, -1, &err_rc);
788 if (rc != LUSTRE_CFG_RC_NO_ERR)
789 cYAML_print_tree2file(stderr, err_rc);
791 cYAML_free_tree(err_rc);
796 static int jt_set_large(int argc, char **argv)
800 struct cYAML *err_rc = NULL;
802 rc = check_cmd(set_cmds, "set", "large_buffers", 2, argc, argv);
806 rc = parse_long(argv[1], &value);
808 cYAML_build_error(-1, -1, "parser", "set",
809 "cannot parse large_buffers value", &err_rc);
810 cYAML_print_tree2file(stderr, err_rc);
811 cYAML_free_tree(err_rc);
815 rc = lustre_lnet_config_buffers(-1, -1, value, -1, &err_rc);
816 if (rc != LUSTRE_CFG_RC_NO_ERR)
817 cYAML_print_tree2file(stderr, err_rc);
819 cYAML_free_tree(err_rc);
824 static int jt_set_routing(int argc, char **argv)
827 struct cYAML *err_rc = NULL;
830 rc = check_cmd(set_cmds, "set", "routing", 2, argc, argv);
834 rc = parse_long(argv[1], &value);
835 if (rc != 0 || (value != 0 && value != 1)) {
836 cYAML_build_error(-1, -1, "parser", "set",
837 "cannot parse routing value.\n"
838 "must be 0 for disable or 1 for enable",
840 cYAML_print_tree2file(stderr, err_rc);
841 cYAML_free_tree(err_rc);
845 rc = lustre_lnet_enable_routing(value, -1, &err_rc);
847 if (rc != LUSTRE_CFG_RC_NO_ERR)
848 cYAML_print_tree2file(stderr, err_rc);
850 cYAML_free_tree(err_rc);
855 static int jt_set_max_recovery_ping_interval(int argc, char **argv)
859 struct cYAML *err_rc = NULL;
861 rc = check_cmd(set_cmds, "set", "maximum recovery_interval", 2, argc, argv);
865 rc = parse_long(argv[1], &value);
867 cYAML_build_error(-1, -1, "parser", "set",
868 "cannot parse maximum recovery interval value",
870 cYAML_print_tree2file(stderr, err_rc);
871 cYAML_free_tree(err_rc);
875 rc = lustre_lnet_config_max_recovery_ping_interval(value, -1, &err_rc);
876 if (rc != LUSTRE_CFG_RC_NO_ERR)
877 cYAML_print_tree2file(stderr, err_rc);
879 cYAML_free_tree(err_rc);
884 static void yaml_lnet_print_error(int op, char *cmd, const char *errstr)
886 char errcode[INT_STRING_LEN];
892 snprintf(errcode, sizeof(errcode), "%d", errno);
894 yaml_emitter_initialize(&log);
895 yaml_emitter_set_indent(&log, LNET_DEFAULT_INDENT);
896 yaml_emitter_set_output_file(&log, stderr);
898 yaml_emitter_open(&log);
899 yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
900 rc = yaml_emitter_emit(&log, &event);
904 yaml_mapping_start_event_initialize(&event, NULL,
905 (yaml_char_t *)YAML_MAP_TAG,
906 1, YAML_ANY_MAPPING_STYLE);
907 rc = yaml_emitter_emit(&log, &event);
930 yaml_scalar_event_initialize(&event, NULL,
931 (yaml_char_t *)YAML_STR_TAG,
934 YAML_PLAIN_SCALAR_STYLE);
935 rc = yaml_emitter_emit(&log, &event);
939 yaml_sequence_start_event_initialize(&event, NULL,
940 (yaml_char_t *)YAML_SEQ_TAG,
941 1, YAML_ANY_SEQUENCE_STYLE);
942 rc = yaml_emitter_emit(&log, &event);
946 yaml_mapping_start_event_initialize(&event, NULL,
947 (yaml_char_t *)YAML_MAP_TAG,
948 1, YAML_ANY_MAPPING_STYLE);
949 rc = yaml_emitter_emit(&log, &event);
953 yaml_scalar_event_initialize(&event, NULL,
954 (yaml_char_t *)YAML_STR_TAG,
957 1, 0, YAML_PLAIN_SCALAR_STYLE);
958 rc = yaml_emitter_emit(&log, &event);
962 yaml_scalar_event_initialize(&event, NULL,
963 (yaml_char_t *)YAML_STR_TAG,
966 1, 0, YAML_PLAIN_SCALAR_STYLE);
967 rc = yaml_emitter_emit(&log, &event);
971 yaml_scalar_event_initialize(&event, NULL,
972 (yaml_char_t *)YAML_STR_TAG,
973 (yaml_char_t *)"errno",
974 strlen("errno"), 1, 0,
975 YAML_PLAIN_SCALAR_STYLE);
976 rc = yaml_emitter_emit(&log, &event);
980 yaml_scalar_event_initialize(&event, NULL,
981 (yaml_char_t *)YAML_INT_TAG,
982 (yaml_char_t *)errcode,
983 strlen(errcode), 1, 0,
984 YAML_PLAIN_SCALAR_STYLE);
985 rc = yaml_emitter_emit(&log, &event);
990 yaml_scalar_event_initialize(&event, NULL,
991 (yaml_char_t *)YAML_STR_TAG,
992 (yaml_char_t *)"descr",
993 strlen("descr"), 1, 0,
994 YAML_PLAIN_SCALAR_STYLE);
995 rc = yaml_emitter_emit(&log, &event);
999 yaml_scalar_event_initialize(&event, NULL,
1000 (yaml_char_t *)YAML_STR_TAG,
1001 (yaml_char_t *)errstr,
1002 strlen(errstr), 1, 0,
1003 YAML_DOUBLE_QUOTED_SCALAR_STYLE);
1004 rc = yaml_emitter_emit(&log, &event);
1008 yaml_mapping_end_event_initialize(&event);
1009 rc = yaml_emitter_emit(&log, &event);
1013 yaml_sequence_end_event_initialize(&event);
1014 rc = yaml_emitter_emit(&log, &event);
1018 yaml_mapping_end_event_initialize(&event);
1019 rc = yaml_emitter_emit(&log, &event);
1023 yaml_document_end_event_initialize(&event, 0);
1024 rc = yaml_emitter_emit(&log, &event);
1028 rc = yaml_emitter_close(&log);
1031 yaml_emitter_log_error(&log, stdout);
1032 yaml_emitter_delete(&log);
1035 static int yaml_lnet_cpt_of_nid_display(yaml_parser_t *reply)
1037 yaml_document_t results;
1038 yaml_emitter_t output;
1041 rc = yaml_parser_load(reply, &results);
1043 yaml_lnet_print_error(NLM_F_DUMP, "cpt-of-nid",
1044 yaml_parser_get_reader_error(reply));
1045 yaml_document_delete(&results);
1049 rc = yaml_emitter_initialize(&output);
1051 yaml_emitter_set_output_file(&output, stdout);
1053 rc = yaml_emitter_dump(&output, &results);
1056 yaml_document_delete(&results);
1058 yaml_emitter_log_error(&output, stderr);
1061 yaml_emitter_delete(&output);
1066 static int yaml_lnet_cpt_of_nid(int start, int end, char **nids)
1068 struct nl_sock *sk = NULL;
1069 yaml_emitter_t request;
1070 yaml_parser_t reply;
1074 /* Create Netlink emitter to send request to kernel */
1075 sk = nl_socket_alloc();
1079 /* Setup parser to receive Netlink packets */
1080 rc = yaml_parser_initialize(&reply);
1086 rc = yaml_parser_set_input_netlink(&reply, sk, false);
1090 /* Create Netlink emitter to send request to kernel */
1091 rc = yaml_emitter_initialize(&request);
1095 rc = yaml_emitter_set_output_netlink(&request, sk, LNET_GENL_NAME,
1097 LNET_CMD_CPT_OF_NID, NLM_F_DUMP);
1101 yaml_emitter_open(&request);
1102 yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
1103 rc = yaml_emitter_emit(&request, &event);
1107 yaml_mapping_start_event_initialize(&event, NULL,
1108 (yaml_char_t *)YAML_MAP_TAG,
1109 1, YAML_ANY_MAPPING_STYLE);
1110 rc = yaml_emitter_emit(&request, &event);
1114 yaml_scalar_event_initialize(&event, NULL,
1115 (yaml_char_t *)YAML_STR_TAG,
1116 (yaml_char_t *)"cpt-of-nid",
1117 strlen("cpt-of-nid"), 1, 0,
1118 YAML_PLAIN_SCALAR_STYLE);
1119 rc = yaml_emitter_emit(&request, &event);
1123 yaml_mapping_start_event_initialize(&event, NULL,
1124 (yaml_char_t *)YAML_MAP_TAG,
1125 1, YAML_ANY_MAPPING_STYLE);
1126 rc = yaml_emitter_emit(&request, &event);
1130 yaml_scalar_event_initialize(&event, NULL,
1131 (yaml_char_t *)YAML_STR_TAG,
1132 (yaml_char_t *)"nids",
1133 strlen("nids"), 1, 0,
1134 YAML_PLAIN_SCALAR_STYLE);
1135 rc = yaml_emitter_emit(&request, &event);
1139 yaml_sequence_start_event_initialize(&event, NULL,
1140 (yaml_char_t *)YAML_SEQ_TAG,
1141 1, YAML_FLOW_SEQUENCE_STYLE);
1142 rc = yaml_emitter_emit(&request, &event);
1146 for (i = start; i < end; i++) {
1147 yaml_scalar_event_initialize(&event, NULL,
1148 (yaml_char_t *)YAML_STR_TAG,
1149 (yaml_char_t *)nids[i],
1150 strlen(nids[i]), 1, 0,
1151 YAML_PLAIN_SCALAR_STYLE);
1152 rc = yaml_emitter_emit(&request, &event);
1157 yaml_sequence_end_event_initialize(&event);
1158 rc = yaml_emitter_emit(&request, &event);
1162 yaml_mapping_end_event_initialize(&event);
1163 rc = yaml_emitter_emit(&request, &event);
1167 yaml_mapping_end_event_initialize(&event);
1168 rc = yaml_emitter_emit(&request, &event);
1172 yaml_document_end_event_initialize(&event, 0);
1173 rc = yaml_emitter_emit(&request, &event);
1177 rc = yaml_emitter_close(&request);
1180 yaml_emitter_log_error(&request, stderr);
1183 rc = yaml_lnet_cpt_of_nid_display(&reply);
1185 yaml_emitter_delete(&request);
1188 yaml_lnet_print_error(NLM_F_DUMP, "cpt-of-nid",
1189 yaml_parser_get_reader_error(&reply));
1193 yaml_parser_delete(&reply);
1196 return rc == 1 ? 0 : rc;
1199 static int jt_calc_cpt_of_nid(int argc, char **argv)
1202 const char *const short_options = "h";
1203 static const struct option long_options[] = {
1204 { .name = "help", .val = 'h' },
1207 rc = check_cmd(cmd_list, "", "cpt-of-nid", 2, argc, argv);
1211 while ((opt = getopt_long(argc, argv, short_options,
1212 long_options, NULL)) != -1) {
1216 print_help(cmd_list, "", "cpt-of-nid");
1222 rc = yaml_lnet_cpt_of_nid(optind, argc, argv);
1223 if (rc == -EOPNOTSUPP)
1224 printf("Operation not supported\n");
1229 static int jt_config_lnet(int argc, char **argv)
1231 struct cYAML *err_rc = NULL;
1232 bool load_mod_params = false;
1235 const char *const short_options = "a";
1236 static const struct option long_options[] = {
1237 { .name = "all", .has_arg = no_argument, .val = 'a' },
1241 rc = check_cmd(lnet_cmds, "lnet", "configure", 0, argc, argv);
1245 while ((opt = getopt_long(argc, argv, short_options,
1246 long_options, NULL)) != -1) {
1249 load_mod_params = true;
1256 rc = lustre_lnet_config_ni_system(LNET_CONFIGURE, load_mod_params,
1259 if (rc != LUSTRE_CFG_RC_NO_ERR)
1260 cYAML_print_tree2file(stderr, err_rc);
1262 cYAML_free_tree(err_rc);
1267 static int jt_unconfig_lnet(int argc, char **argv)
1269 struct cYAML *err_rc = NULL;
1272 rc = check_cmd(lnet_cmds, "lnet", "unconfigure", 0, argc, argv);
1276 rc = lustre_lnet_config_ni_system(LNET_UNCONFIGURE, 0, -1, &err_rc);
1278 if (rc != LUSTRE_CFG_RC_NO_ERR)
1279 cYAML_print_tree2file(stderr, err_rc);
1281 cYAML_free_tree(err_rc);
1286 static int yaml_lnet_router_gateways(yaml_emitter_t *output, const char *nw,
1287 const char *gw, int hops, int prio,
1290 char num[INT_STRING_LEN];
1294 yaml_mapping_start_event_initialize(&event, NULL,
1295 (yaml_char_t *)YAML_MAP_TAG, 1,
1296 YAML_BLOCK_MAPPING_STYLE);
1297 rc = yaml_emitter_emit(output, &event);
1302 yaml_scalar_event_initialize(&event, NULL,
1303 (yaml_char_t *)YAML_STR_TAG,
1304 (yaml_char_t *)"net",
1305 strlen("net"), 1, 0,
1306 YAML_PLAIN_SCALAR_STYLE);
1307 rc = yaml_emitter_emit(output, &event);
1311 yaml_scalar_event_initialize(&event, NULL,
1312 (yaml_char_t *)YAML_STR_TAG,
1315 YAML_PLAIN_SCALAR_STYLE);
1316 rc = yaml_emitter_emit(output, &event);
1322 yaml_scalar_event_initialize(&event, NULL,
1323 (yaml_char_t *)YAML_STR_TAG,
1324 (yaml_char_t *)"gateway",
1325 strlen("gateway"), 1, 0,
1326 YAML_PLAIN_SCALAR_STYLE);
1327 rc = yaml_emitter_emit(output, &event);
1331 yaml_scalar_event_initialize(&event, NULL,
1332 (yaml_char_t *)YAML_STR_TAG,
1335 YAML_PLAIN_SCALAR_STYLE);
1336 rc = yaml_emitter_emit(output, &event);
1342 yaml_scalar_event_initialize(&event, NULL,
1343 (yaml_char_t *)YAML_STR_TAG,
1344 (yaml_char_t *)"hop",
1345 strlen("hop"), 1, 0,
1346 YAML_PLAIN_SCALAR_STYLE);
1347 rc = yaml_emitter_emit(output, &event);
1351 snprintf(num, sizeof(num), "%d", hops);
1352 yaml_scalar_event_initialize(&event, NULL,
1353 (yaml_char_t *)YAML_INT_TAG,
1356 YAML_PLAIN_SCALAR_STYLE);
1357 rc = yaml_emitter_emit(output, &event);
1363 yaml_scalar_event_initialize(&event, NULL,
1364 (yaml_char_t *)YAML_STR_TAG,
1365 (yaml_char_t *)"priority",
1366 strlen("priority"), 1, 0,
1367 YAML_PLAIN_SCALAR_STYLE);
1368 rc = yaml_emitter_emit(output, &event);
1372 snprintf(num, sizeof(num), "%d", prio);
1373 yaml_scalar_event_initialize(&event, NULL,
1374 (yaml_char_t *)YAML_INT_TAG,
1377 YAML_PLAIN_SCALAR_STYLE);
1378 rc = yaml_emitter_emit(output, &event);
1384 yaml_scalar_event_initialize(&event, NULL,
1385 (yaml_char_t *)YAML_STR_TAG,
1386 (yaml_char_t *)"health_sensitivity",
1387 strlen("health_sensitivity"),
1389 YAML_PLAIN_SCALAR_STYLE);
1390 rc = yaml_emitter_emit(output, &event);
1394 snprintf(num, sizeof(num), "%d", sen);
1395 yaml_scalar_event_initialize(&event, NULL,
1396 (yaml_char_t *)YAML_INT_TAG,
1399 YAML_PLAIN_SCALAR_STYLE);
1400 rc = yaml_emitter_emit(output, &event);
1405 yaml_mapping_end_event_initialize(&event);
1406 rc = yaml_emitter_emit(output, &event);
1411 static int yaml_lnet_route(char *nw, char *gw, int hops, int prio, int sen,
1412 int version, int flags)
1414 struct nid_node head, *entry;
1415 struct nl_sock *sk = NULL;
1416 const char *msg = NULL;
1417 yaml_emitter_t output;
1418 yaml_parser_t reply;
1422 if (!(flags & NLM_F_DUMP) && (!nw || !gw)) {
1423 fprintf(stdout, "missing mandatory parameters:'%s'\n",
1424 (!nw && !gw) ? "net , gateway" :
1425 !nw ? "net" : "gateway");
1429 /* Create Netlink emitter to send request to kernel */
1430 sk = nl_socket_alloc();
1434 /* Setup parser to receive Netlink packets */
1435 rc = yaml_parser_initialize(&reply);
1441 rc = yaml_parser_set_input_netlink(&reply, sk, false);
1443 msg = yaml_parser_get_reader_error(&reply);
1447 /* Create Netlink emitter to send request to kernel */
1448 rc = yaml_emitter_initialize(&output);
1450 msg = "failed to initialize emitter";
1454 rc = yaml_emitter_set_output_netlink(&output, sk, LNET_GENL_NAME,
1455 version, LNET_CMD_ROUTES, flags);
1459 yaml_emitter_open(&output);
1460 yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
1461 rc = yaml_emitter_emit(&output, &event);
1465 yaml_mapping_start_event_initialize(&event, NULL,
1466 (yaml_char_t *)YAML_MAP_TAG,
1467 1, YAML_ANY_MAPPING_STYLE);
1468 rc = yaml_emitter_emit(&output, &event);
1472 yaml_scalar_event_initialize(&event, NULL,
1473 (yaml_char_t *)YAML_STR_TAG,
1474 (yaml_char_t *)"route",
1475 strlen("route"), 1, 0,
1476 YAML_PLAIN_SCALAR_STYLE);
1477 rc = yaml_emitter_emit(&output, &event);
1481 /* NLM_F_DUMP can have no arguments */
1483 NL_INIT_LIST_HEAD(&head.children);
1484 nl_init_list_head(&head.list);
1486 rc = lustre_lnet_parse_nid_range(&head, gw, &msg);
1488 lustre_lnet_free_list(&head);
1489 yaml_emitter_delete(&output);
1496 yaml_sequence_start_event_initialize(&event, NULL,
1497 (yaml_char_t *)YAML_SEQ_TAG,
1499 YAML_BLOCK_SEQUENCE_STYLE);
1500 rc = yaml_emitter_emit(&output, &event);
1504 if (!nl_list_empty(&head.children)) {
1505 nl_list_for_each_entry(entry, &head.children, list) {
1506 const char *nid = entry->nidstr;
1508 rc = yaml_lnet_router_gateways(&output, nw, nid,
1514 rc = yaml_lnet_router_gateways(&output, nw, NULL, hops,
1520 yaml_sequence_end_event_initialize(&event);
1521 rc = yaml_emitter_emit(&output, &event);
1525 yaml_scalar_event_initialize(&event, NULL,
1526 (yaml_char_t *)YAML_STR_TAG,
1529 YAML_PLAIN_SCALAR_STYLE);
1530 rc = yaml_emitter_emit(&output, &event);
1535 yaml_mapping_end_event_initialize(&event);
1536 rc = yaml_emitter_emit(&output, &event);
1540 yaml_document_end_event_initialize(&event, 0);
1541 rc = yaml_emitter_emit(&output, &event);
1545 rc = yaml_emitter_close(&output);
1548 yaml_emitter_log_error(&output, stderr);
1551 yaml_document_t errmsg;
1553 rc = yaml_parser_load(&reply, &errmsg);
1554 if (rc == 1 && (flags & NLM_F_DUMP)) {
1555 yaml_emitter_t debug;
1557 rc = yaml_emitter_initialize(&debug);
1559 yaml_emitter_set_indent(&debug,
1560 LNET_DEFAULT_INDENT);
1561 yaml_emitter_set_output_file(&debug,
1563 rc = yaml_emitter_dump(&debug, &errmsg);
1565 yaml_emitter_delete(&debug);
1567 msg = yaml_parser_get_reader_error(&reply);
1568 /* If we didn't find any routes just be silent */
1569 if (msg && strcmp(msg, "No routes found") == 0)
1572 yaml_document_delete(&errmsg);
1574 yaml_emitter_delete(&output);
1577 yaml_lnet_print_error(flags, "route", msg);
1580 yaml_parser_delete(&reply);
1583 return rc == 1 ? 0 : rc;
1586 static int jt_add_route(int argc, char **argv)
1588 char *network = NULL, *gateway = NULL;
1589 long int hop = -1, prio = -1, sen = -1;
1590 struct cYAML *err_rc = NULL;
1593 const char *const short_options = "n:g:c:p:";
1594 static const struct option long_options[] = {
1595 { .name = "net", .has_arg = required_argument, .val = 'n' },
1596 { .name = "gateway", .has_arg = required_argument, .val = 'g' },
1597 { .name = "hop", .has_arg = required_argument, .val = 'c' },
1598 { .name = "hop-count", .has_arg = required_argument, .val = 'c' },
1599 { .name = "priority", .has_arg = required_argument, .val = 'p' },
1600 { .name = "health_sensitivity", .has_arg = required_argument, .val = 's' },
1604 rc = check_cmd(route_cmds, "route", "add", 0, argc, argv);
1608 while ((opt = getopt_long(argc, argv, short_options,
1609 long_options, NULL)) != -1) {
1618 rc = parse_long(optarg, &hop);
1626 rc = parse_long(optarg, &prio);
1634 rc = parse_long(optarg, &sen);
1643 print_help(route_cmds, "route", "add");
1649 rc = yaml_lnet_route(network, gateway, hop, prio, sen,
1650 LNET_GENL_VERSION, NLM_F_CREATE);
1652 if (rc == -EOPNOTSUPP)
1657 rc = lustre_lnet_config_route(network, gateway, hop, prio, sen, -1,
1660 if (rc != LUSTRE_CFG_RC_NO_ERR)
1661 cYAML_print_tree2file(stderr, err_rc);
1663 cYAML_free_tree(err_rc);
1668 static int yaml_add_ni_tunables(yaml_emitter_t *output,
1669 struct lnet_ioctl_config_lnd_tunables *tunables,
1670 struct lnet_dlc_network_descr *nw_descr)
1672 char num[INT_STRING_LEN];
1676 if (tunables->lt_cmn.lct_peer_timeout < 0 &&
1677 tunables->lt_cmn.lct_peer_tx_credits <= 0 &&
1678 tunables->lt_cmn.lct_peer_rtr_credits <= 0 &&
1679 tunables->lt_cmn.lct_max_tx_credits <= 0)
1680 goto skip_general_settings;
1682 yaml_scalar_event_initialize(&event, NULL,
1683 (yaml_char_t *)YAML_STR_TAG,
1684 (yaml_char_t *)"tunables",
1685 strlen("tunables"), 1, 0,
1686 YAML_PLAIN_SCALAR_STYLE);
1687 rc = yaml_emitter_emit(output, &event);
1691 yaml_mapping_start_event_initialize(&event, NULL,
1692 (yaml_char_t *)YAML_MAP_TAG,
1693 1, YAML_ANY_MAPPING_STYLE);
1694 rc = yaml_emitter_emit(output, &event);
1698 if (tunables->lt_cmn.lct_peer_timeout >= 0) {
1699 yaml_scalar_event_initialize(&event, NULL,
1700 (yaml_char_t *)YAML_STR_TAG,
1701 (yaml_char_t *)"peer_timeout",
1702 strlen("peer_timeout"), 1, 0,
1703 YAML_PLAIN_SCALAR_STYLE);
1704 rc = yaml_emitter_emit(output, &event);
1708 snprintf(num, sizeof(num), "%u",
1709 tunables->lt_cmn.lct_peer_timeout);
1710 yaml_scalar_event_initialize(&event, NULL,
1711 (yaml_char_t *)YAML_INT_TAG,
1714 YAML_PLAIN_SCALAR_STYLE);
1715 rc = yaml_emitter_emit(output, &event);
1720 if (tunables->lt_cmn.lct_peer_tx_credits > 0) {
1721 yaml_scalar_event_initialize(&event, NULL,
1722 (yaml_char_t *)YAML_STR_TAG,
1723 (yaml_char_t *)"peer_credits",
1724 strlen("peer_credits"), 1, 0,
1725 YAML_PLAIN_SCALAR_STYLE);
1726 rc = yaml_emitter_emit(output, &event);
1730 snprintf(num, sizeof(num), "%u",
1731 tunables->lt_cmn.lct_peer_tx_credits);
1732 yaml_scalar_event_initialize(&event, NULL,
1733 (yaml_char_t *)YAML_INT_TAG,
1736 YAML_PLAIN_SCALAR_STYLE);
1737 rc = yaml_emitter_emit(output, &event);
1742 if (tunables->lt_cmn.lct_peer_rtr_credits > 0) {
1743 yaml_scalar_event_initialize(&event, NULL,
1744 (yaml_char_t *)YAML_STR_TAG,
1745 (yaml_char_t *)"peer_buffer_credits",
1746 strlen("peer_buffer_credits"), 1, 0,
1747 YAML_PLAIN_SCALAR_STYLE);
1748 rc = yaml_emitter_emit(output, &event);
1752 snprintf(num, sizeof(num), "%u",
1753 tunables->lt_cmn.lct_peer_rtr_credits);
1754 yaml_scalar_event_initialize(&event, NULL,
1755 (yaml_char_t *)YAML_INT_TAG,
1758 YAML_PLAIN_SCALAR_STYLE);
1759 rc = yaml_emitter_emit(output, &event);
1764 if (tunables->lt_cmn.lct_max_tx_credits > 0) {
1765 yaml_scalar_event_initialize(&event, NULL,
1766 (yaml_char_t *)YAML_STR_TAG,
1767 (yaml_char_t *)"credits",
1768 strlen("credits"), 1, 0,
1769 YAML_PLAIN_SCALAR_STYLE);
1770 rc = yaml_emitter_emit(output, &event);
1774 snprintf(num, sizeof(num), "%u",
1775 tunables->lt_cmn.lct_max_tx_credits);
1776 yaml_scalar_event_initialize(&event, NULL,
1777 (yaml_char_t *)YAML_INT_TAG,
1780 YAML_PLAIN_SCALAR_STYLE);
1781 rc = yaml_emitter_emit(output, &event);
1786 yaml_mapping_end_event_initialize(&event);
1787 rc = yaml_emitter_emit(output, &event);
1791 skip_general_settings:
1792 if (tunables->lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer > 0 ||
1794 tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_auth_key > 0 ||
1795 tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_traffic_class_str[0] ||
1797 tunables->lt_tun.lnd_tun_u.lnd_o2ib.lnd_conns_per_peer > 0) {
1798 yaml_scalar_event_initialize(&event, NULL,
1799 (yaml_char_t *)YAML_STR_TAG,
1800 (yaml_char_t *)"lnd tunables",
1801 strlen("lnd tunables"), 1, 0,
1802 YAML_PLAIN_SCALAR_STYLE);
1803 rc = yaml_emitter_emit(output, &event);
1807 yaml_mapping_start_event_initialize(&event, NULL,
1808 (yaml_char_t *)YAML_MAP_TAG,
1809 1, YAML_ANY_MAPPING_STYLE);
1810 rc = yaml_emitter_emit(output, &event);
1814 if (tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_auth_key > 0) {
1815 yaml_scalar_event_initialize(&event, NULL,
1816 (yaml_char_t *)YAML_STR_TAG,
1817 (yaml_char_t *)"auth_key",
1818 strlen("auth_key"), 1, 0,
1819 YAML_PLAIN_SCALAR_STYLE);
1820 rc = yaml_emitter_emit(output, &event);
1824 snprintf(num, sizeof(num), "%u",
1825 tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_auth_key);
1827 yaml_scalar_event_initialize(&event, NULL,
1828 (yaml_char_t *)YAML_INT_TAG,
1831 YAML_PLAIN_SCALAR_STYLE);
1832 rc = yaml_emitter_emit(output, &event);
1837 if (tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_traffic_class_str[0]) {
1838 char *tc = &tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_traffic_class_str[0];
1840 yaml_scalar_event_initialize(&event, NULL,
1841 (yaml_char_t *)YAML_STR_TAG,
1842 (yaml_char_t *)"traffic_class",
1843 strlen("traffic_class"), 1, 0,
1844 YAML_PLAIN_SCALAR_STYLE);
1845 rc = yaml_emitter_emit(output, &event);
1849 yaml_scalar_event_initialize(&event, NULL,
1850 (yaml_char_t *)YAML_INT_TAG,
1853 YAML_PLAIN_SCALAR_STYLE);
1855 rc = yaml_emitter_emit(output, &event);
1860 if (tunables->lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer > 0 ||
1861 tunables->lt_tun.lnd_tun_u.lnd_o2ib.lnd_conns_per_peer > 0) {
1864 yaml_scalar_event_initialize(&event, NULL,
1865 (yaml_char_t *)YAML_STR_TAG,
1866 (yaml_char_t *)"conns_per_peer",
1867 strlen("conns_per_peer"), 1, 0,
1868 YAML_PLAIN_SCALAR_STYLE);
1869 rc = yaml_emitter_emit(output, &event);
1873 if (nw_descr->nw_id == LNET_NET_ANY)
1874 cpp = tunables->lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer;
1875 else if (LNET_NETTYP(nw_descr->nw_id) == SOCKLND)
1876 cpp = tunables->lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer;
1877 else if (LNET_NETTYP(nw_descr->nw_id) == O2IBLND)
1878 cpp = tunables->lt_tun.lnd_tun_u.lnd_o2ib.lnd_conns_per_peer;
1879 snprintf(num, sizeof(num), "%u", cpp);
1881 yaml_scalar_event_initialize(&event, NULL,
1882 (yaml_char_t *)YAML_INT_TAG,
1885 YAML_PLAIN_SCALAR_STYLE);
1886 rc = yaml_emitter_emit(output, &event);
1891 yaml_mapping_end_event_initialize(&event);
1892 rc = yaml_emitter_emit(output, &event);
1898 static int yaml_lnet_config_ni(char *net_id, char *ip2net,
1899 struct lnet_dlc_network_descr *nw_descr,
1900 struct lnet_ioctl_config_lnd_tunables *tunables,
1901 int healthv, struct cfs_expr_list *global_cpts,
1902 int version, int flags)
1904 struct lnet_dlc_intf_descr *intf;
1905 struct nl_sock *sk = NULL;
1906 const char *msg = NULL;
1907 yaml_emitter_t output;
1908 yaml_parser_t reply;
1912 if (!(flags & NLM_F_DUMP) && !ip2net && (!nw_descr || nw_descr->nw_id == 0)) {
1913 fprintf(stdout, "missing mandatory parameters in NI config: '%s'\n",
1914 (!nw_descr) ? "network , interface" :
1915 (nw_descr->nw_id == 0) ? "network" : "interface");
1919 if ((flags == NLM_F_CREATE) && !ip2net && list_empty(&nw_descr->nw_intflist)) {
1920 fprintf(stdout, "creating a local NI needs at least one interface\n");
1924 if ((flags == NLM_F_REPLACE) && list_empty(&nw_descr->nw_intflist)) {
1925 fprintf(stdout, "updating a local NI needs at least one address\n");
1929 /* Create Netlink emitter to send request to kernel */
1930 sk = nl_socket_alloc();
1934 /* Setup parser to receive Netlink packets */
1935 rc = yaml_parser_initialize(&reply);
1941 rc = yaml_parser_set_input_netlink(&reply, sk, false);
1943 msg = yaml_parser_get_reader_error(&reply);
1947 /* Create Netlink emitter to send request to kernel */
1948 rc = yaml_emitter_initialize(&output);
1950 msg = "failed to initialize emitter";
1954 rc = yaml_emitter_set_output_netlink(&output, sk, LNET_GENL_NAME,
1955 version, LNET_CMD_NETS, flags);
1959 yaml_emitter_open(&output);
1960 yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
1961 rc = yaml_emitter_emit(&output, &event);
1965 yaml_mapping_start_event_initialize(&event, NULL,
1966 (yaml_char_t *)YAML_MAP_TAG,
1967 1, YAML_ANY_MAPPING_STYLE);
1968 rc = yaml_emitter_emit(&output, &event);
1972 yaml_scalar_event_initialize(&event, NULL,
1973 (yaml_char_t *)YAML_STR_TAG,
1974 (yaml_char_t *)"net",
1975 strlen("net"), 1, 0,
1976 YAML_PLAIN_SCALAR_STYLE);
1977 rc = yaml_emitter_emit(&output, &event);
1981 if (net_id || ip2net) {
1982 char *key = net_id ? "net type" : "ip2net";
1983 char *value = net_id ? net_id : ip2net;
1985 yaml_sequence_start_event_initialize(&event, NULL,
1986 (yaml_char_t *)YAML_SEQ_TAG,
1987 1, YAML_ANY_SEQUENCE_STYLE);
1988 rc = yaml_emitter_emit(&output, &event);
1992 yaml_mapping_start_event_initialize(&event, NULL,
1993 (yaml_char_t *)YAML_MAP_TAG,
1994 1, YAML_ANY_MAPPING_STYLE);
1995 rc = yaml_emitter_emit(&output, &event);
1999 yaml_scalar_event_initialize(&event, NULL,
2000 (yaml_char_t *)YAML_STR_TAG,
2003 1, 0, YAML_PLAIN_SCALAR_STYLE);
2004 rc = yaml_emitter_emit(&output, &event);
2008 yaml_scalar_event_initialize(&event, NULL,
2009 (yaml_char_t *)YAML_STR_TAG,
2010 (yaml_char_t *)value,
2011 strlen(value), 1, 0,
2012 YAML_PLAIN_SCALAR_STYLE);
2013 rc = yaml_emitter_emit(&output, &event);
2017 yaml_scalar_event_initialize(&event, NULL,
2018 (yaml_char_t *)YAML_STR_TAG,
2021 YAML_PLAIN_SCALAR_STYLE);
2022 rc = yaml_emitter_emit(&output, &event);
2029 if (!nw_descr || list_empty(&nw_descr->nw_intflist))
2032 yaml_scalar_event_initialize(&event, NULL,
2033 (yaml_char_t *)YAML_STR_TAG,
2034 (yaml_char_t *)"local NI(s)",
2035 strlen("local NI(s)"), 1, 0,
2036 YAML_PLAIN_SCALAR_STYLE);
2037 rc = yaml_emitter_emit(&output, &event);
2041 yaml_sequence_start_event_initialize(&event, NULL,
2042 (yaml_char_t *)YAML_SEQ_TAG,
2043 1, YAML_ANY_SEQUENCE_STYLE);
2044 rc = yaml_emitter_emit(&output, &event);
2048 list_for_each_entry(intf, &nw_descr->nw_intflist,
2050 yaml_mapping_start_event_initialize(&event, NULL,
2051 (yaml_char_t *)YAML_MAP_TAG,
2052 1, YAML_ANY_MAPPING_STYLE);
2053 rc = yaml_emitter_emit(&output, &event);
2057 /* Use NI addresses instead of interface */
2058 if ((strchr(intf->intf_name, '@') ||
2059 strcmp(intf->intf_name, "<?>") == 0) &&
2060 flags == NLM_F_REPLACE) {
2061 yaml_scalar_event_initialize(&event, NULL,
2062 (yaml_char_t *)YAML_STR_TAG,
2063 (yaml_char_t *)"nid",
2064 strlen("nid"), 1, 0,
2065 YAML_PLAIN_SCALAR_STYLE);
2066 rc = yaml_emitter_emit(&output, &event);
2070 yaml_scalar_event_initialize(&event, NULL,
2071 (yaml_char_t *)YAML_STR_TAG,
2072 (yaml_char_t *)intf->intf_name,
2073 strlen(intf->intf_name), 1, 0,
2074 YAML_PLAIN_SCALAR_STYLE);
2075 rc = yaml_emitter_emit(&output, &event);
2079 yaml_scalar_event_initialize(&event, NULL,
2080 (yaml_char_t *)YAML_STR_TAG,
2081 (yaml_char_t *)"interfaces",
2082 strlen("interfaces"), 1, 0,
2083 YAML_PLAIN_SCALAR_STYLE);
2084 rc = yaml_emitter_emit(&output, &event);
2088 yaml_mapping_start_event_initialize(&event, NULL,
2089 (yaml_char_t *)YAML_MAP_TAG,
2090 1, YAML_ANY_MAPPING_STYLE);
2091 rc = yaml_emitter_emit(&output, &event);
2095 yaml_scalar_event_initialize(&event, NULL,
2096 (yaml_char_t *)YAML_STR_TAG,
2099 YAML_PLAIN_SCALAR_STYLE);
2100 rc = yaml_emitter_emit(&output, &event);
2104 yaml_scalar_event_initialize(&event, NULL,
2105 (yaml_char_t *)YAML_STR_TAG,
2106 (yaml_char_t *)intf->intf_name,
2107 strlen(intf->intf_name), 1, 0,
2108 YAML_PLAIN_SCALAR_STYLE);
2109 rc = yaml_emitter_emit(&output, &event);
2113 yaml_mapping_end_event_initialize(&event);
2114 rc = yaml_emitter_emit(&output, &event);
2120 rc = yaml_add_ni_tunables(&output, tunables, nw_descr);
2125 if (flags == NLM_F_REPLACE && healthv > -1) {
2126 char health[INT_STRING_LEN];
2128 yaml_scalar_event_initialize(&event, NULL,
2129 (yaml_char_t *)YAML_STR_TAG,
2130 (yaml_char_t *)"health stats",
2131 strlen("health stats"), 1, 0,
2132 YAML_PLAIN_SCALAR_STYLE);
2133 rc = yaml_emitter_emit(&output, &event);
2137 /* Setup all mappings for data related to the 'health stats' */
2138 yaml_mapping_start_event_initialize(&event, NULL,
2139 (yaml_char_t *)YAML_MAP_TAG,
2140 1, YAML_BLOCK_MAPPING_STYLE);
2141 rc = yaml_emitter_emit(&output, &event);
2145 yaml_scalar_event_initialize(&event, NULL,
2146 (yaml_char_t *)YAML_STR_TAG,
2147 (yaml_char_t *)"health value",
2148 strlen("health value"), 1, 0,
2149 YAML_PLAIN_SCALAR_STYLE);
2150 rc = yaml_emitter_emit(&output, &event);
2154 snprintf(health, sizeof(health), "%d", healthv);
2155 yaml_scalar_event_initialize(&event, NULL,
2156 (yaml_char_t *)YAML_INT_TAG,
2157 (yaml_char_t *)health,
2158 strlen(health), 1, 0,
2159 YAML_PLAIN_SCALAR_STYLE);
2160 rc = yaml_emitter_emit(&output, &event);
2164 yaml_mapping_end_event_initialize(&event);
2165 rc = yaml_emitter_emit(&output, &event);
2174 yaml_scalar_event_initialize(&event, NULL,
2175 (yaml_char_t *)YAML_STR_TAG,
2176 (yaml_char_t *)"CPT",
2177 strlen("CPT"), 1, 0,
2178 YAML_PLAIN_SCALAR_STYLE);
2179 rc = yaml_emitter_emit(&output, &event);
2183 yaml_sequence_start_event_initialize(&event, NULL,
2184 (yaml_char_t *)YAML_SEQ_TAG,
2186 YAML_FLOW_SEQUENCE_STYLE);
2187 rc = yaml_emitter_emit(&output, &event);
2191 count = cfs_expr_list_values(global_cpts,
2192 LNET_MAX_SHOW_NUM_CPT,
2194 for (i = 0; i < count; i++) {
2195 char core[INT_STRING_LEN];
2197 snprintf(core, sizeof(core), "%u", cpt_array[i]);
2198 yaml_scalar_event_initialize(&event, NULL,
2199 (yaml_char_t *)YAML_STR_TAG,
2200 (yaml_char_t *)core,
2202 YAML_PLAIN_SCALAR_STYLE);
2203 rc = yaml_emitter_emit(&output, &event);
2208 yaml_sequence_end_event_initialize(&event);
2209 rc = yaml_emitter_emit(&output, &event);
2213 cfs_expr_list_free(global_cpts);
2217 yaml_mapping_end_event_initialize(&event);
2218 rc = yaml_emitter_emit(&output, &event);
2223 yaml_sequence_end_event_initialize(&event);
2224 rc = yaml_emitter_emit(&output, &event);
2228 yaml_mapping_end_event_initialize(&event);
2229 rc = yaml_emitter_emit(&output, &event);
2233 yaml_sequence_end_event_initialize(&event);
2234 rc = yaml_emitter_emit(&output, &event);
2238 yaml_mapping_end_event_initialize(&event);
2239 rc = yaml_emitter_emit(&output, &event);
2243 yaml_document_end_event_initialize(&event, 0);
2244 rc = yaml_emitter_emit(&output, &event);
2248 rc = yaml_emitter_close(&output);
2251 yaml_emitter_log_error(&output, stderr);
2254 yaml_document_t errmsg;
2256 rc = yaml_parser_load(&reply, &errmsg);
2257 if (rc == 1 && (flags & NLM_F_DUMP)) {
2258 yaml_emitter_t debug;
2260 rc = yaml_emitter_initialize(&debug);
2262 yaml_emitter_set_indent(&debug,
2263 LNET_DEFAULT_INDENT);
2264 yaml_emitter_set_output_file(&debug, stdout);
2265 rc = yaml_emitter_dump(&debug, &errmsg);
2267 yaml_emitter_delete(&debug);
2269 msg = yaml_parser_get_reader_error(&reply);
2271 yaml_document_delete(&errmsg);
2273 yaml_emitter_delete(&output);
2276 yaml_lnet_print_error(flags, "net", msg);
2279 yaml_parser_delete(&reply);
2282 return rc == 1 ? 0 : rc;
2285 static int jt_add_ni(int argc, char **argv)
2287 char *ip2net = NULL;
2288 long int pto = -1, pc = -1, pbc = -1, cre = -1, cpp = -1, auth_key = -1;
2289 char *traffic_class = NULL;
2290 struct cYAML *err_rc = NULL;
2291 int rc, opt, cpt_rc = -1;
2292 struct lnet_dlc_network_descr nw_descr;
2293 struct cfs_expr_list *global_cpts = NULL;
2294 struct lnet_ioctl_config_lnd_tunables tunables;
2296 bool skip_mr_route_setup = false;
2297 const char *const short_options = "a:b:c:i:k:m:n:p:r:s:t:T:";
2298 static const struct option long_options[] = {
2299 { .name = "auth-key", .has_arg = required_argument, .val = 'a' },
2300 { .name = "peer-buffer-credits",
2301 .has_arg = required_argument, .val = 'b' },
2302 { .name = "peer-credits", .has_arg = required_argument, .val = 'c' },
2303 { .name = "if", .has_arg = required_argument, .val = 'i' },
2304 { .name = "skip-mr-route-setup",
2305 .has_arg = no_argument, .val = 'k' },
2306 { .name = "conns-per-peer",
2307 .has_arg = required_argument, .val = 'm' },
2308 { .name = "net", .has_arg = required_argument, .val = 'n' },
2309 { .name = "ip2net", .has_arg = required_argument, .val = 'p' },
2310 { .name = "credits", .has_arg = required_argument, .val = 'r' },
2311 { .name = "cpt", .has_arg = required_argument, .val = 's' },
2312 { .name = "peer-timeout", .has_arg = required_argument, .val = 't' },
2313 { .name = "traffic-class", .has_arg = required_argument, .val = 'T' },
2315 char *net_id = NULL;
2317 memset(&tunables, 0, sizeof(tunables));
2318 lustre_lnet_init_nw_descr(&nw_descr);
2320 rc = check_cmd(net_cmds, "net", "add", 0, argc, argv);
2324 while ((opt = getopt_long(argc, argv, short_options,
2325 long_options, NULL)) != -1) {
2328 rc = parse_long(optarg, &auth_key);
2336 rc = parse_long(optarg, &pbc);
2344 rc = parse_long(optarg, &pc);
2352 rc = lustre_lnet_parse_interfaces(optarg, &nw_descr);
2354 cYAML_build_error(-1, -1, "ni", "add",
2355 "bad interface list",
2361 skip_mr_route_setup = true;
2364 rc = parse_long(optarg, &cpp);
2373 nw_descr.nw_id = libcfs_str2net(optarg);
2380 rc = parse_long(optarg, &cre);
2388 cpt_rc = cfs_expr_list_parse(optarg,
2390 UINT_MAX, &global_cpts);
2393 rc = parse_long(optarg, &pto);
2401 traffic_class = optarg;
2402 if (strlen(traffic_class) == 0 ||
2403 strlen(traffic_class) >= LNET_MAX_STR_LEN) {
2404 cYAML_build_error(-1, -1, "ni", "add",
2405 "Invalid traffic-class argument",
2407 rc = LUSTRE_CFG_RC_BAD_PARAM;
2412 print_help(net_cmds, "net", "add");
2418 if (auth_key > 0 && LNET_NETTYP(nw_descr.nw_id) == KFILND) {
2419 tunables.lt_tun.lnd_tun_u.lnd_kfi.lnd_auth_key = auth_key;
2423 if (traffic_class && LNET_NETTYP(nw_descr.nw_id) == KFILND &&
2424 strlen(traffic_class) < LNET_MAX_STR_LEN) {
2425 strcpy(&tunables.lt_tun.lnd_tun_u.lnd_kfi.lnd_traffic_class_str[0],
2431 if (LNET_NETTYP(nw_descr.nw_id) == SOCKLND && (cpp > -1)) {
2432 tunables.lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer = cpp;
2434 } else if (LNET_NETTYP(nw_descr.nw_id) == O2IBLND && (cpp > -1)) {
2435 tunables.lt_tun.lnd_tun_u.lnd_o2ib.lnd_conns_per_peer = cpp;
2439 if (pto >= 0 || pc > 0 || pbc > 0 || cre > 0 || cpp > -1) {
2440 tunables.lt_cmn.lct_peer_timeout = pto;
2441 tunables.lt_cmn.lct_peer_tx_credits = pc;
2442 tunables.lt_cmn.lct_peer_rtr_credits = pbc;
2443 tunables.lt_cmn.lct_max_tx_credits = cre;
2447 if (found && LNET_NETTYP(nw_descr.nw_id) == O2IBLND)
2448 tunables.lt_tun.lnd_tun_u.lnd_o2ib.lnd_map_on_demand = UINT_MAX;
2450 rc = yaml_lnet_config_ni(net_id, ip2net, &nw_descr,
2451 found ? &tunables : NULL, -1,
2452 (cpt_rc == 0) ? global_cpts : NULL,
2453 LNET_GENL_VERSION, NLM_F_CREATE);
2455 if (rc == -EOPNOTSUPP)
2457 if (global_cpts != NULL)
2458 cfs_expr_list_free(global_cpts);
2459 if (rc == 0 && !skip_mr_route_setup)
2460 rc = lustre_lnet_setup_mrrouting(&err_rc);
2464 rc = lustre_lnet_config_ni(&nw_descr,
2465 (cpt_rc == 0) ? global_cpts: NULL,
2466 ip2net, (found) ? &tunables : NULL,
2469 if (global_cpts != NULL)
2470 cfs_expr_list_free(global_cpts);
2473 if (rc != LUSTRE_CFG_RC_NO_ERR)
2474 cYAML_print_tree2file(stderr, err_rc);
2476 cYAML_free_tree(err_rc);
2478 if (rc == LUSTRE_CFG_RC_NO_ERR && !skip_mr_route_setup) {
2480 rc = lustre_lnet_setup_mrrouting(&err_rc);
2482 if (rc != LUSTRE_CFG_RC_NO_ERR)
2483 cYAML_print_tree2file(stderr, err_rc);
2485 cYAML_free_tree(err_rc);
2491 static int jt_del_route(int argc, char **argv)
2493 char *network = NULL, *gateway = NULL;
2494 struct cYAML *err_rc = NULL;
2496 const char *const short_options = "n:g:";
2497 static const struct option long_options[] = {
2498 { .name = "net", .has_arg = required_argument, .val = 'n' },
2499 { .name = "gateway", .has_arg = required_argument, .val = 'g' },
2503 rc = check_cmd(route_cmds, "route", "del", 0, argc, argv);
2507 while ((opt = getopt_long(argc, argv, short_options,
2508 long_options, NULL)) != -1) {
2517 print_help(route_cmds, "route", "del");
2523 rc = yaml_lnet_route(network, gateway, -1, -1, -1, LNET_GENL_VERSION,
2526 if (rc == -EOPNOTSUPP)
2531 rc = lustre_lnet_del_route(network, gateway, -1, &err_rc);
2533 if (rc != LUSTRE_CFG_RC_NO_ERR)
2534 cYAML_print_tree2file(stderr, err_rc);
2536 cYAML_free_tree(err_rc);
2541 static int jt_del_ni(int argc, char **argv)
2543 struct cYAML *err_rc = NULL;
2545 struct lnet_dlc_network_descr nw_descr;
2546 const char *const short_options = "n:i:";
2547 static const struct option long_options[] = {
2548 { .name = "net", .has_arg = required_argument, .val = 'n' },
2549 { .name = "if", .has_arg = required_argument, .val = 'i' },
2551 char *net_id = NULL;
2553 rc = check_cmd(net_cmds, "net", "del", 0, argc, argv);
2557 lustre_lnet_init_nw_descr(&nw_descr);
2559 while ((opt = getopt_long(argc, argv, short_options,
2560 long_options, NULL)) != -1) {
2563 nw_descr.nw_id = libcfs_str2net(optarg);
2567 rc = lustre_lnet_parse_interfaces(optarg, &nw_descr);
2569 cYAML_build_error(-1, -1, "ni", "add",
2570 "bad interface list",
2576 print_help(net_cmds, "net", "del");
2582 rc = yaml_lnet_config_ni(net_id, NULL, &nw_descr, NULL, -1, NULL,
2583 LNET_GENL_VERSION, 0);
2585 if (rc != -EOPNOTSUPP)
2589 rc = lustre_lnet_del_ni(&nw_descr, -1, &err_rc);
2591 if (rc != LUSTRE_CFG_RC_NO_ERR)
2592 cYAML_print_tree2file(stderr, err_rc);
2594 cYAML_free_tree(err_rc);
2599 static int jt_show_route(int argc, char **argv)
2601 char *network = NULL, *gateway = NULL;
2602 long int hop = -1, prio = -1;
2603 int detail = 0, rc, opt;
2604 struct cYAML *err_rc = NULL, *show_rc = NULL;
2605 const char *const short_options = "c:n:g:p:v";
2606 static const struct option long_options[] = {
2607 { .name = "net", .has_arg = required_argument, .val = 'n' },
2608 { .name = "gateway", .has_arg = required_argument, .val = 'g' },
2609 { .name = "hop-count", .has_arg = required_argument, .val = 'c' },
2610 { .name = "hop", .has_arg = required_argument, .val = 'c' },
2611 { .name = "priority", .has_arg = required_argument, .val = 'p' },
2612 { .name = "verbose", .has_arg = no_argument, .val = 'v' },
2616 rc = check_cmd(route_cmds, "route", "show", 0, argc, argv);
2620 while ((opt = getopt_long(argc, argv, short_options,
2621 long_options, NULL)) != -1) {
2630 rc = parse_long(optarg, &hop);
2638 rc = parse_long(optarg, &prio);
2649 print_help(route_cmds, "route", "show");
2655 rc = yaml_lnet_route(network, gateway, hop, prio, -1,
2656 detail, NLM_F_DUMP);
2658 if (rc == -EOPNOTSUPP)
2663 rc = lustre_lnet_show_route(network, gateway, hop, prio,
2665 &show_rc, &err_rc, false);
2667 if (rc != LUSTRE_CFG_RC_NO_ERR)
2668 cYAML_print_tree2file(stderr, err_rc);
2670 cYAML_print_tree(show_rc);
2672 cYAML_free_tree(err_rc);
2673 cYAML_free_tree(show_rc);
2678 static int set_value_helper(int argc, char **argv, int cmd,
2679 int (*cb)(int, bool, char*, int, int, struct cYAML**))
2681 char *nidstr = NULL;
2682 long int healthv = -1;
2684 long int state = -1;
2687 struct cYAML *err_rc = NULL;
2688 const char *const short_options = "t:n:m:s:a";
2689 static const struct option long_options[] = {
2690 { .name = "nid", .has_arg = required_argument, .val = 'n' },
2691 { .name = "health", .has_arg = required_argument, .val = 't' },
2692 { .name = "conns-per-peer", .has_arg = required_argument, .val = 'm' },
2693 { .name = "state", .has_arg = required_argument, .val = 's' },
2694 { .name = "all", .has_arg = no_argument, .val = 'a' },
2698 while ((opt = getopt_long(argc, argv, short_options,
2699 long_options, NULL)) != -1) {
2705 if (parse_long(optarg, &healthv) != 0)
2709 if (cmd != LNET_CMD_PEERS ||
2710 parse_long(optarg, &state) != 0)
2714 if (cmd != LNET_CMD_NETS ||
2715 parse_long(optarg, &cpp) != 0)
2727 rc = cb(healthv, all, nidstr, cmd == LNET_CMD_PEERS ? state : cpp, -1,
2729 if (rc != LUSTRE_CFG_RC_NO_ERR)
2730 cYAML_print_tree2file(stderr, err_rc);
2732 cYAML_free_tree(err_rc);
2737 int yaml_lnet_config_ni_healthv(int healthv, bool all, char *nidstr, int cpp,
2738 int seq_no, struct cYAML **err_rc)
2740 struct lnet_ioctl_config_lnd_tunables tunables;
2741 struct lnet_dlc_network_descr nw_descr;
2742 char *net_id = "<255:65535>"; /* LNET_NET_ANY */
2745 /* For NI you can't have both setting all NIDs and a requested NID */
2746 if (!all && !nidstr)
2749 if (cpp == -1 && healthv == -1)
2753 net_id = strchr(nidstr, '@');
2759 lustre_lnet_init_nw_descr(&nw_descr);
2760 nw_descr.nw_id = libcfs_str2net(net_id);
2762 rc = lustre_lnet_parse_interfaces(nidstr ? nidstr : "<?>", &nw_descr);
2763 if (rc != LUSTRE_CFG_RC_NO_ERR)
2766 memset(&tunables, 0, sizeof(tunables));
2767 tunables.lt_cmn.lct_peer_timeout = -1;
2768 if (nw_descr.nw_id == LNET_NET_ANY && cpp > -1)
2769 tunables.lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer = cpp;
2770 else if (LNET_NETTYP(nw_descr.nw_id) == SOCKLND && (cpp > -1))
2771 tunables.lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer = cpp;
2772 else if (LNET_NETTYP(nw_descr.nw_id) == O2IBLND && (cpp > -1))
2773 tunables.lt_tun.lnd_tun_u.lnd_o2ib.lnd_conns_per_peer = cpp;
2775 rc = yaml_lnet_config_ni(net_id, NULL, &nw_descr,
2776 cpp != -1 ? &tunables : NULL, healthv, NULL,
2777 LNET_GENL_VERSION, NLM_F_REPLACE);
2779 if (rc == -EOPNOTSUPP)
2785 rc = lustre_lnet_config_ni_conns_per_peer(cpp, all, nidstr,
2788 rc = lustre_lnet_config_ni_healthv(healthv, all, nidstr,
2793 static int jt_set_ni_value(int argc, char **argv)
2795 int rc = check_cmd(net_cmds, "net", "set", 0, argc, argv);
2800 return set_value_helper(argc, argv, LNET_CMD_NETS,
2801 yaml_lnet_config_ni_healthv);
2804 static int yaml_lnet_peer_display(yaml_parser_t *reply, bool list_only)
2806 yaml_emitter_t debug;
2809 rc = yaml_emitter_initialize(&debug);
2813 yaml_emitter_set_indent(&debug, 6);
2814 yaml_emitter_set_output_file(&debug, stdout);
2823 rc = yaml_parser_parse(reply, &event);
2825 goto report_reply_error;
2827 if (event.type != YAML_SCALAR_EVENT)
2830 value = (char *)event.data.scalar.value;
2831 if (strcmp(value, "peer") == 0) {
2832 yaml_event_delete(&event);
2834 yaml_scalar_event_initialize(&event, NULL,
2835 (yaml_char_t *)YAML_STR_TAG,
2836 (yaml_char_t *)"peer list",
2837 strlen("peer list"),
2839 YAML_PLAIN_SCALAR_STYLE);
2840 } else if (strcmp(value, "primary nid") == 0) {
2841 yaml_event_delete(&event);
2843 yaml_scalar_event_initialize(&event, NULL,
2844 (yaml_char_t *)YAML_STR_TAG,
2845 (yaml_char_t *)"nid",
2848 YAML_PLAIN_SCALAR_STYLE);
2849 rc = yaml_emitter_emit(&debug, &event);
2853 /* Now print NID address */
2854 rc = yaml_parser_parse(reply, &event);
2856 goto report_reply_error;
2858 rc = yaml_emitter_emit(&debug, &event);
2863 while (event.type != YAML_MAPPING_END_EVENT) {
2864 rc = yaml_parser_parse(reply, &event);
2866 goto report_reply_error;
2869 /* we can have map end, seq end, map end or
2870 * just map end event. If we see seq end event
2871 * then skip to next mapping end event
2873 rc = yaml_parser_parse(reply, &event);
2875 goto report_reply_error;
2877 if (event.type == YAML_SEQUENCE_END_EVENT) {
2878 yaml_event_delete(&event);
2880 rc = yaml_parser_parse(reply, &event);
2882 goto report_reply_error;
2886 rc = yaml_emitter_emit(&debug, &event);
2890 done = (event.type == YAML_DOCUMENT_END_EVENT);
2893 yaml_document_t errmsg;
2895 rc = yaml_parser_load(reply, &errmsg);
2897 rc = yaml_emitter_dump(&debug, &errmsg);
2898 yaml_document_delete(&errmsg);
2902 yaml_emitter_log_error(&debug, stderr);
2904 yaml_emitter_delete(&debug);
2909 static int yaml_lnet_peer(char *prim_nid, char *nidstr, bool disable_mr,
2910 int health_value, int state, bool list_only,
2911 int version, int flags)
2913 struct nl_sock *sk = NULL;
2914 const char *msg = NULL;
2915 yaml_emitter_t output;
2916 yaml_parser_t reply;
2920 /* Create Netlink emitter to send request to kernel */
2921 sk = nl_socket_alloc();
2925 /* Setup parser to receive Netlink packets */
2926 rc = yaml_parser_initialize(&reply);
2932 rc = yaml_parser_set_input_netlink(&reply, sk, false);
2934 msg = yaml_parser_get_reader_error(&reply);
2938 /* Create Netlink emitter to send request to kernel */
2939 rc = yaml_emitter_initialize(&output);
2941 msg = "failed to initialize emitter";
2945 rc = yaml_emitter_set_output_netlink(&output, sk, LNET_GENL_NAME,
2946 version, LNET_CMD_PEERS, flags);
2950 yaml_emitter_open(&output);
2951 yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
2952 rc = yaml_emitter_emit(&output, &event);
2956 yaml_mapping_start_event_initialize(&event, NULL,
2957 (yaml_char_t *)YAML_MAP_TAG,
2958 1, YAML_ANY_MAPPING_STYLE);
2959 rc = yaml_emitter_emit(&output, &event);
2963 yaml_scalar_event_initialize(&event, NULL,
2964 (yaml_char_t *)YAML_STR_TAG,
2965 (yaml_char_t *)"peer",
2966 strlen("peer"), 1, 0,
2967 YAML_PLAIN_SCALAR_STYLE);
2968 rc = yaml_emitter_emit(&output, &event);
2973 yaml_sequence_start_event_initialize(&event, NULL,
2974 (yaml_char_t *)YAML_SEQ_TAG,
2976 YAML_BLOCK_SEQUENCE_STYLE);
2977 rc = yaml_emitter_emit(&output, &event);
2981 yaml_mapping_start_event_initialize(&event, NULL,
2982 (yaml_char_t *)YAML_MAP_TAG,
2984 YAML_BLOCK_MAPPING_STYLE);
2985 rc = yaml_emitter_emit(&output, &event);
2989 yaml_scalar_event_initialize(&event, NULL,
2990 (yaml_char_t *)YAML_STR_TAG,
2991 (yaml_char_t *)"primary nid",
2992 strlen("primary nid"), 1, 0,
2993 YAML_PLAIN_SCALAR_STYLE);
2994 rc = yaml_emitter_emit(&output, &event);
2998 yaml_scalar_event_initialize(&event, NULL,
2999 (yaml_char_t *)YAML_STR_TAG,
3000 (yaml_char_t *)prim_nid,
3001 strlen(prim_nid), 1, 0,
3002 YAML_PLAIN_SCALAR_STYLE);
3003 rc = yaml_emitter_emit(&output, &event);
3008 yaml_scalar_event_initialize(&event, NULL,
3009 (yaml_char_t *)YAML_STR_TAG,
3010 (yaml_char_t *)"Multi-Rail",
3011 strlen("Multi-Rail"), 1, 0,
3012 YAML_PLAIN_SCALAR_STYLE);
3013 rc = yaml_emitter_emit(&output, &event);
3017 yaml_scalar_event_initialize(&event, NULL,
3018 (yaml_char_t *)YAML_BOOL_TAG,
3019 (yaml_char_t *)"False",
3020 strlen("False"), 1, 0,
3021 YAML_PLAIN_SCALAR_STYLE);
3022 rc = yaml_emitter_emit(&output, &event);
3028 char peer_state[INT_STRING_LEN];
3030 yaml_scalar_event_initialize(&event, NULL,
3031 (yaml_char_t *)YAML_STR_TAG,
3032 (yaml_char_t *)"peer state",
3033 strlen("peer state"), 1, 0,
3034 YAML_PLAIN_SCALAR_STYLE);
3035 rc = yaml_emitter_emit(&output, &event);
3039 snprintf(peer_state, sizeof(peer_state), "%d", state);
3040 yaml_scalar_event_initialize(&event, NULL,
3041 (yaml_char_t *)YAML_INT_TAG,
3042 (yaml_char_t *)peer_state,
3043 strlen(peer_state), 1, 0,
3044 YAML_PLAIN_SCALAR_STYLE);
3045 rc = yaml_emitter_emit(&output, &event);
3050 if (!nidstr && health_value == -1)
3053 yaml_scalar_event_initialize(&event, NULL,
3054 (yaml_char_t *)YAML_STR_TAG,
3055 (yaml_char_t *)"peer ni",
3056 strlen("peer ni"), 1, 0,
3057 YAML_PLAIN_SCALAR_STYLE);
3058 rc = yaml_emitter_emit(&output, &event);
3062 yaml_sequence_start_event_initialize(&event, NULL,
3063 (yaml_char_t *)YAML_SEQ_TAG,
3064 1, YAML_BLOCK_SEQUENCE_STYLE);
3065 rc = yaml_emitter_emit(&output, &event);
3070 struct nid_node head, *entry;
3073 /* If we have LNET_ANY_NID and its NLM_F_REPLACE we
3074 * treat it as the all flag case for lnetctl peer set
3076 if (strcmp(nidstr, "<?>") == 0) {
3077 yaml_mapping_start_event_initialize(&event, NULL,
3078 (yaml_char_t *)YAML_MAP_TAG,
3079 1, YAML_BLOCK_MAPPING_STYLE);
3080 rc = yaml_emitter_emit(&output, &event);
3084 yaml_scalar_event_initialize(&event, NULL,
3085 (yaml_char_t *)YAML_STR_TAG,
3086 (yaml_char_t *)"nid",
3087 strlen("nid"), 1, 0,
3088 YAML_PLAIN_SCALAR_STYLE);
3089 rc = yaml_emitter_emit(&output, &event);
3093 yaml_scalar_event_initialize(&event, NULL,
3094 (yaml_char_t *)YAML_STR_TAG,
3095 (yaml_char_t *)nidstr,
3096 strlen(nidstr), 1, 0,
3097 YAML_PLAIN_SCALAR_STYLE);
3098 rc = yaml_emitter_emit(&output, &event);
3102 yaml_mapping_end_event_initialize(&event);
3103 rc = yaml_emitter_emit(&output, &event);
3110 NL_INIT_LIST_HEAD(&head.children);
3111 nl_init_list_head(&head.list);
3112 rc = lustre_lnet_parse_nid_range(&head, nidstr, &msg);
3114 fprintf(stdout, "can't parse nidrange: \"%s\"\n", nidstr);
3115 lustre_lnet_free_list(&head);
3116 yaml_emitter_delete(&output);
3122 if (nl_list_empty(&head.children)) {
3123 lustre_lnet_free_list(&head);
3124 yaml_emitter_delete(&output);
3125 msg = "Unable to parse nidlist: did not expand to any nids";
3130 rc = 1; /* one means its working */
3132 nl_list_for_each_entry(entry, &head.children, list) {
3133 char *nid = entry->nidstr;
3135 if (count++ > LNET_MAX_NIDS_PER_PEER) {
3136 lustre_lnet_free_list(&head);
3137 yaml_emitter_delete(&output);
3138 msg = "Unable to parse nidlist: specifies more NIDs than allowed";
3144 yaml_mapping_start_event_initialize(&event, NULL,
3145 (yaml_char_t *)YAML_MAP_TAG,
3146 1, YAML_BLOCK_MAPPING_STYLE);
3147 rc = yaml_emitter_emit(&output, &event);
3151 yaml_scalar_event_initialize(&event, NULL,
3152 (yaml_char_t *)YAML_STR_TAG,
3153 (yaml_char_t *)"nid",
3154 strlen("nid"), 1, 0,
3155 YAML_PLAIN_SCALAR_STYLE);
3156 rc = yaml_emitter_emit(&output, &event);
3160 yaml_scalar_event_initialize(&event, NULL,
3161 (yaml_char_t *)YAML_STR_TAG,
3164 YAML_PLAIN_SCALAR_STYLE);
3165 rc = yaml_emitter_emit(&output, &event);
3169 yaml_mapping_end_event_initialize(&event);
3170 rc = yaml_emitter_emit(&output, &event);
3174 lustre_lnet_free_list(&head);
3177 if (health_value >= 0) {
3178 char health[INT_STRING_LEN];
3180 /* Create the mapping for 'health stats'. The value field for
3181 * the mapping is not provided so its treated as a empty string.
3183 yaml_mapping_start_event_initialize(&event, NULL,
3184 (yaml_char_t *)YAML_MAP_TAG,
3185 1, YAML_BLOCK_MAPPING_STYLE);
3186 rc = yaml_emitter_emit(&output, &event);
3190 yaml_scalar_event_initialize(&event, NULL,
3191 (yaml_char_t *)YAML_STR_TAG,
3192 (yaml_char_t *)"health stats",
3193 strlen("health stats"), 1, 0,
3194 YAML_PLAIN_SCALAR_STYLE);
3195 rc = yaml_emitter_emit(&output, &event);
3199 /* Setup all mappings for data related to the 'health stats' */
3200 yaml_mapping_start_event_initialize(&event, NULL,
3201 (yaml_char_t *)YAML_MAP_TAG,
3202 1, YAML_BLOCK_MAPPING_STYLE);
3203 rc = yaml_emitter_emit(&output, &event);
3207 yaml_scalar_event_initialize(&event, NULL,
3208 (yaml_char_t *)YAML_STR_TAG,
3209 (yaml_char_t *)"health value",
3210 strlen("health value"), 1, 0,
3211 YAML_PLAIN_SCALAR_STYLE);
3212 rc = yaml_emitter_emit(&output, &event);
3216 snprintf(health, sizeof(health), "%d", health_value);
3217 yaml_scalar_event_initialize(&event, NULL,
3218 (yaml_char_t *)YAML_INT_TAG,
3219 (yaml_char_t *)health,
3220 strlen(health), 1, 0,
3221 YAML_PLAIN_SCALAR_STYLE);
3222 rc = yaml_emitter_emit(&output, &event);
3226 yaml_mapping_end_event_initialize(&event);
3227 rc = yaml_emitter_emit(&output, &event);
3231 yaml_mapping_end_event_initialize(&event);
3232 rc = yaml_emitter_emit(&output, &event);
3237 yaml_sequence_end_event_initialize(&event);
3238 rc = yaml_emitter_emit(&output, &event);
3242 yaml_mapping_end_event_initialize(&event);
3243 rc = yaml_emitter_emit(&output, &event);
3247 yaml_sequence_end_event_initialize(&event);
3248 rc = yaml_emitter_emit(&output, &event);
3252 yaml_scalar_event_initialize(&event, NULL,
3253 (yaml_char_t *)YAML_STR_TAG,
3256 YAML_PLAIN_SCALAR_STYLE);
3257 rc = yaml_emitter_emit(&output, &event);
3262 yaml_mapping_end_event_initialize(&event);
3263 rc = yaml_emitter_emit(&output, &event);
3267 yaml_document_end_event_initialize(&event, 0);
3268 rc = yaml_emitter_emit(&output, &event);
3272 rc = yaml_emitter_close(&output);
3275 yaml_emitter_log_error(&output, stderr);
3278 rc = yaml_lnet_peer_display(&reply, list_only);
3280 msg = yaml_parser_get_reader_error(&reply);
3281 /* If we didn't find any peers just be silent */
3282 if (msg && strcmp(msg, "No peers found") == 0)
3287 yaml_emitter_delete(&output);
3290 yaml_lnet_print_error(flags, "peer", msg);
3293 yaml_parser_delete(&reply);
3296 return rc == 1 ? 0 : rc;
3299 int yaml_lnet_config_peer_ni_healthv(int healthv, bool all, char *lpni_nid,
3300 int state, int seq_no, struct cYAML **err_rc)
3304 rc = yaml_lnet_peer(lpni_nid ? lpni_nid : "<?>", all ? "<?>" : NULL,
3305 false, healthv, state, false, LNET_GENL_VERSION,
3308 if (rc == -EOPNOTSUPP)
3314 rc = lustre_lnet_config_peer_ni_healthv(healthv, all, lpni_nid,
3317 rc = lustre_lnet_set_peer_state(state, lpni_nid, -1, err_rc);
3322 static int jt_set_peer_ni_value(int argc, char **argv)
3324 int rc = check_cmd(peer_cmds, "peer", "set", 0, argc, argv);
3329 return set_value_helper(argc, argv, LNET_CMD_PEERS,
3330 yaml_lnet_config_peer_ni_healthv);
3333 static int jt_show_recovery(int argc, char **argv)
3336 struct cYAML *err_rc = NULL, *show_rc = NULL;
3337 const char *const short_options = "lp";
3338 static const struct option long_options[] = {
3339 { .name = "local", .has_arg = no_argument, .val = 'l' },
3340 { .name = "peer", .has_arg = no_argument, .val = 'p' },
3343 rc = check_cmd(debug_cmds, "debug", "recovery", 0, argc, argv);
3347 while ((opt = getopt_long(argc, argv, short_options,
3348 long_options, NULL)) != -1) {
3351 rc = lustre_lnet_show_local_ni_recovq(-1, &show_rc, &err_rc);
3354 rc = lustre_lnet_show_peer_ni_recovq(-1, &show_rc, &err_rc);
3361 if (rc != LUSTRE_CFG_RC_NO_ERR)
3362 cYAML_print_tree2file(stderr, err_rc);
3364 cYAML_print_tree(show_rc);
3366 cYAML_free_tree(err_rc);
3367 cYAML_free_tree(show_rc);
3372 static int jt_show_peer_debug_info(int argc, char **argv)
3375 struct cYAML *err_rc = NULL;
3376 char *peer_nid = optarg;
3377 const char *const short_opts = "k";
3378 const struct option long_opts[] = {
3379 { .name = "nid", .has_arg = required_argument, .val = 'k' },
3382 rc = check_cmd(debug_cmds, "debug", "peer", 0, argc, argv);
3387 while ((opt = getopt_long(argc, argv, short_opts,
3388 long_opts, NULL)) != -1) {
3398 rc = lustre_lnet_show_peer_debug_info(peer_nid, -1, &err_rc);
3400 if (rc != LUSTRE_CFG_RC_NO_ERR)
3401 cYAML_print_tree2file(stderr, err_rc);
3403 cYAML_free_tree(err_rc);
3408 static int jt_show_net(int argc, char **argv)
3410 char *network = NULL;
3412 struct cYAML *err_rc = NULL, *show_rc = NULL;
3413 long int detail = 0;
3414 const char *const short_options = "n:v";
3415 static const struct option long_options[] = {
3416 { .name = "net", .has_arg = required_argument, .val = 'n' },
3417 { .name = "verbose", .has_arg = optional_argument, .val = 'v' },
3420 rc = check_cmd(net_cmds, "net", "show", 0, argc, argv);
3424 while ((opt = getopt_long(argc, argv, short_options,
3425 long_options, NULL)) != -1) {
3431 if ((!optarg) && (argv[optind] != NULL) &&
3432 (argv[optind][0] != '-')) {
3433 if (parse_long(argv[optind++], &detail) != 0)
3440 print_help(net_cmds, "net", "show");
3446 rc = yaml_lnet_config_ni(network, NULL, NULL, NULL, -1, NULL,
3447 detail, NLM_F_DUMP);
3449 if (rc != -EOPNOTSUPP)
3453 rc = lustre_lnet_show_net(network, (int) detail, -1, &show_rc, &err_rc,
3456 if (rc != LUSTRE_CFG_RC_NO_ERR)
3457 cYAML_print_tree2file(stderr, err_rc);
3459 cYAML_print_tree(show_rc);
3461 cYAML_free_tree(err_rc);
3462 cYAML_free_tree(show_rc);
3467 static int jt_show_routing(int argc, char **argv)
3469 struct cYAML *err_rc = NULL, *show_rc = NULL;
3472 rc = check_cmd(routing_cmds, "routing", "show", 0, argc, argv);
3476 rc = lustre_lnet_show_routing(-1, &show_rc, &err_rc, false);
3478 if (rc != LUSTRE_CFG_RC_NO_ERR)
3479 cYAML_print_tree2file(stderr, err_rc);
3481 cYAML_print_tree(show_rc);
3483 cYAML_free_tree(err_rc);
3484 cYAML_free_tree(show_rc);
3489 static int jt_show_stats(int argc, char **argv)
3492 struct cYAML *show_rc = NULL, *err_rc = NULL;
3494 rc = check_cmd(stats_cmds, "stats", "show", 0, argc, argv);
3498 rc = lustre_lnet_show_stats(-1, &show_rc, &err_rc);
3500 if (rc != LUSTRE_CFG_RC_NO_ERR)
3501 cYAML_print_tree2file(stderr, err_rc);
3503 cYAML_print_tree(show_rc);
3505 cYAML_free_tree(err_rc);
3506 cYAML_free_tree(show_rc);
3511 static int jt_show_udsp(int argc, char **argv)
3515 struct cYAML *err_rc = NULL, *show_rc = NULL;
3517 const char *const short_options = "i:";
3518 static const struct option long_options[] = {
3519 { .name = "idx", .has_arg = required_argument, .val = 'i' },
3523 rc = check_cmd(udsp_cmds, "udsp", "show", 0, argc, argv);
3527 while ((opt = getopt_long(argc, argv, short_options,
3528 long_options, NULL)) != -1) {
3531 rc = parse_long(optarg, &idx);
3532 if (rc != 0 || idx < -1) {
3533 printf("Invalid index \"%s\"\n", optarg);
3538 print_help(net_cmds, "net", "show");
3544 rc = lustre_lnet_show_udsp(idx, -1, &show_rc, &err_rc);
3546 if (rc != LUSTRE_CFG_RC_NO_ERR)
3547 cYAML_print_tree2file(stderr, err_rc);
3549 cYAML_print_tree(show_rc);
3551 cYAML_free_tree(err_rc);
3552 cYAML_free_tree(show_rc);
3557 static int jt_show_global(int argc, char **argv)
3560 struct cYAML *show_rc = NULL, *err_rc = NULL;
3562 rc = check_cmd(global_cmds, "global", "show", 0, argc, argv);
3566 rc = lustre_lnet_show_numa_range(-1, &show_rc, &err_rc);
3567 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3568 cYAML_print_tree2file(stderr, err_rc);
3572 rc = lustre_lnet_show_max_intf(-1, &show_rc, &err_rc);
3573 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3574 cYAML_print_tree2file(stderr, err_rc);
3578 rc = lustre_lnet_show_discovery(-1, &show_rc, &err_rc);
3579 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3580 cYAML_print_tree2file(stderr, err_rc);
3584 rc = lustre_lnet_show_drop_asym_route(-1, &show_rc, &err_rc);
3585 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3586 cYAML_print_tree2file(stderr, err_rc);
3590 rc = lustre_lnet_show_retry_count(-1, &show_rc, &err_rc);
3591 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3592 cYAML_print_tree2file(stderr, err_rc);
3596 rc = lustre_lnet_show_transaction_to(-1, &show_rc, &err_rc);
3597 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3598 cYAML_print_tree2file(stderr, err_rc);
3602 rc = lustre_lnet_show_hsensitivity(-1, &show_rc, &err_rc);
3603 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3604 cYAML_print_tree2file(stderr, err_rc);
3608 rc = lustre_lnet_show_recov_intrv(-1, &show_rc, &err_rc);
3609 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3610 cYAML_print_tree2file(stderr, err_rc);
3614 rc = lustre_lnet_show_rtr_sensitivity(-1, &show_rc, &err_rc);
3615 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3616 cYAML_print_tree2file(stderr, err_rc);
3620 rc = lustre_lnet_show_lnd_timeout(-1, &show_rc, &err_rc);
3621 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3622 cYAML_print_tree2file(stderr, err_rc);
3626 rc = lustre_lnet_show_response_tracking(-1, &show_rc, &err_rc);
3627 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3628 cYAML_print_tree2file(stderr, err_rc);
3632 rc = lustre_lnet_show_recovery_limit(-1, &show_rc, &err_rc);
3633 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3634 cYAML_print_tree2file(stderr, err_rc);
3638 rc = lustre_lnet_show_max_recovery_ping_interval(-1, &show_rc, &err_rc);
3639 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3640 cYAML_print_tree2file(stderr, err_rc);
3645 cYAML_print_tree(show_rc);
3648 cYAML_free_tree(err_rc);
3649 cYAML_free_tree(show_rc);
3654 static int jt_lnet(int argc, char **argv)
3658 rc = check_cmd(lnet_cmds, "lnet", NULL, 2, argc, argv);
3662 return cfs_parser(argc, argv, lnet_cmds);
3665 static int jt_route(int argc, char **argv)
3669 rc = check_cmd(route_cmds, "route", NULL, 2, argc, argv);
3673 return cfs_parser(argc, argv, route_cmds);
3676 static int jt_net(int argc, char **argv)
3680 rc = check_cmd(net_cmds, "net", NULL, 2, argc, argv);
3684 return cfs_parser(argc, argv, net_cmds);
3687 static int jt_routing(int argc, char **argv)
3691 rc = check_cmd(routing_cmds, "routing", NULL, 2, argc, argv);
3695 return cfs_parser(argc, argv, routing_cmds);
3698 static int jt_stats(int argc, char **argv)
3702 rc = check_cmd(stats_cmds, "stats", NULL, 2, argc, argv);
3706 return cfs_parser(argc, argv, stats_cmds);
3709 static int jt_debug(int argc, char **argv)
3713 rc = check_cmd(debug_cmds, "debug", NULL, 2, argc, argv);
3717 return cfs_parser(argc, argv, debug_cmds);
3720 static int jt_global(int argc, char **argv)
3724 rc = check_cmd(global_cmds, "global", NULL, 2, argc, argv);
3728 return cfs_parser(argc, argv, global_cmds);
3731 static int jt_peers(int argc, char **argv)
3735 rc = check_cmd(peer_cmds, "peer", NULL, 2, argc, argv);
3739 return cfs_parser(argc, argv, peer_cmds);
3742 static int jt_set(int argc, char **argv)
3746 rc = check_cmd(set_cmds, "set", NULL, 2, argc, argv);
3750 return cfs_parser(argc, argv, set_cmds);
3753 static int jt_udsp(int argc, char **argv)
3757 rc = check_cmd(udsp_cmds, "udsp", NULL, 2, argc, argv);
3761 return cfs_parser(argc, argv, udsp_cmds);
3764 static int jt_import(int argc, char **argv)
3767 struct cYAML *err_rc = NULL;
3768 struct cYAML *show_rc = NULL;
3769 int rc = 0, return_rc = 0, opt, opt_found = 0;
3770 char *yaml_blk = NULL, *buf, cmd = 'a';
3771 bool release = true;
3776 const char *const short_options = "adseh";
3777 static const struct option long_options[] = {
3778 { .name = "add", .has_arg = no_argument, .val = 'a' },
3779 { .name = "del", .has_arg = no_argument, .val = 'd' },
3780 { .name = "show", .has_arg = no_argument, .val = 's' },
3781 { .name = "exec", .has_arg = no_argument, .val = 'e' },
3782 { .name = "help", .has_arg = no_argument, .val = 'h' },
3786 while ((opt = getopt_long(argc, argv, short_options,
3787 long_options, NULL)) != -1) {
3801 printf("import FILE\n"
3802 "import < FILE : import a file\n"
3803 "\t--add: add configuration\n"
3804 "\t--del: delete configuration\n"
3805 "\t--show: show configuration\n"
3806 "\t--exec: execute command\n"
3807 "\t--help: display this help\n"
3808 "If no command option is given then --add"
3809 " is assumed by default\n");
3816 /* grab the file name if one exists */
3817 if (opt_found && argc == 3)
3819 else if (!opt_found && argc == 2)
3822 /* file always takes precedence */
3824 /* Set a file input. */
3825 input = fopen(file, "rb");
3828 snprintf(err_str, sizeof(err_str),
3829 "cannot open '%s': %s", file,
3831 cYAML_build_error(-1, -1, "yaml", "builder",
3840 /* assume that we're getting our input from stdin */
3841 rc = fstat(fileno(input), &st);
3843 snprintf(err_str, sizeof(err_str),
3844 "cannot get file stats '%s': %s", file,
3846 cYAML_build_error(-1, -1, "yaml", "builder",
3852 yaml_blk = buf = malloc(st.st_size);
3855 snprintf(err_str, sizeof(err_str),
3856 "failed to allocate buffer: %s",
3858 cYAML_build_error(-1, -1, "yaml", "builder",
3865 while (fgets(buf, len, input) != NULL) {
3866 char *seq = strstr(buf, "- ");
3872 skip = strspn(seq, " ");
3877 /* PyYAML format has libyaml free the
3888 rc = lustre_yaml_config(yaml_blk, st.st_size, &err_rc);
3889 return_rc = lustre_yaml_exec(yaml_blk, st.st_size, &show_rc,
3891 cYAML_print_tree(show_rc);
3892 cYAML_free_tree(show_rc);
3895 rc = lustre_yaml_del(yaml_blk, st.st_size, &err_rc);
3898 rc = lustre_yaml_show(yaml_blk, st.st_size, &show_rc,
3900 cYAML_print_tree(show_rc);
3901 cYAML_free_tree(show_rc);
3904 rc = lustre_yaml_exec(yaml_blk, st.st_size, &show_rc,
3906 cYAML_print_tree(show_rc);
3907 cYAML_free_tree(show_rc);
3911 if (yaml_blk && release)
3913 if (rc || return_rc) {
3914 cYAML_print_tree2file(stderr, err_rc);
3915 cYAML_free_tree(err_rc);
3921 static int jt_export(int argc, char **argv)
3923 struct cYAML *show_rc = NULL;
3924 struct cYAML *err_rc = NULL;
3928 bool backup = false;
3931 const char *const short_options = "bh";
3932 static const struct option long_options[] = {
3933 { .name = "backup", .has_arg = no_argument, .val = 'b' },
3934 { .name = "help", .has_arg = no_argument, .val = 'h' },
3937 while ((opt = getopt_long(argc, argv, short_options,
3938 long_options, NULL)) != -1) {
3945 printf("export > FILE.yaml : export configuration\n"
3946 "\t--backup: export only what's necessary for reconfig\n"
3947 "\t--help: display this help\n");
3952 if (backup && argc >= 3)
3954 else if (!backup && argc >= 2)
3960 f = fopen(file, "w");
3965 rc = lustre_lnet_show_net(NULL, 2, -1, &show_rc, &err_rc, backup);
3966 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3967 cYAML_print_tree2file(stderr, err_rc);
3968 cYAML_free_tree(err_rc);
3972 rc = lustre_lnet_show_route(NULL, NULL, -1, -1, 1, -1, &show_rc,
3974 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3975 cYAML_print_tree2file(stderr, err_rc);
3976 cYAML_free_tree(err_rc);
3980 rc = lustre_lnet_show_routing(-1, &show_rc, &err_rc, backup);
3981 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3982 cYAML_print_tree2file(stderr, err_rc);
3983 cYAML_free_tree(err_rc);
3987 rc = lustre_lnet_show_peer(NULL, 2, -1, &show_rc, &err_rc, backup);
3988 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3989 cYAML_print_tree2file(stderr, err_rc);
3990 cYAML_free_tree(err_rc);
3994 rc = lustre_lnet_show_numa_range(-1, &show_rc, &err_rc);
3995 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3996 cYAML_print_tree2file(stderr, err_rc);
3997 cYAML_free_tree(err_rc);
4001 rc = lustre_lnet_show_max_intf(-1, &show_rc, &err_rc);
4002 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4003 cYAML_print_tree2file(stderr, err_rc);
4004 cYAML_free_tree(err_rc);
4008 rc = lustre_lnet_show_discovery(-1, &show_rc, &err_rc);
4009 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4010 cYAML_print_tree2file(stderr, err_rc);
4011 cYAML_free_tree(err_rc);
4015 rc = lustre_lnet_show_drop_asym_route(-1, &show_rc, &err_rc);
4016 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4017 cYAML_print_tree2file(stderr, err_rc);
4018 cYAML_free_tree(err_rc);
4022 rc = lustre_lnet_show_retry_count(-1, &show_rc, &err_rc);
4023 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4024 cYAML_print_tree2file(stderr, err_rc);
4028 rc = lustre_lnet_show_transaction_to(-1, &show_rc, &err_rc);
4029 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4030 cYAML_print_tree2file(stderr, err_rc);
4034 rc = lustre_lnet_show_hsensitivity(-1, &show_rc, &err_rc);
4035 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4036 cYAML_print_tree2file(stderr, err_rc);
4040 rc = lustre_lnet_show_recov_intrv(-1, &show_rc, &err_rc);
4041 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4042 cYAML_print_tree2file(stderr, err_rc);
4046 rc = lustre_lnet_show_rtr_sensitivity(-1, &show_rc, &err_rc);
4047 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4048 cYAML_print_tree2file(stderr, err_rc);
4052 rc = lustre_lnet_show_lnd_timeout(-1, &show_rc, &err_rc);
4053 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4054 cYAML_print_tree2file(stderr, err_rc);
4058 rc = lustre_lnet_show_response_tracking(-1, &show_rc, &err_rc);
4059 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4060 cYAML_print_tree2file(stderr, err_rc);
4061 cYAML_free_tree(err_rc);
4065 rc = lustre_lnet_show_recovery_limit(-1, &show_rc, &err_rc);
4066 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4067 cYAML_print_tree2file(stderr, err_rc);
4068 cYAML_free_tree(err_rc);
4072 rc = lustre_lnet_show_max_recovery_ping_interval(-1, &show_rc, &err_rc);
4073 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4074 cYAML_print_tree2file(stderr, err_rc);
4075 cYAML_free_tree(err_rc);
4079 rc = lustre_lnet_show_udsp(-1, -1, &show_rc, &err_rc);
4080 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4081 cYAML_print_tree2file(stderr, err_rc);
4082 cYAML_free_tree(err_rc);
4086 if (show_rc != NULL) {
4087 cYAML_print_tree2file(f, show_rc);
4088 cYAML_free_tree(show_rc);
4097 static int jt_peer_nid_common(int argc, char **argv, int cmd)
4099 int flags = cmd == LNETCTL_ADD_CMD ? NLM_F_CREATE : 0;
4100 int rc = LUSTRE_CFG_RC_NO_ERR, opt;
4102 char *prim_nid = NULL, *nidstr = NULL;
4103 char err_str[LNET_MAX_STR_LEN] = "Error";
4104 struct cYAML *err_rc = NULL;
4106 const char *const short_opts = "k:m:n:f:l";
4107 const struct option long_opts[] = {
4108 { .name = "prim_nid", .has_arg = required_argument, .val = 'k' },
4109 { .name = "non_mr", .has_arg = no_argument, .val = 'm' },
4110 { .name = "nid", .has_arg = required_argument, .val = 'n' },
4111 { .name = "force", .has_arg = no_argument, .val = 'f' },
4112 { .name = "lock_prim", .has_arg = no_argument, .val = 'l' },
4115 rc = check_cmd(peer_cmds, "peer",
4116 cmd == LNETCTL_ADD_CMD ? "add" : "del", 2, argc, argv);
4120 while ((opt = getopt_long(argc, argv, short_opts,
4121 long_opts, NULL)) != -1) {
4130 if (cmd == LNETCTL_DEL_CMD) {
4131 rc = LUSTRE_CFG_RC_BAD_PARAM;
4132 snprintf(err_str, LNET_MAX_STR_LEN,
4133 "Unrecognized option '-%c'", opt);
4139 if (cmd == LNETCTL_ADD_CMD) {
4140 rc = LUSTRE_CFG_RC_BAD_PARAM;
4141 snprintf(err_str, LNET_MAX_STR_LEN,
4142 "Unrecognized option '-%c'", opt);
4145 flags |= NLM_F_EXCL;
4148 if (cmd == LNETCTL_DEL_CMD) {
4149 rc = LUSTRE_CFG_RC_BAD_PARAM;
4150 snprintf(err_str, LNET_MAX_STR_LEN,
4151 "Unrecognized option '-%c'", opt);
4154 flags |= NLM_F_EXCL;
4157 print_help(peer_cmds, "peer",
4158 cmd == LNETCTL_ADD_CMD ? "add" : "del");
4164 rc = yaml_lnet_peer(prim_nid, nidstr, !is_mr, -1, -1, false,
4165 LNET_GENL_VERSION, flags);
4167 if (rc == -EOPNOTSUPP)
4172 rc = lustre_lnet_modify_peer(prim_nid, nidstr, is_mr, cmd,
4173 force_lock, -1, &err_rc);
4174 if (rc != LUSTRE_CFG_RC_NO_ERR)
4178 cYAML_build_error(rc, -1, "peer",
4179 cmd == LNETCTL_ADD_CMD ? "add" : "del",
4183 if (rc != LUSTRE_CFG_RC_NO_ERR)
4184 cYAML_print_tree2file(stderr, err_rc);
4186 cYAML_free_tree(err_rc);
4191 static int jt_add_peer_nid(int argc, char **argv)
4193 return jt_peer_nid_common(argc, argv, LNETCTL_ADD_CMD);
4196 static int jt_del_peer_nid(int argc, char **argv)
4198 return jt_peer_nid_common(argc, argv, LNETCTL_DEL_CMD);
4201 static int jt_show_peer(int argc, char **argv)
4205 struct cYAML *err_rc = NULL, *show_rc = NULL;
4206 long int detail = 0;
4207 const char *const short_opts = "hn:v::";
4208 const struct option long_opts[] = {
4209 { .name = "help", .has_arg = no_argument, .val = 'h' },
4210 { .name = "nid", .has_arg = required_argument, .val = 'n' },
4211 { .name = "verbose", .has_arg = optional_argument, .val = 'v' },
4215 rc = check_cmd(peer_cmds, "peer", "show", 1, argc, argv);
4219 while ((opt = getopt_long(argc, argv, short_opts,
4220 long_opts, NULL)) != -1) {
4226 if ((!optarg) && (argv[optind] != NULL) &&
4227 (argv[optind][0] != '-')) {
4228 if (parse_long(argv[optind++], &detail) != 0)
4235 print_help(peer_cmds, "peer", "show");
4241 rc = yaml_lnet_peer(nid, NULL, false, -1, -1, false, detail,
4244 if (rc == -EOPNOTSUPP)
4249 rc = lustre_lnet_show_peer(nid, (int) detail, -1, &show_rc, &err_rc,
4252 if (rc != LUSTRE_CFG_RC_NO_ERR)
4253 cYAML_print_tree2file(stderr, err_rc);
4255 cYAML_print_tree(show_rc);
4257 cYAML_free_tree(err_rc);
4258 cYAML_free_tree(show_rc);
4263 static int jt_list_peer(int argc, char **argv)
4265 struct cYAML *err_rc = NULL, *list_rc = NULL;
4268 rc = check_cmd(peer_cmds, "peer", "list", 0, argc, argv);
4272 rc = yaml_lnet_peer(NULL, NULL, false, -1, -1, true, 0, NLM_F_DUMP);
4274 if (rc == -EOPNOTSUPP)
4280 rc = lustre_lnet_list_peer(-1, &list_rc, &err_rc);
4281 if (rc != LUSTRE_CFG_RC_NO_ERR)
4282 cYAML_print_tree2file(stderr, err_rc);
4284 cYAML_print_tree(list_rc);
4286 cYAML_free_tree(err_rc);
4287 cYAML_free_tree(list_rc);
4292 static int yaml_lnet_ping_display(yaml_parser_t *reply)
4294 yaml_emitter_t debug;
4299 rc = yaml_emitter_initialize(&debug);
4301 yaml_emitter_set_output_file(&debug, stdout);
4308 rc = yaml_parser_parse(reply, &event);
4310 goto report_reply_error;
4312 if (event.type != YAML_SCALAR_EVENT) {
4313 rc = yaml_emitter_emit(&debug, &event);
4317 done = (event.type == YAML_DOCUMENT_END_EVENT);
4321 if (strcmp((char *)event.data.scalar.value, "errno") == 0) {
4322 rc = yaml_emitter_emit(&debug, &event);
4326 rc = yaml_parser_parse(reply, &event);
4328 goto report_reply_error;
4330 rc = parse_long((char *)event.data.scalar.value,
4333 goto report_reply_error;
4335 rc = yaml_emitter_emit(&debug, &event);
4340 } else if (error != 0 &&
4341 strcmp((char *)event.data.scalar.value,
4343 rc = yaml_emitter_emit(&debug, &event);
4347 rc = yaml_parser_parse(reply, &event);
4349 goto report_reply_error;
4351 if (strncmp((char *)event.data.scalar.value,
4352 "failed to ", strlen("failed to ")) == 0) {
4355 snprintf(err, sizeof(err), "%s: %s",
4356 (char *)event.data.scalar.value,
4358 yaml_scalar_event_initialize(&event, NULL,
4359 (yaml_char_t *)YAML_STR_TAG,
4362 YAML_PLAIN_SCALAR_STYLE);
4364 rc = yaml_emitter_emit(&debug, &event);
4370 rc = yaml_emitter_emit(&debug, &event);
4377 yaml_emitter_log_error(&debug, stderr);
4379 yaml_emitter_delete(&debug);
4381 return rc2 ? rc2 : rc;
4384 static int yaml_lnet_ping(char *group, int timeout, char *src_nidstr,
4385 int start, int end, char **nids, int flags)
4387 struct nl_sock *sk = NULL;
4388 const char *msg = NULL;
4389 yaml_emitter_t output;
4390 yaml_parser_t reply;
4394 /* Create Netlink emitter to send request to kernel */
4395 sk = nl_socket_alloc();
4399 /* Setup parser to receive Netlink packets */
4400 rc = yaml_parser_initialize(&reply);
4406 rc = yaml_parser_set_input_netlink(&reply, sk, false);
4408 msg = yaml_parser_get_reader_error(&reply);
4412 /* Create Netlink emitter to send request to kernel */
4413 rc = yaml_emitter_initialize(&output);
4415 msg = "failed to initialize emitter";
4419 rc = yaml_emitter_set_output_netlink(&output, sk, LNET_GENL_NAME,
4420 LNET_GENL_VERSION, LNET_CMD_PING,
4425 yaml_emitter_open(&output);
4426 yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
4427 rc = yaml_emitter_emit(&output, &event);
4431 yaml_mapping_start_event_initialize(&event, NULL,
4432 (yaml_char_t *)YAML_MAP_TAG,
4433 1, YAML_ANY_MAPPING_STYLE);
4434 rc = yaml_emitter_emit(&output, &event);
4438 yaml_scalar_event_initialize(&event, NULL,
4439 (yaml_char_t *)YAML_STR_TAG,
4440 (yaml_char_t *)group,
4441 strlen(group), 1, 0,
4442 YAML_PLAIN_SCALAR_STYLE);
4443 rc = yaml_emitter_emit(&output, &event);
4447 yaml_mapping_start_event_initialize(&event, NULL,
4448 (yaml_char_t *)YAML_MAP_TAG,
4449 1, YAML_ANY_MAPPING_STYLE);
4450 rc = yaml_emitter_emit(&output, &event);
4454 if (timeout != 1000 || src_nidstr) {
4456 yaml_scalar_event_initialize(&event, NULL,
4457 (yaml_char_t *)YAML_STR_TAG,
4458 (yaml_char_t *)"source",
4459 strlen("source"), 1, 0,
4460 YAML_PLAIN_SCALAR_STYLE);
4461 rc = yaml_emitter_emit(&output, &event);
4465 yaml_scalar_event_initialize(&event, NULL,
4466 (yaml_char_t *)YAML_STR_TAG,
4467 (yaml_char_t *)src_nidstr,
4468 strlen(src_nidstr), 1, 0,
4469 YAML_PLAIN_SCALAR_STYLE);
4470 rc = yaml_emitter_emit(&output, &event);
4475 if (timeout != 1000) {
4478 yaml_scalar_event_initialize(&event, NULL,
4479 (yaml_char_t *)YAML_STR_TAG,
4480 (yaml_char_t *)"timeout",
4481 strlen("timeout"), 1, 0,
4482 YAML_PLAIN_SCALAR_STYLE);
4483 rc = yaml_emitter_emit(&output, &event);
4487 snprintf(time, sizeof(time), "%u", timeout);
4488 yaml_scalar_event_initialize(&event, NULL,
4489 (yaml_char_t *)YAML_INT_TAG,
4490 (yaml_char_t *)time,
4492 YAML_PLAIN_SCALAR_STYLE);
4493 rc = yaml_emitter_emit(&output, &event);
4499 yaml_scalar_event_initialize(&event, NULL,
4500 (yaml_char_t *)YAML_STR_TAG,
4501 (yaml_char_t *)"nids",
4502 strlen("nids"), 1, 0,
4503 YAML_PLAIN_SCALAR_STYLE);
4504 rc = yaml_emitter_emit(&output, &event);
4508 yaml_sequence_start_event_initialize(&event, NULL,
4509 (yaml_char_t *)YAML_SEQ_TAG,
4510 1, YAML_FLOW_SEQUENCE_STYLE);
4511 rc = yaml_emitter_emit(&output, &event);
4515 for (i = start; i < end; i++) {
4516 yaml_scalar_event_initialize(&event, NULL,
4517 (yaml_char_t *)YAML_STR_TAG,
4518 (yaml_char_t *)nids[i],
4519 strlen(nids[i]), 1, 0,
4520 YAML_PLAIN_SCALAR_STYLE);
4521 rc = yaml_emitter_emit(&output, &event);
4526 yaml_sequence_end_event_initialize(&event);
4527 rc = yaml_emitter_emit(&output, &event);
4531 yaml_mapping_end_event_initialize(&event);
4532 rc = yaml_emitter_emit(&output, &event);
4536 yaml_mapping_end_event_initialize(&event);
4537 rc = yaml_emitter_emit(&output, &event);
4541 yaml_document_end_event_initialize(&event, 0);
4542 rc = yaml_emitter_emit(&output, &event);
4546 rc = yaml_emitter_close(&output);
4549 yaml_emitter_log_error(&output, stderr);
4552 rc = yaml_lnet_ping_display(&reply);
4554 msg = yaml_parser_get_reader_error(&reply);
4556 yaml_emitter_delete(&output);
4559 yaml_lnet_print_error(-1, group, msg);
4563 yaml_parser_delete(&reply);
4566 return rc == 1 ? 0 : rc;
4569 static int jt_ping(int argc, char **argv)
4571 struct cYAML *err_rc = NULL;
4572 struct cYAML *show_rc = NULL;
4575 char *src_nidstr = NULL;
4576 const char *const short_options = "hs:t:";
4577 const struct option long_options[] = {
4578 { .name = "help", .has_arg = no_argument, .val = 'h' },
4579 { .name = "timeout", .has_arg = required_argument, .val = 't' },
4580 { .name = "source", .has_arg = required_argument, .val = 's' },
4584 while ((opt = getopt_long(argc, argv, short_options,
4585 long_options, NULL)) != -1) {
4588 src_nidstr = optarg;
4591 timeout = 1000 * atol(optarg);
4594 printf("ping nid[,nid,...]\n"
4595 "\t --source: source nid\n"
4596 "\t --timeout: ping timeout\n"
4597 "\t --help: display this help\n");
4604 rc = yaml_lnet_ping("ping", timeout, src_nidstr, optind, argc,
4607 if (rc != -EOPNOTSUPP)
4611 for (; optind < argc; optind++)
4612 rc = lustre_lnet_ping_nid(argv[optind], src_nidstr, timeout, -1,
4616 cYAML_print_tree(show_rc);
4619 cYAML_print_tree2file(stderr, err_rc);
4621 cYAML_free_tree(err_rc);
4622 cYAML_free_tree(show_rc);
4627 static int jt_discover(int argc, char **argv)
4629 struct cYAML *err_rc = NULL;
4630 struct cYAML *show_rc = NULL;
4631 int flags = NLM_F_CREATE;
4634 const char *const short_options = "fh";
4635 const struct option long_options[] = {
4636 { .name = "force", .has_arg = no_argument, .val = 'f' },
4637 { .name = "help", .has_arg = no_argument, .val = 'h' },
4641 while ((opt = getopt_long(argc, argv, short_options,
4642 long_options, NULL)) != -1) {
4645 /* BSD treats NLM_F_CREATE | NLM_F_EXCL as an add */
4646 flags |= NLM_F_EXCL;
4650 printf("discover nid[,nid,...]\n"
4651 "\t --force: force discovery\n"
4652 "\t --help: display this help\n");
4659 if (optind == argc) {
4660 printf("Missing nid argument\n");
4664 rc = yaml_lnet_ping("discover", 1000, NULL, optind, argc, argv,
4667 if (rc != -EOPNOTSUPP)
4671 for (; optind < argc; optind++)
4672 rc = lustre_lnet_discover_nid(argv[optind], force, -1, &show_rc,
4676 cYAML_print_tree(show_rc);
4679 cYAML_print_tree2file(stderr, err_rc);
4681 cYAML_free_tree(err_rc);
4682 cYAML_free_tree(show_rc);
4687 static int jt_add_udsp(int argc, char **argv)
4689 char *src = NULL, *dst = NULL, *rte = NULL;
4690 struct cYAML *err_rc = NULL;
4691 union lnet_udsp_action udsp_action;
4692 long int idx = -1, priority = -1;
4694 char *action_type = "pref";
4696 const char *const short_options = "s:d:r:p:i:";
4697 static const struct option long_options[] = {
4698 { .name = "src", .has_arg = required_argument, .val = 's' },
4699 { .name = "dst", .has_arg = required_argument, .val = 'd' },
4700 { .name = "rte", .has_arg = required_argument, .val = 'r' },
4701 { .name = "priority", .has_arg = required_argument, .val = 'p' },
4702 { .name = "idx", .has_arg = required_argument, .val = 'i' },
4705 rc = check_cmd(udsp_cmds, "udsp", "add", 0, argc, argv);
4709 while ((opt = getopt_long(argc, argv, short_options,
4710 long_options, NULL)) != -1) {
4722 rc = parse_long(optarg, &priority);
4723 if (rc != 0 || priority < 0) {
4724 printf("Invalid priority \"%s\"\n", optarg);
4727 action_type = "priority";
4728 udsp_action.udsp_priority = priority;
4731 rc = parse_long(optarg, &idx);
4732 if (rc != 0 || idx < 0) {
4733 printf("Invalid index \"%s\"\n", optarg);
4738 print_help(udsp_cmds, "udsp", "add");
4744 if (!(src || dst || rte)) {
4745 print_help(udsp_cmds, "udsp", "add");
4749 rc = lustre_lnet_add_udsp(src, dst, rte, action_type, &udsp_action,
4752 if (rc != LUSTRE_CFG_RC_NO_ERR)
4753 cYAML_print_tree2file(stderr, err_rc);
4755 cYAML_free_tree(err_rc);
4760 static int jt_del_udsp(int argc, char **argv)
4762 struct cYAML *err_rc = NULL;
4767 const char *const short_options = "ai:";
4768 static const struct option long_options[] = {
4769 { .name = "all", .has_arg = no_argument, .val = 'a' },
4770 { .name = "idx", .has_arg = required_argument, .val = 'i' },
4773 rc = check_cmd(udsp_cmds, "udsp", "del", 0, argc, argv);
4777 while ((opt = getopt_long(argc, argv, short_options,
4778 long_options, NULL)) != -1) {
4784 rc = parse_long(optarg, &idx);
4785 if (rc != 0 || idx < -1) {
4786 printf("Invalid index \"%s\"\n", optarg);
4791 print_help(udsp_cmds, "udsp", "del");
4797 if (all && idx != -2) {
4798 printf("Cannot combine --all with --idx\n");
4802 } else if (idx == -2) {
4803 printf("Must specify --idx or --all\n");
4807 rc = lustre_lnet_del_udsp(idx, -1, &err_rc);
4808 if (rc != LUSTRE_CFG_RC_NO_ERR)
4809 cYAML_print_tree2file(stderr, err_rc);
4811 cYAML_free_tree(err_rc);
4816 int main(int argc, char **argv)
4819 struct cYAML *err_rc = NULL;
4821 rc = lustre_lnet_config_lib_init();
4823 cYAML_build_error(-1, -1, "lnetctl", "startup",
4824 "cannot register LNet device", &err_rc);
4825 cYAML_print_tree2file(stderr, err_rc);
4829 return cfs_parser(argc, argv, cmd_list);