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) 2013, 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];
268 snprintf(err_str, sizeof(err_str),
269 "\"out of memory\"");
272 net = libcfs_str2net(nw);
273 if (net == LNET_NIDNET(LNET_NID_ANY)) {
276 "\"cannot parse net '%s'\"", nw);
277 rc = LUSTRE_CFG_RC_BAD_PARAM;
281 if (LNET_NETTYP(net) == CIBLND ||
282 LNET_NETTYP(net) == OPENIBLND ||
283 LNET_NETTYP(net) == IIBLND ||
284 LNET_NETTYP(net) == VIBLND) {
287 "\"obsolete LNet type '%s'\"",
288 libcfs_lnd2str(net));
289 rc = LUSTRE_CFG_RC_BAD_PARAM;
293 /* show all routes without filtering on net */
294 net = LNET_NIDNET(LNET_NID_ANY);
298 gateway_nid = libcfs_str2nid(gw);
299 if (gateway_nid == LNET_NID_ANY) {
302 "\"cannot parse gateway NID '%s'\"", gw);
303 rc = LUSTRE_CFG_RC_BAD_PARAM;
307 /* show all routes with out filtering on gateway */
308 gateway_nid = LNET_NID_ANY;
310 if ((hops < 1 && hops != -1) || hops > 255) {
313 "\"invalid hop count %d, must be between 0 and 256\"",
315 rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
319 /* create struct cYAML root object */
320 root = cYAML_create_object(NULL, NULL);
324 route = cYAML_create_seq(root, "route");
329 LIBCFS_IOC_INIT_V2(data, cfg_hdr);
332 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_ROUTE, &data);
336 /* filter on provided data */
337 if (net != LNET_NIDNET(LNET_NID_ANY) &&
341 if (gateway_nid != LNET_NID_ANY &&
342 gateway_nid != data.cfg_nid)
346 hops != data.cfg_config_u.cfg_route.rtr_hop)
350 prio != data.cfg_config_u.cfg_route.rtr_priority)
353 /* default rc to -1 incase we hit the goto */
356 item = cYAML_create_seq_item(route);
360 if (first_seq == NULL)
363 if (cYAML_create_string(item, "net",
364 libcfs_net2str(data.cfg_net)) == NULL)
367 if (cYAML_create_string(item, "gateway",
368 libcfs_nid2str(data.cfg_nid)) == NULL)
372 if (cYAML_create_number(item, "hop",
373 data.cfg_config_u.cfg_route.
378 if (cYAML_create_number(item, "priority",
380 cfg_route.rtr_priority) == NULL)
383 if (cYAML_create_string(item, "state",
384 data.cfg_config_u.cfg_route.
386 "up" : "down") == NULL)
391 /* print output iff show_rc is not provided */
393 cYAML_print_tree(root);
395 if (errno != ENOENT) {
398 "\"cannot get routes: %s\"",
403 rc = LUSTRE_CFG_RC_NO_ERR;
405 snprintf(err_str, sizeof(err_str), "\"success\"");
407 if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR) {
408 cYAML_free_tree(root);
409 } else if (show_rc != NULL && *show_rc != NULL) {
410 struct cYAML *show_node;
411 /* find the route node, if one doesn't exist then
412 * insert one. Otherwise add to the one there
414 show_node = cYAML_get_object_item(*show_rc, "route");
415 if (show_node != NULL && cYAML_is_sequence(show_node)) {
416 cYAML_insert_child(show_node, first_seq);
419 } else if (show_node == NULL) {
420 cYAML_insert_sibling((*show_rc)->cy_child,
424 cYAML_free_tree(root);
430 cYAML_build_error(rc, seq_no, SHOW_CMD, "route", err_str, err_rc);
435 int lustre_lnet_config_net(char *net, char *intf, char *ip2net,
436 int peer_to, int peer_cr, int peer_buf_cr,
437 int credits, char *smp, int seq_no,
438 struct cYAML **err_rc)
440 struct lnet_ioctl_config_data data;
441 char buf[LNET_MAX_STR_LEN];
442 int rc = LUSTRE_CFG_RC_NO_ERR, num_of_nets = 0;
443 char err_str[LNET_MAX_STR_LEN];
445 snprintf(err_str, sizeof(err_str), "\"success\"");
447 if (ip2net == NULL && (intf == NULL || net == NULL)) {
450 "\"mandatory parameter '%s' not specified."
451 " Optionally specify ip2net parameter\"",
452 (intf == NULL && net == NULL) ? "net, if" :
453 (intf == NULL) ? "if" : "net");
454 rc = LUSTRE_CFG_RC_MISSING_PARAM;
458 if (peer_to != -1 && peer_to <= 0) {
461 "\"peer timeout %d, must be greater than 0\"",
463 rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
467 if (ip2net != NULL && strlen(ip2net) >= sizeof(buf)) {
470 "\"ip2net string too long %d\"",
471 (int)strlen(ip2net));
472 rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
477 snprintf(buf, sizeof(buf) - 1, "%s(%s)%s",
481 LIBCFS_IOC_INIT_V2(data, cfg_hdr);
482 strncpy(data.cfg_config_u.cfg_net.net_intf,
483 (ip2net != NULL) ? ip2net : buf, sizeof(buf));
484 data.cfg_config_u.cfg_net.net_peer_timeout = peer_to;
485 data.cfg_config_u.cfg_net.net_peer_tx_credits = peer_cr;
486 data.cfg_config_u.cfg_net.net_peer_rtr_credits = peer_buf_cr;
487 data.cfg_config_u.cfg_net.net_max_tx_credits = credits;
489 num_of_nets = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_ADD_NET, &data);
490 if (num_of_nets < 0) {
493 "\"cannot add network: %s\"", strerror(errno));
498 cYAML_build_error((num_of_nets > 0) ? num_of_nets : rc,
499 seq_no, ADD_CMD, "net", err_str, err_rc);
504 int lustre_lnet_del_net(char *nw, int seq_no, struct cYAML **err_rc)
506 struct lnet_ioctl_config_data data;
507 __u32 net = LNET_NIDNET(LNET_NID_ANY);
508 int rc = LUSTRE_CFG_RC_NO_ERR;
509 char err_str[LNET_MAX_STR_LEN];
511 snprintf(err_str, sizeof(err_str), "\"success\"");
516 "\"missing mandatory parameter\"");
517 rc = LUSTRE_CFG_RC_MISSING_PARAM;
521 net = libcfs_str2net(nw);
522 if (net == LNET_NIDNET(LNET_NID_ANY)) {
525 "\"cannot parse net '%s'\"", nw);
526 rc = LUSTRE_CFG_RC_BAD_PARAM;
530 LIBCFS_IOC_INIT_V2(data, cfg_hdr);
533 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_DEL_NET, &data);
537 "\"cannot delete network: %s\"", strerror(errno));
543 cYAML_build_error(rc, seq_no, DEL_CMD, "net", err_str, err_rc);
548 int lustre_lnet_show_net(char *nw, int detail, int seq_no,
549 struct cYAML **show_rc, struct cYAML **err_rc)
552 struct lnet_ioctl_config_data *data;
553 struct lnet_ioctl_net_config *net_config;
554 __u32 net = LNET_NIDNET(LNET_NID_ANY);
555 int rc = LUSTRE_CFG_RC_OUT_OF_MEM, i, j;
556 struct cYAML *root = NULL, *tunables = NULL,
557 *net_node = NULL, *interfaces = NULL,
558 *item = NULL, *first_seq = NULL;
559 int str_buf_len = LNET_MAX_SHOW_NUM_CPT * 2;
560 char str_buf[str_buf_len];
562 char err_str[LNET_MAX_STR_LEN];
564 snprintf(err_str, sizeof(err_str), "\"out of memory\"");
566 buf = calloc(1, sizeof(*data) + sizeof(*net_config));
570 data = (struct lnet_ioctl_config_data *)buf;
573 net = libcfs_str2net(nw);
574 if (net == LNET_NIDNET(LNET_NID_ANY)) {
577 "\"cannot parse net '%s'\"", nw);
578 rc = LUSTRE_CFG_RC_BAD_PARAM;
583 root = cYAML_create_object(NULL, NULL);
587 net_node = cYAML_create_seq(root, "net");
588 if (net_node == NULL)
592 LIBCFS_IOC_INIT_V2(*data, cfg_hdr);
594 * set the ioc_len to the proper value since INIT assumes
597 data->cfg_hdr.ioc_len = sizeof(struct lnet_ioctl_config_data) +
598 sizeof(struct lnet_ioctl_net_config);
601 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_NET, data);
605 /* filter on provided data */
606 if (net != LNET_NIDNET(LNET_NID_ANY) &&
607 net != LNET_NIDNET(data->cfg_nid))
610 /* default rc to -1 in case we hit the goto */
613 net_config = (struct lnet_ioctl_net_config *)data->cfg_bulk;
615 /* create the tree to be printed. */
616 item = cYAML_create_seq_item(net_node);
620 if (first_seq == NULL)
623 if (cYAML_create_string(item,
625 libcfs_nid2str(data->cfg_nid)) == NULL)
628 if (cYAML_create_string(item,
630 (net_config->ni_status ==
632 "up" : "down") == NULL)
635 /* don't add interfaces unless there is at least one
637 if (strlen(net_config->ni_interfaces[0]) > 0) {
638 interfaces = cYAML_create_object(item, "interfaces");
639 if (interfaces == NULL)
642 for (j = 0; j < LNET_MAX_INTERFACES; j++) {
643 if (strlen(net_config->ni_interfaces[j]) > 0) {
645 sizeof(str_buf), "%d", j);
646 if (cYAML_create_string(interfaces,
648 net_config->ni_interfaces[j]) ==
656 tunables = cYAML_create_object(item, "tunables");
657 if (tunables == NULL)
660 if (cYAML_create_number(tunables, "peer_timeout",
661 data->cfg_config_u.cfg_net.
662 net_peer_timeout) == NULL)
665 if (cYAML_create_number(tunables, "peer_credits",
666 data->cfg_config_u.cfg_net.
667 net_peer_tx_credits) == NULL)
670 if (cYAML_create_number(tunables,
671 "peer_buffer_credits",
672 data->cfg_config_u.cfg_net.
673 net_peer_rtr_credits) == NULL)
676 if (cYAML_create_number(tunables, "credits",
677 data->cfg_config_u.cfg_net.
678 net_max_tx_credits) == NULL)
681 for (j = 0 ; data->cfg_ncpts > 1 &&
682 j < data->cfg_ncpts; j++) {
683 pos += snprintf(str_buf,
684 str_buf + str_buf_len - pos,
685 " %d", net_config->ni_cpts[j]);
688 if (data->cfg_ncpts > 1 &&
689 cYAML_create_string(tunables, "CPTs",
695 /* Print out the net information only if show_rc is not provided */
697 cYAML_print_tree(root);
699 if (errno != ENOENT) {
702 "\"cannot get networks: %s\"",
707 rc = LUSTRE_CFG_RC_NO_ERR;
709 snprintf(err_str, sizeof(err_str), "\"success\"");
711 if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR) {
712 cYAML_free_tree(root);
713 } else if (show_rc != NULL && *show_rc != NULL) {
714 struct cYAML *show_node;
715 /* find the net node, if one doesn't exist
716 * then insert one. Otherwise add to the one there
718 show_node = cYAML_get_object_item(*show_rc, "net");
719 if (show_node != NULL && cYAML_is_sequence(show_node)) {
720 cYAML_insert_child(show_node, first_seq);
723 } else if (show_node == NULL) {
724 cYAML_insert_sibling((*show_rc)->cy_child,
728 cYAML_free_tree(root);
734 cYAML_build_error(rc, seq_no, SHOW_CMD, "net", err_str, err_rc);
739 int lustre_lnet_enable_routing(int enable, int seq_no, struct cYAML **err_rc)
741 struct lnet_ioctl_config_data data;
742 int rc = LUSTRE_CFG_RC_NO_ERR;
743 char err_str[LNET_MAX_STR_LEN];
745 snprintf(err_str, sizeof(err_str), "\"success\"");
747 LIBCFS_IOC_INIT_V2(data, cfg_hdr);
748 data.cfg_config_u.cfg_buffers.buf_enable = (enable) ? 1 : 0;
750 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_CONFIG_RTR, &data);
754 "\"cannot %s routing %s\"",
755 (enable) ? "enable" : "disable", strerror(errno));
761 cYAML_build_error(rc, seq_no,
762 (enable) ? ADD_CMD : DEL_CMD,
763 "routing", err_str, err_rc);
768 int lustre_lnet_config_buffers(int tiny, int small, int large, int seq_no,
769 struct cYAML **err_rc)
771 struct lnet_ioctl_config_data data;
772 int rc = LUSTRE_CFG_RC_NO_ERR;
773 char err_str[LNET_MAX_STR_LEN];
775 snprintf(err_str, sizeof(err_str), "\"success\"");
777 /* -1 indicates to ignore changes to this field */
778 if (tiny < -1 || small < -1 || large < -1) {
781 "\"tiny, small and large must be >= 0\"");
782 rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
786 LIBCFS_IOC_INIT_V2(data, cfg_hdr);
787 data.cfg_config_u.cfg_buffers.buf_tiny = tiny;
788 data.cfg_config_u.cfg_buffers.buf_small = small;
789 data.cfg_config_u.cfg_buffers.buf_large = large;
791 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_ADD_BUF, &data);
795 "\"cannot configure buffers: %s\"", strerror(errno));
801 cYAML_build_error(rc, seq_no, DEL_CMD, "buf", err_str, err_rc);
806 int lustre_lnet_show_routing(int seq_no, struct cYAML **show_rc,
807 struct cYAML **err_rc)
809 struct lnet_ioctl_config_data *data;
810 struct lnet_ioctl_pool_cfg *pool_cfg = NULL;
811 int rc = LUSTRE_CFG_RC_OUT_OF_MEM;
813 char *pools[LNET_NRBPOOLS] = {"tiny", "small", "large"};
814 struct cYAML *root = NULL, *pools_node = NULL,
815 *type_node = NULL, *item = NULL, *cpt = NULL,
818 char err_str[LNET_MAX_STR_LEN];
819 char node_name[LNET_MAX_STR_LEN];
821 snprintf(err_str, sizeof(err_str), "\"out of memory\"");
823 buf = calloc(1, sizeof(*data) + sizeof(*pool_cfg));
827 data = (struct lnet_ioctl_config_data *)buf;
829 root = cYAML_create_object(NULL, NULL);
833 pools_node = cYAML_create_seq(root, "routing");
834 if (pools_node == NULL)
838 LIBCFS_IOC_INIT_V2(*data, cfg_hdr);
839 data->cfg_hdr.ioc_len = sizeof(struct lnet_ioctl_config_data) +
840 sizeof(struct lnet_ioctl_pool_cfg);
843 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_BUF, data);
847 pool_cfg = (struct lnet_ioctl_pool_cfg *)data->cfg_bulk;
849 snprintf(node_name, sizeof(node_name), "cpt[%d]", i);
850 item = cYAML_create_seq_item(pools_node);
854 if (first_seq == NULL)
857 cpt = cYAML_create_object(item, node_name);
861 /* create the tree and print */
862 for (i = 0; i < LNET_NRBPOOLS; i++) {
863 type_node = cYAML_create_object(cpt, pools[i]);
864 if (type_node == NULL)
866 if (cYAML_create_number(type_node, "npages",
867 pool_cfg->pl_pools[i].pl_npages)
870 if (cYAML_create_number(type_node, "nbuffers",
871 pool_cfg->pl_pools[i].
872 pl_nbuffers) == NULL)
874 if (cYAML_create_number(type_node, "credits",
875 pool_cfg->pl_pools[i].
878 if (cYAML_create_number(type_node, "mincredits",
879 pool_cfg->pl_pools[i].
880 pl_mincredits) == NULL)
885 if (pool_cfg != NULL) {
886 item = cYAML_create_seq_item(pools_node);
890 if (cYAML_create_number(item, "enable", pool_cfg->pl_routing) ==
896 cYAML_print_tree(root);
898 if (errno != ENOENT) {
901 "\"cannot get routing information: %s\"",
906 rc = LUSTRE_CFG_RC_NO_ERR;
908 snprintf(err_str, sizeof(err_str), "\"success\"");
909 rc = LUSTRE_CFG_RC_NO_ERR;
913 if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR) {
914 cYAML_free_tree(root);
915 } else if (show_rc != NULL && *show_rc != NULL) {
916 struct cYAML *show_node;
917 /* find the routing node, if one doesn't exist then
918 * insert one. Otherwise add to the one there
920 show_node = cYAML_get_object_item(*show_rc, "routing");
921 if (show_node != NULL && cYAML_is_sequence(show_node)) {
922 cYAML_insert_child(show_node, first_seq);
925 } else if (show_node == NULL) {
926 cYAML_insert_sibling((*show_rc)->cy_child,
930 cYAML_free_tree(root);
936 cYAML_build_error(rc, seq_no, SHOW_CMD, "routing", err_str, err_rc);
941 int lustre_lnet_show_peer_credits(int seq_no, struct cYAML **show_rc,
942 struct cYAML **err_rc)
944 struct lnet_ioctl_peer peer_info;
945 int rc = LUSTRE_CFG_RC_OUT_OF_MEM, ncpt = 0, i = 0, j = 0;
946 struct cYAML *root = NULL, *peer = NULL, *first_seq = NULL,
948 char err_str[LNET_MAX_STR_LEN];
949 bool ncpt_set = false;
951 snprintf(err_str, sizeof(err_str),
952 "\"out of memory\"");
954 /* create struct cYAML root object */
955 root = cYAML_create_object(NULL, NULL);
959 peer_root = cYAML_create_seq(root, "peer");
960 if (peer_root == NULL)
965 LIBCFS_IOC_INIT_V2(peer_info, pr_hdr);
966 peer_info.pr_count = i;
967 peer_info.pr_lnd_u.pr_peer_credits.cr_ncpt = j;
968 rc = l_ioctl(LNET_DEV_ID,
969 IOC_LIBCFS_GET_PEER_INFO, &peer_info);
974 ncpt = peer_info.pr_lnd_u.pr_peer_credits.
979 peer = cYAML_create_seq_item(peer_root);
983 if (first_seq == NULL)
986 if (cYAML_create_string(peer, "nid",
988 (peer_info.pr_nid)) == NULL)
991 if (cYAML_create_string(peer, "state",
998 if (cYAML_create_number(peer, "refcount",
1001 cr_refcount) == NULL)
1004 if (cYAML_create_number(peer, "max_ni_tx_credits",
1007 cr_ni_peer_tx_credits)
1011 if (cYAML_create_number(peer, "available_tx_credits",
1018 if (cYAML_create_number(peer, "available_rtr_credits",
1021 cr_peer_rtr_credits)
1025 if (cYAML_create_number(peer, "min_rtr_credits",
1028 cr_peer_min_rtr_credits)
1032 if (cYAML_create_number(peer, "tx_q_num_of_buf",
1040 if (errno != ENOENT) {
1043 "\"cannot get peer information: %s\"",
1052 /* print output iff show_rc is not provided */
1053 if (show_rc == NULL)
1054 cYAML_print_tree(root);
1056 snprintf(err_str, sizeof(err_str), "\"success\"");
1057 rc = LUSTRE_CFG_RC_NO_ERR;
1060 if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR) {
1061 cYAML_free_tree(root);
1062 } else if (show_rc != NULL && *show_rc != NULL) {
1063 struct cYAML *show_node;
1064 /* find the peer node, if one doesn't exist then
1065 * insert one. Otherwise add to the one there
1067 show_node = cYAML_get_object_item(*show_rc,
1069 if (show_node != NULL && cYAML_is_sequence(show_node)) {
1070 cYAML_insert_child(show_node, first_seq);
1073 } else if (show_node == NULL) {
1074 cYAML_insert_sibling((*show_rc)->cy_child,
1078 cYAML_free_tree(root);
1084 cYAML_build_error(rc, seq_no, SHOW_CMD, "peer_credits", err_str,
1090 int lustre_lnet_show_stats(int seq_no, struct cYAML **show_rc,
1091 struct cYAML **err_rc)
1093 struct lnet_ioctl_lnet_stats data;
1094 int rc = LUSTRE_CFG_RC_OUT_OF_MEM;
1095 char err_str[LNET_MAX_STR_LEN];
1096 struct cYAML *root = NULL, *stats = NULL;
1098 snprintf(err_str, sizeof(err_str), "\"out of memory\"");
1100 LIBCFS_IOC_INIT_V2(data, st_hdr);
1102 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_LNET_STATS, &data);
1106 "\"cannot get lnet statistics: %s\"",
1112 root = cYAML_create_object(NULL, NULL);
1116 stats = cYAML_create_object(root, "statistics");
1120 if (cYAML_create_number(stats, "msgs_alloc",
1121 data.st_cntrs.msgs_alloc) == NULL)
1124 if (cYAML_create_number(stats, "msgs_max",
1125 data.st_cntrs.msgs_max) == NULL)
1128 if (cYAML_create_number(stats, "errors",
1129 data.st_cntrs.errors) == NULL)
1132 if (cYAML_create_number(stats, "send_count",
1133 data.st_cntrs.send_count) == NULL)
1136 if (cYAML_create_number(stats, "recv_count",
1137 data.st_cntrs.recv_count) == NULL)
1140 if (cYAML_create_number(stats, "route_count",
1141 data.st_cntrs.route_count) == NULL)
1144 if (cYAML_create_number(stats, "drop_count",
1145 data.st_cntrs.drop_count) == NULL)
1148 if (cYAML_create_number(stats, "send_length",
1149 data.st_cntrs.send_length) == NULL)
1152 if (cYAML_create_number(stats, "recv_length",
1153 data.st_cntrs.recv_length) == NULL)
1156 if (cYAML_create_number(stats, "route_length",
1157 data.st_cntrs.route_length) == NULL)
1160 if (cYAML_create_number(stats, "drop_length",
1161 data.st_cntrs.drop_length) == NULL)
1164 if (show_rc == NULL)
1165 cYAML_print_tree(root);
1167 snprintf(err_str, sizeof(err_str), "\"success\"");
1169 if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR) {
1170 cYAML_free_tree(root);
1171 } else if (show_rc != NULL && *show_rc != NULL) {
1172 cYAML_insert_sibling((*show_rc)->cy_child,
1179 cYAML_build_error(rc, seq_no, SHOW_CMD, "statistics", err_str, err_rc);
1184 typedef int (*cmd_handler_t)(struct cYAML *tree,
1185 struct cYAML **show_rc,
1186 struct cYAML **err_rc);
1188 static int handle_yaml_config_route(struct cYAML *tree, struct cYAML **show_rc,
1189 struct cYAML **err_rc)
1191 struct cYAML *net, *gw, *hop, *prio, *seq_no;
1193 net = cYAML_get_object_item(tree, "net");
1194 gw = cYAML_get_object_item(tree, "gateway");
1195 hop = cYAML_get_object_item(tree, "hop");
1196 prio = cYAML_get_object_item(tree, "priority");
1197 seq_no = cYAML_get_object_item(tree, "seq_no");
1199 return lustre_lnet_config_route((net) ? net->cy_valuestring : NULL,
1200 (gw) ? gw->cy_valuestring : NULL,
1201 (hop) ? hop->cy_valueint : -1,
1202 (prio) ? prio->cy_valueint : -1,
1203 (seq_no) ? seq_no->cy_valueint : -1,
1207 static int handle_yaml_config_net(struct cYAML *tree, struct cYAML **show_rc,
1208 struct cYAML **err_rc)
1210 struct cYAML *net, *intf, *tunables, *seq_no,
1211 *peer_to = NULL, *peer_buf_cr = NULL, *peer_cr = NULL,
1212 *credits = NULL, *ip2net = NULL, *smp = NULL, *child;
1213 char devs[LNET_MAX_STR_LEN];
1215 int size = LNET_MAX_STR_LEN;
1217 bool intf_found = false;
1219 ip2net = cYAML_get_object_item(tree, "ip2net");
1220 net = cYAML_get_object_item(tree, "net");
1221 intf = cYAML_get_object_item(tree, "interfaces");
1223 /* grab all the interfaces */
1224 child = intf->cy_child;
1225 while (child != NULL && size > 0) {
1227 num = snprintf(loc, size, ",%s",
1228 child->cy_valuestring);
1230 num = snprintf(loc, size, "%s",
1231 child->cy_valuestring);
1235 child = child->cy_next;
1239 tunables = cYAML_get_object_item(tree, "tunables");
1240 if (tunables != NULL) {
1241 peer_to = cYAML_get_object_item(tunables, "peer_timeout");
1242 peer_cr = cYAML_get_object_item(tunables, "peer_credits");
1243 peer_buf_cr = cYAML_get_object_item(tunables,
1244 "peer_buffer_credits");
1245 credits = cYAML_get_object_item(tunables, "credits");
1246 smp = cYAML_get_object_item(tunables, "SMP");
1248 seq_no = cYAML_get_object_item(tree, "seq_no");
1250 return lustre_lnet_config_net((net) ? net->cy_valuestring : NULL,
1251 (intf_found) ? devs : NULL,
1252 (ip2net) ? ip2net->cy_valuestring : NULL,
1253 (peer_to) ? peer_to->cy_valueint : -1,
1254 (peer_cr) ? peer_cr->cy_valueint : -1,
1256 peer_buf_cr->cy_valueint : -1,
1257 (credits) ? credits->cy_valueint : -1,
1258 (smp) ? smp->cy_valuestring : NULL,
1259 (seq_no) ? seq_no->cy_valueint : -1,
1263 static int handle_yaml_config_buffers(struct cYAML *tree,
1264 struct cYAML **show_rc,
1265 struct cYAML **err_rc)
1268 struct cYAML *tiny, *small, *large, *seq_no;
1270 tiny = cYAML_get_object_item(tree, "tiny");
1271 small = cYAML_get_object_item(tree, "small");
1272 large = cYAML_get_object_item(tree, "large");
1273 seq_no = cYAML_get_object_item(tree, "seq_no");
1275 rc = lustre_lnet_config_buffers((tiny) ? tiny->cy_valueint : -1,
1276 (small) ? small->cy_valueint : -1,
1277 (large) ? large->cy_valueint : -1,
1278 (seq_no) ? seq_no->cy_valueint : -1,
1284 static int handle_yaml_config_routing(struct cYAML *tree,
1285 struct cYAML **show_rc,
1286 struct cYAML **err_rc)
1288 int rc = LUSTRE_CFG_RC_NO_ERR;
1289 struct cYAML *seq_no, *enable;
1291 seq_no = cYAML_get_object_item(tree, "seq_no");
1292 enable = cYAML_get_object_item(tree, "enable");
1295 rc = lustre_lnet_enable_routing(enable->cy_valueint,
1297 seq_no->cy_valueint : -1,
1304 static int handle_yaml_del_route(struct cYAML *tree, struct cYAML **show_rc,
1305 struct cYAML **err_rc)
1309 struct cYAML *seq_no;
1311 net = cYAML_get_object_item(tree, "net");
1312 gw = cYAML_get_object_item(tree, "gateway");
1313 seq_no = cYAML_get_object_item(tree, "seq_no");
1315 return lustre_lnet_del_route((net) ? net->cy_valuestring : NULL,
1316 (gw) ? gw->cy_valuestring : NULL,
1317 (seq_no) ? seq_no->cy_valueint : -1,
1321 static int handle_yaml_del_net(struct cYAML *tree, struct cYAML **show_rc,
1322 struct cYAML **err_rc)
1324 struct cYAML *net, *seq_no;
1326 net = cYAML_get_object_item(tree, "net");
1327 seq_no = cYAML_get_object_item(tree, "seq_no");
1329 return lustre_lnet_del_net((net) ? net->cy_valuestring : NULL,
1330 (seq_no) ? seq_no->cy_valueint : -1,
1334 static int handle_yaml_del_routing(struct cYAML *tree, struct cYAML **show_rc,
1335 struct cYAML **err_rc)
1337 struct cYAML *seq_no;
1339 seq_no = cYAML_get_object_item(tree, "seq_no");
1341 return lustre_lnet_enable_routing(0, (seq_no) ?
1342 seq_no->cy_valueint : -1,
1346 static int handle_yaml_show_route(struct cYAML *tree, struct cYAML **show_rc,
1347 struct cYAML **err_rc)
1353 struct cYAML *detail;
1354 struct cYAML *seq_no;
1356 net = cYAML_get_object_item(tree, "net");
1357 gw = cYAML_get_object_item(tree, "gateway");
1358 hop = cYAML_get_object_item(tree, "hop");
1359 prio = cYAML_get_object_item(tree, "priority");
1360 detail = cYAML_get_object_item(tree, "detail");
1361 seq_no = cYAML_get_object_item(tree, "seq_no");
1363 return lustre_lnet_show_route((net) ? net->cy_valuestring : NULL,
1364 (gw) ? gw->cy_valuestring : NULL,
1365 (hop) ? hop->cy_valueint : -1,
1366 (prio) ? prio->cy_valueint : -1,
1367 (detail) ? detail->cy_valueint : 0,
1368 (seq_no) ? seq_no->cy_valueint : -1,
1373 static int handle_yaml_show_net(struct cYAML *tree, struct cYAML **show_rc,
1374 struct cYAML **err_rc)
1376 struct cYAML *net, *detail, *seq_no;
1378 net = cYAML_get_object_item(tree, "net");
1379 detail = cYAML_get_object_item(tree, "detail");
1380 seq_no = cYAML_get_object_item(tree, "seq_no");
1382 return lustre_lnet_show_net((net) ? net->cy_valuestring : NULL,
1383 (detail) ? detail->cy_valueint : 0,
1384 (seq_no) ? seq_no->cy_valueint : -1,
1389 static int handle_yaml_show_routing(struct cYAML *tree, struct cYAML **show_rc,
1390 struct cYAML **err_rc)
1392 struct cYAML *seq_no;
1394 seq_no = cYAML_get_object_item(tree, "seq_no");
1396 return lustre_lnet_show_routing((seq_no) ? seq_no->cy_valueint : -1,
1400 static int handle_yaml_show_credits(struct cYAML *tree, struct cYAML **show_rc,
1401 struct cYAML **err_rc)
1403 struct cYAML *seq_no;
1405 seq_no = cYAML_get_object_item(tree, "seq_no");
1407 return lustre_lnet_show_peer_credits((seq_no) ?
1408 seq_no->cy_valueint : -1,
1412 static int handle_yaml_show_stats(struct cYAML *tree, struct cYAML **show_rc,
1413 struct cYAML **err_rc)
1415 struct cYAML *seq_no;
1417 seq_no = cYAML_get_object_item(tree, "seq_no");
1419 return lustre_lnet_show_stats((seq_no) ? seq_no->cy_valueint : -1,
1423 struct lookup_cmd_hdlr_tbl {
1428 static struct lookup_cmd_hdlr_tbl lookup_config_tbl[] = {
1429 {"route", handle_yaml_config_route},
1430 {"net", handle_yaml_config_net},
1431 {"routing", handle_yaml_config_routing},
1432 {"buffers", handle_yaml_config_buffers},
1436 static struct lookup_cmd_hdlr_tbl lookup_del_tbl[] = {
1437 {"route", handle_yaml_del_route},
1438 {"net", handle_yaml_del_net},
1439 {"routing", handle_yaml_del_routing},
1443 static struct lookup_cmd_hdlr_tbl lookup_show_tbl[] = {
1444 {"route", handle_yaml_show_route},
1445 {"net", handle_yaml_show_net},
1446 {"buffers", handle_yaml_show_routing},
1447 {"routing", handle_yaml_show_routing},
1448 {"credits", handle_yaml_show_credits},
1449 {"statistics", handle_yaml_show_stats},
1453 static cmd_handler_t lookup_fn(char *key,
1454 struct lookup_cmd_hdlr_tbl *tbl)
1460 for (i = 0; tbl[i].name != NULL; i++) {
1461 if (strncmp(key, tbl[i].name, strlen(tbl[i].name)) == 0)
1468 static int lustre_yaml_cb_helper(char *f, struct lookup_cmd_hdlr_tbl *table,
1469 struct cYAML **show_rc, struct cYAML **err_rc)
1471 struct cYAML *tree, *item = NULL, *head, *child;
1473 char err_str[LNET_MAX_STR_LEN];
1474 int rc = LUSTRE_CFG_RC_NO_ERR, return_rc = LUSTRE_CFG_RC_NO_ERR;
1476 tree = cYAML_build_tree(f, NULL, 0, err_rc);
1478 return LUSTRE_CFG_RC_BAD_PARAM;
1480 child = tree->cy_child;
1481 while (child != NULL) {
1482 cb = lookup_fn(child->cy_string, table);
1484 snprintf(err_str, sizeof(err_str),
1485 "\"call back for '%s' not found\"",
1487 cYAML_build_error(LUSTRE_CFG_RC_BAD_PARAM, -1,
1488 "yaml", "helper", err_str, err_rc);
1492 if (cYAML_is_sequence(child)) {
1493 while ((head = cYAML_get_next_seq_item(child, &item))
1495 rc = cb(head, show_rc, err_rc);
1496 /* if processing fails or no cb is found
1498 if (rc != LUSTRE_CFG_RC_NO_ERR) {
1499 snprintf(err_str, sizeof(err_str),
1500 "\"Failed to process request: "
1502 head->cy_string, rc, cb);
1504 LUSTRE_CFG_RC_BAD_PARAM, -1,
1505 "yaml", "helper", err_str,
1511 rc = cb(child, show_rc, err_rc);
1512 /* if processing fails or no cb is found then fail */
1513 if (rc != LUSTRE_CFG_RC_NO_ERR) {
1514 snprintf(err_str, sizeof(err_str),
1515 "\"Failed to process request: '%s'"
1517 child->cy_string, rc, cb);
1518 cYAML_build_error(LUSTRE_CFG_RC_BAD_PARAM, -1,
1519 "yaml", "helper", err_str, err_rc);
1524 child = child->cy_next;
1528 cYAML_free_tree(tree);
1533 int lustre_yaml_config(char *f, struct cYAML **err_rc)
1535 return lustre_yaml_cb_helper(f, lookup_config_tbl,
1539 int lustre_yaml_del(char *f, struct cYAML **err_rc)
1541 return lustre_yaml_cb_helper(f, lookup_del_tbl,
1545 int lustre_yaml_show(char *f, struct cYAML **show_rc, struct cYAML **err_rc)
1547 return lustre_yaml_cb_helper(f, lookup_show_tbl,