1 // SPDX-License-Identifier: LGPL-2.0
4 * Copyright (c) 2014, 2017, Intel Corporation.
8 * This file is part of Lustre, http://www.lustre.org/
10 * Author: Amir Shehata <amir.shehata@intel.com>
19 #include <libcfs/util/ioctl.h>
20 #include <libcfs/util/parser.h>
21 #include "lnetconfig/cyaml.h"
22 #include "lnetconfig/liblnetconfig.h"
24 #define LNET_CONFIGURE true
25 #define LNET_UNCONFIGURE false
27 #ifndef NLM_F_DUMP_FILTERED
28 #define NLM_F_DUMP_FILTERED 0x20
31 static int jt_config_lnet(int argc, char **argv);
32 static int jt_unconfig_lnet(int argc, char **argv);
33 static int jt_add_route(int argc, char **argv);
34 static int jt_add_ni(int argc, char **argv);
35 static int jt_set_routing(int argc, char **argv);
36 static int jt_del_route(int argc, char **argv);
37 static int jt_del_ni(int argc, char **argv);
38 static int jt_show_route(int argc, char **argv);
39 static int jt_show_net(int argc, char **argv);
40 static int jt_show_routing(int argc, char **argv);
41 static int jt_show_stats(int argc, char **argv);
42 static int jt_show_peer(int argc, char **argv);
43 static int jt_show_recovery(int argc, char **argv);
44 static int jt_show_global(int argc, char **argv);
45 static int jt_show_udsp(int argc, char **argv);
46 static int jt_set_tiny(int argc, char **argv);
47 static int jt_set_small(int argc, char **argv);
48 static int jt_set_large(int argc, char **argv);
49 static int jt_set_numa(int argc, char **argv);
50 static int jt_set_retry_count(int argc, char **argv);
51 static int jt_set_transaction_to(int argc, char **argv);
52 static int jt_set_recov_intrv(int argc, char **argv);
53 static int jt_set_rtr_sensitivity(int argc, char **argv);
54 static int jt_set_hsensitivity(int argc, char **argv);
55 static int jt_set_max_recovery_ping_interval(int argc, char **argv);
56 static int jt_reset_stats(int argc, char **argv);
57 static int jt_add_peer_nid(int argc, char **argv);
58 static int jt_del_peer_nid(int argc, char **argv);
59 static int jt_set_max_intf(int argc, char **argv);
60 static int jt_set_discovery(int argc, char **argv);
61 static int jt_set_drop_asym_route(int argc, char **argv);
62 static int jt_list_peer(int argc, char **argv);
63 static int jt_add_udsp(int argc, char **argv);
64 static int jt_del_udsp(int argc, char **argv);
65 /*static int jt_show_peer(int argc, char **argv);*/
66 static int jt_import(int argc, char **argv);
67 static int jt_export(int argc, char **argv);
68 static int jt_ping(int argc, char **argv);
69 static int jt_discover(int argc, char **argv);
70 static int jt_lnet(int argc, char **argv);
71 static int jt_route(int argc, char **argv);
72 static int jt_net(int argc, char **argv);
73 static int jt_routing(int argc, char **argv);
74 static int jt_set(int argc, char **argv);
75 static int jt_debug(int argc, char **argv);
76 static int jt_stats(int argc, char **argv);
77 static int jt_global(int argc, char **argv);
78 static int jt_peers(int argc, char **argv);
79 static int jt_set_ni_value(int argc, char **argv);
80 static int jt_set_peer_ni_value(int argc, char **argv);
81 static int jt_calc_service_id(int argc, char **argv);
82 static int jt_set_response_tracking(int argc, char **argv);
83 static int jt_set_recovery_limit(int argc, char **argv);
84 static int jt_udsp(int argc, char **argv);
85 static int jt_setup_mrrouting(int argc, char **argv);
86 static int jt_calc_cpt_of_nid(int argc, char **argv);
87 static int jt_show_peer_debug_info(int argc, char **argv);
89 command_t cmd_list[] = {
90 {"lnet", jt_lnet, 0, "lnet {configure | unconfigure} [--all|--large]"},
91 {"route", jt_route, 0, "route {add | del | show | help}"},
92 {"net", jt_net, 0, "net {add | del | show | set | help}"},
93 {"routing", jt_routing, 0, "routing {show | help}"},
94 {"set", jt_set, 0, "set {tiny_buffers | small_buffers | large_buffers"
95 " | routing | numa_range | max_interfaces"
96 " | discovery | drop_asym_route | retry_count"
97 " | transaction_timeout | health_sensitivity"
98 " | recovery_interval | router_sensitivity"
99 " | response_tracking | recovery_limit}"},
100 {"import", jt_import, 0, "import FILE.yaml"},
101 {"export", jt_export, 0, "export FILE.yaml"},
102 {"stats", jt_stats, 0, "stats {show | help}"},
103 {"debug", jt_debug, 0, "debug {recovery {local | peer} | peer}"},
104 {"global", jt_global, 0, "global {show | help}"},
105 {"peer", jt_peers, 0, "peer {add | del | show | list | set | help}"},
106 {"ping", jt_ping, 0, "ping nid,[nid,...]"},
107 {"discover", jt_discover, 0, "discover nid[,nid,...]"},
108 {"service-id", jt_calc_service_id, 0, "Calculate IB Lustre service ID\n"},
109 {"udsp", jt_udsp, 0, "udsp {add | del | help}"},
110 {"setup-mrrouting", jt_setup_mrrouting, 0,
111 "setup linux routing tables\n"},
112 {"cpt-of-nid", jt_calc_cpt_of_nid, 0,
113 "Calculate the CPTs associated with NIDs\n"
114 " usage:\n\tlnetctl cpt-of-nid nid[ nid ...]\n"},
118 command_t lnet_cmds[] = {
119 {"configure", jt_config_lnet, 0, "configure lnet\n"
120 "\t--all: load NI configuration from module parameters\n"
121 "\t--large: start LNet with large NIDs\n"},
122 {"unconfigure", jt_unconfig_lnet, 0, "unconfigure lnet\n"},
126 command_t route_cmds[] = {
127 {"add", jt_add_route, 0, "add a route\n"
128 "\t--net: net name (e.g. tcp0)\n"
129 "\t--gateway: gateway nid (e.g. 10.1.1.2@tcp)\n"
130 "\t--hop|hop-count: number to final destination (1 <= hops <= 255)\n"
131 "\t--priority: priority of route (0 - highest prio\n"
132 "\t--health_sensitivity: gateway health sensitivity (>= 1)\n"},
133 {"del", jt_del_route, 0, "delete a route\n"
134 "\t--net: net name (e.g. tcp0)\n"
135 "\t--gateway: gateway nid (e.g. 10.1.1.2@tcp)\n"},
136 {"show", jt_show_route, 0, "show routes\n"
137 "\t--net: net name (e.g. tcp0) to filter on\n"
138 "\t--gateway: gateway nid (e.g. 10.1.1.2@tcp) to filter on\n"
139 "\t--hop|hop-count: number to final destination (1 <= hops <= 255) to filter on\n"
140 "\t--priority: priority of route (0 - highest prio to filter on\n"
141 "\t--verbose: display detailed output per route\n"},
145 command_t net_cmds[] = {
146 {"add", jt_add_ni, 0, "add a network\n"
147 "\t--net: net name (e.g. tcp0)\n"
148 "\t--if: physical interface (e.g. eth0)\n"
149 "\t--nid: bring up NI based on the address of the specified LNet NID\n"
150 "\t--ip2net: specify networks based on IP address patterns\n"
151 "\t--peer-timeout: time to wait before declaring a peer dead\n"
152 "\t--peer-credits: define the max number of inflight messages\n"
153 "\t--peer-buffer-credits: the number of buffer credits per peer\n"
154 "\t--credits: Network Interface credits\n"
155 "\t--cpt: CPU Partitions configured net uses (e.g. [0,1]\n"
156 "\t--conns-per-peer: number of connections per peer\n"
157 "\t--skip-mr-route-setup: do not add linux route for the ni\n"
158 "\t--auth-key: Network authorization key (kfilnd only)\n"
159 "\t--traffic-class: Traffic class (kfilnd only)\n"
160 "\t--tos: IP's Type of Service\n"},
161 {"del", jt_del_ni, 0, "delete a network\n"
162 "\t--net: net name (e.g. tcp0)\n"
163 "\t--nid: shutdown NI based on the address of the specified LNet NID\n"
164 "\t--if: physical interface (e.g. eth0)\n"},
165 {"show", jt_show_net, 0, "show networks\n"
166 "\t--net: net name (e.g. tcp0) to filter on\n"
167 "\t--verbose: display detailed output per network."
168 " Optional argument of '2' outputs more stats\n"},
169 {"set", jt_set_ni_value, 0, "set local NI specific parameter\n"
170 "\t--nid: NI NID to set the\n"
171 "\t--health: specify health value to set\n"
172 "\t--conns-per-peer: number of connections per peer\n"
173 "\t--all: set all NIs value to the one specified\n"},
177 command_t routing_cmds[] = {
178 {"show", jt_show_routing, 0, "show routing information\n"},
182 command_t stats_cmds[] = {
183 {"show", jt_show_stats, 0, "show LNET statistics\n"},
184 {"reset", jt_reset_stats, 0, "reset LNET statistics\n"},
188 command_t debug_cmds[] = {
189 {"recovery", jt_show_recovery, 0, "list recovery queues\n"
190 "\t--local : list local recovery queue\n"
191 "\t--peer : list peer recovery queue\n"},
192 {"peer", jt_show_peer_debug_info, 0, "show peer debug info\n"
193 "\t--nid: peer's NID\n"},
197 command_t global_cmds[] = {
198 {"show", jt_show_global, 0, "show global variables\n"},
202 command_t set_cmds[] = {
203 {"tiny_buffers", jt_set_tiny, 0, "set tiny routing buffers\n"
204 "\tVALUE must be greater than 0\n"},
205 {"small_buffers", jt_set_small, 0, "set small routing buffers\n"
206 "\tVALUE must be greater than 0\n"},
207 {"large_buffers", jt_set_large, 0, "set large routing buffers\n"
208 "\tVALUE must be greater than 0\n"},
209 {"routing", jt_set_routing, 0, "enable/disable routing\n"
210 "\t0 - disable routing\n"
211 "\t1 - enable routing\n"},
212 {"numa_range", jt_set_numa, 0, "set NUMA range for NI selection\n"
213 "\tVALUE must be at least 0\n"},
214 {"max_interfaces", jt_set_max_intf, 0, "set the default value for "
216 "\tValue must be greater than 16\n"},
217 {"discovery", jt_set_discovery, 0, "enable/disable peer discovery\n"
218 "\t0 - disable peer discovery\n"
219 "\t1 - enable peer discovery (default)\n"},
220 {"drop_asym_route", jt_set_drop_asym_route, 0,
221 "drop/accept asymmetrical route messages\n"
222 "\t0 - accept asymmetrical route messages (default)\n"
223 "\t1 - drop asymmetrical route messages\n"},
224 {"retry_count", jt_set_retry_count, 0, "number of retries\n"
225 "\t0 - turn of retries\n"
226 "\t>0 - number of retries\n"},
227 {"transaction_timeout", jt_set_transaction_to, 0, "Message/Response timeout\n"
228 "\t>0 - timeout in seconds\n"},
229 {"health_sensitivity", jt_set_hsensitivity, 0, "sensitivity to failure\n"
230 "\t0 - turn off health evaluation\n"
231 "\t>0 - sensitivity value not more than 1000\n"},
232 {"recovery_interval", jt_set_recov_intrv, 0, "interval to ping in seconds (at least 1)\n"
233 "\t>0 - time in seconds between pings\n"},
234 {"router_sensitivity", jt_set_rtr_sensitivity, 0, "router sensitivity %\n"
235 "\t100 - router interfaces need to be fully healthy to be used\n"
236 "\t<100 - router interfaces can be used even if not healthy\n"},
237 {"response_tracking", jt_set_response_tracking, 0,
238 "Set the behavior of response tracking\n"
239 "\t0 - Only LNet pings and discovery pushes utilize response tracking\n"
240 "\t1 - GETs are eligible for response tracking\n"
241 "\t2 - PUTs are eligible for response tracking\n"
242 "\t3 - Both PUTs and GETs are eligible for response tracking (default)\n"
243 "\tNote: Regardless of the value of the response_tracking parameter LNet\n"
244 "\t pings and discovery pushes always utilize response tracking\n"},
245 {"recovery_limit", jt_set_recovery_limit, 0,
246 "Set how long LNet will attempt to recover unhealthy interfaces.\n"
247 "\t0 - Recover indefinitely (default)\n"
248 "\t>0 - Recover for the specified number of seconds.\n"},
249 {"max_recovery_ping_interval", jt_set_max_recovery_ping_interval, 0,
250 "maximum recovery ping interval\n"
251 "\t>0 - maximum recovery ping interval in seconds\n"},
255 command_t peer_cmds[] = {
256 {"add", jt_add_peer_nid, 0, "add a peer NID\n"
257 "\t--prim_nid: Primary NID of the peer.\n"
258 "\t--nid: one or more peer NIDs\n"
259 "\t--non_mr: create this peer as not Multi-Rail capable\n"
260 "\t--ip2nets: specify a range of nids per peer\n"
261 "\t--lock_prim: lock primary nid\n"},
262 {"del", jt_del_peer_nid, 0, "delete a peer NID\n"
263 "\t--prim_nid: Primary NID of the peer.\n"
264 "\t--nid: list of NIDs to remove. If none provided,\n"
265 "\t peer is deleted\n"
266 "\t--ip2nets: specify a range of nids per peer\n"
267 "\t--force: force-delete locked primary NID\n"},
268 {"show", jt_show_peer, 0, "show peer information\n"
269 "\t--nid: NID of peer to filter on.\n"
270 "\t--verbose: display detailed output per peer."
271 " Optional argument of '2' outputs more stats\n"},
272 {"list", jt_list_peer, 0, "list all peers\n"},
273 {"set", jt_set_peer_ni_value, 0, "set peer ni specific parameter\n"
274 "\t--nid: Peer NI NID to set the\n"
275 "\t--health: specify health value to set\n"
276 "\t--all: set all peer_nis values to the one specified\n"
277 "\t--state: set peer state (DANGEROUS: for test/debug only)"},
281 command_t udsp_cmds[] = {
282 {"add", jt_add_udsp, 0, "add a udsp\n"
283 "\t--src nid|net: ip2nets syntax specifying the local NID or network to match.\n"
284 "\t--dst nid: ip2nets syntax specifying the remote NID to match.\n"
285 "\t--rte nid: ip2nets syntax specifying the router NID to match.\n"
286 "\t--priority p: Assign priority value p where p >= 0.\n"
287 "\t Note: 0 is the highest priority.\n"
288 "\t--idx n: Insert the rule in the n'th position on the list of rules.\n"
289 "\t By default, rules are appended to the end of the rule list.\n"},
290 {"del", jt_del_udsp, 0, "delete a udsp\n"
291 "\t--all: Delete all rules.\n"
292 "\t--idx n: Delete the rule at index n.\n"},
293 {"show", jt_show_udsp, 0, "show udsps\n"
294 "\t--idx n: Show the rule at at index n.\n"
295 "\t By default, all rules are shown.\n"},
299 static int parse_long(const char *number, long int *value)
306 *value = strtol(number, &end, 0);
307 if (end != NULL && *end != 0)
313 static int jt_setup_mrrouting(int argc, char **argv)
316 struct cYAML *err_rc = NULL;
318 rc = lustre_lnet_setup_mrrouting(&err_rc);
320 if (rc != LUSTRE_CFG_RC_NO_ERR)
321 cYAML_print_tree2file(stderr, err_rc);
323 cYAML_free_tree(err_rc);
328 static inline void print_help(const command_t cmds[], const char *cmd_type,
331 const command_t *cmd;
333 for (cmd = cmds; cmd->pc_name; cmd++) {
334 if (pc_name != NULL &&
335 strcmp(cmd->pc_name, pc_name) == 0) {
336 printf("%s %s: %s\n", cmd_type, cmd->pc_name,
339 } else if (pc_name != NULL) {
342 printf("%s %s: %s\n", cmd_type, cmd->pc_name, cmd->pc_help);
346 static int check_cmd(const command_t *cmd_list, const char *cmd,
347 const char *sub_cmd, const int min_args,
348 int argc, char **argv)
355 const char *const short_options = "h";
356 static const struct option long_options[] = {
357 { .name = "help", .has_arg = no_argument, .val = 'h' },
361 if (argc < min_args) {
362 print_help(cmd_list, cmd, sub_cmd);
363 rc = LUSTRE_CFG_RC_BAD_PARAM;
365 } else if (argc > 2) {
369 while ((opt = getopt_long(argc, argv, short_options,
370 long_options, NULL)) != -1) {
373 print_help(cmd_list, cmd, sub_cmd);
388 static int jt_set_response_tracking(int argc, char **argv)
392 struct cYAML *err_rc = NULL;
394 rc = check_cmd(set_cmds, "set", "response_tracking", 2, argc, argv);
398 rc = parse_long(argv[1], &value);
400 cYAML_build_error(-1, -1, "parser", "set",
401 "cannot parse response_tracking value",
403 cYAML_print_tree2file(stderr, err_rc);
404 cYAML_free_tree(err_rc);
408 rc = lustre_lnet_config_response_tracking(value, -1, &err_rc);
409 if (rc != LUSTRE_CFG_RC_NO_ERR)
410 cYAML_print_tree2file(stderr, err_rc);
412 cYAML_free_tree(err_rc);
417 static int jt_calc_service_id(int argc, char **argv)
422 rc = lustre_lnet_calc_service_id(&service_id);
423 if (rc != LUSTRE_CFG_RC_NO_ERR)
426 /* cYAML currently doesn't support printing hex values.
427 * Therefore just print it locally here
429 printf("service_id:\n value: 0x%llx\n",
430 (unsigned long long)(service_id));
435 static int jt_set_recovery_limit(int argc, char **argv)
439 struct cYAML *err_rc = NULL;
441 rc = check_cmd(set_cmds, "set", "recovery_limit", 2, argc, argv);
445 rc = parse_long(argv[1], &value);
447 cYAML_build_error(-1, -1, "parser", "set",
448 "cannot parse recovery_limit value",
450 cYAML_print_tree2file(stderr, err_rc);
451 cYAML_free_tree(err_rc);
455 rc = lustre_lnet_config_recovery_limit(value, -1, &err_rc);
456 if (rc != LUSTRE_CFG_RC_NO_ERR)
457 cYAML_print_tree2file(stderr, err_rc);
459 cYAML_free_tree(err_rc);
464 static int jt_set_max_intf(int argc, char **argv)
468 struct cYAML *err_rc = NULL;
470 rc = check_cmd(set_cmds, "set", "max_interfaces", 2, argc, argv);
474 rc = parse_long(argv[1], &value);
476 cYAML_build_error(-1, -1, "parser", "set",
477 "cannot parse max_interfaces value", &err_rc);
478 cYAML_print_tree2file(stderr, err_rc);
479 cYAML_free_tree(err_rc);
483 rc = lustre_lnet_config_max_intf(value, -1, &err_rc);
484 if (rc != LUSTRE_CFG_RC_NO_ERR)
485 cYAML_print_tree2file(stderr, err_rc);
487 cYAML_free_tree(err_rc);
492 static int jt_set_numa(int argc, char **argv)
496 struct cYAML *err_rc = NULL;
498 rc = check_cmd(set_cmds, "set", "numa_range", 2, argc, argv);
502 rc = parse_long(argv[1], &value);
504 cYAML_build_error(-1, -1, "parser", "set",
505 "cannot parse numa_range value", &err_rc);
506 cYAML_print_tree2file(stderr, err_rc);
507 cYAML_free_tree(err_rc);
511 rc = lustre_lnet_config_numa_range(value, -1, &err_rc);
512 if (rc != LUSTRE_CFG_RC_NO_ERR)
513 cYAML_print_tree2file(stderr, err_rc);
515 cYAML_free_tree(err_rc);
520 static int jt_set_recov_intrv(int argc, char **argv)
524 struct cYAML *err_rc = NULL;
526 rc = check_cmd(set_cmds, "set", "recovery_interval", 2, argc, argv);
530 rc = parse_long(argv[1], &value);
532 cYAML_build_error(-1, -1, "parser", "set",
533 "cannot parse recovery interval value", &err_rc);
534 cYAML_print_tree2file(stderr, err_rc);
535 cYAML_free_tree(err_rc);
539 rc = lustre_lnet_config_recov_intrv(value, -1, &err_rc);
540 if (rc != LUSTRE_CFG_RC_NO_ERR)
541 cYAML_print_tree2file(stderr, err_rc);
543 cYAML_free_tree(err_rc);
548 static int jt_set_rtr_sensitivity(int argc, char **argv)
552 struct cYAML *err_rc = NULL;
554 rc = check_cmd(set_cmds, "set", "router_sensitivity", 2, argc, argv);
558 rc = parse_long(argv[1], &value);
560 cYAML_build_error(-1, -1, "parser", "set",
561 "cannot parse router sensitivity value", &err_rc);
562 cYAML_print_tree2file(stderr, err_rc);
563 cYAML_free_tree(err_rc);
567 rc = lustre_lnet_config_rtr_sensitivity(value, -1, &err_rc);
568 if (rc != LUSTRE_CFG_RC_NO_ERR)
569 cYAML_print_tree2file(stderr, err_rc);
571 cYAML_free_tree(err_rc);
576 static int jt_set_hsensitivity(int argc, char **argv)
580 struct cYAML *err_rc = NULL;
582 rc = check_cmd(set_cmds, "set", "health_sensitivity", 2, argc, argv);
586 rc = parse_long(argv[1], &value);
588 cYAML_build_error(-1, -1, "parser", "set",
589 "cannot parse health sensitivity value", &err_rc);
590 cYAML_print_tree2file(stderr, err_rc);
591 cYAML_free_tree(err_rc);
595 rc = lustre_lnet_config_hsensitivity(value, -1, &err_rc);
596 if (rc != LUSTRE_CFG_RC_NO_ERR)
597 cYAML_print_tree2file(stderr, err_rc);
599 cYAML_free_tree(err_rc);
604 static int jt_reset_stats(int argc, char **argv)
607 struct cYAML *err_rc = NULL;
609 rc = check_cmd(stats_cmds, "stats", "reset", 0, argc, argv);
613 rc = lustre_lnet_reset_stats(-1, &err_rc);
614 if (rc != LUSTRE_CFG_RC_NO_ERR)
615 cYAML_print_tree2file(stderr, err_rc);
617 cYAML_free_tree(err_rc);
622 static int jt_set_transaction_to(int argc, char **argv)
626 struct cYAML *err_rc = NULL;
628 rc = check_cmd(set_cmds, "set", "transaction_timeout", 2, argc, argv);
632 rc = parse_long(argv[1], &value);
634 cYAML_build_error(-1, -1, "parser", "set",
635 "cannot parse transaction timeout value", &err_rc);
636 cYAML_print_tree2file(stderr, err_rc);
637 cYAML_free_tree(err_rc);
641 rc = lustre_lnet_config_transaction_to(value, -1, &err_rc);
642 if (rc != LUSTRE_CFG_RC_NO_ERR)
643 cYAML_print_tree2file(stderr, err_rc);
645 cYAML_free_tree(err_rc);
650 static int jt_set_retry_count(int argc, char **argv)
654 struct cYAML *err_rc = NULL;
656 rc = check_cmd(set_cmds, "set", "retry_count", 2, argc, argv);
660 rc = parse_long(argv[1], &value);
662 cYAML_build_error(-1, -1, "parser", "set",
663 "cannot parse retry_count value", &err_rc);
664 cYAML_print_tree2file(stderr, err_rc);
665 cYAML_free_tree(err_rc);
669 rc = lustre_lnet_config_retry_count(value, -1, &err_rc);
670 if (rc != LUSTRE_CFG_RC_NO_ERR)
671 cYAML_print_tree2file(stderr, err_rc);
673 cYAML_free_tree(err_rc);
678 static int jt_set_discovery(int argc, char **argv)
682 struct cYAML *err_rc = NULL;
684 rc = check_cmd(set_cmds, "set", "discovery", 2, argc, argv);
688 rc = parse_long(argv[1], &value);
690 cYAML_build_error(-1, -1, "parser", "set",
691 "cannot parse discovery value", &err_rc);
692 cYAML_print_tree2file(stderr, err_rc);
693 cYAML_free_tree(err_rc);
697 rc = lustre_lnet_config_discovery(value, -1, &err_rc);
698 if (rc != LUSTRE_CFG_RC_NO_ERR)
699 cYAML_print_tree2file(stderr, err_rc);
701 cYAML_free_tree(err_rc);
706 static int jt_set_drop_asym_route(int argc, char **argv)
710 struct cYAML *err_rc = NULL;
712 rc = check_cmd(set_cmds, "set", "drop_asym_route", 2, argc, argv);
716 rc = parse_long(argv[1], &value);
718 cYAML_build_error(-1, -1, "parser", "set",
719 "cannot parse drop_asym_route value",
721 cYAML_print_tree2file(stderr, err_rc);
722 cYAML_free_tree(err_rc);
726 rc = lustre_lnet_config_drop_asym_route(value, -1, &err_rc);
727 if (rc != LUSTRE_CFG_RC_NO_ERR)
728 cYAML_print_tree2file(stderr, err_rc);
730 cYAML_free_tree(err_rc);
735 static int jt_set_tiny(int argc, char **argv)
739 struct cYAML *err_rc = NULL;
741 rc = check_cmd(set_cmds, "set", "tiny_buffers", 2, argc, argv);
745 rc = parse_long(argv[1], &value);
747 cYAML_build_error(-1, -1, "parser", "set",
748 "cannot parse tiny_buffers value", &err_rc);
749 cYAML_print_tree2file(stderr, err_rc);
750 cYAML_free_tree(err_rc);
754 rc = lustre_lnet_config_buffers(value, -1, -1, -1, &err_rc);
755 if (rc != LUSTRE_CFG_RC_NO_ERR)
756 cYAML_print_tree2file(stderr, err_rc);
758 cYAML_free_tree(err_rc);
763 static int jt_set_small(int argc, char **argv)
767 struct cYAML *err_rc = NULL;
769 rc = check_cmd(set_cmds, "set", "small_buffers", 2, argc, argv);
773 rc = parse_long(argv[1], &value);
775 cYAML_build_error(-1, -1, "parser", "set",
776 "cannot parse small_buffers value", &err_rc);
777 cYAML_print_tree2file(stderr, err_rc);
778 cYAML_free_tree(err_rc);
782 rc = lustre_lnet_config_buffers(-1, value, -1, -1, &err_rc);
783 if (rc != LUSTRE_CFG_RC_NO_ERR)
784 cYAML_print_tree2file(stderr, err_rc);
786 cYAML_free_tree(err_rc);
791 static int jt_set_large(int argc, char **argv)
795 struct cYAML *err_rc = NULL;
797 rc = check_cmd(set_cmds, "set", "large_buffers", 2, argc, argv);
801 rc = parse_long(argv[1], &value);
803 cYAML_build_error(-1, -1, "parser", "set",
804 "cannot parse large_buffers value", &err_rc);
805 cYAML_print_tree2file(stderr, err_rc);
806 cYAML_free_tree(err_rc);
810 rc = lustre_lnet_config_buffers(-1, -1, value, -1, &err_rc);
811 if (rc != LUSTRE_CFG_RC_NO_ERR)
812 cYAML_print_tree2file(stderr, err_rc);
814 cYAML_free_tree(err_rc);
819 static int jt_set_routing(int argc, char **argv)
822 struct cYAML *err_rc = NULL;
825 rc = check_cmd(set_cmds, "set", "routing", 2, argc, argv);
829 rc = parse_long(argv[1], &value);
830 if (rc != 0 || (value != 0 && value != 1)) {
831 cYAML_build_error(-1, -1, "parser", "set",
832 "cannot parse routing value.\n"
833 "must be 0 for disable or 1 for enable",
835 cYAML_print_tree2file(stderr, err_rc);
836 cYAML_free_tree(err_rc);
840 rc = lustre_lnet_enable_routing(value, -1, &err_rc);
842 if (rc != LUSTRE_CFG_RC_NO_ERR)
843 cYAML_print_tree2file(stderr, err_rc);
845 cYAML_free_tree(err_rc);
850 static int jt_set_max_recovery_ping_interval(int argc, char **argv)
854 struct cYAML *err_rc = NULL;
856 rc = check_cmd(set_cmds, "set", "maximum recovery_interval", 2, argc, argv);
860 rc = parse_long(argv[1], &value);
862 cYAML_build_error(-1, -1, "parser", "set",
863 "cannot parse maximum recovery interval value",
865 cYAML_print_tree2file(stderr, err_rc);
866 cYAML_free_tree(err_rc);
870 rc = lustre_lnet_config_max_recovery_ping_interval(value, -1, &err_rc);
871 if (rc != LUSTRE_CFG_RC_NO_ERR)
872 cYAML_print_tree2file(stderr, err_rc);
874 cYAML_free_tree(err_rc);
879 static void yaml_lnet_print_error(int op, char *cmd, const char *errstr)
881 char errcode[INT_STRING_LEN];
887 snprintf(errcode, sizeof(errcode), "%d", errno);
889 yaml_emitter_initialize(&log);
890 yaml_emitter_set_indent(&log, LNET_DEFAULT_INDENT);
891 yaml_emitter_set_output_file(&log, stderr);
893 yaml_emitter_open(&log);
894 yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
895 rc = yaml_emitter_emit(&log, &event);
899 yaml_mapping_start_event_initialize(&event, NULL,
900 (yaml_char_t *)YAML_MAP_TAG,
901 1, YAML_ANY_MAPPING_STYLE);
902 rc = yaml_emitter_emit(&log, &event);
906 if (strcmp(cmd, "lnet") == 0) {
930 yaml_scalar_event_initialize(&event, NULL,
931 (yaml_char_t *)YAML_STR_TAG,
934 YAML_PLAIN_SCALAR_STYLE);
935 rc = yaml_emitter_emit(&log, &event);
939 yaml_sequence_start_event_initialize(&event, NULL,
940 (yaml_char_t *)YAML_SEQ_TAG,
941 1, YAML_ANY_SEQUENCE_STYLE);
942 rc = yaml_emitter_emit(&log, &event);
946 yaml_mapping_start_event_initialize(&event, NULL,
947 (yaml_char_t *)YAML_MAP_TAG,
948 1, YAML_ANY_MAPPING_STYLE);
949 rc = yaml_emitter_emit(&log, &event);
953 yaml_scalar_event_initialize(&event, NULL,
954 (yaml_char_t *)YAML_STR_TAG,
957 1, 0, YAML_PLAIN_SCALAR_STYLE);
958 rc = yaml_emitter_emit(&log, &event);
962 yaml_scalar_event_initialize(&event, NULL,
963 (yaml_char_t *)YAML_STR_TAG,
966 1, 0, YAML_PLAIN_SCALAR_STYLE);
967 rc = yaml_emitter_emit(&log, &event);
971 yaml_scalar_event_initialize(&event, NULL,
972 (yaml_char_t *)YAML_STR_TAG,
973 (yaml_char_t *)"errno",
974 strlen("errno"), 1, 0,
975 YAML_PLAIN_SCALAR_STYLE);
976 rc = yaml_emitter_emit(&log, &event);
980 yaml_scalar_event_initialize(&event, NULL,
981 (yaml_char_t *)YAML_INT_TAG,
982 (yaml_char_t *)errcode,
983 strlen(errcode), 1, 0,
984 YAML_PLAIN_SCALAR_STYLE);
985 rc = yaml_emitter_emit(&log, &event);
990 yaml_scalar_event_initialize(&event, NULL,
991 (yaml_char_t *)YAML_STR_TAG,
992 (yaml_char_t *)"descr",
993 strlen("descr"), 1, 0,
994 YAML_PLAIN_SCALAR_STYLE);
995 rc = yaml_emitter_emit(&log, &event);
999 yaml_scalar_event_initialize(&event, NULL,
1000 (yaml_char_t *)YAML_STR_TAG,
1001 (yaml_char_t *)errstr,
1002 strlen(errstr), 1, 0,
1003 YAML_DOUBLE_QUOTED_SCALAR_STYLE);
1004 rc = yaml_emitter_emit(&log, &event);
1008 yaml_mapping_end_event_initialize(&event);
1009 rc = yaml_emitter_emit(&log, &event);
1013 yaml_sequence_end_event_initialize(&event);
1014 rc = yaml_emitter_emit(&log, &event);
1018 yaml_mapping_end_event_initialize(&event);
1019 rc = yaml_emitter_emit(&log, &event);
1023 yaml_document_end_event_initialize(&event, 0);
1024 rc = yaml_emitter_emit(&log, &event);
1028 rc = yaml_emitter_close(&log);
1031 yaml_emitter_log_error(&log, stdout);
1032 yaml_emitter_delete(&log);
1035 static int yaml_lnet_cpt_of_nid_display(yaml_parser_t *reply)
1037 yaml_document_t results;
1038 yaml_emitter_t output;
1041 rc = yaml_parser_load(reply, &results);
1043 yaml_lnet_print_error(NLM_F_DUMP, "cpt-of-nid",
1044 yaml_parser_get_reader_error(reply));
1045 yaml_document_delete(&results);
1049 rc = yaml_emitter_initialize(&output);
1051 yaml_emitter_set_output_file(&output, stdout);
1053 rc = yaml_emitter_dump(&output, &results);
1056 yaml_document_delete(&results);
1058 yaml_emitter_log_error(&output, stderr);
1061 yaml_emitter_delete(&output);
1066 static int yaml_lnet_cpt_of_nid(int start, int end, char **nids)
1068 struct nl_sock *sk = NULL;
1069 yaml_emitter_t request;
1070 yaml_parser_t reply;
1074 /* Create Netlink emitter to send request to kernel */
1075 sk = nl_socket_alloc();
1079 /* Setup parser to receive Netlink packets */
1080 rc = yaml_parser_initialize(&reply);
1086 rc = yaml_parser_set_input_netlink(&reply, sk, false);
1090 /* Create Netlink emitter to send request to kernel */
1091 rc = yaml_emitter_initialize(&request);
1095 rc = yaml_emitter_set_output_netlink(&request, sk, LNET_GENL_NAME,
1097 LNET_CMD_CPT_OF_NID, NLM_F_DUMP);
1101 yaml_emitter_open(&request);
1102 yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
1103 rc = yaml_emitter_emit(&request, &event);
1107 yaml_mapping_start_event_initialize(&event, NULL,
1108 (yaml_char_t *)YAML_MAP_TAG,
1109 1, YAML_ANY_MAPPING_STYLE);
1110 rc = yaml_emitter_emit(&request, &event);
1114 yaml_scalar_event_initialize(&event, NULL,
1115 (yaml_char_t *)YAML_STR_TAG,
1116 (yaml_char_t *)"cpt-of-nid",
1117 strlen("cpt-of-nid"), 1, 0,
1118 YAML_PLAIN_SCALAR_STYLE);
1119 rc = yaml_emitter_emit(&request, &event);
1123 yaml_mapping_start_event_initialize(&event, NULL,
1124 (yaml_char_t *)YAML_MAP_TAG,
1125 1, YAML_ANY_MAPPING_STYLE);
1126 rc = yaml_emitter_emit(&request, &event);
1130 yaml_scalar_event_initialize(&event, NULL,
1131 (yaml_char_t *)YAML_STR_TAG,
1132 (yaml_char_t *)"nids",
1133 strlen("nids"), 1, 0,
1134 YAML_PLAIN_SCALAR_STYLE);
1135 rc = yaml_emitter_emit(&request, &event);
1139 yaml_sequence_start_event_initialize(&event, NULL,
1140 (yaml_char_t *)YAML_SEQ_TAG,
1141 1, YAML_FLOW_SEQUENCE_STYLE);
1142 rc = yaml_emitter_emit(&request, &event);
1146 for (i = start; i < end; i++) {
1147 yaml_scalar_event_initialize(&event, NULL,
1148 (yaml_char_t *)YAML_STR_TAG,
1149 (yaml_char_t *)nids[i],
1150 strlen(nids[i]), 1, 0,
1151 YAML_PLAIN_SCALAR_STYLE);
1152 rc = yaml_emitter_emit(&request, &event);
1157 yaml_sequence_end_event_initialize(&event);
1158 rc = yaml_emitter_emit(&request, &event);
1162 yaml_mapping_end_event_initialize(&event);
1163 rc = yaml_emitter_emit(&request, &event);
1167 yaml_mapping_end_event_initialize(&event);
1168 rc = yaml_emitter_emit(&request, &event);
1172 yaml_document_end_event_initialize(&event, 0);
1173 rc = yaml_emitter_emit(&request, &event);
1177 rc = yaml_emitter_close(&request);
1180 yaml_emitter_log_error(&request, stderr);
1183 rc = yaml_lnet_cpt_of_nid_display(&reply);
1185 yaml_emitter_delete(&request);
1188 yaml_lnet_print_error(NLM_F_DUMP, "cpt-of-nid",
1189 yaml_parser_get_reader_error(&reply));
1193 yaml_parser_delete(&reply);
1196 return rc == 1 ? 0 : rc;
1199 static int jt_calc_cpt_of_nid(int argc, char **argv)
1202 const char *const short_options = "h";
1203 static const struct option long_options[] = {
1204 { .name = "help", .val = 'h' },
1207 rc = check_cmd(cmd_list, "", "cpt-of-nid", 2, argc, argv);
1211 while ((opt = getopt_long(argc, argv, short_options,
1212 long_options, NULL)) != -1) {
1216 print_help(cmd_list, "", "cpt-of-nid");
1222 rc = yaml_lnet_cpt_of_nid(optind, argc, argv);
1223 if (rc == -EOPNOTSUPP)
1224 printf("Operation not supported\n");
1229 static int jt_config_lnet(int argc, char **argv)
1231 struct cYAML *err_rc = NULL;
1232 bool load_mod_params = false;
1233 int flags = NLM_F_CREATE;
1234 const char *msg = NULL;
1236 const char *const short_options = "al";
1237 static const struct option long_options[] = {
1238 { .name = "all", .has_arg = no_argument, .val = 'a' },
1239 { .name = "large", .has_arg = no_argument, .val = 'l' },
1243 rc = check_cmd(lnet_cmds, "lnet", "configure", 0, argc, argv);
1247 while ((opt = getopt_long(argc, argv, short_options,
1248 long_options, NULL)) != -1) {
1251 load_mod_params = true;
1254 flags |= NLM_F_REPLACE;
1261 if (!load_mod_params)
1262 flags |= NLM_F_EXCL;
1264 rc = yaml_lnet_configure(flags, &msg);
1265 if (rc != -EOPNOTSUPP) {
1269 snprintf(errstr, sizeof(errstr),
1270 "LNet configure error: %s", msg);
1271 yaml_lnet_print_error(flags, "lnet", errstr);
1276 rc = lustre_lnet_config_ni_system(LNET_CONFIGURE, load_mod_params,
1279 if (rc != LUSTRE_CFG_RC_NO_ERR)
1280 cYAML_print_tree2file(stderr, err_rc);
1282 cYAML_free_tree(err_rc);
1287 static int jt_unconfig_lnet(int argc, char **argv)
1289 struct cYAML *err_rc = NULL;
1290 const char *msg = NULL;
1293 rc = check_cmd(lnet_cmds, "lnet", "unconfigure", 0, argc, argv);
1297 rc = yaml_lnet_configure(0, &msg);
1298 if (rc != -EOPNOTSUPP) {
1302 snprintf(errstr, sizeof(errstr),
1303 "LNet configure error: %s", msg);
1304 yaml_lnet_print_error(0, "lnet", errstr);
1309 rc = lustre_lnet_config_ni_system(LNET_UNCONFIGURE, 0, -1, &err_rc);
1311 if (rc != LUSTRE_CFG_RC_NO_ERR)
1312 cYAML_print_tree2file(stderr, err_rc);
1314 cYAML_free_tree(err_rc);
1319 static int yaml_lnet_router_gateways(yaml_emitter_t *output, const char *nw,
1320 const char *gw, int hops, int prio,
1323 char num[INT_STRING_LEN];
1327 yaml_mapping_start_event_initialize(&event, NULL,
1328 (yaml_char_t *)YAML_MAP_TAG, 1,
1329 YAML_BLOCK_MAPPING_STYLE);
1330 rc = yaml_emitter_emit(output, &event);
1335 yaml_scalar_event_initialize(&event, NULL,
1336 (yaml_char_t *)YAML_STR_TAG,
1337 (yaml_char_t *)"net",
1338 strlen("net"), 1, 0,
1339 YAML_PLAIN_SCALAR_STYLE);
1340 rc = yaml_emitter_emit(output, &event);
1344 yaml_scalar_event_initialize(&event, NULL,
1345 (yaml_char_t *)YAML_STR_TAG,
1348 YAML_PLAIN_SCALAR_STYLE);
1349 rc = yaml_emitter_emit(output, &event);
1355 yaml_scalar_event_initialize(&event, NULL,
1356 (yaml_char_t *)YAML_STR_TAG,
1357 (yaml_char_t *)"gateway",
1358 strlen("gateway"), 1, 0,
1359 YAML_PLAIN_SCALAR_STYLE);
1360 rc = yaml_emitter_emit(output, &event);
1364 yaml_scalar_event_initialize(&event, NULL,
1365 (yaml_char_t *)YAML_STR_TAG,
1368 YAML_PLAIN_SCALAR_STYLE);
1369 rc = yaml_emitter_emit(output, &event);
1375 yaml_scalar_event_initialize(&event, NULL,
1376 (yaml_char_t *)YAML_STR_TAG,
1377 (yaml_char_t *)"hop",
1378 strlen("hop"), 1, 0,
1379 YAML_PLAIN_SCALAR_STYLE);
1380 rc = yaml_emitter_emit(output, &event);
1384 snprintf(num, sizeof(num), "%d", hops);
1385 yaml_scalar_event_initialize(&event, NULL,
1386 (yaml_char_t *)YAML_INT_TAG,
1389 YAML_PLAIN_SCALAR_STYLE);
1390 rc = yaml_emitter_emit(output, &event);
1396 yaml_scalar_event_initialize(&event, NULL,
1397 (yaml_char_t *)YAML_STR_TAG,
1398 (yaml_char_t *)"priority",
1399 strlen("priority"), 1, 0,
1400 YAML_PLAIN_SCALAR_STYLE);
1401 rc = yaml_emitter_emit(output, &event);
1405 snprintf(num, sizeof(num), "%d", prio);
1406 yaml_scalar_event_initialize(&event, NULL,
1407 (yaml_char_t *)YAML_INT_TAG,
1410 YAML_PLAIN_SCALAR_STYLE);
1411 rc = yaml_emitter_emit(output, &event);
1417 yaml_scalar_event_initialize(&event, NULL,
1418 (yaml_char_t *)YAML_STR_TAG,
1419 (yaml_char_t *)"health_sensitivity",
1420 strlen("health_sensitivity"),
1422 YAML_PLAIN_SCALAR_STYLE);
1423 rc = yaml_emitter_emit(output, &event);
1427 snprintf(num, sizeof(num), "%d", sen);
1428 yaml_scalar_event_initialize(&event, NULL,
1429 (yaml_char_t *)YAML_INT_TAG,
1432 YAML_PLAIN_SCALAR_STYLE);
1433 rc = yaml_emitter_emit(output, &event);
1438 yaml_mapping_end_event_initialize(&event);
1439 rc = yaml_emitter_emit(output, &event);
1444 static int yaml_lnet_route(char *nw, char *gw, int hops, int prio, int sen,
1445 int version, int flags, FILE *fp)
1447 struct nid_node head, *entry;
1448 struct nl_sock *sk = NULL;
1449 const char *msg = NULL;
1450 yaml_emitter_t output;
1451 yaml_parser_t reply;
1455 if (!(flags & NLM_F_DUMP) && (!nw || !gw)) {
1456 fprintf(stdout, "missing mandatory parameters:'%s'\n",
1457 (!nw && !gw) ? "net , gateway" :
1458 !nw ? "net" : "gateway");
1462 /* Create Netlink emitter to send request to kernel */
1463 sk = nl_socket_alloc();
1467 /* Setup parser to receive Netlink packets */
1468 rc = yaml_parser_initialize(&reply);
1474 rc = yaml_parser_set_input_netlink(&reply, sk, false);
1476 msg = yaml_parser_get_reader_error(&reply);
1480 /* Create Netlink emitter to send request to kernel */
1481 rc = yaml_emitter_initialize(&output);
1483 msg = "failed to initialize emitter";
1487 rc = yaml_emitter_set_output_netlink(&output, sk, LNET_GENL_NAME,
1488 version, LNET_CMD_ROUTES, flags);
1492 yaml_emitter_open(&output);
1493 yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
1494 rc = yaml_emitter_emit(&output, &event);
1498 yaml_mapping_start_event_initialize(&event, NULL,
1499 (yaml_char_t *)YAML_MAP_TAG,
1500 1, YAML_ANY_MAPPING_STYLE);
1501 rc = yaml_emitter_emit(&output, &event);
1505 yaml_scalar_event_initialize(&event, NULL,
1506 (yaml_char_t *)YAML_STR_TAG,
1507 (yaml_char_t *)"route",
1508 strlen("route"), 1, 0,
1509 YAML_PLAIN_SCALAR_STYLE);
1510 rc = yaml_emitter_emit(&output, &event);
1514 /* NLM_F_DUMP can have no arguments */
1516 NL_INIT_LIST_HEAD(&head.children);
1517 nl_init_list_head(&head.list);
1519 rc = lustre_lnet_parse_nid_range(&head, gw, &msg);
1521 lustre_lnet_free_list(&head);
1522 yaml_emitter_delete(&output);
1529 yaml_sequence_start_event_initialize(&event, NULL,
1530 (yaml_char_t *)YAML_SEQ_TAG,
1532 YAML_BLOCK_SEQUENCE_STYLE);
1533 rc = yaml_emitter_emit(&output, &event);
1537 if (!nl_list_empty(&head.children)) {
1538 nl_list_for_each_entry(entry, &head.children, list) {
1539 const char *nid = entry->nidstr;
1541 rc = yaml_lnet_router_gateways(&output, nw, nid,
1547 rc = yaml_lnet_router_gateways(&output, nw, NULL, hops,
1553 yaml_sequence_end_event_initialize(&event);
1554 rc = yaml_emitter_emit(&output, &event);
1558 yaml_scalar_event_initialize(&event, NULL,
1559 (yaml_char_t *)YAML_STR_TAG,
1562 YAML_PLAIN_SCALAR_STYLE);
1563 rc = yaml_emitter_emit(&output, &event);
1568 yaml_mapping_end_event_initialize(&event);
1569 rc = yaml_emitter_emit(&output, &event);
1573 yaml_document_end_event_initialize(&event, 0);
1574 rc = yaml_emitter_emit(&output, &event);
1578 rc = yaml_emitter_close(&output);
1581 yaml_emitter_log_error(&output, stderr);
1584 yaml_document_t errmsg;
1586 rc = yaml_parser_load(&reply, &errmsg);
1587 if (rc == 1 && (flags & NLM_F_DUMP)) {
1588 yaml_emitter_t debug;
1590 rc = yaml_emitter_initialize(&debug);
1592 yaml_emitter_set_indent(&debug,
1593 LNET_DEFAULT_INDENT);
1594 yaml_emitter_set_output_file(&debug, fp);
1595 rc = yaml_emitter_dump(&debug, &errmsg);
1597 yaml_emitter_delete(&debug);
1599 msg = yaml_parser_get_reader_error(&reply);
1600 /* If we didn't find any routes just be silent */
1601 if (msg && strcmp(msg, "No routes found") == 0)
1604 yaml_document_delete(&errmsg);
1606 yaml_emitter_delete(&output);
1609 yaml_lnet_print_error(flags, "route", msg);
1612 yaml_parser_delete(&reply);
1615 return rc == 1 ? 0 : rc;
1618 static int jt_add_route(int argc, char **argv)
1620 char *network = NULL, *gateway = NULL;
1621 long int hop = -1, prio = -1, sen = -1;
1622 struct cYAML *err_rc = NULL;
1625 const char *const short_options = "n:g:c:p:";
1626 static const struct option long_options[] = {
1627 { .name = "net", .has_arg = required_argument, .val = 'n' },
1628 { .name = "gateway", .has_arg = required_argument, .val = 'g' },
1629 { .name = "hop", .has_arg = required_argument, .val = 'c' },
1630 { .name = "hop-count", .has_arg = required_argument, .val = 'c' },
1631 { .name = "priority", .has_arg = required_argument, .val = 'p' },
1632 { .name = "health_sensitivity", .has_arg = required_argument, .val = 's' },
1636 rc = check_cmd(route_cmds, "route", "add", 0, argc, argv);
1640 while ((opt = getopt_long(argc, argv, short_options,
1641 long_options, NULL)) != -1) {
1650 rc = parse_long(optarg, &hop);
1658 rc = parse_long(optarg, &prio);
1666 rc = parse_long(optarg, &sen);
1675 print_help(route_cmds, "route", "add");
1681 rc = yaml_lnet_route(network, gateway, hop, prio, sen,
1682 LNET_GENL_VERSION, NLM_F_CREATE, stdout);
1684 if (rc == -EOPNOTSUPP)
1689 rc = lustre_lnet_config_route(network, gateway, hop, prio, sen, -1,
1692 if (rc != LUSTRE_CFG_RC_NO_ERR)
1693 cYAML_print_tree2file(stderr, err_rc);
1695 cYAML_free_tree(err_rc);
1700 static int yaml_add_ni_tunables(yaml_emitter_t *output,
1701 struct lnet_ioctl_config_lnd_tunables *tunables,
1702 struct lnet_dlc_network_descr *nw_descr)
1704 char num[INT_STRING_LEN];
1708 if (tunables->lt_cmn.lct_peer_timeout < 0 &&
1709 tunables->lt_cmn.lct_peer_tx_credits <= 0 &&
1710 tunables->lt_cmn.lct_peer_rtr_credits <= 0 &&
1711 tunables->lt_cmn.lct_max_tx_credits <= 0)
1712 goto skip_general_settings;
1714 yaml_scalar_event_initialize(&event, NULL,
1715 (yaml_char_t *)YAML_STR_TAG,
1716 (yaml_char_t *)"tunables",
1717 strlen("tunables"), 1, 0,
1718 YAML_PLAIN_SCALAR_STYLE);
1719 rc = yaml_emitter_emit(output, &event);
1723 yaml_mapping_start_event_initialize(&event, NULL,
1724 (yaml_char_t *)YAML_MAP_TAG,
1725 1, YAML_ANY_MAPPING_STYLE);
1726 rc = yaml_emitter_emit(output, &event);
1730 if (tunables->lt_cmn.lct_peer_timeout >= 0) {
1731 yaml_scalar_event_initialize(&event, NULL,
1732 (yaml_char_t *)YAML_STR_TAG,
1733 (yaml_char_t *)"peer_timeout",
1734 strlen("peer_timeout"), 1, 0,
1735 YAML_PLAIN_SCALAR_STYLE);
1736 rc = yaml_emitter_emit(output, &event);
1740 snprintf(num, sizeof(num), "%u",
1741 tunables->lt_cmn.lct_peer_timeout);
1742 yaml_scalar_event_initialize(&event, NULL,
1743 (yaml_char_t *)YAML_INT_TAG,
1746 YAML_PLAIN_SCALAR_STYLE);
1747 rc = yaml_emitter_emit(output, &event);
1752 if (tunables->lt_cmn.lct_peer_tx_credits > 0) {
1753 yaml_scalar_event_initialize(&event, NULL,
1754 (yaml_char_t *)YAML_STR_TAG,
1755 (yaml_char_t *)"peer_credits",
1756 strlen("peer_credits"), 1, 0,
1757 YAML_PLAIN_SCALAR_STYLE);
1758 rc = yaml_emitter_emit(output, &event);
1762 snprintf(num, sizeof(num), "%u",
1763 tunables->lt_cmn.lct_peer_tx_credits);
1764 yaml_scalar_event_initialize(&event, NULL,
1765 (yaml_char_t *)YAML_INT_TAG,
1768 YAML_PLAIN_SCALAR_STYLE);
1769 rc = yaml_emitter_emit(output, &event);
1774 if (tunables->lt_cmn.lct_peer_rtr_credits > 0) {
1775 yaml_scalar_event_initialize(&event, NULL,
1776 (yaml_char_t *)YAML_STR_TAG,
1777 (yaml_char_t *)"peer_buffer_credits",
1778 strlen("peer_buffer_credits"), 1, 0,
1779 YAML_PLAIN_SCALAR_STYLE);
1780 rc = yaml_emitter_emit(output, &event);
1784 snprintf(num, sizeof(num), "%u",
1785 tunables->lt_cmn.lct_peer_rtr_credits);
1786 yaml_scalar_event_initialize(&event, NULL,
1787 (yaml_char_t *)YAML_INT_TAG,
1790 YAML_PLAIN_SCALAR_STYLE);
1791 rc = yaml_emitter_emit(output, &event);
1796 if (tunables->lt_cmn.lct_max_tx_credits > 0) {
1797 yaml_scalar_event_initialize(&event, NULL,
1798 (yaml_char_t *)YAML_STR_TAG,
1799 (yaml_char_t *)"credits",
1800 strlen("credits"), 1, 0,
1801 YAML_PLAIN_SCALAR_STYLE);
1802 rc = yaml_emitter_emit(output, &event);
1806 snprintf(num, sizeof(num), "%u",
1807 tunables->lt_cmn.lct_max_tx_credits);
1808 yaml_scalar_event_initialize(&event, NULL,
1809 (yaml_char_t *)YAML_INT_TAG,
1812 YAML_PLAIN_SCALAR_STYLE);
1813 rc = yaml_emitter_emit(output, &event);
1818 yaml_mapping_end_event_initialize(&event);
1819 rc = yaml_emitter_emit(output, &event);
1823 skip_general_settings:
1824 if (tunables->lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer > 0 ||
1825 tunables->lt_tun.lnd_tun_u.lnd_sock.lnd_tos >= 0 ||
1827 tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_auth_key > 0 ||
1828 tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_traffic_class_str[0] ||
1830 tunables->lt_tun.lnd_tun_u.lnd_o2ib.lnd_conns_per_peer > 0 ||
1831 tunables->lt_tun.lnd_tun_u.lnd_o2ib.lnd_tos >= 0) {
1832 yaml_scalar_event_initialize(&event, NULL,
1833 (yaml_char_t *)YAML_STR_TAG,
1834 (yaml_char_t *)"lnd tunables",
1835 strlen("lnd tunables"), 1, 0,
1836 YAML_PLAIN_SCALAR_STYLE);
1837 rc = yaml_emitter_emit(output, &event);
1841 yaml_mapping_start_event_initialize(&event, NULL,
1842 (yaml_char_t *)YAML_MAP_TAG,
1843 1, YAML_ANY_MAPPING_STYLE);
1844 rc = yaml_emitter_emit(output, &event);
1848 if (tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_auth_key > 0) {
1849 yaml_scalar_event_initialize(&event, NULL,
1850 (yaml_char_t *)YAML_STR_TAG,
1851 (yaml_char_t *)"auth_key",
1852 strlen("auth_key"), 1, 0,
1853 YAML_PLAIN_SCALAR_STYLE);
1854 rc = yaml_emitter_emit(output, &event);
1858 snprintf(num, sizeof(num), "%u",
1859 tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_auth_key);
1861 yaml_scalar_event_initialize(&event, NULL,
1862 (yaml_char_t *)YAML_INT_TAG,
1865 YAML_PLAIN_SCALAR_STYLE);
1866 rc = yaml_emitter_emit(output, &event);
1871 if (tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_traffic_class_str[0]) {
1872 char *tc = &tunables->lt_tun.lnd_tun_u.lnd_kfi.lnd_traffic_class_str[0];
1874 yaml_scalar_event_initialize(&event, NULL,
1875 (yaml_char_t *)YAML_STR_TAG,
1876 (yaml_char_t *)"traffic_class",
1877 strlen("traffic_class"), 1, 0,
1878 YAML_PLAIN_SCALAR_STYLE);
1879 rc = yaml_emitter_emit(output, &event);
1883 yaml_scalar_event_initialize(&event, NULL,
1884 (yaml_char_t *)YAML_INT_TAG,
1887 YAML_PLAIN_SCALAR_STYLE);
1889 rc = yaml_emitter_emit(output, &event);
1894 if (tunables->lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer > 0 ||
1895 tunables->lt_tun.lnd_tun_u.lnd_o2ib.lnd_conns_per_peer > 0) {
1898 yaml_scalar_event_initialize(&event, NULL,
1899 (yaml_char_t *)YAML_STR_TAG,
1900 (yaml_char_t *)"conns_per_peer",
1901 strlen("conns_per_peer"), 1, 0,
1902 YAML_PLAIN_SCALAR_STYLE);
1903 rc = yaml_emitter_emit(output, &event);
1907 if (nw_descr->nw_id == LNET_NET_ANY)
1908 cpp = tunables->lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer;
1909 else if (LNET_NETTYP(nw_descr->nw_id) == SOCKLND)
1910 cpp = tunables->lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer;
1911 else if (LNET_NETTYP(nw_descr->nw_id) == O2IBLND)
1912 cpp = tunables->lt_tun.lnd_tun_u.lnd_o2ib.lnd_conns_per_peer;
1913 snprintf(num, sizeof(num), "%u", cpp);
1915 yaml_scalar_event_initialize(&event, NULL,
1916 (yaml_char_t *)YAML_INT_TAG,
1919 YAML_PLAIN_SCALAR_STYLE);
1920 rc = yaml_emitter_emit(output, &event);
1925 if (tunables->lt_tun.lnd_tun_u.lnd_sock.lnd_tos >= 0 ||
1926 tunables->lt_tun.lnd_tun_u.lnd_o2ib.lnd_tos >= 0) {
1929 yaml_scalar_event_initialize(&event, NULL,
1930 (yaml_char_t *)YAML_STR_TAG,
1931 (yaml_char_t *)"tos",
1932 strlen("tos"), 1, 0,
1933 YAML_PLAIN_SCALAR_STYLE);
1934 rc = yaml_emitter_emit(output, &event);
1938 if (LNET_NETTYP(nw_descr->nw_id) == SOCKLND)
1939 tos = tunables->lt_tun.lnd_tun_u.lnd_sock.lnd_tos;
1940 else if (LNET_NETTYP(nw_descr->nw_id) == O2IBLND)
1941 tos = tunables->lt_tun.lnd_tun_u.lnd_o2ib.lnd_tos;
1942 snprintf(num, sizeof(num), "%u", tos);
1944 yaml_scalar_event_initialize(&event, NULL,
1945 (yaml_char_t *)YAML_INT_TAG,
1948 YAML_PLAIN_SCALAR_STYLE);
1949 rc = yaml_emitter_emit(output, &event);
1954 yaml_mapping_end_event_initialize(&event);
1955 rc = yaml_emitter_emit(output, &event);
1961 static int yaml_lnet_config_ni(char *net_id, char *ip2net,
1962 struct lnet_dlc_network_descr *nw_descr,
1963 struct lnet_ioctl_config_lnd_tunables *tunables,
1964 int healthv, struct cfs_expr_list *global_cpts,
1965 int version, int flags, FILE *fp)
1967 struct lnet_dlc_intf_descr *intf;
1968 struct nl_sock *sk = NULL;
1969 const char *msg = NULL;
1970 yaml_emitter_t output;
1971 yaml_parser_t reply;
1975 if (!(flags & NLM_F_DUMP) && !ip2net && (!nw_descr || nw_descr->nw_id == 0)) {
1976 fprintf(stdout, "missing mandatory parameters in NI config: '%s'\n",
1977 (!nw_descr) ? "network , interface" :
1978 (nw_descr->nw_id == 0) ? "network" : "interface");
1982 if ((flags == NLM_F_CREATE) && !ip2net && list_empty(&nw_descr->nw_intflist)) {
1983 fprintf(stdout, "creating a local NI needs at least one interface\n");
1987 if ((flags == NLM_F_REPLACE) && list_empty(&nw_descr->nw_intflist)) {
1988 fprintf(stdout, "updating a local NI needs at least one address\n");
1992 /* Create Netlink emitter to send request to kernel */
1993 sk = nl_socket_alloc();
1997 /* Setup parser to receive Netlink packets */
1998 rc = yaml_parser_initialize(&reply);
2004 rc = yaml_parser_set_input_netlink(&reply, sk, false);
2006 msg = yaml_parser_get_reader_error(&reply);
2010 /* Create Netlink emitter to send request to kernel */
2011 rc = yaml_emitter_initialize(&output);
2013 msg = "failed to initialize emitter";
2017 rc = yaml_emitter_set_output_netlink(&output, sk, LNET_GENL_NAME,
2018 version, LNET_CMD_NETS, flags);
2022 yaml_emitter_open(&output);
2023 yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
2024 rc = yaml_emitter_emit(&output, &event);
2028 yaml_mapping_start_event_initialize(&event, NULL,
2029 (yaml_char_t *)YAML_MAP_TAG,
2030 1, YAML_ANY_MAPPING_STYLE);
2031 rc = yaml_emitter_emit(&output, &event);
2035 yaml_scalar_event_initialize(&event, NULL,
2036 (yaml_char_t *)YAML_STR_TAG,
2037 (yaml_char_t *)"net",
2038 strlen("net"), 1, 0,
2039 YAML_PLAIN_SCALAR_STYLE);
2040 rc = yaml_emitter_emit(&output, &event);
2044 if (net_id || ip2net) {
2045 char *key = net_id ? "net type" : "ip2net";
2046 char *value = net_id ? net_id : ip2net;
2048 yaml_sequence_start_event_initialize(&event, NULL,
2049 (yaml_char_t *)YAML_SEQ_TAG,
2050 1, YAML_ANY_SEQUENCE_STYLE);
2051 rc = yaml_emitter_emit(&output, &event);
2055 yaml_mapping_start_event_initialize(&event, NULL,
2056 (yaml_char_t *)YAML_MAP_TAG,
2057 1, YAML_ANY_MAPPING_STYLE);
2058 rc = yaml_emitter_emit(&output, &event);
2062 yaml_scalar_event_initialize(&event, NULL,
2063 (yaml_char_t *)YAML_STR_TAG,
2066 1, 0, YAML_PLAIN_SCALAR_STYLE);
2067 rc = yaml_emitter_emit(&output, &event);
2071 yaml_scalar_event_initialize(&event, NULL,
2072 (yaml_char_t *)YAML_STR_TAG,
2073 (yaml_char_t *)value,
2074 strlen(value), 1, 0,
2075 YAML_PLAIN_SCALAR_STYLE);
2076 rc = yaml_emitter_emit(&output, &event);
2080 yaml_scalar_event_initialize(&event, NULL,
2081 (yaml_char_t *)YAML_STR_TAG,
2084 YAML_PLAIN_SCALAR_STYLE);
2085 rc = yaml_emitter_emit(&output, &event);
2092 if (!nw_descr || list_empty(&nw_descr->nw_intflist))
2095 yaml_scalar_event_initialize(&event, NULL,
2096 (yaml_char_t *)YAML_STR_TAG,
2097 (yaml_char_t *)"local NI(s)",
2098 strlen("local NI(s)"), 1, 0,
2099 YAML_PLAIN_SCALAR_STYLE);
2100 rc = yaml_emitter_emit(&output, &event);
2104 yaml_sequence_start_event_initialize(&event, NULL,
2105 (yaml_char_t *)YAML_SEQ_TAG,
2106 1, YAML_ANY_SEQUENCE_STYLE);
2107 rc = yaml_emitter_emit(&output, &event);
2111 list_for_each_entry(intf, &nw_descr->nw_intflist,
2113 yaml_mapping_start_event_initialize(&event, NULL,
2114 (yaml_char_t *)YAML_MAP_TAG,
2115 1, YAML_ANY_MAPPING_STYLE);
2116 rc = yaml_emitter_emit(&output, &event);
2120 /* Use NI addresses instead of interface */
2121 if (strchr(intf->intf_name, '@') ||
2122 (strcmp(intf->intf_name, "<?>") == 0 &&
2123 - flags == NLM_F_REPLACE)) {
2124 yaml_scalar_event_initialize(&event, NULL,
2125 (yaml_char_t *)YAML_STR_TAG,
2126 (yaml_char_t *)"nid",
2127 strlen("nid"), 1, 0,
2128 YAML_PLAIN_SCALAR_STYLE);
2129 rc = yaml_emitter_emit(&output, &event);
2133 yaml_scalar_event_initialize(&event, NULL,
2134 (yaml_char_t *)YAML_STR_TAG,
2135 (yaml_char_t *)intf->intf_name,
2136 strlen(intf->intf_name), 1, 0,
2137 YAML_PLAIN_SCALAR_STYLE);
2138 rc = yaml_emitter_emit(&output, &event);
2142 yaml_scalar_event_initialize(&event, NULL,
2143 (yaml_char_t *)YAML_STR_TAG,
2144 (yaml_char_t *)"interfaces",
2145 strlen("interfaces"), 1, 0,
2146 YAML_PLAIN_SCALAR_STYLE);
2147 rc = yaml_emitter_emit(&output, &event);
2151 yaml_mapping_start_event_initialize(&event, NULL,
2152 (yaml_char_t *)YAML_MAP_TAG,
2153 1, YAML_ANY_MAPPING_STYLE);
2154 rc = yaml_emitter_emit(&output, &event);
2158 yaml_scalar_event_initialize(&event, NULL,
2159 (yaml_char_t *)YAML_STR_TAG,
2162 YAML_PLAIN_SCALAR_STYLE);
2163 rc = yaml_emitter_emit(&output, &event);
2167 yaml_scalar_event_initialize(&event, NULL,
2168 (yaml_char_t *)YAML_STR_TAG,
2169 (yaml_char_t *)intf->intf_name,
2170 strlen(intf->intf_name), 1, 0,
2171 YAML_PLAIN_SCALAR_STYLE);
2172 rc = yaml_emitter_emit(&output, &event);
2176 yaml_mapping_end_event_initialize(&event);
2177 rc = yaml_emitter_emit(&output, &event);
2183 rc = yaml_add_ni_tunables(&output, tunables, nw_descr);
2188 if (flags == NLM_F_REPLACE && healthv > -1) {
2189 char health[INT_STRING_LEN];
2191 yaml_scalar_event_initialize(&event, NULL,
2192 (yaml_char_t *)YAML_STR_TAG,
2193 (yaml_char_t *)"health stats",
2194 strlen("health stats"), 1, 0,
2195 YAML_PLAIN_SCALAR_STYLE);
2196 rc = yaml_emitter_emit(&output, &event);
2200 /* Setup all mappings for data related to the 'health stats' */
2201 yaml_mapping_start_event_initialize(&event, NULL,
2202 (yaml_char_t *)YAML_MAP_TAG,
2203 1, YAML_BLOCK_MAPPING_STYLE);
2204 rc = yaml_emitter_emit(&output, &event);
2208 yaml_scalar_event_initialize(&event, NULL,
2209 (yaml_char_t *)YAML_STR_TAG,
2210 (yaml_char_t *)"health value",
2211 strlen("health value"), 1, 0,
2212 YAML_PLAIN_SCALAR_STYLE);
2213 rc = yaml_emitter_emit(&output, &event);
2217 snprintf(health, sizeof(health), "%d", healthv);
2218 yaml_scalar_event_initialize(&event, NULL,
2219 (yaml_char_t *)YAML_INT_TAG,
2220 (yaml_char_t *)health,
2221 strlen(health), 1, 0,
2222 YAML_PLAIN_SCALAR_STYLE);
2223 rc = yaml_emitter_emit(&output, &event);
2227 yaml_mapping_end_event_initialize(&event);
2228 rc = yaml_emitter_emit(&output, &event);
2237 yaml_scalar_event_initialize(&event, NULL,
2238 (yaml_char_t *)YAML_STR_TAG,
2239 (yaml_char_t *)"CPT",
2240 strlen("CPT"), 1, 0,
2241 YAML_PLAIN_SCALAR_STYLE);
2242 rc = yaml_emitter_emit(&output, &event);
2246 yaml_sequence_start_event_initialize(&event, NULL,
2247 (yaml_char_t *)YAML_SEQ_TAG,
2249 YAML_FLOW_SEQUENCE_STYLE);
2250 rc = yaml_emitter_emit(&output, &event);
2254 count = cfs_expr_list_values(global_cpts,
2255 LNET_MAX_SHOW_NUM_CPT,
2257 for (i = 0; i < count; i++) {
2258 char core[INT_STRING_LEN];
2260 snprintf(core, sizeof(core), "%u", cpt_array[i]);
2261 yaml_scalar_event_initialize(&event, NULL,
2262 (yaml_char_t *)YAML_STR_TAG,
2263 (yaml_char_t *)core,
2265 YAML_PLAIN_SCALAR_STYLE);
2266 rc = yaml_emitter_emit(&output, &event);
2271 yaml_sequence_end_event_initialize(&event);
2272 rc = yaml_emitter_emit(&output, &event);
2276 cfs_expr_list_free(global_cpts);
2280 yaml_mapping_end_event_initialize(&event);
2281 rc = yaml_emitter_emit(&output, &event);
2286 yaml_sequence_end_event_initialize(&event);
2287 rc = yaml_emitter_emit(&output, &event);
2291 yaml_mapping_end_event_initialize(&event);
2292 rc = yaml_emitter_emit(&output, &event);
2296 yaml_sequence_end_event_initialize(&event);
2297 rc = yaml_emitter_emit(&output, &event);
2301 yaml_mapping_end_event_initialize(&event);
2302 rc = yaml_emitter_emit(&output, &event);
2306 yaml_document_end_event_initialize(&event, 0);
2307 rc = yaml_emitter_emit(&output, &event);
2311 rc = yaml_emitter_close(&output);
2314 yaml_emitter_log_error(&output, stderr);
2317 yaml_document_t errmsg;
2319 rc = yaml_parser_load(&reply, &errmsg);
2320 if (rc == 1 && (flags & NLM_F_DUMP)) {
2321 yaml_emitter_t debug;
2323 rc = yaml_emitter_initialize(&debug);
2325 yaml_emitter_set_indent(&debug,
2326 LNET_DEFAULT_INDENT);
2327 yaml_emitter_set_output_file(&debug, fp);
2328 rc = yaml_emitter_dump(&debug, &errmsg);
2330 yaml_emitter_delete(&debug);
2332 msg = yaml_parser_get_reader_error(&reply);
2334 yaml_document_delete(&errmsg);
2336 yaml_emitter_delete(&output);
2339 yaml_lnet_print_error(flags, "net", msg);
2342 yaml_parser_delete(&reply);
2345 return rc == 1 ? 0 : rc;
2348 static int jt_add_ni(int argc, char **argv)
2350 char *ip2net = NULL;
2351 long int pto = -1, pc = -1, pbc = -1, cre = -1, cpp = -1, auth_key = -1;
2352 char *traffic_class = NULL;
2354 struct cYAML *err_rc = NULL;
2355 int rc, opt, cpt_rc = -1;
2356 struct lnet_dlc_network_descr nw_descr;
2357 struct cfs_expr_list *global_cpts = NULL;
2358 struct lnet_ioctl_config_lnd_tunables tunables;
2360 bool skip_mr_route_setup = false;
2361 const char *const short_options = "a:b:c:i:k:m:n:p:r:s:t:T:";
2362 static const struct option long_options[] = {
2363 { .name = "auth-key", .has_arg = required_argument, .val = 'a' },
2364 { .name = "peer-buffer-credits",
2365 .has_arg = required_argument, .val = 'b' },
2366 { .name = "peer-credits", .has_arg = required_argument, .val = 'c' },
2367 { .name = "if", .has_arg = required_argument, .val = 'i' },
2368 { .name = "skip-mr-route-setup",
2369 .has_arg = no_argument, .val = 'k' },
2370 { .name = "conns-per-peer",
2371 .has_arg = required_argument, .val = 'm' },
2372 { .name = "net", .has_arg = required_argument, .val = 'n' },
2373 { .name = "nid", .has_arg = required_argument, .val = 'N' },
2374 { .name = "ip2net", .has_arg = required_argument, .val = 'p' },
2375 { .name = "credits", .has_arg = required_argument, .val = 'r' },
2376 { .name = "cpt", .has_arg = required_argument, .val = 's' },
2377 { .name = "peer-timeout", .has_arg = required_argument, .val = 't' },
2378 { .name = "traffic-class", .has_arg = required_argument, .val = 'T' },
2379 { .name = "tos", .has_arg = required_argument, .val = 'S' },
2381 bool nid_request = false;
2382 char *net_id = NULL;
2384 memset(&tunables, 0, sizeof(tunables));
2385 lustre_lnet_init_nw_descr(&nw_descr);
2387 rc = check_cmd(net_cmds, "net", "add", 0, argc, argv);
2391 while ((opt = getopt_long(argc, argv, short_options,
2392 long_options, NULL)) != -1) {
2395 rc = parse_long(optarg, &auth_key);
2403 rc = parse_long(optarg, &pbc);
2411 rc = parse_long(optarg, &pc);
2419 rc = lustre_lnet_parse_interfaces(optarg, &nw_descr);
2421 cYAML_build_error(-1, -1, "ni", "add",
2422 "bad interface list",
2428 skip_mr_route_setup = true;
2431 rc = parse_long(optarg, &cpp);
2440 nw_descr.nw_id = libcfs_str2net(optarg);
2444 rc = lustre_lnet_parse_interfaces(optarg, &nw_descr);
2446 cYAML_build_error(-1, -1, "ni", "add",
2457 rc = parse_long(optarg, &cre);
2465 cpt_rc = cfs_expr_list_parse(optarg,
2467 UINT_MAX, &global_cpts);
2470 rc = parse_long(optarg, &pto);
2478 traffic_class = optarg;
2479 if (strlen(traffic_class) == 0 ||
2480 strlen(traffic_class) >= LNET_MAX_STR_LEN) {
2481 cYAML_build_error(-1, -1, "ni", "add",
2482 "Invalid traffic-class argument",
2484 rc = LUSTRE_CFG_RC_BAD_PARAM;
2489 rc = parse_long(optarg, &tos);
2490 if (rc || tos < -1 || tos > 0xff) {
2491 cYAML_build_error(-1, -1, "ni", "add",
2492 "Invalid ToS argument",
2494 rc = LUSTRE_CFG_RC_BAD_PARAM;
2499 print_help(net_cmds, "net", "add");
2507 fprintf(stdout, "--net is invalid with --nid option\n");
2510 net_id = libcfs_net2str(nw_descr.nw_id);
2513 if (auth_key > 0 && LNET_NETTYP(nw_descr.nw_id) == KFILND) {
2514 tunables.lt_tun.lnd_tun_u.lnd_kfi.lnd_auth_key = auth_key;
2518 if (traffic_class && LNET_NETTYP(nw_descr.nw_id) == KFILND &&
2519 strlen(traffic_class) < LNET_MAX_STR_LEN) {
2520 strcpy(&tunables.lt_tun.lnd_tun_u.lnd_kfi.lnd_traffic_class_str[0],
2526 if (LNET_NETTYP(nw_descr.nw_id) == SOCKLND) {
2527 tunables.lt_tun.lnd_tun_u.lnd_sock.lnd_tos = tos;
2529 } else if (LNET_NETTYP(nw_descr.nw_id) == O2IBLND) {
2530 tunables.lt_tun.lnd_tun_u.lnd_o2ib.lnd_tos = tos;
2534 if (LNET_NETTYP(nw_descr.nw_id) == SOCKLND && (cpp > -1)) {
2535 tunables.lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer = cpp;
2537 } else if (LNET_NETTYP(nw_descr.nw_id) == O2IBLND && (cpp > -1)) {
2538 tunables.lt_tun.lnd_tun_u.lnd_o2ib.lnd_conns_per_peer = cpp;
2542 if (pto >= 0 || pc > 0 || pbc > 0 || cre > 0 || cpp > -1) {
2543 tunables.lt_cmn.lct_peer_timeout = pto;
2544 tunables.lt_cmn.lct_peer_tx_credits = pc;
2545 tunables.lt_cmn.lct_peer_rtr_credits = pbc;
2546 tunables.lt_cmn.lct_max_tx_credits = cre;
2550 if (found && LNET_NETTYP(nw_descr.nw_id) == O2IBLND)
2551 tunables.lt_tun.lnd_tun_u.lnd_o2ib.lnd_map_on_demand = UINT_MAX;
2553 rc = yaml_lnet_config_ni(net_id, ip2net, &nw_descr,
2554 found ? &tunables : NULL, -1,
2555 (cpt_rc == 0) ? global_cpts : NULL,
2556 LNET_GENL_VERSION, NLM_F_CREATE, stdout);
2558 if (rc == -EOPNOTSUPP)
2560 if (global_cpts != NULL)
2561 cfs_expr_list_free(global_cpts);
2562 if (rc == 0 && !skip_mr_route_setup)
2563 rc = lustre_lnet_setup_mrrouting(&err_rc);
2567 rc = lustre_lnet_config_ni(&nw_descr,
2568 (cpt_rc == 0) ? global_cpts: NULL,
2569 ip2net, (found) ? &tunables : NULL,
2572 if (global_cpts != NULL)
2573 cfs_expr_list_free(global_cpts);
2576 if (rc != LUSTRE_CFG_RC_NO_ERR)
2577 cYAML_print_tree2file(stderr, err_rc);
2579 cYAML_free_tree(err_rc);
2581 if (rc == LUSTRE_CFG_RC_NO_ERR && !skip_mr_route_setup) {
2583 rc = lustre_lnet_setup_mrrouting(&err_rc);
2585 if (rc != LUSTRE_CFG_RC_NO_ERR)
2586 cYAML_print_tree2file(stderr, err_rc);
2588 cYAML_free_tree(err_rc);
2594 static int jt_del_route(int argc, char **argv)
2596 char *network = NULL, *gateway = NULL;
2597 struct cYAML *err_rc = NULL;
2599 const char *const short_options = "n:g:";
2600 static const struct option long_options[] = {
2601 { .name = "net", .has_arg = required_argument, .val = 'n' },
2602 { .name = "gateway", .has_arg = required_argument, .val = 'g' },
2606 rc = check_cmd(route_cmds, "route", "del", 0, argc, argv);
2610 while ((opt = getopt_long(argc, argv, short_options,
2611 long_options, NULL)) != -1) {
2620 print_help(route_cmds, "route", "del");
2626 rc = yaml_lnet_route(network, gateway, -1, -1, -1, LNET_GENL_VERSION,
2629 if (rc == -EOPNOTSUPP)
2634 rc = lustre_lnet_del_route(network, gateway, -1, &err_rc);
2636 if (rc != LUSTRE_CFG_RC_NO_ERR)
2637 cYAML_print_tree2file(stderr, err_rc);
2639 cYAML_free_tree(err_rc);
2644 static int jt_del_ni(int argc, char **argv)
2646 struct cYAML *err_rc = NULL;
2648 struct lnet_dlc_network_descr nw_descr;
2649 const char *const short_options = "n:i:";
2650 static const struct option long_options[] = {
2651 { .name = "net", .has_arg = required_argument, .val = 'n' },
2652 { .name = "if", .has_arg = required_argument, .val = 'i' },
2653 { .name = "nid", .has_arg = required_argument, .val = 'N' },
2655 bool nid_request = false;
2656 char *net_id = NULL;
2658 rc = check_cmd(net_cmds, "net", "del", 0, argc, argv);
2662 lustre_lnet_init_nw_descr(&nw_descr);
2664 while ((opt = getopt_long(argc, argv, short_options,
2665 long_options, NULL)) != -1) {
2668 nw_descr.nw_id = libcfs_str2net(optarg);
2672 rc = lustre_lnet_parse_interfaces(optarg, &nw_descr);
2674 cYAML_build_error(-1, -1, "ni", "del",
2682 rc = lustre_lnet_parse_interfaces(optarg, &nw_descr);
2684 cYAML_build_error(-1, -1, "ni", "add",
2685 "bad interface list",
2691 print_help(net_cmds, "net", "del");
2699 fprintf(stdout, "--net is invalid with --nid option\n");
2702 net_id = libcfs_net2str(nw_descr.nw_id);
2705 rc = yaml_lnet_config_ni(net_id, NULL, &nw_descr, NULL, -1, NULL,
2706 LNET_GENL_VERSION, 0, stdout);
2708 if (rc != -EOPNOTSUPP)
2712 rc = lustre_lnet_del_ni(&nw_descr, -1, &err_rc);
2714 if (rc != LUSTRE_CFG_RC_NO_ERR)
2715 cYAML_print_tree2file(stderr, err_rc);
2717 cYAML_free_tree(err_rc);
2722 static int jt_show_route(int argc, char **argv)
2724 char *network = NULL, *gateway = NULL;
2725 long int hop = -1, prio = -1;
2726 int detail = 0, rc, opt;
2727 struct cYAML *err_rc = NULL, *show_rc = NULL;
2728 const char *const short_options = "c:n:g:p:v";
2729 static const struct option long_options[] = {
2730 { .name = "net", .has_arg = required_argument, .val = 'n' },
2731 { .name = "gateway", .has_arg = required_argument, .val = 'g' },
2732 { .name = "hop-count", .has_arg = required_argument, .val = 'c' },
2733 { .name = "hop", .has_arg = required_argument, .val = 'c' },
2734 { .name = "priority", .has_arg = required_argument, .val = 'p' },
2735 { .name = "verbose", .has_arg = no_argument, .val = 'v' },
2739 rc = check_cmd(route_cmds, "route", "show", 0, argc, argv);
2743 while ((opt = getopt_long(argc, argv, short_options,
2744 long_options, NULL)) != -1) {
2753 rc = parse_long(optarg, &hop);
2761 rc = parse_long(optarg, &prio);
2772 print_help(route_cmds, "route", "show");
2778 rc = yaml_lnet_route(network, gateway, hop, prio, -1,
2779 detail, NLM_F_DUMP, stdout);
2781 if (rc == -EOPNOTSUPP)
2786 rc = lustre_lnet_show_route(network, gateway, hop, prio,
2788 &show_rc, &err_rc, false);
2790 if (rc != LUSTRE_CFG_RC_NO_ERR)
2791 cYAML_print_tree2file(stderr, err_rc);
2793 cYAML_print_tree(show_rc);
2795 cYAML_free_tree(err_rc);
2796 cYAML_free_tree(show_rc);
2801 static int set_value_helper(int argc, char **argv, int cmd,
2802 int (*cb)(int, bool, char*, int, int, struct cYAML**))
2804 char *nidstr = NULL;
2805 long int healthv = -1;
2807 long int state = -1;
2810 struct cYAML *err_rc = NULL;
2811 const char *const short_options = "t:n:m:s:a";
2812 static const struct option long_options[] = {
2813 { .name = "nid", .has_arg = required_argument, .val = 'n' },
2814 { .name = "health", .has_arg = required_argument, .val = 't' },
2815 { .name = "conns-per-peer", .has_arg = required_argument, .val = 'm' },
2816 { .name = "state", .has_arg = required_argument, .val = 's' },
2817 { .name = "all", .has_arg = no_argument, .val = 'a' },
2821 while ((opt = getopt_long(argc, argv, short_options,
2822 long_options, NULL)) != -1) {
2828 if (parse_long(optarg, &healthv) != 0)
2832 if (cmd != LNET_CMD_PEERS ||
2833 parse_long(optarg, &state) != 0)
2837 if (cmd != LNET_CMD_NETS ||
2838 parse_long(optarg, &cpp) != 0)
2850 rc = cb(healthv, all, nidstr, cmd == LNET_CMD_PEERS ? state : cpp, -1,
2852 if (rc != LUSTRE_CFG_RC_NO_ERR)
2853 cYAML_print_tree2file(stderr, err_rc);
2855 cYAML_free_tree(err_rc);
2860 int yaml_lnet_config_ni_healthv(int healthv, bool all, char *nidstr, int cpp,
2861 int seq_no, struct cYAML **err_rc)
2863 struct lnet_ioctl_config_lnd_tunables tunables;
2864 struct lnet_dlc_network_descr nw_descr;
2865 char *net_id = "<255:65535>"; /* LNET_NET_ANY */
2868 /* For NI you can't have both setting all NIDs and a requested NID */
2869 if (!all && !nidstr)
2872 if (cpp == -1 && healthv == -1)
2876 net_id = strchr(nidstr, '@');
2882 lustre_lnet_init_nw_descr(&nw_descr);
2883 nw_descr.nw_id = libcfs_str2net(net_id);
2885 rc = lustre_lnet_parse_interfaces(nidstr ? nidstr : "<?>", &nw_descr);
2886 if (rc != LUSTRE_CFG_RC_NO_ERR)
2889 memset(&tunables, 0, sizeof(tunables));
2890 tunables.lt_cmn.lct_peer_timeout = -1;
2891 if (nw_descr.nw_id == LNET_NET_ANY && cpp > -1)
2892 tunables.lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer = cpp;
2893 else if (LNET_NETTYP(nw_descr.nw_id) == SOCKLND && (cpp > -1))
2894 tunables.lt_tun.lnd_tun_u.lnd_sock.lnd_conns_per_peer = cpp;
2895 else if (LNET_NETTYP(nw_descr.nw_id) == O2IBLND && (cpp > -1))
2896 tunables.lt_tun.lnd_tun_u.lnd_o2ib.lnd_conns_per_peer = cpp;
2898 rc = yaml_lnet_config_ni(net_id, NULL, &nw_descr,
2899 cpp != -1 ? &tunables : NULL, healthv, NULL,
2900 LNET_GENL_VERSION, NLM_F_REPLACE, stdout);
2902 if (rc == -EOPNOTSUPP)
2908 rc = lustre_lnet_config_ni_conns_per_peer(cpp, all, nidstr,
2911 rc = lustre_lnet_config_ni_healthv(healthv, all, nidstr,
2916 static int jt_set_ni_value(int argc, char **argv)
2918 int rc = check_cmd(net_cmds, "net", "set", 0, argc, argv);
2923 return set_value_helper(argc, argv, LNET_CMD_NETS,
2924 yaml_lnet_config_ni_healthv);
2927 static int yaml_lnet_peer_display(yaml_parser_t *reply, bool list_only)
2929 yaml_emitter_t debug;
2932 rc = yaml_emitter_initialize(&debug);
2936 yaml_emitter_set_indent(&debug, 6);
2937 yaml_emitter_set_output_file(&debug, stdout);
2946 rc = yaml_parser_parse(reply, &event);
2948 goto report_reply_error;
2950 if (event.type != YAML_SCALAR_EVENT)
2953 value = (char *)event.data.scalar.value;
2954 if (strcmp(value, "peer") == 0) {
2955 yaml_event_delete(&event);
2957 yaml_scalar_event_initialize(&event, NULL,
2958 (yaml_char_t *)YAML_STR_TAG,
2959 (yaml_char_t *)"peer list",
2960 strlen("peer list"),
2962 YAML_PLAIN_SCALAR_STYLE);
2963 } else if (strcmp(value, "primary nid") == 0) {
2964 yaml_event_delete(&event);
2966 yaml_scalar_event_initialize(&event, NULL,
2967 (yaml_char_t *)YAML_STR_TAG,
2968 (yaml_char_t *)"nid",
2971 YAML_PLAIN_SCALAR_STYLE);
2972 rc = yaml_emitter_emit(&debug, &event);
2976 /* Now print NID address */
2977 rc = yaml_parser_parse(reply, &event);
2979 goto report_reply_error;
2981 rc = yaml_emitter_emit(&debug, &event);
2986 while (event.type != YAML_MAPPING_END_EVENT) {
2987 rc = yaml_parser_parse(reply, &event);
2989 goto report_reply_error;
2992 /* we can have map end, seq end, map end or
2993 * just map end event. If we see seq end event
2994 * then skip to next mapping end event
2996 rc = yaml_parser_parse(reply, &event);
2998 goto report_reply_error;
3000 if (event.type == YAML_SEQUENCE_END_EVENT) {
3001 yaml_event_delete(&event);
3003 rc = yaml_parser_parse(reply, &event);
3005 goto report_reply_error;
3009 rc = yaml_emitter_emit(&debug, &event);
3013 done = (event.type == YAML_DOCUMENT_END_EVENT);
3016 yaml_document_t errmsg;
3018 rc = yaml_parser_load(reply, &errmsg);
3020 rc = yaml_emitter_dump(&debug, &errmsg);
3021 yaml_document_delete(&errmsg);
3025 yaml_emitter_log_error(&debug, stderr);
3027 yaml_emitter_delete(&debug);
3032 static int yaml_lnet_peer(char *prim_nid, char *nidstr, bool disable_mr,
3033 int health_value, int state, bool list_only,
3034 int version, int flags, FILE *fp)
3036 struct nl_sock *sk = NULL;
3037 const char *msg = NULL;
3038 yaml_emitter_t output;
3039 yaml_parser_t reply;
3043 /* Create Netlink emitter to send request to kernel */
3044 sk = nl_socket_alloc();
3048 /* Setup parser to receive Netlink packets */
3049 rc = yaml_parser_initialize(&reply);
3055 rc = yaml_parser_set_input_netlink(&reply, sk, false);
3057 msg = yaml_parser_get_reader_error(&reply);
3061 /* Create Netlink emitter to send request to kernel */
3062 rc = yaml_emitter_initialize(&output);
3064 msg = "failed to initialize emitter";
3068 rc = yaml_emitter_set_output_netlink(&output, sk, LNET_GENL_NAME,
3069 version, LNET_CMD_PEERS, flags);
3073 yaml_emitter_open(&output);
3074 yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
3075 rc = yaml_emitter_emit(&output, &event);
3079 yaml_mapping_start_event_initialize(&event, NULL,
3080 (yaml_char_t *)YAML_MAP_TAG,
3081 1, YAML_ANY_MAPPING_STYLE);
3082 rc = yaml_emitter_emit(&output, &event);
3086 yaml_scalar_event_initialize(&event, NULL,
3087 (yaml_char_t *)YAML_STR_TAG,
3088 (yaml_char_t *)"peer",
3089 strlen("peer"), 1, 0,
3090 YAML_PLAIN_SCALAR_STYLE);
3091 rc = yaml_emitter_emit(&output, &event);
3096 yaml_sequence_start_event_initialize(&event, NULL,
3097 (yaml_char_t *)YAML_SEQ_TAG,
3099 YAML_BLOCK_SEQUENCE_STYLE);
3100 rc = yaml_emitter_emit(&output, &event);
3104 yaml_mapping_start_event_initialize(&event, NULL,
3105 (yaml_char_t *)YAML_MAP_TAG,
3107 YAML_BLOCK_MAPPING_STYLE);
3108 rc = yaml_emitter_emit(&output, &event);
3112 yaml_scalar_event_initialize(&event, NULL,
3113 (yaml_char_t *)YAML_STR_TAG,
3114 (yaml_char_t *)"primary nid",
3115 strlen("primary nid"), 1, 0,
3116 YAML_PLAIN_SCALAR_STYLE);
3117 rc = yaml_emitter_emit(&output, &event);
3121 yaml_scalar_event_initialize(&event, NULL,
3122 (yaml_char_t *)YAML_STR_TAG,
3123 (yaml_char_t *)prim_nid,
3124 strlen(prim_nid), 1, 0,
3125 YAML_PLAIN_SCALAR_STYLE);
3126 rc = yaml_emitter_emit(&output, &event);
3131 yaml_scalar_event_initialize(&event, NULL,
3132 (yaml_char_t *)YAML_STR_TAG,
3133 (yaml_char_t *)"Multi-Rail",
3134 strlen("Multi-Rail"), 1, 0,
3135 YAML_PLAIN_SCALAR_STYLE);
3136 rc = yaml_emitter_emit(&output, &event);
3140 yaml_scalar_event_initialize(&event, NULL,
3141 (yaml_char_t *)YAML_BOOL_TAG,
3142 (yaml_char_t *)"False",
3143 strlen("False"), 1, 0,
3144 YAML_PLAIN_SCALAR_STYLE);
3145 rc = yaml_emitter_emit(&output, &event);
3151 char peer_state[INT_STRING_LEN];
3153 yaml_scalar_event_initialize(&event, NULL,
3154 (yaml_char_t *)YAML_STR_TAG,
3155 (yaml_char_t *)"peer state",
3156 strlen("peer state"), 1, 0,
3157 YAML_PLAIN_SCALAR_STYLE);
3158 rc = yaml_emitter_emit(&output, &event);
3162 snprintf(peer_state, sizeof(peer_state), "%d", state);
3163 yaml_scalar_event_initialize(&event, NULL,
3164 (yaml_char_t *)YAML_INT_TAG,
3165 (yaml_char_t *)peer_state,
3166 strlen(peer_state), 1, 0,
3167 YAML_PLAIN_SCALAR_STYLE);
3168 rc = yaml_emitter_emit(&output, &event);
3173 if (!nidstr && health_value == -1)
3176 yaml_scalar_event_initialize(&event, NULL,
3177 (yaml_char_t *)YAML_STR_TAG,
3178 (yaml_char_t *)"peer ni",
3179 strlen("peer ni"), 1, 0,
3180 YAML_PLAIN_SCALAR_STYLE);
3181 rc = yaml_emitter_emit(&output, &event);
3185 yaml_sequence_start_event_initialize(&event, NULL,
3186 (yaml_char_t *)YAML_SEQ_TAG,
3187 1, YAML_BLOCK_SEQUENCE_STYLE);
3188 rc = yaml_emitter_emit(&output, &event);
3193 struct nid_node head, *entry;
3196 /* If we have LNET_ANY_NID and its NLM_F_REPLACE we
3197 * treat it as the all flag case for lnetctl peer set
3199 if (strcmp(nidstr, "<?>") == 0) {
3200 yaml_mapping_start_event_initialize(&event, NULL,
3201 (yaml_char_t *)YAML_MAP_TAG,
3202 1, YAML_BLOCK_MAPPING_STYLE);
3203 rc = yaml_emitter_emit(&output, &event);
3207 yaml_scalar_event_initialize(&event, NULL,
3208 (yaml_char_t *)YAML_STR_TAG,
3209 (yaml_char_t *)"nid",
3210 strlen("nid"), 1, 0,
3211 YAML_PLAIN_SCALAR_STYLE);
3212 rc = yaml_emitter_emit(&output, &event);
3216 yaml_scalar_event_initialize(&event, NULL,
3217 (yaml_char_t *)YAML_STR_TAG,
3218 (yaml_char_t *)nidstr,
3219 strlen(nidstr), 1, 0,
3220 YAML_PLAIN_SCALAR_STYLE);
3221 rc = yaml_emitter_emit(&output, &event);
3225 yaml_mapping_end_event_initialize(&event);
3226 rc = yaml_emitter_emit(&output, &event);
3233 NL_INIT_LIST_HEAD(&head.children);
3234 nl_init_list_head(&head.list);
3235 rc = lustre_lnet_parse_nid_range(&head, nidstr, &msg);
3237 fprintf(stdout, "can't parse nidrange: \"%s\"\n", nidstr);
3238 lustre_lnet_free_list(&head);
3239 yaml_emitter_delete(&output);
3245 if (nl_list_empty(&head.children)) {
3246 lustre_lnet_free_list(&head);
3247 yaml_emitter_delete(&output);
3248 msg = "Unable to parse nidlist: did not expand to any nids";
3253 rc = 1; /* one means its working */
3255 nl_list_for_each_entry(entry, &head.children, list) {
3256 char *nid = entry->nidstr;
3258 if (count++ > LNET_MAX_NIDS_PER_PEER) {
3259 lustre_lnet_free_list(&head);
3260 yaml_emitter_delete(&output);
3261 msg = "Unable to parse nidlist: specifies more NIDs than allowed";
3267 yaml_mapping_start_event_initialize(&event, NULL,
3268 (yaml_char_t *)YAML_MAP_TAG,
3269 1, YAML_BLOCK_MAPPING_STYLE);
3270 rc = yaml_emitter_emit(&output, &event);
3274 yaml_scalar_event_initialize(&event, NULL,
3275 (yaml_char_t *)YAML_STR_TAG,
3276 (yaml_char_t *)"nid",
3277 strlen("nid"), 1, 0,
3278 YAML_PLAIN_SCALAR_STYLE);
3279 rc = yaml_emitter_emit(&output, &event);
3283 yaml_scalar_event_initialize(&event, NULL,
3284 (yaml_char_t *)YAML_STR_TAG,
3287 YAML_PLAIN_SCALAR_STYLE);
3288 rc = yaml_emitter_emit(&output, &event);
3292 yaml_mapping_end_event_initialize(&event);
3293 rc = yaml_emitter_emit(&output, &event);
3297 lustre_lnet_free_list(&head);
3300 if (health_value >= 0) {
3301 char health[INT_STRING_LEN];
3303 /* Create the mapping for 'health stats'. The value field for
3304 * the mapping is not provided so its treated as a empty string.
3306 yaml_mapping_start_event_initialize(&event, NULL,
3307 (yaml_char_t *)YAML_MAP_TAG,
3308 1, YAML_BLOCK_MAPPING_STYLE);
3309 rc = yaml_emitter_emit(&output, &event);
3313 yaml_scalar_event_initialize(&event, NULL,
3314 (yaml_char_t *)YAML_STR_TAG,
3315 (yaml_char_t *)"health stats",
3316 strlen("health stats"), 1, 0,
3317 YAML_PLAIN_SCALAR_STYLE);
3318 rc = yaml_emitter_emit(&output, &event);
3322 /* Setup all mappings for data related to the 'health stats' */
3323 yaml_mapping_start_event_initialize(&event, NULL,
3324 (yaml_char_t *)YAML_MAP_TAG,
3325 1, YAML_BLOCK_MAPPING_STYLE);
3326 rc = yaml_emitter_emit(&output, &event);
3330 yaml_scalar_event_initialize(&event, NULL,
3331 (yaml_char_t *)YAML_STR_TAG,
3332 (yaml_char_t *)"health value",
3333 strlen("health value"), 1, 0,
3334 YAML_PLAIN_SCALAR_STYLE);
3335 rc = yaml_emitter_emit(&output, &event);
3339 snprintf(health, sizeof(health), "%d", health_value);
3340 yaml_scalar_event_initialize(&event, NULL,
3341 (yaml_char_t *)YAML_INT_TAG,
3342 (yaml_char_t *)health,
3343 strlen(health), 1, 0,
3344 YAML_PLAIN_SCALAR_STYLE);
3345 rc = yaml_emitter_emit(&output, &event);
3349 yaml_mapping_end_event_initialize(&event);
3350 rc = yaml_emitter_emit(&output, &event);
3354 yaml_mapping_end_event_initialize(&event);
3355 rc = yaml_emitter_emit(&output, &event);
3360 yaml_sequence_end_event_initialize(&event);
3361 rc = yaml_emitter_emit(&output, &event);
3365 yaml_mapping_end_event_initialize(&event);
3366 rc = yaml_emitter_emit(&output, &event);
3370 yaml_sequence_end_event_initialize(&event);
3371 rc = yaml_emitter_emit(&output, &event);
3375 yaml_scalar_event_initialize(&event, NULL,
3376 (yaml_char_t *)YAML_STR_TAG,
3379 YAML_PLAIN_SCALAR_STYLE);
3380 rc = yaml_emitter_emit(&output, &event);
3385 yaml_mapping_end_event_initialize(&event);
3386 rc = yaml_emitter_emit(&output, &event);
3390 yaml_document_end_event_initialize(&event, 0);
3391 rc = yaml_emitter_emit(&output, &event);
3395 rc = yaml_emitter_close(&output);
3398 yaml_emitter_log_error(&output, stderr);
3401 rc = yaml_lnet_peer_display(&reply, list_only);
3403 msg = yaml_parser_get_reader_error(&reply);
3404 /* If we didn't find any peers just be silent */
3405 if (msg && strcmp(msg, "No peers found") == 0)
3410 yaml_emitter_delete(&output);
3413 yaml_lnet_print_error(flags, "peer", msg);
3416 yaml_parser_delete(&reply);
3419 return rc == 1 ? 0 : rc;
3422 int yaml_lnet_config_peer_ni_healthv(int healthv, bool all, char *lpni_nid,
3423 int state, int seq_no, struct cYAML **err_rc)
3427 rc = yaml_lnet_peer(lpni_nid ? lpni_nid : "<?>", all ? "<?>" : NULL,
3428 false, healthv, state, false, LNET_GENL_VERSION,
3429 NLM_F_REPLACE, stdout);
3431 if (rc == -EOPNOTSUPP)
3437 rc = lustre_lnet_config_peer_ni_healthv(healthv, all, lpni_nid,
3440 rc = lustre_lnet_set_peer_state(state, lpni_nid, -1, err_rc);
3445 static int jt_set_peer_ni_value(int argc, char **argv)
3447 int rc = check_cmd(peer_cmds, "peer", "set", 0, argc, argv);
3452 return set_value_helper(argc, argv, LNET_CMD_PEERS,
3453 yaml_lnet_config_peer_ni_healthv);
3456 static int jt_show_recovery(int argc, char **argv)
3459 struct cYAML *err_rc = NULL, *show_rc = NULL;
3460 const char *const short_options = "lp";
3461 static const struct option long_options[] = {
3462 { .name = "local", .has_arg = no_argument, .val = 'l' },
3463 { .name = "peer", .has_arg = no_argument, .val = 'p' },
3466 rc = check_cmd(debug_cmds, "debug", "recovery", 0, argc, argv);
3470 while ((opt = getopt_long(argc, argv, short_options,
3471 long_options, NULL)) != -1) {
3474 rc = lustre_lnet_show_local_ni_recovq(-1, &show_rc, &err_rc);
3477 rc = lustre_lnet_show_peer_ni_recovq(-1, &show_rc, &err_rc);
3484 if (rc != LUSTRE_CFG_RC_NO_ERR)
3485 cYAML_print_tree2file(stderr, err_rc);
3487 cYAML_print_tree(show_rc);
3489 cYAML_free_tree(err_rc);
3490 cYAML_free_tree(show_rc);
3495 static int jt_show_peer_debug_info(int argc, char **argv)
3498 struct cYAML *err_rc = NULL;
3499 char *peer_nid = optarg;
3500 const char *const short_opts = "k";
3501 const struct option long_opts[] = {
3502 { .name = "nid", .has_arg = required_argument, .val = 'k' },
3505 rc = check_cmd(debug_cmds, "debug", "peer", 0, argc, argv);
3510 while ((opt = getopt_long(argc, argv, short_opts,
3511 long_opts, NULL)) != -1) {
3521 rc = lustre_lnet_show_peer_debug_info(peer_nid, -1, &err_rc);
3523 if (rc != LUSTRE_CFG_RC_NO_ERR)
3524 cYAML_print_tree2file(stderr, err_rc);
3526 cYAML_free_tree(err_rc);
3531 static int jt_show_net(int argc, char **argv)
3533 char *network = NULL;
3535 struct cYAML *err_rc = NULL, *show_rc = NULL;
3536 long int detail = 0;
3537 const char *const short_options = "n:v";
3538 static const struct option long_options[] = {
3539 { .name = "net", .has_arg = required_argument, .val = 'n' },
3540 { .name = "verbose", .has_arg = optional_argument, .val = 'v' },
3543 rc = check_cmd(net_cmds, "net", "show", 0, argc, argv);
3547 while ((opt = getopt_long(argc, argv, short_options,
3548 long_options, NULL)) != -1) {
3554 if ((!optarg) && (argv[optind] != NULL) &&
3555 (argv[optind][0] != '-')) {
3556 if (parse_long(argv[optind++], &detail) != 0)
3563 print_help(net_cmds, "net", "show");
3569 rc = yaml_lnet_config_ni(network, NULL, NULL, NULL, -1, NULL,
3570 detail, NLM_F_DUMP, stdout);
3572 if (rc != -EOPNOTSUPP)
3576 rc = lustre_lnet_show_net(network, (int) detail, -1, &show_rc, &err_rc,
3579 if (rc != LUSTRE_CFG_RC_NO_ERR)
3580 cYAML_print_tree2file(stderr, err_rc);
3582 cYAML_print_tree(show_rc);
3584 cYAML_free_tree(err_rc);
3585 cYAML_free_tree(show_rc);
3590 static int jt_show_routing(int argc, char **argv)
3592 struct cYAML *err_rc = NULL, *show_rc = NULL;
3595 rc = check_cmd(routing_cmds, "routing", "show", 0, argc, argv);
3599 rc = lustre_lnet_show_routing(-1, &show_rc, &err_rc, false);
3601 if (rc != LUSTRE_CFG_RC_NO_ERR)
3602 cYAML_print_tree2file(stderr, err_rc);
3604 cYAML_print_tree(show_rc);
3606 cYAML_free_tree(err_rc);
3607 cYAML_free_tree(show_rc);
3612 static int jt_show_stats(int argc, char **argv)
3615 struct cYAML *show_rc = NULL, *err_rc = NULL;
3617 rc = check_cmd(stats_cmds, "stats", "show", 0, argc, argv);
3621 rc = lustre_lnet_show_stats(-1, &show_rc, &err_rc);
3623 if (rc != LUSTRE_CFG_RC_NO_ERR)
3624 cYAML_print_tree2file(stderr, err_rc);
3626 cYAML_print_tree(show_rc);
3628 cYAML_free_tree(err_rc);
3629 cYAML_free_tree(show_rc);
3634 static int jt_show_udsp(int argc, char **argv)
3638 struct cYAML *err_rc = NULL, *show_rc = NULL;
3640 const char *const short_options = "i:";
3641 static const struct option long_options[] = {
3642 { .name = "idx", .has_arg = required_argument, .val = 'i' },
3646 rc = check_cmd(udsp_cmds, "udsp", "show", 0, argc, argv);
3650 while ((opt = getopt_long(argc, argv, short_options,
3651 long_options, NULL)) != -1) {
3654 rc = parse_long(optarg, &idx);
3655 if (rc != 0 || idx < -1) {
3656 printf("Invalid index \"%s\"\n", optarg);
3661 print_help(net_cmds, "net", "show");
3667 rc = lustre_lnet_show_udsp(idx, -1, &show_rc, &err_rc);
3669 if (rc != LUSTRE_CFG_RC_NO_ERR)
3670 cYAML_print_tree2file(stderr, err_rc);
3672 cYAML_print_tree(show_rc);
3674 cYAML_free_tree(err_rc);
3675 cYAML_free_tree(show_rc);
3680 static int jt_show_global(int argc, char **argv)
3683 struct cYAML *show_rc = NULL, *err_rc = NULL;
3685 rc = check_cmd(global_cmds, "global", "show", 0, argc, argv);
3689 rc = lustre_lnet_show_numa_range(-1, &show_rc, &err_rc);
3690 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3691 cYAML_print_tree2file(stderr, err_rc);
3695 rc = lustre_lnet_show_max_intf(-1, &show_rc, &err_rc);
3696 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3697 cYAML_print_tree2file(stderr, err_rc);
3701 rc = lustre_lnet_show_discovery(-1, &show_rc, &err_rc);
3702 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3703 cYAML_print_tree2file(stderr, err_rc);
3707 rc = lustre_lnet_show_drop_asym_route(-1, &show_rc, &err_rc);
3708 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3709 cYAML_print_tree2file(stderr, err_rc);
3713 rc = lustre_lnet_show_retry_count(-1, &show_rc, &err_rc);
3714 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3715 cYAML_print_tree2file(stderr, err_rc);
3719 rc = lustre_lnet_show_transaction_to(-1, &show_rc, &err_rc);
3720 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3721 cYAML_print_tree2file(stderr, err_rc);
3725 rc = lustre_lnet_show_hsensitivity(-1, &show_rc, &err_rc);
3726 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3727 cYAML_print_tree2file(stderr, err_rc);
3731 rc = lustre_lnet_show_recov_intrv(-1, &show_rc, &err_rc);
3732 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3733 cYAML_print_tree2file(stderr, err_rc);
3737 rc = lustre_lnet_show_rtr_sensitivity(-1, &show_rc, &err_rc);
3738 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3739 cYAML_print_tree2file(stderr, err_rc);
3743 rc = lustre_lnet_show_lnd_timeout(-1, &show_rc, &err_rc);
3744 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3745 cYAML_print_tree2file(stderr, err_rc);
3749 rc = lustre_lnet_show_response_tracking(-1, &show_rc, &err_rc);
3750 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3751 cYAML_print_tree2file(stderr, err_rc);
3755 rc = lustre_lnet_show_recovery_limit(-1, &show_rc, &err_rc);
3756 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3757 cYAML_print_tree2file(stderr, err_rc);
3761 rc = lustre_lnet_show_max_recovery_ping_interval(-1, &show_rc, &err_rc);
3762 if (rc != LUSTRE_CFG_RC_NO_ERR) {
3763 cYAML_print_tree2file(stderr, err_rc);
3768 cYAML_print_tree(show_rc);
3771 cYAML_free_tree(err_rc);
3772 cYAML_free_tree(show_rc);
3777 static int jt_lnet(int argc, char **argv)
3781 rc = check_cmd(lnet_cmds, "lnet", NULL, 2, argc, argv);
3785 return cfs_parser(argc, argv, lnet_cmds);
3788 static int jt_route(int argc, char **argv)
3792 rc = check_cmd(route_cmds, "route", NULL, 2, argc, argv);
3796 return cfs_parser(argc, argv, route_cmds);
3799 static int jt_net(int argc, char **argv)
3803 rc = check_cmd(net_cmds, "net", NULL, 2, argc, argv);
3807 return cfs_parser(argc, argv, net_cmds);
3810 static int jt_routing(int argc, char **argv)
3814 rc = check_cmd(routing_cmds, "routing", NULL, 2, argc, argv);
3818 return cfs_parser(argc, argv, routing_cmds);
3821 static int jt_stats(int argc, char **argv)
3825 rc = check_cmd(stats_cmds, "stats", NULL, 2, argc, argv);
3829 return cfs_parser(argc, argv, stats_cmds);
3832 static int jt_debug(int argc, char **argv)
3836 rc = check_cmd(debug_cmds, "debug", NULL, 2, argc, argv);
3840 return cfs_parser(argc, argv, debug_cmds);
3843 static int jt_global(int argc, char **argv)
3847 rc = check_cmd(global_cmds, "global", NULL, 2, argc, argv);
3851 return cfs_parser(argc, argv, global_cmds);
3854 static int jt_peers(int argc, char **argv)
3858 rc = check_cmd(peer_cmds, "peer", NULL, 2, argc, argv);
3862 return cfs_parser(argc, argv, peer_cmds);
3865 static int jt_set(int argc, char **argv)
3869 rc = check_cmd(set_cmds, "set", NULL, 2, argc, argv);
3873 return cfs_parser(argc, argv, set_cmds);
3876 static int jt_udsp(int argc, char **argv)
3880 rc = check_cmd(udsp_cmds, "udsp", NULL, 2, argc, argv);
3884 return cfs_parser(argc, argv, udsp_cmds);
3887 static int yaml_import_global_settings(char *key, unsigned long value,
3888 char cmd, struct cYAML *show_rc,
3889 struct cYAML *err_rc)
3893 if (strcmp("numa_range", key) == 0) {
3894 if (cmd == 'a' || cmd == 'd') {
3897 rc = lustre_lnet_config_numa_range(value, -1,
3899 } else if (cmd == 's') {
3900 rc = lustre_lnet_show_numa_range(-1, &show_rc,
3903 } else if (strcmp("max_interfaces", key) == 0 ||
3904 strcmp("max_intf", key) == 0) {
3905 if (cmd == 'a' || cmd == 'd') {
3907 value = LNET_INTERFACES_MAX_DEFAULT;
3908 rc = lustre_lnet_config_max_intf(value, -1,
3910 } else if (cmd == 's') {
3911 rc = lustre_lnet_show_max_intf(-1, &show_rc,
3914 } else if (strcmp("discovery", key) == 0) {
3915 if (cmd == 'a' || cmd == 'd') {
3918 rc = lustre_lnet_config_discovery(value, -1,
3920 } else if (cmd == 's') {
3921 rc = lustre_lnet_show_discovery(-1, &show_rc,
3924 } else if (strcmp("drop_asym_route", key) == 0) {
3926 rc = lustre_lnet_config_drop_asym_route(value,
3929 } else if (cmd == 's') {
3930 rc = lustre_lnet_show_drop_asym_route(-1, &show_rc,
3933 } else if (strcmp("retry_count", key) == 0) {
3935 rc = lustre_lnet_config_retry_count(value, -1,
3937 } else if (cmd == 's') {
3938 rc = lustre_lnet_show_retry_count(-1, &show_rc,
3941 } else if (strcmp("transaction_timeout", key) == 0) {
3943 rc = lustre_lnet_config_transaction_to(value, -1,
3945 } else if (cmd == 's') {
3946 rc = lustre_lnet_show_transaction_to(-1, &show_rc,
3949 } else if (strcmp("health_sensitivity", key) == 0) {
3951 rc = lustre_lnet_config_hsensitivity(value, -1,
3953 } else if (cmd == 's') {
3954 rc = lustre_lnet_show_hsensitivity(-1, &show_rc,
3957 } else if (strcmp("recovery_interval", key) == 0) {
3959 rc = lustre_lnet_config_recov_intrv(value, -1,
3961 } else if (cmd == 's') {
3962 rc = lustre_lnet_show_recov_intrv(-1, &show_rc,
3965 } else if (strcmp("router_sensitivity", key) == 0) {
3967 rc = lustre_lnet_config_rtr_sensitivity(value, -1,
3969 } else if (cmd == 's') {
3970 rc = lustre_lnet_show_rtr_sensitivity(-1, &show_rc,
3973 } else if (strcmp("lnd_timeout", key) == 0) {
3975 } else if (cmd == 's') {
3976 rc = lustre_lnet_show_lnd_timeout(-1, &show_rc,
3979 } else if (strcmp("response_tracking", key) == 0) {
3981 rc = lustre_lnet_config_response_tracking(value, -1,
3983 } else if (cmd == 's') {
3984 rc = lustre_lnet_show_response_tracking(-1, &show_rc,
3987 } else if (strcmp("recovery_limit", key) == 0) {
3989 rc = lustre_lnet_config_recovery_limit(value, -1,
3991 } else if (cmd == 's') {
3992 rc = lustre_lnet_show_recovery_limit(-1, &show_rc,
3995 } else if (strcmp("max_recovery_ping_interval", key) == 0) {
3997 rc = lustre_lnet_config_max_recovery_ping_interval(value, -1,
3999 } else if (cmd == 's') {
4000 rc = lustre_lnet_show_max_recovery_ping_interval(-1, &show_rc,
4008 static int jt_import(int argc, char **argv)
4011 struct cYAML *err_rc = NULL;
4012 struct cYAML *show_rc = NULL;
4013 int rc = 0, return_rc = 0, opt, opt_found = 0;
4014 char *yaml_blk = NULL, *buf, cmd = 'a';
4015 int flags = NLM_F_CREATE;
4016 bool release = true;
4021 const char *const short_options = "adseh";
4022 static const struct option long_options[] = {
4023 { .name = "add", .has_arg = no_argument, .val = 'a' },
4024 { .name = "del", .has_arg = no_argument, .val = 'd' },
4025 { .name = "show", .has_arg = no_argument, .val = 's' },
4026 { .name = "exec", .has_arg = no_argument, .val = 'e' },
4027 { .name = "help", .has_arg = no_argument, .val = 'h' },
4030 bool done = false, unspec = true;
4031 yaml_parser_t setup, reply;
4032 struct nl_sock *sk = NULL;
4033 int op = LNET_CMD_UNSPEC;
4034 const char *msg = NULL;
4035 yaml_emitter_t output;
4038 while ((opt = getopt_long(argc, argv, short_options,
4039 long_options, NULL)) != -1) {
4043 /* default is NLM_F_CREATE */
4047 flags = 0; /* Netlink delete cmd */
4055 /* use NLM_F_CREATE for discover */
4059 printf("import FILE\n"
4060 "import < FILE : import a file\n"
4061 "\t--add: add configuration\n"
4062 "\t--del: delete configuration\n"
4063 "\t--show: show configuration\n"
4064 "\t--exec: execute command\n"
4065 "\t--help: display this help\n"
4066 "If no command option is given then --add"
4067 " is assumed by default\n");
4074 /* grab the file name if one exists */
4075 if (opt_found && argc == 3)
4077 else if (!opt_found && argc == 2)
4080 /* file always takes precedence */
4082 /* Set a file input. */
4083 input = fopen(file, "rb");
4086 snprintf(err_str, sizeof(err_str),
4087 "cannot open '%s': %s", file,
4089 cYAML_build_error(-1, -1, "yaml", "builder",
4098 /* Create Netlink emitter to send request to kernel */
4099 sk = nl_socket_alloc();
4103 /* Setup parser to receive Netlink packets */
4104 rc = yaml_parser_initialize(&reply);
4110 rc = yaml_parser_set_input_netlink(&reply, sk, false);
4112 msg = yaml_parser_get_reader_error(&reply);
4116 /* Initialize configuration parser */
4117 rc = yaml_parser_initialize(&setup);
4119 yaml_parser_log_error(&setup, stderr, "import: ");
4120 yaml_parser_delete(&setup);
4124 yaml_parser_set_input_file(&setup, input);
4127 if (!yaml_parser_parse(&setup, &event)) {
4128 yaml_parser_log_error(&setup, stderr, "import: ");
4132 if (event.type != YAML_SCALAR_EVENT)
4135 if (!strcmp((char *)event.data.scalar.value, "net") &&
4136 op != LNET_CMD_ROUTES && cmd != 'e') {
4137 if (op != LNET_CMD_UNSPEC) {
4138 rc = yaml_netlink_complete_emitter(&output);
4144 rc = yaml_netlink_setup_emitter(&output, sk,
4152 } else if (!strcmp((char *)event.data.scalar.value, "peer") &&
4154 if (op != LNET_CMD_UNSPEC) {
4155 rc = yaml_netlink_complete_emitter(&output);
4159 op = LNET_CMD_PEERS;
4161 rc = yaml_netlink_setup_emitter(&output, sk,
4169 } else if (!strcmp((char *)event.data.scalar.value, "route") &&
4171 if (op != LNET_CMD_UNSPEC) {
4172 rc = yaml_netlink_complete_emitter(&output);
4176 op = LNET_CMD_ROUTES;
4178 rc = yaml_netlink_setup_emitter(&output, sk,
4186 } else if ((!strcmp((char *)event.data.scalar.value, "discover") ||
4187 !strcmp((char *)event.data.scalar.value, "ping")) &&
4189 if (op != LNET_CMD_UNSPEC) {
4190 rc = yaml_netlink_complete_emitter(&output);
4196 if (!strcmp((char *)event.data.scalar.value, "ping"))
4199 rc = yaml_netlink_setup_emitter(&output, sk,
4207 } else if (!strcmp((char *)event.data.scalar.value, "global")) {
4208 if (op != LNET_CMD_UNSPEC) {
4209 rc = yaml_netlink_complete_emitter(&output);
4213 op = LNET_CMD_UNSPEC;
4214 } else if (op == LNET_CMD_UNSPEC) {
4215 struct cYAML *err_rc = NULL;
4219 key = strdup((char *)event.data.scalar.value);
4220 rc = yaml_parser_parse(&setup, &event);
4224 rc = parse_long((char *)event.data.scalar.value,
4229 rc = yaml_import_global_settings(key, value, cmd,
4231 if (rc != LUSTRE_CFG_RC_NO_ERR)
4232 cYAML_print_tree2file(stderr, err_rc);
4237 if (op != LNET_CMD_UNSPEC) {
4238 rc = yaml_emitter_emit(&output, &event);
4243 done = (event.type == YAML_STREAM_END_EVENT);
4247 yaml_emitter_log_error(&output, stderr);
4248 yaml_emitter_delete(&output);
4250 } else if (!unspec) {
4251 yaml_document_t errmsg;
4253 rc = yaml_parser_load(&reply, &errmsg);
4254 if (rc == 1 && (flags & NLM_F_DUMP)) {
4255 yaml_emitter_t debug;
4257 rc = yaml_emitter_initialize(&debug);
4259 yaml_emitter_set_indent(&debug,
4260 LNET_DEFAULT_INDENT);
4261 yaml_emitter_set_output_file(&debug,
4263 rc = yaml_emitter_dump(&debug, &errmsg);
4265 yaml_emitter_delete(&debug);
4267 msg = yaml_parser_get_reader_error(&reply);
4269 yaml_emitter_delete(&output);
4270 yaml_document_delete(&errmsg);
4274 yaml_lnet_print_error(flags, "import", msg);
4277 yaml_parser_delete(&reply);
4278 yaml_parser_delete(&setup);
4283 return rc == 1 ? 0 : rc;
4285 /* assume that we're getting our input from stdin */
4286 rc = fstat(fileno(input), &st);
4288 snprintf(err_str, sizeof(err_str),
4289 "cannot get file stats '%s': %s", file,
4291 cYAML_build_error(-1, -1, "yaml", "builder",
4297 yaml_blk = buf = malloc(st.st_size);
4300 snprintf(err_str, sizeof(err_str),
4301 "failed to allocate buffer: %s",
4303 cYAML_build_error(-1, -1, "yaml", "builder",
4310 while (fgets(buf, len, input) != NULL) {
4311 char *seq = strstr(buf, "- ");
4317 skip = strspn(seq, " ");
4322 /* PyYAML format has libyaml free the
4333 rc = lustre_yaml_config(yaml_blk, st.st_size, &err_rc);
4334 return_rc = lustre_yaml_exec(yaml_blk, st.st_size, &show_rc,
4336 cYAML_print_tree(show_rc);
4337 cYAML_free_tree(show_rc);
4340 rc = lustre_yaml_del(yaml_blk, st.st_size, &err_rc);
4343 rc = lustre_yaml_show(yaml_blk, st.st_size, &show_rc,
4345 cYAML_print_tree(show_rc);
4346 cYAML_free_tree(show_rc);
4349 rc = lustre_yaml_exec(yaml_blk, st.st_size, &show_rc,
4351 cYAML_print_tree(show_rc);
4352 cYAML_free_tree(show_rc);
4356 if (yaml_blk && release)
4358 if (rc || return_rc) {
4359 cYAML_print_tree2file(stderr, err_rc);
4360 cYAML_free_tree(err_rc);
4366 static int jt_export(int argc, char **argv)
4368 struct cYAML *show_rc = NULL;
4369 struct cYAML *err_rc = NULL;
4370 int flags = NLM_F_DUMP;
4374 bool backup = false;
4376 const char *const short_options = "bh";
4377 static const struct option long_options[] = {
4378 { .name = "backup", .has_arg = no_argument, .val = 'b' },
4379 { .name = "help", .has_arg = no_argument, .val = 'h' },
4383 while ((opt = getopt_long(argc, argv, short_options,
4384 long_options, NULL)) != -1) {
4387 flags |= NLM_F_DUMP_FILTERED;
4392 printf("export > FILE.yaml : export configuration\n"
4393 "\t--backup: export only what's necessary for reconfig\n"
4394 "\t--help: display this help\n");
4399 if (backup && argc >= 3)
4401 else if (!backup && argc >= 2)
4407 f = fopen(file, "w");
4412 rc = yaml_lnet_config_ni(NULL, NULL, NULL, NULL, -1, NULL,
4413 flags & NLM_F_DUMP_FILTERED ? 1 : 2,
4416 if (rc == -EOPNOTSUPP)
4420 rc = yaml_lnet_route(NULL, NULL, -1, -1, -1, LNET_GENL_VERSION,
4423 if (rc == -EOPNOTSUPP)
4427 rc = lustre_lnet_show_routing(-1, &show_rc, &err_rc, backup);
4428 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4429 cYAML_print_tree2file(f, err_rc);
4430 cYAML_free_tree(err_rc);
4434 rc = yaml_lnet_peer(NULL, NULL, false, -1, false, false,
4435 flags & NLM_F_DUMP_FILTERED ? 0 : 3,
4438 if (rc == -EOPNOTSUPP)
4444 rc = lustre_lnet_show_net(NULL, 2, -1, &show_rc, &err_rc, backup);
4445 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4446 cYAML_print_tree2file(f, err_rc);
4447 cYAML_free_tree(err_rc);
4451 rc = lustre_lnet_show_route(NULL, NULL, -1, -1, 1, -1, &show_rc,
4453 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4454 cYAML_print_tree2file(f, err_rc);
4455 cYAML_free_tree(err_rc);
4459 rc = lustre_lnet_show_routing(-1, &show_rc, &err_rc, backup);
4460 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4461 cYAML_print_tree2file(f, err_rc);
4462 cYAML_free_tree(err_rc);
4466 rc = lustre_lnet_show_peer(NULL, 2, -1, &show_rc, &err_rc, backup);
4467 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4468 cYAML_print_tree2file(f, err_rc);
4469 cYAML_free_tree(err_rc);
4473 rc = lustre_lnet_show_numa_range(-1, &show_rc, &err_rc);
4474 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4475 cYAML_print_tree2file(f, err_rc);
4476 cYAML_free_tree(err_rc);
4480 rc = lustre_lnet_show_max_intf(-1, &show_rc, &err_rc);
4481 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4482 cYAML_print_tree2file(f, err_rc);
4483 cYAML_free_tree(err_rc);
4487 rc = lustre_lnet_show_discovery(-1, &show_rc, &err_rc);
4488 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4489 cYAML_print_tree2file(f, err_rc);
4490 cYAML_free_tree(err_rc);
4494 rc = lustre_lnet_show_drop_asym_route(-1, &show_rc, &err_rc);
4495 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4496 cYAML_print_tree2file(f, err_rc);
4497 cYAML_free_tree(err_rc);
4501 rc = lustre_lnet_show_retry_count(-1, &show_rc, &err_rc);
4502 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4503 cYAML_print_tree2file(f, err_rc);
4507 rc = lustre_lnet_show_transaction_to(-1, &show_rc, &err_rc);
4508 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4509 cYAML_print_tree2file(f, err_rc);
4513 rc = lustre_lnet_show_hsensitivity(-1, &show_rc, &err_rc);
4514 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4515 cYAML_print_tree2file(f, err_rc);
4519 rc = lustre_lnet_show_recov_intrv(-1, &show_rc, &err_rc);
4520 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4521 cYAML_print_tree2file(f, err_rc);
4525 rc = lustre_lnet_show_rtr_sensitivity(-1, &show_rc, &err_rc);
4526 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4527 cYAML_print_tree2file(f, err_rc);
4531 rc = lustre_lnet_show_lnd_timeout(-1, &show_rc, &err_rc);
4532 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4533 cYAML_print_tree2file(f, err_rc);
4537 rc = lustre_lnet_show_response_tracking(-1, &show_rc, &err_rc);
4538 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4539 cYAML_print_tree2file(f, err_rc);
4540 cYAML_free_tree(err_rc);
4544 rc = lustre_lnet_show_recovery_limit(-1, &show_rc, &err_rc);
4545 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4546 cYAML_print_tree2file(f, err_rc);
4547 cYAML_free_tree(err_rc);
4551 rc = lustre_lnet_show_max_recovery_ping_interval(-1, &show_rc, &err_rc);
4552 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4553 cYAML_print_tree2file(f, err_rc);
4554 cYAML_free_tree(err_rc);
4558 rc = lustre_lnet_show_udsp(-1, -1, &show_rc, &err_rc);
4559 if (rc != LUSTRE_CFG_RC_NO_ERR) {
4560 cYAML_print_tree2file(f, err_rc);
4561 cYAML_free_tree(err_rc);
4565 if (show_rc != NULL) {
4566 cYAML_print_tree2file(f, show_rc);
4567 cYAML_free_tree(show_rc);
4576 static int jt_peer_nid_common(int argc, char **argv, int cmd)
4578 int flags = cmd == LNETCTL_ADD_CMD ? NLM_F_CREATE : 0;
4579 int rc = LUSTRE_CFG_RC_NO_ERR, opt;
4581 char *prim_nid = NULL, *nidstr = NULL;
4582 char err_str[LNET_MAX_STR_LEN] = "Error";
4583 struct cYAML *err_rc = NULL;
4585 const char *const short_opts = "k:m:n:f:l";
4586 const struct option long_opts[] = {
4587 { .name = "prim_nid", .has_arg = required_argument, .val = 'k' },
4588 { .name = "non_mr", .has_arg = no_argument, .val = 'm' },
4589 { .name = "nid", .has_arg = required_argument, .val = 'n' },
4590 { .name = "force", .has_arg = no_argument, .val = 'f' },
4591 { .name = "lock_prim", .has_arg = no_argument, .val = 'l' },
4594 rc = check_cmd(peer_cmds, "peer",
4595 cmd == LNETCTL_ADD_CMD ? "add" : "del", 2, argc, argv);
4599 while ((opt = getopt_long(argc, argv, short_opts,
4600 long_opts, NULL)) != -1) {
4609 if (cmd == LNETCTL_DEL_CMD) {
4610 rc = LUSTRE_CFG_RC_BAD_PARAM;
4611 snprintf(err_str, LNET_MAX_STR_LEN,
4612 "Unrecognized option '-%c'", opt);
4618 if (cmd == LNETCTL_ADD_CMD) {
4619 rc = LUSTRE_CFG_RC_BAD_PARAM;
4620 snprintf(err_str, LNET_MAX_STR_LEN,
4621 "Unrecognized option '-%c'", opt);
4624 flags |= NLM_F_EXCL;
4627 if (cmd == LNETCTL_DEL_CMD) {
4628 rc = LUSTRE_CFG_RC_BAD_PARAM;
4629 snprintf(err_str, LNET_MAX_STR_LEN,
4630 "Unrecognized option '-%c'", opt);
4633 flags |= NLM_F_EXCL;
4636 print_help(peer_cmds, "peer",
4637 cmd == LNETCTL_ADD_CMD ? "add" : "del");
4643 rc = yaml_lnet_peer(prim_nid, nidstr, !is_mr, -1, -1, false,
4644 LNET_GENL_VERSION, flags, stdout);
4646 if (rc == -EOPNOTSUPP)
4651 rc = lustre_lnet_modify_peer(prim_nid, nidstr, is_mr, cmd,
4652 force_lock, -1, &err_rc);
4653 if (rc != LUSTRE_CFG_RC_NO_ERR)
4657 cYAML_build_error(rc, -1, "peer",
4658 cmd == LNETCTL_ADD_CMD ? "add" : "del",
4662 if (rc != LUSTRE_CFG_RC_NO_ERR)
4663 cYAML_print_tree2file(stderr, err_rc);
4665 cYAML_free_tree(err_rc);
4670 static int jt_add_peer_nid(int argc, char **argv)
4672 return jt_peer_nid_common(argc, argv, LNETCTL_ADD_CMD);
4675 static int jt_del_peer_nid(int argc, char **argv)
4677 return jt_peer_nid_common(argc, argv, LNETCTL_DEL_CMD);
4680 static int jt_show_peer(int argc, char **argv)
4684 struct cYAML *err_rc = NULL, *show_rc = NULL;
4685 long int detail = 0;
4686 const char *const short_opts = "hn:v::";
4687 const struct option long_opts[] = {
4688 { .name = "help", .has_arg = no_argument, .val = 'h' },
4689 { .name = "nid", .has_arg = required_argument, .val = 'n' },
4690 { .name = "verbose", .has_arg = optional_argument, .val = 'v' },
4694 rc = check_cmd(peer_cmds, "peer", "show", 1, argc, argv);
4698 while ((opt = getopt_long(argc, argv, short_opts,
4699 long_opts, NULL)) != -1) {
4705 if ((!optarg) && (argv[optind] != NULL) &&
4706 (argv[optind][0] != '-')) {
4707 if (parse_long(argv[optind++], &detail) != 0)
4714 print_help(peer_cmds, "peer", "show");
4720 rc = yaml_lnet_peer(nid, NULL, false, -1, -1, false, detail,
4721 NLM_F_DUMP, stdout);
4723 if (rc == -EOPNOTSUPP)
4728 rc = lustre_lnet_show_peer(nid, (int) detail, -1, &show_rc, &err_rc,
4731 if (rc != LUSTRE_CFG_RC_NO_ERR)
4732 cYAML_print_tree2file(stderr, err_rc);
4734 cYAML_print_tree(show_rc);
4736 cYAML_free_tree(err_rc);
4737 cYAML_free_tree(show_rc);
4742 static int jt_list_peer(int argc, char **argv)
4744 struct cYAML *err_rc = NULL, *list_rc = NULL;
4747 rc = check_cmd(peer_cmds, "peer", "list", 0, argc, argv);
4751 rc = yaml_lnet_peer(NULL, NULL, false, -1, -1, true, 0, NLM_F_DUMP,
4754 if (rc == -EOPNOTSUPP)
4760 rc = lustre_lnet_list_peer(-1, &list_rc, &err_rc);
4761 if (rc != LUSTRE_CFG_RC_NO_ERR)
4762 cYAML_print_tree2file(stderr, err_rc);
4764 cYAML_print_tree(list_rc);
4766 cYAML_free_tree(err_rc);
4767 cYAML_free_tree(list_rc);
4772 static int yaml_lnet_ping_display(yaml_parser_t *reply)
4774 yaml_emitter_t debug;
4779 rc = yaml_emitter_initialize(&debug);
4781 yaml_emitter_set_output_file(&debug, stdout);
4788 rc = yaml_parser_parse(reply, &event);
4790 goto report_reply_error;
4792 if (event.type != YAML_SCALAR_EVENT) {
4793 rc = yaml_emitter_emit(&debug, &event);
4797 done = (event.type == YAML_DOCUMENT_END_EVENT);
4801 if (strcmp((char *)event.data.scalar.value, "errno") == 0) {
4802 rc = yaml_emitter_emit(&debug, &event);
4806 rc = yaml_parser_parse(reply, &event);
4808 goto report_reply_error;
4810 rc = parse_long((char *)event.data.scalar.value,
4813 goto report_reply_error;
4815 rc = yaml_emitter_emit(&debug, &event);
4820 } else if (error != 0 &&
4821 strcmp((char *)event.data.scalar.value,
4823 rc = yaml_emitter_emit(&debug, &event);
4827 rc = yaml_parser_parse(reply, &event);
4829 goto report_reply_error;
4831 if (strncmp((char *)event.data.scalar.value,
4832 "failed to ", strlen("failed to ")) == 0) {
4835 snprintf(err, sizeof(err), "%s: %s",
4836 (char *)event.data.scalar.value,
4838 yaml_scalar_event_initialize(&event, NULL,
4839 (yaml_char_t *)YAML_STR_TAG,
4842 YAML_PLAIN_SCALAR_STYLE);
4844 rc = yaml_emitter_emit(&debug, &event);
4850 rc = yaml_emitter_emit(&debug, &event);
4857 yaml_emitter_log_error(&debug, stderr);
4859 yaml_emitter_delete(&debug);
4861 return rc2 ? rc2 : rc;
4864 static int yaml_lnet_ping(char *group, int timeout, char *src_nidstr,
4865 int start, int end, char **nids, int flags)
4867 struct nl_sock *sk = NULL;
4868 const char *msg = NULL;
4869 yaml_emitter_t output;
4870 yaml_parser_t reply;
4874 /* Create Netlink emitter to send request to kernel */
4875 sk = nl_socket_alloc();
4879 /* Setup parser to receive Netlink packets */
4880 rc = yaml_parser_initialize(&reply);
4886 rc = yaml_parser_set_input_netlink(&reply, sk, false);
4888 msg = yaml_parser_get_reader_error(&reply);
4892 /* Create Netlink emitter to send request to kernel */
4893 rc = yaml_emitter_initialize(&output);
4895 msg = "failed to initialize emitter";
4899 rc = yaml_emitter_set_output_netlink(&output, sk, LNET_GENL_NAME,
4900 LNET_GENL_VERSION, LNET_CMD_PING,
4905 yaml_emitter_open(&output);
4906 yaml_document_start_event_initialize(&event, NULL, NULL, NULL, 0);
4907 rc = yaml_emitter_emit(&output, &event);
4911 yaml_mapping_start_event_initialize(&event, NULL,
4912 (yaml_char_t *)YAML_MAP_TAG,
4913 1, YAML_ANY_MAPPING_STYLE);
4914 rc = yaml_emitter_emit(&output, &event);
4918 yaml_scalar_event_initialize(&event, NULL,
4919 (yaml_char_t *)YAML_STR_TAG,
4920 (yaml_char_t *)group,
4921 strlen(group), 1, 0,
4922 YAML_PLAIN_SCALAR_STYLE);
4923 rc = yaml_emitter_emit(&output, &event);
4927 yaml_mapping_start_event_initialize(&event, NULL,
4928 (yaml_char_t *)YAML_MAP_TAG,
4929 1, YAML_ANY_MAPPING_STYLE);
4930 rc = yaml_emitter_emit(&output, &event);
4934 if (timeout != 1000 || src_nidstr) {
4936 yaml_scalar_event_initialize(&event, NULL,
4937 (yaml_char_t *)YAML_STR_TAG,
4938 (yaml_char_t *)"source",
4939 strlen("source"), 1, 0,
4940 YAML_PLAIN_SCALAR_STYLE);
4941 rc = yaml_emitter_emit(&output, &event);
4945 yaml_scalar_event_initialize(&event, NULL,
4946 (yaml_char_t *)YAML_STR_TAG,
4947 (yaml_char_t *)src_nidstr,
4948 strlen(src_nidstr), 1, 0,
4949 YAML_PLAIN_SCALAR_STYLE);
4950 rc = yaml_emitter_emit(&output, &event);
4955 if (timeout != 1000) {
4958 yaml_scalar_event_initialize(&event, NULL,
4959 (yaml_char_t *)YAML_STR_TAG,
4960 (yaml_char_t *)"timeout",
4961 strlen("timeout"), 1, 0,
4962 YAML_PLAIN_SCALAR_STYLE);
4963 rc = yaml_emitter_emit(&output, &event);
4967 snprintf(time, sizeof(time), "%u", timeout);
4968 yaml_scalar_event_initialize(&event, NULL,
4969 (yaml_char_t *)YAML_INT_TAG,
4970 (yaml_char_t *)time,
4972 YAML_PLAIN_SCALAR_STYLE);
4973 rc = yaml_emitter_emit(&output, &event);
4979 yaml_scalar_event_initialize(&event, NULL,
4980 (yaml_char_t *)YAML_STR_TAG,
4981 (yaml_char_t *)"nids",
4982 strlen("nids"), 1, 0,
4983 YAML_PLAIN_SCALAR_STYLE);
4984 rc = yaml_emitter_emit(&output, &event);
4988 yaml_sequence_start_event_initialize(&event, NULL,
4989 (yaml_char_t *)YAML_SEQ_TAG,
4990 1, YAML_FLOW_SEQUENCE_STYLE);
4991 rc = yaml_emitter_emit(&output, &event);
4995 for (i = start; i < end; i++) {
4996 yaml_scalar_event_initialize(&event, NULL,
4997 (yaml_char_t *)YAML_STR_TAG,
4998 (yaml_char_t *)nids[i],
4999 strlen(nids[i]), 1, 0,
5000 YAML_PLAIN_SCALAR_STYLE);
5001 rc = yaml_emitter_emit(&output, &event);
5006 yaml_sequence_end_event_initialize(&event);
5007 rc = yaml_emitter_emit(&output, &event);
5011 yaml_mapping_end_event_initialize(&event);
5012 rc = yaml_emitter_emit(&output, &event);
5016 yaml_mapping_end_event_initialize(&event);
5017 rc = yaml_emitter_emit(&output, &event);
5021 yaml_document_end_event_initialize(&event, 0);
5022 rc = yaml_emitter_emit(&output, &event);
5026 rc = yaml_emitter_close(&output);
5029 yaml_emitter_log_error(&output, stderr);
5032 rc = yaml_lnet_ping_display(&reply);
5034 msg = yaml_parser_get_reader_error(&reply);
5036 yaml_emitter_delete(&output);
5039 yaml_lnet_print_error(-1, group, msg);
5043 yaml_parser_delete(&reply);
5046 return rc == 1 ? 0 : rc;
5049 static int jt_ping(int argc, char **argv)
5051 struct cYAML *err_rc = NULL;
5052 struct cYAML *show_rc = NULL;
5055 char *src_nidstr = NULL;
5056 const char *const short_options = "hs:t:";
5057 const struct option long_options[] = {
5058 { .name = "help", .has_arg = no_argument, .val = 'h' },
5059 { .name = "timeout", .has_arg = required_argument, .val = 't' },
5060 { .name = "source", .has_arg = required_argument, .val = 's' },
5064 while ((opt = getopt_long(argc, argv, short_options,
5065 long_options, NULL)) != -1) {
5068 src_nidstr = optarg;
5071 timeout = 1000 * atol(optarg);
5074 printf("ping nid[,nid,...]\n"
5075 "\t --source: source nid\n"
5076 "\t --timeout: ping timeout\n"
5077 "\t --help: display this help\n");
5084 rc = yaml_lnet_ping("ping", timeout, src_nidstr, optind, argc,
5087 if (rc != -EOPNOTSUPP)
5091 for (; optind < argc; optind++)
5092 rc = lustre_lnet_ping_nid(argv[optind], src_nidstr, timeout, -1,
5096 cYAML_print_tree(show_rc);
5099 cYAML_print_tree2file(stderr, err_rc);
5101 cYAML_free_tree(err_rc);
5102 cYAML_free_tree(show_rc);
5107 static int jt_discover(int argc, char **argv)
5109 struct cYAML *err_rc = NULL;
5110 struct cYAML *show_rc = NULL;
5111 int flags = NLM_F_CREATE;
5114 const char *const short_options = "fh";
5115 const struct option long_options[] = {
5116 { .name = "force", .has_arg = no_argument, .val = 'f' },
5117 { .name = "help", .has_arg = no_argument, .val = 'h' },
5121 while ((opt = getopt_long(argc, argv, short_options,
5122 long_options, NULL)) != -1) {
5125 /* BSD treats NLM_F_CREATE | NLM_F_EXCL as an add */
5126 flags |= NLM_F_EXCL;
5130 printf("discover nid[,nid,...]\n"
5131 "\t --force: force discovery\n"
5132 "\t --help: display this help\n");
5139 if (optind == argc) {
5140 printf("Missing nid argument\n");
5144 rc = yaml_lnet_ping("discover", 1000, NULL, optind, argc, argv,
5147 if (rc != -EOPNOTSUPP)
5151 for (; optind < argc; optind++)
5152 rc = lustre_lnet_discover_nid(argv[optind], force, -1, &show_rc,
5156 cYAML_print_tree(show_rc);
5159 cYAML_print_tree2file(stderr, err_rc);
5161 cYAML_free_tree(err_rc);
5162 cYAML_free_tree(show_rc);
5167 static int jt_add_udsp(int argc, char **argv)
5169 char *src = NULL, *dst = NULL, *rte = NULL;
5170 struct cYAML *err_rc = NULL;
5171 union lnet_udsp_action udsp_action;
5172 long int idx = -1, priority = -1;
5174 char *action_type = "pref";
5176 const char *const short_options = "s:d:r:p:i:";
5177 static const struct option long_options[] = {
5178 { .name = "src", .has_arg = required_argument, .val = 's' },
5179 { .name = "dst", .has_arg = required_argument, .val = 'd' },
5180 { .name = "rte", .has_arg = required_argument, .val = 'r' },
5181 { .name = "priority", .has_arg = required_argument, .val = 'p' },
5182 { .name = "idx", .has_arg = required_argument, .val = 'i' },
5185 rc = check_cmd(udsp_cmds, "udsp", "add", 0, argc, argv);
5189 while ((opt = getopt_long(argc, argv, short_options,
5190 long_options, NULL)) != -1) {
5202 rc = parse_long(optarg, &priority);
5203 if (rc != 0 || priority < 0) {
5204 printf("Invalid priority \"%s\"\n", optarg);
5207 action_type = "priority";
5208 udsp_action.udsp_priority = priority;
5211 rc = parse_long(optarg, &idx);
5212 if (rc != 0 || idx < 0) {
5213 printf("Invalid index \"%s\"\n", optarg);
5218 print_help(udsp_cmds, "udsp", "add");
5224 if (!(src || dst || rte)) {
5225 print_help(udsp_cmds, "udsp", "add");
5229 rc = lustre_lnet_add_udsp(src, dst, rte, action_type, &udsp_action,
5232 if (rc != LUSTRE_CFG_RC_NO_ERR)
5233 cYAML_print_tree2file(stderr, err_rc);
5235 cYAML_free_tree(err_rc);
5240 static int jt_del_udsp(int argc, char **argv)
5242 struct cYAML *err_rc = NULL;
5247 const char *const short_options = "ai:";
5248 static const struct option long_options[] = {
5249 { .name = "all", .has_arg = no_argument, .val = 'a' },
5250 { .name = "idx", .has_arg = required_argument, .val = 'i' },
5253 rc = check_cmd(udsp_cmds, "udsp", "del", 0, argc, argv);
5257 while ((opt = getopt_long(argc, argv, short_options,
5258 long_options, NULL)) != -1) {
5264 rc = parse_long(optarg, &idx);
5265 if (rc != 0 || idx < -1) {
5266 printf("Invalid index \"%s\"\n", optarg);
5271 print_help(udsp_cmds, "udsp", "del");
5277 if (all && idx != -2) {
5278 printf("Cannot combine --all with --idx\n");
5282 } else if (idx == -2) {
5283 printf("Must specify --idx or --all\n");
5287 rc = lustre_lnet_del_udsp(idx, -1, &err_rc);
5288 if (rc != LUSTRE_CFG_RC_NO_ERR)
5289 cYAML_print_tree2file(stderr, err_rc);
5291 cYAML_free_tree(err_rc);
5296 int main(int argc, char **argv)
5299 struct cYAML *err_rc = NULL;
5301 rc = lustre_lnet_config_lib_init();
5303 cYAML_build_error(-1, -1, "lnetctl", "startup",
5304 "cannot register LNet device", &err_rc);
5305 cYAML_print_tree2file(stderr, err_rc);
5309 return cfs_parser(argc, argv, cmd_list);