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>
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 /* hops is undefined */
147 hops = LNET_UNDEFINED_HOPS;
148 } else if (hops < 1 || hops > 255) {
151 "\"invalid hop count %d, must be between 1 and 255\"",
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 lnet_ioctl_config_lnd_tunables *lnd_tunables,
447 struct cYAML **err_rc)
449 struct lnet_ioctl_config_lnd_tunables *lnd = NULL;
450 struct lnet_ioctl_config_data *data;
451 size_t ioctl_size = sizeof(*data);
452 char buf[LNET_MAX_STR_LEN];
453 int rc = LUSTRE_CFG_RC_NO_ERR;
454 char err_str[LNET_MAX_STR_LEN];
456 snprintf(err_str, sizeof(err_str), "\"success\"");
458 /* No need to register lo */
459 if (net != NULL && !strcmp(net, "lo"))
462 if (ip2net == NULL && (intf == NULL || net == NULL)) {
465 "\"mandatory parameter '%s' not specified."
466 " Optionally specify ip2net parameter\"",
467 (intf == NULL && net == NULL) ? "net, if" :
468 (intf == NULL) ? "if" : "net");
469 rc = LUSTRE_CFG_RC_MISSING_PARAM;
473 if (peer_to != -1 && peer_to <= 0) {
476 "\"peer timeout %d, must be greater than 0\"",
478 rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
482 if (ip2net != NULL && strlen(ip2net) >= sizeof(buf)) {
485 "\"ip2net string too long %d\"",
486 (int)strlen(ip2net));
487 rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
491 if (lnd_tunables != NULL)
492 ioctl_size += sizeof(*lnd_tunables);
494 data = calloc(1, ioctl_size);
499 snprintf(buf, sizeof(buf) - 1, "%s(%s)%s",
503 LIBCFS_IOC_INIT_V2(*data, cfg_hdr);
504 strncpy(data->cfg_config_u.cfg_net.net_intf,
505 (ip2net != NULL) ? ip2net : buf, sizeof(buf));
506 data->cfg_config_u.cfg_net.net_peer_timeout = peer_to;
507 data->cfg_config_u.cfg_net.net_peer_tx_credits = peer_cr;
508 data->cfg_config_u.cfg_net.net_peer_rtr_credits = peer_buf_cr;
509 data->cfg_config_u.cfg_net.net_max_tx_credits = credits;
510 /* Add in tunable settings if available */
511 if (lnd_tunables != NULL) {
512 lnd = (struct lnet_ioctl_config_lnd_tunables *)data->cfg_bulk;
514 data->cfg_hdr.ioc_len = ioctl_size;
515 memcpy(lnd, lnd_tunables, sizeof(*lnd_tunables));
518 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_ADD_NET, data);
523 "\"cannot add network: %s\"", strerror(errno));
528 cYAML_build_error(rc, seq_no, ADD_CMD, "net", err_str, err_rc);
533 int lustre_lnet_del_net(char *nw, int seq_no, struct cYAML **err_rc)
535 struct lnet_ioctl_config_data data;
536 __u32 net = LNET_NIDNET(LNET_NID_ANY);
537 int rc = LUSTRE_CFG_RC_NO_ERR;
538 char err_str[LNET_MAX_STR_LEN];
540 snprintf(err_str, sizeof(err_str), "\"success\"");
545 "\"missing mandatory parameter\"");
546 rc = LUSTRE_CFG_RC_MISSING_PARAM;
550 net = libcfs_str2net(nw);
551 if (net == LNET_NIDNET(LNET_NID_ANY)) {
554 "\"cannot parse net '%s'\"", nw);
555 rc = LUSTRE_CFG_RC_BAD_PARAM;
559 LIBCFS_IOC_INIT_V2(data, cfg_hdr);
562 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_DEL_NET, &data);
567 "\"cannot delete network: %s\"", strerror(errno));
572 cYAML_build_error(rc, seq_no, DEL_CMD, "net", err_str, err_rc);
577 int lustre_lnet_show_net(char *nw, int detail, int seq_no,
578 struct cYAML **show_rc, struct cYAML **err_rc)
581 struct lnet_ioctl_config_lnd_tunables *lnd_cfg;
582 struct lnet_ioctl_config_data *data;
583 struct lnet_ioctl_net_config *net_config;
584 __u32 net = LNET_NIDNET(LNET_NID_ANY);
585 int rc = LUSTRE_CFG_RC_OUT_OF_MEM, i, j;
587 struct cYAML *root = NULL, *tunables = NULL, *net_node = NULL,
588 *interfaces = NULL, *item = NULL, *first_seq = NULL;
589 int str_buf_len = LNET_MAX_SHOW_NUM_CPT * 2;
590 char str_buf[str_buf_len];
592 char err_str[LNET_MAX_STR_LEN];
596 snprintf(err_str, sizeof(err_str), "\"out of memory\"");
598 buf_len = sizeof(*data) + sizeof(*net_config) + sizeof(*lnd_cfg);
599 buf = calloc(1, buf_len);
603 data = (struct lnet_ioctl_config_data *)buf;
606 net = libcfs_str2net(nw);
607 if (net == LNET_NIDNET(LNET_NID_ANY)) {
610 "\"cannot parse net '%s'\"", nw);
611 rc = LUSTRE_CFG_RC_BAD_PARAM;
616 root = cYAML_create_object(NULL, NULL);
620 net_node = cYAML_create_seq(root, "net");
621 if (net_node == NULL)
627 memset(buf, 0, buf_len);
629 LIBCFS_IOC_INIT_V2(*data, cfg_hdr);
631 * set the ioc_len to the proper value since INIT assumes
634 data->cfg_hdr.ioc_len = buf_len;
637 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_NET, data);
643 /* filter on provided data */
644 if (net != LNET_NIDNET(LNET_NID_ANY) &&
645 net != LNET_NIDNET(data->cfg_nid))
648 /* default rc to -1 in case we hit the goto */
652 net_config = (struct lnet_ioctl_net_config *)data->cfg_bulk;
654 /* create the tree to be printed. */
655 item = cYAML_create_seq_item(net_node);
659 if (first_seq == NULL)
662 if (cYAML_create_string(item, "net",
664 LNET_NIDNET(data->cfg_nid)))
668 if (cYAML_create_string(item, "nid",
669 libcfs_nid2str(data->cfg_nid)) == NULL)
672 if (cYAML_create_string(item, "status",
673 (net_config->ni_status ==
675 "up" : "down") == NULL)
678 /* don't add interfaces unless there is at least one
680 if (strlen(net_config->ni_interfaces[0]) > 0) {
681 interfaces = cYAML_create_object(item, "interfaces");
682 if (interfaces == NULL)
685 for (j = 0; j < LNET_MAX_INTERFACES; j++) {
686 if (lustre_interface_show_net(interfaces, j,
696 tunables = cYAML_create_object(item, "tunables");
697 if (tunables == NULL)
700 if (cYAML_create_number(tunables, "peer_timeout",
701 data->cfg_config_u.cfg_net.
702 net_peer_timeout) == NULL)
705 if (cYAML_create_number(tunables, "peer_credits",
706 data->cfg_config_u.cfg_net.
707 net_peer_tx_credits) == NULL)
710 if (cYAML_create_number(tunables,
711 "peer_buffer_credits",
712 data->cfg_config_u.cfg_net.
713 net_peer_rtr_credits) == NULL)
716 if (cYAML_create_number(tunables, "credits",
717 data->cfg_config_u.cfg_net.
718 net_max_tx_credits) == NULL)
721 /* out put the CPTs in the format: "[x,x,x,...]" */
722 limit = str_buf + str_buf_len - 3;
723 pos += snprintf(pos, limit - pos, "\"[");
724 for (j = 0 ; data->cfg_ncpts > 1 &&
725 j < data->cfg_ncpts &&
727 pos += snprintf(pos, limit - pos,
728 "%d", net_config->ni_cpts[j]);
729 if ((j + 1) < data->cfg_ncpts)
730 pos += snprintf(pos, limit - pos, ",");
732 pos += snprintf(pos, 3, "]\"");
734 if (data->cfg_ncpts > 1 &&
735 cYAML_create_string(tunables, "CPT",
741 /* Print out the net information only if show_rc is not provided */
743 cYAML_print_tree(root);
745 if (l_errno != ENOENT) {
748 "\"cannot get networks: %s\"",
753 rc = LUSTRE_CFG_RC_NO_ERR;
755 snprintf(err_str, sizeof(err_str), "\"success\"");
757 if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR || !exist) {
758 cYAML_free_tree(root);
759 } else if (show_rc != NULL && *show_rc != NULL) {
760 struct cYAML *show_node;
761 /* find the net node, if one doesn't exist
762 * then insert one. Otherwise add to the one there
764 show_node = cYAML_get_object_item(*show_rc, "net");
765 if (show_node != NULL && cYAML_is_sequence(show_node)) {
766 cYAML_insert_child(show_node, first_seq);
769 } else if (show_node == NULL) {
770 cYAML_insert_sibling((*show_rc)->cy_child,
774 cYAML_free_tree(root);
780 cYAML_build_error(rc, seq_no, SHOW_CMD, "net", err_str, err_rc);
785 int lustre_lnet_enable_routing(int enable, int seq_no, struct cYAML **err_rc)
787 struct lnet_ioctl_config_data data;
788 int rc = LUSTRE_CFG_RC_NO_ERR;
789 char err_str[LNET_MAX_STR_LEN];
791 snprintf(err_str, sizeof(err_str), "\"success\"");
793 LIBCFS_IOC_INIT_V2(data, cfg_hdr);
794 data.cfg_config_u.cfg_buffers.buf_enable = (enable) ? 1 : 0;
796 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_CONFIG_RTR, &data);
801 "\"cannot %s routing %s\"",
802 (enable) ? "enable" : "disable", strerror(errno));
807 cYAML_build_error(rc, seq_no,
808 (enable) ? ADD_CMD : DEL_CMD,
809 "routing", err_str, err_rc);
814 int lustre_lnet_config_buffers(int tiny, int small, int large, int seq_no,
815 struct cYAML **err_rc)
817 struct lnet_ioctl_config_data data;
818 int rc = LUSTRE_CFG_RC_NO_ERR;
819 char err_str[LNET_MAX_STR_LEN];
821 snprintf(err_str, sizeof(err_str), "\"success\"");
823 /* -1 indicates to ignore changes to this field */
824 if (tiny < -1 || small < -1 || large < -1) {
827 "\"tiny, small and large must be >= 0\"");
828 rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
832 LIBCFS_IOC_INIT_V2(data, cfg_hdr);
833 data.cfg_config_u.cfg_buffers.buf_tiny = tiny;
834 data.cfg_config_u.cfg_buffers.buf_small = small;
835 data.cfg_config_u.cfg_buffers.buf_large = large;
837 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_ADD_BUF, &data);
842 "\"cannot configure buffers: %s\"", strerror(errno));
847 cYAML_build_error(rc, seq_no, ADD_CMD, "buf", err_str, err_rc);
852 int lustre_lnet_show_routing(int seq_no, struct cYAML **show_rc,
853 struct cYAML **err_rc)
855 struct lnet_ioctl_config_data *data;
856 struct lnet_ioctl_pool_cfg *pool_cfg = NULL;
857 int rc = LUSTRE_CFG_RC_OUT_OF_MEM;
860 char *pools[LNET_NRBPOOLS] = {"tiny", "small", "large"};
861 int buf_count[LNET_NRBPOOLS] = {0};
862 struct cYAML *root = NULL, *pools_node = NULL,
863 *type_node = NULL, *item = NULL, *cpt = NULL,
864 *first_seq = NULL, *buffers = NULL;
866 char err_str[LNET_MAX_STR_LEN];
867 char node_name[LNET_MAX_STR_LEN];
870 snprintf(err_str, sizeof(err_str), "\"out of memory\"");
872 buf = calloc(1, sizeof(*data) + sizeof(*pool_cfg));
876 data = (struct lnet_ioctl_config_data *)buf;
878 root = cYAML_create_object(NULL, NULL);
882 pools_node = cYAML_create_seq(root, "routing");
883 if (pools_node == NULL)
887 LIBCFS_IOC_INIT_V2(*data, cfg_hdr);
888 data->cfg_hdr.ioc_len = sizeof(struct lnet_ioctl_config_data) +
889 sizeof(struct lnet_ioctl_pool_cfg);
892 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_BUF, data);
900 pool_cfg = (struct lnet_ioctl_pool_cfg *)data->cfg_bulk;
902 snprintf(node_name, sizeof(node_name), "cpt[%d]", i);
903 item = cYAML_create_seq_item(pools_node);
907 if (first_seq == NULL)
910 cpt = cYAML_create_object(item, node_name);
914 /* create the tree and print */
915 for (j = 0; j < LNET_NRBPOOLS; j++) {
916 type_node = cYAML_create_object(cpt, pools[j]);
917 if (type_node == NULL)
919 if (cYAML_create_number(type_node, "npages",
920 pool_cfg->pl_pools[j].pl_npages)
923 if (cYAML_create_number(type_node, "nbuffers",
924 pool_cfg->pl_pools[j].
925 pl_nbuffers) == NULL)
927 if (cYAML_create_number(type_node, "credits",
928 pool_cfg->pl_pools[j].
931 if (cYAML_create_number(type_node, "mincredits",
932 pool_cfg->pl_pools[j].
933 pl_mincredits) == NULL)
935 /* keep track of the total count for each of the
936 * tiny, small and large buffers */
937 buf_count[j] += pool_cfg->pl_pools[j].pl_nbuffers;
941 if (pool_cfg != NULL) {
942 item = cYAML_create_seq_item(pools_node);
946 if (cYAML_create_number(item, "enable", pool_cfg->pl_routing) ==
951 /* create a buffers entry in the show. This is necessary so that
952 * if the YAML output is used to configure a node, the buffer
953 * configuration takes hold */
954 buffers = cYAML_create_object(root, "buffers");
958 for (i = 0; i < LNET_NRBPOOLS; i++) {
959 if (cYAML_create_number(buffers, pools[i], buf_count[i]) == NULL)
964 cYAML_print_tree(root);
966 if (l_errno != ENOENT) {
969 "\"cannot get routing information: %s\"",
974 rc = LUSTRE_CFG_RC_NO_ERR;
976 snprintf(err_str, sizeof(err_str), "\"success\"");
977 rc = LUSTRE_CFG_RC_NO_ERR;
981 if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR || !exist) {
982 cYAML_free_tree(root);
983 } else if (show_rc != NULL && *show_rc != NULL) {
984 struct cYAML *routing_node;
985 /* there should exist only one routing block and one
986 * buffers block. If there already exists a previous one
987 * then don't add another */
988 routing_node = cYAML_get_object_item(*show_rc, "routing");
989 if (routing_node == NULL) {
990 cYAML_insert_sibling((*show_rc)->cy_child,
994 cYAML_free_tree(root);
1000 cYAML_build_error(rc, seq_no, SHOW_CMD, "routing", err_str, err_rc);
1005 int lustre_lnet_show_peer_credits(int seq_no, struct cYAML **show_rc,
1006 struct cYAML **err_rc)
1008 struct lnet_ioctl_peer peer_info;
1009 int rc = LUSTRE_CFG_RC_OUT_OF_MEM, ncpt = 0, i = 0, j = 0;
1011 struct cYAML *root = NULL, *peer = NULL, *first_seq = NULL,
1013 char err_str[LNET_MAX_STR_LEN];
1014 bool ncpt_set = false;
1016 snprintf(err_str, sizeof(err_str),
1017 "\"out of memory\"");
1019 /* create struct cYAML root object */
1020 root = cYAML_create_object(NULL, NULL);
1024 peer_root = cYAML_create_seq(root, "peer");
1025 if (peer_root == NULL)
1030 LIBCFS_IOC_INIT_V2(peer_info, pr_hdr);
1031 peer_info.pr_count = i;
1032 peer_info.pr_lnd_u.pr_peer_credits.cr_ncpt = j;
1033 rc = l_ioctl(LNET_DEV_ID,
1034 IOC_LIBCFS_GET_PEER_INFO, &peer_info);
1040 if (ncpt_set != 0) {
1041 ncpt = peer_info.pr_lnd_u.pr_peer_credits.
1046 peer = cYAML_create_seq_item(peer_root);
1050 if (first_seq == NULL)
1053 if (cYAML_create_string(peer, "nid",
1055 (peer_info.pr_nid)) == NULL)
1058 if (cYAML_create_string(peer, "state",
1065 if (cYAML_create_number(peer, "refcount",
1068 cr_refcount) == NULL)
1071 if (cYAML_create_number(peer, "max_ni_tx_credits",
1074 cr_ni_peer_tx_credits)
1078 if (cYAML_create_number(peer, "available_tx_credits",
1085 if (cYAML_create_number(peer, "available_rtr_credits",
1088 cr_peer_rtr_credits)
1092 if (cYAML_create_number(peer, "min_rtr_credits",
1095 cr_peer_min_rtr_credits)
1099 if (cYAML_create_number(peer, "tx_q_num_of_buf",
1107 if (l_errno != ENOENT) {
1110 "\"cannot get peer information: %s\"",
1119 /* print output iff show_rc is not provided */
1120 if (show_rc == NULL)
1121 cYAML_print_tree(root);
1123 snprintf(err_str, sizeof(err_str), "\"success\"");
1124 rc = LUSTRE_CFG_RC_NO_ERR;
1127 if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR) {
1128 cYAML_free_tree(root);
1129 } else if (show_rc != NULL && *show_rc != NULL) {
1130 struct cYAML *show_node;
1131 /* find the peer node, if one doesn't exist then
1132 * insert one. Otherwise add to the one there
1134 show_node = cYAML_get_object_item(*show_rc,
1136 if (show_node != NULL && cYAML_is_sequence(show_node)) {
1137 cYAML_insert_child(show_node, first_seq);
1140 } else if (show_node == NULL) {
1141 cYAML_insert_sibling((*show_rc)->cy_child,
1145 cYAML_free_tree(root);
1151 cYAML_build_error(rc, seq_no, SHOW_CMD, "peer_credits", err_str,
1157 int lustre_lnet_show_stats(int seq_no, struct cYAML **show_rc,
1158 struct cYAML **err_rc)
1160 struct lnet_ioctl_lnet_stats data;
1161 int rc = LUSTRE_CFG_RC_OUT_OF_MEM;
1163 char err_str[LNET_MAX_STR_LEN];
1164 struct cYAML *root = NULL, *stats = NULL;
1166 snprintf(err_str, sizeof(err_str), "\"out of memory\"");
1168 LIBCFS_IOC_INIT_V2(data, st_hdr);
1170 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_LNET_STATS, &data);
1175 "\"cannot get lnet statistics: %s\"",
1181 root = cYAML_create_object(NULL, NULL);
1185 stats = cYAML_create_object(root, "statistics");
1189 if (cYAML_create_number(stats, "msgs_alloc",
1190 data.st_cntrs.msgs_alloc) == NULL)
1193 if (cYAML_create_number(stats, "msgs_max",
1194 data.st_cntrs.msgs_max) == NULL)
1197 if (cYAML_create_number(stats, "errors",
1198 data.st_cntrs.errors) == NULL)
1201 if (cYAML_create_number(stats, "send_count",
1202 data.st_cntrs.send_count) == NULL)
1205 if (cYAML_create_number(stats, "recv_count",
1206 data.st_cntrs.recv_count) == NULL)
1209 if (cYAML_create_number(stats, "route_count",
1210 data.st_cntrs.route_count) == NULL)
1213 if (cYAML_create_number(stats, "drop_count",
1214 data.st_cntrs.drop_count) == NULL)
1217 if (cYAML_create_number(stats, "send_length",
1218 data.st_cntrs.send_length) == NULL)
1221 if (cYAML_create_number(stats, "recv_length",
1222 data.st_cntrs.recv_length) == NULL)
1225 if (cYAML_create_number(stats, "route_length",
1226 data.st_cntrs.route_length) == NULL)
1229 if (cYAML_create_number(stats, "drop_length",
1230 data.st_cntrs.drop_length) == NULL)
1233 if (show_rc == NULL)
1234 cYAML_print_tree(root);
1236 snprintf(err_str, sizeof(err_str), "\"success\"");
1238 if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR) {
1239 cYAML_free_tree(root);
1240 } else if (show_rc != NULL && *show_rc != NULL) {
1241 cYAML_insert_sibling((*show_rc)->cy_child,
1248 cYAML_build_error(rc, seq_no, SHOW_CMD, "statistics", err_str, err_rc);
1253 typedef int (*cmd_handler_t)(struct cYAML *tree,
1254 struct cYAML **show_rc,
1255 struct cYAML **err_rc);
1257 static int handle_yaml_config_route(struct cYAML *tree, struct cYAML **show_rc,
1258 struct cYAML **err_rc)
1260 struct cYAML *net, *gw, *hop, *prio, *seq_no;
1262 net = cYAML_get_object_item(tree, "net");
1263 gw = cYAML_get_object_item(tree, "gateway");
1264 hop = cYAML_get_object_item(tree, "hop");
1265 prio = cYAML_get_object_item(tree, "priority");
1266 seq_no = cYAML_get_object_item(tree, "seq_no");
1268 return lustre_lnet_config_route((net) ? net->cy_valuestring : NULL,
1269 (gw) ? gw->cy_valuestring : NULL,
1270 (hop) ? hop->cy_valueint : -1,
1271 (prio) ? prio->cy_valueint : -1,
1272 (seq_no) ? seq_no->cy_valueint : -1,
1276 static int handle_yaml_config_net(struct cYAML *tree, struct cYAML **show_rc,
1277 struct cYAML **err_rc)
1279 struct cYAML *net, *intf, *tunables, *seq_no,
1280 *peer_to = NULL, *peer_buf_cr = NULL, *peer_cr = NULL,
1281 *credits = NULL, *ip2net = NULL, *smp = NULL, *child;
1282 struct lnet_ioctl_config_lnd_tunables *lnd_tunables_p = NULL;
1283 struct lnet_ioctl_config_lnd_tunables lnd_tunables;
1284 char devs[LNET_MAX_STR_LEN];
1286 int size = LNET_MAX_STR_LEN;
1288 bool intf_found = false;
1290 ip2net = cYAML_get_object_item(tree, "ip2net");
1291 net = cYAML_get_object_item(tree, "net");
1292 intf = cYAML_get_object_item(tree, "interfaces");
1294 /* grab all the interfaces */
1295 child = intf->cy_child;
1296 while (child != NULL && size > 0) {
1297 struct cYAML *lnd_params;
1299 if (child->cy_valuestring == NULL)
1303 num = snprintf(loc, size, ",%s",
1304 child->cy_valuestring);
1306 num = snprintf(loc, size, "%s",
1307 child->cy_valuestring);
1312 lnd_params = cYAML_get_object_item(intf,
1314 if (lnd_params != NULL) {
1315 const char *dev_name = child->cy_valuestring;
1316 lnd_tunables_p = &lnd_tunables;
1318 lustre_interface_parse(lnd_params, dev_name,
1322 child = child->cy_next;
1326 tunables = cYAML_get_object_item(tree, "tunables");
1327 if (tunables != NULL) {
1328 peer_to = cYAML_get_object_item(tunables, "peer_timeout");
1329 peer_cr = cYAML_get_object_item(tunables, "peer_credits");
1330 peer_buf_cr = cYAML_get_object_item(tunables,
1331 "peer_buffer_credits");
1332 credits = cYAML_get_object_item(tunables, "credits");
1333 smp = cYAML_get_object_item(tunables, "CPT");
1335 seq_no = cYAML_get_object_item(tree, "seq_no");
1337 return lustre_lnet_config_net((net) ? net->cy_valuestring : NULL,
1338 (intf_found) ? devs : NULL,
1339 (ip2net) ? ip2net->cy_valuestring : NULL,
1340 (peer_to) ? peer_to->cy_valueint : -1,
1341 (peer_cr) ? peer_cr->cy_valueint : -1,
1343 peer_buf_cr->cy_valueint : -1,
1344 (credits) ? credits->cy_valueint : -1,
1345 (smp) ? smp->cy_valuestring : NULL,
1346 (seq_no) ? seq_no->cy_valueint : -1,
1351 static int handle_yaml_config_buffers(struct cYAML *tree,
1352 struct cYAML **show_rc,
1353 struct cYAML **err_rc)
1356 struct cYAML *tiny, *small, *large, *seq_no;
1358 tiny = cYAML_get_object_item(tree, "tiny");
1359 small = cYAML_get_object_item(tree, "small");
1360 large = cYAML_get_object_item(tree, "large");
1361 seq_no = cYAML_get_object_item(tree, "seq_no");
1363 rc = lustre_lnet_config_buffers((tiny) ? tiny->cy_valueint : -1,
1364 (small) ? small->cy_valueint : -1,
1365 (large) ? large->cy_valueint : -1,
1366 (seq_no) ? seq_no->cy_valueint : -1,
1372 static int handle_yaml_config_routing(struct cYAML *tree,
1373 struct cYAML **show_rc,
1374 struct cYAML **err_rc)
1376 int rc = LUSTRE_CFG_RC_NO_ERR;
1377 struct cYAML *seq_no, *enable;
1379 seq_no = cYAML_get_object_item(tree, "seq_no");
1380 enable = cYAML_get_object_item(tree, "enable");
1383 rc = lustre_lnet_enable_routing(enable->cy_valueint,
1385 seq_no->cy_valueint : -1,
1392 static int handle_yaml_del_route(struct cYAML *tree, struct cYAML **show_rc,
1393 struct cYAML **err_rc)
1397 struct cYAML *seq_no;
1399 net = cYAML_get_object_item(tree, "net");
1400 gw = cYAML_get_object_item(tree, "gateway");
1401 seq_no = cYAML_get_object_item(tree, "seq_no");
1403 return lustre_lnet_del_route((net) ? net->cy_valuestring : NULL,
1404 (gw) ? gw->cy_valuestring : NULL,
1405 (seq_no) ? seq_no->cy_valueint : -1,
1409 static int handle_yaml_del_net(struct cYAML *tree, struct cYAML **show_rc,
1410 struct cYAML **err_rc)
1412 struct cYAML *net, *seq_no;
1414 net = cYAML_get_object_item(tree, "net");
1415 seq_no = cYAML_get_object_item(tree, "seq_no");
1417 return lustre_lnet_del_net((net) ? net->cy_valuestring : NULL,
1418 (seq_no) ? seq_no->cy_valueint : -1,
1422 static int handle_yaml_del_routing(struct cYAML *tree, struct cYAML **show_rc,
1423 struct cYAML **err_rc)
1425 struct cYAML *seq_no;
1427 seq_no = cYAML_get_object_item(tree, "seq_no");
1429 return lustre_lnet_enable_routing(0, (seq_no) ?
1430 seq_no->cy_valueint : -1,
1434 static int handle_yaml_show_route(struct cYAML *tree, struct cYAML **show_rc,
1435 struct cYAML **err_rc)
1441 struct cYAML *detail;
1442 struct cYAML *seq_no;
1444 net = cYAML_get_object_item(tree, "net");
1445 gw = cYAML_get_object_item(tree, "gateway");
1446 hop = cYAML_get_object_item(tree, "hop");
1447 prio = cYAML_get_object_item(tree, "priority");
1448 detail = cYAML_get_object_item(tree, "detail");
1449 seq_no = cYAML_get_object_item(tree, "seq_no");
1451 return lustre_lnet_show_route((net) ? net->cy_valuestring : NULL,
1452 (gw) ? gw->cy_valuestring : NULL,
1453 (hop) ? hop->cy_valueint : -1,
1454 (prio) ? prio->cy_valueint : -1,
1455 (detail) ? detail->cy_valueint : 0,
1456 (seq_no) ? seq_no->cy_valueint : -1,
1461 static int handle_yaml_show_net(struct cYAML *tree, struct cYAML **show_rc,
1462 struct cYAML **err_rc)
1464 struct cYAML *net, *detail, *seq_no;
1466 net = cYAML_get_object_item(tree, "net");
1467 detail = cYAML_get_object_item(tree, "detail");
1468 seq_no = cYAML_get_object_item(tree, "seq_no");
1470 return lustre_lnet_show_net((net) ? net->cy_valuestring : NULL,
1471 (detail) ? detail->cy_valueint : 0,
1472 (seq_no) ? seq_no->cy_valueint : -1,
1477 static int handle_yaml_show_routing(struct cYAML *tree, struct cYAML **show_rc,
1478 struct cYAML **err_rc)
1480 struct cYAML *seq_no;
1482 seq_no = cYAML_get_object_item(tree, "seq_no");
1484 return lustre_lnet_show_routing((seq_no) ? seq_no->cy_valueint : -1,
1488 static int handle_yaml_show_credits(struct cYAML *tree, struct cYAML **show_rc,
1489 struct cYAML **err_rc)
1491 struct cYAML *seq_no;
1493 seq_no = cYAML_get_object_item(tree, "seq_no");
1495 return lustre_lnet_show_peer_credits((seq_no) ?
1496 seq_no->cy_valueint : -1,
1500 static int handle_yaml_show_stats(struct cYAML *tree, struct cYAML **show_rc,
1501 struct cYAML **err_rc)
1503 struct cYAML *seq_no;
1505 seq_no = cYAML_get_object_item(tree, "seq_no");
1507 return lustre_lnet_show_stats((seq_no) ? seq_no->cy_valueint : -1,
1511 struct lookup_cmd_hdlr_tbl {
1516 static struct lookup_cmd_hdlr_tbl lookup_config_tbl[] = {
1517 {"route", handle_yaml_config_route},
1518 {"net", handle_yaml_config_net},
1519 {"routing", handle_yaml_config_routing},
1520 {"buffers", handle_yaml_config_buffers},
1524 static struct lookup_cmd_hdlr_tbl lookup_del_tbl[] = {
1525 {"route", handle_yaml_del_route},
1526 {"net", handle_yaml_del_net},
1527 {"routing", handle_yaml_del_routing},
1531 static struct lookup_cmd_hdlr_tbl lookup_show_tbl[] = {
1532 {"route", handle_yaml_show_route},
1533 {"net", handle_yaml_show_net},
1534 {"buffers", handle_yaml_show_routing},
1535 {"routing", handle_yaml_show_routing},
1536 {"credits", handle_yaml_show_credits},
1537 {"statistics", handle_yaml_show_stats},
1541 static cmd_handler_t lookup_fn(char *key,
1542 struct lookup_cmd_hdlr_tbl *tbl)
1548 for (i = 0; tbl[i].name != NULL; i++) {
1549 if (strncmp(key, tbl[i].name, strlen(tbl[i].name)) == 0)
1556 static int lustre_yaml_cb_helper(char *f, struct lookup_cmd_hdlr_tbl *table,
1557 struct cYAML **show_rc, struct cYAML **err_rc)
1559 struct cYAML *tree, *item = NULL, *head, *child;
1561 char err_str[LNET_MAX_STR_LEN];
1562 int rc = LUSTRE_CFG_RC_NO_ERR, return_rc = LUSTRE_CFG_RC_NO_ERR;
1564 tree = cYAML_build_tree(f, NULL, 0, err_rc);
1566 return LUSTRE_CFG_RC_BAD_PARAM;
1568 child = tree->cy_child;
1569 while (child != NULL) {
1570 cb = lookup_fn(child->cy_string, table);
1572 snprintf(err_str, sizeof(err_str),
1573 "\"call back for '%s' not found\"",
1575 cYAML_build_error(LUSTRE_CFG_RC_BAD_PARAM, -1,
1576 "yaml", "helper", err_str, err_rc);
1580 if (cYAML_is_sequence(child)) {
1581 while ((head = cYAML_get_next_seq_item(child, &item))
1583 rc = cb(head, show_rc, err_rc);
1584 if (rc != LUSTRE_CFG_RC_NO_ERR)
1588 rc = cb(child, show_rc, err_rc);
1589 if (rc != LUSTRE_CFG_RC_NO_ERR)
1593 child = child->cy_next;
1597 cYAML_free_tree(tree);
1602 int lustre_yaml_config(char *f, struct cYAML **err_rc)
1604 return lustre_yaml_cb_helper(f, lookup_config_tbl,
1608 int lustre_yaml_del(char *f, struct cYAML **err_rc)
1610 return lustre_yaml_cb_helper(f, lookup_del_tbl,
1614 int lustre_yaml_show(char *f, struct cYAML **show_rc, struct cYAML **err_rc)
1616 return lustre_yaml_cb_helper(f, lookup_show_tbl,