4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as
8 * published by the Free Software Foundation; either version 2.1 of the
9 * License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
21 * Copyright (c) 2014, Intel Corporation.
24 * Amir Shehata <amir.shehata@intel.com>
29 * 1. APIs that take the actual parameters expanded. This is for other
30 * entities that would like to link against the library and call the APIs
31 * directly without having to form an intermediate representation.
32 * 2. APIs that take a YAML file and parses out the information there and
33 * calls the APIs mentioned in 1
38 #include <libcfs/libcfsutil.h>
39 #include <lnet/lnetctl.h>
40 #include <lnet/socklnd.h>
41 #include <lnet/lib-dlc.h>
42 #include <lnet/nidstr.h>
43 #include "liblnetconfig.h"
46 #define CONFIG_CMD "configure"
47 #define UNCONFIG_CMD "unconfigure"
50 #define SHOW_CMD "show"
52 int lustre_lnet_config_lib_init(void)
54 return register_ioc_dev(LNET_DEV_ID, LNET_DEV_PATH,
55 LNET_DEV_MAJOR, LNET_DEV_MINOR);
58 int lustre_lnet_config_ni_system(bool up, bool load_ni_from_mod,
59 int seq_no, struct cYAML **err_rc)
61 struct libcfs_ioctl_data data;
64 char err_str[LNET_MAX_STR_LEN];
66 snprintf(err_str, sizeof(err_str), "\"Success\"");
68 LIBCFS_IOC_INIT(data);
70 /* Reverse logic is used here in order not to change
72 data.ioc_flags = load_ni_from_mod ? 0 : 1;
74 opc = up ? IOC_LIBCFS_CONFIGURE : IOC_LIBCFS_UNCONFIGURE;
76 rc = l_ioctl(LNET_DEV_ID, opc, &data);
81 "\"LNet %s error: %s\"", (up) ? "configure" :
82 "unconfigure", strerror(errno));
86 cYAML_build_error(rc, seq_no, (up) ? CONFIG_CMD : UNCONFIG_CMD,
87 "lnet", err_str, err_rc);
92 int lustre_lnet_config_route(char *nw, char *gw, int hops, int prio,
93 int seq_no, struct cYAML **err_rc)
95 struct lnet_ioctl_config_data data;
96 lnet_nid_t gateway_nid;
97 int rc = LUSTRE_CFG_RC_NO_ERR;
98 __u32 net = LNET_NIDNET(LNET_NID_ANY);
99 char err_str[LNET_MAX_STR_LEN];
101 snprintf(err_str, sizeof(err_str), "\"Success\"");
103 if (nw == NULL || gw == NULL) {
106 "\"missing mandatory parameter(s): '%s'\"",
107 (nw == NULL && gw == NULL) ? "network, gateway" :
108 (nw == NULL) ? "network" : "gateway");
109 rc = LUSTRE_CFG_RC_MISSING_PARAM;
113 net = libcfs_str2net(nw);
114 if (net == LNET_NIDNET(LNET_NID_ANY)) {
117 "\"cannot parse net %s\"", nw);
118 rc = LUSTRE_CFG_RC_BAD_PARAM;
122 if (LNET_NETTYP(net) == CIBLND ||
123 LNET_NETTYP(net) == OPENIBLND ||
124 LNET_NETTYP(net) == IIBLND ||
125 LNET_NETTYP(net) == VIBLND) {
128 "\"obselete LNet type '%s'\"", libcfs_lnd2str(net));
129 rc = LUSTRE_CFG_RC_BAD_PARAM;
133 gateway_nid = libcfs_str2nid(gw);
134 if (gateway_nid == LNET_NID_ANY) {
137 "\"cannot parse gateway NID '%s'\"", gw);
138 rc = LUSTRE_CFG_RC_BAD_PARAM;
143 /* -1 indicates to use the default hop value */
145 } else if (hops < 1 || hops > 255) {
148 "\"invalid hop count %d, must be between 0 and 256\"",
150 rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
156 } else if (prio < 0) {
159 "\"invalid priority %d, must be greater than 0\"",
161 rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
165 LIBCFS_IOC_INIT_V2(data, cfg_hdr);
167 data.cfg_config_u.cfg_route.rtr_hop = hops;
168 data.cfg_config_u.cfg_route.rtr_priority = prio;
169 data.cfg_nid = gateway_nid;
171 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_ADD_ROUTE, &data);
175 "\"cannot add route: %s\"", strerror(errno));
181 cYAML_build_error(rc, seq_no, ADD_CMD, "route", err_str, err_rc);
186 int lustre_lnet_del_route(char *nw, char *gw,
187 int seq_no, struct cYAML **err_rc)
189 struct lnet_ioctl_config_data data;
190 lnet_nid_t gateway_nid;
191 int rc = LUSTRE_CFG_RC_NO_ERR;
192 __u32 net = LNET_NIDNET(LNET_NID_ANY);
193 char err_str[LNET_MAX_STR_LEN];
195 snprintf(err_str, sizeof(err_str), "\"Success\"");
197 if (nw == NULL || gw == NULL) {
200 "\"missing mandatory parameter(s): '%s'\"",
201 (nw == NULL && gw == NULL) ? "network, gateway" :
202 (nw == NULL) ? "network" : "gateway");
203 rc = LUSTRE_CFG_RC_MISSING_PARAM;
207 net = libcfs_str2net(nw);
208 if (net == LNET_NIDNET(LNET_NID_ANY)) {
211 "\"cannot parse net '%s'\"", nw);
212 rc = LUSTRE_CFG_RC_BAD_PARAM;
216 if (LNET_NETTYP(net) == CIBLND ||
217 LNET_NETTYP(net) == OPENIBLND ||
218 LNET_NETTYP(net) == IIBLND ||
219 LNET_NETTYP(net) == VIBLND) {
222 "\"obselete LNet type '%s'\"", libcfs_lnd2str(net));
223 rc = LUSTRE_CFG_RC_BAD_PARAM;
227 gateway_nid = libcfs_str2nid(gw);
228 if (gateway_nid == LNET_NID_ANY) {
231 "\"cannot parse gateway NID '%s'\"", gw);
232 rc = LUSTRE_CFG_RC_BAD_PARAM;
236 LIBCFS_IOC_INIT_V2(data, cfg_hdr);
238 data.cfg_nid = gateway_nid;
240 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_DEL_ROUTE, &data);
244 "\"cannot delete route: %s\"", strerror(errno));
250 cYAML_build_error(rc, seq_no, DEL_CMD, "route", err_str, err_rc);
255 int lustre_lnet_show_route(char *nw, char *gw, int hops, int prio, int detail,
256 int seq_no, struct cYAML **show_rc,
257 struct cYAML **err_rc)
259 struct lnet_ioctl_config_data data;
260 lnet_nid_t gateway_nid;
261 int rc = LUSTRE_CFG_RC_OUT_OF_MEM;
262 __u32 net = LNET_NIDNET(LNET_NID_ANY);
264 struct cYAML *root = NULL, *route = NULL, *item = NULL;
265 struct cYAML *first_seq = NULL;
266 char err_str[LNET_MAX_STR_LEN];
269 snprintf(err_str, sizeof(err_str),
270 "\"out of memory\"");
273 net = libcfs_str2net(nw);
274 if (net == LNET_NIDNET(LNET_NID_ANY)) {
277 "\"cannot parse net '%s'\"", nw);
278 rc = LUSTRE_CFG_RC_BAD_PARAM;
282 if (LNET_NETTYP(net) == CIBLND ||
283 LNET_NETTYP(net) == OPENIBLND ||
284 LNET_NETTYP(net) == IIBLND ||
285 LNET_NETTYP(net) == VIBLND) {
288 "\"obsolete LNet type '%s'\"",
289 libcfs_lnd2str(net));
290 rc = LUSTRE_CFG_RC_BAD_PARAM;
294 /* show all routes without filtering on net */
295 net = LNET_NIDNET(LNET_NID_ANY);
299 gateway_nid = libcfs_str2nid(gw);
300 if (gateway_nid == LNET_NID_ANY) {
303 "\"cannot parse gateway NID '%s'\"", gw);
304 rc = LUSTRE_CFG_RC_BAD_PARAM;
308 /* show all routes with out filtering on gateway */
309 gateway_nid = LNET_NID_ANY;
311 if ((hops < 1 && hops != -1) || hops > 255) {
314 "\"invalid hop count %d, must be between 0 and 256\"",
316 rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
320 /* create struct cYAML root object */
321 root = cYAML_create_object(NULL, NULL);
325 route = cYAML_create_seq(root, "route");
330 LIBCFS_IOC_INIT_V2(data, cfg_hdr);
333 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_ROUTE, &data);
337 /* filter on provided data */
338 if (net != LNET_NIDNET(LNET_NID_ANY) &&
342 if (gateway_nid != LNET_NID_ANY &&
343 gateway_nid != data.cfg_nid)
347 hops != data.cfg_config_u.cfg_route.rtr_hop)
351 prio != data.cfg_config_u.cfg_route.rtr_priority)
354 /* default rc to -1 incase we hit the goto */
358 item = cYAML_create_seq_item(route);
362 if (first_seq == NULL)
365 if (cYAML_create_string(item, "net",
366 libcfs_net2str(data.cfg_net)) == NULL)
369 if (cYAML_create_string(item, "gateway",
370 libcfs_nid2str(data.cfg_nid)) == NULL)
374 if (cYAML_create_number(item, "hop",
375 data.cfg_config_u.cfg_route.
380 if (cYAML_create_number(item, "priority",
382 cfg_route.rtr_priority) == NULL)
385 if (cYAML_create_string(item, "state",
386 data.cfg_config_u.cfg_route.
388 "up" : "down") == NULL)
393 /* print output iff show_rc is not provided */
395 cYAML_print_tree(root);
397 if (errno != ENOENT) {
400 "\"cannot get routes: %s\"",
405 rc = LUSTRE_CFG_RC_NO_ERR;
407 snprintf(err_str, sizeof(err_str), "\"success\"");
409 if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR || !exist) {
410 cYAML_free_tree(root);
411 } else if (show_rc != NULL && *show_rc != NULL) {
412 struct cYAML *show_node;
413 /* find the route node, if one doesn't exist then
414 * insert one. Otherwise add to the one there
416 show_node = cYAML_get_object_item(*show_rc, "route");
417 if (show_node != NULL && cYAML_is_sequence(show_node)) {
418 cYAML_insert_child(show_node, first_seq);
421 } else if (show_node == NULL) {
422 cYAML_insert_sibling((*show_rc)->cy_child,
426 cYAML_free_tree(root);
432 cYAML_build_error(rc, seq_no, SHOW_CMD, "route", err_str, err_rc);
437 int lustre_lnet_config_net(char *net, char *intf, char *ip2net,
438 int peer_to, int peer_cr, int peer_buf_cr,
439 int credits, char *smp, int seq_no,
440 struct cYAML **err_rc)
442 struct lnet_ioctl_config_data data;
443 char buf[LNET_MAX_STR_LEN];
444 int rc = LUSTRE_CFG_RC_NO_ERR, num_of_nets = 0;
445 char err_str[LNET_MAX_STR_LEN];
447 snprintf(err_str, sizeof(err_str), "\"success\"");
449 if (ip2net == NULL && (intf == NULL || net == NULL)) {
452 "\"mandatory parameter '%s' not specified."
453 " Optionally specify ip2net parameter\"",
454 (intf == NULL && net == NULL) ? "net, if" :
455 (intf == NULL) ? "if" : "net");
456 rc = LUSTRE_CFG_RC_MISSING_PARAM;
460 if (peer_to != -1 && peer_to <= 0) {
463 "\"peer timeout %d, must be greater than 0\"",
465 rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
469 if (ip2net != NULL && strlen(ip2net) >= sizeof(buf)) {
472 "\"ip2net string too long %d\"",
473 (int)strlen(ip2net));
474 rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
479 snprintf(buf, sizeof(buf) - 1, "%s(%s)%s",
483 LIBCFS_IOC_INIT_V2(data, cfg_hdr);
484 strncpy(data.cfg_config_u.cfg_net.net_intf,
485 (ip2net != NULL) ? ip2net : buf, sizeof(buf));
486 data.cfg_config_u.cfg_net.net_peer_timeout = peer_to;
487 data.cfg_config_u.cfg_net.net_peer_tx_credits = peer_cr;
488 data.cfg_config_u.cfg_net.net_peer_rtr_credits = peer_buf_cr;
489 data.cfg_config_u.cfg_net.net_max_tx_credits = credits;
491 num_of_nets = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_ADD_NET, &data);
492 if (num_of_nets < 0) {
495 "\"cannot add network: %s\"", strerror(errno));
500 cYAML_build_error((num_of_nets > 0) ? num_of_nets : rc,
501 seq_no, ADD_CMD, "net", err_str, err_rc);
506 int lustre_lnet_del_net(char *nw, int seq_no, struct cYAML **err_rc)
508 struct lnet_ioctl_config_data data;
509 __u32 net = LNET_NIDNET(LNET_NID_ANY);
510 int rc = LUSTRE_CFG_RC_NO_ERR;
511 char err_str[LNET_MAX_STR_LEN];
513 snprintf(err_str, sizeof(err_str), "\"success\"");
518 "\"missing mandatory parameter\"");
519 rc = LUSTRE_CFG_RC_MISSING_PARAM;
523 net = libcfs_str2net(nw);
524 if (net == LNET_NIDNET(LNET_NID_ANY)) {
527 "\"cannot parse net '%s'\"", nw);
528 rc = LUSTRE_CFG_RC_BAD_PARAM;
532 LIBCFS_IOC_INIT_V2(data, cfg_hdr);
535 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_DEL_NET, &data);
539 "\"cannot delete network: %s\"", strerror(errno));
545 cYAML_build_error(rc, seq_no, DEL_CMD, "net", err_str, err_rc);
550 int lustre_lnet_show_net(char *nw, int detail, int seq_no,
551 struct cYAML **show_rc, struct cYAML **err_rc)
554 struct lnet_ioctl_config_data *data;
555 struct lnet_ioctl_net_config *net_config;
556 __u32 net = LNET_NIDNET(LNET_NID_ANY);
557 int rc = LUSTRE_CFG_RC_OUT_OF_MEM, i, j;
558 struct cYAML *root = NULL, *tunables = NULL,
559 *net_node = NULL, *interfaces = NULL,
560 *item = NULL, *first_seq = NULL;
561 int str_buf_len = LNET_MAX_SHOW_NUM_CPT * 2;
562 char str_buf[str_buf_len];
564 char err_str[LNET_MAX_STR_LEN];
567 snprintf(err_str, sizeof(err_str), "\"out of memory\"");
569 buf = calloc(1, sizeof(*data) + sizeof(*net_config));
573 data = (struct lnet_ioctl_config_data *)buf;
576 net = libcfs_str2net(nw);
577 if (net == LNET_NIDNET(LNET_NID_ANY)) {
580 "\"cannot parse net '%s'\"", nw);
581 rc = LUSTRE_CFG_RC_BAD_PARAM;
586 root = cYAML_create_object(NULL, NULL);
590 net_node = cYAML_create_seq(root, "net");
591 if (net_node == NULL)
597 memset(buf, 0, sizeof(*data) + sizeof(*net_config));
599 LIBCFS_IOC_INIT_V2(*data, cfg_hdr);
601 * set the ioc_len to the proper value since INIT assumes
604 data->cfg_hdr.ioc_len = sizeof(struct lnet_ioctl_config_data) +
605 sizeof(struct lnet_ioctl_net_config);
608 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_NET, data);
612 /* filter on provided data */
613 if (net != LNET_NIDNET(LNET_NID_ANY) &&
614 net != LNET_NIDNET(data->cfg_nid))
617 /* default rc to -1 in case we hit the goto */
621 net_config = (struct lnet_ioctl_net_config *)data->cfg_bulk;
623 /* create the tree to be printed. */
624 item = cYAML_create_seq_item(net_node);
628 if (first_seq == NULL)
631 if (cYAML_create_string(item,
634 LNET_NIDNET(data->cfg_nid)))
638 if (cYAML_create_string(item, "nid",
639 libcfs_nid2str(data->cfg_nid)) == NULL)
642 if (cYAML_create_string(item,
644 (net_config->ni_status ==
646 "up" : "down") == NULL)
649 /* don't add interfaces unless there is at least one
651 if (strlen(net_config->ni_interfaces[0]) > 0) {
652 interfaces = cYAML_create_object(item, "interfaces");
653 if (interfaces == NULL)
656 for (j = 0; j < LNET_MAX_INTERFACES; j++) {
657 if (strlen(net_config->ni_interfaces[j]) > 0) {
659 sizeof(str_buf), "%d", j);
660 if (cYAML_create_string(interfaces,
662 net_config->ni_interfaces[j]) ==
670 tunables = cYAML_create_object(item, "tunables");
671 if (tunables == NULL)
674 if (cYAML_create_number(tunables, "peer_timeout",
675 data->cfg_config_u.cfg_net.
676 net_peer_timeout) == NULL)
679 if (cYAML_create_number(tunables, "peer_credits",
680 data->cfg_config_u.cfg_net.
681 net_peer_tx_credits) == NULL)
684 if (cYAML_create_number(tunables,
685 "peer_buffer_credits",
686 data->cfg_config_u.cfg_net.
687 net_peer_rtr_credits) == NULL)
690 if (cYAML_create_number(tunables, "credits",
691 data->cfg_config_u.cfg_net.
692 net_max_tx_credits) == NULL)
695 /* out put the CPTs in the format: "[x,x,x,...]" */
696 pos += snprintf(pos, str_buf + str_buf_len - pos, "[");
697 for (j = 0 ; data->cfg_ncpts > 1 &&
698 j < data->cfg_ncpts; j++) {
700 str_buf + str_buf_len - pos,
701 "%d", net_config->ni_cpts[j]);
702 if ((j + 1) < data->cfg_ncpts)
708 if (str_buf + str_buf_len - pos <= 0)
709 pos += snprintf(str_buf + str_buf_len - 2,
713 str_buf + str_buf_len - pos,
716 if (data->cfg_ncpts > 1 &&
717 cYAML_create_string(tunables, "CPT",
723 /* Print out the net information only if show_rc is not provided */
725 cYAML_print_tree(root);
727 if (errno != ENOENT) {
730 "\"cannot get networks: %s\"",
735 rc = LUSTRE_CFG_RC_NO_ERR;
737 snprintf(err_str, sizeof(err_str), "\"success\"");
739 if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR || !exist) {
740 cYAML_free_tree(root);
741 } else if (show_rc != NULL && *show_rc != NULL) {
742 struct cYAML *show_node;
743 /* find the net node, if one doesn't exist
744 * then insert one. Otherwise add to the one there
746 show_node = cYAML_get_object_item(*show_rc, "net");
747 if (show_node != NULL && cYAML_is_sequence(show_node)) {
748 cYAML_insert_child(show_node, first_seq);
751 } else if (show_node == NULL) {
752 cYAML_insert_sibling((*show_rc)->cy_child,
756 cYAML_free_tree(root);
762 cYAML_build_error(rc, seq_no, SHOW_CMD, "net", err_str, err_rc);
767 int lustre_lnet_enable_routing(int enable, int seq_no, struct cYAML **err_rc)
769 struct lnet_ioctl_config_data data;
770 int rc = LUSTRE_CFG_RC_NO_ERR;
771 char err_str[LNET_MAX_STR_LEN];
773 snprintf(err_str, sizeof(err_str), "\"success\"");
775 LIBCFS_IOC_INIT_V2(data, cfg_hdr);
776 data.cfg_config_u.cfg_buffers.buf_enable = (enable) ? 1 : 0;
778 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_CONFIG_RTR, &data);
782 "\"cannot %s routing %s\"",
783 (enable) ? "enable" : "disable", strerror(errno));
789 cYAML_build_error(rc, seq_no,
790 (enable) ? ADD_CMD : DEL_CMD,
791 "routing", err_str, err_rc);
796 int lustre_lnet_config_buffers(int tiny, int small, int large, int seq_no,
797 struct cYAML **err_rc)
799 struct lnet_ioctl_config_data data;
800 int rc = LUSTRE_CFG_RC_NO_ERR;
801 char err_str[LNET_MAX_STR_LEN];
803 snprintf(err_str, sizeof(err_str), "\"success\"");
805 /* -1 indicates to ignore changes to this field */
806 if (tiny < -1 || small < -1 || large < -1) {
809 "\"tiny, small and large must be >= 0\"");
810 rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
814 LIBCFS_IOC_INIT_V2(data, cfg_hdr);
815 data.cfg_config_u.cfg_buffers.buf_tiny = tiny;
816 data.cfg_config_u.cfg_buffers.buf_small = small;
817 data.cfg_config_u.cfg_buffers.buf_large = large;
819 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_ADD_BUF, &data);
823 "\"cannot configure buffers: %s\"", strerror(errno));
829 cYAML_build_error(rc, seq_no, DEL_CMD, "buf", err_str, err_rc);
834 int lustre_lnet_show_routing(int seq_no, struct cYAML **show_rc,
835 struct cYAML **err_rc)
837 struct lnet_ioctl_config_data *data;
838 struct lnet_ioctl_pool_cfg *pool_cfg = NULL;
839 int rc = LUSTRE_CFG_RC_OUT_OF_MEM;
841 char *pools[LNET_NRBPOOLS] = {"tiny", "small", "large"};
842 struct cYAML *root = NULL, *pools_node = NULL,
843 *type_node = NULL, *item = NULL, *cpt = NULL,
846 char err_str[LNET_MAX_STR_LEN];
847 char node_name[LNET_MAX_STR_LEN];
850 snprintf(err_str, sizeof(err_str), "\"out of memory\"");
852 buf = calloc(1, sizeof(*data) + sizeof(*pool_cfg));
856 data = (struct lnet_ioctl_config_data *)buf;
858 root = cYAML_create_object(NULL, NULL);
862 pools_node = cYAML_create_seq(root, "routing");
863 if (pools_node == NULL)
867 LIBCFS_IOC_INIT_V2(*data, cfg_hdr);
868 data->cfg_hdr.ioc_len = sizeof(struct lnet_ioctl_config_data) +
869 sizeof(struct lnet_ioctl_pool_cfg);
872 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_BUF, data);
878 pool_cfg = (struct lnet_ioctl_pool_cfg *)data->cfg_bulk;
880 snprintf(node_name, sizeof(node_name), "cpt[%d]", i);
881 item = cYAML_create_seq_item(pools_node);
885 if (first_seq == NULL)
888 cpt = cYAML_create_object(item, node_name);
892 /* create the tree and print */
893 for (j = 0; j < LNET_NRBPOOLS; j++) {
894 type_node = cYAML_create_object(cpt, pools[j]);
895 if (type_node == NULL)
897 if (cYAML_create_number(type_node, "npages",
898 pool_cfg->pl_pools[j].pl_npages)
901 if (cYAML_create_number(type_node, "nbuffers",
902 pool_cfg->pl_pools[j].
903 pl_nbuffers) == NULL)
905 if (cYAML_create_number(type_node, "credits",
906 pool_cfg->pl_pools[j].
909 if (cYAML_create_number(type_node, "mincredits",
910 pool_cfg->pl_pools[j].
911 pl_mincredits) == NULL)
916 if (pool_cfg != NULL) {
917 item = cYAML_create_seq_item(pools_node);
921 if (cYAML_create_number(item, "enable", pool_cfg->pl_routing) ==
927 cYAML_print_tree(root);
929 if (errno != ENOENT) {
932 "\"cannot get routing information: %s\"",
937 rc = LUSTRE_CFG_RC_NO_ERR;
939 snprintf(err_str, sizeof(err_str), "\"success\"");
940 rc = LUSTRE_CFG_RC_NO_ERR;
944 if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR || !exist) {
945 cYAML_free_tree(root);
946 } else if (show_rc != NULL && *show_rc != NULL) {
947 struct cYAML *show_node;
948 /* find the routing node, if one doesn't exist then
949 * insert one. Otherwise add to the one there
951 show_node = cYAML_get_object_item(*show_rc, "routing");
952 if (show_node != NULL && cYAML_is_sequence(show_node)) {
953 cYAML_insert_child(show_node, first_seq);
956 } else if (show_node == NULL) {
957 cYAML_insert_sibling((*show_rc)->cy_child,
961 cYAML_free_tree(root);
967 cYAML_build_error(rc, seq_no, SHOW_CMD, "routing", err_str, err_rc);
972 int lustre_lnet_show_peer_credits(int seq_no, struct cYAML **show_rc,
973 struct cYAML **err_rc)
975 struct lnet_ioctl_peer peer_info;
976 int rc = LUSTRE_CFG_RC_OUT_OF_MEM, ncpt = 0, i = 0, j = 0;
977 struct cYAML *root = NULL, *peer = NULL, *first_seq = NULL,
979 char err_str[LNET_MAX_STR_LEN];
980 bool ncpt_set = false;
982 snprintf(err_str, sizeof(err_str),
983 "\"out of memory\"");
985 /* create struct cYAML root object */
986 root = cYAML_create_object(NULL, NULL);
990 peer_root = cYAML_create_seq(root, "peer");
991 if (peer_root == NULL)
996 LIBCFS_IOC_INIT_V2(peer_info, pr_hdr);
997 peer_info.pr_count = i;
998 peer_info.pr_lnd_u.pr_peer_credits.cr_ncpt = j;
999 rc = l_ioctl(LNET_DEV_ID,
1000 IOC_LIBCFS_GET_PEER_INFO, &peer_info);
1004 if (ncpt_set != 0) {
1005 ncpt = peer_info.pr_lnd_u.pr_peer_credits.
1010 peer = cYAML_create_seq_item(peer_root);
1014 if (first_seq == NULL)
1017 if (cYAML_create_string(peer, "nid",
1019 (peer_info.pr_nid)) == NULL)
1022 if (cYAML_create_string(peer, "state",
1029 if (cYAML_create_number(peer, "refcount",
1032 cr_refcount) == NULL)
1035 if (cYAML_create_number(peer, "max_ni_tx_credits",
1038 cr_ni_peer_tx_credits)
1042 if (cYAML_create_number(peer, "available_tx_credits",
1049 if (cYAML_create_number(peer, "available_rtr_credits",
1052 cr_peer_rtr_credits)
1056 if (cYAML_create_number(peer, "min_rtr_credits",
1059 cr_peer_min_rtr_credits)
1063 if (cYAML_create_number(peer, "tx_q_num_of_buf",
1071 if (errno != ENOENT) {
1074 "\"cannot get peer information: %s\"",
1083 /* print output iff show_rc is not provided */
1084 if (show_rc == NULL)
1085 cYAML_print_tree(root);
1087 snprintf(err_str, sizeof(err_str), "\"success\"");
1088 rc = LUSTRE_CFG_RC_NO_ERR;
1091 if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR) {
1092 cYAML_free_tree(root);
1093 } else if (show_rc != NULL && *show_rc != NULL) {
1094 struct cYAML *show_node;
1095 /* find the peer node, if one doesn't exist then
1096 * insert one. Otherwise add to the one there
1098 show_node = cYAML_get_object_item(*show_rc,
1100 if (show_node != NULL && cYAML_is_sequence(show_node)) {
1101 cYAML_insert_child(show_node, first_seq);
1104 } else if (show_node == NULL) {
1105 cYAML_insert_sibling((*show_rc)->cy_child,
1109 cYAML_free_tree(root);
1115 cYAML_build_error(rc, seq_no, SHOW_CMD, "peer_credits", err_str,
1121 int lustre_lnet_show_stats(int seq_no, struct cYAML **show_rc,
1122 struct cYAML **err_rc)
1124 struct lnet_ioctl_lnet_stats data;
1125 int rc = LUSTRE_CFG_RC_OUT_OF_MEM;
1126 char err_str[LNET_MAX_STR_LEN];
1127 struct cYAML *root = NULL, *stats = NULL;
1129 snprintf(err_str, sizeof(err_str), "\"out of memory\"");
1131 LIBCFS_IOC_INIT_V2(data, st_hdr);
1133 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_LNET_STATS, &data);
1137 "\"cannot get lnet statistics: %s\"",
1143 root = cYAML_create_object(NULL, NULL);
1147 stats = cYAML_create_object(root, "statistics");
1151 if (cYAML_create_number(stats, "msgs_alloc",
1152 data.st_cntrs.msgs_alloc) == NULL)
1155 if (cYAML_create_number(stats, "msgs_max",
1156 data.st_cntrs.msgs_max) == NULL)
1159 if (cYAML_create_number(stats, "errors",
1160 data.st_cntrs.errors) == NULL)
1163 if (cYAML_create_number(stats, "send_count",
1164 data.st_cntrs.send_count) == NULL)
1167 if (cYAML_create_number(stats, "recv_count",
1168 data.st_cntrs.recv_count) == NULL)
1171 if (cYAML_create_number(stats, "route_count",
1172 data.st_cntrs.route_count) == NULL)
1175 if (cYAML_create_number(stats, "drop_count",
1176 data.st_cntrs.drop_count) == NULL)
1179 if (cYAML_create_number(stats, "send_length",
1180 data.st_cntrs.send_length) == NULL)
1183 if (cYAML_create_number(stats, "recv_length",
1184 data.st_cntrs.recv_length) == NULL)
1187 if (cYAML_create_number(stats, "route_length",
1188 data.st_cntrs.route_length) == NULL)
1191 if (cYAML_create_number(stats, "drop_length",
1192 data.st_cntrs.drop_length) == NULL)
1195 if (show_rc == NULL)
1196 cYAML_print_tree(root);
1198 snprintf(err_str, sizeof(err_str), "\"success\"");
1200 if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR) {
1201 cYAML_free_tree(root);
1202 } else if (show_rc != NULL && *show_rc != NULL) {
1203 cYAML_insert_sibling((*show_rc)->cy_child,
1210 cYAML_build_error(rc, seq_no, SHOW_CMD, "statistics", err_str, err_rc);
1215 typedef int (*cmd_handler_t)(struct cYAML *tree,
1216 struct cYAML **show_rc,
1217 struct cYAML **err_rc);
1219 static int handle_yaml_config_route(struct cYAML *tree, struct cYAML **show_rc,
1220 struct cYAML **err_rc)
1222 struct cYAML *net, *gw, *hop, *prio, *seq_no;
1224 net = cYAML_get_object_item(tree, "net");
1225 gw = cYAML_get_object_item(tree, "gateway");
1226 hop = cYAML_get_object_item(tree, "hop");
1227 prio = cYAML_get_object_item(tree, "priority");
1228 seq_no = cYAML_get_object_item(tree, "seq_no");
1230 return lustre_lnet_config_route((net) ? net->cy_valuestring : NULL,
1231 (gw) ? gw->cy_valuestring : NULL,
1232 (hop) ? hop->cy_valueint : -1,
1233 (prio) ? prio->cy_valueint : -1,
1234 (seq_no) ? seq_no->cy_valueint : -1,
1238 static int handle_yaml_config_net(struct cYAML *tree, struct cYAML **show_rc,
1239 struct cYAML **err_rc)
1241 struct cYAML *net, *intf, *tunables, *seq_no,
1242 *peer_to = NULL, *peer_buf_cr = NULL, *peer_cr = NULL,
1243 *credits = NULL, *ip2net = NULL, *smp = NULL, *child;
1244 char devs[LNET_MAX_STR_LEN];
1246 int size = LNET_MAX_STR_LEN;
1248 bool intf_found = false;
1250 ip2net = cYAML_get_object_item(tree, "ip2net");
1251 net = cYAML_get_object_item(tree, "net");
1252 intf = cYAML_get_object_item(tree, "interfaces");
1254 /* grab all the interfaces */
1255 child = intf->cy_child;
1256 while (child != NULL && size > 0) {
1258 num = snprintf(loc, size, ",%s",
1259 child->cy_valuestring);
1261 num = snprintf(loc, size, "%s",
1262 child->cy_valuestring);
1266 child = child->cy_next;
1270 tunables = cYAML_get_object_item(tree, "tunables");
1271 if (tunables != NULL) {
1272 peer_to = cYAML_get_object_item(tunables, "peer_timeout");
1273 peer_cr = cYAML_get_object_item(tunables, "peer_credits");
1274 peer_buf_cr = cYAML_get_object_item(tunables,
1275 "peer_buffer_credits");
1276 credits = cYAML_get_object_item(tunables, "credits");
1277 smp = cYAML_get_object_item(tunables, "CPT");
1279 seq_no = cYAML_get_object_item(tree, "seq_no");
1281 return lustre_lnet_config_net((net) ? net->cy_valuestring : NULL,
1282 (intf_found) ? devs : NULL,
1283 (ip2net) ? ip2net->cy_valuestring : NULL,
1284 (peer_to) ? peer_to->cy_valueint : -1,
1285 (peer_cr) ? peer_cr->cy_valueint : -1,
1287 peer_buf_cr->cy_valueint : -1,
1288 (credits) ? credits->cy_valueint : -1,
1289 (smp) ? smp->cy_valuestring : NULL,
1290 (seq_no) ? seq_no->cy_valueint : -1,
1294 static int handle_yaml_config_buffers(struct cYAML *tree,
1295 struct cYAML **show_rc,
1296 struct cYAML **err_rc)
1299 struct cYAML *tiny, *small, *large, *seq_no;
1301 tiny = cYAML_get_object_item(tree, "tiny");
1302 small = cYAML_get_object_item(tree, "small");
1303 large = cYAML_get_object_item(tree, "large");
1304 seq_no = cYAML_get_object_item(tree, "seq_no");
1306 rc = lustre_lnet_config_buffers((tiny) ? tiny->cy_valueint : -1,
1307 (small) ? small->cy_valueint : -1,
1308 (large) ? large->cy_valueint : -1,
1309 (seq_no) ? seq_no->cy_valueint : -1,
1315 static int handle_yaml_config_routing(struct cYAML *tree,
1316 struct cYAML **show_rc,
1317 struct cYAML **err_rc)
1319 int rc = LUSTRE_CFG_RC_NO_ERR;
1320 struct cYAML *seq_no, *enable;
1322 seq_no = cYAML_get_object_item(tree, "seq_no");
1323 enable = cYAML_get_object_item(tree, "enable");
1326 rc = lustre_lnet_enable_routing(enable->cy_valueint,
1328 seq_no->cy_valueint : -1,
1335 static int handle_yaml_del_route(struct cYAML *tree, struct cYAML **show_rc,
1336 struct cYAML **err_rc)
1340 struct cYAML *seq_no;
1342 net = cYAML_get_object_item(tree, "net");
1343 gw = cYAML_get_object_item(tree, "gateway");
1344 seq_no = cYAML_get_object_item(tree, "seq_no");
1346 return lustre_lnet_del_route((net) ? net->cy_valuestring : NULL,
1347 (gw) ? gw->cy_valuestring : NULL,
1348 (seq_no) ? seq_no->cy_valueint : -1,
1352 static int handle_yaml_del_net(struct cYAML *tree, struct cYAML **show_rc,
1353 struct cYAML **err_rc)
1355 struct cYAML *net, *seq_no;
1357 net = cYAML_get_object_item(tree, "net");
1358 seq_no = cYAML_get_object_item(tree, "seq_no");
1360 return lustre_lnet_del_net((net) ? net->cy_valuestring : NULL,
1361 (seq_no) ? seq_no->cy_valueint : -1,
1365 static int handle_yaml_del_routing(struct cYAML *tree, struct cYAML **show_rc,
1366 struct cYAML **err_rc)
1368 struct cYAML *seq_no;
1370 seq_no = cYAML_get_object_item(tree, "seq_no");
1372 return lustre_lnet_enable_routing(0, (seq_no) ?
1373 seq_no->cy_valueint : -1,
1377 static int handle_yaml_show_route(struct cYAML *tree, struct cYAML **show_rc,
1378 struct cYAML **err_rc)
1384 struct cYAML *detail;
1385 struct cYAML *seq_no;
1387 net = cYAML_get_object_item(tree, "net");
1388 gw = cYAML_get_object_item(tree, "gateway");
1389 hop = cYAML_get_object_item(tree, "hop");
1390 prio = cYAML_get_object_item(tree, "priority");
1391 detail = cYAML_get_object_item(tree, "detail");
1392 seq_no = cYAML_get_object_item(tree, "seq_no");
1394 return lustre_lnet_show_route((net) ? net->cy_valuestring : NULL,
1395 (gw) ? gw->cy_valuestring : NULL,
1396 (hop) ? hop->cy_valueint : -1,
1397 (prio) ? prio->cy_valueint : -1,
1398 (detail) ? detail->cy_valueint : 0,
1399 (seq_no) ? seq_no->cy_valueint : -1,
1404 static int handle_yaml_show_net(struct cYAML *tree, struct cYAML **show_rc,
1405 struct cYAML **err_rc)
1407 struct cYAML *net, *detail, *seq_no;
1409 net = cYAML_get_object_item(tree, "net");
1410 detail = cYAML_get_object_item(tree, "detail");
1411 seq_no = cYAML_get_object_item(tree, "seq_no");
1413 return lustre_lnet_show_net((net) ? net->cy_valuestring : NULL,
1414 (detail) ? detail->cy_valueint : 0,
1415 (seq_no) ? seq_no->cy_valueint : -1,
1420 static int handle_yaml_show_routing(struct cYAML *tree, struct cYAML **show_rc,
1421 struct cYAML **err_rc)
1423 struct cYAML *seq_no;
1425 seq_no = cYAML_get_object_item(tree, "seq_no");
1427 return lustre_lnet_show_routing((seq_no) ? seq_no->cy_valueint : -1,
1431 static int handle_yaml_show_credits(struct cYAML *tree, struct cYAML **show_rc,
1432 struct cYAML **err_rc)
1434 struct cYAML *seq_no;
1436 seq_no = cYAML_get_object_item(tree, "seq_no");
1438 return lustre_lnet_show_peer_credits((seq_no) ?
1439 seq_no->cy_valueint : -1,
1443 static int handle_yaml_show_stats(struct cYAML *tree, struct cYAML **show_rc,
1444 struct cYAML **err_rc)
1446 struct cYAML *seq_no;
1448 seq_no = cYAML_get_object_item(tree, "seq_no");
1450 return lustre_lnet_show_stats((seq_no) ? seq_no->cy_valueint : -1,
1454 struct lookup_cmd_hdlr_tbl {
1459 static struct lookup_cmd_hdlr_tbl lookup_config_tbl[] = {
1460 {"route", handle_yaml_config_route},
1461 {"net", handle_yaml_config_net},
1462 {"routing", handle_yaml_config_routing},
1463 {"buffers", handle_yaml_config_buffers},
1467 static struct lookup_cmd_hdlr_tbl lookup_del_tbl[] = {
1468 {"route", handle_yaml_del_route},
1469 {"net", handle_yaml_del_net},
1470 {"routing", handle_yaml_del_routing},
1474 static struct lookup_cmd_hdlr_tbl lookup_show_tbl[] = {
1475 {"route", handle_yaml_show_route},
1476 {"net", handle_yaml_show_net},
1477 {"buffers", handle_yaml_show_routing},
1478 {"routing", handle_yaml_show_routing},
1479 {"credits", handle_yaml_show_credits},
1480 {"statistics", handle_yaml_show_stats},
1484 static cmd_handler_t lookup_fn(char *key,
1485 struct lookup_cmd_hdlr_tbl *tbl)
1491 for (i = 0; tbl[i].name != NULL; i++) {
1492 if (strncmp(key, tbl[i].name, strlen(tbl[i].name)) == 0)
1499 static int lustre_yaml_cb_helper(char *f, struct lookup_cmd_hdlr_tbl *table,
1500 struct cYAML **show_rc, struct cYAML **err_rc)
1502 struct cYAML *tree, *item = NULL, *head, *child;
1504 char err_str[LNET_MAX_STR_LEN];
1505 int rc = LUSTRE_CFG_RC_NO_ERR, return_rc = LUSTRE_CFG_RC_NO_ERR;
1507 tree = cYAML_build_tree(f, NULL, 0, err_rc);
1509 return LUSTRE_CFG_RC_BAD_PARAM;
1511 child = tree->cy_child;
1512 while (child != NULL) {
1513 cb = lookup_fn(child->cy_string, table);
1515 snprintf(err_str, sizeof(err_str),
1516 "\"call back for '%s' not found\"",
1518 cYAML_build_error(LUSTRE_CFG_RC_BAD_PARAM, -1,
1519 "yaml", "helper", err_str, err_rc);
1523 if (cYAML_is_sequence(child)) {
1524 while ((head = cYAML_get_next_seq_item(child, &item))
1526 rc = cb(head, show_rc, err_rc);
1527 if (rc != LUSTRE_CFG_RC_NO_ERR)
1531 rc = cb(child, show_rc, err_rc);
1532 if (rc != LUSTRE_CFG_RC_NO_ERR)
1536 child = child->cy_next;
1540 cYAML_free_tree(tree);
1545 int lustre_yaml_config(char *f, struct cYAML **err_rc)
1547 return lustre_yaml_cb_helper(f, lookup_config_tbl,
1551 int lustre_yaml_del(char *f, struct cYAML **err_rc)
1553 return lustre_yaml_cb_helper(f, lookup_del_tbl,
1557 int lustre_yaml_show(char *f, struct cYAML **show_rc, struct cYAML **err_rc)
1559 return lustre_yaml_cb_helper(f, lookup_show_tbl,