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
42 #include <sys/ioctl.h>
43 #include <libcfs/util/ioctl.h>
44 #include <lnet/lnetctl.h>
45 #include <lnet/socklnd.h>
46 #include <lnet/lnet.h>
47 #include "liblnetconfig.h"
50 #define CONFIG_CMD "configure"
51 #define UNCONFIG_CMD "unconfigure"
54 #define SHOW_CMD "show"
56 int lustre_lnet_config_lib_init(void)
58 return register_ioc_dev(LNET_DEV_ID, LNET_DEV_PATH,
59 LNET_DEV_MAJOR, LNET_DEV_MINOR);
62 int lustre_lnet_config_ni_system(bool up, bool load_ni_from_mod,
63 int seq_no, struct cYAML **err_rc)
65 struct libcfs_ioctl_data data;
68 char err_str[LNET_MAX_STR_LEN];
70 snprintf(err_str, sizeof(err_str), "\"Success\"");
72 LIBCFS_IOC_INIT(data);
74 /* Reverse logic is used here in order not to change
76 data.ioc_flags = load_ni_from_mod ? 0 : 1;
78 opc = up ? IOC_LIBCFS_CONFIGURE : IOC_LIBCFS_UNCONFIGURE;
80 rc = l_ioctl(LNET_DEV_ID, opc, &data);
85 "\"LNet %s error: %s\"", (up) ? "configure" :
86 "unconfigure", strerror(errno));
90 cYAML_build_error(rc, seq_no, (up) ? CONFIG_CMD : UNCONFIG_CMD,
91 "lnet", err_str, err_rc);
96 int lustre_lnet_config_route(char *nw, char *gw, int hops, int prio,
97 int seq_no, struct cYAML **err_rc)
99 struct lnet_ioctl_config_data data;
100 lnet_nid_t gateway_nid;
101 int rc = LUSTRE_CFG_RC_NO_ERR;
102 __u32 net = LNET_NIDNET(LNET_NID_ANY);
103 char err_str[LNET_MAX_STR_LEN];
105 snprintf(err_str, sizeof(err_str), "\"Success\"");
107 if (nw == NULL || gw == NULL) {
110 "\"missing mandatory parameter(s): '%s'\"",
111 (nw == NULL && gw == NULL) ? "network, gateway" :
112 (nw == NULL) ? "network" : "gateway");
113 rc = LUSTRE_CFG_RC_MISSING_PARAM;
117 net = libcfs_str2net(nw);
118 if (net == LNET_NIDNET(LNET_NID_ANY)) {
121 "\"cannot parse net %s\"", nw);
122 rc = LUSTRE_CFG_RC_BAD_PARAM;
126 if (LNET_NETTYP(net) == CIBLND ||
127 LNET_NETTYP(net) == OPENIBLND ||
128 LNET_NETTYP(net) == IIBLND ||
129 LNET_NETTYP(net) == VIBLND) {
132 "\"obselete LNet type '%s'\"", libcfs_lnd2str(net));
133 rc = LUSTRE_CFG_RC_BAD_PARAM;
137 gateway_nid = libcfs_str2nid(gw);
138 if (gateway_nid == LNET_NID_ANY) {
141 "\"cannot parse gateway NID '%s'\"", gw);
142 rc = LUSTRE_CFG_RC_BAD_PARAM;
147 /* -1 indicates to use the default hop value */
149 } else if (hops < 1 || hops > 255) {
152 "\"invalid hop count %d, must be between 0 and 256\"",
154 rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
160 } else if (prio < 0) {
163 "\"invalid priority %d, must be greater than 0\"",
165 rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
169 LIBCFS_IOC_INIT_V2(data, cfg_hdr);
171 data.cfg_config_u.cfg_route.rtr_hop = hops;
172 data.cfg_config_u.cfg_route.rtr_priority = prio;
173 data.cfg_nid = gateway_nid;
175 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_ADD_ROUTE, &data);
179 "\"cannot add route: %s\"", strerror(errno));
185 cYAML_build_error(rc, seq_no, ADD_CMD, "route", err_str, err_rc);
190 int lustre_lnet_del_route(char *nw, char *gw,
191 int seq_no, struct cYAML **err_rc)
193 struct lnet_ioctl_config_data data;
194 lnet_nid_t gateway_nid;
195 int rc = LUSTRE_CFG_RC_NO_ERR;
196 __u32 net = LNET_NIDNET(LNET_NID_ANY);
197 char err_str[LNET_MAX_STR_LEN];
199 snprintf(err_str, sizeof(err_str), "\"Success\"");
201 if (nw == NULL || gw == NULL) {
204 "\"missing mandatory parameter(s): '%s'\"",
205 (nw == NULL && gw == NULL) ? "network, gateway" :
206 (nw == NULL) ? "network" : "gateway");
207 rc = LUSTRE_CFG_RC_MISSING_PARAM;
211 net = libcfs_str2net(nw);
212 if (net == LNET_NIDNET(LNET_NID_ANY)) {
215 "\"cannot parse net '%s'\"", nw);
216 rc = LUSTRE_CFG_RC_BAD_PARAM;
220 if (LNET_NETTYP(net) == CIBLND ||
221 LNET_NETTYP(net) == OPENIBLND ||
222 LNET_NETTYP(net) == IIBLND ||
223 LNET_NETTYP(net) == VIBLND) {
226 "\"obselete LNet type '%s'\"", libcfs_lnd2str(net));
227 rc = LUSTRE_CFG_RC_BAD_PARAM;
231 gateway_nid = libcfs_str2nid(gw);
232 if (gateway_nid == LNET_NID_ANY) {
235 "\"cannot parse gateway NID '%s'\"", gw);
236 rc = LUSTRE_CFG_RC_BAD_PARAM;
240 LIBCFS_IOC_INIT_V2(data, cfg_hdr);
242 data.cfg_nid = gateway_nid;
244 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_DEL_ROUTE, &data);
248 "\"cannot delete route: %s\"", strerror(errno));
254 cYAML_build_error(rc, seq_no, DEL_CMD, "route", err_str, err_rc);
259 int lustre_lnet_show_route(char *nw, char *gw, int hops, int prio, int detail,
260 int seq_no, struct cYAML **show_rc,
261 struct cYAML **err_rc)
263 struct lnet_ioctl_config_data data;
264 lnet_nid_t gateway_nid;
265 int rc = LUSTRE_CFG_RC_OUT_OF_MEM;
266 __u32 net = LNET_NIDNET(LNET_NID_ANY);
268 struct cYAML *root = NULL, *route = NULL, *item = NULL;
269 struct cYAML *first_seq = NULL;
270 char err_str[LNET_MAX_STR_LEN];
273 snprintf(err_str, sizeof(err_str),
274 "\"out of memory\"");
277 net = libcfs_str2net(nw);
278 if (net == LNET_NIDNET(LNET_NID_ANY)) {
281 "\"cannot parse net '%s'\"", nw);
282 rc = LUSTRE_CFG_RC_BAD_PARAM;
286 if (LNET_NETTYP(net) == CIBLND ||
287 LNET_NETTYP(net) == OPENIBLND ||
288 LNET_NETTYP(net) == IIBLND ||
289 LNET_NETTYP(net) == VIBLND) {
292 "\"obsolete LNet type '%s'\"",
293 libcfs_lnd2str(net));
294 rc = LUSTRE_CFG_RC_BAD_PARAM;
298 /* show all routes without filtering on net */
299 net = LNET_NIDNET(LNET_NID_ANY);
303 gateway_nid = libcfs_str2nid(gw);
304 if (gateway_nid == LNET_NID_ANY) {
307 "\"cannot parse gateway NID '%s'\"", gw);
308 rc = LUSTRE_CFG_RC_BAD_PARAM;
312 /* show all routes with out filtering on gateway */
313 gateway_nid = LNET_NID_ANY;
315 if ((hops < 1 && hops != -1) || hops > 255) {
318 "\"invalid hop count %d, must be between 0 and 256\"",
320 rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
324 /* create struct cYAML root object */
325 root = cYAML_create_object(NULL, NULL);
329 route = cYAML_create_seq(root, "route");
334 LIBCFS_IOC_INIT_V2(data, cfg_hdr);
337 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_ROUTE, &data);
341 /* filter on provided data */
342 if (net != LNET_NIDNET(LNET_NID_ANY) &&
346 if (gateway_nid != LNET_NID_ANY &&
347 gateway_nid != data.cfg_nid)
351 hops != data.cfg_config_u.cfg_route.rtr_hop)
355 prio != data.cfg_config_u.cfg_route.rtr_priority)
358 /* default rc to -1 incase we hit the goto */
362 item = cYAML_create_seq_item(route);
366 if (first_seq == NULL)
369 if (cYAML_create_string(item, "net",
370 libcfs_net2str(data.cfg_net)) == NULL)
373 if (cYAML_create_string(item, "gateway",
374 libcfs_nid2str(data.cfg_nid)) == NULL)
378 if (cYAML_create_number(item, "hop",
379 data.cfg_config_u.cfg_route.
384 if (cYAML_create_number(item, "priority",
386 cfg_route.rtr_priority) == NULL)
389 if (cYAML_create_string(item, "state",
390 data.cfg_config_u.cfg_route.
392 "up" : "down") == NULL)
397 /* print output iff show_rc is not provided */
399 cYAML_print_tree(root);
401 if (errno != ENOENT) {
404 "\"cannot get routes: %s\"",
409 rc = LUSTRE_CFG_RC_NO_ERR;
411 snprintf(err_str, sizeof(err_str), "\"success\"");
413 if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR || !exist) {
414 cYAML_free_tree(root);
415 } else if (show_rc != NULL && *show_rc != NULL) {
416 struct cYAML *show_node;
417 /* find the route node, if one doesn't exist then
418 * insert one. Otherwise add to the one there
420 show_node = cYAML_get_object_item(*show_rc, "route");
421 if (show_node != NULL && cYAML_is_sequence(show_node)) {
422 cYAML_insert_child(show_node, first_seq);
425 } else if (show_node == NULL) {
426 cYAML_insert_sibling((*show_rc)->cy_child,
430 cYAML_free_tree(root);
436 cYAML_build_error(rc, seq_no, SHOW_CMD, "route", err_str, err_rc);
441 int lustre_lnet_config_net(char *net, char *intf, char *ip2net,
442 int peer_to, int peer_cr, int peer_buf_cr,
443 int credits, char *smp, int seq_no,
444 struct cYAML **err_rc)
446 struct lnet_ioctl_config_data data;
447 char buf[LNET_MAX_STR_LEN];
448 int rc = LUSTRE_CFG_RC_NO_ERR, num_of_nets = 0;
449 char err_str[LNET_MAX_STR_LEN];
451 snprintf(err_str, sizeof(err_str), "\"success\"");
453 if (ip2net == NULL && (intf == NULL || net == NULL)) {
456 "\"mandatory parameter '%s' not specified."
457 " Optionally specify ip2net parameter\"",
458 (intf == NULL && net == NULL) ? "net, if" :
459 (intf == NULL) ? "if" : "net");
460 rc = LUSTRE_CFG_RC_MISSING_PARAM;
464 if (peer_to != -1 && peer_to <= 0) {
467 "\"peer timeout %d, must be greater than 0\"",
469 rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
473 if (ip2net != NULL && strlen(ip2net) >= sizeof(buf)) {
476 "\"ip2net string too long %d\"",
477 (int)strlen(ip2net));
478 rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
483 snprintf(buf, sizeof(buf) - 1, "%s(%s)%s",
487 LIBCFS_IOC_INIT_V2(data, cfg_hdr);
488 strncpy(data.cfg_config_u.cfg_net.net_intf,
489 (ip2net != NULL) ? ip2net : buf, sizeof(buf));
490 data.cfg_config_u.cfg_net.net_peer_timeout = peer_to;
491 data.cfg_config_u.cfg_net.net_peer_tx_credits = peer_cr;
492 data.cfg_config_u.cfg_net.net_peer_rtr_credits = peer_buf_cr;
493 data.cfg_config_u.cfg_net.net_max_tx_credits = credits;
495 num_of_nets = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_ADD_NET, &data);
496 if (num_of_nets < 0) {
499 "\"cannot add network: %s\"", strerror(errno));
504 cYAML_build_error((num_of_nets > 0) ? num_of_nets : rc,
505 seq_no, ADD_CMD, "net", err_str, err_rc);
510 int lustre_lnet_del_net(char *nw, int seq_no, struct cYAML **err_rc)
512 struct lnet_ioctl_config_data data;
513 __u32 net = LNET_NIDNET(LNET_NID_ANY);
514 int rc = LUSTRE_CFG_RC_NO_ERR;
515 char err_str[LNET_MAX_STR_LEN];
517 snprintf(err_str, sizeof(err_str), "\"success\"");
522 "\"missing mandatory parameter\"");
523 rc = LUSTRE_CFG_RC_MISSING_PARAM;
527 net = libcfs_str2net(nw);
528 if (net == LNET_NIDNET(LNET_NID_ANY)) {
531 "\"cannot parse net '%s'\"", nw);
532 rc = LUSTRE_CFG_RC_BAD_PARAM;
536 LIBCFS_IOC_INIT_V2(data, cfg_hdr);
539 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_DEL_NET, &data);
543 "\"cannot delete network: %s\"", strerror(errno));
549 cYAML_build_error(rc, seq_no, DEL_CMD, "net", err_str, err_rc);
554 int lustre_lnet_show_net(char *nw, int detail, int seq_no,
555 struct cYAML **show_rc, struct cYAML **err_rc)
558 struct lnet_ioctl_config_data *data;
559 struct lnet_ioctl_net_config *net_config;
560 __u32 net = LNET_NIDNET(LNET_NID_ANY);
561 int rc = LUSTRE_CFG_RC_OUT_OF_MEM, i, j;
562 struct cYAML *root = NULL, *tunables = NULL,
563 *net_node = NULL, *interfaces = NULL,
564 *item = NULL, *first_seq = NULL;
565 int str_buf_len = LNET_MAX_SHOW_NUM_CPT * 2;
566 char str_buf[str_buf_len];
568 char err_str[LNET_MAX_STR_LEN];
571 snprintf(err_str, sizeof(err_str), "\"out of memory\"");
573 buf = calloc(1, sizeof(*data) + sizeof(*net_config));
577 data = (struct lnet_ioctl_config_data *)buf;
580 net = libcfs_str2net(nw);
581 if (net == LNET_NIDNET(LNET_NID_ANY)) {
584 "\"cannot parse net '%s'\"", nw);
585 rc = LUSTRE_CFG_RC_BAD_PARAM;
590 root = cYAML_create_object(NULL, NULL);
594 net_node = cYAML_create_seq(root, "net");
595 if (net_node == NULL)
601 memset(buf, 0, sizeof(*data) + sizeof(*net_config));
603 LIBCFS_IOC_INIT_V2(*data, cfg_hdr);
605 * set the ioc_len to the proper value since INIT assumes
608 data->cfg_hdr.ioc_len = sizeof(struct lnet_ioctl_config_data) +
609 sizeof(struct lnet_ioctl_net_config);
612 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_NET, data);
616 /* filter on provided data */
617 if (net != LNET_NIDNET(LNET_NID_ANY) &&
618 net != LNET_NIDNET(data->cfg_nid))
621 /* default rc to -1 in case we hit the goto */
625 net_config = (struct lnet_ioctl_net_config *)data->cfg_bulk;
627 /* create the tree to be printed. */
628 item = cYAML_create_seq_item(net_node);
632 if (first_seq == NULL)
635 if (cYAML_create_string(item,
638 LNET_NIDNET(data->cfg_nid)))
642 if (cYAML_create_string(item, "nid",
643 libcfs_nid2str(data->cfg_nid)) == NULL)
646 if (cYAML_create_string(item,
648 (net_config->ni_status ==
650 "up" : "down") == NULL)
653 /* don't add interfaces unless there is at least one
655 if (strlen(net_config->ni_interfaces[0]) > 0) {
656 interfaces = cYAML_create_object(item, "interfaces");
657 if (interfaces == NULL)
660 for (j = 0; j < LNET_MAX_INTERFACES; j++) {
661 if (strlen(net_config->ni_interfaces[j]) > 0) {
663 sizeof(str_buf), "%d", j);
664 if (cYAML_create_string(interfaces,
666 net_config->ni_interfaces[j]) ==
676 tunables = cYAML_create_object(item, "tunables");
677 if (tunables == NULL)
680 if (cYAML_create_number(tunables, "peer_timeout",
681 data->cfg_config_u.cfg_net.
682 net_peer_timeout) == NULL)
685 if (cYAML_create_number(tunables, "peer_credits",
686 data->cfg_config_u.cfg_net.
687 net_peer_tx_credits) == NULL)
690 if (cYAML_create_number(tunables,
691 "peer_buffer_credits",
692 data->cfg_config_u.cfg_net.
693 net_peer_rtr_credits) == NULL)
696 if (cYAML_create_number(tunables, "credits",
697 data->cfg_config_u.cfg_net.
698 net_max_tx_credits) == NULL)
701 /* out put the CPTs in the format: "[x,x,x,...]" */
702 limit = str_buf + str_buf_len - 3;
703 pos += snprintf(pos, limit - pos, "\"[");
704 for (j = 0 ; data->cfg_ncpts > 1 &&
705 j < data->cfg_ncpts &&
707 pos += snprintf(pos, limit - pos,
708 "%d", net_config->ni_cpts[j]);
709 if ((j + 1) < data->cfg_ncpts)
710 pos += snprintf(pos, limit - pos, ",");
712 pos += snprintf(pos, 3, "]\"");
714 if (data->cfg_ncpts > 1 &&
715 cYAML_create_string(tunables, "CPT",
721 /* Print out the net information only if show_rc is not provided */
723 cYAML_print_tree(root);
725 if (errno != ENOENT) {
728 "\"cannot get networks: %s\"",
733 rc = LUSTRE_CFG_RC_NO_ERR;
735 snprintf(err_str, sizeof(err_str), "\"success\"");
737 if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR || !exist) {
738 cYAML_free_tree(root);
739 } else if (show_rc != NULL && *show_rc != NULL) {
740 struct cYAML *show_node;
741 /* find the net node, if one doesn't exist
742 * then insert one. Otherwise add to the one there
744 show_node = cYAML_get_object_item(*show_rc, "net");
745 if (show_node != NULL && cYAML_is_sequence(show_node)) {
746 cYAML_insert_child(show_node, first_seq);
749 } else if (show_node == NULL) {
750 cYAML_insert_sibling((*show_rc)->cy_child,
754 cYAML_free_tree(root);
760 cYAML_build_error(rc, seq_no, SHOW_CMD, "net", err_str, err_rc);
765 int lustre_lnet_enable_routing(int enable, int seq_no, struct cYAML **err_rc)
767 struct lnet_ioctl_config_data data;
768 int rc = LUSTRE_CFG_RC_NO_ERR;
769 char err_str[LNET_MAX_STR_LEN];
771 snprintf(err_str, sizeof(err_str), "\"success\"");
773 LIBCFS_IOC_INIT_V2(data, cfg_hdr);
774 data.cfg_config_u.cfg_buffers.buf_enable = (enable) ? 1 : 0;
776 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_CONFIG_RTR, &data);
780 "\"cannot %s routing %s\"",
781 (enable) ? "enable" : "disable", strerror(errno));
787 cYAML_build_error(rc, seq_no,
788 (enable) ? ADD_CMD : DEL_CMD,
789 "routing", err_str, err_rc);
794 int lustre_lnet_config_buffers(int tiny, int small, int large, int seq_no,
795 struct cYAML **err_rc)
797 struct lnet_ioctl_config_data data;
798 int rc = LUSTRE_CFG_RC_NO_ERR;
799 char err_str[LNET_MAX_STR_LEN];
801 snprintf(err_str, sizeof(err_str), "\"success\"");
803 /* -1 indicates to ignore changes to this field */
804 if (tiny < -1 || small < -1 || large < -1) {
807 "\"tiny, small and large must be >= 0\"");
808 rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
812 LIBCFS_IOC_INIT_V2(data, cfg_hdr);
813 data.cfg_config_u.cfg_buffers.buf_tiny = tiny;
814 data.cfg_config_u.cfg_buffers.buf_small = small;
815 data.cfg_config_u.cfg_buffers.buf_large = large;
817 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_ADD_BUF, &data);
821 "\"cannot configure buffers: %s\"", strerror(errno));
827 cYAML_build_error(rc, seq_no, DEL_CMD, "buf", err_str, err_rc);
832 int lustre_lnet_show_routing(int seq_no, struct cYAML **show_rc,
833 struct cYAML **err_rc)
835 struct lnet_ioctl_config_data *data;
836 struct lnet_ioctl_pool_cfg *pool_cfg = NULL;
837 int rc = LUSTRE_CFG_RC_OUT_OF_MEM;
839 char *pools[LNET_NRBPOOLS] = {"tiny", "small", "large"};
840 struct cYAML *root = NULL, *pools_node = NULL,
841 *type_node = NULL, *item = NULL, *cpt = NULL,
844 char err_str[LNET_MAX_STR_LEN];
845 char node_name[LNET_MAX_STR_LEN];
848 snprintf(err_str, sizeof(err_str), "\"out of memory\"");
850 buf = calloc(1, sizeof(*data) + sizeof(*pool_cfg));
854 data = (struct lnet_ioctl_config_data *)buf;
856 root = cYAML_create_object(NULL, NULL);
860 pools_node = cYAML_create_seq(root, "routing");
861 if (pools_node == NULL)
865 LIBCFS_IOC_INIT_V2(*data, cfg_hdr);
866 data->cfg_hdr.ioc_len = sizeof(struct lnet_ioctl_config_data) +
867 sizeof(struct lnet_ioctl_pool_cfg);
870 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_BUF, data);
876 pool_cfg = (struct lnet_ioctl_pool_cfg *)data->cfg_bulk;
878 snprintf(node_name, sizeof(node_name), "cpt[%d]", i);
879 item = cYAML_create_seq_item(pools_node);
883 if (first_seq == NULL)
886 cpt = cYAML_create_object(item, node_name);
890 /* create the tree and print */
891 for (j = 0; j < LNET_NRBPOOLS; j++) {
892 type_node = cYAML_create_object(cpt, pools[j]);
893 if (type_node == NULL)
895 if (cYAML_create_number(type_node, "npages",
896 pool_cfg->pl_pools[j].pl_npages)
899 if (cYAML_create_number(type_node, "nbuffers",
900 pool_cfg->pl_pools[j].
901 pl_nbuffers) == NULL)
903 if (cYAML_create_number(type_node, "credits",
904 pool_cfg->pl_pools[j].
907 if (cYAML_create_number(type_node, "mincredits",
908 pool_cfg->pl_pools[j].
909 pl_mincredits) == NULL)
914 if (pool_cfg != NULL) {
915 item = cYAML_create_seq_item(pools_node);
919 if (cYAML_create_number(item, "enable", pool_cfg->pl_routing) ==
925 cYAML_print_tree(root);
927 if (errno != ENOENT) {
930 "\"cannot get routing information: %s\"",
935 rc = LUSTRE_CFG_RC_NO_ERR;
937 snprintf(err_str, sizeof(err_str), "\"success\"");
938 rc = LUSTRE_CFG_RC_NO_ERR;
942 if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR || !exist) {
943 cYAML_free_tree(root);
944 } else if (show_rc != NULL && *show_rc != NULL) {
945 struct cYAML *show_node;
946 /* find the routing node, if one doesn't exist then
947 * insert one. Otherwise add to the one there
949 show_node = cYAML_get_object_item(*show_rc, "routing");
950 if (show_node != NULL && cYAML_is_sequence(show_node)) {
951 cYAML_insert_child(show_node, first_seq);
954 } else if (show_node == NULL) {
955 cYAML_insert_sibling((*show_rc)->cy_child,
959 cYAML_free_tree(root);
965 cYAML_build_error(rc, seq_no, SHOW_CMD, "routing", err_str, err_rc);
970 int lustre_lnet_show_peer_credits(int seq_no, struct cYAML **show_rc,
971 struct cYAML **err_rc)
973 struct lnet_ioctl_peer peer_info;
974 int rc = LUSTRE_CFG_RC_OUT_OF_MEM, ncpt = 0, i = 0, j = 0;
975 struct cYAML *root = NULL, *peer = NULL, *first_seq = NULL,
977 char err_str[LNET_MAX_STR_LEN];
978 bool ncpt_set = false;
980 snprintf(err_str, sizeof(err_str),
981 "\"out of memory\"");
983 /* create struct cYAML root object */
984 root = cYAML_create_object(NULL, NULL);
988 peer_root = cYAML_create_seq(root, "peer");
989 if (peer_root == NULL)
994 LIBCFS_IOC_INIT_V2(peer_info, pr_hdr);
995 peer_info.pr_count = i;
996 peer_info.pr_lnd_u.pr_peer_credits.cr_ncpt = j;
997 rc = l_ioctl(LNET_DEV_ID,
998 IOC_LIBCFS_GET_PEER_INFO, &peer_info);
1002 if (ncpt_set != 0) {
1003 ncpt = peer_info.pr_lnd_u.pr_peer_credits.
1008 peer = cYAML_create_seq_item(peer_root);
1012 if (first_seq == NULL)
1015 if (cYAML_create_string(peer, "nid",
1017 (peer_info.pr_nid)) == NULL)
1020 if (cYAML_create_string(peer, "state",
1027 if (cYAML_create_number(peer, "refcount",
1030 cr_refcount) == NULL)
1033 if (cYAML_create_number(peer, "max_ni_tx_credits",
1036 cr_ni_peer_tx_credits)
1040 if (cYAML_create_number(peer, "available_tx_credits",
1047 if (cYAML_create_number(peer, "available_rtr_credits",
1050 cr_peer_rtr_credits)
1054 if (cYAML_create_number(peer, "min_rtr_credits",
1057 cr_peer_min_rtr_credits)
1061 if (cYAML_create_number(peer, "tx_q_num_of_buf",
1069 if (errno != ENOENT) {
1072 "\"cannot get peer information: %s\"",
1081 /* print output iff show_rc is not provided */
1082 if (show_rc == NULL)
1083 cYAML_print_tree(root);
1085 snprintf(err_str, sizeof(err_str), "\"success\"");
1086 rc = LUSTRE_CFG_RC_NO_ERR;
1089 if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR) {
1090 cYAML_free_tree(root);
1091 } else if (show_rc != NULL && *show_rc != NULL) {
1092 struct cYAML *show_node;
1093 /* find the peer node, if one doesn't exist then
1094 * insert one. Otherwise add to the one there
1096 show_node = cYAML_get_object_item(*show_rc,
1098 if (show_node != NULL && cYAML_is_sequence(show_node)) {
1099 cYAML_insert_child(show_node, first_seq);
1102 } else if (show_node == NULL) {
1103 cYAML_insert_sibling((*show_rc)->cy_child,
1107 cYAML_free_tree(root);
1113 cYAML_build_error(rc, seq_no, SHOW_CMD, "peer_credits", err_str,
1119 int lustre_lnet_show_stats(int seq_no, struct cYAML **show_rc,
1120 struct cYAML **err_rc)
1122 struct lnet_ioctl_lnet_stats data;
1123 int rc = LUSTRE_CFG_RC_OUT_OF_MEM;
1124 char err_str[LNET_MAX_STR_LEN];
1125 struct cYAML *root = NULL, *stats = NULL;
1127 snprintf(err_str, sizeof(err_str), "\"out of memory\"");
1129 LIBCFS_IOC_INIT_V2(data, st_hdr);
1131 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_LNET_STATS, &data);
1135 "\"cannot get lnet statistics: %s\"",
1141 root = cYAML_create_object(NULL, NULL);
1145 stats = cYAML_create_object(root, "statistics");
1149 if (cYAML_create_number(stats, "msgs_alloc",
1150 data.st_cntrs.msgs_alloc) == NULL)
1153 if (cYAML_create_number(stats, "msgs_max",
1154 data.st_cntrs.msgs_max) == NULL)
1157 if (cYAML_create_number(stats, "errors",
1158 data.st_cntrs.errors) == NULL)
1161 if (cYAML_create_number(stats, "send_count",
1162 data.st_cntrs.send_count) == NULL)
1165 if (cYAML_create_number(stats, "recv_count",
1166 data.st_cntrs.recv_count) == NULL)
1169 if (cYAML_create_number(stats, "route_count",
1170 data.st_cntrs.route_count) == NULL)
1173 if (cYAML_create_number(stats, "drop_count",
1174 data.st_cntrs.drop_count) == NULL)
1177 if (cYAML_create_number(stats, "send_length",
1178 data.st_cntrs.send_length) == NULL)
1181 if (cYAML_create_number(stats, "recv_length",
1182 data.st_cntrs.recv_length) == NULL)
1185 if (cYAML_create_number(stats, "route_length",
1186 data.st_cntrs.route_length) == NULL)
1189 if (cYAML_create_number(stats, "drop_length",
1190 data.st_cntrs.drop_length) == NULL)
1193 if (show_rc == NULL)
1194 cYAML_print_tree(root);
1196 snprintf(err_str, sizeof(err_str), "\"success\"");
1198 if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR) {
1199 cYAML_free_tree(root);
1200 } else if (show_rc != NULL && *show_rc != NULL) {
1201 cYAML_insert_sibling((*show_rc)->cy_child,
1208 cYAML_build_error(rc, seq_no, SHOW_CMD, "statistics", err_str, err_rc);
1213 typedef int (*cmd_handler_t)(struct cYAML *tree,
1214 struct cYAML **show_rc,
1215 struct cYAML **err_rc);
1217 static int handle_yaml_config_route(struct cYAML *tree, struct cYAML **show_rc,
1218 struct cYAML **err_rc)
1220 struct cYAML *net, *gw, *hop, *prio, *seq_no;
1222 net = cYAML_get_object_item(tree, "net");
1223 gw = cYAML_get_object_item(tree, "gateway");
1224 hop = cYAML_get_object_item(tree, "hop");
1225 prio = cYAML_get_object_item(tree, "priority");
1226 seq_no = cYAML_get_object_item(tree, "seq_no");
1228 return lustre_lnet_config_route((net) ? net->cy_valuestring : NULL,
1229 (gw) ? gw->cy_valuestring : NULL,
1230 (hop) ? hop->cy_valueint : -1,
1231 (prio) ? prio->cy_valueint : -1,
1232 (seq_no) ? seq_no->cy_valueint : -1,
1236 static int handle_yaml_config_net(struct cYAML *tree, struct cYAML **show_rc,
1237 struct cYAML **err_rc)
1239 struct cYAML *net, *intf, *tunables, *seq_no,
1240 *peer_to = NULL, *peer_buf_cr = NULL, *peer_cr = NULL,
1241 *credits = NULL, *ip2net = NULL, *smp = NULL, *child;
1242 char devs[LNET_MAX_STR_LEN];
1244 int size = LNET_MAX_STR_LEN;
1246 bool intf_found = false;
1248 ip2net = cYAML_get_object_item(tree, "ip2net");
1249 net = cYAML_get_object_item(tree, "net");
1250 intf = cYAML_get_object_item(tree, "interfaces");
1252 /* grab all the interfaces */
1253 child = intf->cy_child;
1254 while (child != NULL && size > 0) {
1256 num = snprintf(loc, size, ",%s",
1257 child->cy_valuestring);
1259 num = snprintf(loc, size, "%s",
1260 child->cy_valuestring);
1264 child = child->cy_next;
1268 tunables = cYAML_get_object_item(tree, "tunables");
1269 if (tunables != NULL) {
1270 peer_to = cYAML_get_object_item(tunables, "peer_timeout");
1271 peer_cr = cYAML_get_object_item(tunables, "peer_credits");
1272 peer_buf_cr = cYAML_get_object_item(tunables,
1273 "peer_buffer_credits");
1274 credits = cYAML_get_object_item(tunables, "credits");
1275 smp = cYAML_get_object_item(tunables, "CPT");
1277 seq_no = cYAML_get_object_item(tree, "seq_no");
1279 return lustre_lnet_config_net((net) ? net->cy_valuestring : NULL,
1280 (intf_found) ? devs : NULL,
1281 (ip2net) ? ip2net->cy_valuestring : NULL,
1282 (peer_to) ? peer_to->cy_valueint : -1,
1283 (peer_cr) ? peer_cr->cy_valueint : -1,
1285 peer_buf_cr->cy_valueint : -1,
1286 (credits) ? credits->cy_valueint : -1,
1287 (smp) ? smp->cy_valuestring : NULL,
1288 (seq_no) ? seq_no->cy_valueint : -1,
1292 static int handle_yaml_config_buffers(struct cYAML *tree,
1293 struct cYAML **show_rc,
1294 struct cYAML **err_rc)
1297 struct cYAML *tiny, *small, *large, *seq_no;
1299 tiny = cYAML_get_object_item(tree, "tiny");
1300 small = cYAML_get_object_item(tree, "small");
1301 large = cYAML_get_object_item(tree, "large");
1302 seq_no = cYAML_get_object_item(tree, "seq_no");
1304 rc = lustre_lnet_config_buffers((tiny) ? tiny->cy_valueint : -1,
1305 (small) ? small->cy_valueint : -1,
1306 (large) ? large->cy_valueint : -1,
1307 (seq_no) ? seq_no->cy_valueint : -1,
1313 static int handle_yaml_config_routing(struct cYAML *tree,
1314 struct cYAML **show_rc,
1315 struct cYAML **err_rc)
1317 int rc = LUSTRE_CFG_RC_NO_ERR;
1318 struct cYAML *seq_no, *enable;
1320 seq_no = cYAML_get_object_item(tree, "seq_no");
1321 enable = cYAML_get_object_item(tree, "enable");
1324 rc = lustre_lnet_enable_routing(enable->cy_valueint,
1326 seq_no->cy_valueint : -1,
1333 static int handle_yaml_del_route(struct cYAML *tree, struct cYAML **show_rc,
1334 struct cYAML **err_rc)
1338 struct cYAML *seq_no;
1340 net = cYAML_get_object_item(tree, "net");
1341 gw = cYAML_get_object_item(tree, "gateway");
1342 seq_no = cYAML_get_object_item(tree, "seq_no");
1344 return lustre_lnet_del_route((net) ? net->cy_valuestring : NULL,
1345 (gw) ? gw->cy_valuestring : NULL,
1346 (seq_no) ? seq_no->cy_valueint : -1,
1350 static int handle_yaml_del_net(struct cYAML *tree, struct cYAML **show_rc,
1351 struct cYAML **err_rc)
1353 struct cYAML *net, *seq_no;
1355 net = cYAML_get_object_item(tree, "net");
1356 seq_no = cYAML_get_object_item(tree, "seq_no");
1358 return lustre_lnet_del_net((net) ? net->cy_valuestring : NULL,
1359 (seq_no) ? seq_no->cy_valueint : -1,
1363 static int handle_yaml_del_routing(struct cYAML *tree, struct cYAML **show_rc,
1364 struct cYAML **err_rc)
1366 struct cYAML *seq_no;
1368 seq_no = cYAML_get_object_item(tree, "seq_no");
1370 return lustre_lnet_enable_routing(0, (seq_no) ?
1371 seq_no->cy_valueint : -1,
1375 static int handle_yaml_show_route(struct cYAML *tree, struct cYAML **show_rc,
1376 struct cYAML **err_rc)
1382 struct cYAML *detail;
1383 struct cYAML *seq_no;
1385 net = cYAML_get_object_item(tree, "net");
1386 gw = cYAML_get_object_item(tree, "gateway");
1387 hop = cYAML_get_object_item(tree, "hop");
1388 prio = cYAML_get_object_item(tree, "priority");
1389 detail = cYAML_get_object_item(tree, "detail");
1390 seq_no = cYAML_get_object_item(tree, "seq_no");
1392 return lustre_lnet_show_route((net) ? net->cy_valuestring : NULL,
1393 (gw) ? gw->cy_valuestring : NULL,
1394 (hop) ? hop->cy_valueint : -1,
1395 (prio) ? prio->cy_valueint : -1,
1396 (detail) ? detail->cy_valueint : 0,
1397 (seq_no) ? seq_no->cy_valueint : -1,
1402 static int handle_yaml_show_net(struct cYAML *tree, struct cYAML **show_rc,
1403 struct cYAML **err_rc)
1405 struct cYAML *net, *detail, *seq_no;
1407 net = cYAML_get_object_item(tree, "net");
1408 detail = cYAML_get_object_item(tree, "detail");
1409 seq_no = cYAML_get_object_item(tree, "seq_no");
1411 return lustre_lnet_show_net((net) ? net->cy_valuestring : NULL,
1412 (detail) ? detail->cy_valueint : 0,
1413 (seq_no) ? seq_no->cy_valueint : -1,
1418 static int handle_yaml_show_routing(struct cYAML *tree, struct cYAML **show_rc,
1419 struct cYAML **err_rc)
1421 struct cYAML *seq_no;
1423 seq_no = cYAML_get_object_item(tree, "seq_no");
1425 return lustre_lnet_show_routing((seq_no) ? seq_no->cy_valueint : -1,
1429 static int handle_yaml_show_credits(struct cYAML *tree, struct cYAML **show_rc,
1430 struct cYAML **err_rc)
1432 struct cYAML *seq_no;
1434 seq_no = cYAML_get_object_item(tree, "seq_no");
1436 return lustre_lnet_show_peer_credits((seq_no) ?
1437 seq_no->cy_valueint : -1,
1441 static int handle_yaml_show_stats(struct cYAML *tree, struct cYAML **show_rc,
1442 struct cYAML **err_rc)
1444 struct cYAML *seq_no;
1446 seq_no = cYAML_get_object_item(tree, "seq_no");
1448 return lustre_lnet_show_stats((seq_no) ? seq_no->cy_valueint : -1,
1452 struct lookup_cmd_hdlr_tbl {
1457 static struct lookup_cmd_hdlr_tbl lookup_config_tbl[] = {
1458 {"route", handle_yaml_config_route},
1459 {"net", handle_yaml_config_net},
1460 {"routing", handle_yaml_config_routing},
1461 {"buffers", handle_yaml_config_buffers},
1465 static struct lookup_cmd_hdlr_tbl lookup_del_tbl[] = {
1466 {"route", handle_yaml_del_route},
1467 {"net", handle_yaml_del_net},
1468 {"routing", handle_yaml_del_routing},
1472 static struct lookup_cmd_hdlr_tbl lookup_show_tbl[] = {
1473 {"route", handle_yaml_show_route},
1474 {"net", handle_yaml_show_net},
1475 {"buffers", handle_yaml_show_routing},
1476 {"routing", handle_yaml_show_routing},
1477 {"credits", handle_yaml_show_credits},
1478 {"statistics", handle_yaml_show_stats},
1482 static cmd_handler_t lookup_fn(char *key,
1483 struct lookup_cmd_hdlr_tbl *tbl)
1489 for (i = 0; tbl[i].name != NULL; i++) {
1490 if (strncmp(key, tbl[i].name, strlen(tbl[i].name)) == 0)
1497 static int lustre_yaml_cb_helper(char *f, struct lookup_cmd_hdlr_tbl *table,
1498 struct cYAML **show_rc, struct cYAML **err_rc)
1500 struct cYAML *tree, *item = NULL, *head, *child;
1502 char err_str[LNET_MAX_STR_LEN];
1503 int rc = LUSTRE_CFG_RC_NO_ERR, return_rc = LUSTRE_CFG_RC_NO_ERR;
1505 tree = cYAML_build_tree(f, NULL, 0, err_rc);
1507 return LUSTRE_CFG_RC_BAD_PARAM;
1509 child = tree->cy_child;
1510 while (child != NULL) {
1511 cb = lookup_fn(child->cy_string, table);
1513 snprintf(err_str, sizeof(err_str),
1514 "\"call back for '%s' not found\"",
1516 cYAML_build_error(LUSTRE_CFG_RC_BAD_PARAM, -1,
1517 "yaml", "helper", err_str, err_rc);
1521 if (cYAML_is_sequence(child)) {
1522 while ((head = cYAML_get_next_seq_item(child, &item))
1524 rc = cb(head, show_rc, err_rc);
1525 if (rc != LUSTRE_CFG_RC_NO_ERR)
1529 rc = cb(child, show_rc, err_rc);
1530 if (rc != LUSTRE_CFG_RC_NO_ERR)
1534 child = child->cy_next;
1538 cYAML_free_tree(tree);
1543 int lustre_yaml_config(char *f, struct cYAML **err_rc)
1545 return lustre_yaml_cb_helper(f, lookup_config_tbl,
1549 int lustre_yaml_del(char *f, struct cYAML **err_rc)
1551 return lustre_yaml_cb_helper(f, lookup_del_tbl,
1555 int lustre_yaml_show(char *f, struct cYAML **show_rc, struct cYAML **err_rc)
1557 return lustre_yaml_cb_helper(f, lookup_show_tbl,