1 // SPDX-License-Identifier: LGPL-2.1+
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_debug_nidlist(int argc, char **argv);
45 static int jt_show_global(int argc, char **argv);
46 static int jt_show_udsp(int argc, char **argv);
47 static int jt_set_tiny(int argc, char **argv);
48 static int jt_set_small(int argc, char **argv);
49 static int jt_set_large(int argc, char **argv);
50 static int jt_set_numa(int argc, char **argv);
51 static int jt_set_retry_count(int argc, char **argv);
52 static int jt_set_transaction_to(int argc, char **argv);
53 static int jt_set_recov_intrv(int argc, char **argv);
54 static int jt_set_rtr_sensitivity(int argc, char **argv);
55 static int jt_set_hsensitivity(int argc, char **argv);
56 static int jt_set_max_recovery_ping_interval(int argc, char **argv);
57 static int jt_reset_stats(int argc, char **argv);
58 static int jt_add_peer_nid(int argc, char **argv);
59 static int jt_del_peer_nid(int argc, char **argv);
60 static int jt_set_max_intf(int argc, char **argv);
61 static int jt_set_discovery(int argc, char **argv);
62 static int jt_set_drop_asym_route(int argc, char **argv);
63 static int jt_list_peer(int argc, char **argv);
64 static int jt_add_udsp(int argc, char **argv);
65 static int jt_del_udsp(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_fault(int argc, char **argv);
86 static int jt_fault_drop(int argc, char **argv);
87 static int jt_fault_drop_add(int argc, char **argv);
88 static int jt_fault_drop_del(int argc, char **argv);
89 static int jt_fault_drop_reset(int argc, char **argv);
90 static int jt_fault_drop_show(int argc, char **argv);
91 static int jt_fault_delay(int argc, char **argv);
92 static int jt_fault_delay_add(int argc, char **argv);
93 static int jt_fault_delay_del(int argc, char **argv);
94 static int jt_fault_delay_reset(int argc, char **argv);
95 static int jt_fault_delay_show(int argc, char **argv);
96 static int jt_setup_mrrouting(int argc, char **argv);
97 static int jt_setup_sysctl(int argc, char **argv);
98 static int jt_calc_cpt_of_nid(int argc, char **argv);
99 static int jt_show_peer_debug_info(int argc, char **argv);
101 command_t cmd_list[] = {
102 {"lnet", jt_lnet, 0, "lnet {configure | unconfigure} [--all|--large]"},
103 {"route", jt_route, 0, "route {add | del | show | help}"},
104 {"net", jt_net, 0, "net {add | del | show | set | help}"},
105 {"routing", jt_routing, 0, "routing {show | help}"},
106 {"set", jt_set, 0, "set {tiny_buffers | small_buffers | large_buffers"
107 " | routing | numa_range | max_interfaces"
108 " | discovery | drop_asym_route | retry_count"
109 " | transaction_timeout | health_sensitivity"
110 " | recovery_interval | router_sensitivity"
111 " | response_tracking | recovery_limit}"},
112 {"import", jt_import, 0, "import FILE.yaml"},
113 {"export", jt_export, 0, "export FILE.yaml"},
114 {"stats", jt_stats, 0, "stats {show | help}"},
115 {"debug", jt_debug, 0, "debug {recovery {local | peer} | peer}"},
116 {"global", jt_global, 0, "global {show | help}"},
117 {"peer", jt_peers, 0, "peer {add | del | show | list | set | help}"},
118 {"ping", jt_ping, 0, "ping nid,[nid,...]"},
119 {"discover", jt_discover, 0, "discover nid[,nid,...]"},
120 {"service-id", jt_calc_service_id, 0, "Calculate IB Lustre service ID\n"},
121 {"udsp", jt_udsp, 0, "udsp {add | del | help}"},
122 {"fault", jt_fault, 0, "{drop | delay | help}"},
123 {"setup-mrrouting", jt_setup_mrrouting, 0,
124 "setup linux routing tables\n"},
125 {"setup-sysctl", jt_setup_sysctl, 0,
126 "setup linux sysctl parameter for large systems\n"},
127 {"cpt-of-nid", jt_calc_cpt_of_nid, 0,
128 "Calculate the CPTs associated with NIDs\n"
129 " usage:\n\tlnetctl cpt-of-nid nid[ nid ...]\n"},
133 command_t lnet_cmds[] = {
134 {"configure", jt_config_lnet, 0, "configure lnet\n"
135 "\t--all: load NI configuration from module parameters\n"
136 "\t--large: start LNet with large NIDs\n"},
137 {"unconfigure", jt_unconfig_lnet, 0, "unconfigure lnet\n"},
141 command_t route_cmds[] = {
142 {"add", jt_add_route, 0, "add a route\n"
143 "\t--net: net name (e.g. tcp0)\n"
144 "\t--gateway: gateway nid (e.g. 10.1.1.2@tcp)\n"
145 "\t--hop|hop-count: number to final destination (1 <= hops <= 255)\n"
146 "\t--priority: priority of route (0 - highest prio\n"
147 "\t--health_sensitivity: gateway health sensitivity (>= 1)\n"},
148 {"del", jt_del_route, 0, "delete a route\n"
149 "\t--net: net name (e.g. tcp0)\n"
150 "\t--gateway: gateway nid (e.g. 10.1.1.2@tcp)\n"},
151 {"show", jt_show_route, 0, "show routes\n"
152 "\t--net: net name (e.g. tcp0) to filter on\n"
153 "\t--gateway: gateway nid (e.g. 10.1.1.2@tcp) to filter on\n"
154 "\t--hop|hop-count: number to final destination (1 <= hops <= 255) to filter on\n"
155 "\t--priority: priority of route (0 - highest prio to filter on\n"
156 "\t--verbose: display detailed output per route\n"},
160 command_t net_cmds[] = {
161 {"add", jt_add_ni, 0, "add a network\n"
162 "\t--net: net name (e.g. tcp0)\n"
163 "\t--if: physical interface (e.g. eth0)\n"
164 "\t--nid: bring up NI based on the address of the specified LNet NID\n"
165 "\t--ip2net: specify networks based on IP address patterns\n"
166 "\t--peer-timeout: time to wait before declaring a peer dead\n"
167 "\t--peer-credits: define the max number of inflight messages\n"
168 "\t--peer-buffer-credits: the number of buffer credits per peer\n"
169 "\t--credits: Network Interface credits\n"
170 "\t--cpt: CPU Partitions configured net uses (e.g. [0,1]\n"
171 "\t--conns-per-peer: number of connections per peer\n"
172 "\t--skip-mr-route-setup: do not add linux route for the ni\n"
173 "\t--auth-key: Network authorization key (kfilnd only)\n"
174 "\t--traffic-class: Traffic class (kfilnd only)\n"
175 "\t--tos: IP's Type of Service\n"},
176 {"del", jt_del_ni, 0, "delete a network\n"
177 "\t--net: net name (e.g. tcp0)\n"
178 "\t--nid: shutdown NI based on the address of the specified LNet NID\n"
179 "\t--if: physical interface (e.g. eth0)\n"},
180 {"show", jt_show_net, 0, "show networks\n"
181 "\t--net: net name (e.g. tcp0) to filter on\n"
182 "\t--verbose: display detailed output per network."
183 " Optional argument of '2' outputs more stats\n"},
184 {"set", jt_set_ni_value, 0, "set local NI specific parameter\n"
185 "\t--nid: NI NID to set the value on\n"
186 "\t--net: network to set the value on (e.g. tcp, o2ib, kfi)\n"
187 "\t--lnd-timeout: set LND timeout (seconds) for LND used by --net argument\n"
188 "\t--health: specify health value to set\n"
189 "\t--conns-per-peer: number of connections per peer\n"
190 "\t--all: set all NIs value to the one specified\n"},
194 command_t routing_cmds[] = {
195 {"show", jt_show_routing, 0, "show routing information\n"},
199 command_t stats_cmds[] = {
200 {"show", jt_show_stats, 0, "show LNET statistics\n"},
201 {"reset", jt_reset_stats, 0, "reset LNET statistics\n"},
205 command_t debug_cmds[] = {
206 {"recovery", jt_show_recovery, 0, "list recovery queues\n"
207 "\t--local : list local recovery queue\n"
208 "\t--peer : list peer recovery queue\n"},
209 {"peer", jt_show_peer_debug_info, 0, "show peer debug info\n"
210 "\t--nid: peer's NID\n"},
211 {"nidlist", jt_debug_nidlist, 0, "debug nidlist parsing\n"},
215 command_t global_cmds[] = {
216 {"show", jt_show_global, 0, "show global variables\n"},
220 command_t set_cmds[] = {
221 {"tiny_buffers", jt_set_tiny, 0, "set tiny routing buffers\n"
222 "\tVALUE must be greater than 0\n"},
223 {"small_buffers", jt_set_small, 0, "set small routing buffers\n"
224 "\tVALUE must be greater than 0\n"},
225 {"large_buffers", jt_set_large, 0, "set large routing buffers\n"
226 "\tVALUE must be greater than 0\n"},
227 {"routing", jt_set_routing, 0, "enable/disable routing\n"
228 "\t0 - disable routing\n"
229 "\t1 - enable routing\n"},
230 {"numa_range", jt_set_numa, 0, "set NUMA range for NI selection\n"
231 "\tVALUE must be at least 0\n"},
232 {"max_interfaces", jt_set_max_intf, 0, "set the default value for "
234 "\tValue must be greater than 16\n"},
235 {"discovery", jt_set_discovery, 0, "enable/disable peer discovery\n"
236 "\t0 - disable peer discovery\n"
237 "\t1 - enable peer discovery (default)\n"},
238 {"drop_asym_route", jt_set_drop_asym_route, 0,
239 "drop/accept asymmetrical route messages\n"
240 "\t0 - accept asymmetrical route messages (default)\n"
241 "\t1 - drop asymmetrical route messages\n"},
242 {"retry_count", jt_set_retry_count, 0, "number of retries\n"
243 "\t0 - turn of retries\n"
244 "\t>0 - number of retries\n"},
245 {"transaction_timeout", jt_set_transaction_to, 0, "Message/Response timeout\n"
246 "\t>0 - timeout in seconds\n"},
247 {"health_sensitivity", jt_set_hsensitivity, 0, "sensitivity to failure\n"
248 "\t0 - turn off health evaluation\n"
249 "\t>0 - sensitivity value not more than 1000\n"},
250 {"recovery_interval", jt_set_recov_intrv, 0, "interval to ping in seconds (at least 1)\n"
251 "\t>0 - time in seconds between pings\n"},
252 {"router_sensitivity", jt_set_rtr_sensitivity, 0, "router sensitivity %\n"
253 "\t100 - router interfaces need to be fully healthy to be used\n"
254 "\t<100 - router interfaces can be used even if not healthy\n"},
255 {"response_tracking", jt_set_response_tracking, 0,
256 "Set the behavior of response tracking\n"
257 "\t0 - Only LNet pings and discovery pushes utilize response tracking\n"
258 "\t1 - GETs are eligible for response tracking\n"
259 "\t2 - PUTs are eligible for response tracking\n"
260 "\t3 - Both PUTs and GETs are eligible for response tracking (default)\n"
261 "\tNote: Regardless of the value of the response_tracking parameter LNet\n"
262 "\t pings and discovery pushes always utilize response tracking\n"},
263 {"recovery_limit", jt_set_recovery_limit, 0,
264 "Set how long LNet will attempt to recover unhealthy interfaces.\n"
265 "\t0 - Recover indefinitely (default)\n"
266 "\t>0 - Recover for the specified number of seconds.\n"},
267 {"max_recovery_ping_interval", jt_set_max_recovery_ping_interval, 0,
268 "maximum recovery ping interval\n"
269 "\t>0 - maximum recovery ping interval in seconds\n"},
273 command_t peer_cmds[] = {
274 {"add", jt_add_peer_nid, 0, "add a peer NID\n"
275 "\t--prim_nid: Primary NID of the peer.\n"
276 "\t--nid: one or more peer NIDs\n"
277 "\t--non_mr: create this peer as not Multi-Rail capable\n"
278 "\t--ip2nets: specify a range of nids per peer\n"
279 "\t--lock_prim: lock primary nid\n"},
280 {"del", jt_del_peer_nid, 0, "delete a peer NID\n"
281 "\t--prim_nid: Primary NID of the peer.\n"
282 "\t--nid: list of NIDs to remove. If none provided,\n"
283 "\t peer is deleted\n"
284 "\t--ip2nets: specify a range of nids per peer\n"
285 "\t--force: force-delete locked primary NID\n"},
286 {"show", jt_show_peer, 0, "show peer information\n"
287 "\t--nid: NID of peer to filter on.\n"
288 "\t--verbose: display detailed output per peer."
289 " Optional argument of '2' outputs more stats\n"},
290 {"list", jt_list_peer, 0, "list all peers\n"},
291 {"set", jt_set_peer_ni_value, 0, "set peer ni specific parameter\n"
292 "\t--nid: Peer NI NID to set the\n"
293 "\t--health: specify health value to set\n"
294 "\t--all: set all peer_nis values to the one specified\n"
295 "\t--state: set peer state (DANGEROUS: for test/debug only)"},
299 command_t udsp_cmds[] = {
300 {"add", jt_add_udsp, 0, "add a udsp\n"
301 "\t--src nid|net: ip2nets syntax specifying the local NID or network to match.\n"
302 "\t--dst nid: ip2nets syntax specifying the remote NID to match.\n"
303 "\t--rte nid: ip2nets syntax specifying the router NID to match.\n"
304 "\t--priority p: Assign priority value p where p >= 0.\n"
305 "\t Note: 0 is the highest priority.\n"
306 "\t--idx n: Insert the rule in the n'th position on the list of rules.\n"
307 "\t By default, rules are appended to the end of the rule list.\n"},
308 {"del", jt_del_udsp, 0, "delete a udsp\n"
309 "\t--all: Delete all rules.\n"
310 "\t--idx n: Delete the rule at index n.\n"},
311 {"show", jt_show_udsp, 0, "show udsps\n"
312 "\t--idx n: Show the rule at at index n.\n"
313 "\t By default, all rules are shown.\n"},
317 command_t fault_cmds[] = {
318 {"drop", jt_fault_drop, 0, "Manage drop rules\n"
319 "usage: lnetctl fault drop add [<options>] -r <rate>|-i <interval> -s <src> -d <dest>\n"
320 " or: lnetctl fault drop del -s <src> -d <dest>\n"
321 " or: lnetctl fault drop show\n"
322 " or: lnetctl fault drop reset\n" },
323 {"delay", jt_fault_delay, 0, "Manage delay rules\n"
324 "usage: lnetctl fault delay add [<options>] -r <rate>|-i <interval> -s <src> -d <dest>\n"
325 " or: lnetctl fault delay del -s <src> -d <dest>\n"
326 " or: lnetctl fault delay show\n"
327 " or: lnetctl fault delay reset\n" },
331 command_t fault_drop_cmds[] = {
332 {"add", jt_fault_drop_add, 0, "add LNet drop rule\n"
333 "\t--source nid: Drop messages originating from <nid>.\n"
334 "\t--dest nid: Drop messages destined for <nid>.\n"
335 "\t--rate r: Drop messages at specified rate (1/<r>).\n"
336 "\t--interval i: Drop messages at specified time interval (seconds).\n"
337 "\t--portal p: Drop messages on specified portal.\n"
338 "\t--message m: Drop messages of specified type <PUT|ACK|GET|REPLY>.\n"
339 "\t--health_error: Dropped messages simulate the specified health status\n"
340 "\t <local_timeout|remote_dropped|network_timeout|...>.\n" },
341 {"del", jt_fault_drop_del, 0, "delete LNet drop rules\n"
342 "\t--all: Delete all drop rules\n"
343 "\t--source nid: Delete drop rule with specified source NID\n"
344 "\t--dest nid: Delete drop rule with specified destination NID\n"},
345 {"reset", jt_fault_drop_reset, 0, "reset counters for all drop rules\n" },
346 {"show", jt_fault_drop_show, 0, "show drop rules\n" },
350 command_t fault_delay_cmds[] = {
351 {"add", jt_fault_delay_add, 0, "add LNet delay rule\n"
352 "\t--source nid: Delay messages originating from <nid>.\n"
353 "\t--dest nid: Delay messages destined for <nid>.\n"
354 "\t--rate r: Delay messages at specified rate (1/<r>).\n"
355 "\t--interval i: Delay messages at specified time interval (seconds).\n"
356 "\t--portal p: Delay messages on specified portal.\n"
357 "\t--message m: Delay messages of specified type <PUT|ACK|GET|REPLY>.\n"
358 "\t--latency: Delay sending a message (delay only).\n"},
359 {"del", jt_fault_delay_del, 0, "delete LNet delay rules\n"
360 "\t--all: Delete all delay rules\n"
361 "\t--source nid: Delete delay rule with specified source NID\n"
362 "\t--dest nid: Delete delay rule with specified destination NID\n"},
363 {"reset", jt_fault_delay_reset, 0, "reset counters for all delay rules\n" },
364 {"show", jt_fault_delay_show, 0, "show delay rules\n" },
368 static int parse_long(const char *number, long int *value)
375 *value = strtol(number, &end, 0);
376 if (end != NULL && *end != 0)
382 static int jt_setup_mrrouting(int argc, char **argv)
385 struct cYAML *err_rc = NULL;
387 rc = lustre_lnet_setup_mrrouting(&err_rc);
389 if (rc != LUSTRE_CFG_RC_NO_ERR)
390 cYAML_print_tree2file(stderr, err_rc);
392 cYAML_free_tree(err_rc);
397 static int jt_setup_sysctl(int argc, char **argv)
400 struct cYAML *err_rc = NULL;
402 rc = lustre_lnet_setup_sysctl(&err_rc);
404 if (rc != LUSTRE_CFG_RC_NO_ERR)
405 cYAML_print_tree2file(stderr, err_rc);
407 cYAML_free_tree(err_rc);
412 static inline void print_help(const command_t cmds[], const char *cmd_type,
415 const command_t *cmd;
417 for (cmd = cmds; cmd->pc_name; cmd++) {
418 if (pc_name != NULL &&
419 strcmp(cmd->pc_name, pc_name) == 0) {
420 printf("%s %s: %s\n", cmd_type, cmd->pc_name,
423 } else if (pc_name != NULL) {
426 printf("%s %s: %s\n", cmd_type, cmd->pc_name, cmd->pc_help);
431 * Perform some basic input validation.
433 * LUSTRE_CFG_RC_BAD_PARAM: when minimum number of arguments has not been
435 * > 0: when '-h' or '--help' has been supplied
436 * 0: when the "check" passes and command can continue execution
438 static int check_cmd(const command_t *cmd_list, const char *cmd,
439 const char *sub_cmd, const int min_args,
440 int argc, char **argv)
447 const char *const short_options = "h";
448 static const struct option long_options[] = {
449 { .name = "help", .has_arg = no_argument, .val = 'h' },
453 if (argc < min_args) {
454 print_help(cmd_list, cmd, sub_cmd);
455 rc = LUSTRE_CFG_RC_BAD_PARAM;
457 } else if (argc > 2) {
461 while ((opt = getopt_long(argc, argv, short_options,
462 long_options, NULL)) != -1) {
465 print_help(cmd_list, cmd, sub_cmd);
480 static int jt_set_response_tracking(int argc, char **argv)
484 struct cYAML *err_rc = NULL;
486 rc = check_cmd(set_cmds, "set", "response_tracking", 2, argc, argv);
490 rc = parse_long(argv[1], &value);
492 cYAML_build_error(-1, -1, "parser", "set",
493 "cannot parse response_tracking value",
495 cYAML_print_tree2file(stderr, err_rc);
496 cYAML_free_tree(err_rc);
500 rc = lustre_lnet_config_response_tracking(value, -1, &err_rc);
501 if (rc != LUSTRE_CFG_RC_NO_ERR)
502 cYAML_print_tree2file(stderr, err_rc);
504 cYAML_free_tree(err_rc);
509 static int jt_calc_service_id(int argc, char **argv)
514 rc = lustre_lnet_calc_service_id(&service_id);
515 if (rc != LUSTRE_CFG_RC_NO_ERR)
518 /* cYAML currently doesn't support printing hex values.
519 * Therefore just print it locally here
521 printf("service_id:\n value: 0x%llx\n",
522 (unsigned long long)(service_id));
527 static int jt_set_recovery_limit(int argc, char **argv)
531 struct cYAML *err_rc = NULL;
533 rc = check_cmd(set_cmds, "set", "recovery_limit", 2, argc, argv);
537 rc = parse_long(argv[1], &value);
539 cYAML_build_error(-1, -1, "parser", "set",
540 "cannot parse recovery_limit value",
542 cYAML_print_tree2file(stderr, err_rc);
543 cYAML_free_tree(err_rc);
547 rc = lustre_lnet_config_recovery_limit(value, -1, &err_rc);
548 if (rc != LUSTRE_CFG_RC_NO_ERR)
549 cYAML_print_tree2file(stderr, err_rc);
551 cYAML_free_tree(err_rc);
556 static int jt_set_max_intf(int argc, char **argv)
560 struct cYAML *err_rc = NULL;
562 rc = check_cmd(set_cmds, "set", "max_interfaces", 2, argc, argv);
566 rc = parse_long(argv[1], &value);
568 cYAML_build_error(-1, -1, "parser", "set",
569 "cannot parse max_interfaces value", &err_rc);
570 cYAML_print_tree2file(stderr, err_rc);
571 cYAML_free_tree(err_rc);
575 rc = lustre_lnet_config_max_intf(value, -1, &err_rc);
576 if (rc != LUSTRE_CFG_RC_NO_ERR)
577 cYAML_print_tree2file(stderr, err_rc);
579 cYAML_free_tree(err_rc);
584 static int jt_set_numa(int argc, char **argv)
588 struct cYAML *err_rc = NULL;
590 rc = check_cmd(set_cmds, "set", "numa_range", 2, argc, argv);
594 rc = parse_long(argv[1], &value);
596 cYAML_build_error(-1, -1, "parser", "set",
597 "cannot parse numa_range value", &err_rc);
598 cYAML_print_tree2file(stderr, err_rc);
599 cYAML_free_tree(err_rc);
603 rc = lustre_lnet_config_numa_range(value, -1, &err_rc);
604 if (rc != LUSTRE_CFG_RC_NO_ERR)
605 cYAML_print_tree2file(stderr, err_rc);
607 cYAML_free_tree(err_rc);
612 static int jt_set_recov_intrv(int argc, char **argv)
616 struct cYAML *err_rc = NULL;
618 rc = check_cmd(set_cmds, "set", "recovery_interval", 2, argc, argv);
622 rc = parse_long(argv[1], &value);
624 cYAML_build_error(-1, -1, "parser", "set",
625 "cannot parse recovery interval value", &err_rc);
626 cYAML_print_tree2file(stderr, err_rc);
627 cYAML_free_tree(err_rc);
631 rc = lustre_lnet_config_recov_intrv(value, -1, &err_rc);
632 if (rc != LUSTRE_CFG_RC_NO_ERR)
633 cYAML_print_tree2file(stderr, err_rc);
635 cYAML_free_tree(err_rc);
640 static int jt_set_rtr_sensitivity(int argc, char **argv)
644 struct cYAML *err_rc = NULL;
646 rc = check_cmd(set_cmds, "set", "router_sensitivity", 2, argc, argv);
650 rc = parse_long(argv[1], &value);
652 cYAML_build_error(-1, -1, "parser", "set",
653 "cannot parse router sensitivity value", &err_rc);
654 cYAML_print_tree2file(stderr, err_rc);
655 cYAML_free_tree(err_rc);
659 rc = lustre_lnet_config_rtr_sensitivity(value, -1, &err_rc);
660 if (rc != LUSTRE_CFG_RC_NO_ERR)
661 cYAML_print_tree2file(stderr, err_rc);
663 cYAML_free_tree(err_rc);
668 static int jt_set_hsensitivity(int argc, char **argv)
672 struct cYAML *err_rc = NULL;
674 rc = check_cmd(set_cmds, "set", "health_sensitivity", 2, argc, argv);
678 rc = parse_long(argv[1], &value);
680 cYAML_build_error(-1, -1, "parser", "set",
681 "cannot parse health sensitivity value", &err_rc);
682 cYAML_print_tree2file(stderr, err_rc);
683 cYAML_free_tree(err_rc);
687 rc = lustre_lnet_config_hsensitivity(value, -1, &err_rc);
688 if (rc != LUSTRE_CFG_RC_NO_ERR)
689 cYAML_print_tree2file(stderr, err_rc);
691 cYAML_free_tree(err_rc);
696 static int jt_reset_stats(int argc, char **argv)
699 struct cYAML *err_rc = NULL;
701 rc = check_cmd(stats_cmds, "stats", "reset", 0, argc, argv);
705 rc = lustre_lnet_reset_stats(-1, &err_rc);
706 if (rc != LUSTRE_CFG_RC_NO_ERR)
707 cYAML_print_tree2file(stderr, err_rc);
709 cYAML_free_tree(err_rc);
714 static int jt_set_transaction_to(int argc, char **argv)
718 struct cYAML *err_rc = NULL;
720 rc = check_cmd(set_cmds, "set", "transaction_timeout", 2, argc, argv);
724 rc = parse_long(argv[1], &value);
726 cYAML_build_error(-1, -1, "parser", "set",
727 "cannot parse transaction timeout value", &err_rc);
728 cYAML_print_tree2file(stderr, err_rc);
729 cYAML_free_tree(err_rc);
733 rc = lustre_lnet_config_transaction_to(value, -1, &err_rc);
734 if (rc != LUSTRE_CFG_RC_NO_ERR)
735 cYAML_print_tree2file(stderr, err_rc);
737 cYAML_free_tree(err_rc);
742 static int jt_set_retry_count(int argc, char **argv)
746 struct cYAML *err_rc = NULL;
748 rc = check_cmd(set_cmds, "set", "retry_count", 2, argc, argv);
752 rc = parse_long(argv[1], &value);
754 cYAML_build_error(-1, -1, "parser", "set",
755 "cannot parse retry_count value", &err_rc);
756 cYAML_print_tree2file(stderr, err_rc);
757 cYAML_free_tree(err_rc);
761 rc = lustre_lnet_config_retry_count(value, -1, &err_rc);
762 if (rc != LUSTRE_CFG_RC_NO_ERR)
763 cYAML_print_tree2file(stderr, err_rc);
765 cYAML_free_tree(err_rc);
770 static int jt_set_discovery(int argc, char **argv)
774 struct cYAML *err_rc = NULL;
776 rc = check_cmd(set_cmds, "set", "discovery", 2, argc, argv);
780 rc = parse_long(argv[1], &value);
782 cYAML_build_error(-1, -1, "parser", "set",
783 "cannot parse discovery value", &err_rc);
784 cYAML_print_tree2file(stderr, err_rc);
785 cYAML_free_tree(err_rc);
789 rc = lustre_lnet_config_discovery(value, -1, &err_rc);
790 if (rc != LUSTRE_CFG_RC_NO_ERR)
791 cYAML_print_tree2file(stderr, err_rc);
793 cYAML_free_tree(err_rc);
798 static int jt_set_drop_asym_route(int argc, char **argv)
802 struct cYAML *err_rc = NULL;
804 rc = check_cmd(set_cmds, "set", "drop_asym_route", 2, argc, argv);
808 rc = parse_long(argv[1], &value);
810 cYAML_build_error(-1, -1, "parser", "set",
811 "cannot parse drop_asym_route value",
813 cYAML_print_tree2file(stderr, err_rc);
814 cYAML_free_tree(err_rc);
818 rc = lustre_lnet_config_drop_asym_route(value, -1, &err_rc);
819 if (rc != LUSTRE_CFG_RC_NO_ERR)
820 cYAML_print_tree2file(stderr, err_rc);
822 cYAML_free_tree(err_rc);
827 static int jt_set_tiny(int argc, char **argv)
831 struct cYAML *err_rc = NULL;
833 rc = check_cmd(set_cmds, "set", "tiny_buffers", 2, argc, argv);
837 rc = parse_long(argv[1], &value);
839 cYAML_build_error(-1, -1, "parser", "set",
840 "cannot parse tiny_buffers value", &err_rc);
841 cYAML_print_tree2file(stderr, err_rc);
842 cYAML_free_tree(err_rc);
846 rc = lustre_lnet_config_buffers(value, -1, -1, -1, &err_rc);
847 if (rc != LUSTRE_CFG_RC_NO_ERR)
848 cYAML_print_tree2file(stderr, err_rc);
850 cYAML_free_tree(err_rc);
855 static int jt_set_small(int argc, char **argv)
859 struct cYAML *err_rc = NULL;
861 rc = check_cmd(set_cmds, "set", "small_buffers", 2, argc, argv);
865 rc = parse_long(argv[1], &value);
867 cYAML_build_error(-1, -1, "parser", "set",
868 "cannot parse small_buffers value", &err_rc);
869 cYAML_print_tree2file(stderr, err_rc);
870 cYAML_free_tree(err_rc);
874 rc = lustre_lnet_config_buffers(-1, value, -1, -1, &err_rc);
875 if (rc != LUSTRE_CFG_RC_NO_ERR)
876 cYAML_print_tree2file(stderr, err_rc);
878 cYAML_free_tree(err_rc);
883 static int jt_set_large(int argc, char **argv)
887 struct cYAML *err_rc = NULL;
889 rc = check_cmd(set_cmds, "set", "large_buffers", 2, argc, argv);
893 rc = parse_long(argv[1], &value);
895 cYAML_build_error(-1, -1, "parser", "set",
896 "cannot parse large_buffers value", &err_rc);
897 cYAML_print_tree2file(stderr, err_rc);
898 cYAML_free_tree(err_rc);
902 rc = lustre_lnet_config_buffers(-1, -1, value, -1, &err_rc);
903 if (rc != LUSTRE_CFG_RC_NO_ERR)
904 cYAML_print_tree2file(stderr, err_rc);
906 cYAML_free_tree(err_rc);
911 static int jt_set_routing(int argc, char **argv)
914 struct cYAML *err_rc = NULL;
917 rc = check_cmd(set_cmds, "set", "routing", 2, argc, argv);
921 rc = parse_long(argv[1], &value);
922 if (rc != 0 || (value != 0 && value != 1)) {
923 cYAML_build_error(-1, -1, "parser", "set",
924 "cannot parse routing value.\n"
925 "must be 0 for disable or 1 for enable",
927 cYAML_print_tree2file(stderr, err_rc);
928 cYAML_free_tree(err_rc);
932 rc = lustre_lnet_enable_routing(value, -1, &err_rc);
934 if (rc != LUSTRE_CFG_RC_NO_ERR)
935 cYAML_print_tree2file(stderr, err_rc);
937 cYAML_free_tree(err_rc);
942 static int jt_set_max_recovery_ping_interval(int argc, char **argv)
946 struct cYAML *err_rc = NULL;
948 rc = check_cmd(set_cmds, "set", "maximum recovery_interval", 2, argc, argv);
952 rc = parse_long(argv[1], &value);
954 cYAML_build_error(-1, -1, "parser", "set",
955 "cannot parse maximum recovery interval value",
957 cYAML_print_tree2file(stderr, err_rc);
958 cYAML_free_tree(err_rc);
962 rc = lustre_lnet_config_max_recovery_ping_interval(value, -1, &err_rc);
963 if (rc != LUSTRE_CFG_RC_NO_ERR)
964 cYAML_print_tree2file(stderr, err_rc);
966 cYAML_free_tree(err_rc);
971 static void yaml_lnet_print_error(int op, char *cmd, const char *errstr)
973 char errcode[INT_STRING_LEN];
979 snprintf(errcode, sizeof(errcode), "%d", errno);
981 yaml_emitter_initialize(&log);
982 yaml_emitter_set_indent(&log, LNET_DEFAULT_INDENT);
983 yaml_emitter_set_output_file(&log, stderr);
985 yaml_emitter_open(&log);
986 yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
987 rc = yaml_emitter_emit(&log, &event);
991 yaml_mapping_start_event_initialize(&event, NULL,
992 (yaml_char_t *)YAML_MAP_TAG,
993 1, YAML_ANY_MAPPING_STYLE);
994 rc = yaml_emitter_emit(&log, &event);
998 if (strcmp(cmd, "lnet") == 0) {
1022 yaml_scalar_event_initialize(&event, NULL,
1023 (yaml_char_t *)YAML_STR_TAG,
1024 (yaml_char_t *)flag,
1026 YAML_PLAIN_SCALAR_STYLE);
1027 rc = yaml_emitter_emit(&log, &event);
1031 yaml_sequence_start_event_initialize(&event, NULL,
1032 (yaml_char_t *)YAML_SEQ_TAG,
1033 1, YAML_ANY_SEQUENCE_STYLE);
1034 rc = yaml_emitter_emit(&log, &event);
1038 yaml_mapping_start_event_initialize(&event, NULL,
1039 (yaml_char_t *)YAML_MAP_TAG,
1040 1, YAML_ANY_MAPPING_STYLE);
1041 rc = yaml_emitter_emit(&log, &event);
1045 yaml_scalar_event_initialize(&event, NULL,
1046 (yaml_char_t *)YAML_STR_TAG,
1049 1, 0, YAML_PLAIN_SCALAR_STYLE);
1050 rc = yaml_emitter_emit(&log, &event);
1054 yaml_scalar_event_initialize(&event, NULL,
1055 (yaml_char_t *)YAML_STR_TAG,
1058 1, 0, YAML_PLAIN_SCALAR_STYLE);
1059 rc = yaml_emitter_emit(&log, &event);
1063 yaml_scalar_event_initialize(&event, NULL,
1064 (yaml_char_t *)YAML_STR_TAG,
1065 (yaml_char_t *)"errno",
1066 strlen("errno"), 1, 0,
1067 YAML_PLAIN_SCALAR_STYLE);
1068 rc = yaml_emitter_emit(&log, &event);
1072 yaml_scalar_event_initialize(&event, NULL,
1073 (yaml_char_t *)YAML_INT_TAG,
1074 (yaml_char_t *)errcode,
1075 strlen(errcode), 1, 0,
1076 YAML_PLAIN_SCALAR_STYLE);
1077 rc = yaml_emitter_emit(&log, &event);
1082 yaml_scalar_event_initialize(&event, NULL,
1083 (yaml_char_t *)YAML_STR_TAG,
1084 (yaml_char_t *)"descr",
1085 strlen("descr"), 1, 0,
1086 YAML_PLAIN_SCALAR_STYLE);
1087 rc = yaml_emitter_emit(&log, &event);
1091 yaml_scalar_event_initialize(&event, NULL,
1092 (yaml_char_t *)YAML_STR_TAG,
1093 (yaml_char_t *)errstr,
1094 strlen(errstr), 1, 0,
1095 YAML_DOUBLE_QUOTED_SCALAR_STYLE);
1096 rc = yaml_emitter_emit(&log, &event);
1100 yaml_mapping_end_event_initialize(&event);
1101 rc = yaml_emitter_emit(&log, &event);
1105 yaml_sequence_end_event_initialize(&event);
1106 rc = yaml_emitter_emit(&log, &event);
1110 yaml_mapping_end_event_initialize(&event);
1111 rc = yaml_emitter_emit(&log, &event);
1115 yaml_document_end_event_initialize(&event, 0);
1116 rc = yaml_emitter_emit(&log, &event);
1120 rc = yaml_emitter_close(&log);
1123 yaml_emitter_log_error(&log, stdout);
1124 yaml_emitter_delete(&log);
1127 static int yaml_lnet_cpt_of_nid_display(yaml_parser_t *reply)
1129 yaml_document_t results;
1130 yaml_emitter_t output;
1133 rc = yaml_parser_load(reply, &results);
1135 yaml_lnet_print_error(NLM_F_DUMP, "cpt-of-nid",
1136 yaml_parser_get_reader_error(reply));
1137 yaml_document_delete(&results);
1141 rc = yaml_emitter_initialize(&output);
1143 yaml_emitter_set_output_file(&output, stdout);
1145 rc = yaml_emitter_dump(&output, &results);
1148 yaml_document_delete(&results);
1150 yaml_emitter_log_error(&output, stderr);
1153 yaml_emitter_delete(&output);
1158 static int yaml_lnet_cpt_of_nid(int start, int end, char **nids)
1160 struct nl_sock *sk = NULL;
1161 yaml_emitter_t request;
1162 yaml_parser_t reply;
1166 /* Create Netlink emitter to send request to kernel */
1167 sk = nl_socket_alloc();
1171 /* Setup parser to receive Netlink packets */
1172 rc = yaml_parser_initialize(&reply);
1178 rc = yaml_parser_set_input_netlink(&reply, sk, false);
1182 /* Create Netlink emitter to send request to kernel */
1183 rc = yaml_emitter_initialize(&request);
1187 rc = yaml_emitter_set_output_netlink(&request, sk, LNET_GENL_NAME,
1189 LNET_CMD_CPT_OF_NID, NLM_F_DUMP);
1193 yaml_emitter_open(&request);
1194 yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
1195 rc = yaml_emitter_emit(&request, &event);
1199 yaml_mapping_start_event_initialize(&event, NULL,
1200 (yaml_char_t *)YAML_MAP_TAG,
1201 1, YAML_ANY_MAPPING_STYLE);
1202 rc = yaml_emitter_emit(&request, &event);
1206 yaml_scalar_event_initialize(&event, NULL,
1207 (yaml_char_t *)YAML_STR_TAG,
1208 (yaml_char_t *)"cpt-of-nid",
1209 strlen("cpt-of-nid"), 1, 0,
1210 YAML_PLAIN_SCALAR_STYLE);
1211 rc = yaml_emitter_emit(&request, &event);
1215 yaml_mapping_start_event_initialize(&event, NULL,
1216 (yaml_char_t *)YAML_MAP_TAG,
1217 1, YAML_ANY_MAPPING_STYLE);
1218 rc = yaml_emitter_emit(&request, &event);
1222 yaml_scalar_event_initialize(&event, NULL,
1223 (yaml_char_t *)YAML_STR_TAG,
1224 (yaml_char_t *)"nids",
1225 strlen("nids"), 1, 0,
1226 YAML_PLAIN_SCALAR_STYLE);
1227 rc = yaml_emitter_emit(&request, &event);
1231 yaml_sequence_start_event_initialize(&event, NULL,
1232 (yaml_char_t *)YAML_SEQ_TAG,
1233 1, YAML_FLOW_SEQUENCE_STYLE);
1234 rc = yaml_emitter_emit(&request, &event);
1238 for (i = start; i < end; i++) {
1239 yaml_scalar_event_initialize(&event, NULL,
1240 (yaml_char_t *)YAML_STR_TAG,
1241 (yaml_char_t *)nids[i],
1242 strlen(nids[i]), 1, 0,
1243 YAML_PLAIN_SCALAR_STYLE);
1244 rc = yaml_emitter_emit(&request, &event);
1249 yaml_sequence_end_event_initialize(&event);
1250 rc = yaml_emitter_emit(&request, &event);
1254 yaml_mapping_end_event_initialize(&event);
1255 rc = yaml_emitter_emit(&request, &event);
1259 yaml_mapping_end_event_initialize(&event);
1260 rc = yaml_emitter_emit(&request, &event);
1264 yaml_document_end_event_initialize(&event, 0);
1265 rc = yaml_emitter_emit(&request, &event);
1269 rc = yaml_emitter_close(&request);
1272 yaml_emitter_log_error(&request, stderr);
1275 rc = yaml_lnet_cpt_of_nid_display(&reply);
1277 yaml_emitter_delete(&request);
1280 yaml_lnet_print_error(NLM_F_DUMP, "cpt-of-nid",
1281 yaml_parser_get_reader_error(&reply));
1285 yaml_parser_delete(&reply);
1288 return rc == 1 ? 0 : rc;
1291 static int jt_calc_cpt_of_nid(int argc, char **argv)
1294 const char *const short_options = "h";
1295 static const struct option long_options[] = {
1296 { .name = "help", .val = 'h' },
1299 rc = check_cmd(cmd_list, "", "cpt-of-nid", 2, argc, argv);
1303 while ((opt = getopt_long(argc, argv, short_options,
1304 long_options, NULL)) != -1) {
1308 print_help(cmd_list, "", "cpt-of-nid");
1314 rc = yaml_lnet_cpt_of_nid(optind, argc, argv);
1315 if (rc == -EOPNOTSUPP)
1316 printf("Operation not supported\n");
1321 static int jt_config_lnet(int argc, char **argv)
1323 struct cYAML *err_rc = NULL;
1324 bool load_mod_params = false;
1325 int flags = NLM_F_CREATE;
1326 const char *msg = NULL;
1328 const char *const short_options = "al";
1329 static const struct option long_options[] = {
1330 { .name = "all", .has_arg = no_argument, .val = 'a' },
1331 { .name = "large", .has_arg = no_argument, .val = 'l' },
1335 rc = check_cmd(lnet_cmds, "lnet", "configure", 0, argc, argv);
1339 while ((opt = getopt_long(argc, argv, short_options,
1340 long_options, NULL)) != -1) {
1343 load_mod_params = true;
1346 flags |= NLM_F_APPEND;
1353 if (!load_mod_params)
1354 flags |= NLM_F_EXCL;
1356 rc = yaml_lnet_configure(flags, &msg);
1357 if (rc != -EOPNOTSUPP) {
1361 snprintf(errstr, sizeof(errstr),
1362 "LNet configure error: %s", msg);
1363 yaml_lnet_print_error(flags, "lnet", errstr);
1368 rc = lustre_lnet_config_ni_system(LNET_CONFIGURE, load_mod_params,
1371 if (rc != LUSTRE_CFG_RC_NO_ERR)
1372 cYAML_print_tree2file(stderr, err_rc);
1374 cYAML_free_tree(err_rc);
1379 static int jt_unconfig_lnet(int argc, char **argv)
1381 struct cYAML *err_rc = NULL;
1382 const char *msg = NULL;
1385 rc = check_cmd(lnet_cmds, "lnet", "unconfigure", 0, argc, argv);
1389 rc = yaml_lnet_configure(0, &msg);
1390 if (rc != -EOPNOTSUPP) {
1394 snprintf(errstr, sizeof(errstr),
1395 "LNet configure error: %s", msg);
1396 yaml_lnet_print_error(0, "lnet", errstr);
1401 rc = lustre_lnet_config_ni_system(LNET_UNCONFIGURE, 0, -1, &err_rc);
1403 if (rc != LUSTRE_CFG_RC_NO_ERR)
1404 cYAML_print_tree2file(stderr, err_rc);
1406 cYAML_free_tree(err_rc);
1411 static int yaml_lnet_router_gateways(yaml_emitter_t *output, const char *nw,
1412 const char *gw, int hops, int prio,
1415 char num[INT_STRING_LEN];
1419 yaml_mapping_start_event_initialize(&event, NULL,
1420 (yaml_char_t *)YAML_MAP_TAG, 1,
1421 YAML_BLOCK_MAPPING_STYLE);
1422 rc = yaml_emitter_emit(output, &event);
1427 yaml_scalar_event_initialize(&event, NULL,
1428 (yaml_char_t *)YAML_STR_TAG,
1429 (yaml_char_t *)"net",
1430 strlen("net"), 1, 0,
1431 YAML_PLAIN_SCALAR_STYLE);
1432 rc = yaml_emitter_emit(output, &event);
1436 yaml_scalar_event_initialize(&event, NULL,
1437 (yaml_char_t *)YAML_STR_TAG,
1440 YAML_PLAIN_SCALAR_STYLE);
1441 rc = yaml_emitter_emit(output, &event);
1447 yaml_scalar_event_initialize(&event, NULL,
1448 (yaml_char_t *)YAML_STR_TAG,
1449 (yaml_char_t *)"gateway",
1450 strlen("gateway"), 1, 0,
1451 YAML_PLAIN_SCALAR_STYLE);
1452 rc = yaml_emitter_emit(output, &event);
1456 yaml_scalar_event_initialize(&event, NULL,
1457 (yaml_char_t *)YAML_STR_TAG,
1460 YAML_PLAIN_SCALAR_STYLE);
1461 rc = yaml_emitter_emit(output, &event);
1467 yaml_scalar_event_initialize(&event, NULL,
1468 (yaml_char_t *)YAML_STR_TAG,
1469 (yaml_char_t *)"hop",
1470 strlen("hop"), 1, 0,
1471 YAML_PLAIN_SCALAR_STYLE);
1472 rc = yaml_emitter_emit(output, &event);
1476 snprintf(num, sizeof(num), "%d", hops);
1477 yaml_scalar_event_initialize(&event, NULL,
1478 (yaml_char_t *)YAML_INT_TAG,
1481 YAML_PLAIN_SCALAR_STYLE);
1482 rc = yaml_emitter_emit(output, &event);
1488 yaml_scalar_event_initialize(&event, NULL,
1489 (yaml_char_t *)YAML_STR_TAG,
1490 (yaml_char_t *)"priority",
1491 strlen("priority"), 1, 0,
1492 YAML_PLAIN_SCALAR_STYLE);
1493 rc = yaml_emitter_emit(output, &event);
1497 snprintf(num, sizeof(num), "%d", prio);
1498 yaml_scalar_event_initialize(&event, NULL,
1499 (yaml_char_t *)YAML_INT_TAG,
1502 YAML_PLAIN_SCALAR_STYLE);
1503 rc = yaml_emitter_emit(output, &event);
1509 yaml_scalar_event_initialize(&event, NULL,
1510 (yaml_char_t *)YAML_STR_TAG,
1511 (yaml_char_t *)"health_sensitivity",
1512 strlen("health_sensitivity"),
1514 YAML_PLAIN_SCALAR_STYLE);
1515 rc = yaml_emitter_emit(output, &event);
1519 snprintf(num, sizeof(num), "%d", sen);
1520 yaml_scalar_event_initialize(&event, NULL,
1521 (yaml_char_t *)YAML_INT_TAG,
1524 YAML_PLAIN_SCALAR_STYLE);
1525 rc = yaml_emitter_emit(output, &event);
1530 yaml_mapping_end_event_initialize(&event);
1531 rc = yaml_emitter_emit(output, &event);
1536 static int yaml_lnet_route(char *nw, char *gw, int hops, int prio, int sen,
1537 int version, int flags, FILE *fp)
1539 struct nid_node head, *entry;
1540 struct nl_sock *sk = NULL;
1541 const char *msg = NULL;
1542 yaml_emitter_t output;
1543 yaml_parser_t reply;
1547 if (!(flags & NLM_F_DUMP) && (!nw || !gw)) {
1548 fprintf(stdout, "missing mandatory parameters:'%s'\n",
1549 (!nw && !gw) ? "net , gateway" :
1550 !nw ? "net" : "gateway");
1554 /* Create Netlink emitter to send request to kernel */
1555 sk = nl_socket_alloc();
1559 /* Setup parser to receive Netlink packets */
1560 rc = yaml_parser_initialize(&reply);
1566 rc = yaml_parser_set_input_netlink(&reply, sk, false);
1568 msg = yaml_parser_get_reader_error(&reply);
1572 /* Create Netlink emitter to send request to kernel */
1573 rc = yaml_emitter_initialize(&output);
1575 msg = "failed to initialize emitter";
1579 rc = yaml_emitter_set_output_netlink(&output, sk, LNET_GENL_NAME,
1580 version, LNET_CMD_ROUTES, flags);
1584 yaml_emitter_open(&output);
1585 yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
1586 rc = yaml_emitter_emit(&output, &event);
1590 yaml_mapping_start_event_initialize(&event, NULL,
1591 (yaml_char_t *)YAML_MAP_TAG,
1592 1, YAML_ANY_MAPPING_STYLE);
1593 rc = yaml_emitter_emit(&output, &event);
1597 yaml_scalar_event_initialize(&event, NULL,
1598 (yaml_char_t *)YAML_STR_TAG,
1599 (yaml_char_t *)"route",
1600 strlen("route"), 1, 0,
1601 YAML_PLAIN_SCALAR_STYLE);
1602 rc = yaml_emitter_emit(&output, &event);
1606 /* NLM_F_DUMP can have no arguments */
1608 NL_INIT_LIST_HEAD(&head.children);
1609 nl_init_list_head(&head.list);
1611 rc = lustre_lnet_parse_nid_range(&head, gw, &msg);
1613 lustre_lnet_free_list(&head);
1614 yaml_emitter_delete(&output);
1621 yaml_sequence_start_event_initialize(&event, NULL,
1622 (yaml_char_t *)YAML_SEQ_TAG,
1624 YAML_BLOCK_SEQUENCE_STYLE);
1625 rc = yaml_emitter_emit(&output, &event);
1629 if (!nl_list_empty(&head.children)) {
1630 nl_list_for_each_entry(entry, &head.children, list) {
1631 const char *nid = entry->nidstr;
1633 rc = yaml_lnet_router_gateways(&output, nw, nid,
1639 rc = yaml_lnet_router_gateways(&output, nw, NULL, hops,
1645 yaml_sequence_end_event_initialize(&event);
1646 rc = yaml_emitter_emit(&output, &event);
1650 yaml_scalar_event_initialize(&event, NULL,
1651 (yaml_char_t *)YAML_STR_TAG,
1654 YAML_PLAIN_SCALAR_STYLE);
1655 rc = yaml_emitter_emit(&output, &event);
1660 yaml_mapping_end_event_initialize(&event);
1661 rc = yaml_emitter_emit(&output, &event);
1665 yaml_document_end_event_initialize(&event, 0);
1666 rc = yaml_emitter_emit(&output, &event);
1670 rc = yaml_emitter_close(&output);
1673 yaml_emitter_log_error(&output, stderr);
1676 yaml_document_t errmsg;
1678 rc = yaml_parser_load(&reply, &errmsg);
1679 if (rc == 1 && (flags & NLM_F_DUMP)) {
1680 yaml_emitter_t debug;
1682 rc = yaml_emitter_initialize(&debug);
1684 yaml_emitter_set_indent(&debug,
1685 LNET_DEFAULT_INDENT);
1686 yaml_emitter_set_output_file(&debug, fp);
1687 rc = yaml_emitter_dump(&debug, &errmsg);
1689 yaml_emitter_delete(&debug);
1691 msg = yaml_parser_get_reader_error(&reply);
1692 /* If we didn't find any routes just be silent */
1693 if (msg && strcmp(msg, "No routes found") == 0)
1696 yaml_document_delete(&errmsg);
1698 yaml_emitter_delete(&output);
1701 yaml_lnet_print_error(flags, "route", msg);
1704 yaml_parser_delete(&reply);
1707 return rc == 1 ? 0 : rc;
1710 static int jt_add_route(int argc, char **argv)
1712 char *network = NULL, *gateway = NULL;
1713 long int hop = -1, prio = -1, sen = -1;
1714 struct cYAML *err_rc = NULL;
1717 const char *const short_options = "n:g:c:p:";
1718 static const struct option long_options[] = {
1719 { .name = "net", .has_arg = required_argument, .val = 'n' },
1720 { .name = "gateway", .has_arg = required_argument, .val = 'g' },
1721 { .name = "hop", .has_arg = required_argument, .val = 'c' },
1722 { .name = "hop-count", .has_arg = required_argument, .val = 'c' },
1723 { .name = "priority", .has_arg = required_argument, .val = 'p' },
1724 { .name = "health_sensitivity", .has_arg = required_argument, .val = 's' },
1728 rc = check_cmd(route_cmds, "route", "add", 0, argc, argv);
1732 while ((opt = getopt_long(argc, argv, short_options,
1733 long_options, NULL)) != -1) {
1742 rc = parse_long(optarg, &hop);
1750 rc = parse_long(optarg, &prio);
1758 rc = parse_long(optarg, &sen);
1767 print_help(route_cmds, "route", "add");
1773 rc = yaml_lnet_route(network, gateway, hop, prio, sen,
1774 LNET_GENL_VERSION, NLM_F_CREATE, stdout);
1776 if (rc == -EOPNOTSUPP)
1781 rc = lustre_lnet_config_route(network, gateway, hop, prio, sen, -1,
1784 if (rc != LUSTRE_CFG_RC_NO_ERR)
1785 cYAML_print_tree2file(stderr, err_rc);
1787 cYAML_free_tree(err_rc);
1792 static int yaml_add_ni_tunables(yaml_emitter_t *output,
1793 struct lnet_ioctl_config_lnd_tunables *tunables,
1794 struct lnet_dlc_network_descr *nw_descr)
1796 char num[INT_STRING_LEN];
1800 if (tunables->lt_cmn.lct_peer_timeout < 0 &&
1801 tunables->lt_cmn.lct_peer_tx_credits <= 0 &&
1802 tunables->lt_cmn.lct_peer_rtr_credits <= 0 &&
1803 tunables->lt_cmn.lct_max_tx_credits <= 0)
1804 goto skip_general_settings;
1806 yaml_scalar_event_initialize(&event, NULL,
1807 (yaml_char_t *)YAML_STR_TAG,
1808 (yaml_char_t *)"tunables",
1809 strlen("tunables"), 1, 0,
1810 YAML_PLAIN_SCALAR_STYLE);
1811 rc = yaml_emitter_emit(output, &event);
1815 yaml_mapping_start_event_initialize(&event, NULL,
1816 (yaml_char_t *)YAML_MAP_TAG,
1817 1, YAML_ANY_MAPPING_STYLE);
1818 rc = yaml_emitter_emit(output, &event);
1822 if (tunables->lt_cmn.lct_peer_timeout >= 0) {
1823 yaml_scalar_event_initialize(&event, NULL,
1824 (yaml_char_t *)YAML_STR_TAG,
1825 (yaml_char_t *)"peer_timeout",
1826 strlen("peer_timeout"), 1, 0,
1827 YAML_PLAIN_SCALAR_STYLE);
1828 rc = yaml_emitter_emit(output, &event);
1832 snprintf(num, sizeof(num), "%u",
1833 tunables->lt_cmn.lct_peer_timeout);
1834 yaml_scalar_event_initialize(&event, NULL,
1835 (yaml_char_t *)YAML_INT_TAG,
1838 YAML_PLAIN_SCALAR_STYLE);
1839 rc = yaml_emitter_emit(output, &event);
1844 if (tunables->lt_cmn.lct_peer_tx_credits > 0) {
1845 yaml_scalar_event_initialize(&event, NULL,
1846 (yaml_char_t *)YAML_STR_TAG,
1847 (yaml_char_t *)"peer_credits",
1848 strlen("peer_credits"), 1, 0,
1849 YAML_PLAIN_SCALAR_STYLE);
1850 rc = yaml_emitter_emit(output, &event);
1854 snprintf(num, sizeof(num), "%u",
1855 tunables->lt_cmn.lct_peer_tx_credits);
1856 yaml_scalar_event_initialize(&event, NULL,
1857 (yaml_char_t *)YAML_INT_TAG,
1860 YAML_PLAIN_SCALAR_STYLE);
1861 rc = yaml_emitter_emit(output, &event);
1866 if (tunables->lt_cmn.lct_peer_rtr_credits > 0) {
1867 yaml_scalar_event_initialize(&event, NULL,
1868 (yaml_char_t *)YAML_STR_TAG,
1869 (yaml_char_t *)"peer_buffer_credits",
1870 strlen("peer_buffer_credits"), 1, 0,
1871 YAML_PLAIN_SCALAR_STYLE);
1872 rc = yaml_emitter_emit(output, &event);
1876 snprintf(num, sizeof(num), "%u",
1877 tunables->lt_cmn.lct_peer_rtr_credits);
1878 yaml_scalar_event_initialize(&event, NULL,
1879 (yaml_char_t *)YAML_INT_TAG,
1882 YAML_PLAIN_SCALAR_STYLE);
1883 rc = yaml_emitter_emit(output, &event);
1888 if (tunables->lt_cmn.lct_max_tx_credits > 0) {
1889 yaml_scalar_event_initialize(&event, NULL,
1890 (yaml_char_t *)YAML_STR_TAG,
1891 (yaml_char_t *)"credits",
1892 strlen("credits"), 1, 0,
1893 YAML_PLAIN_SCALAR_STYLE);
1894 rc = yaml_emitter_emit(output, &event);
1898 snprintf(num, sizeof(num), "%u",
1899 tunables->lt_cmn.lct_max_tx_credits);
1900 yaml_scalar_event_initialize(&event, NULL,
1901 (yaml_char_t *)YAML_INT_TAG,
1904 YAML_PLAIN_SCALAR_STYLE);
1905 rc = yaml_emitter_emit(output, &event);
1910 yaml_mapping_end_event_initialize(&event);
1911 rc = yaml_emitter_emit(output, &event);
1915 skip_general_settings:
1916 if (tunables->lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer > 0 ||
1917 tunables->lt_tun.lnd_tun_u.lnd_sock.lnd_tos >= 0 ||
1919 tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_auth_key > 0 ||
1920 tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_traffic_class_str[0] ||
1922 tunables->lt_tun.lnd_tun_u.lnd_o2ib.lnd_conns_per_peer > 0 ||
1923 tunables->lt_tun.lnd_tun_u.lnd_o2ib.lnd_tos >= 0) {
1924 yaml_scalar_event_initialize(&event, NULL,
1925 (yaml_char_t *)YAML_STR_TAG,
1926 (yaml_char_t *)"lnd tunables",
1927 strlen("lnd tunables"), 1, 0,
1928 YAML_PLAIN_SCALAR_STYLE);
1929 rc = yaml_emitter_emit(output, &event);
1933 yaml_mapping_start_event_initialize(&event, NULL,
1934 (yaml_char_t *)YAML_MAP_TAG,
1935 1, YAML_ANY_MAPPING_STYLE);
1936 rc = yaml_emitter_emit(output, &event);
1940 if (tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_auth_key > 0) {
1941 yaml_scalar_event_initialize(&event, NULL,
1942 (yaml_char_t *)YAML_STR_TAG,
1943 (yaml_char_t *)"auth_key",
1944 strlen("auth_key"), 1, 0,
1945 YAML_PLAIN_SCALAR_STYLE);
1946 rc = yaml_emitter_emit(output, &event);
1950 snprintf(num, sizeof(num), "%u",
1951 tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_auth_key);
1953 yaml_scalar_event_initialize(&event, NULL,
1954 (yaml_char_t *)YAML_INT_TAG,
1957 YAML_PLAIN_SCALAR_STYLE);
1958 rc = yaml_emitter_emit(output, &event);
1963 if (tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_traffic_class_str[0]) {
1964 char *tc = &tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_traffic_class_str[0];
1966 yaml_scalar_event_initialize(&event, NULL,
1967 (yaml_char_t *)YAML_STR_TAG,
1968 (yaml_char_t *)"traffic_class",
1969 strlen("traffic_class"), 1, 0,
1970 YAML_PLAIN_SCALAR_STYLE);
1971 rc = yaml_emitter_emit(output, &event);
1975 yaml_scalar_event_initialize(&event, NULL,
1976 (yaml_char_t *)YAML_INT_TAG,
1979 YAML_PLAIN_SCALAR_STYLE);
1981 rc = yaml_emitter_emit(output, &event);
1986 if (tunables->lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer > 0 ||
1987 tunables->lt_tun.lnd_tun_u.lnd_o2ib.lnd_conns_per_peer > 0) {
1990 yaml_scalar_event_initialize(&event, NULL,
1991 (yaml_char_t *)YAML_STR_TAG,
1992 (yaml_char_t *)"conns_per_peer",
1993 strlen("conns_per_peer"), 1, 0,
1994 YAML_PLAIN_SCALAR_STYLE);
1995 rc = yaml_emitter_emit(output, &event);
1999 if (nw_descr->nw_id == LNET_NET_ANY)
2000 cpp = tunables->lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer;
2001 else if (LNET_NETTYP(nw_descr->nw_id) == SOCKLND)
2002 cpp = tunables->lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer;
2003 else if (LNET_NETTYP(nw_descr->nw_id) == O2IBLND)
2004 cpp = tunables->lt_tun.lnd_tun_u.lnd_o2ib.lnd_conns_per_peer;
2005 snprintf(num, sizeof(num), "%u", cpp);
2007 yaml_scalar_event_initialize(&event, NULL,
2008 (yaml_char_t *)YAML_INT_TAG,
2011 YAML_PLAIN_SCALAR_STYLE);
2012 rc = yaml_emitter_emit(output, &event);
2017 if (tunables->lt_tun.lnd_tun_u.lnd_sock.lnd_tos >= 0 ||
2018 tunables->lt_tun.lnd_tun_u.lnd_o2ib.lnd_tos >= 0) {
2021 yaml_scalar_event_initialize(&event, NULL,
2022 (yaml_char_t *)YAML_STR_TAG,
2023 (yaml_char_t *)"tos",
2024 strlen("tos"), 1, 0,
2025 YAML_PLAIN_SCALAR_STYLE);
2026 rc = yaml_emitter_emit(output, &event);
2030 if (LNET_NETTYP(nw_descr->nw_id) == SOCKLND)
2031 tos = tunables->lt_tun.lnd_tun_u.lnd_sock.lnd_tos;
2032 else if (LNET_NETTYP(nw_descr->nw_id) == O2IBLND)
2033 tos = tunables->lt_tun.lnd_tun_u.lnd_o2ib.lnd_tos;
2034 snprintf(num, sizeof(num), "%u", tos);
2036 yaml_scalar_event_initialize(&event, NULL,
2037 (yaml_char_t *)YAML_INT_TAG,
2040 YAML_PLAIN_SCALAR_STYLE);
2041 rc = yaml_emitter_emit(output, &event);
2046 yaml_mapping_end_event_initialize(&event);
2047 rc = yaml_emitter_emit(output, &event);
2053 static int yaml_lnet_config_ni(char *net_id, char *ip2net,
2054 struct lnet_dlc_network_descr *nw_descr,
2055 struct lnet_ioctl_config_lnd_tunables *tunables,
2056 int healthv, struct cfs_expr_list *global_cpts,
2057 int version, int flags, FILE *fp)
2059 struct lnet_dlc_intf_descr *intf;
2060 struct nl_sock *sk = NULL;
2061 const char *msg = NULL;
2062 yaml_emitter_t output;
2063 yaml_parser_t reply;
2067 if (!(flags & NLM_F_DUMP) && !ip2net && (!nw_descr || nw_descr->nw_id == 0)) {
2068 fprintf(stdout, "missing mandatory parameters in NI config: '%s'\n",
2069 (!nw_descr) ? "network , interface" :
2070 (nw_descr->nw_id == 0) ? "network" : "interface");
2074 if ((flags == NLM_F_CREATE) && !ip2net && list_empty(&nw_descr->nw_intflist)) {
2075 fprintf(stdout, "creating a local NI needs at least one interface\n");
2079 if ((flags == NLM_F_REPLACE) && list_empty(&nw_descr->nw_intflist)) {
2080 fprintf(stdout, "updating a local NI needs at least one address\n");
2084 /* Create Netlink emitter to send request to kernel */
2085 sk = nl_socket_alloc();
2089 /* Setup parser to receive Netlink packets */
2090 rc = yaml_parser_initialize(&reply);
2096 rc = yaml_parser_set_input_netlink(&reply, sk, false);
2098 msg = yaml_parser_get_reader_error(&reply);
2102 /* Create Netlink emitter to send request to kernel */
2103 rc = yaml_emitter_initialize(&output);
2105 msg = "failed to initialize emitter";
2109 rc = yaml_emitter_set_output_netlink(&output, sk, LNET_GENL_NAME,
2110 version, LNET_CMD_NETS, flags);
2114 yaml_emitter_open(&output);
2115 yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
2116 rc = yaml_emitter_emit(&output, &event);
2120 yaml_mapping_start_event_initialize(&event, NULL,
2121 (yaml_char_t *)YAML_MAP_TAG,
2122 1, YAML_ANY_MAPPING_STYLE);
2123 rc = yaml_emitter_emit(&output, &event);
2127 yaml_scalar_event_initialize(&event, NULL,
2128 (yaml_char_t *)YAML_STR_TAG,
2129 (yaml_char_t *)"net",
2130 strlen("net"), 1, 0,
2131 YAML_PLAIN_SCALAR_STYLE);
2132 rc = yaml_emitter_emit(&output, &event);
2136 if (net_id || ip2net) {
2137 char *key = net_id ? "net type" : "ip2net";
2138 char *value = net_id ? net_id : ip2net;
2140 yaml_sequence_start_event_initialize(&event, NULL,
2141 (yaml_char_t *)YAML_SEQ_TAG,
2142 1, YAML_ANY_SEQUENCE_STYLE);
2143 rc = yaml_emitter_emit(&output, &event);
2147 yaml_mapping_start_event_initialize(&event, NULL,
2148 (yaml_char_t *)YAML_MAP_TAG,
2149 1, YAML_ANY_MAPPING_STYLE);
2150 rc = yaml_emitter_emit(&output, &event);
2154 yaml_scalar_event_initialize(&event, NULL,
2155 (yaml_char_t *)YAML_STR_TAG,
2158 1, 0, YAML_PLAIN_SCALAR_STYLE);
2159 rc = yaml_emitter_emit(&output, &event);
2163 yaml_scalar_event_initialize(&event, NULL,
2164 (yaml_char_t *)YAML_STR_TAG,
2165 (yaml_char_t *)value,
2166 strlen(value), 1, 0,
2167 YAML_PLAIN_SCALAR_STYLE);
2168 rc = yaml_emitter_emit(&output, &event);
2172 yaml_scalar_event_initialize(&event, NULL,
2173 (yaml_char_t *)YAML_STR_TAG,
2176 YAML_PLAIN_SCALAR_STYLE);
2177 rc = yaml_emitter_emit(&output, &event);
2184 if (!nw_descr || list_empty(&nw_descr->nw_intflist))
2187 yaml_scalar_event_initialize(&event, NULL,
2188 (yaml_char_t *)YAML_STR_TAG,
2189 (yaml_char_t *)"local NI(s)",
2190 strlen("local NI(s)"), 1, 0,
2191 YAML_PLAIN_SCALAR_STYLE);
2192 rc = yaml_emitter_emit(&output, &event);
2196 yaml_sequence_start_event_initialize(&event, NULL,
2197 (yaml_char_t *)YAML_SEQ_TAG,
2198 1, YAML_ANY_SEQUENCE_STYLE);
2199 rc = yaml_emitter_emit(&output, &event);
2203 list_for_each_entry(intf, &nw_descr->nw_intflist,
2205 yaml_mapping_start_event_initialize(&event, NULL,
2206 (yaml_char_t *)YAML_MAP_TAG,
2207 1, YAML_ANY_MAPPING_STYLE);
2208 rc = yaml_emitter_emit(&output, &event);
2212 /* Use NI addresses instead of interface */
2213 if (strchr(intf->intf_name, '@') ||
2214 (strcmp(intf->intf_name, "<?>") == 0 &&
2215 - flags == NLM_F_REPLACE)) {
2216 yaml_scalar_event_initialize(&event, NULL,
2217 (yaml_char_t *)YAML_STR_TAG,
2218 (yaml_char_t *)"nid",
2219 strlen("nid"), 1, 0,
2220 YAML_PLAIN_SCALAR_STYLE);
2221 rc = yaml_emitter_emit(&output, &event);
2225 yaml_scalar_event_initialize(&event, NULL,
2226 (yaml_char_t *)YAML_STR_TAG,
2227 (yaml_char_t *)intf->intf_name,
2228 strlen(intf->intf_name), 1, 0,
2229 YAML_PLAIN_SCALAR_STYLE);
2230 rc = yaml_emitter_emit(&output, &event);
2234 yaml_scalar_event_initialize(&event, NULL,
2235 (yaml_char_t *)YAML_STR_TAG,
2236 (yaml_char_t *)"interfaces",
2237 strlen("interfaces"), 1, 0,
2238 YAML_PLAIN_SCALAR_STYLE);
2239 rc = yaml_emitter_emit(&output, &event);
2243 yaml_mapping_start_event_initialize(&event, NULL,
2244 (yaml_char_t *)YAML_MAP_TAG,
2245 1, YAML_ANY_MAPPING_STYLE);
2246 rc = yaml_emitter_emit(&output, &event);
2250 yaml_scalar_event_initialize(&event, NULL,
2251 (yaml_char_t *)YAML_STR_TAG,
2254 YAML_PLAIN_SCALAR_STYLE);
2255 rc = yaml_emitter_emit(&output, &event);
2259 yaml_scalar_event_initialize(&event, NULL,
2260 (yaml_char_t *)YAML_STR_TAG,
2261 (yaml_char_t *)intf->intf_name,
2262 strlen(intf->intf_name), 1, 0,
2263 YAML_PLAIN_SCALAR_STYLE);
2264 rc = yaml_emitter_emit(&output, &event);
2268 yaml_mapping_end_event_initialize(&event);
2269 rc = yaml_emitter_emit(&output, &event);
2275 rc = yaml_add_ni_tunables(&output, tunables, nw_descr);
2280 if (flags == NLM_F_REPLACE && healthv > -1) {
2281 char health[INT_STRING_LEN];
2283 yaml_scalar_event_initialize(&event, NULL,
2284 (yaml_char_t *)YAML_STR_TAG,
2285 (yaml_char_t *)"health stats",
2286 strlen("health stats"), 1, 0,
2287 YAML_PLAIN_SCALAR_STYLE);
2288 rc = yaml_emitter_emit(&output, &event);
2292 /* Setup all mappings for data related to the 'health stats' */
2293 yaml_mapping_start_event_initialize(&event, NULL,
2294 (yaml_char_t *)YAML_MAP_TAG,
2295 1, YAML_BLOCK_MAPPING_STYLE);
2296 rc = yaml_emitter_emit(&output, &event);
2300 yaml_scalar_event_initialize(&event, NULL,
2301 (yaml_char_t *)YAML_STR_TAG,
2302 (yaml_char_t *)"health value",
2303 strlen("health value"), 1, 0,
2304 YAML_PLAIN_SCALAR_STYLE);
2305 rc = yaml_emitter_emit(&output, &event);
2309 snprintf(health, sizeof(health), "%d", healthv);
2310 yaml_scalar_event_initialize(&event, NULL,
2311 (yaml_char_t *)YAML_INT_TAG,
2312 (yaml_char_t *)health,
2313 strlen(health), 1, 0,
2314 YAML_PLAIN_SCALAR_STYLE);
2315 rc = yaml_emitter_emit(&output, &event);
2319 yaml_mapping_end_event_initialize(&event);
2320 rc = yaml_emitter_emit(&output, &event);
2329 yaml_scalar_event_initialize(&event, NULL,
2330 (yaml_char_t *)YAML_STR_TAG,
2331 (yaml_char_t *)"CPT",
2332 strlen("CPT"), 1, 0,
2333 YAML_PLAIN_SCALAR_STYLE);
2334 rc = yaml_emitter_emit(&output, &event);
2338 yaml_sequence_start_event_initialize(&event, NULL,
2339 (yaml_char_t *)YAML_SEQ_TAG,
2341 YAML_FLOW_SEQUENCE_STYLE);
2342 rc = yaml_emitter_emit(&output, &event);
2346 count = cfs_expr_list_values(global_cpts,
2347 LNET_MAX_SHOW_NUM_CPT,
2349 for (i = 0; i < count; i++) {
2350 char core[INT_STRING_LEN];
2352 snprintf(core, sizeof(core), "%u", cpt_array[i]);
2353 yaml_scalar_event_initialize(&event, NULL,
2354 (yaml_char_t *)YAML_STR_TAG,
2355 (yaml_char_t *)core,
2357 YAML_PLAIN_SCALAR_STYLE);
2358 rc = yaml_emitter_emit(&output, &event);
2363 yaml_sequence_end_event_initialize(&event);
2364 rc = yaml_emitter_emit(&output, &event);
2368 cfs_expr_list_free(global_cpts);
2372 yaml_mapping_end_event_initialize(&event);
2373 rc = yaml_emitter_emit(&output, &event);
2378 yaml_sequence_end_event_initialize(&event);
2379 rc = yaml_emitter_emit(&output, &event);
2383 yaml_mapping_end_event_initialize(&event);
2384 rc = yaml_emitter_emit(&output, &event);
2388 yaml_sequence_end_event_initialize(&event);
2389 rc = yaml_emitter_emit(&output, &event);
2393 yaml_mapping_end_event_initialize(&event);
2394 rc = yaml_emitter_emit(&output, &event);
2398 yaml_document_end_event_initialize(&event, 0);
2399 rc = yaml_emitter_emit(&output, &event);
2403 rc = yaml_emitter_close(&output);
2406 yaml_emitter_log_error(&output, stderr);
2409 yaml_document_t errmsg;
2411 rc = yaml_parser_load(&reply, &errmsg);
2412 if (rc == 1 && (flags & NLM_F_DUMP)) {
2413 yaml_emitter_t debug;
2415 rc = yaml_emitter_initialize(&debug);
2417 yaml_emitter_set_indent(&debug,
2418 LNET_DEFAULT_INDENT);
2419 yaml_emitter_set_output_file(&debug, fp);
2420 rc = yaml_emitter_dump(&debug, &errmsg);
2422 yaml_emitter_delete(&debug);
2424 msg = yaml_parser_get_reader_error(&reply);
2426 yaml_document_delete(&errmsg);
2428 yaml_emitter_delete(&output);
2431 yaml_lnet_print_error(flags, "net", msg);
2434 yaml_parser_delete(&reply);
2437 return rc == 1 ? 0 : rc;
2440 static int jt_add_ni(int argc, char **argv)
2442 char *ip2net = NULL;
2443 long int pto = -1, pc = -1, pbc = -1, cre = -1, cpp = -1, auth_key = -1;
2444 char *traffic_class = NULL;
2446 struct cYAML *err_rc = NULL;
2447 int rc, opt, cpt_rc = -1;
2448 struct lnet_dlc_network_descr nw_descr;
2449 struct cfs_expr_list *global_cpts = NULL;
2450 struct lnet_ioctl_config_lnd_tunables tunables;
2452 bool skip_mr_route_setup = false;
2453 const char *const short_options = "a:b:c:i:k:m:n:p:r:s:t:T:";
2454 static const struct option long_options[] = {
2455 { .name = "auth-key", .has_arg = required_argument, .val = 'a' },
2456 { .name = "peer-buffer-credits",
2457 .has_arg = required_argument, .val = 'b' },
2458 { .name = "peer-credits", .has_arg = required_argument, .val = 'c' },
2459 { .name = "if", .has_arg = required_argument, .val = 'i' },
2460 { .name = "skip-mr-route-setup",
2461 .has_arg = no_argument, .val = 'k' },
2462 { .name = "conns-per-peer",
2463 .has_arg = required_argument, .val = 'm' },
2464 { .name = "net", .has_arg = required_argument, .val = 'n' },
2465 { .name = "nid", .has_arg = required_argument, .val = 'N' },
2466 { .name = "ip2net", .has_arg = required_argument, .val = 'p' },
2467 { .name = "credits", .has_arg = required_argument, .val = 'r' },
2468 { .name = "cpt", .has_arg = required_argument, .val = 's' },
2469 { .name = "peer-timeout", .has_arg = required_argument, .val = 't' },
2470 { .name = "traffic-class", .has_arg = required_argument, .val = 'T' },
2471 { .name = "tos", .has_arg = required_argument, .val = 'S' },
2473 bool nid_request = false;
2474 char *net_id = NULL;
2476 memset(&tunables, 0, sizeof(tunables));
2477 lustre_lnet_init_nw_descr(&nw_descr);
2479 rc = check_cmd(net_cmds, "net", "add", 0, argc, argv);
2483 while ((opt = getopt_long(argc, argv, short_options,
2484 long_options, NULL)) != -1) {
2487 rc = parse_long(optarg, &auth_key);
2495 rc = parse_long(optarg, &pbc);
2503 rc = parse_long(optarg, &pc);
2511 rc = lustre_lnet_parse_interfaces(optarg, &nw_descr);
2513 cYAML_build_error(-1, -1, "ni", "add",
2514 "bad interface list",
2520 skip_mr_route_setup = true;
2523 rc = parse_long(optarg, &cpp);
2532 nw_descr.nw_id = libcfs_str2net(optarg);
2536 rc = lustre_lnet_parse_interfaces(optarg, &nw_descr);
2538 cYAML_build_error(-1, -1, "ni", "add",
2549 rc = parse_long(optarg, &cre);
2557 cpt_rc = cfs_expr_list_parse(optarg,
2559 UINT_MAX, &global_cpts);
2562 rc = parse_long(optarg, &pto);
2570 traffic_class = optarg;
2571 if (strlen(traffic_class) == 0 ||
2572 strlen(traffic_class) >= LNET_MAX_STR_LEN) {
2573 cYAML_build_error(-1, -1, "ni", "add",
2574 "Invalid traffic-class argument",
2576 rc = LUSTRE_CFG_RC_BAD_PARAM;
2581 rc = parse_long(optarg, &tos);
2582 if (rc || tos < -1 || tos > 0xff) {
2583 cYAML_build_error(-1, -1, "ni", "add",
2584 "Invalid ToS argument",
2586 rc = LUSTRE_CFG_RC_BAD_PARAM;
2591 print_help(net_cmds, "net", "add");
2599 fprintf(stdout, "--net is invalid with --nid option\n");
2602 net_id = libcfs_net2str(nw_descr.nw_id);
2605 if (auth_key > 0 && LNET_NETTYP(nw_descr.nw_id) == KFILND) {
2606 tunables.lt_tun.lnd_tun_u.lnd_kfi.lnd_auth_key = auth_key;
2610 if (traffic_class && LNET_NETTYP(nw_descr.nw_id) == KFILND &&
2611 strlen(traffic_class) < LNET_MAX_STR_LEN) {
2612 strcpy(&tunables.lt_tun.lnd_tun_u.lnd_kfi.lnd_traffic_class_str[0],
2618 if (LNET_NETTYP(nw_descr.nw_id) == SOCKLND) {
2619 tunables.lt_tun.lnd_tun_u.lnd_sock.lnd_tos = tos;
2621 } else if (LNET_NETTYP(nw_descr.nw_id) == O2IBLND) {
2622 tunables.lt_tun.lnd_tun_u.lnd_o2ib.lnd_tos = tos;
2626 if (LNET_NETTYP(nw_descr.nw_id) == SOCKLND && (cpp > -1)) {
2627 tunables.lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer = cpp;
2629 } else if (LNET_NETTYP(nw_descr.nw_id) == O2IBLND && (cpp > -1)) {
2630 tunables.lt_tun.lnd_tun_u.lnd_o2ib.lnd_conns_per_peer = cpp;
2634 tunables.lt_cmn.lct_peer_timeout = pto;
2635 tunables.lt_cmn.lct_peer_tx_credits = pc;
2636 tunables.lt_cmn.lct_peer_rtr_credits = pbc;
2637 tunables.lt_cmn.lct_max_tx_credits = cre;
2638 if (pto >= 0 || pc > 0 || pbc > 0 || cre > 0)
2641 if (found && LNET_NETTYP(nw_descr.nw_id) == O2IBLND)
2642 tunables.lt_tun.lnd_tun_u.lnd_o2ib.lnd_map_on_demand = UINT_MAX;
2644 rc = yaml_lnet_config_ni(net_id, ip2net, &nw_descr,
2645 found ? &tunables : NULL, -1,
2646 (cpt_rc == 0) ? global_cpts : NULL,
2647 LNET_GENL_VERSION, NLM_F_CREATE, stdout);
2649 if (rc == -EOPNOTSUPP)
2651 if (global_cpts != NULL)
2652 cfs_expr_list_free(global_cpts);
2653 if (rc == 0 && !skip_mr_route_setup)
2654 rc = lustre_lnet_setup_mrrouting(&err_rc);
2658 rc = lustre_lnet_config_ni(&nw_descr,
2659 (cpt_rc == 0) ? global_cpts: NULL,
2660 ip2net, (found) ? &tunables : NULL,
2663 if (global_cpts != NULL)
2664 cfs_expr_list_free(global_cpts);
2667 if (rc != LUSTRE_CFG_RC_NO_ERR)
2668 cYAML_print_tree2file(stderr, err_rc);
2670 cYAML_free_tree(err_rc);
2672 if (rc == LUSTRE_CFG_RC_NO_ERR && !skip_mr_route_setup) {
2674 rc = lustre_lnet_setup_mrrouting(&err_rc);
2676 if (rc != LUSTRE_CFG_RC_NO_ERR)
2677 cYAML_print_tree2file(stderr, err_rc);
2679 cYAML_free_tree(err_rc);
2685 static int jt_del_route(int argc, char **argv)
2687 char *network = NULL, *gateway = NULL;
2688 struct cYAML *err_rc = NULL;
2690 const char *const short_options = "n:g:";
2691 static const struct option long_options[] = {
2692 { .name = "net", .has_arg = required_argument, .val = 'n' },
2693 { .name = "gateway", .has_arg = required_argument, .val = 'g' },
2697 rc = check_cmd(route_cmds, "route", "del", 0, argc, argv);
2701 while ((opt = getopt_long(argc, argv, short_options,
2702 long_options, NULL)) != -1) {
2711 print_help(route_cmds, "route", "del");
2717 rc = yaml_lnet_route(network, gateway, -1, -1, -1, LNET_GENL_VERSION,
2720 if (rc == -EOPNOTSUPP)
2725 rc = lustre_lnet_del_route(network, gateway, -1, &err_rc);
2727 if (rc != LUSTRE_CFG_RC_NO_ERR)
2728 cYAML_print_tree2file(stderr, err_rc);
2730 cYAML_free_tree(err_rc);
2735 static int jt_del_ni(int argc, char **argv)
2737 struct cYAML *err_rc = NULL;
2739 struct lnet_dlc_network_descr nw_descr;
2740 const char *const short_options = "n:i:";
2741 static const struct option long_options[] = {
2742 { .name = "net", .has_arg = required_argument, .val = 'n' },
2743 { .name = "if", .has_arg = required_argument, .val = 'i' },
2744 { .name = "nid", .has_arg = required_argument, .val = 'N' },
2746 bool nid_request = false;
2747 char *net_id = NULL;
2749 rc = check_cmd(net_cmds, "net", "del", 0, argc, argv);
2753 lustre_lnet_init_nw_descr(&nw_descr);
2755 while ((opt = getopt_long(argc, argv, short_options,
2756 long_options, NULL)) != -1) {
2759 nw_descr.nw_id = libcfs_str2net(optarg);
2763 rc = lustre_lnet_parse_interfaces(optarg, &nw_descr);
2765 cYAML_build_error(-1, -1, "ni", "del",
2773 rc = lustre_lnet_parse_interfaces(optarg, &nw_descr);
2775 cYAML_build_error(-1, -1, "ni", "add",
2776 "bad interface list",
2782 print_help(net_cmds, "net", "del");
2790 fprintf(stdout, "--net is invalid with --nid option\n");
2793 net_id = libcfs_net2str(nw_descr.nw_id);
2796 rc = yaml_lnet_config_ni(net_id, NULL, &nw_descr, NULL, -1, NULL,
2797 LNET_GENL_VERSION, 0, stdout);
2799 if (rc != -EOPNOTSUPP)
2803 rc = lustre_lnet_del_ni(&nw_descr, -1, &err_rc);
2805 if (rc != LUSTRE_CFG_RC_NO_ERR)
2806 cYAML_print_tree2file(stderr, err_rc);
2808 cYAML_free_tree(err_rc);
2813 static int jt_show_route(int argc, char **argv)
2815 char *network = NULL, *gateway = NULL;
2816 long int hop = -1, prio = -1;
2817 int detail = 0, rc, opt;
2818 struct cYAML *err_rc = NULL, *show_rc = NULL;
2819 const char *const short_options = "c:n:g:p:v";
2820 static const struct option long_options[] = {
2821 { .name = "net", .has_arg = required_argument, .val = 'n' },
2822 { .name = "gateway", .has_arg = required_argument, .val = 'g' },
2823 { .name = "hop-count", .has_arg = required_argument, .val = 'c' },
2824 { .name = "hop", .has_arg = required_argument, .val = 'c' },
2825 { .name = "priority", .has_arg = required_argument, .val = 'p' },
2826 { .name = "verbose", .has_arg = no_argument, .val = 'v' },
2830 rc = check_cmd(route_cmds, "route", "show", 0, argc, argv);
2834 while ((opt = getopt_long(argc, argv, short_options,
2835 long_options, NULL)) != -1) {
2844 rc = parse_long(optarg, &hop);
2852 rc = parse_long(optarg, &prio);
2863 print_help(route_cmds, "route", "show");
2869 rc = yaml_lnet_route(network, gateway, hop, prio, -1,
2870 detail, NLM_F_DUMP, stdout);
2872 if (rc == -EOPNOTSUPP)
2877 rc = lustre_lnet_show_route(network, gateway, hop, prio,
2879 &show_rc, &err_rc, false);
2881 if (rc != LUSTRE_CFG_RC_NO_ERR)
2882 cYAML_print_tree2file(stderr, err_rc);
2884 cYAML_print_tree(show_rc);
2886 cYAML_free_tree(err_rc);
2887 cYAML_free_tree(show_rc);
2892 static int yaml_lnet_config_ni_value(int healthv, bool all, char *nidstr,
2893 int cpp, int lnd_timeout, __u32 net,
2894 int seq_no, struct cYAML **err_rc)
2896 struct lnet_ioctl_config_lnd_tunables tunables;
2897 struct lnet_dlc_network_descr nw_descr;
2898 char *net_id = "<255:65535>"; /* LNET_NET_ANY */
2901 /* For NI you can't have both setting all NIDs and a requested NID */
2905 if (lnd_timeout > -1)
2906 return lustre_lnet_config_lnd_timeout(lnd_timeout, net,
2909 if (cpp == -1 && healthv == -1)
2913 net_id = strchr(nidstr, '@');
2919 lustre_lnet_init_nw_descr(&nw_descr);
2920 nw_descr.nw_id = libcfs_str2net(net_id);
2922 rc = lustre_lnet_parse_interfaces(nidstr ? nidstr : "<?>", &nw_descr);
2923 if (rc != LUSTRE_CFG_RC_NO_ERR)
2926 memset(&tunables, 0, sizeof(tunables));
2927 tunables.lt_cmn.lct_peer_timeout = -1;
2928 if (nw_descr.nw_id == LNET_NET_ANY && cpp > -1)
2929 tunables.lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer = cpp;
2930 else if (LNET_NETTYP(nw_descr.nw_id) == SOCKLND && (cpp > -1))
2931 tunables.lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer = cpp;
2932 else if (LNET_NETTYP(nw_descr.nw_id) == O2IBLND && (cpp > -1))
2933 tunables.lt_tun.lnd_tun_u.lnd_o2ib.lnd_conns_per_peer = cpp;
2935 rc = yaml_lnet_config_ni(net_id, NULL, &nw_descr,
2936 cpp != -1 ? &tunables : NULL, healthv, NULL,
2937 LNET_GENL_VERSION, NLM_F_REPLACE, stdout);
2939 if (rc == -EOPNOTSUPP)
2945 rc = lustre_lnet_config_ni_conns_per_peer(cpp, all, nidstr,
2948 rc = lustre_lnet_config_ni_healthv(healthv, all, nidstr,
2953 static int yaml_lnet_peer_display(yaml_parser_t *reply, bool list_only)
2955 yaml_emitter_t debug;
2958 rc = yaml_emitter_initialize(&debug);
2962 yaml_emitter_set_indent(&debug, 6);
2963 yaml_emitter_set_output_file(&debug, stdout);
2972 rc = yaml_parser_parse(reply, &event);
2974 goto report_reply_error;
2976 if (event.type != YAML_SCALAR_EVENT)
2979 value = (char *)event.data.scalar.value;
2980 if (strcmp(value, "peer") == 0) {
2981 yaml_event_delete(&event);
2983 yaml_scalar_event_initialize(&event, NULL,
2984 (yaml_char_t *)YAML_STR_TAG,
2985 (yaml_char_t *)"peer list",
2986 strlen("peer list"),
2988 YAML_PLAIN_SCALAR_STYLE);
2989 } else if (strcmp(value, "primary nid") == 0) {
2990 yaml_event_delete(&event);
2992 yaml_scalar_event_initialize(&event, NULL,
2993 (yaml_char_t *)YAML_STR_TAG,
2994 (yaml_char_t *)"nid",
2997 YAML_PLAIN_SCALAR_STYLE);
2998 rc = yaml_emitter_emit(&debug, &event);
3002 /* Now print NID address */
3003 rc = yaml_parser_parse(reply, &event);
3005 goto report_reply_error;
3007 rc = yaml_emitter_emit(&debug, &event);
3011 /* skip ALL peer_ni info */
3012 while (event.type != YAML_SEQUENCE_END_EVENT) {
3013 rc = yaml_parser_parse(reply, &event);
3015 goto report_reply_error;
3018 /* But keep sequence end event */
3019 rc = yaml_parser_parse(reply, &event);
3021 goto report_reply_error;
3023 if (event.type == YAML_SEQUENCE_END_EVENT) {
3024 yaml_event_delete(&event);
3026 rc = yaml_parser_parse(reply, &event);
3028 goto report_reply_error;
3032 rc = yaml_emitter_emit(&debug, &event);
3036 done = (event.type == YAML_DOCUMENT_END_EVENT);
3039 yaml_document_t errmsg;
3041 rc = yaml_parser_load(reply, &errmsg);
3043 rc = yaml_emitter_dump(&debug, &errmsg);
3044 yaml_document_delete(&errmsg);
3048 yaml_emitter_log_error(&debug, stderr);
3049 rc = -EINVAL; /* Avoid reporting as reply error */
3052 yaml_emitter_delete(&debug);
3057 static int yaml_lnet_peer(char *prim_nid, char *nidstr, bool disable_mr,
3058 int health_value, int state, bool list_only,
3059 int version, int flags, FILE *fp)
3061 struct nl_sock *sk = NULL;
3062 const char *msg = NULL;
3063 yaml_emitter_t output;
3064 yaml_parser_t reply;
3068 /* Create Netlink emitter to send request to kernel */
3069 sk = nl_socket_alloc();
3073 /* Setup parser to receive Netlink packets */
3074 rc = yaml_parser_initialize(&reply);
3080 rc = yaml_parser_set_input_netlink(&reply, sk, false);
3082 msg = yaml_parser_get_reader_error(&reply);
3086 /* Create Netlink emitter to send request to kernel */
3087 rc = yaml_emitter_initialize(&output);
3089 msg = "failed to initialize emitter";
3093 rc = yaml_emitter_set_output_netlink(&output, sk, LNET_GENL_NAME,
3094 version, LNET_CMD_PEERS, flags);
3098 yaml_emitter_open(&output);
3099 yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
3100 rc = yaml_emitter_emit(&output, &event);
3104 yaml_mapping_start_event_initialize(&event, NULL,
3105 (yaml_char_t *)YAML_MAP_TAG,
3106 1, YAML_ANY_MAPPING_STYLE);
3107 rc = yaml_emitter_emit(&output, &event);
3111 yaml_scalar_event_initialize(&event, NULL,
3112 (yaml_char_t *)YAML_STR_TAG,
3113 (yaml_char_t *)"peer",
3114 strlen("peer"), 1, 0,
3115 YAML_PLAIN_SCALAR_STYLE);
3116 rc = yaml_emitter_emit(&output, &event);
3121 yaml_sequence_start_event_initialize(&event, NULL,
3122 (yaml_char_t *)YAML_SEQ_TAG,
3124 YAML_BLOCK_SEQUENCE_STYLE);
3125 rc = yaml_emitter_emit(&output, &event);
3129 yaml_mapping_start_event_initialize(&event, NULL,
3130 (yaml_char_t *)YAML_MAP_TAG,
3132 YAML_BLOCK_MAPPING_STYLE);
3133 rc = yaml_emitter_emit(&output, &event);
3137 yaml_scalar_event_initialize(&event, NULL,
3138 (yaml_char_t *)YAML_STR_TAG,
3139 (yaml_char_t *)"primary nid",
3140 strlen("primary nid"), 1, 0,
3141 YAML_PLAIN_SCALAR_STYLE);
3142 rc = yaml_emitter_emit(&output, &event);
3146 yaml_scalar_event_initialize(&event, NULL,
3147 (yaml_char_t *)YAML_STR_TAG,
3148 (yaml_char_t *)prim_nid,
3149 strlen(prim_nid), 1, 0,
3150 YAML_PLAIN_SCALAR_STYLE);
3151 rc = yaml_emitter_emit(&output, &event);
3156 yaml_scalar_event_initialize(&event, NULL,
3157 (yaml_char_t *)YAML_STR_TAG,
3158 (yaml_char_t *)"Multi-Rail",
3159 strlen("Multi-Rail"), 1, 0,
3160 YAML_PLAIN_SCALAR_STYLE);
3161 rc = yaml_emitter_emit(&output, &event);
3165 yaml_scalar_event_initialize(&event, NULL,
3166 (yaml_char_t *)YAML_BOOL_TAG,
3167 (yaml_char_t *)"False",
3168 strlen("False"), 1, 0,
3169 YAML_PLAIN_SCALAR_STYLE);
3170 rc = yaml_emitter_emit(&output, &event);
3176 char peer_state[INT_STRING_LEN];
3178 yaml_scalar_event_initialize(&event, NULL,
3179 (yaml_char_t *)YAML_STR_TAG,
3180 (yaml_char_t *)"peer state",
3181 strlen("peer state"), 1, 0,
3182 YAML_PLAIN_SCALAR_STYLE);
3183 rc = yaml_emitter_emit(&output, &event);
3187 snprintf(peer_state, sizeof(peer_state), "%d", state);
3188 yaml_scalar_event_initialize(&event, NULL,
3189 (yaml_char_t *)YAML_INT_TAG,
3190 (yaml_char_t *)peer_state,
3191 strlen(peer_state), 1, 0,
3192 YAML_PLAIN_SCALAR_STYLE);
3193 rc = yaml_emitter_emit(&output, &event);
3198 if (!nidstr && health_value == -1)
3201 yaml_scalar_event_initialize(&event, NULL,
3202 (yaml_char_t *)YAML_STR_TAG,
3203 (yaml_char_t *)"peer ni",
3204 strlen("peer ni"), 1, 0,
3205 YAML_PLAIN_SCALAR_STYLE);
3206 rc = yaml_emitter_emit(&output, &event);
3210 yaml_sequence_start_event_initialize(&event, NULL,
3211 (yaml_char_t *)YAML_SEQ_TAG,
3212 1, YAML_BLOCK_SEQUENCE_STYLE);
3213 rc = yaml_emitter_emit(&output, &event);
3218 struct nid_node head, *entry;
3221 /* If we have LNET_ANY_NID and its NLM_F_REPLACE we
3222 * treat it as the all flag case for lnetctl peer set
3224 if (strcmp(nidstr, "<?>") == 0) {
3225 yaml_mapping_start_event_initialize(&event, NULL,
3226 (yaml_char_t *)YAML_MAP_TAG,
3227 1, YAML_BLOCK_MAPPING_STYLE);
3228 rc = yaml_emitter_emit(&output, &event);
3232 yaml_scalar_event_initialize(&event, NULL,
3233 (yaml_char_t *)YAML_STR_TAG,
3234 (yaml_char_t *)"nid",
3235 strlen("nid"), 1, 0,
3236 YAML_PLAIN_SCALAR_STYLE);
3237 rc = yaml_emitter_emit(&output, &event);
3241 yaml_scalar_event_initialize(&event, NULL,
3242 (yaml_char_t *)YAML_STR_TAG,
3243 (yaml_char_t *)nidstr,
3244 strlen(nidstr), 1, 0,
3245 YAML_PLAIN_SCALAR_STYLE);
3246 rc = yaml_emitter_emit(&output, &event);
3250 yaml_mapping_end_event_initialize(&event);
3251 rc = yaml_emitter_emit(&output, &event);
3258 NL_INIT_LIST_HEAD(&head.children);
3259 nl_init_list_head(&head.list);
3260 rc = lustre_lnet_parse_nid_range(&head, nidstr, &msg);
3262 fprintf(stdout, "can't parse nidrange: \"%s\"\n", nidstr);
3263 lustre_lnet_free_list(&head);
3264 yaml_emitter_delete(&output);
3270 if (nl_list_empty(&head.children)) {
3271 lustre_lnet_free_list(&head);
3272 yaml_emitter_delete(&output);
3273 msg = "Unable to parse nidlist: did not expand to any nids";
3278 rc = 1; /* one means its working */
3280 nl_list_for_each_entry(entry, &head.children, list) {
3281 char *nid = entry->nidstr;
3283 if (count++ > LNET_MAX_NIDS_PER_PEER) {
3284 lustre_lnet_free_list(&head);
3285 yaml_emitter_delete(&output);
3286 msg = "Unable to parse nidlist: specifies more NIDs than allowed";
3292 yaml_mapping_start_event_initialize(&event, NULL,
3293 (yaml_char_t *)YAML_MAP_TAG,
3294 1, YAML_BLOCK_MAPPING_STYLE);
3295 rc = yaml_emitter_emit(&output, &event);
3299 yaml_scalar_event_initialize(&event, NULL,
3300 (yaml_char_t *)YAML_STR_TAG,
3301 (yaml_char_t *)"nid",
3302 strlen("nid"), 1, 0,
3303 YAML_PLAIN_SCALAR_STYLE);
3304 rc = yaml_emitter_emit(&output, &event);
3308 yaml_scalar_event_initialize(&event, NULL,
3309 (yaml_char_t *)YAML_STR_TAG,
3312 YAML_PLAIN_SCALAR_STYLE);
3313 rc = yaml_emitter_emit(&output, &event);
3317 yaml_mapping_end_event_initialize(&event);
3318 rc = yaml_emitter_emit(&output, &event);
3322 lustre_lnet_free_list(&head);
3325 if (health_value >= 0) {
3326 char health[INT_STRING_LEN];
3328 /* Create the mapping for 'health stats'. The value field for
3329 * the mapping is not provided so its treated as a empty string.
3331 yaml_mapping_start_event_initialize(&event, NULL,
3332 (yaml_char_t *)YAML_MAP_TAG,
3333 1, YAML_BLOCK_MAPPING_STYLE);
3334 rc = yaml_emitter_emit(&output, &event);
3338 yaml_scalar_event_initialize(&event, NULL,
3339 (yaml_char_t *)YAML_STR_TAG,
3340 (yaml_char_t *)"health stats",
3341 strlen("health stats"), 1, 0,
3342 YAML_PLAIN_SCALAR_STYLE);
3343 rc = yaml_emitter_emit(&output, &event);
3347 /* Setup all mappings for data related to the 'health stats' */
3348 yaml_mapping_start_event_initialize(&event, NULL,
3349 (yaml_char_t *)YAML_MAP_TAG,
3350 1, YAML_BLOCK_MAPPING_STYLE);
3351 rc = yaml_emitter_emit(&output, &event);
3355 yaml_scalar_event_initialize(&event, NULL,
3356 (yaml_char_t *)YAML_STR_TAG,
3357 (yaml_char_t *)"health value",
3358 strlen("health value"), 1, 0,
3359 YAML_PLAIN_SCALAR_STYLE);
3360 rc = yaml_emitter_emit(&output, &event);
3364 snprintf(health, sizeof(health), "%d", health_value);
3365 yaml_scalar_event_initialize(&event, NULL,
3366 (yaml_char_t *)YAML_INT_TAG,
3367 (yaml_char_t *)health,
3368 strlen(health), 1, 0,
3369 YAML_PLAIN_SCALAR_STYLE);
3370 rc = yaml_emitter_emit(&output, &event);
3374 yaml_mapping_end_event_initialize(&event);
3375 rc = yaml_emitter_emit(&output, &event);
3379 yaml_mapping_end_event_initialize(&event);
3380 rc = yaml_emitter_emit(&output, &event);
3385 yaml_sequence_end_event_initialize(&event);
3386 rc = yaml_emitter_emit(&output, &event);
3390 yaml_mapping_end_event_initialize(&event);
3391 rc = yaml_emitter_emit(&output, &event);
3395 yaml_sequence_end_event_initialize(&event);
3396 rc = yaml_emitter_emit(&output, &event);
3400 yaml_scalar_event_initialize(&event, NULL,
3401 (yaml_char_t *)YAML_STR_TAG,
3404 YAML_PLAIN_SCALAR_STYLE);
3405 rc = yaml_emitter_emit(&output, &event);
3410 yaml_mapping_end_event_initialize(&event);
3411 rc = yaml_emitter_emit(&output, &event);
3415 yaml_document_end_event_initialize(&event, 0);
3416 rc = yaml_emitter_emit(&output, &event);
3420 rc = yaml_emitter_close(&output);
3423 yaml_emitter_log_error(&output, stderr);
3426 rc = yaml_lnet_peer_display(&reply, list_only);
3428 msg = yaml_parser_get_reader_error(&reply);
3429 /* If we didn't find any peers just be silent */
3430 if (msg && strcmp(msg, "No peers found") == 0)
3434 yaml_emitter_delete(&output);
3437 yaml_lnet_print_error(flags, "peer", msg);
3440 yaml_parser_delete(&reply);
3443 return rc == 1 ? 0 : rc;
3446 static int yaml_lnet_config_peer_ni_healthv(int healthv, bool all,
3447 char *lpni_nid, int state,
3448 int seq_no, struct cYAML **err_rc)
3452 rc = yaml_lnet_peer(lpni_nid ? lpni_nid : "<?>", all ? "<?>" : NULL,
3453 false, healthv, state, false, LNET_GENL_VERSION,
3454 NLM_F_REPLACE, stdout);
3456 if (rc == -EOPNOTSUPP)
3462 rc = lustre_lnet_config_peer_ni_healthv(healthv, all, lpni_nid,
3465 rc = lustre_lnet_set_peer_state(state, lpni_nid, -1, err_rc);
3470 static int set_value_helper(int argc, char **argv, int cmd)
3472 char *nidstr = NULL;
3475 int lnd_timeout = -1;
3481 struct cYAML *err_rc = NULL;
3482 char err_str[LNET_MAX_STR_LEN] = "";
3483 static const struct option long_options[] = {
3484 { .val = 'a', .name = "all", .has_arg = no_argument },
3485 { .val = 'i', .name = "net", .has_arg = required_argument },
3486 { .val = 'l', .name = "lnd-timeout",
3487 .has_arg = required_argument },
3488 { .val = 'm', .name = "conns-per-peer",
3489 .has_arg = required_argument },
3490 { .val = 'n', .name = "nid", .has_arg = required_argument },
3491 { .val = 's', .name = "state", .has_arg = required_argument },
3492 { .val = 't', .name = "health", .has_arg = required_argument },
3496 while ((opt = getopt_long(argc, argv, "ai:l:m:n:s:t:",
3497 long_options, NULL)) != -1) {
3503 net = libcfs_str2net(optarg);
3504 if (net == LNET_NET_ANY) {
3505 rc = LUSTRE_CFG_RC_BAD_PARAM;
3506 snprintf(err_str, sizeof(err_str),
3507 "\"Invalid network type: %s\"",
3513 lnd_timeout = atoi(optarg);
3514 if (lnd_timeout < 0) {
3515 rc = LUSTRE_CFG_RC_BAD_PARAM;
3516 snprintf(err_str, sizeof(err_str),
3517 "\"Invalid LND timeout value '%s', must be >= 0\"",
3523 if (cmd != LNET_CMD_NETS ||
3524 parse_long(optarg, &cpp) != 0)
3531 if (cmd != LNET_CMD_PEERS ||
3532 parse_long(optarg, &state) != 0)
3536 if (parse_long(optarg, &healthv) != 0)
3540 rc = LUSTRE_CFG_RC_BAD_PARAM;
3541 snprintf(err_str, sizeof(err_str),
3542 "\"Invalid option or missing argument\"");
3549 if (lnd_timeout >= 0 && net == 0) {
3550 rc = LUSTRE_CFG_RC_BAD_PARAM;
3551 snprintf(err_str, sizeof(err_str),
3552 "\"Specified --lnd-timeout without --net option\"");
3556 if (cmd == LNET_CMD_PEERS)
3557 rc = yaml_lnet_config_peer_ni_healthv(healthv, all, nidstr,
3558 state, seq_no, &err_rc);
3560 rc = yaml_lnet_config_ni_value(healthv, all, nidstr, cpp,
3561 lnd_timeout, net, seq_no,
3565 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3566 cYAML_build_error(rc, -1, "net", "set", err_str, &err_rc);
3567 cYAML_print_tree2file(stderr, err_rc);
3570 cYAML_free_tree(err_rc);
3575 static int jt_set_ni_value(int argc, char **argv)
3577 int rc = check_cmd(net_cmds, "net", "set", 0, argc, argv);
3582 return set_value_helper(argc, argv, LNET_CMD_NETS);
3585 static int jt_set_peer_ni_value(int argc, char **argv)
3587 int rc = check_cmd(peer_cmds, "peer", "set", 0, argc, argv);
3592 return set_value_helper(argc, argv, LNET_CMD_PEERS);
3595 static int yaml_debug_recovery(enum lnet_health_type type)
3597 yaml_parser_t setup, reply;
3598 yaml_document_t results;
3599 yaml_emitter_t output;
3600 const char *msg = NULL;
3606 case LNET_HEALTH_TYPE_LOCAL_NI:
3607 config = "dbg-recov:\n queue_type: 0\n";
3609 case LNET_HEALTH_TYPE_PEER_NI:
3610 config = "dbg-recov:\n queue_type: 1\n";
3619 /* Initialize configuration parser */
3620 rc = yaml_parser_initialize(&setup);
3622 yaml_parser_log_error(&setup, stderr, NULL);
3623 yaml_parser_delete(&setup);
3627 yaml_parser_set_input_string(&setup, (unsigned char *)config,
3629 rc = yaml_parser_load(&setup, &results);
3631 yaml_parser_log_error(&setup, stderr, NULL);
3632 yaml_parser_delete(&setup);
3635 yaml_parser_delete(&setup);
3637 /* Create Netlink emitter to send request to kernel */
3638 sk = nl_socket_alloc();
3640 yaml_document_delete(&results);
3644 /* Setup parser to recieve Netlink packets */
3645 rc = yaml_parser_initialize(&reply);
3647 yaml_document_delete(&results);
3652 rc = yaml_parser_set_input_netlink(&reply, sk, false);
3656 yaml_emitter_initialize(&output);
3657 rc = yaml_emitter_set_output_netlink(&output, sk, LNET_GENL_NAME,
3659 LNET_CMD_DBG_RECOV, NLM_F_DUMP);
3660 if (rc == 1) /* 1 is success */
3661 rc = yaml_emitter_dump(&output, &results);
3663 yaml_emitter_log_error(&output, stderr);
3666 yaml_document_t errmsg;
3668 rc = yaml_parser_load(&reply, &errmsg);
3670 yaml_emitter_t debug;
3672 rc = yaml_emitter_initialize(&debug);
3674 yaml_emitter_set_indent(&debug,
3675 LNET_DEFAULT_INDENT);
3676 yaml_emitter_set_output_file(&debug,
3678 rc = yaml_emitter_dump(&debug, &errmsg);
3680 yaml_emitter_delete(&debug);
3682 msg = yaml_parser_get_reader_error(&reply);
3683 if (errno == -ENOENT)
3686 yaml_document_delete(&errmsg);
3688 yaml_emitter_delete(&output);
3692 msg = yaml_parser_get_reader_error(&reply);
3694 fprintf(stdout, "Operation failed: %s\n", msg);
3696 yaml_parser_delete(&reply);
3699 return rc == 1 ? 0 : rc;
3702 static int jt_show_recovery(int argc, char **argv)
3705 struct cYAML *err_rc = NULL, *show_rc = NULL;
3706 const char *const short_options = "lp";
3707 static const struct option long_options[] = {
3708 { .name = "local", .has_arg = no_argument, .val = 'l' },
3709 { .name = "peer", .has_arg = no_argument, .val = 'p' },
3712 enum lnet_health_type type = -1;
3714 rc = check_cmd(debug_cmds, "debug", "recovery", 0, argc, argv);
3718 while ((opt = getopt_long(argc, argv, short_options,
3719 long_options, NULL)) != -1) {
3722 type = LNET_HEALTH_TYPE_LOCAL_NI;
3725 type = LNET_HEALTH_TYPE_PEER_NI;
3732 rc = yaml_debug_recovery(type);
3734 if (rc == -EOPNOTSUPP)
3740 case LNET_HEALTH_TYPE_LOCAL_NI:
3741 rc = lustre_lnet_show_local_ni_recovq(-1, &show_rc, &err_rc);
3743 case LNET_HEALTH_TYPE_PEER_NI:
3744 rc = lustre_lnet_show_peer_ni_recovq(-1, &show_rc, &err_rc);
3747 rc = LUSTRE_CFG_RC_BAD_PARAM;
3751 if (rc != LUSTRE_CFG_RC_NO_ERR)
3752 cYAML_print_tree2file(stderr, err_rc);
3754 cYAML_print_tree(show_rc);
3756 cYAML_free_tree(err_rc);
3757 cYAML_free_tree(show_rc);
3762 static int jt_debug_nidlist(int argc, char **argv)
3767 fprintf(stderr, "Missing nidlist argument\n");
3769 } else if (argc == 2) {
3770 rc = lustre_lnet_debug_nidlist(argv[1], NULL);
3771 } else if (argc == 3) {
3772 rc = lustre_lnet_debug_nidlist(argv[1], argv[2]);
3774 fprintf(stderr, "Too many arguments\n");
3781 static int jt_show_peer_debug_info(int argc, char **argv)
3784 struct cYAML *err_rc = NULL;
3785 char *peer_nid = optarg;
3786 const char *const short_opts = "k";
3787 const struct option long_opts[] = {
3788 { .name = "nid", .has_arg = required_argument, .val = 'k' },
3791 rc = check_cmd(debug_cmds, "debug", "peer", 0, argc, argv);
3796 while ((opt = getopt_long(argc, argv, short_opts,
3797 long_opts, NULL)) != -1) {
3807 rc = lustre_lnet_show_peer_debug_info(peer_nid, -1, &err_rc);
3809 if (rc != LUSTRE_CFG_RC_NO_ERR)
3810 cYAML_print_tree2file(stderr, err_rc);
3812 cYAML_free_tree(err_rc);
3817 static int jt_show_net(int argc, char **argv)
3819 char *network = NULL;
3821 struct cYAML *err_rc = NULL, *show_rc = NULL;
3822 long int detail = 0;
3823 const char *const short_options = "n:v";
3824 static const struct option long_options[] = {
3825 { .name = "net", .has_arg = required_argument, .val = 'n' },
3826 { .name = "verbose", .has_arg = optional_argument, .val = 'v' },
3829 rc = check_cmd(net_cmds, "net", "show", 0, argc, argv);
3833 while ((opt = getopt_long(argc, argv, short_options,
3834 long_options, NULL)) != -1) {
3840 /* '-v' has an optional argument. Default is 1. */
3841 if (optarg || optind >= argc ||
3842 argv[optind] == NULL || argv[optind][0] == '-' ||
3843 parse_long(argv[optind++], &detail))
3847 print_help(net_cmds, "net", "show");
3853 rc = yaml_lnet_config_ni(network, NULL, NULL, NULL, -1, NULL,
3854 detail, NLM_F_DUMP, stdout);
3856 if (rc != -EOPNOTSUPP)
3860 rc = lustre_lnet_show_net(network, (int) detail, -1, &show_rc, &err_rc,
3863 if (rc != LUSTRE_CFG_RC_NO_ERR)
3864 cYAML_print_tree2file(stderr, err_rc);
3866 cYAML_print_tree(show_rc);
3868 cYAML_free_tree(err_rc);
3869 cYAML_free_tree(show_rc);
3874 static int jt_show_routing(int argc, char **argv)
3876 struct cYAML *err_rc = NULL, *show_rc = NULL;
3879 rc = check_cmd(routing_cmds, "routing", "show", 0, argc, argv);
3883 rc = lustre_lnet_show_routing(-1, &show_rc, &err_rc, false);
3885 if (rc != LUSTRE_CFG_RC_NO_ERR)
3886 cYAML_print_tree2file(stderr, err_rc);
3888 cYAML_print_tree(show_rc);
3890 cYAML_free_tree(err_rc);
3891 cYAML_free_tree(show_rc);
3896 static int jt_show_stats(int argc, char **argv)
3899 struct cYAML *show_rc = NULL, *err_rc = NULL;
3901 rc = check_cmd(stats_cmds, "stats", "show", 0, argc, argv);
3905 rc = lustre_lnet_show_stats(-1, &show_rc, &err_rc);
3907 if (rc != LUSTRE_CFG_RC_NO_ERR)
3908 cYAML_print_tree2file(stderr, err_rc);
3910 cYAML_print_tree(show_rc);
3912 cYAML_free_tree(err_rc);
3913 cYAML_free_tree(show_rc);
3918 static int jt_show_udsp(int argc, char **argv)
3922 struct cYAML *err_rc = NULL, *show_rc = NULL;
3924 const char *const short_options = "i:";
3925 static const struct option long_options[] = {
3926 { .name = "idx", .has_arg = required_argument, .val = 'i' },
3930 rc = check_cmd(udsp_cmds, "udsp", "show", 0, argc, argv);
3934 while ((opt = getopt_long(argc, argv, short_options,
3935 long_options, NULL)) != -1) {
3938 rc = parse_long(optarg, &idx);
3939 if (rc != 0 || idx < -1) {
3940 printf("Invalid index \"%s\"\n", optarg);
3945 print_help(net_cmds, "net", "show");
3951 rc = lustre_lnet_show_udsp(idx, -1, &show_rc, &err_rc);
3953 if (rc != LUSTRE_CFG_RC_NO_ERR)
3954 cYAML_print_tree2file(stderr, err_rc);
3956 cYAML_print_tree(show_rc);
3958 cYAML_free_tree(err_rc);
3959 cYAML_free_tree(show_rc);
3964 static int jt_show_global(int argc, char **argv)
3967 struct cYAML *show_rc = NULL, *err_rc = NULL;
3969 rc = check_cmd(global_cmds, "global", "show", 0, argc, argv);
3973 rc = lustre_lnet_show_numa_range(-1, &show_rc, &err_rc);
3974 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3975 cYAML_print_tree2file(stderr, err_rc);
3979 rc = lustre_lnet_show_max_intf(-1, &show_rc, &err_rc);
3980 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3981 cYAML_print_tree2file(stderr, err_rc);
3985 rc = lustre_lnet_show_discovery(-1, &show_rc, &err_rc);
3986 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3987 cYAML_print_tree2file(stderr, err_rc);
3991 rc = lustre_lnet_show_drop_asym_route(-1, &show_rc, &err_rc);
3992 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3993 cYAML_print_tree2file(stderr, err_rc);
3997 rc = lustre_lnet_show_retry_count(-1, &show_rc, &err_rc);
3998 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3999 cYAML_print_tree2file(stderr, err_rc);
4003 rc = lustre_lnet_show_transaction_to(-1, &show_rc, &err_rc);
4004 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4005 cYAML_print_tree2file(stderr, err_rc);
4009 rc = lustre_lnet_show_hsensitivity(-1, &show_rc, &err_rc);
4010 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4011 cYAML_print_tree2file(stderr, err_rc);
4015 rc = lustre_lnet_show_recov_intrv(-1, &show_rc, &err_rc);
4016 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4017 cYAML_print_tree2file(stderr, err_rc);
4021 rc = lustre_lnet_show_rtr_sensitivity(-1, &show_rc, &err_rc);
4022 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4023 cYAML_print_tree2file(stderr, err_rc);
4027 rc = lustre_lnet_show_lnd_timeout(-1, &show_rc, &err_rc);
4028 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4029 cYAML_print_tree2file(stderr, err_rc);
4033 rc = lustre_lnet_show_response_tracking(-1, &show_rc, &err_rc);
4034 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4035 cYAML_print_tree2file(stderr, err_rc);
4039 rc = lustre_lnet_show_recovery_limit(-1, &show_rc, &err_rc);
4040 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4041 cYAML_print_tree2file(stderr, err_rc);
4045 rc = lustre_lnet_show_max_recovery_ping_interval(-1, &show_rc, &err_rc);
4046 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4047 cYAML_print_tree2file(stderr, err_rc);
4052 cYAML_print_tree(show_rc);
4055 cYAML_free_tree(err_rc);
4056 cYAML_free_tree(show_rc);
4061 static int jt_lnet(int argc, char **argv)
4065 rc = check_cmd(lnet_cmds, "lnet", NULL, 2, argc, argv);
4069 return cfs_parser(argc, argv, lnet_cmds);
4072 static int jt_route(int argc, char **argv)
4076 rc = check_cmd(route_cmds, "route", NULL, 2, argc, argv);
4080 return cfs_parser(argc, argv, route_cmds);
4083 static int jt_net(int argc, char **argv)
4087 rc = check_cmd(net_cmds, "net", NULL, 2, argc, argv);
4091 return cfs_parser(argc, argv, net_cmds);
4094 static int jt_routing(int argc, char **argv)
4098 rc = check_cmd(routing_cmds, "routing", NULL, 2, argc, argv);
4102 return cfs_parser(argc, argv, routing_cmds);
4105 static int jt_stats(int argc, char **argv)
4109 rc = check_cmd(stats_cmds, "stats", NULL, 2, argc, argv);
4113 return cfs_parser(argc, argv, stats_cmds);
4116 static int jt_debug(int argc, char **argv)
4120 rc = check_cmd(debug_cmds, "debug", NULL, 2, argc, argv);
4124 return cfs_parser(argc, argv, debug_cmds);
4127 static int jt_global(int argc, char **argv)
4131 rc = check_cmd(global_cmds, "global", NULL, 2, argc, argv);
4135 return cfs_parser(argc, argv, global_cmds);
4138 static int jt_peers(int argc, char **argv)
4142 rc = check_cmd(peer_cmds, "peer", NULL, 2, argc, argv);
4146 return cfs_parser(argc, argv, peer_cmds);
4149 static int jt_set(int argc, char **argv)
4153 rc = check_cmd(set_cmds, "set", NULL, 2, argc, argv);
4157 return cfs_parser(argc, argv, set_cmds);
4160 static int jt_udsp(int argc, char **argv)
4164 rc = check_cmd(udsp_cmds, "udsp", NULL, 2, argc, argv);
4168 return cfs_parser(argc, argv, udsp_cmds);
4171 static int jt_fault(int argc, char **argv)
4175 rc = check_cmd(fault_cmds, "fault", NULL, 2, argc, argv);
4179 return cfs_parser(argc, argv, fault_cmds);
4182 static int jt_fault_drop(int argc, char **argv)
4186 rc = check_cmd(fault_drop_cmds, "drop", NULL, 2, argc, argv);
4190 return cfs_parser(argc, argv, fault_drop_cmds);
4193 static int jt_fault_delay(int argc, char **argv)
4197 rc = check_cmd(fault_delay_cmds, "delay", NULL, 2, argc, argv);
4201 return cfs_parser(argc, argv, fault_delay_cmds);
4204 static int yaml_import_global_settings(char *key, unsigned long value,
4205 char cmd, struct cYAML *show_rc,
4206 struct cYAML *err_rc)
4210 if (strcmp("numa_range", key) == 0) {
4211 if (cmd == 'a' || cmd == 'd') {
4214 rc = lustre_lnet_config_numa_range(value, -1,
4216 } else if (cmd == 's') {
4217 rc = lustre_lnet_show_numa_range(-1, &show_rc,
4220 } else if (strcmp("max_interfaces", key) == 0 ||
4221 strcmp("max_intf", key) == 0) {
4222 if (cmd == 'a' || cmd == 'd') {
4224 value = LNET_INTERFACES_MAX_DEFAULT;
4225 rc = lustre_lnet_config_max_intf(value, -1,
4227 } else if (cmd == 's') {
4228 rc = lustre_lnet_show_max_intf(-1, &show_rc,
4231 } else if (strcmp("discovery", key) == 0) {
4232 if (cmd == 'a' || cmd == 'd') {
4235 rc = lustre_lnet_config_discovery(value, -1,
4237 } else if (cmd == 's') {
4238 rc = lustre_lnet_show_discovery(-1, &show_rc,
4241 } else if (strcmp("drop_asym_route", key) == 0) {
4243 rc = lustre_lnet_config_drop_asym_route(value,
4246 } else if (cmd == 's') {
4247 rc = lustre_lnet_show_drop_asym_route(-1, &show_rc,
4250 } else if (strcmp("retry_count", key) == 0) {
4252 rc = lustre_lnet_config_retry_count(value, -1,
4254 } else if (cmd == 's') {
4255 rc = lustre_lnet_show_retry_count(-1, &show_rc,
4258 } else if (strcmp("transaction_timeout", key) == 0) {
4260 rc = lustre_lnet_config_transaction_to(value, -1,
4262 } else if (cmd == 's') {
4263 rc = lustre_lnet_show_transaction_to(-1, &show_rc,
4266 } else if (strcmp("health_sensitivity", key) == 0) {
4268 rc = lustre_lnet_config_hsensitivity(value, -1,
4270 } else if (cmd == 's') {
4271 rc = lustre_lnet_show_hsensitivity(-1, &show_rc,
4274 } else if (strcmp("recovery_interval", key) == 0) {
4276 rc = lustre_lnet_config_recov_intrv(value, -1,
4278 } else if (cmd == 's') {
4279 rc = lustre_lnet_show_recov_intrv(-1, &show_rc,
4282 } else if (strcmp("router_sensitivity", key) == 0) {
4284 rc = lustre_lnet_config_rtr_sensitivity(value, -1,
4286 } else if (cmd == 's') {
4287 rc = lustre_lnet_show_rtr_sensitivity(-1, &show_rc,
4290 } else if (strcmp("lnd_timeout", key) == 0) {
4292 } else if (cmd == 's') {
4293 rc = lustre_lnet_show_lnd_timeout(-1, &show_rc,
4296 } else if (strcmp("response_tracking", key) == 0) {
4298 rc = lustre_lnet_config_response_tracking(value, -1,
4300 } else if (cmd == 's') {
4301 rc = lustre_lnet_show_response_tracking(-1, &show_rc,
4304 } else if (strcmp("recovery_limit", key) == 0) {
4306 rc = lustre_lnet_config_recovery_limit(value, -1,
4308 } else if (cmd == 's') {
4309 rc = lustre_lnet_show_recovery_limit(-1, &show_rc,
4312 } else if (strcmp("max_recovery_ping_interval", key) == 0) {
4314 rc = lustre_lnet_config_max_recovery_ping_interval(value, -1,
4316 } else if (cmd == 's') {
4317 rc = lustre_lnet_show_max_recovery_ping_interval(-1, &show_rc,
4325 static char *global_params[] = {
4332 "transaction_timeout",
4333 "health_sensitivity",
4334 "recovery_interval",
4335 "router_sensitivity",
4337 "response_tracking",
4339 "max_recovery_ping_interval"
4342 static bool key_is_global_param(const char *key)
4346 for (i = 0; i < sizeof(global_params)/sizeof(global_params[0]); i++) {
4347 if (!strcmp(key, global_params[i]))
4353 static int jt_import(int argc, char **argv)
4356 struct cYAML *err_rc = NULL;
4357 struct cYAML *show_rc = NULL;
4358 int rc = 0, return_rc = 0, opt, opt_found = 0;
4359 char *yaml_blk = NULL, *buf, cmd = 'a';
4360 int flags = NLM_F_CREATE;
4361 bool release = true;
4366 const char *const short_options = "adseh";
4367 static const struct option long_options[] = {
4368 { .name = "add", .has_arg = no_argument, .val = 'a' },
4369 { .name = "del", .has_arg = no_argument, .val = 'd' },
4370 { .name = "show", .has_arg = no_argument, .val = 's' },
4371 { .name = "exec", .has_arg = no_argument, .val = 'e' },
4372 { .name = "help", .has_arg = no_argument, .val = 'h' },
4375 bool done = false, unspec = true;
4376 yaml_parser_t setup, reply;
4377 struct nl_sock *sk = NULL;
4378 int op = LNET_CMD_UNSPEC;
4379 const char *msg = NULL;
4380 yaml_emitter_t output;
4383 while ((opt = getopt_long(argc, argv, short_options,
4384 long_options, NULL)) != -1) {
4388 /* default is NLM_F_CREATE */
4392 flags = 0; /* Netlink delete cmd */
4400 /* use NLM_F_CREATE for discover */
4404 printf("import FILE\n"
4405 "import < FILE : import a file\n"
4406 "\t--add: add configuration\n"
4407 "\t--del: delete configuration\n"
4408 "\t--show: show configuration\n"
4409 "\t--exec: execute command\n"
4410 "\t--help: display this help\n"
4411 "If no command option is given then --add"
4412 " is assumed by default\n");
4419 /* grab the file name if one exists */
4420 if (opt_found && argc == 3)
4422 else if (!opt_found && argc == 2)
4425 /* file always takes precedence */
4427 /* Set a file input. */
4428 input = fopen(file, "rb");
4431 snprintf(err_str, sizeof(err_str),
4432 "cannot open '%s': %s", file,
4434 cYAML_build_error(-1, -1, "yaml", "builder",
4443 /* Create Netlink emitter to send request to kernel */
4444 sk = nl_socket_alloc();
4448 /* Setup parser to receive Netlink packets */
4449 rc = yaml_parser_initialize(&reply);
4455 rc = yaml_parser_set_input_netlink(&reply, sk, false);
4457 msg = yaml_parser_get_reader_error(&reply);
4461 /* Initialize configuration parser */
4462 rc = yaml_parser_initialize(&setup);
4464 yaml_parser_log_error(&setup, stderr, "import: ");
4465 yaml_parser_delete(&setup);
4469 yaml_parser_set_input_file(&setup, input);
4472 if (!yaml_parser_parse(&setup, &event)) {
4473 yaml_parser_log_error(&setup, stderr, "import: ");
4477 if (event.type != YAML_SCALAR_EVENT)
4480 if (!strcmp((char *)event.data.scalar.value, "net") &&
4481 op != LNET_CMD_ROUTES && cmd != 'e') {
4482 if (op != LNET_CMD_UNSPEC) {
4483 rc = yaml_netlink_complete_emitter(&output);
4489 rc = yaml_netlink_setup_emitter(&output, sk,
4497 } else if (!strcmp((char *)event.data.scalar.value, "peer") &&
4499 if (op != LNET_CMD_UNSPEC) {
4500 rc = yaml_netlink_complete_emitter(&output);
4504 op = LNET_CMD_PEERS;
4506 rc = yaml_netlink_setup_emitter(&output, sk,
4514 } else if (!strcmp((char *)event.data.scalar.value, "route") &&
4516 if (op != LNET_CMD_UNSPEC) {
4517 rc = yaml_netlink_complete_emitter(&output);
4521 op = LNET_CMD_ROUTES;
4523 rc = yaml_netlink_setup_emitter(&output, sk,
4531 } else if ((!strcmp((char *)event.data.scalar.value, "discover") ||
4532 !strcmp((char *)event.data.scalar.value, "ping")) &&
4534 if (op != LNET_CMD_UNSPEC) {
4535 rc = yaml_netlink_complete_emitter(&output);
4541 if (!strcmp((char *)event.data.scalar.value, "ping"))
4544 rc = yaml_netlink_setup_emitter(&output, sk,
4552 } else if (!strcmp((char *)event.data.scalar.value, "global")) {
4553 if (op != LNET_CMD_UNSPEC) {
4554 rc = yaml_netlink_complete_emitter(&output);
4558 op = LNET_CMD_UNSPEC;
4559 } else if (op == LNET_CMD_UNSPEC) {
4560 struct cYAML *err_rc = NULL;
4563 char errmsg[LNET_MAX_STR_LEN];
4565 key = strdup((char *)event.data.scalar.value);
4566 if (!key_is_global_param(key)) {
4567 snprintf(errmsg, LNET_MAX_STR_LEN,
4568 "invalid key '%s'", key);
4569 errno = rc = -EINVAL;
4570 yaml_lnet_print_error(flags, "import", errmsg);
4574 rc = yaml_parser_parse(&setup, &event);
4576 yaml_parser_log_error(&setup, stderr,
4581 if (!strlen((char *)event.data.scalar.value)) {
4582 snprintf(errmsg, LNET_MAX_STR_LEN,
4583 "no value specified for key '%s'",
4585 errno = rc = -EINVAL;
4586 yaml_lnet_print_error(flags, "import", errmsg);
4590 rc = parse_long((char *)event.data.scalar.value,
4593 snprintf(errmsg, LNET_MAX_STR_LEN,
4594 "invalid value '%s' for key '%s'",
4595 (char *)event.data.scalar.value, key);
4596 errno = rc = -EINVAL;
4597 yaml_lnet_print_error(flags, "import", errmsg);
4601 rc = yaml_import_global_settings(key, value, cmd,
4603 if (rc != LUSTRE_CFG_RC_NO_ERR)
4604 cYAML_print_tree2file(stderr, err_rc);
4609 if (op != LNET_CMD_UNSPEC) {
4610 rc = yaml_emitter_emit(&output, &event);
4615 done = (event.type == YAML_STREAM_END_EVENT);
4619 yaml_emitter_log_error(&output, stderr);
4620 yaml_emitter_delete(&output);
4622 } else if (!unspec) {
4623 yaml_document_t errmsg;
4625 rc = yaml_parser_load(&reply, &errmsg);
4626 if (rc == 1 && (flags & NLM_F_DUMP)) {
4627 yaml_emitter_t debug;
4629 rc = yaml_emitter_initialize(&debug);
4631 yaml_emitter_set_indent(&debug,
4632 LNET_DEFAULT_INDENT);
4633 yaml_emitter_set_output_file(&debug,
4635 rc = yaml_emitter_dump(&debug, &errmsg);
4637 yaml_emitter_delete(&debug);
4639 msg = yaml_parser_get_reader_error(&reply);
4641 yaml_emitter_delete(&output);
4642 yaml_document_delete(&errmsg);
4646 yaml_lnet_print_error(flags, "import", msg);
4649 yaml_parser_delete(&reply);
4650 yaml_parser_delete(&setup);
4655 return rc == 1 ? 0 : rc;
4657 /* assume that we're getting our input from stdin */
4658 rc = fstat(fileno(input), &st);
4660 snprintf(err_str, sizeof(err_str),
4661 "cannot get file stats '%s': %s", file,
4663 cYAML_build_error(-1, -1, "yaml", "builder",
4669 yaml_blk = buf = malloc(st.st_size);
4672 snprintf(err_str, sizeof(err_str),
4673 "failed to allocate buffer: %s",
4675 cYAML_build_error(-1, -1, "yaml", "builder",
4682 while (fgets(buf, len, input) != NULL) {
4683 char *seq = strstr(buf, "- ");
4689 skip = strspn(seq, " ");
4694 /* PyYAML format has libyaml free the
4705 rc = lustre_yaml_config(yaml_blk, st.st_size, &err_rc);
4706 return_rc = lustre_yaml_exec(yaml_blk, st.st_size, &show_rc,
4708 cYAML_print_tree(show_rc);
4709 cYAML_free_tree(show_rc);
4712 rc = lustre_yaml_del(yaml_blk, st.st_size, &err_rc);
4715 rc = lustre_yaml_show(yaml_blk, st.st_size, &show_rc,
4717 cYAML_print_tree(show_rc);
4718 cYAML_free_tree(show_rc);
4721 rc = lustre_yaml_exec(yaml_blk, st.st_size, &show_rc,
4723 cYAML_print_tree(show_rc);
4724 cYAML_free_tree(show_rc);
4728 if (yaml_blk && release)
4730 if (rc || return_rc) {
4731 cYAML_print_tree2file(stderr, err_rc);
4732 cYAML_free_tree(err_rc);
4738 static int jt_export(int argc, char **argv)
4740 struct cYAML *show_rc = NULL;
4741 struct cYAML *err_rc = NULL;
4742 int flags = NLM_F_DUMP;
4746 bool backup = false;
4748 const char *const short_options = "bh";
4749 static const struct option long_options[] = {
4750 { .name = "backup", .has_arg = no_argument, .val = 'b' },
4751 { .name = "help", .has_arg = no_argument, .val = 'h' },
4755 while ((opt = getopt_long(argc, argv, short_options,
4756 long_options, NULL)) != -1) {
4759 flags |= NLM_F_DUMP_FILTERED;
4764 printf("export > FILE.yaml : export configuration\n"
4765 "\t--backup: export only what's necessary for reconfig\n"
4766 "\t--help: display this help\n");
4771 if (backup && argc >= 3)
4773 else if (!backup && argc >= 2)
4779 f = fopen(file, "w");
4784 rc = yaml_lnet_config_ni(NULL, NULL, NULL, NULL, -1, NULL,
4785 flags & NLM_F_DUMP_FILTERED ? 1 : 2,
4788 if (rc == -EOPNOTSUPP)
4792 rc = yaml_lnet_route(NULL, NULL, -1, -1, -1, LNET_GENL_VERSION,
4795 if (rc == -EOPNOTSUPP)
4799 rc = lustre_lnet_show_routing(-1, &show_rc, &err_rc, backup);
4800 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4801 cYAML_print_tree2file(f, err_rc);
4802 cYAML_free_tree(err_rc);
4806 rc = yaml_lnet_peer(NULL, NULL, false, -1, false, false,
4807 flags & NLM_F_DUMP_FILTERED ? 0 : 3,
4810 if (rc == -EOPNOTSUPP)
4816 rc = lustre_lnet_show_net(NULL, 2, -1, &show_rc, &err_rc, backup);
4817 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4818 cYAML_print_tree2file(f, err_rc);
4819 cYAML_free_tree(err_rc);
4823 rc = lustre_lnet_show_route(NULL, NULL, -1, -1, 1, -1, &show_rc,
4825 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4826 cYAML_print_tree2file(f, err_rc);
4827 cYAML_free_tree(err_rc);
4831 rc = lustre_lnet_show_routing(-1, &show_rc, &err_rc, backup);
4832 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4833 cYAML_print_tree2file(f, err_rc);
4834 cYAML_free_tree(err_rc);
4838 rc = lustre_lnet_show_peer(NULL, 2, -1, &show_rc, &err_rc, backup);
4839 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4840 cYAML_print_tree2file(f, err_rc);
4841 cYAML_free_tree(err_rc);
4845 rc = lustre_lnet_show_numa_range(-1, &show_rc, &err_rc);
4846 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4847 cYAML_print_tree2file(f, err_rc);
4848 cYAML_free_tree(err_rc);
4852 rc = lustre_lnet_show_max_intf(-1, &show_rc, &err_rc);
4853 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4854 cYAML_print_tree2file(f, err_rc);
4855 cYAML_free_tree(err_rc);
4859 rc = lustre_lnet_show_discovery(-1, &show_rc, &err_rc);
4860 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4861 cYAML_print_tree2file(f, err_rc);
4862 cYAML_free_tree(err_rc);
4866 rc = lustre_lnet_show_drop_asym_route(-1, &show_rc, &err_rc);
4867 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4868 cYAML_print_tree2file(f, err_rc);
4869 cYAML_free_tree(err_rc);
4873 rc = lustre_lnet_show_retry_count(-1, &show_rc, &err_rc);
4874 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4875 cYAML_print_tree2file(f, err_rc);
4879 rc = lustre_lnet_show_transaction_to(-1, &show_rc, &err_rc);
4880 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4881 cYAML_print_tree2file(f, err_rc);
4885 rc = lustre_lnet_show_hsensitivity(-1, &show_rc, &err_rc);
4886 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4887 cYAML_print_tree2file(f, err_rc);
4891 rc = lustre_lnet_show_recov_intrv(-1, &show_rc, &err_rc);
4892 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4893 cYAML_print_tree2file(f, err_rc);
4897 rc = lustre_lnet_show_rtr_sensitivity(-1, &show_rc, &err_rc);
4898 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4899 cYAML_print_tree2file(f, err_rc);
4903 rc = lustre_lnet_show_lnd_timeout(-1, &show_rc, &err_rc);
4904 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4905 cYAML_print_tree2file(f, err_rc);
4909 rc = lustre_lnet_show_response_tracking(-1, &show_rc, &err_rc);
4910 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4911 cYAML_print_tree2file(f, err_rc);
4912 cYAML_free_tree(err_rc);
4916 rc = lustre_lnet_show_recovery_limit(-1, &show_rc, &err_rc);
4917 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4918 cYAML_print_tree2file(f, err_rc);
4919 cYAML_free_tree(err_rc);
4923 rc = lustre_lnet_show_max_recovery_ping_interval(-1, &show_rc, &err_rc);
4924 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4925 cYAML_print_tree2file(f, err_rc);
4926 cYAML_free_tree(err_rc);
4930 rc = lustre_lnet_show_udsp(-1, -1, &show_rc, &err_rc);
4931 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4932 cYAML_print_tree2file(f, err_rc);
4933 cYAML_free_tree(err_rc);
4937 if (show_rc != NULL) {
4938 cYAML_print_tree2file(f, show_rc);
4939 cYAML_free_tree(show_rc);
4948 static int jt_peer_nid_common(int argc, char **argv, int cmd)
4950 int flags = cmd == LNETCTL_ADD_CMD ? NLM_F_CREATE : 0;
4951 int rc = LUSTRE_CFG_RC_NO_ERR, opt;
4953 char *prim_nid = NULL, *nidstr = NULL;
4954 char err_str[LNET_MAX_STR_LEN] = "Error";
4955 struct cYAML *err_rc = NULL;
4957 const char *const short_opts = "k:m:n:f:l";
4958 const struct option long_opts[] = {
4959 { .name = "prim_nid", .has_arg = required_argument, .val = 'k' },
4960 { .name = "non_mr", .has_arg = no_argument, .val = 'm' },
4961 { .name = "nid", .has_arg = required_argument, .val = 'n' },
4962 { .name = "force", .has_arg = no_argument, .val = 'f' },
4963 { .name = "lock_prim", .has_arg = no_argument, .val = 'l' },
4966 rc = check_cmd(peer_cmds, "peer",
4967 cmd == LNETCTL_ADD_CMD ? "add" : "del", 2, argc, argv);
4971 while ((opt = getopt_long(argc, argv, short_opts,
4972 long_opts, NULL)) != -1) {
4981 if (cmd == LNETCTL_DEL_CMD) {
4982 rc = LUSTRE_CFG_RC_BAD_PARAM;
4983 snprintf(err_str, LNET_MAX_STR_LEN,
4984 "Unrecognized option '-%c'", opt);
4990 if (cmd == LNETCTL_ADD_CMD) {
4991 rc = LUSTRE_CFG_RC_BAD_PARAM;
4992 snprintf(err_str, LNET_MAX_STR_LEN,
4993 "Unrecognized option '-%c'", opt);
4996 flags |= NLM_F_EXCL;
4999 if (cmd == LNETCTL_DEL_CMD) {
5000 rc = LUSTRE_CFG_RC_BAD_PARAM;
5001 snprintf(err_str, LNET_MAX_STR_LEN,
5002 "Unrecognized option '-%c'", opt);
5005 flags |= NLM_F_EXCL;
5008 print_help(peer_cmds, "peer",
5009 cmd == LNETCTL_ADD_CMD ? "add" : "del");
5015 rc = yaml_lnet_peer(prim_nid, nidstr, !is_mr, -1, -1, false,
5016 LNET_GENL_VERSION, flags, stdout);
5018 if (rc == -EOPNOTSUPP)
5023 rc = lustre_lnet_modify_peer(prim_nid, nidstr, is_mr, cmd,
5024 force_lock, -1, &err_rc);
5025 if (rc != LUSTRE_CFG_RC_NO_ERR)
5029 cYAML_build_error(rc, -1, "peer",
5030 cmd == LNETCTL_ADD_CMD ? "add" : "del",
5034 if (rc != LUSTRE_CFG_RC_NO_ERR)
5035 cYAML_print_tree2file(stderr, err_rc);
5037 cYAML_free_tree(err_rc);
5042 static int jt_add_peer_nid(int argc, char **argv)
5044 return jt_peer_nid_common(argc, argv, LNETCTL_ADD_CMD);
5047 static int jt_del_peer_nid(int argc, char **argv)
5049 return jt_peer_nid_common(argc, argv, LNETCTL_DEL_CMD);
5052 static int jt_show_peer(int argc, char **argv)
5056 struct cYAML *err_rc = NULL, *show_rc = NULL;
5057 long int detail = 0;
5058 const char *const short_opts = "hn:v::";
5059 const struct option long_opts[] = {
5060 { .name = "help", .has_arg = no_argument, .val = 'h' },
5061 { .name = "nid", .has_arg = required_argument, .val = 'n' },
5062 { .name = "verbose", .has_arg = optional_argument, .val = 'v' },
5066 rc = check_cmd(peer_cmds, "peer", "show", 1, argc, argv);
5070 while ((opt = getopt_long(argc, argv, short_opts,
5071 long_opts, NULL)) != -1) {
5077 /* '-v' has an optional argument. Default is 1. */
5078 if (optarg || optind >= argc ||
5079 argv[optind] == NULL || argv[optind][0] == '-' ||
5080 parse_long(argv[optind++], &detail))
5084 print_help(peer_cmds, "peer", "show");
5090 rc = yaml_lnet_peer(nid, NULL, false, -1, -1, false, detail,
5091 NLM_F_DUMP, stdout);
5093 if (rc == -EOPNOTSUPP)
5098 rc = lustre_lnet_show_peer(nid, (int) detail, -1, &show_rc, &err_rc,
5101 if (rc != LUSTRE_CFG_RC_NO_ERR)
5102 cYAML_print_tree2file(stderr, err_rc);
5104 cYAML_print_tree(show_rc);
5106 cYAML_free_tree(err_rc);
5107 cYAML_free_tree(show_rc);
5112 static int jt_list_peer(int argc, char **argv)
5114 struct cYAML *err_rc = NULL, *list_rc = NULL;
5117 rc = check_cmd(peer_cmds, "peer", "list", 0, argc, argv);
5121 rc = yaml_lnet_peer(NULL, NULL, false, -1, -1, true, 0, NLM_F_DUMP,
5124 if (rc == -EOPNOTSUPP)
5130 rc = lustre_lnet_list_peer(-1, &list_rc, &err_rc);
5131 if (rc != LUSTRE_CFG_RC_NO_ERR)
5132 cYAML_print_tree2file(stderr, err_rc);
5134 cYAML_print_tree(list_rc);
5136 cYAML_free_tree(err_rc);
5137 cYAML_free_tree(list_rc);
5142 static int yaml_lnet_ping_display(yaml_parser_t *reply)
5144 yaml_emitter_t debug;
5149 rc = yaml_emitter_initialize(&debug);
5151 yaml_emitter_set_output_file(&debug, stdout);
5158 rc = yaml_parser_parse(reply, &event);
5160 goto report_reply_error;
5162 if (event.type != YAML_SCALAR_EVENT) {
5163 rc = yaml_emitter_emit(&debug, &event);
5167 done = (event.type == YAML_DOCUMENT_END_EVENT);
5171 if (strcmp((char *)event.data.scalar.value, "errno") == 0) {
5172 rc = yaml_emitter_emit(&debug, &event);
5176 rc = yaml_parser_parse(reply, &event);
5178 goto report_reply_error;
5180 rc = parse_long((char *)event.data.scalar.value,
5183 goto report_reply_error;
5185 rc = yaml_emitter_emit(&debug, &event);
5190 } else if (error != 0 &&
5191 strcmp((char *)event.data.scalar.value,
5193 rc = yaml_emitter_emit(&debug, &event);
5197 rc = yaml_parser_parse(reply, &event);
5199 goto report_reply_error;
5201 if (strncmp((char *)event.data.scalar.value,
5202 "failed to ", strlen("failed to ")) == 0) {
5205 snprintf(err, sizeof(err), "%s: %s",
5206 (char *)event.data.scalar.value,
5208 yaml_scalar_event_initialize(&event, NULL,
5209 (yaml_char_t *)YAML_STR_TAG,
5212 YAML_PLAIN_SCALAR_STYLE);
5214 rc = yaml_emitter_emit(&debug, &event);
5220 rc = yaml_emitter_emit(&debug, &event);
5227 yaml_emitter_log_error(&debug, stderr);
5229 yaml_emitter_delete(&debug);
5231 return rc2 ? rc2 : rc;
5234 static int yaml_lnet_ping(char *group, int timeout, struct lnet_nid *src_nid,
5235 int start, int end, char **nids, int flags)
5237 struct nid_node head, *entry;
5238 struct nl_sock *sk = NULL;
5239 const char *msg = NULL;
5240 yaml_emitter_t output;
5241 yaml_parser_t reply;
5245 /* Create Netlink emitter to send request to kernel */
5246 sk = nl_socket_alloc();
5250 /* Setup parser to receive Netlink packets */
5251 rc = yaml_parser_initialize(&reply);
5257 rc = yaml_parser_set_input_netlink(&reply, sk, false);
5259 msg = yaml_parser_get_reader_error(&reply);
5263 /* Create Netlink emitter to send request to kernel */
5264 rc = yaml_emitter_initialize(&output);
5266 msg = "failed to initialize emitter";
5270 rc = yaml_emitter_set_output_netlink(&output, sk, LNET_GENL_NAME,
5271 LNET_GENL_VERSION, LNET_CMD_PING,
5276 yaml_emitter_open(&output);
5277 yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
5278 rc = yaml_emitter_emit(&output, &event);
5282 yaml_mapping_start_event_initialize(&event, NULL,
5283 (yaml_char_t *)YAML_MAP_TAG,
5284 1, YAML_ANY_MAPPING_STYLE);
5285 rc = yaml_emitter_emit(&output, &event);
5289 yaml_scalar_event_initialize(&event, NULL,
5290 (yaml_char_t *)YAML_STR_TAG,
5291 (yaml_char_t *)group,
5292 strlen(group), 1, 0,
5293 YAML_PLAIN_SCALAR_STYLE);
5294 rc = yaml_emitter_emit(&output, &event);
5298 yaml_mapping_start_event_initialize(&event, NULL,
5299 (yaml_char_t *)YAML_MAP_TAG,
5300 1, YAML_ANY_MAPPING_STYLE);
5301 rc = yaml_emitter_emit(&output, &event);
5305 if (timeout != 1000 || (src_nid && nid_addr_is_set(src_nid))) {
5306 if (src_nid && nid_addr_is_set(src_nid)) {
5307 char *src_nidstr = libcfs_nidstr(src_nid);
5309 yaml_scalar_event_initialize(&event, NULL,
5310 (yaml_char_t *)YAML_STR_TAG,
5311 (yaml_char_t *)"source",
5312 strlen("source"), 1, 0,
5313 YAML_PLAIN_SCALAR_STYLE);
5314 rc = yaml_emitter_emit(&output, &event);
5318 yaml_scalar_event_initialize(&event, NULL,
5319 (yaml_char_t *)YAML_STR_TAG,
5320 (yaml_char_t *)src_nidstr,
5321 strlen(src_nidstr), 1, 0,
5322 YAML_PLAIN_SCALAR_STYLE);
5323 rc = yaml_emitter_emit(&output, &event);
5328 if (timeout != 1000) {
5331 yaml_scalar_event_initialize(&event, NULL,
5332 (yaml_char_t *)YAML_STR_TAG,
5333 (yaml_char_t *)"timeout",
5334 strlen("timeout"), 1, 0,
5335 YAML_PLAIN_SCALAR_STYLE);
5336 rc = yaml_emitter_emit(&output, &event);
5340 snprintf(time, sizeof(time), "%u", timeout);
5341 yaml_scalar_event_initialize(&event, NULL,
5342 (yaml_char_t *)YAML_INT_TAG,
5343 (yaml_char_t *)time,
5345 YAML_PLAIN_SCALAR_STYLE);
5346 rc = yaml_emitter_emit(&output, &event);
5352 yaml_scalar_event_initialize(&event, NULL,
5353 (yaml_char_t *)YAML_STR_TAG,
5354 (yaml_char_t *)"nids",
5355 strlen("nids"), 1, 0,
5356 YAML_PLAIN_SCALAR_STYLE);
5357 rc = yaml_emitter_emit(&output, &event);
5361 yaml_sequence_start_event_initialize(&event, NULL,
5362 (yaml_char_t *)YAML_SEQ_TAG,
5363 1, YAML_FLOW_SEQUENCE_STYLE);
5364 rc = yaml_emitter_emit(&output, &event);
5368 NL_INIT_LIST_HEAD(&head.children);
5369 nl_init_list_head(&head.list);
5370 for (i = start; i < end; i++) {
5371 rc = lustre_lnet_parse_nid_range(&head, nids[i], &msg);
5373 lustre_lnet_free_list(&head);
5374 yaml_emitter_delete(&output);
5381 if (nl_list_empty(&head.children))
5384 nl_list_for_each_entry(entry, &head.children, list) {
5385 yaml_scalar_event_initialize(&event, NULL,
5386 (yaml_char_t *)YAML_STR_TAG,
5387 (yaml_char_t *)entry->nidstr,
5388 strlen(entry->nidstr), 1, 0,
5389 YAML_PLAIN_SCALAR_STYLE);
5390 rc = yaml_emitter_emit(&output, &event);
5395 yaml_sequence_end_event_initialize(&event);
5396 rc = yaml_emitter_emit(&output, &event);
5400 yaml_mapping_end_event_initialize(&event);
5401 rc = yaml_emitter_emit(&output, &event);
5405 yaml_mapping_end_event_initialize(&event);
5406 rc = yaml_emitter_emit(&output, &event);
5410 yaml_document_end_event_initialize(&event, 0);
5411 rc = yaml_emitter_emit(&output, &event);
5415 rc = yaml_emitter_close(&output);
5418 yaml_emitter_log_error(&output, stderr);
5421 rc = yaml_lnet_ping_display(&reply);
5423 msg = yaml_parser_get_reader_error(&reply);
5425 yaml_emitter_delete(&output);
5428 yaml_lnet_print_error(-1, group, msg);
5432 yaml_parser_delete(&reply);
5435 return rc == 1 ? 0 : rc;
5438 static int jt_ping(int argc, char **argv)
5440 struct cYAML *err_rc = NULL;
5441 struct cYAML *show_rc = NULL;
5442 struct lnet_nid src = { };
5445 char *src_nidstr = NULL;
5446 const char *const short_options = "hs:t:";
5447 const struct option long_options[] = {
5448 { .name = "help", .has_arg = no_argument, .val = 'h' },
5449 { .name = "timeout", .has_arg = required_argument, .val = 't' },
5450 { .name = "source", .has_arg = required_argument, .val = 's' },
5454 while ((opt = getopt_long(argc, argv, short_options,
5455 long_options, NULL)) != -1) {
5458 src_nidstr = optarg;
5459 rc = libcfs_strnid(&src, src_nidstr);
5462 timeout = 1000 * atol(optarg);
5465 printf("ping nid[,nid,...]\n"
5466 "\t --source: source nid\n"
5467 "\t --timeout: ping timeout\n"
5468 "\t --help: display this help\n");
5477 rc = yaml_lnet_ping("ping", timeout, &src, optind, argc, argv,
5480 if (rc != -EOPNOTSUPP)
5484 for (; optind < argc; optind++) {
5487 rc2 = lustre_lnet_ping_nid(argv[optind], src_nidstr, timeout,
5488 -1, &show_rc, &err_rc);
5489 if (rc2 != 0 && (rc > 0 || rc == -EOPNOTSUPP))
5494 cYAML_print_tree(show_rc);
5497 cYAML_print_tree2file(stderr, err_rc);
5499 cYAML_free_tree(err_rc);
5500 cYAML_free_tree(show_rc);
5505 static int jt_discover(int argc, char **argv)
5507 struct cYAML *err_rc = NULL;
5508 struct cYAML *show_rc = NULL;
5509 int flags = NLM_F_CREATE;
5512 const char *const short_options = "fh";
5513 const struct option long_options[] = {
5514 { .name = "force", .has_arg = no_argument, .val = 'f' },
5515 { .name = "help", .has_arg = no_argument, .val = 'h' },
5519 while ((opt = getopt_long(argc, argv, short_options,
5520 long_options, NULL)) != -1) {
5523 /* BSD treats NLM_F_CREATE | NLM_F_EXCL as an add */
5524 flags |= NLM_F_EXCL;
5528 printf("discover nid[,nid,...]\n"
5529 "\t --force: force discovery\n"
5530 "\t --help: display this help\n");
5537 if (optind == argc) {
5538 printf("Missing nid argument\n");
5542 rc = yaml_lnet_ping("discover", 1000, NULL, optind, argc, argv,
5545 if (rc != -EOPNOTSUPP)
5549 for (; optind < argc; optind++)
5550 rc = lustre_lnet_discover_nid(argv[optind], force, -1, &show_rc,
5554 cYAML_print_tree(show_rc);
5557 cYAML_print_tree2file(stderr, err_rc);
5559 cYAML_free_tree(err_rc);
5560 cYAML_free_tree(show_rc);
5565 static int jt_add_udsp(int argc, char **argv)
5567 char *src = NULL, *dst = NULL, *rte = NULL;
5568 struct cYAML *err_rc = NULL;
5569 union lnet_udsp_action udsp_action;
5570 long int idx = -1, priority = -1;
5572 char *action_type = "pref";
5574 const char *const short_options = "s:d:r:p:i:";
5575 static const struct option long_options[] = {
5576 { .name = "src", .has_arg = required_argument, .val = 's' },
5577 { .name = "dst", .has_arg = required_argument, .val = 'd' },
5578 { .name = "rte", .has_arg = required_argument, .val = 'r' },
5579 { .name = "priority", .has_arg = required_argument, .val = 'p' },
5580 { .name = "idx", .has_arg = required_argument, .val = 'i' },
5583 rc = check_cmd(udsp_cmds, "udsp", "add", 0, argc, argv);
5587 while ((opt = getopt_long(argc, argv, short_options,
5588 long_options, NULL)) != -1) {
5600 rc = parse_long(optarg, &priority);
5601 if (rc != 0 || priority < 0) {
5602 printf("Invalid priority \"%s\"\n", optarg);
5605 action_type = "priority";
5606 udsp_action.udsp_priority = priority;
5609 rc = parse_long(optarg, &idx);
5610 if (rc != 0 || idx < 0) {
5611 printf("Invalid index \"%s\"\n", optarg);
5616 print_help(udsp_cmds, "udsp", "add");
5622 if (!(src || dst || rte)) {
5623 print_help(udsp_cmds, "udsp", "add");
5627 rc = lustre_lnet_add_udsp(src, dst, rte, action_type, &udsp_action,
5630 if (rc != LUSTRE_CFG_RC_NO_ERR)
5631 cYAML_print_tree2file(stderr, err_rc);
5633 cYAML_free_tree(err_rc);
5638 static int jt_del_udsp(int argc, char **argv)
5640 struct cYAML *err_rc = NULL;
5645 const char *const short_options = "ai:";
5646 static const struct option long_options[] = {
5647 { .name = "all", .has_arg = no_argument, .val = 'a' },
5648 { .name = "idx", .has_arg = required_argument, .val = 'i' },
5651 rc = check_cmd(udsp_cmds, "udsp", "del", 0, argc, argv);
5655 while ((opt = getopt_long(argc, argv, short_options,
5656 long_options, NULL)) != -1) {
5662 rc = parse_long(optarg, &idx);
5663 if (rc != 0 || idx < -1) {
5664 printf("Invalid index \"%s\"\n", optarg);
5669 print_help(udsp_cmds, "udsp", "del");
5675 if (all && idx != -2) {
5676 printf("Cannot combine --all with --idx\n");
5680 } else if (idx == -2) {
5681 printf("Must specify --idx or --all\n");
5685 rc = lustre_lnet_del_udsp(idx, -1, &err_rc);
5686 if (rc != LUSTRE_CFG_RC_NO_ERR)
5687 cYAML_print_tree2file(stderr, err_rc);
5689 cYAML_free_tree(err_rc);
5695 fault_attr_health_error_parse(char *error, __u32 *mask)
5697 if (!strcasecmp(error, "local_interrupt")) {
5698 *mask |= HSTATUS_LOCAL_INTERRUPT_BIT;
5701 if (!strcasecmp(error, "local_dropped")) {
5702 *mask |= HSTATUS_LOCAL_DROPPED_BIT;
5705 if (!strcasecmp(error, "local_aborted")) {
5706 *mask |= HSTATUS_LOCAL_ABORTED_BIT;
5709 if (!strcasecmp(error, "local_no_route")) {
5710 *mask |= HSTATUS_LOCAL_NO_ROUTE_BIT;
5713 if (!strcasecmp(error, "local_error")) {
5714 *mask |= HSTATUS_LOCAL_ERROR_BIT;
5717 if (!strcasecmp(error, "local_timeout")) {
5718 *mask |= HSTATUS_LOCAL_TIMEOUT_BIT;
5721 if (!strcasecmp(error, "remote_error")) {
5722 *mask |= HSTATUS_REMOTE_ERROR_BIT;
5725 if (!strcasecmp(error, "remote_dropped")) {
5726 *mask |= HSTATUS_REMOTE_DROPPED_BIT;
5729 if (!strcasecmp(error, "remote_timeout")) {
5730 *mask |= HSTATUS_REMOTE_TIMEOUT_BIT;
5733 if (!strcasecmp(error, "network_timeout")) {
5734 *mask |= HSTATUS_NETWORK_TIMEOUT_BIT;
5737 if (!strcasecmp(error, "random")) {
5738 *mask = HSTATUS_RANDOM;
5746 fault_attr_msg_parse(char *msg_str, __u32 *mask_p)
5748 if (!strcasecmp(msg_str, "put")) {
5749 *mask_p |= LNET_PUT_BIT;
5752 } else if (!strcasecmp(msg_str, "ack")) {
5753 *mask_p |= LNET_ACK_BIT;
5756 } else if (!strcasecmp(msg_str, "get")) {
5757 *mask_p |= LNET_GET_BIT;
5760 } else if (!strcasecmp(msg_str, "reply")) {
5761 *mask_p |= LNET_REPLY_BIT;
5765 fprintf(stderr, "unknown message type %s\n", msg_str);
5770 fault_attr_ptl_parse(char *ptl_str, __u64 *mask_p)
5772 unsigned long rc = strtoul(optarg, NULL, 0);
5775 fprintf(stderr, "invalid portal: %lu\n", rc);
5779 *mask_p |= (1ULL << rc);
5783 static int jt_fault_add(__u32 opc, int argc, char **argv)
5785 static const struct option long_options[] = {
5786 { .name = "dest", .has_arg = required_argument, .val = 'd' },
5787 { .name = "health_error", .has_arg = required_argument, .val = 'e' },
5788 { .name = "interval", .has_arg = required_argument, .val = 'i' },
5789 { .name = "latency", .has_arg = required_argument, .val = 'l' },
5790 { .name = "message", .has_arg = required_argument, .val = 'm' },
5791 { .name = "random", .has_arg = no_argument, .val = 'n' },
5792 { .name = "local_nid", .has_arg = required_argument, .val = 'o' },
5793 { .name = "portal", .has_arg = required_argument, .val = 'p' },
5794 { .name = "rate", .has_arg = required_argument, .val = 'r' },
5795 { .name = "source", .has_arg = required_argument, .val = 's' },
5796 { .name = "rule_type", .has_arg = required_argument, .val = 't' },
5797 { .name = "drop_all", .has_arg = no_argument, .val = 'x' },
5801 char *fa_src = NULL, *fa_dst = NULL, *fa_local_nid = NULL;
5803 struct lnet_fault_attr attr;
5804 yaml_document_t results;
5805 yaml_emitter_t debug;
5807 if (opc == LNET_CTL_DROP_ADD) {
5808 optstr = "d:e:i:m:no:p:r:s:t:x";
5810 rc = check_cmd(fault_drop_cmds, "drop", "add", 2, argc, argv);
5812 optstr = "d:l:m:o:p:r:s:";
5814 rc = check_cmd(fault_delay_cmds, "delay", "add", 2, argc, argv);
5820 memset(&attr, 0, sizeof(attr));
5821 while ((opt = getopt_long(argc, argv, optstr,
5822 long_options, NULL)) != -1) {
5824 case 'd': /* dest NID/NET */
5828 if (opc == LNET_CTL_DROP_ADD) {
5829 rc = fault_attr_health_error_parse(optarg,
5830 &attr.u.drop.da_health_error_mask);
5835 case 'i': /* time interval (# seconds) for message drop */
5836 if (opc == LNET_CTL_DROP_ADD)
5837 attr.u.drop.da_interval = strtoul(optarg,
5840 attr.u.delay.la_interval = strtoul(optarg,
5843 case 'l': /* seconds to wait before activating rule */
5844 attr.u.delay.la_latency = strtoul(optarg, NULL, 0);
5846 case 'm': /* message types to filter */
5847 rc = fault_attr_msg_parse(optarg, &attr.fa_msg_mask);
5852 if (opc == LNET_CTL_DROP_ADD)
5853 attr.u.drop.da_random = true;
5856 fa_local_nid = optarg;
5858 case 'p': /* portal to filter */
5859 rc = fault_attr_ptl_parse(optarg, &attr.fa_ptl_mask);
5863 case 'r': /* drop rate */
5864 if (opc == LNET_CTL_DROP_ADD)
5865 attr.u.drop.da_rate = strtoul(optarg, NULL, 0);
5867 attr.u.delay.la_rate = strtoul(optarg, NULL, 0);
5869 case 's': /* source NID/NET */
5873 /* Handled by our caller */
5876 if (opc == LNET_CTL_DROP_ADD)
5877 attr.u.drop.da_drop_all = true;
5880 fprintf(stderr, "Unrecognized option %c\n", opt);
5883 fprintf(stderr, "Unrecognized character %c\n", opt);
5888 if (opc == LNET_CTL_DROP_ADD) {
5889 /* NB: drop rate and interval are exclusive to each other */
5890 if (!((attr.u.drop.da_rate == 0) ^
5891 (attr.u.drop.da_interval == 0))) {
5893 "please provide either drop rate or interval but not both at the same time.\n");
5897 if (attr.u.drop.da_random &&
5898 attr.u.drop.da_interval == 0) {
5900 "please provide an interval to randomize\n");
5903 } else if (opc == LNET_CTL_DELAY_ADD) {
5904 if (!((attr.u.delay.la_rate == 0) ^
5905 (attr.u.delay.la_interval == 0))) {
5907 "please provide either delay rate or interval but not both at the same time.\n");
5911 if (attr.u.delay.la_latency == 0) {
5912 fprintf(stderr, "latency cannot be zero\n");
5917 if (!(fa_src && fa_dst)) {
5919 "Please provide both source and destination of %s rule\n",
5924 rc = yaml_lnet_fault_rule(&results, opc, fa_src, fa_dst, fa_local_nid,
5929 rc = yaml_emitter_initialize(&debug);
5933 yaml_emitter_set_indent(&debug, LNET_DEFAULT_INDENT);
5934 yaml_emitter_set_output_file(&debug, stdout);
5935 rc = yaml_emitter_dump(&debug, &results);
5937 yaml_emitter_delete(&debug);
5938 yaml_document_delete(&results);
5940 return rc == 0 ? -EINVAL : 0;
5947 static int jt_fault_drop_add(int argc, char **argv)
5949 return jt_fault_add(LNET_CTL_DROP_ADD, argc, argv);
5952 static int jt_fault_delay_add(int argc, char **argv)
5954 return jt_fault_add(LNET_CTL_DELAY_ADD, argc, argv);
5957 static int jt_fault_del_common(__u32 opc, int argc, char **argv)
5959 const char *const short_options = "ad:s:";
5960 static const struct option long_options[] = {
5961 { .name = "all", .has_arg = no_argument, .val = 'a' },
5962 { .name = "dest", .has_arg = required_argument, .val = 'd' },
5963 { .name = "source", .has_arg = required_argument, .val = 's' },
5966 yaml_document_t results;
5967 yaml_emitter_t debug;
5968 char *fa_src = NULL, *fa_dst = NULL;
5972 if (opc == LNET_CTL_DROP_DEL)
5973 rc = check_cmd(fault_drop_cmds, "drop", "del", 2, argc, argv);
5975 rc = check_cmd(fault_delay_cmds, "delay", "del", 2, argc, argv);
5980 while ((opt = getopt_long(argc, argv, short_options,
5981 long_options, NULL)) != -1) {
5985 case 'd': /* dest NID/NET */
5988 case 's': /* source NID/NET */
5996 if (!all && !(fa_src && fa_dst)) {
5998 "Failed, please provide source and destination of rule\n");
6000 } else if (all && (fa_src || fa_dst)) {
6001 fprintf(stderr, "'-s' or '-d' cannot be combined with '-a'\n");
6005 rc = yaml_lnet_fault_rule(&results, opc, fa_src, fa_dst, NULL, NULL);
6009 rc = yaml_emitter_initialize(&debug);
6013 yaml_emitter_set_indent(&debug, LNET_DEFAULT_INDENT);
6014 yaml_emitter_set_output_file(&debug, stdout);
6015 rc = yaml_emitter_dump(&debug, &results);
6016 yaml_emitter_delete(&debug);
6017 yaml_document_delete(&results);
6019 return rc == 0 ? -EINVAL : 0;
6022 static int jt_fault_drop_del(int argc, char **argv)
6024 return jt_fault_del_common(LNET_CTL_DROP_DEL, argc, argv);
6027 static int jt_fault_delay_del(int argc, char **argv)
6029 return jt_fault_del_common(LNET_CTL_DELAY_DEL, argc, argv);
6032 static int jt_fault_reset_common(__u32 opc, int argc, char **argv)
6034 yaml_document_t results;
6035 yaml_emitter_t debug;
6038 if (opc == LNET_CTL_DROP_RESET)
6039 rc = check_cmd(fault_drop_cmds, "drop", "reset", 2, argc, argv);
6041 rc = check_cmd(fault_delay_cmds, "delay", "reset", 2, argc,
6046 rc = yaml_lnet_fault_rule(&results, opc, NULL, NULL, NULL, NULL);
6050 rc = yaml_emitter_initialize(&debug);
6054 yaml_emitter_set_indent(&debug, LNET_DEFAULT_INDENT);
6055 yaml_emitter_set_output_file(&debug, stdout);
6056 rc = yaml_emitter_dump(&debug, &results);
6057 yaml_emitter_delete(&debug);
6058 yaml_document_delete(&results);
6060 return rc == 0 ? -EINVAL : 0;
6063 static int jt_fault_drop_reset(int argc, char **argv)
6065 return jt_fault_reset_common(LNET_CTL_DROP_RESET, argc, argv);
6068 static int jt_fault_delay_reset(int argc, char **argv)
6070 return jt_fault_reset_common(LNET_CTL_DELAY_RESET, argc, argv);
6073 static int jt_fault_show_common(__u32 opc, int argc, char **argv)
6075 yaml_document_t results;
6076 yaml_emitter_t debug;
6079 if (opc == LNET_CTL_DROP_LIST)
6080 rc = check_cmd(fault_drop_cmds, "drop", "show", 1, argc, argv);
6082 rc = check_cmd(fault_delay_cmds, "delay", "show", 1, argc,
6087 rc = yaml_lnet_fault_rule(&results, opc, NULL, NULL, NULL, NULL);
6091 rc = yaml_emitter_initialize(&debug);
6095 yaml_emitter_set_indent(&debug, LNET_DEFAULT_INDENT);
6096 yaml_emitter_set_output_file(&debug, stdout);
6097 rc = yaml_emitter_dump(&debug, &results);
6099 yaml_emitter_delete(&debug);
6100 yaml_document_delete(&results);
6102 return rc == 0 ? -EINVAL : 0;
6105 static int jt_fault_drop_show(int argc, char **argv)
6107 return jt_fault_show_common(LNET_CTL_DROP_LIST, argc, argv);
6110 static int jt_fault_delay_show(int argc, char **argv)
6112 return jt_fault_show_common(LNET_CTL_DELAY_LIST, argc, argv);
6115 int main(int argc, char **argv)
6118 struct cYAML *err_rc = NULL;
6120 rc = lustre_lnet_config_lib_init();
6122 cYAML_build_error(-1, -1, "lnetctl", "startup",
6123 "cannot register LNet device", &err_rc);
6124 cYAML_print_tree2file(stderr, err_rc);
6128 return cfs_parser(argc, argv, cmd_list);