1 // SPDX-License-Identifier: LGPL-2.0
4 * Copyright (c) 2014, 2017, Intel Corporation.
8 * This file is part of Lustre, http://www.lustre.org/
10 * Author: Amir Shehata <amir.shehata@intel.com>
19 #include <libcfs/util/ioctl.h>
20 #include <libcfs/util/parser.h>
21 #include "lnetconfig/cyaml.h"
22 #include "lnetconfig/liblnetconfig.h"
24 #define LNET_CONFIGURE true
25 #define LNET_UNCONFIGURE false
27 #ifndef NLM_F_DUMP_FILTERED
28 #define NLM_F_DUMP_FILTERED 0x20
31 static int jt_config_lnet(int argc, char **argv);
32 static int jt_unconfig_lnet(int argc, char **argv);
33 static int jt_add_route(int argc, char **argv);
34 static int jt_add_ni(int argc, char **argv);
35 static int jt_set_routing(int argc, char **argv);
36 static int jt_del_route(int argc, char **argv);
37 static int jt_del_ni(int argc, char **argv);
38 static int jt_show_route(int argc, char **argv);
39 static int jt_show_net(int argc, char **argv);
40 static int jt_show_routing(int argc, char **argv);
41 static int jt_show_stats(int argc, char **argv);
42 static int jt_show_peer(int argc, char **argv);
43 static int jt_show_recovery(int argc, char **argv);
44 static int jt_show_global(int argc, char **argv);
45 static int jt_show_udsp(int argc, char **argv);
46 static int jt_set_tiny(int argc, char **argv);
47 static int jt_set_small(int argc, char **argv);
48 static int jt_set_large(int argc, char **argv);
49 static int jt_set_numa(int argc, char **argv);
50 static int jt_set_retry_count(int argc, char **argv);
51 static int jt_set_transaction_to(int argc, char **argv);
52 static int jt_set_recov_intrv(int argc, char **argv);
53 static int jt_set_rtr_sensitivity(int argc, char **argv);
54 static int jt_set_hsensitivity(int argc, char **argv);
55 static int jt_set_max_recovery_ping_interval(int argc, char **argv);
56 static int jt_reset_stats(int argc, char **argv);
57 static int jt_add_peer_nid(int argc, char **argv);
58 static int jt_del_peer_nid(int argc, char **argv);
59 static int jt_set_max_intf(int argc, char **argv);
60 static int jt_set_discovery(int argc, char **argv);
61 static int jt_set_drop_asym_route(int argc, char **argv);
62 static int jt_list_peer(int argc, char **argv);
63 static int jt_add_udsp(int argc, char **argv);
64 static int jt_del_udsp(int argc, char **argv);
65 /*static int jt_show_peer(int argc, char **argv);*/
66 static int jt_import(int argc, char **argv);
67 static int jt_export(int argc, char **argv);
68 static int jt_ping(int argc, char **argv);
69 static int jt_discover(int argc, char **argv);
70 static int jt_lnet(int argc, char **argv);
71 static int jt_route(int argc, char **argv);
72 static int jt_net(int argc, char **argv);
73 static int jt_routing(int argc, char **argv);
74 static int jt_set(int argc, char **argv);
75 static int jt_debug(int argc, char **argv);
76 static int jt_stats(int argc, char **argv);
77 static int jt_global(int argc, char **argv);
78 static int jt_peers(int argc, char **argv);
79 static int jt_set_ni_value(int argc, char **argv);
80 static int jt_set_peer_ni_value(int argc, char **argv);
81 static int jt_calc_service_id(int argc, char **argv);
82 static int jt_set_response_tracking(int argc, char **argv);
83 static int jt_set_recovery_limit(int argc, char **argv);
84 static int jt_udsp(int argc, char **argv);
85 static int jt_setup_mrrouting(int argc, char **argv);
86 static int jt_calc_cpt_of_nid(int argc, char **argv);
87 static int jt_show_peer_debug_info(int argc, char **argv);
89 command_t cmd_list[] = {
90 {"lnet", jt_lnet, 0, "lnet {configure | unconfigure} [--all]"},
91 {"route", jt_route, 0, "route {add | del | show | help}"},
92 {"net", jt_net, 0, "net {add | del | show | set | help}"},
93 {"routing", jt_routing, 0, "routing {show | help}"},
94 {"set", jt_set, 0, "set {tiny_buffers | small_buffers | large_buffers"
95 " | routing | numa_range | max_interfaces"
96 " | discovery | drop_asym_route | retry_count"
97 " | transaction_timeout | health_sensitivity"
98 " | recovery_interval | router_sensitivity"
99 " | response_tracking | recovery_limit}"},
100 {"import", jt_import, 0, "import FILE.yaml"},
101 {"export", jt_export, 0, "export FILE.yaml"},
102 {"stats", jt_stats, 0, "stats {show | help}"},
103 {"debug", jt_debug, 0, "debug {recovery {local | peer} | peer}"},
104 {"global", jt_global, 0, "global {show | help}"},
105 {"peer", jt_peers, 0, "peer {add | del | show | list | set | help}"},
106 {"ping", jt_ping, 0, "ping nid,[nid,...]"},
107 {"discover", jt_discover, 0, "discover nid[,nid,...]"},
108 {"service-id", jt_calc_service_id, 0, "Calculate IB Lustre service ID\n"},
109 {"udsp", jt_udsp, 0, "udsp {add | del | help}"},
110 {"setup-mrrouting", jt_setup_mrrouting, 0,
111 "setup linux routing tables\n"},
112 {"cpt-of-nid", jt_calc_cpt_of_nid, 0,
113 "Calculate the CPTs associated with NIDs\n"
114 " usage:\n\tlnetctl cpt-of-nid nid[ nid ...]\n"},
118 command_t lnet_cmds[] = {
119 {"configure", jt_config_lnet, 0, "configure lnet\n"
120 "\t--all: load NI configuration from module parameters\n"},
121 {"unconfigure", jt_unconfig_lnet, 0, "unconfigure lnet\n"},
125 command_t route_cmds[] = {
126 {"add", jt_add_route, 0, "add a route\n"
127 "\t--net: net name (e.g. tcp0)\n"
128 "\t--gateway: gateway nid (e.g. 10.1.1.2@tcp)\n"
129 "\t--hop|hop-count: number to final destination (1 <= hops <= 255)\n"
130 "\t--priority: priority of route (0 - highest prio\n"
131 "\t--health_sensitivity: gateway health sensitivity (>= 1)\n"},
132 {"del", jt_del_route, 0, "delete a route\n"
133 "\t--net: net name (e.g. tcp0)\n"
134 "\t--gateway: gateway nid (e.g. 10.1.1.2@tcp)\n"},
135 {"show", jt_show_route, 0, "show routes\n"
136 "\t--net: net name (e.g. tcp0) to filter on\n"
137 "\t--gateway: gateway nid (e.g. 10.1.1.2@tcp) to filter on\n"
138 "\t--hop|hop-count: number to final destination (1 <= hops <= 255) to filter on\n"
139 "\t--priority: priority of route (0 - highest prio to filter on\n"
140 "\t--verbose: display detailed output per route\n"},
144 command_t net_cmds[] = {
145 {"add", jt_add_ni, 0, "add a network\n"
146 "\t--net: net name (e.g. tcp0)\n"
147 "\t--if: physical interface (e.g. eth0)\n"
148 "\t--nid: bring up NI based on the address of the specified LNet NID\n"
149 "\t--ip2net: specify networks based on IP address patterns\n"
150 "\t--peer-timeout: time to wait before declaring a peer dead\n"
151 "\t--peer-credits: define the max number of inflight messages\n"
152 "\t--peer-buffer-credits: the number of buffer credits per peer\n"
153 "\t--credits: Network Interface credits\n"
154 "\t--cpt: CPU Partitions configured net uses (e.g. [0,1]\n"
155 "\t--conns-per-peer: number of connections per peer\n"
156 "\t--skip-mr-route-setup: do not add linux route for the ni\n"
157 "\t--auth-key: Network authorization key (kfilnd only)\n"
158 "\t--traffic-class: Traffic class (kfilnd only)\n"},
159 {"del", jt_del_ni, 0, "delete a network\n"
160 "\t--net: net name (e.g. tcp0)\n"
161 "\t--nid: shutdown NI based on the address of the specified LNet NID\n"
162 "\t--if: physical interface (e.g. eth0)\n"},
163 {"show", jt_show_net, 0, "show networks\n"
164 "\t--net: net name (e.g. tcp0) to filter on\n"
165 "\t--verbose: display detailed output per network."
166 " Optional argument of '2' outputs more stats\n"},
167 {"set", jt_set_ni_value, 0, "set local NI specific parameter\n"
168 "\t--nid: NI NID to set the\n"
169 "\t--health: specify health value to set\n"
170 "\t--conns-per-peer: number of connections per peer\n"
171 "\t--all: set all NIs value to the one specified\n"},
175 command_t routing_cmds[] = {
176 {"show", jt_show_routing, 0, "show routing information\n"},
180 command_t stats_cmds[] = {
181 {"show", jt_show_stats, 0, "show LNET statistics\n"},
182 {"reset", jt_reset_stats, 0, "reset LNET statistics\n"},
186 command_t debug_cmds[] = {
187 {"recovery", jt_show_recovery, 0, "list recovery queues\n"
188 "\t--local : list local recovery queue\n"
189 "\t--peer : list peer recovery queue\n"},
190 {"peer", jt_show_peer_debug_info, 0, "show peer debug info\n"
191 "\t--nid: peer's NID\n"},
195 command_t global_cmds[] = {
196 {"show", jt_show_global, 0, "show global variables\n"},
200 command_t set_cmds[] = {
201 {"tiny_buffers", jt_set_tiny, 0, "set tiny routing buffers\n"
202 "\tVALUE must be greater than 0\n"},
203 {"small_buffers", jt_set_small, 0, "set small routing buffers\n"
204 "\tVALUE must be greater than 0\n"},
205 {"large_buffers", jt_set_large, 0, "set large routing buffers\n"
206 "\tVALUE must be greater than 0\n"},
207 {"routing", jt_set_routing, 0, "enable/disable routing\n"
208 "\t0 - disable routing\n"
209 "\t1 - enable routing\n"},
210 {"numa_range", jt_set_numa, 0, "set NUMA range for NI selection\n"
211 "\tVALUE must be at least 0\n"},
212 {"max_interfaces", jt_set_max_intf, 0, "set the default value for "
214 "\tValue must be greater than 16\n"},
215 {"discovery", jt_set_discovery, 0, "enable/disable peer discovery\n"
216 "\t0 - disable peer discovery\n"
217 "\t1 - enable peer discovery (default)\n"},
218 {"drop_asym_route", jt_set_drop_asym_route, 0,
219 "drop/accept asymmetrical route messages\n"
220 "\t0 - accept asymmetrical route messages (default)\n"
221 "\t1 - drop asymmetrical route messages\n"},
222 {"retry_count", jt_set_retry_count, 0, "number of retries\n"
223 "\t0 - turn of retries\n"
224 "\t>0 - number of retries\n"},
225 {"transaction_timeout", jt_set_transaction_to, 0, "Message/Response timeout\n"
226 "\t>0 - timeout in seconds\n"},
227 {"health_sensitivity", jt_set_hsensitivity, 0, "sensitivity to failure\n"
228 "\t0 - turn off health evaluation\n"
229 "\t>0 - sensitivity value not more than 1000\n"},
230 {"recovery_interval", jt_set_recov_intrv, 0, "interval to ping in seconds (at least 1)\n"
231 "\t>0 - time in seconds between pings\n"},
232 {"router_sensitivity", jt_set_rtr_sensitivity, 0, "router sensitivity %\n"
233 "\t100 - router interfaces need to be fully healthy to be used\n"
234 "\t<100 - router interfaces can be used even if not healthy\n"},
235 {"response_tracking", jt_set_response_tracking, 0,
236 "Set the behavior of response tracking\n"
237 "\t0 - Only LNet pings and discovery pushes utilize response tracking\n"
238 "\t1 - GETs are eligible for response tracking\n"
239 "\t2 - PUTs are eligible for response tracking\n"
240 "\t3 - Both PUTs and GETs are eligible for response tracking (default)\n"
241 "\tNote: Regardless of the value of the response_tracking parameter LNet\n"
242 "\t pings and discovery pushes always utilize response tracking\n"},
243 {"recovery_limit", jt_set_recovery_limit, 0,
244 "Set how long LNet will attempt to recover unhealthy interfaces.\n"
245 "\t0 - Recover indefinitely (default)\n"
246 "\t>0 - Recover for the specified number of seconds.\n"},
247 {"max_recovery_ping_interval", jt_set_max_recovery_ping_interval, 0,
248 "maximum recovery ping interval\n"
249 "\t>0 - maximum recovery ping interval in seconds\n"},
253 command_t peer_cmds[] = {
254 {"add", jt_add_peer_nid, 0, "add a peer NID\n"
255 "\t--prim_nid: Primary NID of the peer.\n"
256 "\t--nid: one or more peer NIDs\n"
257 "\t--non_mr: create this peer as not Multi-Rail capable\n"
258 "\t--ip2nets: specify a range of nids per peer\n"
259 "\t--lock_prim: lock primary nid\n"},
260 {"del", jt_del_peer_nid, 0, "delete a peer NID\n"
261 "\t--prim_nid: Primary NID of the peer.\n"
262 "\t--nid: list of NIDs to remove. If none provided,\n"
263 "\t peer is deleted\n"
264 "\t--ip2nets: specify a range of nids per peer\n"
265 "\t--force: force-delete locked primary NID\n"},
266 {"show", jt_show_peer, 0, "show peer information\n"
267 "\t--nid: NID of peer to filter on.\n"
268 "\t--verbose: display detailed output per peer."
269 " Optional argument of '2' outputs more stats\n"},
270 {"list", jt_list_peer, 0, "list all peers\n"},
271 {"set", jt_set_peer_ni_value, 0, "set peer ni specific parameter\n"
272 "\t--nid: Peer NI NID to set the\n"
273 "\t--health: specify health value to set\n"
274 "\t--all: set all peer_nis values to the one specified\n"
275 "\t--state: set peer state (DANGEROUS: for test/debug only)"},
279 command_t udsp_cmds[] = {
280 {"add", jt_add_udsp, 0, "add a udsp\n"
281 "\t--src nid|net: ip2nets syntax specifying the local NID or network to match.\n"
282 "\t--dst nid: ip2nets syntax specifying the remote NID to match.\n"
283 "\t--rte nid: ip2nets syntax specifying the router NID to match.\n"
284 "\t--priority p: Assign priority value p where p >= 0.\n"
285 "\t Note: 0 is the highest priority.\n"
286 "\t--idx n: Insert the rule in the n'th position on the list of rules.\n"
287 "\t By default, rules are appended to the end of the rule list.\n"},
288 {"del", jt_del_udsp, 0, "delete a udsp\n"
289 "\t--all: Delete all rules.\n"
290 "\t--idx n: Delete the rule at index n.\n"},
291 {"show", jt_show_udsp, 0, "show udsps\n"
292 "\t--idx n: Show the rule at at index n.\n"
293 "\t By default, all rules are shown.\n"},
297 static int parse_long(const char *number, long int *value)
304 *value = strtol(number, &end, 0);
305 if (end != NULL && *end != 0)
311 static int jt_setup_mrrouting(int argc, char **argv)
314 struct cYAML *err_rc = NULL;
316 rc = lustre_lnet_setup_mrrouting(&err_rc);
318 if (rc != LUSTRE_CFG_RC_NO_ERR)
319 cYAML_print_tree2file(stderr, err_rc);
321 cYAML_free_tree(err_rc);
326 static inline void print_help(const command_t cmds[], const char *cmd_type,
329 const command_t *cmd;
331 for (cmd = cmds; cmd->pc_name; cmd++) {
332 if (pc_name != NULL &&
333 strcmp(cmd->pc_name, pc_name) == 0) {
334 printf("%s %s: %s\n", cmd_type, cmd->pc_name,
337 } else if (pc_name != NULL) {
340 printf("%s %s: %s\n", cmd_type, cmd->pc_name, cmd->pc_help);
344 static int check_cmd(const command_t *cmd_list, const char *cmd,
345 const char *sub_cmd, const int min_args,
346 int argc, char **argv)
353 const char *const short_options = "h";
354 static const struct option long_options[] = {
355 { .name = "help", .has_arg = no_argument, .val = 'h' },
359 if (argc < min_args) {
360 print_help(cmd_list, cmd, sub_cmd);
361 rc = LUSTRE_CFG_RC_BAD_PARAM;
363 } else if (argc > 2) {
367 while ((opt = getopt_long(argc, argv, short_options,
368 long_options, NULL)) != -1) {
371 print_help(cmd_list, cmd, sub_cmd);
386 static int jt_set_response_tracking(int argc, char **argv)
390 struct cYAML *err_rc = NULL;
392 rc = check_cmd(set_cmds, "set", "response_tracking", 2, argc, argv);
396 rc = parse_long(argv[1], &value);
398 cYAML_build_error(-1, -1, "parser", "set",
399 "cannot parse response_tracking value",
401 cYAML_print_tree2file(stderr, err_rc);
402 cYAML_free_tree(err_rc);
406 rc = lustre_lnet_config_response_tracking(value, -1, &err_rc);
407 if (rc != LUSTRE_CFG_RC_NO_ERR)
408 cYAML_print_tree2file(stderr, err_rc);
410 cYAML_free_tree(err_rc);
415 static int jt_calc_service_id(int argc, char **argv)
420 rc = lustre_lnet_calc_service_id(&service_id);
421 if (rc != LUSTRE_CFG_RC_NO_ERR)
424 /* cYAML currently doesn't support printing hex values.
425 * Therefore just print it locally here
427 printf("service_id:\n value: 0x%llx\n",
428 (unsigned long long)(service_id));
433 static int jt_set_recovery_limit(int argc, char **argv)
437 struct cYAML *err_rc = NULL;
439 rc = check_cmd(set_cmds, "set", "recovery_limit", 2, argc, argv);
443 rc = parse_long(argv[1], &value);
445 cYAML_build_error(-1, -1, "parser", "set",
446 "cannot parse recovery_limit value",
448 cYAML_print_tree2file(stderr, err_rc);
449 cYAML_free_tree(err_rc);
453 rc = lustre_lnet_config_recovery_limit(value, -1, &err_rc);
454 if (rc != LUSTRE_CFG_RC_NO_ERR)
455 cYAML_print_tree2file(stderr, err_rc);
457 cYAML_free_tree(err_rc);
462 static int jt_set_max_intf(int argc, char **argv)
466 struct cYAML *err_rc = NULL;
468 rc = check_cmd(set_cmds, "set", "max_interfaces", 2, argc, argv);
472 rc = parse_long(argv[1], &value);
474 cYAML_build_error(-1, -1, "parser", "set",
475 "cannot parse max_interfaces value", &err_rc);
476 cYAML_print_tree2file(stderr, err_rc);
477 cYAML_free_tree(err_rc);
481 rc = lustre_lnet_config_max_intf(value, -1, &err_rc);
482 if (rc != LUSTRE_CFG_RC_NO_ERR)
483 cYAML_print_tree2file(stderr, err_rc);
485 cYAML_free_tree(err_rc);
490 static int jt_set_numa(int argc, char **argv)
494 struct cYAML *err_rc = NULL;
496 rc = check_cmd(set_cmds, "set", "numa_range", 2, argc, argv);
500 rc = parse_long(argv[1], &value);
502 cYAML_build_error(-1, -1, "parser", "set",
503 "cannot parse numa_range value", &err_rc);
504 cYAML_print_tree2file(stderr, err_rc);
505 cYAML_free_tree(err_rc);
509 rc = lustre_lnet_config_numa_range(value, -1, &err_rc);
510 if (rc != LUSTRE_CFG_RC_NO_ERR)
511 cYAML_print_tree2file(stderr, err_rc);
513 cYAML_free_tree(err_rc);
518 static int jt_set_recov_intrv(int argc, char **argv)
522 struct cYAML *err_rc = NULL;
524 rc = check_cmd(set_cmds, "set", "recovery_interval", 2, argc, argv);
528 rc = parse_long(argv[1], &value);
530 cYAML_build_error(-1, -1, "parser", "set",
531 "cannot parse recovery interval value", &err_rc);
532 cYAML_print_tree2file(stderr, err_rc);
533 cYAML_free_tree(err_rc);
537 rc = lustre_lnet_config_recov_intrv(value, -1, &err_rc);
538 if (rc != LUSTRE_CFG_RC_NO_ERR)
539 cYAML_print_tree2file(stderr, err_rc);
541 cYAML_free_tree(err_rc);
546 static int jt_set_rtr_sensitivity(int argc, char **argv)
550 struct cYAML *err_rc = NULL;
552 rc = check_cmd(set_cmds, "set", "router_sensitivity", 2, argc, argv);
556 rc = parse_long(argv[1], &value);
558 cYAML_build_error(-1, -1, "parser", "set",
559 "cannot parse router sensitivity value", &err_rc);
560 cYAML_print_tree2file(stderr, err_rc);
561 cYAML_free_tree(err_rc);
565 rc = lustre_lnet_config_rtr_sensitivity(value, -1, &err_rc);
566 if (rc != LUSTRE_CFG_RC_NO_ERR)
567 cYAML_print_tree2file(stderr, err_rc);
569 cYAML_free_tree(err_rc);
574 static int jt_set_hsensitivity(int argc, char **argv)
578 struct cYAML *err_rc = NULL;
580 rc = check_cmd(set_cmds, "set", "health_sensitivity", 2, argc, argv);
584 rc = parse_long(argv[1], &value);
586 cYAML_build_error(-1, -1, "parser", "set",
587 "cannot parse health sensitivity value", &err_rc);
588 cYAML_print_tree2file(stderr, err_rc);
589 cYAML_free_tree(err_rc);
593 rc = lustre_lnet_config_hsensitivity(value, -1, &err_rc);
594 if (rc != LUSTRE_CFG_RC_NO_ERR)
595 cYAML_print_tree2file(stderr, err_rc);
597 cYAML_free_tree(err_rc);
602 static int jt_reset_stats(int argc, char **argv)
605 struct cYAML *err_rc = NULL;
607 rc = check_cmd(stats_cmds, "stats", "reset", 0, argc, argv);
611 rc = lustre_lnet_reset_stats(-1, &err_rc);
612 if (rc != LUSTRE_CFG_RC_NO_ERR)
613 cYAML_print_tree2file(stderr, err_rc);
615 cYAML_free_tree(err_rc);
620 static int jt_set_transaction_to(int argc, char **argv)
624 struct cYAML *err_rc = NULL;
626 rc = check_cmd(set_cmds, "set", "transaction_timeout", 2, argc, argv);
630 rc = parse_long(argv[1], &value);
632 cYAML_build_error(-1, -1, "parser", "set",
633 "cannot parse transaction timeout value", &err_rc);
634 cYAML_print_tree2file(stderr, err_rc);
635 cYAML_free_tree(err_rc);
639 rc = lustre_lnet_config_transaction_to(value, -1, &err_rc);
640 if (rc != LUSTRE_CFG_RC_NO_ERR)
641 cYAML_print_tree2file(stderr, err_rc);
643 cYAML_free_tree(err_rc);
648 static int jt_set_retry_count(int argc, char **argv)
652 struct cYAML *err_rc = NULL;
654 rc = check_cmd(set_cmds, "set", "retry_count", 2, argc, argv);
658 rc = parse_long(argv[1], &value);
660 cYAML_build_error(-1, -1, "parser", "set",
661 "cannot parse retry_count value", &err_rc);
662 cYAML_print_tree2file(stderr, err_rc);
663 cYAML_free_tree(err_rc);
667 rc = lustre_lnet_config_retry_count(value, -1, &err_rc);
668 if (rc != LUSTRE_CFG_RC_NO_ERR)
669 cYAML_print_tree2file(stderr, err_rc);
671 cYAML_free_tree(err_rc);
676 static int jt_set_discovery(int argc, char **argv)
680 struct cYAML *err_rc = NULL;
682 rc = check_cmd(set_cmds, "set", "discovery", 2, argc, argv);
686 rc = parse_long(argv[1], &value);
688 cYAML_build_error(-1, -1, "parser", "set",
689 "cannot parse discovery value", &err_rc);
690 cYAML_print_tree2file(stderr, err_rc);
691 cYAML_free_tree(err_rc);
695 rc = lustre_lnet_config_discovery(value, -1, &err_rc);
696 if (rc != LUSTRE_CFG_RC_NO_ERR)
697 cYAML_print_tree2file(stderr, err_rc);
699 cYAML_free_tree(err_rc);
704 static int jt_set_drop_asym_route(int argc, char **argv)
708 struct cYAML *err_rc = NULL;
710 rc = check_cmd(set_cmds, "set", "drop_asym_route", 2, argc, argv);
714 rc = parse_long(argv[1], &value);
716 cYAML_build_error(-1, -1, "parser", "set",
717 "cannot parse drop_asym_route value",
719 cYAML_print_tree2file(stderr, err_rc);
720 cYAML_free_tree(err_rc);
724 rc = lustre_lnet_config_drop_asym_route(value, -1, &err_rc);
725 if (rc != LUSTRE_CFG_RC_NO_ERR)
726 cYAML_print_tree2file(stderr, err_rc);
728 cYAML_free_tree(err_rc);
733 static int jt_set_tiny(int argc, char **argv)
737 struct cYAML *err_rc = NULL;
739 rc = check_cmd(set_cmds, "set", "tiny_buffers", 2, argc, argv);
743 rc = parse_long(argv[1], &value);
745 cYAML_build_error(-1, -1, "parser", "set",
746 "cannot parse tiny_buffers value", &err_rc);
747 cYAML_print_tree2file(stderr, err_rc);
748 cYAML_free_tree(err_rc);
752 rc = lustre_lnet_config_buffers(value, -1, -1, -1, &err_rc);
753 if (rc != LUSTRE_CFG_RC_NO_ERR)
754 cYAML_print_tree2file(stderr, err_rc);
756 cYAML_free_tree(err_rc);
761 static int jt_set_small(int argc, char **argv)
765 struct cYAML *err_rc = NULL;
767 rc = check_cmd(set_cmds, "set", "small_buffers", 2, argc, argv);
771 rc = parse_long(argv[1], &value);
773 cYAML_build_error(-1, -1, "parser", "set",
774 "cannot parse small_buffers value", &err_rc);
775 cYAML_print_tree2file(stderr, err_rc);
776 cYAML_free_tree(err_rc);
780 rc = lustre_lnet_config_buffers(-1, value, -1, -1, &err_rc);
781 if (rc != LUSTRE_CFG_RC_NO_ERR)
782 cYAML_print_tree2file(stderr, err_rc);
784 cYAML_free_tree(err_rc);
789 static int jt_set_large(int argc, char **argv)
793 struct cYAML *err_rc = NULL;
795 rc = check_cmd(set_cmds, "set", "large_buffers", 2, argc, argv);
799 rc = parse_long(argv[1], &value);
801 cYAML_build_error(-1, -1, "parser", "set",
802 "cannot parse large_buffers value", &err_rc);
803 cYAML_print_tree2file(stderr, err_rc);
804 cYAML_free_tree(err_rc);
808 rc = lustre_lnet_config_buffers(-1, -1, value, -1, &err_rc);
809 if (rc != LUSTRE_CFG_RC_NO_ERR)
810 cYAML_print_tree2file(stderr, err_rc);
812 cYAML_free_tree(err_rc);
817 static int jt_set_routing(int argc, char **argv)
820 struct cYAML *err_rc = NULL;
823 rc = check_cmd(set_cmds, "set", "routing", 2, argc, argv);
827 rc = parse_long(argv[1], &value);
828 if (rc != 0 || (value != 0 && value != 1)) {
829 cYAML_build_error(-1, -1, "parser", "set",
830 "cannot parse routing value.\n"
831 "must be 0 for disable or 1 for enable",
833 cYAML_print_tree2file(stderr, err_rc);
834 cYAML_free_tree(err_rc);
838 rc = lustre_lnet_enable_routing(value, -1, &err_rc);
840 if (rc != LUSTRE_CFG_RC_NO_ERR)
841 cYAML_print_tree2file(stderr, err_rc);
843 cYAML_free_tree(err_rc);
848 static int jt_set_max_recovery_ping_interval(int argc, char **argv)
852 struct cYAML *err_rc = NULL;
854 rc = check_cmd(set_cmds, "set", "maximum recovery_interval", 2, argc, argv);
858 rc = parse_long(argv[1], &value);
860 cYAML_build_error(-1, -1, "parser", "set",
861 "cannot parse maximum recovery interval value",
863 cYAML_print_tree2file(stderr, err_rc);
864 cYAML_free_tree(err_rc);
868 rc = lustre_lnet_config_max_recovery_ping_interval(value, -1, &err_rc);
869 if (rc != LUSTRE_CFG_RC_NO_ERR)
870 cYAML_print_tree2file(stderr, err_rc);
872 cYAML_free_tree(err_rc);
877 static void yaml_lnet_print_error(int op, char *cmd, const char *errstr)
879 char errcode[INT_STRING_LEN];
885 snprintf(errcode, sizeof(errcode), "%d", errno);
887 yaml_emitter_initialize(&log);
888 yaml_emitter_set_indent(&log, LNET_DEFAULT_INDENT);
889 yaml_emitter_set_output_file(&log, stderr);
891 yaml_emitter_open(&log);
892 yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
893 rc = yaml_emitter_emit(&log, &event);
897 yaml_mapping_start_event_initialize(&event, NULL,
898 (yaml_char_t *)YAML_MAP_TAG,
899 1, YAML_ANY_MAPPING_STYLE);
900 rc = yaml_emitter_emit(&log, &event);
904 if (strcmp(cmd, "lnet") == 0) {
928 yaml_scalar_event_initialize(&event, NULL,
929 (yaml_char_t *)YAML_STR_TAG,
932 YAML_PLAIN_SCALAR_STYLE);
933 rc = yaml_emitter_emit(&log, &event);
937 yaml_sequence_start_event_initialize(&event, NULL,
938 (yaml_char_t *)YAML_SEQ_TAG,
939 1, YAML_ANY_SEQUENCE_STYLE);
940 rc = yaml_emitter_emit(&log, &event);
944 yaml_mapping_start_event_initialize(&event, NULL,
945 (yaml_char_t *)YAML_MAP_TAG,
946 1, YAML_ANY_MAPPING_STYLE);
947 rc = yaml_emitter_emit(&log, &event);
951 yaml_scalar_event_initialize(&event, NULL,
952 (yaml_char_t *)YAML_STR_TAG,
955 1, 0, YAML_PLAIN_SCALAR_STYLE);
956 rc = yaml_emitter_emit(&log, &event);
960 yaml_scalar_event_initialize(&event, NULL,
961 (yaml_char_t *)YAML_STR_TAG,
964 1, 0, YAML_PLAIN_SCALAR_STYLE);
965 rc = yaml_emitter_emit(&log, &event);
969 yaml_scalar_event_initialize(&event, NULL,
970 (yaml_char_t *)YAML_STR_TAG,
971 (yaml_char_t *)"errno",
972 strlen("errno"), 1, 0,
973 YAML_PLAIN_SCALAR_STYLE);
974 rc = yaml_emitter_emit(&log, &event);
978 yaml_scalar_event_initialize(&event, NULL,
979 (yaml_char_t *)YAML_INT_TAG,
980 (yaml_char_t *)errcode,
981 strlen(errcode), 1, 0,
982 YAML_PLAIN_SCALAR_STYLE);
983 rc = yaml_emitter_emit(&log, &event);
988 yaml_scalar_event_initialize(&event, NULL,
989 (yaml_char_t *)YAML_STR_TAG,
990 (yaml_char_t *)"descr",
991 strlen("descr"), 1, 0,
992 YAML_PLAIN_SCALAR_STYLE);
993 rc = yaml_emitter_emit(&log, &event);
997 yaml_scalar_event_initialize(&event, NULL,
998 (yaml_char_t *)YAML_STR_TAG,
999 (yaml_char_t *)errstr,
1000 strlen(errstr), 1, 0,
1001 YAML_DOUBLE_QUOTED_SCALAR_STYLE);
1002 rc = yaml_emitter_emit(&log, &event);
1006 yaml_mapping_end_event_initialize(&event);
1007 rc = yaml_emitter_emit(&log, &event);
1011 yaml_sequence_end_event_initialize(&event);
1012 rc = yaml_emitter_emit(&log, &event);
1016 yaml_mapping_end_event_initialize(&event);
1017 rc = yaml_emitter_emit(&log, &event);
1021 yaml_document_end_event_initialize(&event, 0);
1022 rc = yaml_emitter_emit(&log, &event);
1026 rc = yaml_emitter_close(&log);
1029 yaml_emitter_log_error(&log, stdout);
1030 yaml_emitter_delete(&log);
1033 static int yaml_lnet_cpt_of_nid_display(yaml_parser_t *reply)
1035 yaml_document_t results;
1036 yaml_emitter_t output;
1039 rc = yaml_parser_load(reply, &results);
1041 yaml_lnet_print_error(NLM_F_DUMP, "cpt-of-nid",
1042 yaml_parser_get_reader_error(reply));
1043 yaml_document_delete(&results);
1047 rc = yaml_emitter_initialize(&output);
1049 yaml_emitter_set_output_file(&output, stdout);
1051 rc = yaml_emitter_dump(&output, &results);
1054 yaml_document_delete(&results);
1056 yaml_emitter_log_error(&output, stderr);
1059 yaml_emitter_delete(&output);
1064 static int yaml_lnet_cpt_of_nid(int start, int end, char **nids)
1066 struct nl_sock *sk = NULL;
1067 yaml_emitter_t request;
1068 yaml_parser_t reply;
1072 /* Create Netlink emitter to send request to kernel */
1073 sk = nl_socket_alloc();
1077 /* Setup parser to receive Netlink packets */
1078 rc = yaml_parser_initialize(&reply);
1084 rc = yaml_parser_set_input_netlink(&reply, sk, false);
1088 /* Create Netlink emitter to send request to kernel */
1089 rc = yaml_emitter_initialize(&request);
1093 rc = yaml_emitter_set_output_netlink(&request, sk, LNET_GENL_NAME,
1095 LNET_CMD_CPT_OF_NID, NLM_F_DUMP);
1099 yaml_emitter_open(&request);
1100 yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
1101 rc = yaml_emitter_emit(&request, &event);
1105 yaml_mapping_start_event_initialize(&event, NULL,
1106 (yaml_char_t *)YAML_MAP_TAG,
1107 1, YAML_ANY_MAPPING_STYLE);
1108 rc = yaml_emitter_emit(&request, &event);
1112 yaml_scalar_event_initialize(&event, NULL,
1113 (yaml_char_t *)YAML_STR_TAG,
1114 (yaml_char_t *)"cpt-of-nid",
1115 strlen("cpt-of-nid"), 1, 0,
1116 YAML_PLAIN_SCALAR_STYLE);
1117 rc = yaml_emitter_emit(&request, &event);
1121 yaml_mapping_start_event_initialize(&event, NULL,
1122 (yaml_char_t *)YAML_MAP_TAG,
1123 1, YAML_ANY_MAPPING_STYLE);
1124 rc = yaml_emitter_emit(&request, &event);
1128 yaml_scalar_event_initialize(&event, NULL,
1129 (yaml_char_t *)YAML_STR_TAG,
1130 (yaml_char_t *)"nids",
1131 strlen("nids"), 1, 0,
1132 YAML_PLAIN_SCALAR_STYLE);
1133 rc = yaml_emitter_emit(&request, &event);
1137 yaml_sequence_start_event_initialize(&event, NULL,
1138 (yaml_char_t *)YAML_SEQ_TAG,
1139 1, YAML_FLOW_SEQUENCE_STYLE);
1140 rc = yaml_emitter_emit(&request, &event);
1144 for (i = start; i < end; i++) {
1145 yaml_scalar_event_initialize(&event, NULL,
1146 (yaml_char_t *)YAML_STR_TAG,
1147 (yaml_char_t *)nids[i],
1148 strlen(nids[i]), 1, 0,
1149 YAML_PLAIN_SCALAR_STYLE);
1150 rc = yaml_emitter_emit(&request, &event);
1155 yaml_sequence_end_event_initialize(&event);
1156 rc = yaml_emitter_emit(&request, &event);
1160 yaml_mapping_end_event_initialize(&event);
1161 rc = yaml_emitter_emit(&request, &event);
1165 yaml_mapping_end_event_initialize(&event);
1166 rc = yaml_emitter_emit(&request, &event);
1170 yaml_document_end_event_initialize(&event, 0);
1171 rc = yaml_emitter_emit(&request, &event);
1175 rc = yaml_emitter_close(&request);
1178 yaml_emitter_log_error(&request, stderr);
1181 rc = yaml_lnet_cpt_of_nid_display(&reply);
1183 yaml_emitter_delete(&request);
1186 yaml_lnet_print_error(NLM_F_DUMP, "cpt-of-nid",
1187 yaml_parser_get_reader_error(&reply));
1191 yaml_parser_delete(&reply);
1194 return rc == 1 ? 0 : rc;
1197 static int jt_calc_cpt_of_nid(int argc, char **argv)
1200 const char *const short_options = "h";
1201 static const struct option long_options[] = {
1202 { .name = "help", .val = 'h' },
1205 rc = check_cmd(cmd_list, "", "cpt-of-nid", 2, argc, argv);
1209 while ((opt = getopt_long(argc, argv, short_options,
1210 long_options, NULL)) != -1) {
1214 print_help(cmd_list, "", "cpt-of-nid");
1220 rc = yaml_lnet_cpt_of_nid(optind, argc, argv);
1221 if (rc == -EOPNOTSUPP)
1222 printf("Operation not supported\n");
1227 static int jt_config_lnet(int argc, char **argv)
1229 struct cYAML *err_rc = NULL;
1230 bool load_mod_params = false;
1231 int flags = NLM_F_CREATE;
1232 const char *msg = NULL;
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 if (!load_mod_params)
1257 flags |= NLM_F_EXCL;
1259 rc = yaml_lnet_configure(flags, &msg);
1260 if (rc != -EOPNOTSUPP) {
1264 snprintf(errstr, sizeof(errstr),
1265 "LNet configure error: %s", msg);
1266 yaml_lnet_print_error(flags, "lnet", errstr);
1271 rc = lustre_lnet_config_ni_system(LNET_CONFIGURE, load_mod_params,
1274 if (rc != LUSTRE_CFG_RC_NO_ERR)
1275 cYAML_print_tree2file(stderr, err_rc);
1277 cYAML_free_tree(err_rc);
1282 static int jt_unconfig_lnet(int argc, char **argv)
1284 struct cYAML *err_rc = NULL;
1285 const char *msg = NULL;
1288 rc = check_cmd(lnet_cmds, "lnet", "unconfigure", 0, argc, argv);
1292 rc = yaml_lnet_configure(0, &msg);
1293 if (rc != -EOPNOTSUPP) {
1297 snprintf(errstr, sizeof(errstr),
1298 "LNet configure error: %s", msg);
1299 yaml_lnet_print_error(0, "lnet", errstr);
1304 rc = lustre_lnet_config_ni_system(LNET_UNCONFIGURE, 0, -1, &err_rc);
1306 if (rc != LUSTRE_CFG_RC_NO_ERR)
1307 cYAML_print_tree2file(stderr, err_rc);
1309 cYAML_free_tree(err_rc);
1314 static int yaml_lnet_router_gateways(yaml_emitter_t *output, const char *nw,
1315 const char *gw, int hops, int prio,
1318 char num[INT_STRING_LEN];
1322 yaml_mapping_start_event_initialize(&event, NULL,
1323 (yaml_char_t *)YAML_MAP_TAG, 1,
1324 YAML_BLOCK_MAPPING_STYLE);
1325 rc = yaml_emitter_emit(output, &event);
1330 yaml_scalar_event_initialize(&event, NULL,
1331 (yaml_char_t *)YAML_STR_TAG,
1332 (yaml_char_t *)"net",
1333 strlen("net"), 1, 0,
1334 YAML_PLAIN_SCALAR_STYLE);
1335 rc = yaml_emitter_emit(output, &event);
1339 yaml_scalar_event_initialize(&event, NULL,
1340 (yaml_char_t *)YAML_STR_TAG,
1343 YAML_PLAIN_SCALAR_STYLE);
1344 rc = yaml_emitter_emit(output, &event);
1350 yaml_scalar_event_initialize(&event, NULL,
1351 (yaml_char_t *)YAML_STR_TAG,
1352 (yaml_char_t *)"gateway",
1353 strlen("gateway"), 1, 0,
1354 YAML_PLAIN_SCALAR_STYLE);
1355 rc = yaml_emitter_emit(output, &event);
1359 yaml_scalar_event_initialize(&event, NULL,
1360 (yaml_char_t *)YAML_STR_TAG,
1363 YAML_PLAIN_SCALAR_STYLE);
1364 rc = yaml_emitter_emit(output, &event);
1370 yaml_scalar_event_initialize(&event, NULL,
1371 (yaml_char_t *)YAML_STR_TAG,
1372 (yaml_char_t *)"hop",
1373 strlen("hop"), 1, 0,
1374 YAML_PLAIN_SCALAR_STYLE);
1375 rc = yaml_emitter_emit(output, &event);
1379 snprintf(num, sizeof(num), "%d", hops);
1380 yaml_scalar_event_initialize(&event, NULL,
1381 (yaml_char_t *)YAML_INT_TAG,
1384 YAML_PLAIN_SCALAR_STYLE);
1385 rc = yaml_emitter_emit(output, &event);
1391 yaml_scalar_event_initialize(&event, NULL,
1392 (yaml_char_t *)YAML_STR_TAG,
1393 (yaml_char_t *)"priority",
1394 strlen("priority"), 1, 0,
1395 YAML_PLAIN_SCALAR_STYLE);
1396 rc = yaml_emitter_emit(output, &event);
1400 snprintf(num, sizeof(num), "%d", prio);
1401 yaml_scalar_event_initialize(&event, NULL,
1402 (yaml_char_t *)YAML_INT_TAG,
1405 YAML_PLAIN_SCALAR_STYLE);
1406 rc = yaml_emitter_emit(output, &event);
1412 yaml_scalar_event_initialize(&event, NULL,
1413 (yaml_char_t *)YAML_STR_TAG,
1414 (yaml_char_t *)"health_sensitivity",
1415 strlen("health_sensitivity"),
1417 YAML_PLAIN_SCALAR_STYLE);
1418 rc = yaml_emitter_emit(output, &event);
1422 snprintf(num, sizeof(num), "%d", sen);
1423 yaml_scalar_event_initialize(&event, NULL,
1424 (yaml_char_t *)YAML_INT_TAG,
1427 YAML_PLAIN_SCALAR_STYLE);
1428 rc = yaml_emitter_emit(output, &event);
1433 yaml_mapping_end_event_initialize(&event);
1434 rc = yaml_emitter_emit(output, &event);
1439 static int yaml_lnet_route(char *nw, char *gw, int hops, int prio, int sen,
1440 int version, int flags, FILE *fp)
1442 struct nid_node head, *entry;
1443 struct nl_sock *sk = NULL;
1444 const char *msg = NULL;
1445 yaml_emitter_t output;
1446 yaml_parser_t reply;
1450 if (!(flags & NLM_F_DUMP) && (!nw || !gw)) {
1451 fprintf(stdout, "missing mandatory parameters:'%s'\n",
1452 (!nw && !gw) ? "net , gateway" :
1453 !nw ? "net" : "gateway");
1457 /* Create Netlink emitter to send request to kernel */
1458 sk = nl_socket_alloc();
1462 /* Setup parser to receive Netlink packets */
1463 rc = yaml_parser_initialize(&reply);
1469 rc = yaml_parser_set_input_netlink(&reply, sk, false);
1471 msg = yaml_parser_get_reader_error(&reply);
1475 /* Create Netlink emitter to send request to kernel */
1476 rc = yaml_emitter_initialize(&output);
1478 msg = "failed to initialize emitter";
1482 rc = yaml_emitter_set_output_netlink(&output, sk, LNET_GENL_NAME,
1483 version, LNET_CMD_ROUTES, flags);
1487 yaml_emitter_open(&output);
1488 yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
1489 rc = yaml_emitter_emit(&output, &event);
1493 yaml_mapping_start_event_initialize(&event, NULL,
1494 (yaml_char_t *)YAML_MAP_TAG,
1495 1, YAML_ANY_MAPPING_STYLE);
1496 rc = yaml_emitter_emit(&output, &event);
1500 yaml_scalar_event_initialize(&event, NULL,
1501 (yaml_char_t *)YAML_STR_TAG,
1502 (yaml_char_t *)"route",
1503 strlen("route"), 1, 0,
1504 YAML_PLAIN_SCALAR_STYLE);
1505 rc = yaml_emitter_emit(&output, &event);
1509 /* NLM_F_DUMP can have no arguments */
1511 NL_INIT_LIST_HEAD(&head.children);
1512 nl_init_list_head(&head.list);
1514 rc = lustre_lnet_parse_nid_range(&head, gw, &msg);
1516 lustre_lnet_free_list(&head);
1517 yaml_emitter_delete(&output);
1524 yaml_sequence_start_event_initialize(&event, NULL,
1525 (yaml_char_t *)YAML_SEQ_TAG,
1527 YAML_BLOCK_SEQUENCE_STYLE);
1528 rc = yaml_emitter_emit(&output, &event);
1532 if (!nl_list_empty(&head.children)) {
1533 nl_list_for_each_entry(entry, &head.children, list) {
1534 const char *nid = entry->nidstr;
1536 rc = yaml_lnet_router_gateways(&output, nw, nid,
1542 rc = yaml_lnet_router_gateways(&output, nw, NULL, hops,
1548 yaml_sequence_end_event_initialize(&event);
1549 rc = yaml_emitter_emit(&output, &event);
1553 yaml_scalar_event_initialize(&event, NULL,
1554 (yaml_char_t *)YAML_STR_TAG,
1557 YAML_PLAIN_SCALAR_STYLE);
1558 rc = yaml_emitter_emit(&output, &event);
1563 yaml_mapping_end_event_initialize(&event);
1564 rc = yaml_emitter_emit(&output, &event);
1568 yaml_document_end_event_initialize(&event, 0);
1569 rc = yaml_emitter_emit(&output, &event);
1573 rc = yaml_emitter_close(&output);
1576 yaml_emitter_log_error(&output, stderr);
1579 yaml_document_t errmsg;
1581 rc = yaml_parser_load(&reply, &errmsg);
1582 if (rc == 1 && (flags & NLM_F_DUMP)) {
1583 yaml_emitter_t debug;
1585 rc = yaml_emitter_initialize(&debug);
1587 yaml_emitter_set_indent(&debug,
1588 LNET_DEFAULT_INDENT);
1589 yaml_emitter_set_output_file(&debug, fp);
1590 rc = yaml_emitter_dump(&debug, &errmsg);
1592 yaml_emitter_delete(&debug);
1594 msg = yaml_parser_get_reader_error(&reply);
1595 /* If we didn't find any routes just be silent */
1596 if (msg && strcmp(msg, "No routes found") == 0)
1599 yaml_document_delete(&errmsg);
1601 yaml_emitter_delete(&output);
1604 yaml_lnet_print_error(flags, "route", msg);
1607 yaml_parser_delete(&reply);
1610 return rc == 1 ? 0 : rc;
1613 static int jt_add_route(int argc, char **argv)
1615 char *network = NULL, *gateway = NULL;
1616 long int hop = -1, prio = -1, sen = -1;
1617 struct cYAML *err_rc = NULL;
1620 const char *const short_options = "n:g:c:p:";
1621 static const struct option long_options[] = {
1622 { .name = "net", .has_arg = required_argument, .val = 'n' },
1623 { .name = "gateway", .has_arg = required_argument, .val = 'g' },
1624 { .name = "hop", .has_arg = required_argument, .val = 'c' },
1625 { .name = "hop-count", .has_arg = required_argument, .val = 'c' },
1626 { .name = "priority", .has_arg = required_argument, .val = 'p' },
1627 { .name = "health_sensitivity", .has_arg = required_argument, .val = 's' },
1631 rc = check_cmd(route_cmds, "route", "add", 0, argc, argv);
1635 while ((opt = getopt_long(argc, argv, short_options,
1636 long_options, NULL)) != -1) {
1645 rc = parse_long(optarg, &hop);
1653 rc = parse_long(optarg, &prio);
1661 rc = parse_long(optarg, &sen);
1670 print_help(route_cmds, "route", "add");
1676 rc = yaml_lnet_route(network, gateway, hop, prio, sen,
1677 LNET_GENL_VERSION, NLM_F_CREATE, stdout);
1679 if (rc == -EOPNOTSUPP)
1684 rc = lustre_lnet_config_route(network, gateway, hop, prio, sen, -1,
1687 if (rc != LUSTRE_CFG_RC_NO_ERR)
1688 cYAML_print_tree2file(stderr, err_rc);
1690 cYAML_free_tree(err_rc);
1695 static int yaml_add_ni_tunables(yaml_emitter_t *output,
1696 struct lnet_ioctl_config_lnd_tunables *tunables,
1697 struct lnet_dlc_network_descr *nw_descr)
1699 char num[INT_STRING_LEN];
1703 if (tunables->lt_cmn.lct_peer_timeout < 0 &&
1704 tunables->lt_cmn.lct_peer_tx_credits <= 0 &&
1705 tunables->lt_cmn.lct_peer_rtr_credits <= 0 &&
1706 tunables->lt_cmn.lct_max_tx_credits <= 0)
1707 goto skip_general_settings;
1709 yaml_scalar_event_initialize(&event, NULL,
1710 (yaml_char_t *)YAML_STR_TAG,
1711 (yaml_char_t *)"tunables",
1712 strlen("tunables"), 1, 0,
1713 YAML_PLAIN_SCALAR_STYLE);
1714 rc = yaml_emitter_emit(output, &event);
1718 yaml_mapping_start_event_initialize(&event, NULL,
1719 (yaml_char_t *)YAML_MAP_TAG,
1720 1, YAML_ANY_MAPPING_STYLE);
1721 rc = yaml_emitter_emit(output, &event);
1725 if (tunables->lt_cmn.lct_peer_timeout >= 0) {
1726 yaml_scalar_event_initialize(&event, NULL,
1727 (yaml_char_t *)YAML_STR_TAG,
1728 (yaml_char_t *)"peer_timeout",
1729 strlen("peer_timeout"), 1, 0,
1730 YAML_PLAIN_SCALAR_STYLE);
1731 rc = yaml_emitter_emit(output, &event);
1735 snprintf(num, sizeof(num), "%u",
1736 tunables->lt_cmn.lct_peer_timeout);
1737 yaml_scalar_event_initialize(&event, NULL,
1738 (yaml_char_t *)YAML_INT_TAG,
1741 YAML_PLAIN_SCALAR_STYLE);
1742 rc = yaml_emitter_emit(output, &event);
1747 if (tunables->lt_cmn.lct_peer_tx_credits > 0) {
1748 yaml_scalar_event_initialize(&event, NULL,
1749 (yaml_char_t *)YAML_STR_TAG,
1750 (yaml_char_t *)"peer_credits",
1751 strlen("peer_credits"), 1, 0,
1752 YAML_PLAIN_SCALAR_STYLE);
1753 rc = yaml_emitter_emit(output, &event);
1757 snprintf(num, sizeof(num), "%u",
1758 tunables->lt_cmn.lct_peer_tx_credits);
1759 yaml_scalar_event_initialize(&event, NULL,
1760 (yaml_char_t *)YAML_INT_TAG,
1763 YAML_PLAIN_SCALAR_STYLE);
1764 rc = yaml_emitter_emit(output, &event);
1769 if (tunables->lt_cmn.lct_peer_rtr_credits > 0) {
1770 yaml_scalar_event_initialize(&event, NULL,
1771 (yaml_char_t *)YAML_STR_TAG,
1772 (yaml_char_t *)"peer_buffer_credits",
1773 strlen("peer_buffer_credits"), 1, 0,
1774 YAML_PLAIN_SCALAR_STYLE);
1775 rc = yaml_emitter_emit(output, &event);
1779 snprintf(num, sizeof(num), "%u",
1780 tunables->lt_cmn.lct_peer_rtr_credits);
1781 yaml_scalar_event_initialize(&event, NULL,
1782 (yaml_char_t *)YAML_INT_TAG,
1785 YAML_PLAIN_SCALAR_STYLE);
1786 rc = yaml_emitter_emit(output, &event);
1791 if (tunables->lt_cmn.lct_max_tx_credits > 0) {
1792 yaml_scalar_event_initialize(&event, NULL,
1793 (yaml_char_t *)YAML_STR_TAG,
1794 (yaml_char_t *)"credits",
1795 strlen("credits"), 1, 0,
1796 YAML_PLAIN_SCALAR_STYLE);
1797 rc = yaml_emitter_emit(output, &event);
1801 snprintf(num, sizeof(num), "%u",
1802 tunables->lt_cmn.lct_max_tx_credits);
1803 yaml_scalar_event_initialize(&event, NULL,
1804 (yaml_char_t *)YAML_INT_TAG,
1807 YAML_PLAIN_SCALAR_STYLE);
1808 rc = yaml_emitter_emit(output, &event);
1813 yaml_mapping_end_event_initialize(&event);
1814 rc = yaml_emitter_emit(output, &event);
1818 skip_general_settings:
1819 if (tunables->lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer > 0 ||
1821 tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_auth_key > 0 ||
1822 tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_traffic_class_str[0] ||
1824 tunables->lt_tun.lnd_tun_u.lnd_o2ib.lnd_conns_per_peer > 0) {
1825 yaml_scalar_event_initialize(&event, NULL,
1826 (yaml_char_t *)YAML_STR_TAG,
1827 (yaml_char_t *)"lnd tunables",
1828 strlen("lnd tunables"), 1, 0,
1829 YAML_PLAIN_SCALAR_STYLE);
1830 rc = yaml_emitter_emit(output, &event);
1834 yaml_mapping_start_event_initialize(&event, NULL,
1835 (yaml_char_t *)YAML_MAP_TAG,
1836 1, YAML_ANY_MAPPING_STYLE);
1837 rc = yaml_emitter_emit(output, &event);
1841 if (tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_auth_key > 0) {
1842 yaml_scalar_event_initialize(&event, NULL,
1843 (yaml_char_t *)YAML_STR_TAG,
1844 (yaml_char_t *)"auth_key",
1845 strlen("auth_key"), 1, 0,
1846 YAML_PLAIN_SCALAR_STYLE);
1847 rc = yaml_emitter_emit(output, &event);
1851 snprintf(num, sizeof(num), "%u",
1852 tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_auth_key);
1854 yaml_scalar_event_initialize(&event, NULL,
1855 (yaml_char_t *)YAML_INT_TAG,
1858 YAML_PLAIN_SCALAR_STYLE);
1859 rc = yaml_emitter_emit(output, &event);
1864 if (tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_traffic_class_str[0]) {
1865 char *tc = &tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_traffic_class_str[0];
1867 yaml_scalar_event_initialize(&event, NULL,
1868 (yaml_char_t *)YAML_STR_TAG,
1869 (yaml_char_t *)"traffic_class",
1870 strlen("traffic_class"), 1, 0,
1871 YAML_PLAIN_SCALAR_STYLE);
1872 rc = yaml_emitter_emit(output, &event);
1876 yaml_scalar_event_initialize(&event, NULL,
1877 (yaml_char_t *)YAML_INT_TAG,
1880 YAML_PLAIN_SCALAR_STYLE);
1882 rc = yaml_emitter_emit(output, &event);
1887 if (tunables->lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer > 0 ||
1888 tunables->lt_tun.lnd_tun_u.lnd_o2ib.lnd_conns_per_peer > 0) {
1891 yaml_scalar_event_initialize(&event, NULL,
1892 (yaml_char_t *)YAML_STR_TAG,
1893 (yaml_char_t *)"conns_per_peer",
1894 strlen("conns_per_peer"), 1, 0,
1895 YAML_PLAIN_SCALAR_STYLE);
1896 rc = yaml_emitter_emit(output, &event);
1900 if (nw_descr->nw_id == LNET_NET_ANY)
1901 cpp = tunables->lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer;
1902 else if (LNET_NETTYP(nw_descr->nw_id) == SOCKLND)
1903 cpp = tunables->lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer;
1904 else if (LNET_NETTYP(nw_descr->nw_id) == O2IBLND)
1905 cpp = tunables->lt_tun.lnd_tun_u.lnd_o2ib.lnd_conns_per_peer;
1906 snprintf(num, sizeof(num), "%u", cpp);
1908 yaml_scalar_event_initialize(&event, NULL,
1909 (yaml_char_t *)YAML_INT_TAG,
1912 YAML_PLAIN_SCALAR_STYLE);
1913 rc = yaml_emitter_emit(output, &event);
1918 yaml_mapping_end_event_initialize(&event);
1919 rc = yaml_emitter_emit(output, &event);
1925 static int yaml_lnet_config_ni(char *net_id, char *ip2net,
1926 struct lnet_dlc_network_descr *nw_descr,
1927 struct lnet_ioctl_config_lnd_tunables *tunables,
1928 int healthv, struct cfs_expr_list *global_cpts,
1929 int version, int flags, FILE *fp)
1931 struct lnet_dlc_intf_descr *intf;
1932 struct nl_sock *sk = NULL;
1933 const char *msg = NULL;
1934 yaml_emitter_t output;
1935 yaml_parser_t reply;
1939 if (!(flags & NLM_F_DUMP) && !ip2net && (!nw_descr || nw_descr->nw_id == 0)) {
1940 fprintf(stdout, "missing mandatory parameters in NI config: '%s'\n",
1941 (!nw_descr) ? "network , interface" :
1942 (nw_descr->nw_id == 0) ? "network" : "interface");
1946 if ((flags == NLM_F_CREATE) && !ip2net && list_empty(&nw_descr->nw_intflist)) {
1947 fprintf(stdout, "creating a local NI needs at least one interface\n");
1951 if ((flags == NLM_F_REPLACE) && list_empty(&nw_descr->nw_intflist)) {
1952 fprintf(stdout, "updating a local NI needs at least one address\n");
1956 /* Create Netlink emitter to send request to kernel */
1957 sk = nl_socket_alloc();
1961 /* Setup parser to receive Netlink packets */
1962 rc = yaml_parser_initialize(&reply);
1968 rc = yaml_parser_set_input_netlink(&reply, sk, false);
1970 msg = yaml_parser_get_reader_error(&reply);
1974 /* Create Netlink emitter to send request to kernel */
1975 rc = yaml_emitter_initialize(&output);
1977 msg = "failed to initialize emitter";
1981 rc = yaml_emitter_set_output_netlink(&output, sk, LNET_GENL_NAME,
1982 version, LNET_CMD_NETS, flags);
1986 yaml_emitter_open(&output);
1987 yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
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,
2001 (yaml_char_t *)"net",
2002 strlen("net"), 1, 0,
2003 YAML_PLAIN_SCALAR_STYLE);
2004 rc = yaml_emitter_emit(&output, &event);
2008 if (net_id || ip2net) {
2009 char *key = net_id ? "net type" : "ip2net";
2010 char *value = net_id ? net_id : ip2net;
2012 yaml_sequence_start_event_initialize(&event, NULL,
2013 (yaml_char_t *)YAML_SEQ_TAG,
2014 1, YAML_ANY_SEQUENCE_STYLE);
2015 rc = yaml_emitter_emit(&output, &event);
2019 yaml_mapping_start_event_initialize(&event, NULL,
2020 (yaml_char_t *)YAML_MAP_TAG,
2021 1, YAML_ANY_MAPPING_STYLE);
2022 rc = yaml_emitter_emit(&output, &event);
2026 yaml_scalar_event_initialize(&event, NULL,
2027 (yaml_char_t *)YAML_STR_TAG,
2030 1, 0, YAML_PLAIN_SCALAR_STYLE);
2031 rc = yaml_emitter_emit(&output, &event);
2035 yaml_scalar_event_initialize(&event, NULL,
2036 (yaml_char_t *)YAML_STR_TAG,
2037 (yaml_char_t *)value,
2038 strlen(value), 1, 0,
2039 YAML_PLAIN_SCALAR_STYLE);
2040 rc = yaml_emitter_emit(&output, &event);
2044 yaml_scalar_event_initialize(&event, NULL,
2045 (yaml_char_t *)YAML_STR_TAG,
2048 YAML_PLAIN_SCALAR_STYLE);
2049 rc = yaml_emitter_emit(&output, &event);
2056 if (!nw_descr || list_empty(&nw_descr->nw_intflist))
2059 yaml_scalar_event_initialize(&event, NULL,
2060 (yaml_char_t *)YAML_STR_TAG,
2061 (yaml_char_t *)"local NI(s)",
2062 strlen("local NI(s)"), 1, 0,
2063 YAML_PLAIN_SCALAR_STYLE);
2064 rc = yaml_emitter_emit(&output, &event);
2068 yaml_sequence_start_event_initialize(&event, NULL,
2069 (yaml_char_t *)YAML_SEQ_TAG,
2070 1, YAML_ANY_SEQUENCE_STYLE);
2071 rc = yaml_emitter_emit(&output, &event);
2075 list_for_each_entry(intf, &nw_descr->nw_intflist,
2077 yaml_mapping_start_event_initialize(&event, NULL,
2078 (yaml_char_t *)YAML_MAP_TAG,
2079 1, YAML_ANY_MAPPING_STYLE);
2080 rc = yaml_emitter_emit(&output, &event);
2084 /* Use NI addresses instead of interface */
2085 if (strchr(intf->intf_name, '@') ||
2086 (strcmp(intf->intf_name, "<?>") == 0 &&
2087 - flags == NLM_F_REPLACE)) {
2088 yaml_scalar_event_initialize(&event, NULL,
2089 (yaml_char_t *)YAML_STR_TAG,
2090 (yaml_char_t *)"nid",
2091 strlen("nid"), 1, 0,
2092 YAML_PLAIN_SCALAR_STYLE);
2093 rc = yaml_emitter_emit(&output, &event);
2097 yaml_scalar_event_initialize(&event, NULL,
2098 (yaml_char_t *)YAML_STR_TAG,
2099 (yaml_char_t *)intf->intf_name,
2100 strlen(intf->intf_name), 1, 0,
2101 YAML_PLAIN_SCALAR_STYLE);
2102 rc = yaml_emitter_emit(&output, &event);
2106 yaml_scalar_event_initialize(&event, NULL,
2107 (yaml_char_t *)YAML_STR_TAG,
2108 (yaml_char_t *)"interfaces",
2109 strlen("interfaces"), 1, 0,
2110 YAML_PLAIN_SCALAR_STYLE);
2111 rc = yaml_emitter_emit(&output, &event);
2115 yaml_mapping_start_event_initialize(&event, NULL,
2116 (yaml_char_t *)YAML_MAP_TAG,
2117 1, YAML_ANY_MAPPING_STYLE);
2118 rc = yaml_emitter_emit(&output, &event);
2122 yaml_scalar_event_initialize(&event, NULL,
2123 (yaml_char_t *)YAML_STR_TAG,
2126 YAML_PLAIN_SCALAR_STYLE);
2127 rc = yaml_emitter_emit(&output, &event);
2131 yaml_scalar_event_initialize(&event, NULL,
2132 (yaml_char_t *)YAML_STR_TAG,
2133 (yaml_char_t *)intf->intf_name,
2134 strlen(intf->intf_name), 1, 0,
2135 YAML_PLAIN_SCALAR_STYLE);
2136 rc = yaml_emitter_emit(&output, &event);
2140 yaml_mapping_end_event_initialize(&event);
2141 rc = yaml_emitter_emit(&output, &event);
2147 rc = yaml_add_ni_tunables(&output, tunables, nw_descr);
2152 if (flags == NLM_F_REPLACE && healthv > -1) {
2153 char health[INT_STRING_LEN];
2155 yaml_scalar_event_initialize(&event, NULL,
2156 (yaml_char_t *)YAML_STR_TAG,
2157 (yaml_char_t *)"health stats",
2158 strlen("health stats"), 1, 0,
2159 YAML_PLAIN_SCALAR_STYLE);
2160 rc = yaml_emitter_emit(&output, &event);
2164 /* Setup all mappings for data related to the 'health stats' */
2165 yaml_mapping_start_event_initialize(&event, NULL,
2166 (yaml_char_t *)YAML_MAP_TAG,
2167 1, YAML_BLOCK_MAPPING_STYLE);
2168 rc = yaml_emitter_emit(&output, &event);
2172 yaml_scalar_event_initialize(&event, NULL,
2173 (yaml_char_t *)YAML_STR_TAG,
2174 (yaml_char_t *)"health value",
2175 strlen("health value"), 1, 0,
2176 YAML_PLAIN_SCALAR_STYLE);
2177 rc = yaml_emitter_emit(&output, &event);
2181 snprintf(health, sizeof(health), "%d", healthv);
2182 yaml_scalar_event_initialize(&event, NULL,
2183 (yaml_char_t *)YAML_INT_TAG,
2184 (yaml_char_t *)health,
2185 strlen(health), 1, 0,
2186 YAML_PLAIN_SCALAR_STYLE);
2187 rc = yaml_emitter_emit(&output, &event);
2191 yaml_mapping_end_event_initialize(&event);
2192 rc = yaml_emitter_emit(&output, &event);
2201 yaml_scalar_event_initialize(&event, NULL,
2202 (yaml_char_t *)YAML_STR_TAG,
2203 (yaml_char_t *)"CPT",
2204 strlen("CPT"), 1, 0,
2205 YAML_PLAIN_SCALAR_STYLE);
2206 rc = yaml_emitter_emit(&output, &event);
2210 yaml_sequence_start_event_initialize(&event, NULL,
2211 (yaml_char_t *)YAML_SEQ_TAG,
2213 YAML_FLOW_SEQUENCE_STYLE);
2214 rc = yaml_emitter_emit(&output, &event);
2218 count = cfs_expr_list_values(global_cpts,
2219 LNET_MAX_SHOW_NUM_CPT,
2221 for (i = 0; i < count; i++) {
2222 char core[INT_STRING_LEN];
2224 snprintf(core, sizeof(core), "%u", cpt_array[i]);
2225 yaml_scalar_event_initialize(&event, NULL,
2226 (yaml_char_t *)YAML_STR_TAG,
2227 (yaml_char_t *)core,
2229 YAML_PLAIN_SCALAR_STYLE);
2230 rc = yaml_emitter_emit(&output, &event);
2235 yaml_sequence_end_event_initialize(&event);
2236 rc = yaml_emitter_emit(&output, &event);
2240 cfs_expr_list_free(global_cpts);
2244 yaml_mapping_end_event_initialize(&event);
2245 rc = yaml_emitter_emit(&output, &event);
2250 yaml_sequence_end_event_initialize(&event);
2251 rc = yaml_emitter_emit(&output, &event);
2255 yaml_mapping_end_event_initialize(&event);
2256 rc = yaml_emitter_emit(&output, &event);
2260 yaml_sequence_end_event_initialize(&event);
2261 rc = yaml_emitter_emit(&output, &event);
2265 yaml_mapping_end_event_initialize(&event);
2266 rc = yaml_emitter_emit(&output, &event);
2270 yaml_document_end_event_initialize(&event, 0);
2271 rc = yaml_emitter_emit(&output, &event);
2275 rc = yaml_emitter_close(&output);
2278 yaml_emitter_log_error(&output, stderr);
2281 yaml_document_t errmsg;
2283 rc = yaml_parser_load(&reply, &errmsg);
2284 if (rc == 1 && (flags & NLM_F_DUMP)) {
2285 yaml_emitter_t debug;
2287 rc = yaml_emitter_initialize(&debug);
2289 yaml_emitter_set_indent(&debug,
2290 LNET_DEFAULT_INDENT);
2291 yaml_emitter_set_output_file(&debug, fp);
2292 rc = yaml_emitter_dump(&debug, &errmsg);
2294 yaml_emitter_delete(&debug);
2296 msg = yaml_parser_get_reader_error(&reply);
2298 yaml_document_delete(&errmsg);
2300 yaml_emitter_delete(&output);
2303 yaml_lnet_print_error(flags, "net", msg);
2306 yaml_parser_delete(&reply);
2309 return rc == 1 ? 0 : rc;
2312 static int jt_add_ni(int argc, char **argv)
2314 char *ip2net = NULL;
2315 long int pto = -1, pc = -1, pbc = -1, cre = -1, cpp = -1, auth_key = -1;
2316 char *traffic_class = NULL;
2317 struct cYAML *err_rc = NULL;
2318 int rc, opt, cpt_rc = -1;
2319 struct lnet_dlc_network_descr nw_descr;
2320 struct cfs_expr_list *global_cpts = NULL;
2321 struct lnet_ioctl_config_lnd_tunables tunables;
2323 bool skip_mr_route_setup = false;
2324 const char *const short_options = "a:b:c:i:k:m:n:p:r:s:t:T:";
2325 static const struct option long_options[] = {
2326 { .name = "auth-key", .has_arg = required_argument, .val = 'a' },
2327 { .name = "peer-buffer-credits",
2328 .has_arg = required_argument, .val = 'b' },
2329 { .name = "peer-credits", .has_arg = required_argument, .val = 'c' },
2330 { .name = "if", .has_arg = required_argument, .val = 'i' },
2331 { .name = "skip-mr-route-setup",
2332 .has_arg = no_argument, .val = 'k' },
2333 { .name = "conns-per-peer",
2334 .has_arg = required_argument, .val = 'm' },
2335 { .name = "net", .has_arg = required_argument, .val = 'n' },
2336 { .name = "nid", .has_arg = required_argument, .val = 'N' },
2337 { .name = "ip2net", .has_arg = required_argument, .val = 'p' },
2338 { .name = "credits", .has_arg = required_argument, .val = 'r' },
2339 { .name = "cpt", .has_arg = required_argument, .val = 's' },
2340 { .name = "peer-timeout", .has_arg = required_argument, .val = 't' },
2341 { .name = "traffic-class", .has_arg = required_argument, .val = 'T' },
2343 bool nid_request = false;
2344 char *net_id = NULL;
2346 memset(&tunables, 0, sizeof(tunables));
2347 lustre_lnet_init_nw_descr(&nw_descr);
2349 rc = check_cmd(net_cmds, "net", "add", 0, argc, argv);
2353 while ((opt = getopt_long(argc, argv, short_options,
2354 long_options, NULL)) != -1) {
2357 rc = parse_long(optarg, &auth_key);
2365 rc = parse_long(optarg, &pbc);
2373 rc = parse_long(optarg, &pc);
2381 rc = lustre_lnet_parse_interfaces(optarg, &nw_descr);
2383 cYAML_build_error(-1, -1, "ni", "add",
2384 "bad interface list",
2390 skip_mr_route_setup = true;
2393 rc = parse_long(optarg, &cpp);
2402 nw_descr.nw_id = libcfs_str2net(optarg);
2406 rc = lustre_lnet_parse_interfaces(optarg, &nw_descr);
2408 cYAML_build_error(-1, -1, "ni", "add",
2419 rc = parse_long(optarg, &cre);
2427 cpt_rc = cfs_expr_list_parse(optarg,
2429 UINT_MAX, &global_cpts);
2432 rc = parse_long(optarg, &pto);
2440 traffic_class = optarg;
2441 if (strlen(traffic_class) == 0 ||
2442 strlen(traffic_class) >= LNET_MAX_STR_LEN) {
2443 cYAML_build_error(-1, -1, "ni", "add",
2444 "Invalid traffic-class argument",
2446 rc = LUSTRE_CFG_RC_BAD_PARAM;
2451 print_help(net_cmds, "net", "add");
2459 fprintf(stdout, "--net is invalid with --nid option\n");
2462 net_id = libcfs_net2str(nw_descr.nw_id);
2465 if (auth_key > 0 && LNET_NETTYP(nw_descr.nw_id) == KFILND) {
2466 tunables.lt_tun.lnd_tun_u.lnd_kfi.lnd_auth_key = auth_key;
2470 if (traffic_class && LNET_NETTYP(nw_descr.nw_id) == KFILND &&
2471 strlen(traffic_class) < LNET_MAX_STR_LEN) {
2472 strcpy(&tunables.lt_tun.lnd_tun_u.lnd_kfi.lnd_traffic_class_str[0],
2478 if (LNET_NETTYP(nw_descr.nw_id) == SOCKLND && (cpp > -1)) {
2479 tunables.lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer = cpp;
2481 } else if (LNET_NETTYP(nw_descr.nw_id) == O2IBLND && (cpp > -1)) {
2482 tunables.lt_tun.lnd_tun_u.lnd_o2ib.lnd_conns_per_peer = cpp;
2486 if (pto >= 0 || pc > 0 || pbc > 0 || cre > 0 || cpp > -1) {
2487 tunables.lt_cmn.lct_peer_timeout = pto;
2488 tunables.lt_cmn.lct_peer_tx_credits = pc;
2489 tunables.lt_cmn.lct_peer_rtr_credits = pbc;
2490 tunables.lt_cmn.lct_max_tx_credits = cre;
2494 if (found && LNET_NETTYP(nw_descr.nw_id) == O2IBLND)
2495 tunables.lt_tun.lnd_tun_u.lnd_o2ib.lnd_map_on_demand = UINT_MAX;
2497 rc = yaml_lnet_config_ni(net_id, ip2net, &nw_descr,
2498 found ? &tunables : NULL, -1,
2499 (cpt_rc == 0) ? global_cpts : NULL,
2500 LNET_GENL_VERSION, NLM_F_CREATE, stdout);
2502 if (rc == -EOPNOTSUPP)
2504 if (global_cpts != NULL)
2505 cfs_expr_list_free(global_cpts);
2506 if (rc == 0 && !skip_mr_route_setup)
2507 rc = lustre_lnet_setup_mrrouting(&err_rc);
2511 rc = lustre_lnet_config_ni(&nw_descr,
2512 (cpt_rc == 0) ? global_cpts: NULL,
2513 ip2net, (found) ? &tunables : NULL,
2516 if (global_cpts != NULL)
2517 cfs_expr_list_free(global_cpts);
2520 if (rc != LUSTRE_CFG_RC_NO_ERR)
2521 cYAML_print_tree2file(stderr, err_rc);
2523 cYAML_free_tree(err_rc);
2525 if (rc == LUSTRE_CFG_RC_NO_ERR && !skip_mr_route_setup) {
2527 rc = lustre_lnet_setup_mrrouting(&err_rc);
2529 if (rc != LUSTRE_CFG_RC_NO_ERR)
2530 cYAML_print_tree2file(stderr, err_rc);
2532 cYAML_free_tree(err_rc);
2538 static int jt_del_route(int argc, char **argv)
2540 char *network = NULL, *gateway = NULL;
2541 struct cYAML *err_rc = NULL;
2543 const char *const short_options = "n:g:";
2544 static const struct option long_options[] = {
2545 { .name = "net", .has_arg = required_argument, .val = 'n' },
2546 { .name = "gateway", .has_arg = required_argument, .val = 'g' },
2550 rc = check_cmd(route_cmds, "route", "del", 0, argc, argv);
2554 while ((opt = getopt_long(argc, argv, short_options,
2555 long_options, NULL)) != -1) {
2564 print_help(route_cmds, "route", "del");
2570 rc = yaml_lnet_route(network, gateway, -1, -1, -1, LNET_GENL_VERSION,
2573 if (rc == -EOPNOTSUPP)
2578 rc = lustre_lnet_del_route(network, gateway, -1, &err_rc);
2580 if (rc != LUSTRE_CFG_RC_NO_ERR)
2581 cYAML_print_tree2file(stderr, err_rc);
2583 cYAML_free_tree(err_rc);
2588 static int jt_del_ni(int argc, char **argv)
2590 struct cYAML *err_rc = NULL;
2592 struct lnet_dlc_network_descr nw_descr;
2593 const char *const short_options = "n:i:";
2594 static const struct option long_options[] = {
2595 { .name = "net", .has_arg = required_argument, .val = 'n' },
2596 { .name = "if", .has_arg = required_argument, .val = 'i' },
2597 { .name = "nid", .has_arg = required_argument, .val = 'N' },
2599 bool nid_request = false;
2600 char *net_id = NULL;
2602 rc = check_cmd(net_cmds, "net", "del", 0, argc, argv);
2606 lustre_lnet_init_nw_descr(&nw_descr);
2608 while ((opt = getopt_long(argc, argv, short_options,
2609 long_options, NULL)) != -1) {
2612 nw_descr.nw_id = libcfs_str2net(optarg);
2616 rc = lustre_lnet_parse_interfaces(optarg, &nw_descr);
2618 cYAML_build_error(-1, -1, "ni", "del",
2626 rc = lustre_lnet_parse_interfaces(optarg, &nw_descr);
2628 cYAML_build_error(-1, -1, "ni", "add",
2629 "bad interface list",
2635 print_help(net_cmds, "net", "del");
2643 fprintf(stdout, "--net is invalid with --nid option\n");
2646 net_id = libcfs_net2str(nw_descr.nw_id);
2649 rc = yaml_lnet_config_ni(net_id, NULL, &nw_descr, NULL, -1, NULL,
2650 LNET_GENL_VERSION, 0, stdout);
2652 if (rc != -EOPNOTSUPP)
2656 rc = lustre_lnet_del_ni(&nw_descr, -1, &err_rc);
2658 if (rc != LUSTRE_CFG_RC_NO_ERR)
2659 cYAML_print_tree2file(stderr, err_rc);
2661 cYAML_free_tree(err_rc);
2666 static int jt_show_route(int argc, char **argv)
2668 char *network = NULL, *gateway = NULL;
2669 long int hop = -1, prio = -1;
2670 int detail = 0, rc, opt;
2671 struct cYAML *err_rc = NULL, *show_rc = NULL;
2672 const char *const short_options = "c:n:g:p:v";
2673 static const struct option long_options[] = {
2674 { .name = "net", .has_arg = required_argument, .val = 'n' },
2675 { .name = "gateway", .has_arg = required_argument, .val = 'g' },
2676 { .name = "hop-count", .has_arg = required_argument, .val = 'c' },
2677 { .name = "hop", .has_arg = required_argument, .val = 'c' },
2678 { .name = "priority", .has_arg = required_argument, .val = 'p' },
2679 { .name = "verbose", .has_arg = no_argument, .val = 'v' },
2683 rc = check_cmd(route_cmds, "route", "show", 0, argc, argv);
2687 while ((opt = getopt_long(argc, argv, short_options,
2688 long_options, NULL)) != -1) {
2697 rc = parse_long(optarg, &hop);
2705 rc = parse_long(optarg, &prio);
2716 print_help(route_cmds, "route", "show");
2722 rc = yaml_lnet_route(network, gateway, hop, prio, -1,
2723 detail, NLM_F_DUMP, stdout);
2725 if (rc == -EOPNOTSUPP)
2730 rc = lustre_lnet_show_route(network, gateway, hop, prio,
2732 &show_rc, &err_rc, false);
2734 if (rc != LUSTRE_CFG_RC_NO_ERR)
2735 cYAML_print_tree2file(stderr, err_rc);
2737 cYAML_print_tree(show_rc);
2739 cYAML_free_tree(err_rc);
2740 cYAML_free_tree(show_rc);
2745 static int set_value_helper(int argc, char **argv, int cmd,
2746 int (*cb)(int, bool, char*, int, int, struct cYAML**))
2748 char *nidstr = NULL;
2749 long int healthv = -1;
2751 long int state = -1;
2754 struct cYAML *err_rc = NULL;
2755 const char *const short_options = "t:n:m:s:a";
2756 static const struct option long_options[] = {
2757 { .name = "nid", .has_arg = required_argument, .val = 'n' },
2758 { .name = "health", .has_arg = required_argument, .val = 't' },
2759 { .name = "conns-per-peer", .has_arg = required_argument, .val = 'm' },
2760 { .name = "state", .has_arg = required_argument, .val = 's' },
2761 { .name = "all", .has_arg = no_argument, .val = 'a' },
2765 while ((opt = getopt_long(argc, argv, short_options,
2766 long_options, NULL)) != -1) {
2772 if (parse_long(optarg, &healthv) != 0)
2776 if (cmd != LNET_CMD_PEERS ||
2777 parse_long(optarg, &state) != 0)
2781 if (cmd != LNET_CMD_NETS ||
2782 parse_long(optarg, &cpp) != 0)
2794 rc = cb(healthv, all, nidstr, cmd == LNET_CMD_PEERS ? state : cpp, -1,
2796 if (rc != LUSTRE_CFG_RC_NO_ERR)
2797 cYAML_print_tree2file(stderr, err_rc);
2799 cYAML_free_tree(err_rc);
2804 int yaml_lnet_config_ni_healthv(int healthv, bool all, char *nidstr, int cpp,
2805 int seq_no, struct cYAML **err_rc)
2807 struct lnet_ioctl_config_lnd_tunables tunables;
2808 struct lnet_dlc_network_descr nw_descr;
2809 char *net_id = "<255:65535>"; /* LNET_NET_ANY */
2812 /* For NI you can't have both setting all NIDs and a requested NID */
2813 if (!all && !nidstr)
2816 if (cpp == -1 && healthv == -1)
2820 net_id = strchr(nidstr, '@');
2826 lustre_lnet_init_nw_descr(&nw_descr);
2827 nw_descr.nw_id = libcfs_str2net(net_id);
2829 rc = lustre_lnet_parse_interfaces(nidstr ? nidstr : "<?>", &nw_descr);
2830 if (rc != LUSTRE_CFG_RC_NO_ERR)
2833 memset(&tunables, 0, sizeof(tunables));
2834 tunables.lt_cmn.lct_peer_timeout = -1;
2835 if (nw_descr.nw_id == LNET_NET_ANY && cpp > -1)
2836 tunables.lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer = cpp;
2837 else if (LNET_NETTYP(nw_descr.nw_id) == SOCKLND && (cpp > -1))
2838 tunables.lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer = cpp;
2839 else if (LNET_NETTYP(nw_descr.nw_id) == O2IBLND && (cpp > -1))
2840 tunables.lt_tun.lnd_tun_u.lnd_o2ib.lnd_conns_per_peer = cpp;
2842 rc = yaml_lnet_config_ni(net_id, NULL, &nw_descr,
2843 cpp != -1 ? &tunables : NULL, healthv, NULL,
2844 LNET_GENL_VERSION, NLM_F_REPLACE, stdout);
2846 if (rc == -EOPNOTSUPP)
2852 rc = lustre_lnet_config_ni_conns_per_peer(cpp, all, nidstr,
2855 rc = lustre_lnet_config_ni_healthv(healthv, all, nidstr,
2860 static int jt_set_ni_value(int argc, char **argv)
2862 int rc = check_cmd(net_cmds, "net", "set", 0, argc, argv);
2867 return set_value_helper(argc, argv, LNET_CMD_NETS,
2868 yaml_lnet_config_ni_healthv);
2871 static int yaml_lnet_peer_display(yaml_parser_t *reply, bool list_only)
2873 yaml_emitter_t debug;
2876 rc = yaml_emitter_initialize(&debug);
2880 yaml_emitter_set_indent(&debug, 6);
2881 yaml_emitter_set_output_file(&debug, stdout);
2890 rc = yaml_parser_parse(reply, &event);
2892 goto report_reply_error;
2894 if (event.type != YAML_SCALAR_EVENT)
2897 value = (char *)event.data.scalar.value;
2898 if (strcmp(value, "peer") == 0) {
2899 yaml_event_delete(&event);
2901 yaml_scalar_event_initialize(&event, NULL,
2902 (yaml_char_t *)YAML_STR_TAG,
2903 (yaml_char_t *)"peer list",
2904 strlen("peer list"),
2906 YAML_PLAIN_SCALAR_STYLE);
2907 } else if (strcmp(value, "primary nid") == 0) {
2908 yaml_event_delete(&event);
2910 yaml_scalar_event_initialize(&event, NULL,
2911 (yaml_char_t *)YAML_STR_TAG,
2912 (yaml_char_t *)"nid",
2915 YAML_PLAIN_SCALAR_STYLE);
2916 rc = yaml_emitter_emit(&debug, &event);
2920 /* Now print NID address */
2921 rc = yaml_parser_parse(reply, &event);
2923 goto report_reply_error;
2925 rc = yaml_emitter_emit(&debug, &event);
2930 while (event.type != YAML_MAPPING_END_EVENT) {
2931 rc = yaml_parser_parse(reply, &event);
2933 goto report_reply_error;
2936 /* we can have map end, seq end, map end or
2937 * just map end event. If we see seq end event
2938 * then skip to next mapping end event
2940 rc = yaml_parser_parse(reply, &event);
2942 goto report_reply_error;
2944 if (event.type == YAML_SEQUENCE_END_EVENT) {
2945 yaml_event_delete(&event);
2947 rc = yaml_parser_parse(reply, &event);
2949 goto report_reply_error;
2953 rc = yaml_emitter_emit(&debug, &event);
2957 done = (event.type == YAML_DOCUMENT_END_EVENT);
2960 yaml_document_t errmsg;
2962 rc = yaml_parser_load(reply, &errmsg);
2964 rc = yaml_emitter_dump(&debug, &errmsg);
2965 yaml_document_delete(&errmsg);
2969 yaml_emitter_log_error(&debug, stderr);
2971 yaml_emitter_delete(&debug);
2976 static int yaml_lnet_peer(char *prim_nid, char *nidstr, bool disable_mr,
2977 int health_value, int state, bool list_only,
2978 int version, int flags, FILE *fp)
2980 struct nl_sock *sk = NULL;
2981 const char *msg = NULL;
2982 yaml_emitter_t output;
2983 yaml_parser_t reply;
2987 /* Create Netlink emitter to send request to kernel */
2988 sk = nl_socket_alloc();
2992 /* Setup parser to receive Netlink packets */
2993 rc = yaml_parser_initialize(&reply);
2999 rc = yaml_parser_set_input_netlink(&reply, sk, false);
3001 msg = yaml_parser_get_reader_error(&reply);
3005 /* Create Netlink emitter to send request to kernel */
3006 rc = yaml_emitter_initialize(&output);
3008 msg = "failed to initialize emitter";
3012 rc = yaml_emitter_set_output_netlink(&output, sk, LNET_GENL_NAME,
3013 version, LNET_CMD_PEERS, flags);
3017 yaml_emitter_open(&output);
3018 yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
3019 rc = yaml_emitter_emit(&output, &event);
3023 yaml_mapping_start_event_initialize(&event, NULL,
3024 (yaml_char_t *)YAML_MAP_TAG,
3025 1, YAML_ANY_MAPPING_STYLE);
3026 rc = yaml_emitter_emit(&output, &event);
3030 yaml_scalar_event_initialize(&event, NULL,
3031 (yaml_char_t *)YAML_STR_TAG,
3032 (yaml_char_t *)"peer",
3033 strlen("peer"), 1, 0,
3034 YAML_PLAIN_SCALAR_STYLE);
3035 rc = yaml_emitter_emit(&output, &event);
3040 yaml_sequence_start_event_initialize(&event, NULL,
3041 (yaml_char_t *)YAML_SEQ_TAG,
3043 YAML_BLOCK_SEQUENCE_STYLE);
3044 rc = yaml_emitter_emit(&output, &event);
3048 yaml_mapping_start_event_initialize(&event, NULL,
3049 (yaml_char_t *)YAML_MAP_TAG,
3051 YAML_BLOCK_MAPPING_STYLE);
3052 rc = yaml_emitter_emit(&output, &event);
3056 yaml_scalar_event_initialize(&event, NULL,
3057 (yaml_char_t *)YAML_STR_TAG,
3058 (yaml_char_t *)"primary nid",
3059 strlen("primary nid"), 1, 0,
3060 YAML_PLAIN_SCALAR_STYLE);
3061 rc = yaml_emitter_emit(&output, &event);
3065 yaml_scalar_event_initialize(&event, NULL,
3066 (yaml_char_t *)YAML_STR_TAG,
3067 (yaml_char_t *)prim_nid,
3068 strlen(prim_nid), 1, 0,
3069 YAML_PLAIN_SCALAR_STYLE);
3070 rc = yaml_emitter_emit(&output, &event);
3075 yaml_scalar_event_initialize(&event, NULL,
3076 (yaml_char_t *)YAML_STR_TAG,
3077 (yaml_char_t *)"Multi-Rail",
3078 strlen("Multi-Rail"), 1, 0,
3079 YAML_PLAIN_SCALAR_STYLE);
3080 rc = yaml_emitter_emit(&output, &event);
3084 yaml_scalar_event_initialize(&event, NULL,
3085 (yaml_char_t *)YAML_BOOL_TAG,
3086 (yaml_char_t *)"False",
3087 strlen("False"), 1, 0,
3088 YAML_PLAIN_SCALAR_STYLE);
3089 rc = yaml_emitter_emit(&output, &event);
3095 char peer_state[INT_STRING_LEN];
3097 yaml_scalar_event_initialize(&event, NULL,
3098 (yaml_char_t *)YAML_STR_TAG,
3099 (yaml_char_t *)"peer state",
3100 strlen("peer state"), 1, 0,
3101 YAML_PLAIN_SCALAR_STYLE);
3102 rc = yaml_emitter_emit(&output, &event);
3106 snprintf(peer_state, sizeof(peer_state), "%d", state);
3107 yaml_scalar_event_initialize(&event, NULL,
3108 (yaml_char_t *)YAML_INT_TAG,
3109 (yaml_char_t *)peer_state,
3110 strlen(peer_state), 1, 0,
3111 YAML_PLAIN_SCALAR_STYLE);
3112 rc = yaml_emitter_emit(&output, &event);
3117 if (!nidstr && health_value == -1)
3120 yaml_scalar_event_initialize(&event, NULL,
3121 (yaml_char_t *)YAML_STR_TAG,
3122 (yaml_char_t *)"peer ni",
3123 strlen("peer ni"), 1, 0,
3124 YAML_PLAIN_SCALAR_STYLE);
3125 rc = yaml_emitter_emit(&output, &event);
3129 yaml_sequence_start_event_initialize(&event, NULL,
3130 (yaml_char_t *)YAML_SEQ_TAG,
3131 1, YAML_BLOCK_SEQUENCE_STYLE);
3132 rc = yaml_emitter_emit(&output, &event);
3137 struct nid_node head, *entry;
3140 /* If we have LNET_ANY_NID and its NLM_F_REPLACE we
3141 * treat it as the all flag case for lnetctl peer set
3143 if (strcmp(nidstr, "<?>") == 0) {
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,
3162 (yaml_char_t *)nidstr,
3163 strlen(nidstr), 1, 0,
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);
3177 NL_INIT_LIST_HEAD(&head.children);
3178 nl_init_list_head(&head.list);
3179 rc = lustre_lnet_parse_nid_range(&head, nidstr, &msg);
3181 fprintf(stdout, "can't parse nidrange: \"%s\"\n", nidstr);
3182 lustre_lnet_free_list(&head);
3183 yaml_emitter_delete(&output);
3189 if (nl_list_empty(&head.children)) {
3190 lustre_lnet_free_list(&head);
3191 yaml_emitter_delete(&output);
3192 msg = "Unable to parse nidlist: did not expand to any nids";
3197 rc = 1; /* one means its working */
3199 nl_list_for_each_entry(entry, &head.children, list) {
3200 char *nid = entry->nidstr;
3202 if (count++ > LNET_MAX_NIDS_PER_PEER) {
3203 lustre_lnet_free_list(&head);
3204 yaml_emitter_delete(&output);
3205 msg = "Unable to parse nidlist: specifies more NIDs than allowed";
3211 yaml_mapping_start_event_initialize(&event, NULL,
3212 (yaml_char_t *)YAML_MAP_TAG,
3213 1, YAML_BLOCK_MAPPING_STYLE);
3214 rc = yaml_emitter_emit(&output, &event);
3218 yaml_scalar_event_initialize(&event, NULL,
3219 (yaml_char_t *)YAML_STR_TAG,
3220 (yaml_char_t *)"nid",
3221 strlen("nid"), 1, 0,
3222 YAML_PLAIN_SCALAR_STYLE);
3223 rc = yaml_emitter_emit(&output, &event);
3227 yaml_scalar_event_initialize(&event, NULL,
3228 (yaml_char_t *)YAML_STR_TAG,
3231 YAML_PLAIN_SCALAR_STYLE);
3232 rc = yaml_emitter_emit(&output, &event);
3236 yaml_mapping_end_event_initialize(&event);
3237 rc = yaml_emitter_emit(&output, &event);
3241 lustre_lnet_free_list(&head);
3244 if (health_value >= 0) {
3245 char health[INT_STRING_LEN];
3247 /* Create the mapping for 'health stats'. The value field for
3248 * the mapping is not provided so its treated as a empty string.
3250 yaml_mapping_start_event_initialize(&event, NULL,
3251 (yaml_char_t *)YAML_MAP_TAG,
3252 1, YAML_BLOCK_MAPPING_STYLE);
3253 rc = yaml_emitter_emit(&output, &event);
3257 yaml_scalar_event_initialize(&event, NULL,
3258 (yaml_char_t *)YAML_STR_TAG,
3259 (yaml_char_t *)"health stats",
3260 strlen("health stats"), 1, 0,
3261 YAML_PLAIN_SCALAR_STYLE);
3262 rc = yaml_emitter_emit(&output, &event);
3266 /* Setup all mappings for data related to the 'health stats' */
3267 yaml_mapping_start_event_initialize(&event, NULL,
3268 (yaml_char_t *)YAML_MAP_TAG,
3269 1, YAML_BLOCK_MAPPING_STYLE);
3270 rc = yaml_emitter_emit(&output, &event);
3274 yaml_scalar_event_initialize(&event, NULL,
3275 (yaml_char_t *)YAML_STR_TAG,
3276 (yaml_char_t *)"health value",
3277 strlen("health value"), 1, 0,
3278 YAML_PLAIN_SCALAR_STYLE);
3279 rc = yaml_emitter_emit(&output, &event);
3283 snprintf(health, sizeof(health), "%d", health_value);
3284 yaml_scalar_event_initialize(&event, NULL,
3285 (yaml_char_t *)YAML_INT_TAG,
3286 (yaml_char_t *)health,
3287 strlen(health), 1, 0,
3288 YAML_PLAIN_SCALAR_STYLE);
3289 rc = yaml_emitter_emit(&output, &event);
3293 yaml_mapping_end_event_initialize(&event);
3294 rc = yaml_emitter_emit(&output, &event);
3298 yaml_mapping_end_event_initialize(&event);
3299 rc = yaml_emitter_emit(&output, &event);
3304 yaml_sequence_end_event_initialize(&event);
3305 rc = yaml_emitter_emit(&output, &event);
3309 yaml_mapping_end_event_initialize(&event);
3310 rc = yaml_emitter_emit(&output, &event);
3314 yaml_sequence_end_event_initialize(&event);
3315 rc = yaml_emitter_emit(&output, &event);
3319 yaml_scalar_event_initialize(&event, NULL,
3320 (yaml_char_t *)YAML_STR_TAG,
3323 YAML_PLAIN_SCALAR_STYLE);
3324 rc = yaml_emitter_emit(&output, &event);
3329 yaml_mapping_end_event_initialize(&event);
3330 rc = yaml_emitter_emit(&output, &event);
3334 yaml_document_end_event_initialize(&event, 0);
3335 rc = yaml_emitter_emit(&output, &event);
3339 rc = yaml_emitter_close(&output);
3342 yaml_emitter_log_error(&output, stderr);
3345 rc = yaml_lnet_peer_display(&reply, list_only);
3347 msg = yaml_parser_get_reader_error(&reply);
3348 /* If we didn't find any peers just be silent */
3349 if (msg && strcmp(msg, "No peers found") == 0)
3354 yaml_emitter_delete(&output);
3357 yaml_lnet_print_error(flags, "peer", msg);
3360 yaml_parser_delete(&reply);
3363 return rc == 1 ? 0 : rc;
3366 int yaml_lnet_config_peer_ni_healthv(int healthv, bool all, char *lpni_nid,
3367 int state, int seq_no, struct cYAML **err_rc)
3371 rc = yaml_lnet_peer(lpni_nid ? lpni_nid : "<?>", all ? "<?>" : NULL,
3372 false, healthv, state, false, LNET_GENL_VERSION,
3373 NLM_F_REPLACE, stdout);
3375 if (rc == -EOPNOTSUPP)
3381 rc = lustre_lnet_config_peer_ni_healthv(healthv, all, lpni_nid,
3384 rc = lustre_lnet_set_peer_state(state, lpni_nid, -1, err_rc);
3389 static int jt_set_peer_ni_value(int argc, char **argv)
3391 int rc = check_cmd(peer_cmds, "peer", "set", 0, argc, argv);
3396 return set_value_helper(argc, argv, LNET_CMD_PEERS,
3397 yaml_lnet_config_peer_ni_healthv);
3400 static int jt_show_recovery(int argc, char **argv)
3403 struct cYAML *err_rc = NULL, *show_rc = NULL;
3404 const char *const short_options = "lp";
3405 static const struct option long_options[] = {
3406 { .name = "local", .has_arg = no_argument, .val = 'l' },
3407 { .name = "peer", .has_arg = no_argument, .val = 'p' },
3410 rc = check_cmd(debug_cmds, "debug", "recovery", 0, argc, argv);
3414 while ((opt = getopt_long(argc, argv, short_options,
3415 long_options, NULL)) != -1) {
3418 rc = lustre_lnet_show_local_ni_recovq(-1, &show_rc, &err_rc);
3421 rc = lustre_lnet_show_peer_ni_recovq(-1, &show_rc, &err_rc);
3428 if (rc != LUSTRE_CFG_RC_NO_ERR)
3429 cYAML_print_tree2file(stderr, err_rc);
3431 cYAML_print_tree(show_rc);
3433 cYAML_free_tree(err_rc);
3434 cYAML_free_tree(show_rc);
3439 static int jt_show_peer_debug_info(int argc, char **argv)
3442 struct cYAML *err_rc = NULL;
3443 char *peer_nid = optarg;
3444 const char *const short_opts = "k";
3445 const struct option long_opts[] = {
3446 { .name = "nid", .has_arg = required_argument, .val = 'k' },
3449 rc = check_cmd(debug_cmds, "debug", "peer", 0, argc, argv);
3454 while ((opt = getopt_long(argc, argv, short_opts,
3455 long_opts, NULL)) != -1) {
3465 rc = lustre_lnet_show_peer_debug_info(peer_nid, -1, &err_rc);
3467 if (rc != LUSTRE_CFG_RC_NO_ERR)
3468 cYAML_print_tree2file(stderr, err_rc);
3470 cYAML_free_tree(err_rc);
3475 static int jt_show_net(int argc, char **argv)
3477 char *network = NULL;
3479 struct cYAML *err_rc = NULL, *show_rc = NULL;
3480 long int detail = 0;
3481 const char *const short_options = "n:v";
3482 static const struct option long_options[] = {
3483 { .name = "net", .has_arg = required_argument, .val = 'n' },
3484 { .name = "verbose", .has_arg = optional_argument, .val = 'v' },
3487 rc = check_cmd(net_cmds, "net", "show", 0, argc, argv);
3491 while ((opt = getopt_long(argc, argv, short_options,
3492 long_options, NULL)) != -1) {
3498 if ((!optarg) && (argv[optind] != NULL) &&
3499 (argv[optind][0] != '-')) {
3500 if (parse_long(argv[optind++], &detail) != 0)
3507 print_help(net_cmds, "net", "show");
3513 rc = yaml_lnet_config_ni(network, NULL, NULL, NULL, -1, NULL,
3514 detail, NLM_F_DUMP, stdout);
3516 if (rc != -EOPNOTSUPP)
3520 rc = lustre_lnet_show_net(network, (int) detail, -1, &show_rc, &err_rc,
3523 if (rc != LUSTRE_CFG_RC_NO_ERR)
3524 cYAML_print_tree2file(stderr, err_rc);
3526 cYAML_print_tree(show_rc);
3528 cYAML_free_tree(err_rc);
3529 cYAML_free_tree(show_rc);
3534 static int jt_show_routing(int argc, char **argv)
3536 struct cYAML *err_rc = NULL, *show_rc = NULL;
3539 rc = check_cmd(routing_cmds, "routing", "show", 0, argc, argv);
3543 rc = lustre_lnet_show_routing(-1, &show_rc, &err_rc, false);
3545 if (rc != LUSTRE_CFG_RC_NO_ERR)
3546 cYAML_print_tree2file(stderr, err_rc);
3548 cYAML_print_tree(show_rc);
3550 cYAML_free_tree(err_rc);
3551 cYAML_free_tree(show_rc);
3556 static int jt_show_stats(int argc, char **argv)
3559 struct cYAML *show_rc = NULL, *err_rc = NULL;
3561 rc = check_cmd(stats_cmds, "stats", "show", 0, argc, argv);
3565 rc = lustre_lnet_show_stats(-1, &show_rc, &err_rc);
3567 if (rc != LUSTRE_CFG_RC_NO_ERR)
3568 cYAML_print_tree2file(stderr, err_rc);
3570 cYAML_print_tree(show_rc);
3572 cYAML_free_tree(err_rc);
3573 cYAML_free_tree(show_rc);
3578 static int jt_show_udsp(int argc, char **argv)
3582 struct cYAML *err_rc = NULL, *show_rc = NULL;
3584 const char *const short_options = "i:";
3585 static const struct option long_options[] = {
3586 { .name = "idx", .has_arg = required_argument, .val = 'i' },
3590 rc = check_cmd(udsp_cmds, "udsp", "show", 0, argc, argv);
3594 while ((opt = getopt_long(argc, argv, short_options,
3595 long_options, NULL)) != -1) {
3598 rc = parse_long(optarg, &idx);
3599 if (rc != 0 || idx < -1) {
3600 printf("Invalid index \"%s\"\n", optarg);
3605 print_help(net_cmds, "net", "show");
3611 rc = lustre_lnet_show_udsp(idx, -1, &show_rc, &err_rc);
3613 if (rc != LUSTRE_CFG_RC_NO_ERR)
3614 cYAML_print_tree2file(stderr, err_rc);
3616 cYAML_print_tree(show_rc);
3618 cYAML_free_tree(err_rc);
3619 cYAML_free_tree(show_rc);
3624 static int jt_show_global(int argc, char **argv)
3627 struct cYAML *show_rc = NULL, *err_rc = NULL;
3629 rc = check_cmd(global_cmds, "global", "show", 0, argc, argv);
3633 rc = lustre_lnet_show_numa_range(-1, &show_rc, &err_rc);
3634 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3635 cYAML_print_tree2file(stderr, err_rc);
3639 rc = lustre_lnet_show_max_intf(-1, &show_rc, &err_rc);
3640 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3641 cYAML_print_tree2file(stderr, err_rc);
3645 rc = lustre_lnet_show_discovery(-1, &show_rc, &err_rc);
3646 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3647 cYAML_print_tree2file(stderr, err_rc);
3651 rc = lustre_lnet_show_drop_asym_route(-1, &show_rc, &err_rc);
3652 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3653 cYAML_print_tree2file(stderr, err_rc);
3657 rc = lustre_lnet_show_retry_count(-1, &show_rc, &err_rc);
3658 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3659 cYAML_print_tree2file(stderr, err_rc);
3663 rc = lustre_lnet_show_transaction_to(-1, &show_rc, &err_rc);
3664 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3665 cYAML_print_tree2file(stderr, err_rc);
3669 rc = lustre_lnet_show_hsensitivity(-1, &show_rc, &err_rc);
3670 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3671 cYAML_print_tree2file(stderr, err_rc);
3675 rc = lustre_lnet_show_recov_intrv(-1, &show_rc, &err_rc);
3676 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3677 cYAML_print_tree2file(stderr, err_rc);
3681 rc = lustre_lnet_show_rtr_sensitivity(-1, &show_rc, &err_rc);
3682 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3683 cYAML_print_tree2file(stderr, err_rc);
3687 rc = lustre_lnet_show_lnd_timeout(-1, &show_rc, &err_rc);
3688 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3689 cYAML_print_tree2file(stderr, err_rc);
3693 rc = lustre_lnet_show_response_tracking(-1, &show_rc, &err_rc);
3694 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3695 cYAML_print_tree2file(stderr, err_rc);
3699 rc = lustre_lnet_show_recovery_limit(-1, &show_rc, &err_rc);
3700 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3701 cYAML_print_tree2file(stderr, err_rc);
3705 rc = lustre_lnet_show_max_recovery_ping_interval(-1, &show_rc, &err_rc);
3706 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3707 cYAML_print_tree2file(stderr, err_rc);
3712 cYAML_print_tree(show_rc);
3715 cYAML_free_tree(err_rc);
3716 cYAML_free_tree(show_rc);
3721 static int jt_lnet(int argc, char **argv)
3725 rc = check_cmd(lnet_cmds, "lnet", NULL, 2, argc, argv);
3729 return cfs_parser(argc, argv, lnet_cmds);
3732 static int jt_route(int argc, char **argv)
3736 rc = check_cmd(route_cmds, "route", NULL, 2, argc, argv);
3740 return cfs_parser(argc, argv, route_cmds);
3743 static int jt_net(int argc, char **argv)
3747 rc = check_cmd(net_cmds, "net", NULL, 2, argc, argv);
3751 return cfs_parser(argc, argv, net_cmds);
3754 static int jt_routing(int argc, char **argv)
3758 rc = check_cmd(routing_cmds, "routing", NULL, 2, argc, argv);
3762 return cfs_parser(argc, argv, routing_cmds);
3765 static int jt_stats(int argc, char **argv)
3769 rc = check_cmd(stats_cmds, "stats", NULL, 2, argc, argv);
3773 return cfs_parser(argc, argv, stats_cmds);
3776 static int jt_debug(int argc, char **argv)
3780 rc = check_cmd(debug_cmds, "debug", NULL, 2, argc, argv);
3784 return cfs_parser(argc, argv, debug_cmds);
3787 static int jt_global(int argc, char **argv)
3791 rc = check_cmd(global_cmds, "global", NULL, 2, argc, argv);
3795 return cfs_parser(argc, argv, global_cmds);
3798 static int jt_peers(int argc, char **argv)
3802 rc = check_cmd(peer_cmds, "peer", NULL, 2, argc, argv);
3806 return cfs_parser(argc, argv, peer_cmds);
3809 static int jt_set(int argc, char **argv)
3813 rc = check_cmd(set_cmds, "set", NULL, 2, argc, argv);
3817 return cfs_parser(argc, argv, set_cmds);
3820 static int jt_udsp(int argc, char **argv)
3824 rc = check_cmd(udsp_cmds, "udsp", NULL, 2, argc, argv);
3828 return cfs_parser(argc, argv, udsp_cmds);
3831 static int yaml_import_global_settings(char *key, unsigned long value,
3832 char cmd, struct cYAML *show_rc,
3833 struct cYAML *err_rc)
3837 if (strcmp("numa_range", key) == 0) {
3838 if (cmd == 'a' || cmd == 'd') {
3841 rc = lustre_lnet_config_numa_range(value, -1,
3843 } else if (cmd == 's') {
3844 rc = lustre_lnet_show_numa_range(-1, &show_rc,
3847 } else if (strcmp("max_interfaces", key) == 0 ||
3848 strcmp("max_intf", key) == 0) {
3849 if (cmd == 'a' || cmd == 'd') {
3851 value = LNET_INTERFACES_MAX_DEFAULT;
3852 rc = lustre_lnet_config_max_intf(value, -1,
3854 } else if (cmd == 's') {
3855 rc = lustre_lnet_show_max_intf(-1, &show_rc,
3858 } else if (strcmp("discovery", key) == 0) {
3859 if (cmd == 'a' || cmd == 'd') {
3862 rc = lustre_lnet_config_discovery(value, -1,
3864 } else if (cmd == 's') {
3865 rc = lustre_lnet_show_discovery(-1, &show_rc,
3868 } else if (strcmp("drop_asym_route", key) == 0) {
3870 rc = lustre_lnet_config_drop_asym_route(value,
3873 } else if (cmd == 's') {
3874 rc = lustre_lnet_show_drop_asym_route(-1, &show_rc,
3877 } else if (strcmp("retry_count", key) == 0) {
3879 rc = lustre_lnet_config_retry_count(value, -1,
3881 } else if (cmd == 's') {
3882 rc = lustre_lnet_show_retry_count(-1, &show_rc,
3885 } else if (strcmp("transaction_timeout", key) == 0) {
3887 rc = lustre_lnet_config_transaction_to(value, -1,
3889 } else if (cmd == 's') {
3890 rc = lustre_lnet_show_transaction_to(-1, &show_rc,
3893 } else if (strcmp("health_sensitivity", key) == 0) {
3895 rc = lustre_lnet_config_hsensitivity(value, -1,
3897 } else if (cmd == 's') {
3898 rc = lustre_lnet_show_hsensitivity(-1, &show_rc,
3901 } else if (strcmp("recovery_interval", key) == 0) {
3903 rc = lustre_lnet_config_recov_intrv(value, -1,
3905 } else if (cmd == 's') {
3906 rc = lustre_lnet_show_recov_intrv(-1, &show_rc,
3909 } else if (strcmp("router_sensitivity", key) == 0) {
3911 rc = lustre_lnet_config_rtr_sensitivity(value, -1,
3913 } else if (cmd == 's') {
3914 rc = lustre_lnet_show_rtr_sensitivity(-1, &show_rc,
3917 } else if (strcmp("lnd_timeout", key) == 0) {
3919 } else if (cmd == 's') {
3920 rc = lustre_lnet_show_lnd_timeout(-1, &show_rc,
3923 } else if (strcmp("response_tracking", key) == 0) {
3925 rc = lustre_lnet_config_response_tracking(value, -1,
3927 } else if (cmd == 's') {
3928 rc = lustre_lnet_show_response_tracking(-1, &show_rc,
3931 } else if (strcmp("recovery_limit", key) == 0) {
3933 rc = lustre_lnet_config_recovery_limit(value, -1,
3935 } else if (cmd == 's') {
3936 rc = lustre_lnet_show_recovery_limit(-1, &show_rc,
3939 } else if (strcmp("max_recovery_ping_interval", key) == 0) {
3941 rc = lustre_lnet_config_max_recovery_ping_interval(value, -1,
3943 } else if (cmd == 's') {
3944 rc = lustre_lnet_show_max_recovery_ping_interval(-1, &show_rc,
3952 static int jt_import(int argc, char **argv)
3955 struct cYAML *err_rc = NULL;
3956 struct cYAML *show_rc = NULL;
3957 int rc = 0, return_rc = 0, opt, opt_found = 0;
3958 char *yaml_blk = NULL, *buf, cmd = 'a';
3959 int flags = NLM_F_CREATE;
3960 bool release = true;
3965 const char *const short_options = "adseh";
3966 static const struct option long_options[] = {
3967 { .name = "add", .has_arg = no_argument, .val = 'a' },
3968 { .name = "del", .has_arg = no_argument, .val = 'd' },
3969 { .name = "show", .has_arg = no_argument, .val = 's' },
3970 { .name = "exec", .has_arg = no_argument, .val = 'e' },
3971 { .name = "help", .has_arg = no_argument, .val = 'h' },
3974 bool done = false, unspec = true;
3975 yaml_parser_t setup, reply;
3976 struct nl_sock *sk = NULL;
3977 int op = LNET_CMD_UNSPEC;
3978 const char *msg = NULL;
3979 yaml_emitter_t output;
3982 while ((opt = getopt_long(argc, argv, short_options,
3983 long_options, NULL)) != -1) {
3987 /* default is NLM_F_CREATE */
3991 flags = 0; /* Netlink delete cmd */
3999 /* use NLM_F_CREATE for discover */
4003 printf("import FILE\n"
4004 "import < FILE : import a file\n"
4005 "\t--add: add configuration\n"
4006 "\t--del: delete configuration\n"
4007 "\t--show: show configuration\n"
4008 "\t--exec: execute command\n"
4009 "\t--help: display this help\n"
4010 "If no command option is given then --add"
4011 " is assumed by default\n");
4018 /* grab the file name if one exists */
4019 if (opt_found && argc == 3)
4021 else if (!opt_found && argc == 2)
4024 /* file always takes precedence */
4026 /* Set a file input. */
4027 input = fopen(file, "rb");
4030 snprintf(err_str, sizeof(err_str),
4031 "cannot open '%s': %s", file,
4033 cYAML_build_error(-1, -1, "yaml", "builder",
4042 /* Create Netlink emitter to send request to kernel */
4043 sk = nl_socket_alloc();
4047 /* Setup parser to receive Netlink packets */
4048 rc = yaml_parser_initialize(&reply);
4054 rc = yaml_parser_set_input_netlink(&reply, sk, false);
4056 msg = yaml_parser_get_reader_error(&reply);
4060 /* Initialize configuration parser */
4061 rc = yaml_parser_initialize(&setup);
4063 yaml_parser_log_error(&setup, stderr, "import: ");
4064 yaml_parser_delete(&setup);
4068 yaml_parser_set_input_file(&setup, input);
4071 if (!yaml_parser_parse(&setup, &event)) {
4072 yaml_parser_log_error(&setup, stderr, "import: ");
4076 if (event.type != YAML_SCALAR_EVENT)
4079 if (!strcmp((char *)event.data.scalar.value, "net") &&
4080 op != LNET_CMD_ROUTES && cmd != 'e') {
4081 if (op != LNET_CMD_UNSPEC) {
4082 rc = yaml_netlink_complete_emitter(&output);
4088 rc = yaml_netlink_setup_emitter(&output, sk,
4096 } else if (!strcmp((char *)event.data.scalar.value, "peer") &&
4098 if (op != LNET_CMD_UNSPEC) {
4099 rc = yaml_netlink_complete_emitter(&output);
4103 op = LNET_CMD_PEERS;
4105 rc = yaml_netlink_setup_emitter(&output, sk,
4113 } else if (!strcmp((char *)event.data.scalar.value, "route") &&
4115 if (op != LNET_CMD_UNSPEC) {
4116 rc = yaml_netlink_complete_emitter(&output);
4120 op = LNET_CMD_ROUTES;
4122 rc = yaml_netlink_setup_emitter(&output, sk,
4130 } else if ((!strcmp((char *)event.data.scalar.value, "discover") ||
4131 !strcmp((char *)event.data.scalar.value, "ping")) &&
4133 if (op != LNET_CMD_UNSPEC) {
4134 rc = yaml_netlink_complete_emitter(&output);
4140 if (!strcmp((char *)event.data.scalar.value, "ping"))
4143 rc = yaml_netlink_setup_emitter(&output, sk,
4151 } else if (!strcmp((char *)event.data.scalar.value, "global")) {
4152 if (op != LNET_CMD_UNSPEC) {
4153 rc = yaml_netlink_complete_emitter(&output);
4157 op = LNET_CMD_UNSPEC;
4158 } else if (op == LNET_CMD_UNSPEC) {
4159 struct cYAML *err_rc = NULL;
4163 key = strdup((char *)event.data.scalar.value);
4164 rc = yaml_parser_parse(&setup, &event);
4168 rc = parse_long((char *)event.data.scalar.value,
4173 rc = yaml_import_global_settings(key, value, cmd,
4175 if (rc != LUSTRE_CFG_RC_NO_ERR)
4176 cYAML_print_tree2file(stderr, err_rc);
4181 if (op != LNET_CMD_UNSPEC) {
4182 rc = yaml_emitter_emit(&output, &event);
4187 done = (event.type == YAML_STREAM_END_EVENT);
4191 yaml_emitter_log_error(&output, stderr);
4192 yaml_emitter_delete(&output);
4194 } else if (!unspec) {
4195 yaml_document_t errmsg;
4197 rc = yaml_parser_load(&reply, &errmsg);
4198 if (rc == 1 && (flags & NLM_F_DUMP)) {
4199 yaml_emitter_t debug;
4201 rc = yaml_emitter_initialize(&debug);
4203 yaml_emitter_set_indent(&debug,
4204 LNET_DEFAULT_INDENT);
4205 yaml_emitter_set_output_file(&debug,
4207 rc = yaml_emitter_dump(&debug, &errmsg);
4209 yaml_emitter_delete(&debug);
4211 msg = yaml_parser_get_reader_error(&reply);
4213 yaml_emitter_delete(&output);
4214 yaml_document_delete(&errmsg);
4218 yaml_lnet_print_error(flags, "import", msg);
4221 yaml_parser_delete(&reply);
4222 yaml_parser_delete(&setup);
4227 return rc == 1 ? 0 : rc;
4229 /* assume that we're getting our input from stdin */
4230 rc = fstat(fileno(input), &st);
4232 snprintf(err_str, sizeof(err_str),
4233 "cannot get file stats '%s': %s", file,
4235 cYAML_build_error(-1, -1, "yaml", "builder",
4241 yaml_blk = buf = malloc(st.st_size);
4244 snprintf(err_str, sizeof(err_str),
4245 "failed to allocate buffer: %s",
4247 cYAML_build_error(-1, -1, "yaml", "builder",
4254 while (fgets(buf, len, input) != NULL) {
4255 char *seq = strstr(buf, "- ");
4261 skip = strspn(seq, " ");
4266 /* PyYAML format has libyaml free the
4277 rc = lustre_yaml_config(yaml_blk, st.st_size, &err_rc);
4278 return_rc = lustre_yaml_exec(yaml_blk, st.st_size, &show_rc,
4280 cYAML_print_tree(show_rc);
4281 cYAML_free_tree(show_rc);
4284 rc = lustre_yaml_del(yaml_blk, st.st_size, &err_rc);
4287 rc = lustre_yaml_show(yaml_blk, st.st_size, &show_rc,
4289 cYAML_print_tree(show_rc);
4290 cYAML_free_tree(show_rc);
4293 rc = lustre_yaml_exec(yaml_blk, st.st_size, &show_rc,
4295 cYAML_print_tree(show_rc);
4296 cYAML_free_tree(show_rc);
4300 if (yaml_blk && release)
4302 if (rc || return_rc) {
4303 cYAML_print_tree2file(stderr, err_rc);
4304 cYAML_free_tree(err_rc);
4310 static int jt_export(int argc, char **argv)
4312 struct cYAML *show_rc = NULL;
4313 struct cYAML *err_rc = NULL;
4314 int flags = NLM_F_DUMP;
4318 bool backup = false;
4320 const char *const short_options = "bh";
4321 static const struct option long_options[] = {
4322 { .name = "backup", .has_arg = no_argument, .val = 'b' },
4323 { .name = "help", .has_arg = no_argument, .val = 'h' },
4327 while ((opt = getopt_long(argc, argv, short_options,
4328 long_options, NULL)) != -1) {
4331 flags |= NLM_F_DUMP_FILTERED;
4336 printf("export > FILE.yaml : export configuration\n"
4337 "\t--backup: export only what's necessary for reconfig\n"
4338 "\t--help: display this help\n");
4343 if (backup && argc >= 3)
4345 else if (!backup && argc >= 2)
4351 f = fopen(file, "w");
4356 rc = yaml_lnet_config_ni(NULL, NULL, NULL, NULL, -1, NULL,
4357 flags & NLM_F_DUMP_FILTERED ? 1 : 2,
4360 if (rc == -EOPNOTSUPP)
4364 rc = yaml_lnet_route(NULL, NULL, -1, -1, -1, LNET_GENL_VERSION,
4367 if (rc == -EOPNOTSUPP)
4371 rc = lustre_lnet_show_routing(-1, &show_rc, &err_rc, backup);
4372 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4373 cYAML_print_tree2file(f, err_rc);
4374 cYAML_free_tree(err_rc);
4378 rc = yaml_lnet_peer(NULL, NULL, false, -1, false, false,
4379 flags & NLM_F_DUMP_FILTERED ? 0 : 3,
4382 if (rc == -EOPNOTSUPP)
4388 rc = lustre_lnet_show_net(NULL, 2, -1, &show_rc, &err_rc, backup);
4389 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4390 cYAML_print_tree2file(f, err_rc);
4391 cYAML_free_tree(err_rc);
4395 rc = lustre_lnet_show_route(NULL, NULL, -1, -1, 1, -1, &show_rc,
4397 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4398 cYAML_print_tree2file(f, err_rc);
4399 cYAML_free_tree(err_rc);
4403 rc = lustre_lnet_show_routing(-1, &show_rc, &err_rc, backup);
4404 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4405 cYAML_print_tree2file(f, err_rc);
4406 cYAML_free_tree(err_rc);
4410 rc = lustre_lnet_show_peer(NULL, 2, -1, &show_rc, &err_rc, backup);
4411 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4412 cYAML_print_tree2file(f, err_rc);
4413 cYAML_free_tree(err_rc);
4417 rc = lustre_lnet_show_numa_range(-1, &show_rc, &err_rc);
4418 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4419 cYAML_print_tree2file(f, err_rc);
4420 cYAML_free_tree(err_rc);
4424 rc = lustre_lnet_show_max_intf(-1, &show_rc, &err_rc);
4425 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4426 cYAML_print_tree2file(f, err_rc);
4427 cYAML_free_tree(err_rc);
4431 rc = lustre_lnet_show_discovery(-1, &show_rc, &err_rc);
4432 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4433 cYAML_print_tree2file(f, err_rc);
4434 cYAML_free_tree(err_rc);
4438 rc = lustre_lnet_show_drop_asym_route(-1, &show_rc, &err_rc);
4439 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4440 cYAML_print_tree2file(f, err_rc);
4441 cYAML_free_tree(err_rc);
4445 rc = lustre_lnet_show_retry_count(-1, &show_rc, &err_rc);
4446 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4447 cYAML_print_tree2file(f, err_rc);
4451 rc = lustre_lnet_show_transaction_to(-1, &show_rc, &err_rc);
4452 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4453 cYAML_print_tree2file(f, err_rc);
4457 rc = lustre_lnet_show_hsensitivity(-1, &show_rc, &err_rc);
4458 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4459 cYAML_print_tree2file(f, err_rc);
4463 rc = lustre_lnet_show_recov_intrv(-1, &show_rc, &err_rc);
4464 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4465 cYAML_print_tree2file(f, err_rc);
4469 rc = lustre_lnet_show_rtr_sensitivity(-1, &show_rc, &err_rc);
4470 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4471 cYAML_print_tree2file(f, err_rc);
4475 rc = lustre_lnet_show_lnd_timeout(-1, &show_rc, &err_rc);
4476 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4477 cYAML_print_tree2file(f, err_rc);
4481 rc = lustre_lnet_show_response_tracking(-1, &show_rc, &err_rc);
4482 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4483 cYAML_print_tree2file(f, err_rc);
4484 cYAML_free_tree(err_rc);
4488 rc = lustre_lnet_show_recovery_limit(-1, &show_rc, &err_rc);
4489 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4490 cYAML_print_tree2file(f, err_rc);
4491 cYAML_free_tree(err_rc);
4495 rc = lustre_lnet_show_max_recovery_ping_interval(-1, &show_rc, &err_rc);
4496 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4497 cYAML_print_tree2file(f, err_rc);
4498 cYAML_free_tree(err_rc);
4502 rc = lustre_lnet_show_udsp(-1, -1, &show_rc, &err_rc);
4503 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4504 cYAML_print_tree2file(f, err_rc);
4505 cYAML_free_tree(err_rc);
4509 if (show_rc != NULL) {
4510 cYAML_print_tree2file(f, show_rc);
4511 cYAML_free_tree(show_rc);
4520 static int jt_peer_nid_common(int argc, char **argv, int cmd)
4522 int flags = cmd == LNETCTL_ADD_CMD ? NLM_F_CREATE : 0;
4523 int rc = LUSTRE_CFG_RC_NO_ERR, opt;
4525 char *prim_nid = NULL, *nidstr = NULL;
4526 char err_str[LNET_MAX_STR_LEN] = "Error";
4527 struct cYAML *err_rc = NULL;
4529 const char *const short_opts = "k:m:n:f:l";
4530 const struct option long_opts[] = {
4531 { .name = "prim_nid", .has_arg = required_argument, .val = 'k' },
4532 { .name = "non_mr", .has_arg = no_argument, .val = 'm' },
4533 { .name = "nid", .has_arg = required_argument, .val = 'n' },
4534 { .name = "force", .has_arg = no_argument, .val = 'f' },
4535 { .name = "lock_prim", .has_arg = no_argument, .val = 'l' },
4538 rc = check_cmd(peer_cmds, "peer",
4539 cmd == LNETCTL_ADD_CMD ? "add" : "del", 2, argc, argv);
4543 while ((opt = getopt_long(argc, argv, short_opts,
4544 long_opts, NULL)) != -1) {
4553 if (cmd == LNETCTL_DEL_CMD) {
4554 rc = LUSTRE_CFG_RC_BAD_PARAM;
4555 snprintf(err_str, LNET_MAX_STR_LEN,
4556 "Unrecognized option '-%c'", opt);
4562 if (cmd == LNETCTL_ADD_CMD) {
4563 rc = LUSTRE_CFG_RC_BAD_PARAM;
4564 snprintf(err_str, LNET_MAX_STR_LEN,
4565 "Unrecognized option '-%c'", opt);
4568 flags |= NLM_F_EXCL;
4571 if (cmd == LNETCTL_DEL_CMD) {
4572 rc = LUSTRE_CFG_RC_BAD_PARAM;
4573 snprintf(err_str, LNET_MAX_STR_LEN,
4574 "Unrecognized option '-%c'", opt);
4577 flags |= NLM_F_EXCL;
4580 print_help(peer_cmds, "peer",
4581 cmd == LNETCTL_ADD_CMD ? "add" : "del");
4587 rc = yaml_lnet_peer(prim_nid, nidstr, !is_mr, -1, -1, false,
4588 LNET_GENL_VERSION, flags, stdout);
4590 if (rc == -EOPNOTSUPP)
4595 rc = lustre_lnet_modify_peer(prim_nid, nidstr, is_mr, cmd,
4596 force_lock, -1, &err_rc);
4597 if (rc != LUSTRE_CFG_RC_NO_ERR)
4601 cYAML_build_error(rc, -1, "peer",
4602 cmd == LNETCTL_ADD_CMD ? "add" : "del",
4606 if (rc != LUSTRE_CFG_RC_NO_ERR)
4607 cYAML_print_tree2file(stderr, err_rc);
4609 cYAML_free_tree(err_rc);
4614 static int jt_add_peer_nid(int argc, char **argv)
4616 return jt_peer_nid_common(argc, argv, LNETCTL_ADD_CMD);
4619 static int jt_del_peer_nid(int argc, char **argv)
4621 return jt_peer_nid_common(argc, argv, LNETCTL_DEL_CMD);
4624 static int jt_show_peer(int argc, char **argv)
4628 struct cYAML *err_rc = NULL, *show_rc = NULL;
4629 long int detail = 0;
4630 const char *const short_opts = "hn:v::";
4631 const struct option long_opts[] = {
4632 { .name = "help", .has_arg = no_argument, .val = 'h' },
4633 { .name = "nid", .has_arg = required_argument, .val = 'n' },
4634 { .name = "verbose", .has_arg = optional_argument, .val = 'v' },
4638 rc = check_cmd(peer_cmds, "peer", "show", 1, argc, argv);
4642 while ((opt = getopt_long(argc, argv, short_opts,
4643 long_opts, NULL)) != -1) {
4649 if ((!optarg) && (argv[optind] != NULL) &&
4650 (argv[optind][0] != '-')) {
4651 if (parse_long(argv[optind++], &detail) != 0)
4658 print_help(peer_cmds, "peer", "show");
4664 rc = yaml_lnet_peer(nid, NULL, false, -1, -1, false, detail,
4665 NLM_F_DUMP, stdout);
4667 if (rc == -EOPNOTSUPP)
4672 rc = lustre_lnet_show_peer(nid, (int) detail, -1, &show_rc, &err_rc,
4675 if (rc != LUSTRE_CFG_RC_NO_ERR)
4676 cYAML_print_tree2file(stderr, err_rc);
4678 cYAML_print_tree(show_rc);
4680 cYAML_free_tree(err_rc);
4681 cYAML_free_tree(show_rc);
4686 static int jt_list_peer(int argc, char **argv)
4688 struct cYAML *err_rc = NULL, *list_rc = NULL;
4691 rc = check_cmd(peer_cmds, "peer", "list", 0, argc, argv);
4695 rc = yaml_lnet_peer(NULL, NULL, false, -1, -1, true, 0, NLM_F_DUMP,
4698 if (rc == -EOPNOTSUPP)
4704 rc = lustre_lnet_list_peer(-1, &list_rc, &err_rc);
4705 if (rc != LUSTRE_CFG_RC_NO_ERR)
4706 cYAML_print_tree2file(stderr, err_rc);
4708 cYAML_print_tree(list_rc);
4710 cYAML_free_tree(err_rc);
4711 cYAML_free_tree(list_rc);
4716 static int yaml_lnet_ping_display(yaml_parser_t *reply)
4718 yaml_emitter_t debug;
4723 rc = yaml_emitter_initialize(&debug);
4725 yaml_emitter_set_output_file(&debug, stdout);
4732 rc = yaml_parser_parse(reply, &event);
4734 goto report_reply_error;
4736 if (event.type != YAML_SCALAR_EVENT) {
4737 rc = yaml_emitter_emit(&debug, &event);
4741 done = (event.type == YAML_DOCUMENT_END_EVENT);
4745 if (strcmp((char *)event.data.scalar.value, "errno") == 0) {
4746 rc = yaml_emitter_emit(&debug, &event);
4750 rc = yaml_parser_parse(reply, &event);
4752 goto report_reply_error;
4754 rc = parse_long((char *)event.data.scalar.value,
4757 goto report_reply_error;
4759 rc = yaml_emitter_emit(&debug, &event);
4764 } else if (error != 0 &&
4765 strcmp((char *)event.data.scalar.value,
4767 rc = yaml_emitter_emit(&debug, &event);
4771 rc = yaml_parser_parse(reply, &event);
4773 goto report_reply_error;
4775 if (strncmp((char *)event.data.scalar.value,
4776 "failed to ", strlen("failed to ")) == 0) {
4779 snprintf(err, sizeof(err), "%s: %s",
4780 (char *)event.data.scalar.value,
4782 yaml_scalar_event_initialize(&event, NULL,
4783 (yaml_char_t *)YAML_STR_TAG,
4786 YAML_PLAIN_SCALAR_STYLE);
4788 rc = yaml_emitter_emit(&debug, &event);
4794 rc = yaml_emitter_emit(&debug, &event);
4801 yaml_emitter_log_error(&debug, stderr);
4803 yaml_emitter_delete(&debug);
4805 return rc2 ? rc2 : rc;
4808 static int yaml_lnet_ping(char *group, int timeout, char *src_nidstr,
4809 int start, int end, char **nids, int flags)
4811 struct nl_sock *sk = NULL;
4812 const char *msg = NULL;
4813 yaml_emitter_t output;
4814 yaml_parser_t reply;
4818 /* Create Netlink emitter to send request to kernel */
4819 sk = nl_socket_alloc();
4823 /* Setup parser to receive Netlink packets */
4824 rc = yaml_parser_initialize(&reply);
4830 rc = yaml_parser_set_input_netlink(&reply, sk, false);
4832 msg = yaml_parser_get_reader_error(&reply);
4836 /* Create Netlink emitter to send request to kernel */
4837 rc = yaml_emitter_initialize(&output);
4839 msg = "failed to initialize emitter";
4843 rc = yaml_emitter_set_output_netlink(&output, sk, LNET_GENL_NAME,
4844 LNET_GENL_VERSION, LNET_CMD_PING,
4849 yaml_emitter_open(&output);
4850 yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
4851 rc = yaml_emitter_emit(&output, &event);
4855 yaml_mapping_start_event_initialize(&event, NULL,
4856 (yaml_char_t *)YAML_MAP_TAG,
4857 1, YAML_ANY_MAPPING_STYLE);
4858 rc = yaml_emitter_emit(&output, &event);
4862 yaml_scalar_event_initialize(&event, NULL,
4863 (yaml_char_t *)YAML_STR_TAG,
4864 (yaml_char_t *)group,
4865 strlen(group), 1, 0,
4866 YAML_PLAIN_SCALAR_STYLE);
4867 rc = yaml_emitter_emit(&output, &event);
4871 yaml_mapping_start_event_initialize(&event, NULL,
4872 (yaml_char_t *)YAML_MAP_TAG,
4873 1, YAML_ANY_MAPPING_STYLE);
4874 rc = yaml_emitter_emit(&output, &event);
4878 if (timeout != 1000 || src_nidstr) {
4880 yaml_scalar_event_initialize(&event, NULL,
4881 (yaml_char_t *)YAML_STR_TAG,
4882 (yaml_char_t *)"source",
4883 strlen("source"), 1, 0,
4884 YAML_PLAIN_SCALAR_STYLE);
4885 rc = yaml_emitter_emit(&output, &event);
4889 yaml_scalar_event_initialize(&event, NULL,
4890 (yaml_char_t *)YAML_STR_TAG,
4891 (yaml_char_t *)src_nidstr,
4892 strlen(src_nidstr), 1, 0,
4893 YAML_PLAIN_SCALAR_STYLE);
4894 rc = yaml_emitter_emit(&output, &event);
4899 if (timeout != 1000) {
4902 yaml_scalar_event_initialize(&event, NULL,
4903 (yaml_char_t *)YAML_STR_TAG,
4904 (yaml_char_t *)"timeout",
4905 strlen("timeout"), 1, 0,
4906 YAML_PLAIN_SCALAR_STYLE);
4907 rc = yaml_emitter_emit(&output, &event);
4911 snprintf(time, sizeof(time), "%u", timeout);
4912 yaml_scalar_event_initialize(&event, NULL,
4913 (yaml_char_t *)YAML_INT_TAG,
4914 (yaml_char_t *)time,
4916 YAML_PLAIN_SCALAR_STYLE);
4917 rc = yaml_emitter_emit(&output, &event);
4923 yaml_scalar_event_initialize(&event, NULL,
4924 (yaml_char_t *)YAML_STR_TAG,
4925 (yaml_char_t *)"nids",
4926 strlen("nids"), 1, 0,
4927 YAML_PLAIN_SCALAR_STYLE);
4928 rc = yaml_emitter_emit(&output, &event);
4932 yaml_sequence_start_event_initialize(&event, NULL,
4933 (yaml_char_t *)YAML_SEQ_TAG,
4934 1, YAML_FLOW_SEQUENCE_STYLE);
4935 rc = yaml_emitter_emit(&output, &event);
4939 for (i = start; i < end; i++) {
4940 yaml_scalar_event_initialize(&event, NULL,
4941 (yaml_char_t *)YAML_STR_TAG,
4942 (yaml_char_t *)nids[i],
4943 strlen(nids[i]), 1, 0,
4944 YAML_PLAIN_SCALAR_STYLE);
4945 rc = yaml_emitter_emit(&output, &event);
4950 yaml_sequence_end_event_initialize(&event);
4951 rc = yaml_emitter_emit(&output, &event);
4955 yaml_mapping_end_event_initialize(&event);
4956 rc = yaml_emitter_emit(&output, &event);
4960 yaml_mapping_end_event_initialize(&event);
4961 rc = yaml_emitter_emit(&output, &event);
4965 yaml_document_end_event_initialize(&event, 0);
4966 rc = yaml_emitter_emit(&output, &event);
4970 rc = yaml_emitter_close(&output);
4973 yaml_emitter_log_error(&output, stderr);
4976 rc = yaml_lnet_ping_display(&reply);
4978 msg = yaml_parser_get_reader_error(&reply);
4980 yaml_emitter_delete(&output);
4983 yaml_lnet_print_error(-1, group, msg);
4987 yaml_parser_delete(&reply);
4990 return rc == 1 ? 0 : rc;
4993 static int jt_ping(int argc, char **argv)
4995 struct cYAML *err_rc = NULL;
4996 struct cYAML *show_rc = NULL;
4999 char *src_nidstr = NULL;
5000 const char *const short_options = "hs:t:";
5001 const struct option long_options[] = {
5002 { .name = "help", .has_arg = no_argument, .val = 'h' },
5003 { .name = "timeout", .has_arg = required_argument, .val = 't' },
5004 { .name = "source", .has_arg = required_argument, .val = 's' },
5008 while ((opt = getopt_long(argc, argv, short_options,
5009 long_options, NULL)) != -1) {
5012 src_nidstr = optarg;
5015 timeout = 1000 * atol(optarg);
5018 printf("ping nid[,nid,...]\n"
5019 "\t --source: source nid\n"
5020 "\t --timeout: ping timeout\n"
5021 "\t --help: display this help\n");
5028 rc = yaml_lnet_ping("ping", timeout, src_nidstr, optind, argc,
5031 if (rc != -EOPNOTSUPP)
5035 for (; optind < argc; optind++)
5036 rc = lustre_lnet_ping_nid(argv[optind], src_nidstr, timeout, -1,
5040 cYAML_print_tree(show_rc);
5043 cYAML_print_tree2file(stderr, err_rc);
5045 cYAML_free_tree(err_rc);
5046 cYAML_free_tree(show_rc);
5051 static int jt_discover(int argc, char **argv)
5053 struct cYAML *err_rc = NULL;
5054 struct cYAML *show_rc = NULL;
5055 int flags = NLM_F_CREATE;
5058 const char *const short_options = "fh";
5059 const struct option long_options[] = {
5060 { .name = "force", .has_arg = no_argument, .val = 'f' },
5061 { .name = "help", .has_arg = no_argument, .val = 'h' },
5065 while ((opt = getopt_long(argc, argv, short_options,
5066 long_options, NULL)) != -1) {
5069 /* BSD treats NLM_F_CREATE | NLM_F_EXCL as an add */
5070 flags |= NLM_F_EXCL;
5074 printf("discover nid[,nid,...]\n"
5075 "\t --force: force discovery\n"
5076 "\t --help: display this help\n");
5083 if (optind == argc) {
5084 printf("Missing nid argument\n");
5088 rc = yaml_lnet_ping("discover", 1000, NULL, optind, argc, argv,
5091 if (rc != -EOPNOTSUPP)
5095 for (; optind < argc; optind++)
5096 rc = lustre_lnet_discover_nid(argv[optind], force, -1, &show_rc,
5100 cYAML_print_tree(show_rc);
5103 cYAML_print_tree2file(stderr, err_rc);
5105 cYAML_free_tree(err_rc);
5106 cYAML_free_tree(show_rc);
5111 static int jt_add_udsp(int argc, char **argv)
5113 char *src = NULL, *dst = NULL, *rte = NULL;
5114 struct cYAML *err_rc = NULL;
5115 union lnet_udsp_action udsp_action;
5116 long int idx = -1, priority = -1;
5118 char *action_type = "pref";
5120 const char *const short_options = "s:d:r:p:i:";
5121 static const struct option long_options[] = {
5122 { .name = "src", .has_arg = required_argument, .val = 's' },
5123 { .name = "dst", .has_arg = required_argument, .val = 'd' },
5124 { .name = "rte", .has_arg = required_argument, .val = 'r' },
5125 { .name = "priority", .has_arg = required_argument, .val = 'p' },
5126 { .name = "idx", .has_arg = required_argument, .val = 'i' },
5129 rc = check_cmd(udsp_cmds, "udsp", "add", 0, argc, argv);
5133 while ((opt = getopt_long(argc, argv, short_options,
5134 long_options, NULL)) != -1) {
5146 rc = parse_long(optarg, &priority);
5147 if (rc != 0 || priority < 0) {
5148 printf("Invalid priority \"%s\"\n", optarg);
5151 action_type = "priority";
5152 udsp_action.udsp_priority = priority;
5155 rc = parse_long(optarg, &idx);
5156 if (rc != 0 || idx < 0) {
5157 printf("Invalid index \"%s\"\n", optarg);
5162 print_help(udsp_cmds, "udsp", "add");
5168 if (!(src || dst || rte)) {
5169 print_help(udsp_cmds, "udsp", "add");
5173 rc = lustre_lnet_add_udsp(src, dst, rte, action_type, &udsp_action,
5176 if (rc != LUSTRE_CFG_RC_NO_ERR)
5177 cYAML_print_tree2file(stderr, err_rc);
5179 cYAML_free_tree(err_rc);
5184 static int jt_del_udsp(int argc, char **argv)
5186 struct cYAML *err_rc = NULL;
5191 const char *const short_options = "ai:";
5192 static const struct option long_options[] = {
5193 { .name = "all", .has_arg = no_argument, .val = 'a' },
5194 { .name = "idx", .has_arg = required_argument, .val = 'i' },
5197 rc = check_cmd(udsp_cmds, "udsp", "del", 0, argc, argv);
5201 while ((opt = getopt_long(argc, argv, short_options,
5202 long_options, NULL)) != -1) {
5208 rc = parse_long(optarg, &idx);
5209 if (rc != 0 || idx < -1) {
5210 printf("Invalid index \"%s\"\n", optarg);
5215 print_help(udsp_cmds, "udsp", "del");
5221 if (all && idx != -2) {
5222 printf("Cannot combine --all with --idx\n");
5226 } else if (idx == -2) {
5227 printf("Must specify --idx or --all\n");
5231 rc = lustre_lnet_del_udsp(idx, -1, &err_rc);
5232 if (rc != LUSTRE_CFG_RC_NO_ERR)
5233 cYAML_print_tree2file(stderr, err_rc);
5235 cYAML_free_tree(err_rc);
5240 int main(int argc, char **argv)
5243 struct cYAML *err_rc = NULL;
5245 rc = lustre_lnet_config_lib_init();
5247 cYAML_build_error(-1, -1, "lnetctl", "startup",
5248 "cannot register LNet device", &err_rc);
5249 cYAML_print_tree2file(stderr, err_rc);
5253 return cfs_parser(argc, argv, cmd_list);