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)
594 memset(buf, 0, sizeof(*data) + sizeof(*net_config));
596 LIBCFS_IOC_INIT_V2(*data, cfg_hdr);
598 * set the ioc_len to the proper value since INIT assumes
601 data->cfg_hdr.ioc_len = sizeof(struct lnet_ioctl_config_data) +
602 sizeof(struct lnet_ioctl_net_config);
605 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_NET, data);
609 /* filter on provided data */
610 if (net != LNET_NIDNET(LNET_NID_ANY) &&
611 net != LNET_NIDNET(data->cfg_nid))
614 /* default rc to -1 in case we hit the goto */
617 net_config = (struct lnet_ioctl_net_config *)data->cfg_bulk;
619 /* create the tree to be printed. */
620 item = cYAML_create_seq_item(net_node);
624 if (first_seq == NULL)
627 if (cYAML_create_string(item,
630 LNET_NIDNET(data->cfg_nid)))
634 if (cYAML_create_string(item, "nid",
635 libcfs_nid2str(data->cfg_nid)) == NULL)
638 if (cYAML_create_string(item,
640 (net_config->ni_status ==
642 "up" : "down") == NULL)
645 /* don't add interfaces unless there is at least one
647 if (strlen(net_config->ni_interfaces[0]) > 0) {
648 interfaces = cYAML_create_object(item, "interfaces");
649 if (interfaces == NULL)
652 for (j = 0; j < LNET_MAX_INTERFACES; j++) {
653 if (strlen(net_config->ni_interfaces[j]) > 0) {
655 sizeof(str_buf), "%d", j);
656 if (cYAML_create_string(interfaces,
658 net_config->ni_interfaces[j]) ==
666 tunables = cYAML_create_object(item, "tunables");
667 if (tunables == NULL)
670 if (cYAML_create_number(tunables, "peer_timeout",
671 data->cfg_config_u.cfg_net.
672 net_peer_timeout) == NULL)
675 if (cYAML_create_number(tunables, "peer_credits",
676 data->cfg_config_u.cfg_net.
677 net_peer_tx_credits) == NULL)
680 if (cYAML_create_number(tunables,
681 "peer_buffer_credits",
682 data->cfg_config_u.cfg_net.
683 net_peer_rtr_credits) == NULL)
686 if (cYAML_create_number(tunables, "credits",
687 data->cfg_config_u.cfg_net.
688 net_max_tx_credits) == NULL)
691 /* out put the CPTs in the format: "[x,x,x,...]" */
692 pos += snprintf(pos, str_buf + str_buf_len - pos, "[");
693 for (j = 0 ; data->cfg_ncpts > 1 &&
694 j < data->cfg_ncpts; j++) {
696 str_buf + str_buf_len - pos,
697 "%d", net_config->ni_cpts[j]);
698 if ((j + 1) < data->cfg_ncpts)
704 if (str_buf + str_buf_len - pos <= 0)
705 pos += snprintf(str_buf + str_buf_len - 2,
709 str_buf + str_buf_len - pos,
712 if (data->cfg_ncpts > 1 &&
713 cYAML_create_string(tunables, "CPT",
719 /* Print out the net information only if show_rc is not provided */
721 cYAML_print_tree(root);
723 if (errno != ENOENT) {
726 "\"cannot get networks: %s\"",
731 rc = LUSTRE_CFG_RC_NO_ERR;
733 snprintf(err_str, sizeof(err_str), "\"success\"");
735 if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR) {
736 cYAML_free_tree(root);
737 } else if (show_rc != NULL && *show_rc != NULL) {
738 struct cYAML *show_node;
739 /* find the net node, if one doesn't exist
740 * then insert one. Otherwise add to the one there
742 show_node = cYAML_get_object_item(*show_rc, "net");
743 if (show_node != NULL && cYAML_is_sequence(show_node)) {
744 cYAML_insert_child(show_node, first_seq);
747 } else if (show_node == NULL) {
748 cYAML_insert_sibling((*show_rc)->cy_child,
752 cYAML_free_tree(root);
758 cYAML_build_error(rc, seq_no, SHOW_CMD, "net", err_str, err_rc);
763 int lustre_lnet_enable_routing(int enable, int seq_no, struct cYAML **err_rc)
765 struct lnet_ioctl_config_data data;
766 int rc = LUSTRE_CFG_RC_NO_ERR;
767 char err_str[LNET_MAX_STR_LEN];
769 snprintf(err_str, sizeof(err_str), "\"success\"");
771 LIBCFS_IOC_INIT_V2(data, cfg_hdr);
772 data.cfg_config_u.cfg_buffers.buf_enable = (enable) ? 1 : 0;
774 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_CONFIG_RTR, &data);
778 "\"cannot %s routing %s\"",
779 (enable) ? "enable" : "disable", strerror(errno));
785 cYAML_build_error(rc, seq_no,
786 (enable) ? ADD_CMD : DEL_CMD,
787 "routing", err_str, err_rc);
792 int lustre_lnet_config_buffers(int tiny, int small, int large, int seq_no,
793 struct cYAML **err_rc)
795 struct lnet_ioctl_config_data data;
796 int rc = LUSTRE_CFG_RC_NO_ERR;
797 char err_str[LNET_MAX_STR_LEN];
799 snprintf(err_str, sizeof(err_str), "\"success\"");
801 /* -1 indicates to ignore changes to this field */
802 if (tiny < -1 || small < -1 || large < -1) {
805 "\"tiny, small and large must be >= 0\"");
806 rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
810 LIBCFS_IOC_INIT_V2(data, cfg_hdr);
811 data.cfg_config_u.cfg_buffers.buf_tiny = tiny;
812 data.cfg_config_u.cfg_buffers.buf_small = small;
813 data.cfg_config_u.cfg_buffers.buf_large = large;
815 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_ADD_BUF, &data);
819 "\"cannot configure buffers: %s\"", strerror(errno));
825 cYAML_build_error(rc, seq_no, DEL_CMD, "buf", err_str, err_rc);
830 int lustre_lnet_show_routing(int seq_no, struct cYAML **show_rc,
831 struct cYAML **err_rc)
833 struct lnet_ioctl_config_data *data;
834 struct lnet_ioctl_pool_cfg *pool_cfg = NULL;
835 int rc = LUSTRE_CFG_RC_OUT_OF_MEM;
837 char *pools[LNET_NRBPOOLS] = {"tiny", "small", "large"};
838 struct cYAML *root = NULL, *pools_node = NULL,
839 *type_node = NULL, *item = NULL, *cpt = NULL,
842 char err_str[LNET_MAX_STR_LEN];
843 char node_name[LNET_MAX_STR_LEN];
845 snprintf(err_str, sizeof(err_str), "\"out of memory\"");
847 buf = calloc(1, sizeof(*data) + sizeof(*pool_cfg));
851 data = (struct lnet_ioctl_config_data *)buf;
853 root = cYAML_create_object(NULL, NULL);
857 pools_node = cYAML_create_seq(root, "routing");
858 if (pools_node == NULL)
862 LIBCFS_IOC_INIT_V2(*data, cfg_hdr);
863 data->cfg_hdr.ioc_len = sizeof(struct lnet_ioctl_config_data) +
864 sizeof(struct lnet_ioctl_pool_cfg);
867 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_BUF, data);
871 pool_cfg = (struct lnet_ioctl_pool_cfg *)data->cfg_bulk;
873 snprintf(node_name, sizeof(node_name), "cpt[%d]", i);
874 item = cYAML_create_seq_item(pools_node);
878 if (first_seq == NULL)
881 cpt = cYAML_create_object(item, node_name);
885 /* create the tree and print */
886 for (j = 0; j < LNET_NRBPOOLS; j++) {
887 type_node = cYAML_create_object(cpt, pools[j]);
888 if (type_node == NULL)
890 if (cYAML_create_number(type_node, "npages",
891 pool_cfg->pl_pools[j].pl_npages)
894 if (cYAML_create_number(type_node, "nbuffers",
895 pool_cfg->pl_pools[j].
896 pl_nbuffers) == NULL)
898 if (cYAML_create_number(type_node, "credits",
899 pool_cfg->pl_pools[j].
902 if (cYAML_create_number(type_node, "mincredits",
903 pool_cfg->pl_pools[j].
904 pl_mincredits) == NULL)
909 if (pool_cfg != NULL) {
910 item = cYAML_create_seq_item(pools_node);
914 if (cYAML_create_number(item, "enable", pool_cfg->pl_routing) ==
920 cYAML_print_tree(root);
922 if (errno != ENOENT) {
925 "\"cannot get routing information: %s\"",
930 rc = LUSTRE_CFG_RC_NO_ERR;
932 snprintf(err_str, sizeof(err_str), "\"success\"");
933 rc = LUSTRE_CFG_RC_NO_ERR;
937 if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR) {
938 cYAML_free_tree(root);
939 } else if (show_rc != NULL && *show_rc != NULL) {
940 struct cYAML *show_node;
941 /* find the routing node, if one doesn't exist then
942 * insert one. Otherwise add to the one there
944 show_node = cYAML_get_object_item(*show_rc, "routing");
945 if (show_node != NULL && cYAML_is_sequence(show_node)) {
946 cYAML_insert_child(show_node, first_seq);
949 } else if (show_node == NULL) {
950 cYAML_insert_sibling((*show_rc)->cy_child,
954 cYAML_free_tree(root);
960 cYAML_build_error(rc, seq_no, SHOW_CMD, "routing", err_str, err_rc);
965 int lustre_lnet_show_peer_credits(int seq_no, struct cYAML **show_rc,
966 struct cYAML **err_rc)
968 struct lnet_ioctl_peer peer_info;
969 int rc = LUSTRE_CFG_RC_OUT_OF_MEM, ncpt = 0, i = 0, j = 0;
970 struct cYAML *root = NULL, *peer = NULL, *first_seq = NULL,
972 char err_str[LNET_MAX_STR_LEN];
973 bool ncpt_set = false;
975 snprintf(err_str, sizeof(err_str),
976 "\"out of memory\"");
978 /* create struct cYAML root object */
979 root = cYAML_create_object(NULL, NULL);
983 peer_root = cYAML_create_seq(root, "peer");
984 if (peer_root == NULL)
989 LIBCFS_IOC_INIT_V2(peer_info, pr_hdr);
990 peer_info.pr_count = i;
991 peer_info.pr_lnd_u.pr_peer_credits.cr_ncpt = j;
992 rc = l_ioctl(LNET_DEV_ID,
993 IOC_LIBCFS_GET_PEER_INFO, &peer_info);
998 ncpt = peer_info.pr_lnd_u.pr_peer_credits.
1003 peer = cYAML_create_seq_item(peer_root);
1007 if (first_seq == NULL)
1010 if (cYAML_create_string(peer, "nid",
1012 (peer_info.pr_nid)) == NULL)
1015 if (cYAML_create_string(peer, "state",
1022 if (cYAML_create_number(peer, "refcount",
1025 cr_refcount) == NULL)
1028 if (cYAML_create_number(peer, "max_ni_tx_credits",
1031 cr_ni_peer_tx_credits)
1035 if (cYAML_create_number(peer, "available_tx_credits",
1042 if (cYAML_create_number(peer, "available_rtr_credits",
1045 cr_peer_rtr_credits)
1049 if (cYAML_create_number(peer, "min_rtr_credits",
1052 cr_peer_min_rtr_credits)
1056 if (cYAML_create_number(peer, "tx_q_num_of_buf",
1064 if (errno != ENOENT) {
1067 "\"cannot get peer information: %s\"",
1076 /* print output iff show_rc is not provided */
1077 if (show_rc == NULL)
1078 cYAML_print_tree(root);
1080 snprintf(err_str, sizeof(err_str), "\"success\"");
1081 rc = LUSTRE_CFG_RC_NO_ERR;
1084 if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR) {
1085 cYAML_free_tree(root);
1086 } else if (show_rc != NULL && *show_rc != NULL) {
1087 struct cYAML *show_node;
1088 /* find the peer node, if one doesn't exist then
1089 * insert one. Otherwise add to the one there
1091 show_node = cYAML_get_object_item(*show_rc,
1093 if (show_node != NULL && cYAML_is_sequence(show_node)) {
1094 cYAML_insert_child(show_node, first_seq);
1097 } else if (show_node == NULL) {
1098 cYAML_insert_sibling((*show_rc)->cy_child,
1102 cYAML_free_tree(root);
1108 cYAML_build_error(rc, seq_no, SHOW_CMD, "peer_credits", err_str,
1114 int lustre_lnet_show_stats(int seq_no, struct cYAML **show_rc,
1115 struct cYAML **err_rc)
1117 struct lnet_ioctl_lnet_stats data;
1118 int rc = LUSTRE_CFG_RC_OUT_OF_MEM;
1119 char err_str[LNET_MAX_STR_LEN];
1120 struct cYAML *root = NULL, *stats = NULL;
1122 snprintf(err_str, sizeof(err_str), "\"out of memory\"");
1124 LIBCFS_IOC_INIT_V2(data, st_hdr);
1126 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_LNET_STATS, &data);
1130 "\"cannot get lnet statistics: %s\"",
1136 root = cYAML_create_object(NULL, NULL);
1140 stats = cYAML_create_object(root, "statistics");
1144 if (cYAML_create_number(stats, "msgs_alloc",
1145 data.st_cntrs.msgs_alloc) == NULL)
1148 if (cYAML_create_number(stats, "msgs_max",
1149 data.st_cntrs.msgs_max) == NULL)
1152 if (cYAML_create_number(stats, "errors",
1153 data.st_cntrs.errors) == NULL)
1156 if (cYAML_create_number(stats, "send_count",
1157 data.st_cntrs.send_count) == NULL)
1160 if (cYAML_create_number(stats, "recv_count",
1161 data.st_cntrs.recv_count) == NULL)
1164 if (cYAML_create_number(stats, "route_count",
1165 data.st_cntrs.route_count) == NULL)
1168 if (cYAML_create_number(stats, "drop_count",
1169 data.st_cntrs.drop_count) == NULL)
1172 if (cYAML_create_number(stats, "send_length",
1173 data.st_cntrs.send_length) == NULL)
1176 if (cYAML_create_number(stats, "recv_length",
1177 data.st_cntrs.recv_length) == NULL)
1180 if (cYAML_create_number(stats, "route_length",
1181 data.st_cntrs.route_length) == NULL)
1184 if (cYAML_create_number(stats, "drop_length",
1185 data.st_cntrs.drop_length) == NULL)
1188 if (show_rc == NULL)
1189 cYAML_print_tree(root);
1191 snprintf(err_str, sizeof(err_str), "\"success\"");
1193 if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR) {
1194 cYAML_free_tree(root);
1195 } else if (show_rc != NULL && *show_rc != NULL) {
1196 cYAML_insert_sibling((*show_rc)->cy_child,
1203 cYAML_build_error(rc, seq_no, SHOW_CMD, "statistics", err_str, err_rc);
1208 typedef int (*cmd_handler_t)(struct cYAML *tree,
1209 struct cYAML **show_rc,
1210 struct cYAML **err_rc);
1212 static int handle_yaml_config_route(struct cYAML *tree, struct cYAML **show_rc,
1213 struct cYAML **err_rc)
1215 struct cYAML *net, *gw, *hop, *prio, *seq_no;
1217 net = cYAML_get_object_item(tree, "net");
1218 gw = cYAML_get_object_item(tree, "gateway");
1219 hop = cYAML_get_object_item(tree, "hop");
1220 prio = cYAML_get_object_item(tree, "priority");
1221 seq_no = cYAML_get_object_item(tree, "seq_no");
1223 return lustre_lnet_config_route((net) ? net->cy_valuestring : NULL,
1224 (gw) ? gw->cy_valuestring : NULL,
1225 (hop) ? hop->cy_valueint : -1,
1226 (prio) ? prio->cy_valueint : -1,
1227 (seq_no) ? seq_no->cy_valueint : -1,
1231 static int handle_yaml_config_net(struct cYAML *tree, struct cYAML **show_rc,
1232 struct cYAML **err_rc)
1234 struct cYAML *net, *intf, *tunables, *seq_no,
1235 *peer_to = NULL, *peer_buf_cr = NULL, *peer_cr = NULL,
1236 *credits = NULL, *ip2net = NULL, *smp = NULL, *child;
1237 char devs[LNET_MAX_STR_LEN];
1239 int size = LNET_MAX_STR_LEN;
1241 bool intf_found = false;
1243 ip2net = cYAML_get_object_item(tree, "ip2net");
1244 net = cYAML_get_object_item(tree, "net");
1245 intf = cYAML_get_object_item(tree, "interfaces");
1247 /* grab all the interfaces */
1248 child = intf->cy_child;
1249 while (child != NULL && size > 0) {
1251 num = snprintf(loc, size, ",%s",
1252 child->cy_valuestring);
1254 num = snprintf(loc, size, "%s",
1255 child->cy_valuestring);
1259 child = child->cy_next;
1263 tunables = cYAML_get_object_item(tree, "tunables");
1264 if (tunables != NULL) {
1265 peer_to = cYAML_get_object_item(tunables, "peer_timeout");
1266 peer_cr = cYAML_get_object_item(tunables, "peer_credits");
1267 peer_buf_cr = cYAML_get_object_item(tunables,
1268 "peer_buffer_credits");
1269 credits = cYAML_get_object_item(tunables, "credits");
1270 smp = cYAML_get_object_item(tunables, "CPT");
1272 seq_no = cYAML_get_object_item(tree, "seq_no");
1274 return lustre_lnet_config_net((net) ? net->cy_valuestring : NULL,
1275 (intf_found) ? devs : NULL,
1276 (ip2net) ? ip2net->cy_valuestring : NULL,
1277 (peer_to) ? peer_to->cy_valueint : -1,
1278 (peer_cr) ? peer_cr->cy_valueint : -1,
1280 peer_buf_cr->cy_valueint : -1,
1281 (credits) ? credits->cy_valueint : -1,
1282 (smp) ? smp->cy_valuestring : NULL,
1283 (seq_no) ? seq_no->cy_valueint : -1,
1287 static int handle_yaml_config_buffers(struct cYAML *tree,
1288 struct cYAML **show_rc,
1289 struct cYAML **err_rc)
1292 struct cYAML *tiny, *small, *large, *seq_no;
1294 tiny = cYAML_get_object_item(tree, "tiny");
1295 small = cYAML_get_object_item(tree, "small");
1296 large = cYAML_get_object_item(tree, "large");
1297 seq_no = cYAML_get_object_item(tree, "seq_no");
1299 rc = lustre_lnet_config_buffers((tiny) ? tiny->cy_valueint : -1,
1300 (small) ? small->cy_valueint : -1,
1301 (large) ? large->cy_valueint : -1,
1302 (seq_no) ? seq_no->cy_valueint : -1,
1308 static int handle_yaml_config_routing(struct cYAML *tree,
1309 struct cYAML **show_rc,
1310 struct cYAML **err_rc)
1312 int rc = LUSTRE_CFG_RC_NO_ERR;
1313 struct cYAML *seq_no, *enable;
1315 seq_no = cYAML_get_object_item(tree, "seq_no");
1316 enable = cYAML_get_object_item(tree, "enable");
1319 rc = lustre_lnet_enable_routing(enable->cy_valueint,
1321 seq_no->cy_valueint : -1,
1328 static int handle_yaml_del_route(struct cYAML *tree, struct cYAML **show_rc,
1329 struct cYAML **err_rc)
1333 struct cYAML *seq_no;
1335 net = cYAML_get_object_item(tree, "net");
1336 gw = cYAML_get_object_item(tree, "gateway");
1337 seq_no = cYAML_get_object_item(tree, "seq_no");
1339 return lustre_lnet_del_route((net) ? net->cy_valuestring : NULL,
1340 (gw) ? gw->cy_valuestring : NULL,
1341 (seq_no) ? seq_no->cy_valueint : -1,
1345 static int handle_yaml_del_net(struct cYAML *tree, struct cYAML **show_rc,
1346 struct cYAML **err_rc)
1348 struct cYAML *net, *seq_no;
1350 net = cYAML_get_object_item(tree, "net");
1351 seq_no = cYAML_get_object_item(tree, "seq_no");
1353 return lustre_lnet_del_net((net) ? net->cy_valuestring : NULL,
1354 (seq_no) ? seq_no->cy_valueint : -1,
1358 static int handle_yaml_del_routing(struct cYAML *tree, struct cYAML **show_rc,
1359 struct cYAML **err_rc)
1361 struct cYAML *seq_no;
1363 seq_no = cYAML_get_object_item(tree, "seq_no");
1365 return lustre_lnet_enable_routing(0, (seq_no) ?
1366 seq_no->cy_valueint : -1,
1370 static int handle_yaml_show_route(struct cYAML *tree, struct cYAML **show_rc,
1371 struct cYAML **err_rc)
1377 struct cYAML *detail;
1378 struct cYAML *seq_no;
1380 net = cYAML_get_object_item(tree, "net");
1381 gw = cYAML_get_object_item(tree, "gateway");
1382 hop = cYAML_get_object_item(tree, "hop");
1383 prio = cYAML_get_object_item(tree, "priority");
1384 detail = cYAML_get_object_item(tree, "detail");
1385 seq_no = cYAML_get_object_item(tree, "seq_no");
1387 return lustre_lnet_show_route((net) ? net->cy_valuestring : NULL,
1388 (gw) ? gw->cy_valuestring : NULL,
1389 (hop) ? hop->cy_valueint : -1,
1390 (prio) ? prio->cy_valueint : -1,
1391 (detail) ? detail->cy_valueint : 0,
1392 (seq_no) ? seq_no->cy_valueint : -1,
1397 static int handle_yaml_show_net(struct cYAML *tree, struct cYAML **show_rc,
1398 struct cYAML **err_rc)
1400 struct cYAML *net, *detail, *seq_no;
1402 net = cYAML_get_object_item(tree, "net");
1403 detail = cYAML_get_object_item(tree, "detail");
1404 seq_no = cYAML_get_object_item(tree, "seq_no");
1406 return lustre_lnet_show_net((net) ? net->cy_valuestring : NULL,
1407 (detail) ? detail->cy_valueint : 0,
1408 (seq_no) ? seq_no->cy_valueint : -1,
1413 static int handle_yaml_show_routing(struct cYAML *tree, struct cYAML **show_rc,
1414 struct cYAML **err_rc)
1416 struct cYAML *seq_no;
1418 seq_no = cYAML_get_object_item(tree, "seq_no");
1420 return lustre_lnet_show_routing((seq_no) ? seq_no->cy_valueint : -1,
1424 static int handle_yaml_show_credits(struct cYAML *tree, struct cYAML **show_rc,
1425 struct cYAML **err_rc)
1427 struct cYAML *seq_no;
1429 seq_no = cYAML_get_object_item(tree, "seq_no");
1431 return lustre_lnet_show_peer_credits((seq_no) ?
1432 seq_no->cy_valueint : -1,
1436 static int handle_yaml_show_stats(struct cYAML *tree, struct cYAML **show_rc,
1437 struct cYAML **err_rc)
1439 struct cYAML *seq_no;
1441 seq_no = cYAML_get_object_item(tree, "seq_no");
1443 return lustre_lnet_show_stats((seq_no) ? seq_no->cy_valueint : -1,
1447 struct lookup_cmd_hdlr_tbl {
1452 static struct lookup_cmd_hdlr_tbl lookup_config_tbl[] = {
1453 {"route", handle_yaml_config_route},
1454 {"net", handle_yaml_config_net},
1455 {"routing", handle_yaml_config_routing},
1456 {"buffers", handle_yaml_config_buffers},
1460 static struct lookup_cmd_hdlr_tbl lookup_del_tbl[] = {
1461 {"route", handle_yaml_del_route},
1462 {"net", handle_yaml_del_net},
1463 {"routing", handle_yaml_del_routing},
1467 static struct lookup_cmd_hdlr_tbl lookup_show_tbl[] = {
1468 {"route", handle_yaml_show_route},
1469 {"net", handle_yaml_show_net},
1470 {"buffers", handle_yaml_show_routing},
1471 {"routing", handle_yaml_show_routing},
1472 {"credits", handle_yaml_show_credits},
1473 {"statistics", handle_yaml_show_stats},
1477 static cmd_handler_t lookup_fn(char *key,
1478 struct lookup_cmd_hdlr_tbl *tbl)
1484 for (i = 0; tbl[i].name != NULL; i++) {
1485 if (strncmp(key, tbl[i].name, strlen(tbl[i].name)) == 0)
1492 static int lustre_yaml_cb_helper(char *f, struct lookup_cmd_hdlr_tbl *table,
1493 struct cYAML **show_rc, struct cYAML **err_rc)
1495 struct cYAML *tree, *item = NULL, *head, *child;
1497 char err_str[LNET_MAX_STR_LEN];
1498 int rc = LUSTRE_CFG_RC_NO_ERR, return_rc = LUSTRE_CFG_RC_NO_ERR;
1500 tree = cYAML_build_tree(f, NULL, 0, err_rc);
1502 return LUSTRE_CFG_RC_BAD_PARAM;
1504 child = tree->cy_child;
1505 while (child != NULL) {
1506 cb = lookup_fn(child->cy_string, table);
1508 snprintf(err_str, sizeof(err_str),
1509 "\"call back for '%s' not found\"",
1511 cYAML_build_error(LUSTRE_CFG_RC_BAD_PARAM, -1,
1512 "yaml", "helper", err_str, err_rc);
1516 if (cYAML_is_sequence(child)) {
1517 while ((head = cYAML_get_next_seq_item(child, &item))
1519 rc = cb(head, show_rc, err_rc);
1520 /* if processing fails or no cb is found
1522 if (rc != LUSTRE_CFG_RC_NO_ERR) {
1523 snprintf(err_str, sizeof(err_str),
1524 "\"Failed to process request: "
1526 head->cy_string, rc, cb);
1528 LUSTRE_CFG_RC_BAD_PARAM, -1,
1529 "yaml", "helper", err_str,
1535 rc = cb(child, show_rc, err_rc);
1536 /* if processing fails or no cb is found then fail */
1537 if (rc != LUSTRE_CFG_RC_NO_ERR) {
1538 snprintf(err_str, sizeof(err_str),
1539 "\"Failed to process request: '%s'"
1541 child->cy_string, rc, cb);
1542 cYAML_build_error(LUSTRE_CFG_RC_BAD_PARAM, -1,
1543 "yaml", "helper", err_str, err_rc);
1548 child = child->cy_next;
1552 cYAML_free_tree(tree);
1557 int lustre_yaml_config(char *f, struct cYAML **err_rc)
1559 return lustre_yaml_cb_helper(f, lookup_config_tbl,
1563 int lustre_yaml_del(char *f, struct cYAML **err_rc)
1565 return lustre_yaml_cb_helper(f, lookup_del_tbl,
1569 int lustre_yaml_show(char *f, struct cYAML **show_rc, struct cYAML **err_rc)
1571 return lustre_yaml_cb_helper(f, lookup_show_tbl,