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, 2015, 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);
84 "\"LNet %s error: %s\"", (up) ? "configure" :
85 "unconfigure", strerror(errno));
89 cYAML_build_error(rc, seq_no, (up) ? CONFIG_CMD : UNCONFIG_CMD,
90 "lnet", err_str, err_rc);
95 int lustre_lnet_config_route(char *nw, char *gw, int hops, int prio,
96 int seq_no, struct cYAML **err_rc)
98 struct lnet_ioctl_config_data data;
99 lnet_nid_t gateway_nid;
100 int rc = LUSTRE_CFG_RC_NO_ERR;
101 __u32 net = LNET_NIDNET(LNET_NID_ANY);
102 char err_str[LNET_MAX_STR_LEN];
104 snprintf(err_str, sizeof(err_str), "\"Success\"");
106 if (nw == NULL || gw == NULL) {
109 "\"missing mandatory parameter(s): '%s'\"",
110 (nw == NULL && gw == NULL) ? "network, gateway" :
111 (nw == NULL) ? "network" : "gateway");
112 rc = LUSTRE_CFG_RC_MISSING_PARAM;
116 net = libcfs_str2net(nw);
117 if (net == LNET_NIDNET(LNET_NID_ANY)) {
120 "\"cannot parse net %s\"", nw);
121 rc = LUSTRE_CFG_RC_BAD_PARAM;
125 if (LNET_NETTYP(net) == CIBLND ||
126 LNET_NETTYP(net) == OPENIBLND ||
127 LNET_NETTYP(net) == IIBLND ||
128 LNET_NETTYP(net) == VIBLND) {
131 "\"obselete LNet type '%s'\"", libcfs_lnd2str(net));
132 rc = LUSTRE_CFG_RC_BAD_PARAM;
136 gateway_nid = libcfs_str2nid(gw);
137 if (gateway_nid == LNET_NID_ANY) {
140 "\"cannot parse gateway NID '%s'\"", gw);
141 rc = LUSTRE_CFG_RC_BAD_PARAM;
146 /* -1 indicates to use the default hop value */
148 } else if (hops < 1 || hops > 255) {
151 "\"invalid hop count %d, must be between 0 and 256\"",
153 rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
159 } else if (prio < 0) {
162 "\"invalid priority %d, must be greater than 0\"",
164 rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
168 LIBCFS_IOC_INIT_V2(data, cfg_hdr);
170 data.cfg_config_u.cfg_route.rtr_hop = hops;
171 data.cfg_config_u.cfg_route.rtr_priority = prio;
172 data.cfg_nid = gateway_nid;
174 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_ADD_ROUTE, &data);
179 "\"cannot add route: %s\"", strerror(errno));
184 cYAML_build_error(rc, seq_no, ADD_CMD, "route", err_str, err_rc);
189 int lustre_lnet_del_route(char *nw, char *gw,
190 int seq_no, struct cYAML **err_rc)
192 struct lnet_ioctl_config_data data;
193 lnet_nid_t gateway_nid;
194 int rc = LUSTRE_CFG_RC_NO_ERR;
195 __u32 net = LNET_NIDNET(LNET_NID_ANY);
196 char err_str[LNET_MAX_STR_LEN];
198 snprintf(err_str, sizeof(err_str), "\"Success\"");
200 if (nw == NULL || gw == NULL) {
203 "\"missing mandatory parameter(s): '%s'\"",
204 (nw == NULL && gw == NULL) ? "network, gateway" :
205 (nw == NULL) ? "network" : "gateway");
206 rc = LUSTRE_CFG_RC_MISSING_PARAM;
210 net = libcfs_str2net(nw);
211 if (net == LNET_NIDNET(LNET_NID_ANY)) {
214 "\"cannot parse net '%s'\"", nw);
215 rc = LUSTRE_CFG_RC_BAD_PARAM;
219 if (LNET_NETTYP(net) == CIBLND ||
220 LNET_NETTYP(net) == OPENIBLND ||
221 LNET_NETTYP(net) == IIBLND ||
222 LNET_NETTYP(net) == VIBLND) {
225 "\"obselete LNet type '%s'\"", libcfs_lnd2str(net));
226 rc = LUSTRE_CFG_RC_BAD_PARAM;
230 gateway_nid = libcfs_str2nid(gw);
231 if (gateway_nid == LNET_NID_ANY) {
234 "\"cannot parse gateway NID '%s'\"", gw);
235 rc = LUSTRE_CFG_RC_BAD_PARAM;
239 LIBCFS_IOC_INIT_V2(data, cfg_hdr);
241 data.cfg_nid = gateway_nid;
243 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_DEL_ROUTE, &data);
248 "\"cannot delete route: %s\"", strerror(errno));
253 cYAML_build_error(rc, seq_no, DEL_CMD, "route", err_str, err_rc);
258 int lustre_lnet_show_route(char *nw, char *gw, int hops, int prio, int detail,
259 int seq_no, struct cYAML **show_rc,
260 struct cYAML **err_rc)
262 struct lnet_ioctl_config_data data;
263 lnet_nid_t gateway_nid;
264 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);
343 /* filter on provided data */
344 if (net != LNET_NIDNET(LNET_NID_ANY) &&
348 if (gateway_nid != LNET_NID_ANY &&
349 gateway_nid != data.cfg_nid)
353 hops != data.cfg_config_u.cfg_route.rtr_hop)
357 prio != data.cfg_config_u.cfg_route.rtr_priority)
360 /* default rc to -1 incase we hit the goto */
364 item = cYAML_create_seq_item(route);
368 if (first_seq == NULL)
371 if (cYAML_create_string(item, "net",
372 libcfs_net2str(data.cfg_net)) == NULL)
375 if (cYAML_create_string(item, "gateway",
376 libcfs_nid2str(data.cfg_nid)) == NULL)
380 if (cYAML_create_number(item, "hop",
381 data.cfg_config_u.cfg_route.
386 if (cYAML_create_number(item, "priority",
388 cfg_route.rtr_priority) == NULL)
391 if (cYAML_create_string(item, "state",
392 data.cfg_config_u.cfg_route.
394 "up" : "down") == NULL)
399 /* print output iff show_rc is not provided */
401 cYAML_print_tree(root);
403 if (l_errno != ENOENT) {
406 "\"cannot get routes: %s\"",
411 rc = LUSTRE_CFG_RC_NO_ERR;
413 snprintf(err_str, sizeof(err_str), "\"success\"");
415 if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR || !exist) {
416 cYAML_free_tree(root);
417 } else if (show_rc != NULL && *show_rc != NULL) {
418 struct cYAML *show_node;
419 /* find the route node, if one doesn't exist then
420 * insert one. Otherwise add to the one there
422 show_node = cYAML_get_object_item(*show_rc, "route");
423 if (show_node != NULL && cYAML_is_sequence(show_node)) {
424 cYAML_insert_child(show_node, first_seq);
427 } else if (show_node == NULL) {
428 cYAML_insert_sibling((*show_rc)->cy_child,
432 cYAML_free_tree(root);
438 cYAML_build_error(rc, seq_no, SHOW_CMD, "route", err_str, err_rc);
443 int lustre_lnet_config_net(char *net, char *intf, char *ip2net,
444 int peer_to, int peer_cr, int peer_buf_cr,
445 int credits, char *smp, int seq_no,
446 struct cYAML **err_rc)
448 struct lnet_ioctl_config_data data;
449 char buf[LNET_MAX_STR_LEN];
450 int rc = LUSTRE_CFG_RC_NO_ERR;
451 char err_str[LNET_MAX_STR_LEN];
453 snprintf(err_str, sizeof(err_str), "\"success\"");
455 if (ip2net == NULL && (intf == NULL || net == NULL)) {
458 "\"mandatory parameter '%s' not specified."
459 " Optionally specify ip2net parameter\"",
460 (intf == NULL && net == NULL) ? "net, if" :
461 (intf == NULL) ? "if" : "net");
462 rc = LUSTRE_CFG_RC_MISSING_PARAM;
466 if (peer_to != -1 && peer_to <= 0) {
469 "\"peer timeout %d, must be greater than 0\"",
471 rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
475 if (ip2net != NULL && strlen(ip2net) >= sizeof(buf)) {
478 "\"ip2net string too long %d\"",
479 (int)strlen(ip2net));
480 rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
485 snprintf(buf, sizeof(buf) - 1, "%s(%s)%s",
489 LIBCFS_IOC_INIT_V2(data, cfg_hdr);
490 strncpy(data.cfg_config_u.cfg_net.net_intf,
491 (ip2net != NULL) ? ip2net : buf, sizeof(buf));
492 data.cfg_config_u.cfg_net.net_peer_timeout = peer_to;
493 data.cfg_config_u.cfg_net.net_peer_tx_credits = peer_cr;
494 data.cfg_config_u.cfg_net.net_peer_rtr_credits = peer_buf_cr;
495 data.cfg_config_u.cfg_net.net_max_tx_credits = credits;
497 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_ADD_NET, &data);
502 "\"cannot add network: %s\"", strerror(errno));
506 cYAML_build_error(rc, seq_no, ADD_CMD, "net", err_str, err_rc);
511 int lustre_lnet_del_net(char *nw, int seq_no, struct cYAML **err_rc)
513 struct lnet_ioctl_config_data data;
514 __u32 net = LNET_NIDNET(LNET_NID_ANY);
515 int rc = LUSTRE_CFG_RC_NO_ERR;
516 char err_str[LNET_MAX_STR_LEN];
518 snprintf(err_str, sizeof(err_str), "\"success\"");
523 "\"missing mandatory parameter\"");
524 rc = LUSTRE_CFG_RC_MISSING_PARAM;
528 net = libcfs_str2net(nw);
529 if (net == LNET_NIDNET(LNET_NID_ANY)) {
532 "\"cannot parse net '%s'\"", nw);
533 rc = LUSTRE_CFG_RC_BAD_PARAM;
537 LIBCFS_IOC_INIT_V2(data, cfg_hdr);
540 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_DEL_NET, &data);
545 "\"cannot delete network: %s\"", strerror(errno));
550 cYAML_build_error(rc, seq_no, DEL_CMD, "net", err_str, err_rc);
555 int lustre_lnet_show_net(char *nw, int detail, int seq_no,
556 struct cYAML **show_rc, struct cYAML **err_rc)
559 struct lnet_ioctl_config_data *data;
560 struct lnet_ioctl_net_config *net_config;
561 __u32 net = LNET_NIDNET(LNET_NID_ANY);
562 int rc = LUSTRE_CFG_RC_OUT_OF_MEM, i, j;
564 struct cYAML *root = NULL, *tunables = NULL,
565 *net_node = NULL, *interfaces = NULL,
566 *item = NULL, *first_seq = NULL;
567 int str_buf_len = LNET_MAX_SHOW_NUM_CPT * 2;
568 char str_buf[str_buf_len];
570 char err_str[LNET_MAX_STR_LEN];
573 snprintf(err_str, sizeof(err_str), "\"out of memory\"");
575 buf = calloc(1, sizeof(*data) + sizeof(*net_config));
579 data = (struct lnet_ioctl_config_data *)buf;
582 net = libcfs_str2net(nw);
583 if (net == LNET_NIDNET(LNET_NID_ANY)) {
586 "\"cannot parse net '%s'\"", nw);
587 rc = LUSTRE_CFG_RC_BAD_PARAM;
592 root = cYAML_create_object(NULL, NULL);
596 net_node = cYAML_create_seq(root, "net");
597 if (net_node == NULL)
603 memset(buf, 0, sizeof(*data) + sizeof(*net_config));
605 LIBCFS_IOC_INIT_V2(*data, cfg_hdr);
607 * set the ioc_len to the proper value since INIT assumes
610 data->cfg_hdr.ioc_len = sizeof(struct lnet_ioctl_config_data) +
611 sizeof(struct lnet_ioctl_net_config);
614 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_NET, data);
620 /* filter on provided data */
621 if (net != LNET_NIDNET(LNET_NID_ANY) &&
622 net != LNET_NIDNET(data->cfg_nid))
625 /* default rc to -1 in case we hit the goto */
629 net_config = (struct lnet_ioctl_net_config *)data->cfg_bulk;
631 /* create the tree to be printed. */
632 item = cYAML_create_seq_item(net_node);
636 if (first_seq == NULL)
639 if (cYAML_create_string(item,
642 LNET_NIDNET(data->cfg_nid)))
646 if (cYAML_create_string(item, "nid",
647 libcfs_nid2str(data->cfg_nid)) == NULL)
650 if (cYAML_create_string(item,
652 (net_config->ni_status ==
654 "up" : "down") == NULL)
657 /* don't add interfaces unless there is at least one
659 if (strlen(net_config->ni_interfaces[0]) > 0) {
660 interfaces = cYAML_create_object(item, "interfaces");
661 if (interfaces == NULL)
664 for (j = 0; j < LNET_MAX_INTERFACES; j++) {
665 if (strlen(net_config->ni_interfaces[j]) > 0) {
667 sizeof(str_buf), "%d", j);
668 if (cYAML_create_string(interfaces,
670 net_config->ni_interfaces[j]) ==
680 tunables = cYAML_create_object(item, "tunables");
681 if (tunables == NULL)
684 if (cYAML_create_number(tunables, "peer_timeout",
685 data->cfg_config_u.cfg_net.
686 net_peer_timeout) == NULL)
689 if (cYAML_create_number(tunables, "peer_credits",
690 data->cfg_config_u.cfg_net.
691 net_peer_tx_credits) == NULL)
694 if (cYAML_create_number(tunables,
695 "peer_buffer_credits",
696 data->cfg_config_u.cfg_net.
697 net_peer_rtr_credits) == NULL)
700 if (cYAML_create_number(tunables, "credits",
701 data->cfg_config_u.cfg_net.
702 net_max_tx_credits) == NULL)
705 /* out put the CPTs in the format: "[x,x,x,...]" */
706 limit = str_buf + str_buf_len - 3;
707 pos += snprintf(pos, limit - pos, "\"[");
708 for (j = 0 ; data->cfg_ncpts > 1 &&
709 j < data->cfg_ncpts &&
711 pos += snprintf(pos, limit - pos,
712 "%d", net_config->ni_cpts[j]);
713 if ((j + 1) < data->cfg_ncpts)
714 pos += snprintf(pos, limit - pos, ",");
716 pos += snprintf(pos, 3, "]\"");
718 if (data->cfg_ncpts > 1 &&
719 cYAML_create_string(tunables, "CPT",
725 /* Print out the net information only if show_rc is not provided */
727 cYAML_print_tree(root);
729 if (l_errno != ENOENT) {
732 "\"cannot get networks: %s\"",
737 rc = LUSTRE_CFG_RC_NO_ERR;
739 snprintf(err_str, sizeof(err_str), "\"success\"");
741 if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR || !exist) {
742 cYAML_free_tree(root);
743 } else if (show_rc != NULL && *show_rc != NULL) {
744 struct cYAML *show_node;
745 /* find the net node, if one doesn't exist
746 * then insert one. Otherwise add to the one there
748 show_node = cYAML_get_object_item(*show_rc, "net");
749 if (show_node != NULL && cYAML_is_sequence(show_node)) {
750 cYAML_insert_child(show_node, first_seq);
753 } else if (show_node == NULL) {
754 cYAML_insert_sibling((*show_rc)->cy_child,
758 cYAML_free_tree(root);
764 cYAML_build_error(rc, seq_no, SHOW_CMD, "net", err_str, err_rc);
769 int lustre_lnet_enable_routing(int enable, int seq_no, 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 LIBCFS_IOC_INIT_V2(data, cfg_hdr);
778 data.cfg_config_u.cfg_buffers.buf_enable = (enable) ? 1 : 0;
780 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_CONFIG_RTR, &data);
785 "\"cannot %s routing %s\"",
786 (enable) ? "enable" : "disable", strerror(errno));
791 cYAML_build_error(rc, seq_no,
792 (enable) ? ADD_CMD : DEL_CMD,
793 "routing", err_str, err_rc);
798 int lustre_lnet_config_buffers(int tiny, int small, int large, int seq_no,
799 struct cYAML **err_rc)
801 struct lnet_ioctl_config_data data;
802 int rc = LUSTRE_CFG_RC_NO_ERR;
803 char err_str[LNET_MAX_STR_LEN];
805 snprintf(err_str, sizeof(err_str), "\"success\"");
807 /* -1 indicates to ignore changes to this field */
808 if (tiny < -1 || small < -1 || large < -1) {
811 "\"tiny, small and large must be >= 0\"");
812 rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
816 LIBCFS_IOC_INIT_V2(data, cfg_hdr);
817 data.cfg_config_u.cfg_buffers.buf_tiny = tiny;
818 data.cfg_config_u.cfg_buffers.buf_small = small;
819 data.cfg_config_u.cfg_buffers.buf_large = large;
821 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_ADD_BUF, &data);
826 "\"cannot configure buffers: %s\"", strerror(errno));
831 cYAML_build_error(rc, seq_no, DEL_CMD, "buf", err_str, err_rc);
836 int lustre_lnet_show_routing(int seq_no, struct cYAML **show_rc,
837 struct cYAML **err_rc)
839 struct lnet_ioctl_config_data *data;
840 struct lnet_ioctl_pool_cfg *pool_cfg = NULL;
841 int rc = LUSTRE_CFG_RC_OUT_OF_MEM;
844 char *pools[LNET_NRBPOOLS] = {"tiny", "small", "large"};
845 struct cYAML *root = NULL, *pools_node = NULL,
846 *type_node = NULL, *item = NULL, *cpt = NULL,
849 char err_str[LNET_MAX_STR_LEN];
850 char node_name[LNET_MAX_STR_LEN];
853 snprintf(err_str, sizeof(err_str), "\"out of memory\"");
855 buf = calloc(1, sizeof(*data) + sizeof(*pool_cfg));
859 data = (struct lnet_ioctl_config_data *)buf;
861 root = cYAML_create_object(NULL, NULL);
865 pools_node = cYAML_create_seq(root, "routing");
866 if (pools_node == NULL)
870 LIBCFS_IOC_INIT_V2(*data, cfg_hdr);
871 data->cfg_hdr.ioc_len = sizeof(struct lnet_ioctl_config_data) +
872 sizeof(struct lnet_ioctl_pool_cfg);
875 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_BUF, data);
883 pool_cfg = (struct lnet_ioctl_pool_cfg *)data->cfg_bulk;
885 snprintf(node_name, sizeof(node_name), "cpt[%d]", i);
886 item = cYAML_create_seq_item(pools_node);
890 if (first_seq == NULL)
893 cpt = cYAML_create_object(item, node_name);
897 /* create the tree and print */
898 for (j = 0; j < LNET_NRBPOOLS; j++) {
899 type_node = cYAML_create_object(cpt, pools[j]);
900 if (type_node == NULL)
902 if (cYAML_create_number(type_node, "npages",
903 pool_cfg->pl_pools[j].pl_npages)
906 if (cYAML_create_number(type_node, "nbuffers",
907 pool_cfg->pl_pools[j].
908 pl_nbuffers) == NULL)
910 if (cYAML_create_number(type_node, "credits",
911 pool_cfg->pl_pools[j].
914 if (cYAML_create_number(type_node, "mincredits",
915 pool_cfg->pl_pools[j].
916 pl_mincredits) == NULL)
921 if (pool_cfg != NULL) {
922 item = cYAML_create_seq_item(pools_node);
926 if (cYAML_create_number(item, "enable", pool_cfg->pl_routing) ==
932 cYAML_print_tree(root);
934 if (l_errno != ENOENT) {
937 "\"cannot get routing information: %s\"",
942 rc = LUSTRE_CFG_RC_NO_ERR;
944 snprintf(err_str, sizeof(err_str), "\"success\"");
945 rc = LUSTRE_CFG_RC_NO_ERR;
949 if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR || !exist) {
950 cYAML_free_tree(root);
951 } else if (show_rc != NULL && *show_rc != NULL) {
952 struct cYAML *show_node;
953 /* find the routing node, if one doesn't exist then
954 * insert one. Otherwise add to the one there
956 show_node = cYAML_get_object_item(*show_rc, "routing");
957 if (show_node != NULL && cYAML_is_sequence(show_node)) {
958 cYAML_insert_child(show_node, first_seq);
961 } else if (show_node == NULL) {
962 cYAML_insert_sibling((*show_rc)->cy_child,
966 cYAML_free_tree(root);
972 cYAML_build_error(rc, seq_no, SHOW_CMD, "routing", err_str, err_rc);
977 int lustre_lnet_show_peer_credits(int seq_no, struct cYAML **show_rc,
978 struct cYAML **err_rc)
980 struct lnet_ioctl_peer peer_info;
981 int rc = LUSTRE_CFG_RC_OUT_OF_MEM, ncpt = 0, i = 0, j = 0;
983 struct cYAML *root = NULL, *peer = NULL, *first_seq = NULL,
985 char err_str[LNET_MAX_STR_LEN];
986 bool ncpt_set = false;
988 snprintf(err_str, sizeof(err_str),
989 "\"out of memory\"");
991 /* create struct cYAML root object */
992 root = cYAML_create_object(NULL, NULL);
996 peer_root = cYAML_create_seq(root, "peer");
997 if (peer_root == NULL)
1002 LIBCFS_IOC_INIT_V2(peer_info, pr_hdr);
1003 peer_info.pr_count = i;
1004 peer_info.pr_lnd_u.pr_peer_credits.cr_ncpt = j;
1005 rc = l_ioctl(LNET_DEV_ID,
1006 IOC_LIBCFS_GET_PEER_INFO, &peer_info);
1012 if (ncpt_set != 0) {
1013 ncpt = peer_info.pr_lnd_u.pr_peer_credits.
1018 peer = cYAML_create_seq_item(peer_root);
1022 if (first_seq == NULL)
1025 if (cYAML_create_string(peer, "nid",
1027 (peer_info.pr_nid)) == NULL)
1030 if (cYAML_create_string(peer, "state",
1037 if (cYAML_create_number(peer, "refcount",
1040 cr_refcount) == NULL)
1043 if (cYAML_create_number(peer, "max_ni_tx_credits",
1046 cr_ni_peer_tx_credits)
1050 if (cYAML_create_number(peer, "available_tx_credits",
1057 if (cYAML_create_number(peer, "available_rtr_credits",
1060 cr_peer_rtr_credits)
1064 if (cYAML_create_number(peer, "min_rtr_credits",
1067 cr_peer_min_rtr_credits)
1071 if (cYAML_create_number(peer, "tx_q_num_of_buf",
1079 if (l_errno != ENOENT) {
1082 "\"cannot get peer information: %s\"",
1091 /* print output iff show_rc is not provided */
1092 if (show_rc == NULL)
1093 cYAML_print_tree(root);
1095 snprintf(err_str, sizeof(err_str), "\"success\"");
1096 rc = LUSTRE_CFG_RC_NO_ERR;
1099 if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR) {
1100 cYAML_free_tree(root);
1101 } else if (show_rc != NULL && *show_rc != NULL) {
1102 struct cYAML *show_node;
1103 /* find the peer node, if one doesn't exist then
1104 * insert one. Otherwise add to the one there
1106 show_node = cYAML_get_object_item(*show_rc,
1108 if (show_node != NULL && cYAML_is_sequence(show_node)) {
1109 cYAML_insert_child(show_node, first_seq);
1112 } else if (show_node == NULL) {
1113 cYAML_insert_sibling((*show_rc)->cy_child,
1117 cYAML_free_tree(root);
1123 cYAML_build_error(rc, seq_no, SHOW_CMD, "peer_credits", err_str,
1129 int lustre_lnet_show_stats(int seq_no, struct cYAML **show_rc,
1130 struct cYAML **err_rc)
1132 struct lnet_ioctl_lnet_stats data;
1133 int rc = LUSTRE_CFG_RC_OUT_OF_MEM;
1135 char err_str[LNET_MAX_STR_LEN];
1136 struct cYAML *root = NULL, *stats = NULL;
1138 snprintf(err_str, sizeof(err_str), "\"out of memory\"");
1140 LIBCFS_IOC_INIT_V2(data, st_hdr);
1142 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_LNET_STATS, &data);
1147 "\"cannot get lnet statistics: %s\"",
1153 root = cYAML_create_object(NULL, NULL);
1157 stats = cYAML_create_object(root, "statistics");
1161 if (cYAML_create_number(stats, "msgs_alloc",
1162 data.st_cntrs.msgs_alloc) == NULL)
1165 if (cYAML_create_number(stats, "msgs_max",
1166 data.st_cntrs.msgs_max) == NULL)
1169 if (cYAML_create_number(stats, "errors",
1170 data.st_cntrs.errors) == NULL)
1173 if (cYAML_create_number(stats, "send_count",
1174 data.st_cntrs.send_count) == NULL)
1177 if (cYAML_create_number(stats, "recv_count",
1178 data.st_cntrs.recv_count) == NULL)
1181 if (cYAML_create_number(stats, "route_count",
1182 data.st_cntrs.route_count) == NULL)
1185 if (cYAML_create_number(stats, "drop_count",
1186 data.st_cntrs.drop_count) == NULL)
1189 if (cYAML_create_number(stats, "send_length",
1190 data.st_cntrs.send_length) == NULL)
1193 if (cYAML_create_number(stats, "recv_length",
1194 data.st_cntrs.recv_length) == NULL)
1197 if (cYAML_create_number(stats, "route_length",
1198 data.st_cntrs.route_length) == NULL)
1201 if (cYAML_create_number(stats, "drop_length",
1202 data.st_cntrs.drop_length) == NULL)
1205 if (show_rc == NULL)
1206 cYAML_print_tree(root);
1208 snprintf(err_str, sizeof(err_str), "\"success\"");
1210 if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR) {
1211 cYAML_free_tree(root);
1212 } else if (show_rc != NULL && *show_rc != NULL) {
1213 cYAML_insert_sibling((*show_rc)->cy_child,
1220 cYAML_build_error(rc, seq_no, SHOW_CMD, "statistics", err_str, err_rc);
1225 typedef int (*cmd_handler_t)(struct cYAML *tree,
1226 struct cYAML **show_rc,
1227 struct cYAML **err_rc);
1229 static int handle_yaml_config_route(struct cYAML *tree, struct cYAML **show_rc,
1230 struct cYAML **err_rc)
1232 struct cYAML *net, *gw, *hop, *prio, *seq_no;
1234 net = cYAML_get_object_item(tree, "net");
1235 gw = cYAML_get_object_item(tree, "gateway");
1236 hop = cYAML_get_object_item(tree, "hop");
1237 prio = cYAML_get_object_item(tree, "priority");
1238 seq_no = cYAML_get_object_item(tree, "seq_no");
1240 return lustre_lnet_config_route((net) ? net->cy_valuestring : NULL,
1241 (gw) ? gw->cy_valuestring : NULL,
1242 (hop) ? hop->cy_valueint : -1,
1243 (prio) ? prio->cy_valueint : -1,
1244 (seq_no) ? seq_no->cy_valueint : -1,
1248 static int handle_yaml_config_net(struct cYAML *tree, struct cYAML **show_rc,
1249 struct cYAML **err_rc)
1251 struct cYAML *net, *intf, *tunables, *seq_no,
1252 *peer_to = NULL, *peer_buf_cr = NULL, *peer_cr = NULL,
1253 *credits = NULL, *ip2net = NULL, *smp = NULL, *child;
1254 char devs[LNET_MAX_STR_LEN];
1256 int size = LNET_MAX_STR_LEN;
1258 bool intf_found = false;
1260 ip2net = cYAML_get_object_item(tree, "ip2net");
1261 net = cYAML_get_object_item(tree, "net");
1262 intf = cYAML_get_object_item(tree, "interfaces");
1264 /* grab all the interfaces */
1265 child = intf->cy_child;
1266 while (child != NULL && size > 0) {
1268 num = snprintf(loc, size, ",%s",
1269 child->cy_valuestring);
1271 num = snprintf(loc, size, "%s",
1272 child->cy_valuestring);
1276 child = child->cy_next;
1280 tunables = cYAML_get_object_item(tree, "tunables");
1281 if (tunables != NULL) {
1282 peer_to = cYAML_get_object_item(tunables, "peer_timeout");
1283 peer_cr = cYAML_get_object_item(tunables, "peer_credits");
1284 peer_buf_cr = cYAML_get_object_item(tunables,
1285 "peer_buffer_credits");
1286 credits = cYAML_get_object_item(tunables, "credits");
1287 smp = cYAML_get_object_item(tunables, "CPT");
1289 seq_no = cYAML_get_object_item(tree, "seq_no");
1291 return lustre_lnet_config_net((net) ? net->cy_valuestring : NULL,
1292 (intf_found) ? devs : NULL,
1293 (ip2net) ? ip2net->cy_valuestring : NULL,
1294 (peer_to) ? peer_to->cy_valueint : -1,
1295 (peer_cr) ? peer_cr->cy_valueint : -1,
1297 peer_buf_cr->cy_valueint : -1,
1298 (credits) ? credits->cy_valueint : -1,
1299 (smp) ? smp->cy_valuestring : NULL,
1300 (seq_no) ? seq_no->cy_valueint : -1,
1304 static int handle_yaml_config_buffers(struct cYAML *tree,
1305 struct cYAML **show_rc,
1306 struct cYAML **err_rc)
1309 struct cYAML *tiny, *small, *large, *seq_no;
1311 tiny = cYAML_get_object_item(tree, "tiny");
1312 small = cYAML_get_object_item(tree, "small");
1313 large = cYAML_get_object_item(tree, "large");
1314 seq_no = cYAML_get_object_item(tree, "seq_no");
1316 rc = lustre_lnet_config_buffers((tiny) ? tiny->cy_valueint : -1,
1317 (small) ? small->cy_valueint : -1,
1318 (large) ? large->cy_valueint : -1,
1319 (seq_no) ? seq_no->cy_valueint : -1,
1325 static int handle_yaml_config_routing(struct cYAML *tree,
1326 struct cYAML **show_rc,
1327 struct cYAML **err_rc)
1329 int rc = LUSTRE_CFG_RC_NO_ERR;
1330 struct cYAML *seq_no, *enable;
1332 seq_no = cYAML_get_object_item(tree, "seq_no");
1333 enable = cYAML_get_object_item(tree, "enable");
1336 rc = lustre_lnet_enable_routing(enable->cy_valueint,
1338 seq_no->cy_valueint : -1,
1345 static int handle_yaml_del_route(struct cYAML *tree, struct cYAML **show_rc,
1346 struct cYAML **err_rc)
1350 struct cYAML *seq_no;
1352 net = cYAML_get_object_item(tree, "net");
1353 gw = cYAML_get_object_item(tree, "gateway");
1354 seq_no = cYAML_get_object_item(tree, "seq_no");
1356 return lustre_lnet_del_route((net) ? net->cy_valuestring : NULL,
1357 (gw) ? gw->cy_valuestring : NULL,
1358 (seq_no) ? seq_no->cy_valueint : -1,
1362 static int handle_yaml_del_net(struct cYAML *tree, struct cYAML **show_rc,
1363 struct cYAML **err_rc)
1365 struct cYAML *net, *seq_no;
1367 net = cYAML_get_object_item(tree, "net");
1368 seq_no = cYAML_get_object_item(tree, "seq_no");
1370 return lustre_lnet_del_net((net) ? net->cy_valuestring : NULL,
1371 (seq_no) ? seq_no->cy_valueint : -1,
1375 static int handle_yaml_del_routing(struct cYAML *tree, struct cYAML **show_rc,
1376 struct cYAML **err_rc)
1378 struct cYAML *seq_no;
1380 seq_no = cYAML_get_object_item(tree, "seq_no");
1382 return lustre_lnet_enable_routing(0, (seq_no) ?
1383 seq_no->cy_valueint : -1,
1387 static int handle_yaml_show_route(struct cYAML *tree, struct cYAML **show_rc,
1388 struct cYAML **err_rc)
1394 struct cYAML *detail;
1395 struct cYAML *seq_no;
1397 net = cYAML_get_object_item(tree, "net");
1398 gw = cYAML_get_object_item(tree, "gateway");
1399 hop = cYAML_get_object_item(tree, "hop");
1400 prio = cYAML_get_object_item(tree, "priority");
1401 detail = cYAML_get_object_item(tree, "detail");
1402 seq_no = cYAML_get_object_item(tree, "seq_no");
1404 return lustre_lnet_show_route((net) ? net->cy_valuestring : NULL,
1405 (gw) ? gw->cy_valuestring : NULL,
1406 (hop) ? hop->cy_valueint : -1,
1407 (prio) ? prio->cy_valueint : -1,
1408 (detail) ? detail->cy_valueint : 0,
1409 (seq_no) ? seq_no->cy_valueint : -1,
1414 static int handle_yaml_show_net(struct cYAML *tree, struct cYAML **show_rc,
1415 struct cYAML **err_rc)
1417 struct cYAML *net, *detail, *seq_no;
1419 net = cYAML_get_object_item(tree, "net");
1420 detail = cYAML_get_object_item(tree, "detail");
1421 seq_no = cYAML_get_object_item(tree, "seq_no");
1423 return lustre_lnet_show_net((net) ? net->cy_valuestring : NULL,
1424 (detail) ? detail->cy_valueint : 0,
1425 (seq_no) ? seq_no->cy_valueint : -1,
1430 static int handle_yaml_show_routing(struct cYAML *tree, struct cYAML **show_rc,
1431 struct cYAML **err_rc)
1433 struct cYAML *seq_no;
1435 seq_no = cYAML_get_object_item(tree, "seq_no");
1437 return lustre_lnet_show_routing((seq_no) ? seq_no->cy_valueint : -1,
1441 static int handle_yaml_show_credits(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_peer_credits((seq_no) ?
1449 seq_no->cy_valueint : -1,
1453 static int handle_yaml_show_stats(struct cYAML *tree, struct cYAML **show_rc,
1454 struct cYAML **err_rc)
1456 struct cYAML *seq_no;
1458 seq_no = cYAML_get_object_item(tree, "seq_no");
1460 return lustre_lnet_show_stats((seq_no) ? seq_no->cy_valueint : -1,
1464 struct lookup_cmd_hdlr_tbl {
1469 static struct lookup_cmd_hdlr_tbl lookup_config_tbl[] = {
1470 {"route", handle_yaml_config_route},
1471 {"net", handle_yaml_config_net},
1472 {"routing", handle_yaml_config_routing},
1473 {"buffers", handle_yaml_config_buffers},
1477 static struct lookup_cmd_hdlr_tbl lookup_del_tbl[] = {
1478 {"route", handle_yaml_del_route},
1479 {"net", handle_yaml_del_net},
1480 {"routing", handle_yaml_del_routing},
1484 static struct lookup_cmd_hdlr_tbl lookup_show_tbl[] = {
1485 {"route", handle_yaml_show_route},
1486 {"net", handle_yaml_show_net},
1487 {"buffers", handle_yaml_show_routing},
1488 {"routing", handle_yaml_show_routing},
1489 {"credits", handle_yaml_show_credits},
1490 {"statistics", handle_yaml_show_stats},
1494 static cmd_handler_t lookup_fn(char *key,
1495 struct lookup_cmd_hdlr_tbl *tbl)
1501 for (i = 0; tbl[i].name != NULL; i++) {
1502 if (strncmp(key, tbl[i].name, strlen(tbl[i].name)) == 0)
1509 static int lustre_yaml_cb_helper(char *f, struct lookup_cmd_hdlr_tbl *table,
1510 struct cYAML **show_rc, struct cYAML **err_rc)
1512 struct cYAML *tree, *item = NULL, *head, *child;
1514 char err_str[LNET_MAX_STR_LEN];
1515 int rc = LUSTRE_CFG_RC_NO_ERR, return_rc = LUSTRE_CFG_RC_NO_ERR;
1517 tree = cYAML_build_tree(f, NULL, 0, err_rc);
1519 return LUSTRE_CFG_RC_BAD_PARAM;
1521 child = tree->cy_child;
1522 while (child != NULL) {
1523 cb = lookup_fn(child->cy_string, table);
1525 snprintf(err_str, sizeof(err_str),
1526 "\"call back for '%s' not found\"",
1528 cYAML_build_error(LUSTRE_CFG_RC_BAD_PARAM, -1,
1529 "yaml", "helper", err_str, err_rc);
1533 if (cYAML_is_sequence(child)) {
1534 while ((head = cYAML_get_next_seq_item(child, &item))
1536 rc = cb(head, show_rc, err_rc);
1537 if (rc != LUSTRE_CFG_RC_NO_ERR)
1541 rc = cb(child, show_rc, err_rc);
1542 if (rc != LUSTRE_CFG_RC_NO_ERR)
1546 child = child->cy_next;
1550 cYAML_free_tree(tree);
1555 int lustre_yaml_config(char *f, struct cYAML **err_rc)
1557 return lustre_yaml_cb_helper(f, lookup_config_tbl,
1561 int lustre_yaml_del(char *f, struct cYAML **err_rc)
1563 return lustre_yaml_cb_helper(f, lookup_del_tbl,
1567 int lustre_yaml_show(char *f, struct cYAML **show_rc, struct cYAML **err_rc)
1569 return lustre_yaml_cb_helper(f, lookup_show_tbl,