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, 2016, 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
43 #include <sys/ioctl.h>
45 #include <libcfs/util/ioctl.h>
46 #include <lnet/lnetctl.h>
47 #include <lnet/socklnd.h>
49 #include <lnet/lnet.h>
50 #include <libcfs/libcfs_string.h>
51 #include <sys/types.h>
53 #include "liblnetconfig.h"
56 #define CONFIG_CMD "configure"
57 #define UNCONFIG_CMD "unconfigure"
60 #define SHOW_CMD "show"
64 * lustre_lnet_ip_range_descr
65 * Describes an IP range.
66 * Each octect is an expression
68 struct lustre_lnet_ip_range_descr {
69 struct list_head ipr_entry;
70 struct list_head ipr_expr;
75 * Describes an ip2nets rule. This can be on a list of rules.
77 struct lustre_lnet_ip2nets {
78 struct lnet_dlc_network_descr ip2nets_net;
79 struct list_head ip2nets_ip_ranges;
83 * lustre_lnet_add_ip_range
85 * given a string of the format:
86 * <expr.expr.expr.expr> parse each expr into
87 * a lustre_lnet_ip_range_descr structure and insert on the list.
89 * This function is called from
90 * YAML on each ip-range.
91 * As a result of lnetctl command
92 * When building a NID or P2P selection rules
94 int lustre_lnet_add_ip_range(struct list_head *list, char *str_ip_range)
96 struct lustre_lnet_ip_range_descr *ip_range;
99 ip_range = calloc(1, sizeof(*ip_range));
100 if (ip_range == NULL)
101 return LUSTRE_CFG_RC_OUT_OF_MEM;
103 INIT_LIST_HEAD(&ip_range->ipr_entry);
104 INIT_LIST_HEAD(&ip_range->ipr_expr);
106 rc = cfs_ip_addr_parse(str_ip_range, strlen(str_ip_range),
107 &ip_range->ipr_expr);
109 return LUSTRE_CFG_RC_BAD_PARAM;
111 list_add_tail(&ip_range->ipr_entry, list);
113 return LUSTRE_CFG_RC_NO_ERR;
116 int lustre_lnet_add_intf_descr(struct list_head *list, char *intf, int len)
118 char *open_sq_bracket = NULL, *close_sq_bracket = NULL,
120 struct lnet_dlc_intf_descr *intf_descr = NULL;
122 char intf_string[LNET_MAX_STR_LEN];
124 if (len >= LNET_MAX_STR_LEN)
125 return LUSTRE_CFG_RC_BAD_PARAM;
127 strncpy(intf_string, intf, len);
128 intf_string[len] = '\0';
130 intf_descr = calloc(1, sizeof(*intf_descr));
131 if (intf_descr == NULL)
132 return LUSTRE_CFG_RC_OUT_OF_MEM;
134 INIT_LIST_HEAD(&intf_descr->intf_on_network);
136 intf_name = intf_string;
137 open_sq_bracket = strchr(intf_string, '[');
138 if (open_sq_bracket != NULL) {
139 close_sq_bracket = strchr(intf_string, ']');
140 if (close_sq_bracket == NULL) {
142 return LUSTRE_CFG_RC_BAD_PARAM;
144 rc = cfs_expr_list_parse(open_sq_bracket,
145 strlen(open_sq_bracket), 0, UINT_MAX,
146 &intf_descr->cpt_expr);
149 return LUSTRE_CFG_RC_BAD_PARAM;
151 strncpy(intf_descr->intf_name, intf_name,
152 open_sq_bracket - intf_name);
153 intf_descr->intf_name[open_sq_bracket - intf_name] = '\0';
155 strcpy(intf_descr->intf_name, intf_name);
156 intf_descr->cpt_expr = NULL;
159 list_add_tail(&intf_descr->intf_on_network, list);
161 return LUSTRE_CFG_RC_NO_ERR;
164 void lustre_lnet_init_nw_descr(struct lnet_dlc_network_descr *nw_descr)
166 if (nw_descr != NULL) {
167 INIT_LIST_HEAD(&nw_descr->network_on_rule);
168 INIT_LIST_HEAD(&nw_descr->nw_intflist);
174 * <intf>[<expr>], <intf>[<expr>],..
176 int lustre_lnet_parse_interfaces(char *intf_str,
177 struct lnet_dlc_network_descr *nw_descr)
182 char *cur = intf_str, *next = NULL;
183 char *end = intf_str + strlen(intf_str);
185 struct lnet_dlc_intf_descr *intf_descr, *tmp;
187 if (nw_descr == NULL)
188 return LUSTRE_CFG_RC_BAD_PARAM;
191 open_square = strchr(cur, '[');
192 if (open_square != NULL) {
193 close_square = strchr(cur, ']');
194 if (close_square == NULL) {
195 rc = LUSTRE_CFG_RC_BAD_PARAM;
199 comma = strchr(cur, ',');
200 if (comma != NULL && comma > close_square) {
202 len = next - close_square;
208 comma = strchr(cur, ',');
218 rc = lustre_lnet_add_intf_descr(&nw_descr->nw_intflist, cur, len);
219 if (rc != LUSTRE_CFG_RC_NO_ERR)
225 return LUSTRE_CFG_RC_NO_ERR;
228 list_for_each_entry_safe(intf_descr, tmp, &nw_descr->nw_intflist,
230 if (intf_descr->cpt_expr != NULL)
231 cfs_expr_list_free(intf_descr->cpt_expr);
238 int lustre_lnet_config_lib_init(void)
240 return register_ioc_dev(LNET_DEV_ID, LNET_DEV_PATH,
241 LNET_DEV_MAJOR, LNET_DEV_MINOR);
244 void lustre_lnet_config_lib_uninit(void)
246 unregister_ioc_dev(LNET_DEV_ID);
249 int lustre_lnet_config_ni_system(bool up, bool load_ni_from_mod,
250 int seq_no, struct cYAML **err_rc)
252 struct libcfs_ioctl_data data;
255 char err_str[LNET_MAX_STR_LEN];
257 snprintf(err_str, sizeof(err_str), "\"Success\"");
259 LIBCFS_IOC_INIT(data);
261 /* Reverse logic is used here in order not to change
262 * the lctl utility */
263 data.ioc_flags = load_ni_from_mod ? 0 : 1;
265 opc = up ? IOC_LIBCFS_CONFIGURE : IOC_LIBCFS_UNCONFIGURE;
267 rc = l_ioctl(LNET_DEV_ID, opc, &data);
271 "\"LNet %s error: %s\"", (up) ? "configure" :
272 "unconfigure", strerror(errno));
276 cYAML_build_error(rc, seq_no, (up) ? CONFIG_CMD : UNCONFIG_CMD,
277 "lnet", err_str, err_rc);
282 static lnet_nid_t *allocate_create_nid_array(char **nids, char *err_str)
284 lnet_nid_t *array = NULL;
288 snprintf(err_str, LNET_MAX_STR_LEN, "no NIDs to add");
292 /* count the size of the array */
293 while (nids[idx] != NULL)
296 array = calloc(sizeof(*array) * idx + 1, 1);
298 snprintf(err_str, LNET_MAX_STR_LEN, "out of memory");
303 while (nids[idx] != NULL) {
304 array[idx] = libcfs_str2nid(nids[idx]);
305 if (array[idx] == LNET_NID_ANY) {
307 snprintf(err_str, LNET_MAX_STR_LEN,
315 /* identify last entry */
316 array[idx] = LNET_NID_ANY;
321 static int dispatch_peer_ni_cmd(lnet_nid_t knid, lnet_nid_t nid, __u32 cmd,
322 struct lnet_ioctl_peer_cfg *data,
323 char *err_str, char *cmd_str)
327 data->prcfg_key_nid = knid;
328 data->prcfg_cfg_nid = nid;
330 rc = l_ioctl(LNET_DEV_ID, cmd, data);
335 "\"cannot %s peer ni: %s\"",
336 (cmd_str) ? cmd_str : "add", strerror(errno));
342 int lustre_lnet_config_peer_nid(char *knid, char **nid, bool mr, int seq_no,
343 struct cYAML **err_rc)
345 struct lnet_ioctl_peer_cfg data;
346 lnet_nid_t key_nid = LNET_NID_ANY;
347 int rc = LUSTRE_CFG_RC_NO_ERR;
349 char err_str[LNET_MAX_STR_LEN] = {0};
350 lnet_nid_t *nids = allocate_create_nid_array(nid, err_str);
353 key_nid = libcfs_str2nid(knid);
354 if (key_nid == LNET_NID_ANY) {
355 snprintf(err_str, sizeof(err_str),
358 rc = LUSTRE_CFG_RC_MISSING_PARAM;
361 } else if (nids[0] == LNET_NID_ANY) {
362 snprintf(err_str, sizeof(err_str),
363 "no NIDs provided for configuration");
364 rc = LUSTRE_CFG_RC_MISSING_PARAM;
367 key_nid = LNET_NID_ANY;
370 snprintf(err_str, sizeof(err_str), "\"Success\"");
372 LIBCFS_IOC_INIT_V2(data, prcfg_hdr);
374 if (nids[0] == LNET_NID_ANY) {
375 rc = dispatch_peer_ni_cmd(LNET_NID_ANY, key_nid,
376 IOC_LIBCFS_ADD_PEER_NI,
377 &data, err_str, "add");
381 while (nids[idx] != LNET_NID_ANY) {
383 * If key_nid is not provided then the first nid in the
384 * list becomes the key_nid. First time round the loop use
385 * LNET_NID_ANY for the first parameter, then use nid[0]
386 * as the key nid after wards
388 rc = dispatch_peer_ni_cmd(key_nid, nids[idx],
389 IOC_LIBCFS_ADD_PEER_NI, &data,
395 if (idx == 0 && key_nid == LNET_NID_ANY)
404 cYAML_build_error(rc, seq_no, ADD_CMD, "peer_ni", err_str, err_rc);
408 int lustre_lnet_del_peer_nid(char *knid, char **nid, int seq_no,
409 struct cYAML **err_rc)
411 struct lnet_ioctl_peer_cfg data;
413 int rc = LUSTRE_CFG_RC_NO_ERR;
415 char err_str[LNET_MAX_STR_LEN] = {0};
416 lnet_nid_t *nids = allocate_create_nid_array(nid, err_str);
419 snprintf(err_str, sizeof(err_str),
420 "\"Primary nid is not provided\"");
421 rc = LUSTRE_CFG_RC_MISSING_PARAM;
424 key_nid = libcfs_str2nid(knid);
425 if (key_nid == LNET_NID_ANY) {
426 rc = LUSTRE_CFG_RC_BAD_PARAM;
427 snprintf(err_str, sizeof(err_str),
434 snprintf(err_str, sizeof(err_str), "\"Success\"");
436 LIBCFS_IOC_INIT_V2(data, prcfg_hdr);
437 if (nids[0] == LNET_NID_ANY) {
438 rc = dispatch_peer_ni_cmd(key_nid, LNET_NID_ANY,
439 IOC_LIBCFS_DEL_PEER_NI,
440 &data, err_str, "del");
444 while (nids[idx] != LNET_NID_ANY) {
445 rc = dispatch_peer_ni_cmd(key_nid, nids[idx],
446 IOC_LIBCFS_DEL_PEER_NI, &data,
458 cYAML_build_error(rc, seq_no, DEL_CMD, "peer_ni", err_str, err_rc);
462 int lustre_lnet_config_route(char *nw, char *gw, int hops, int prio,
463 int seq_no, struct cYAML **err_rc)
465 struct lnet_ioctl_config_data data;
466 lnet_nid_t gateway_nid;
467 int rc = LUSTRE_CFG_RC_NO_ERR;
468 __u32 net = LNET_NIDNET(LNET_NID_ANY);
469 char err_str[LNET_MAX_STR_LEN];
471 snprintf(err_str, sizeof(err_str), "\"Success\"");
473 if (nw == NULL || gw == NULL) {
476 "\"missing mandatory parameter(s): '%s'\"",
477 (nw == NULL && gw == NULL) ? "network, gateway" :
478 (nw == NULL) ? "network" : "gateway");
479 rc = LUSTRE_CFG_RC_MISSING_PARAM;
483 net = libcfs_str2net(nw);
484 if (net == LNET_NIDNET(LNET_NID_ANY)) {
487 "\"cannot parse net %s\"", nw);
488 rc = LUSTRE_CFG_RC_BAD_PARAM;
492 if (LNET_NETTYP(net) == CIBLND ||
493 LNET_NETTYP(net) == OPENIBLND ||
494 LNET_NETTYP(net) == IIBLND ||
495 LNET_NETTYP(net) == VIBLND) {
498 "\"obselete LNet type '%s'\"", libcfs_lnd2str(net));
499 rc = LUSTRE_CFG_RC_BAD_PARAM;
503 gateway_nid = libcfs_str2nid(gw);
504 if (gateway_nid == LNET_NID_ANY) {
507 "\"cannot parse gateway NID '%s'\"", gw);
508 rc = LUSTRE_CFG_RC_BAD_PARAM;
513 /* hops is undefined */
514 hops = LNET_UNDEFINED_HOPS;
515 } else if (hops < 1 || hops > 255) {
518 "\"invalid hop count %d, must be between 1 and 255\"",
520 rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
526 } else if (prio < 0) {
529 "\"invalid priority %d, must be greater than 0\"",
531 rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
535 LIBCFS_IOC_INIT_V2(data, cfg_hdr);
537 data.cfg_config_u.cfg_route.rtr_hop = hops;
538 data.cfg_config_u.cfg_route.rtr_priority = prio;
539 data.cfg_nid = gateway_nid;
541 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_ADD_ROUTE, &data);
546 "\"cannot add route: %s\"", strerror(errno));
551 cYAML_build_error(rc, seq_no, ADD_CMD, "route", err_str, err_rc);
556 int lustre_lnet_del_route(char *nw, char *gw,
557 int seq_no, struct cYAML **err_rc)
559 struct lnet_ioctl_config_data data;
560 lnet_nid_t gateway_nid;
561 int rc = LUSTRE_CFG_RC_NO_ERR;
562 __u32 net = LNET_NIDNET(LNET_NID_ANY);
563 char err_str[LNET_MAX_STR_LEN];
565 snprintf(err_str, sizeof(err_str), "\"Success\"");
567 if (nw == NULL || gw == NULL) {
570 "\"missing mandatory parameter(s): '%s'\"",
571 (nw == NULL && gw == NULL) ? "network, gateway" :
572 (nw == NULL) ? "network" : "gateway");
573 rc = LUSTRE_CFG_RC_MISSING_PARAM;
577 net = libcfs_str2net(nw);
578 if (net == LNET_NIDNET(LNET_NID_ANY)) {
581 "\"cannot parse net '%s'\"", nw);
582 rc = LUSTRE_CFG_RC_BAD_PARAM;
586 if (LNET_NETTYP(net) == CIBLND ||
587 LNET_NETTYP(net) == OPENIBLND ||
588 LNET_NETTYP(net) == IIBLND ||
589 LNET_NETTYP(net) == VIBLND) {
592 "\"obselete LNet type '%s'\"", libcfs_lnd2str(net));
593 rc = LUSTRE_CFG_RC_BAD_PARAM;
597 gateway_nid = libcfs_str2nid(gw);
598 if (gateway_nid == LNET_NID_ANY) {
601 "\"cannot parse gateway NID '%s'\"", gw);
602 rc = LUSTRE_CFG_RC_BAD_PARAM;
606 LIBCFS_IOC_INIT_V2(data, cfg_hdr);
608 data.cfg_nid = gateway_nid;
610 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_DEL_ROUTE, &data);
615 "\"cannot delete route: %s\"", strerror(errno));
620 cYAML_build_error(rc, seq_no, DEL_CMD, "route", err_str, err_rc);
625 int lustre_lnet_show_route(char *nw, char *gw, int hops, int prio, int detail,
626 int seq_no, struct cYAML **show_rc,
627 struct cYAML **err_rc)
629 struct lnet_ioctl_config_data data;
630 lnet_nid_t gateway_nid;
631 int rc = LUSTRE_CFG_RC_OUT_OF_MEM;
633 __u32 net = LNET_NIDNET(LNET_NID_ANY);
635 struct cYAML *root = NULL, *route = NULL, *item = NULL;
636 struct cYAML *first_seq = NULL;
637 char err_str[LNET_MAX_STR_LEN];
640 snprintf(err_str, sizeof(err_str),
641 "\"out of memory\"");
644 net = libcfs_str2net(nw);
645 if (net == LNET_NIDNET(LNET_NID_ANY)) {
648 "\"cannot parse net '%s'\"", nw);
649 rc = LUSTRE_CFG_RC_BAD_PARAM;
653 if (LNET_NETTYP(net) == CIBLND ||
654 LNET_NETTYP(net) == OPENIBLND ||
655 LNET_NETTYP(net) == IIBLND ||
656 LNET_NETTYP(net) == VIBLND) {
659 "\"obsolete LNet type '%s'\"",
660 libcfs_lnd2str(net));
661 rc = LUSTRE_CFG_RC_BAD_PARAM;
665 /* show all routes without filtering on net */
666 net = LNET_NIDNET(LNET_NID_ANY);
670 gateway_nid = libcfs_str2nid(gw);
671 if (gateway_nid == LNET_NID_ANY) {
674 "\"cannot parse gateway NID '%s'\"", gw);
675 rc = LUSTRE_CFG_RC_BAD_PARAM;
679 /* show all routes with out filtering on gateway */
680 gateway_nid = LNET_NID_ANY;
682 if ((hops < 1 && hops != -1) || hops > 255) {
685 "\"invalid hop count %d, must be between 0 and 256\"",
687 rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
691 /* create struct cYAML root object */
692 root = cYAML_create_object(NULL, NULL);
696 route = cYAML_create_seq(root, "route");
701 LIBCFS_IOC_INIT_V2(data, cfg_hdr);
704 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_ROUTE, &data);
710 /* filter on provided data */
711 if (net != LNET_NIDNET(LNET_NID_ANY) &&
715 if (gateway_nid != LNET_NID_ANY &&
716 gateway_nid != data.cfg_nid)
720 hops != data.cfg_config_u.cfg_route.rtr_hop)
724 prio != data.cfg_config_u.cfg_route.rtr_priority)
727 /* default rc to -1 incase we hit the goto */
731 item = cYAML_create_seq_item(route);
735 if (first_seq == NULL)
738 if (cYAML_create_string(item, "net",
739 libcfs_net2str(data.cfg_net)) == NULL)
742 if (cYAML_create_string(item, "gateway",
743 libcfs_nid2str(data.cfg_nid)) == NULL)
747 if (cYAML_create_number(item, "hop",
748 data.cfg_config_u.cfg_route.
753 if (cYAML_create_number(item, "priority",
755 cfg_route.rtr_priority) == NULL)
758 if (cYAML_create_string(item, "state",
759 data.cfg_config_u.cfg_route.
761 "up" : "down") == NULL)
766 /* print output iff show_rc is not provided */
768 cYAML_print_tree(root);
770 if (l_errno != ENOENT) {
773 "\"cannot get routes: %s\"",
778 rc = LUSTRE_CFG_RC_NO_ERR;
780 snprintf(err_str, sizeof(err_str), "\"success\"");
782 if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR || !exist) {
783 cYAML_free_tree(root);
784 } else if (show_rc != NULL && *show_rc != NULL) {
785 struct cYAML *show_node;
786 /* find the route node, if one doesn't exist then
787 * insert one. Otherwise add to the one there
789 show_node = cYAML_get_object_item(*show_rc, "route");
790 if (show_node != NULL && cYAML_is_sequence(show_node)) {
791 cYAML_insert_child(show_node, first_seq);
794 } else if (show_node == NULL) {
795 cYAML_insert_sibling((*show_rc)->cy_child,
799 cYAML_free_tree(root);
805 cYAML_build_error(rc, seq_no, SHOW_CMD, "route", err_str, err_rc);
810 static int socket_intf_query(int request, char *intf,
816 if (strlen(intf) >= IFNAMSIZ || ifr == NULL)
817 return LUSTRE_CFG_RC_BAD_PARAM;
819 sockfd = socket(AF_INET, SOCK_DGRAM, 0);
821 return LUSTRE_CFG_RC_BAD_PARAM;
823 strcpy(ifr->ifr_name, intf);
824 rc = ioctl(sockfd, request, ifr);
826 return LUSTRE_CFG_RC_BAD_PARAM;
832 * for each interface in the array of interfaces find the IP address of
833 * that interface, create its nid and add it to an array of NIDs.
834 * Stop if any of the interfaces is down
836 static int lustre_lnet_intf2nids(struct lnet_dlc_network_descr *nw,
837 lnet_nid_t **nids, __u32 *nnids)
839 int i = 0, count = 0, rc;
842 struct lnet_dlc_intf_descr *intf;
844 if (nw == NULL || nids == NULL)
845 return LUSTRE_CFG_RC_BAD_PARAM;
847 list_for_each_entry(intf, &nw->nw_intflist, intf_on_network)
850 *nids = calloc(count, sizeof(lnet_nid_t));
852 return LUSTRE_CFG_RC_OUT_OF_MEM;
854 list_for_each_entry(intf, &nw->nw_intflist, intf_on_network) {
855 memset(&ifr, 0, sizeof(ifr));
856 rc = socket_intf_query(SIOCGIFFLAGS, intf->intf_name, &ifr);
860 if ((ifr.ifr_flags & IFF_UP) == 0) {
861 rc = LUSTRE_CFG_RC_BAD_PARAM;
865 memset(&ifr, 0, sizeof(ifr));
866 rc = socket_intf_query(SIOCGIFADDR, intf->intf_name, &ifr);
870 ip = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
872 (*nids)[i] = LNET_MKNID(nw->nw_id, ip);
887 * called repeatedly until a match or no more ip range
889 * ip_range expression
890 * interface list with all the interface names.
891 * all the interfaces in the system.
893 * try to match the ip_range expr to one of the interfaces' IPs in
894 * the system. If we hit a patch for an interface. Check if that
895 * interface name is in the list.
897 * If there are more than one interface in the list, then make sure
898 * that the IPs for all of these interfaces match the ip ranges
901 * for each interface in intf_list
902 * look up the intf name in ifa
903 * if not there then no match
904 * check ip obtained from ifa against a match to any of the
906 * If no match, then fail
908 * The result is that all the interfaces have to match.
910 int lustre_lnet_match_ip_to_intf(struct ifaddrs *ifa,
911 struct list_head *intf_list,
912 struct list_head *ip_ranges)
916 struct lnet_dlc_intf_descr *intf_descr;
917 struct ifaddrs *ifaddr = ifa;
918 struct lustre_lnet_ip_range_descr *ip_range;
922 * if there are no explicit interfaces, and no ip ranges, then
923 * configure the first tcp interface we encounter.
925 if (list_empty(intf_list) && list_empty(ip_ranges)) {
926 for (ifaddr = ifa; ifaddr != NULL; ifaddr = ifaddr->ifa_next) {
927 if (ifaddr->ifa_addr == NULL)
930 if ((ifaddr->ifa_flags & IFF_UP) == 0)
933 family = ifaddr->ifa_addr->sa_family;
934 if (family == AF_INET) {
935 rc = lustre_lnet_add_intf_descr
936 (intf_list, ifaddr->ifa_name,
937 strlen(ifaddr->ifa_name));
939 if (rc != LUSTRE_CFG_RC_NO_ERR)
942 return LUSTRE_CFG_RC_MATCH;
945 return LUSTRE_CFG_RC_NO_MATCH;
949 * First interface which matches an IP pattern will be used
951 if (list_empty(intf_list)) {
953 * no interfaces provided in the rule, but an ip range is
954 * provided, so try and match an interface to the ip
957 for (ifaddr = ifa; ifaddr != NULL; ifaddr = ifaddr->ifa_next) {
958 if (ifaddr->ifa_addr == NULL)
961 if ((ifaddr->ifa_flags & IFF_UP) == 0)
964 family = ifaddr->ifa_addr->sa_family;
965 if (family == AF_INET) {
966 ip = ((struct sockaddr_in *)ifaddr->ifa_addr)->
969 list_for_each_entry(ip_range, ip_ranges,
971 rc = cfs_ip_addr_match(bswap_32(ip),
972 &ip_range->ipr_expr);
976 rc = lustre_lnet_add_intf_descr
977 (intf_list, ifaddr->ifa_name,
978 strlen(ifaddr->ifa_name));
980 if (rc != LUSTRE_CFG_RC_NO_ERR)
983 return LUSTRE_CFG_RC_MATCH;
990 * If an interface is explicitly specified the ip-range might or
991 * might not be specified. if specified the interface needs to match the
992 * ip-range. If no ip-range then the interfaces are
993 * automatically matched if they are all up.
994 * If > 1 interfaces all the interfaces must match for the NI to
997 list_for_each_entry(intf_descr, intf_list, intf_on_network) {
998 for (ifaddr = ifa; ifaddr != NULL; ifaddr = ifaddr->ifa_next) {
999 if (ifaddr->ifa_addr == NULL)
1002 family = ifaddr->ifa_addr->sa_family;
1003 if (family == AF_INET &&
1004 strcmp(intf_descr->intf_name,
1005 ifaddr->ifa_name) == 0)
1010 return LUSTRE_CFG_RC_NO_MATCH;
1012 if ((ifaddr->ifa_flags & IFF_UP) == 0)
1013 return LUSTRE_CFG_RC_NO_MATCH;
1015 ip = ((struct sockaddr_in *)ifaddr->ifa_addr)->sin_addr.s_addr;
1017 list_for_each_entry(ip_range, ip_ranges, ipr_entry) {
1018 rc = cfs_ip_addr_match(bswap_32(ip), &ip_range->ipr_expr);
1022 return LUSTRE_CFG_RC_NO_MATCH;
1026 return LUSTRE_CFG_RC_MATCH;
1029 int lustre_lnet_resolve_ip2nets_rule(struct lustre_lnet_ip2nets *ip2nets,
1030 lnet_nid_t **nids, __u32 *nnids)
1032 struct ifaddrs *ifa;
1033 int rc = LUSTRE_CFG_RC_NO_ERR;
1035 rc = getifaddrs(&ifa);
1039 rc = lustre_lnet_match_ip_to_intf(ifa,
1040 &ip2nets->ip2nets_net.nw_intflist,
1041 &ip2nets->ip2nets_ip_ranges);
1042 if (rc != LUSTRE_CFG_RC_MATCH) {
1047 rc = lustre_lnet_intf2nids(&ip2nets->ip2nets_net, nids, nnids);
1048 if (rc != LUSTRE_CFG_RC_NO_ERR) {
1059 lustre_lnet_ioctl_config_ni(struct list_head *intf_list,
1060 struct lnet_ioctl_config_lnd_tunables *tunables,
1061 struct cfs_expr_list *global_cpts,
1062 lnet_nid_t *nids, char *err_str)
1065 struct lnet_ioctl_config_ni *conf;
1066 struct lnet_ioctl_config_lnd_tunables *tun = NULL;
1067 int rc = LUSTRE_CFG_RC_NO_ERR, i = 0;
1070 struct lnet_dlc_intf_descr *intf_descr;
1072 struct cfs_expr_list *cpt_expr;
1074 list_for_each_entry(intf_descr, intf_list,
1076 if (i == 0 && tunables != NULL)
1077 len = sizeof(struct lnet_ioctl_config_ni) +
1078 sizeof(struct lnet_ioctl_config_lnd_tunables);
1080 len = sizeof(struct lnet_ioctl_config_ni);
1082 data = calloc(1, len);
1083 conf = (struct lnet_ioctl_config_ni*) data;
1084 if (i == 0 && tunables != NULL)
1085 tun = (struct lnet_ioctl_config_lnd_tunables*)
1086 (data + sizeof(*conf));
1088 LIBCFS_IOC_INIT_V2(*conf, lic_cfg_hdr);
1089 conf->lic_cfg_hdr.ioc_len = len;
1090 conf->lic_nid = nids[i];
1091 strncpy(conf->lic_ni_intf[0], intf_descr->intf_name,
1094 if (intf_descr->cpt_expr != NULL)
1095 cpt_expr = intf_descr->cpt_expr;
1096 else if (global_cpts != NULL)
1097 cpt_expr = global_cpts;
1101 if (cpt_expr != NULL) {
1102 count = cfs_expr_list_values(cpt_expr,
1103 LNET_MAX_SHOW_NUM_CPT,
1106 memcpy(conf->lic_cpts, cpt_array,
1107 sizeof(cpt_array[0]) * LNET_MAX_STR_LEN);
1116 conf->lic_ncpts = count;
1118 if (i == 0 && tunables != NULL)
1119 /* TODO put in the LND tunables */
1120 memcpy(tun, tunables, sizeof(*tunables));
1122 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_ADD_LOCAL_NI, data);
1127 "\"cannot add network: %s\"", strerror(errno));
1133 return LUSTRE_CFG_RC_NO_ERR;
1137 lustre_lnet_config_ip2nets(struct lustre_lnet_ip2nets *ip2nets,
1138 struct lnet_ioctl_config_lnd_tunables *tunables,
1139 struct cfs_expr_list *global_cpts,
1140 int seq_no, struct cYAML **err_rc)
1142 lnet_nid_t *nids = NULL;
1145 char err_str[LNET_MAX_STR_LEN];
1147 snprintf(err_str, sizeof(err_str), "\"success\"");
1149 if (ip2nets == NULL ||
1150 list_empty(&ip2nets->ip2nets_net.nw_intflist)) {
1153 "\"incomplete ip2nets information\"");
1154 rc = LUSTRE_CFG_RC_BAD_PARAM;
1158 rc = lustre_lnet_resolve_ip2nets_rule(ip2nets, &nids, &nnids);
1159 if (rc != LUSTRE_CFG_RC_NO_ERR && rc != LUSTRE_CFG_RC_MATCH) {
1162 "\"cannot resolve ip2nets rule\"");
1166 rc = lustre_lnet_ioctl_config_ni(&ip2nets->ip2nets_net.nw_intflist,
1167 tunables, global_cpts, nids,
1169 if (rc != LUSTRE_CFG_RC_NO_ERR)
1173 cYAML_build_error(rc, seq_no, ADD_CMD, "ip2nets", err_str, err_rc);
1177 int lustre_lnet_config_ni(struct lnet_dlc_network_descr *nw_descr,
1178 struct cfs_expr_list *global_cpts,
1180 struct lnet_ioctl_config_lnd_tunables *tunables,
1181 int seq_no, struct cYAML **err_rc)
1184 struct lnet_ioctl_config_ni *conf;
1185 struct lnet_ioctl_config_lnd_tunables *tun = NULL;
1186 char buf[LNET_MAX_STR_LEN];
1187 int rc = LUSTRE_CFG_RC_NO_ERR;
1188 char err_str[LNET_MAX_STR_LEN];
1189 lnet_nid_t *nids = NULL;
1193 struct lnet_dlc_intf_descr *intf_descr, *tmp;
1196 snprintf(err_str, sizeof(err_str), "\"success\"");
1198 if (ip2net == NULL && nw_descr == NULL) {
1201 "\"mandatory parameters not specified.\"");
1202 rc = LUSTRE_CFG_RC_MISSING_PARAM;
1206 if (ip2net != NULL && strlen(ip2net) >= sizeof(buf)) {
1209 "\"ip2net string too long %d\"",
1210 (int)strlen(ip2net));
1211 rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
1215 if (ip2net != NULL) {
1216 if (tunables != NULL)
1217 len = sizeof(struct lnet_ioctl_config_ni) +
1218 sizeof(struct lnet_ioctl_config_lnd_tunables);
1220 len = sizeof(struct lnet_ioctl_config_ni);
1221 data = calloc(1, len);
1222 conf = (struct lnet_ioctl_config_ni*) data;
1223 if (tunables != NULL)
1224 tun = (struct lnet_ioctl_config_lnd_tunables*)
1225 (data + sizeof(*conf));
1227 LIBCFS_IOC_INIT_V2(*conf, lic_cfg_hdr);
1228 conf->lic_cfg_hdr.ioc_len = len;
1229 strncpy(conf->lic_legacy_ip2nets, ip2net,
1232 if (global_cpts != NULL) {
1233 count = cfs_expr_list_values(global_cpts,
1234 LNET_MAX_SHOW_NUM_CPT,
1237 memcpy(conf->lic_cpts, cpt_array,
1238 sizeof(cpt_array[0]) * LNET_MAX_STR_LEN);
1247 conf->lic_ncpts = count;
1249 if (tunables != NULL)
1250 memcpy(tun, tunables, sizeof(*tunables));
1252 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_ADD_LOCAL_NI, data);
1257 "\"cannot add network: %s\"", strerror(errno));
1264 if (LNET_NETTYP(nw_descr->nw_id) == LOLND)
1265 return LUSTRE_CFG_RC_NO_ERR;
1267 if (nw_descr->nw_id == LNET_NIDNET(LNET_NID_ANY)) {
1270 "\"cannot parse net '%s'\"",
1271 libcfs_net2str(nw_descr->nw_id));
1272 rc = LUSTRE_CFG_RC_BAD_PARAM;
1276 if (list_empty(&nw_descr->nw_intflist)) {
1279 "\"no interface name provided\"");
1280 rc = LUSTRE_CFG_RC_BAD_PARAM;
1284 rc = lustre_lnet_intf2nids(nw_descr, &nids, &nnids);
1286 snprintf(err_str, sizeof(err_str),
1287 "\"bad parameter\"");
1288 rc = LUSTRE_CFG_RC_BAD_PARAM;
1292 rc = lustre_lnet_ioctl_config_ni(&nw_descr->nw_intflist,
1293 tunables, global_cpts, nids,
1297 if (nw_descr != NULL) {
1298 list_for_each_entry_safe(intf_descr, tmp,
1299 &nw_descr->nw_intflist,
1301 if (intf_descr->cpt_expr != NULL)
1302 cfs_expr_list_free(intf_descr->cpt_expr);
1307 cYAML_build_error(rc, seq_no, ADD_CMD, "net", err_str, err_rc);
1318 int lustre_lnet_del_ni(struct lnet_dlc_network_descr *nw_descr,
1319 int seq_no, struct cYAML **err_rc)
1321 struct lnet_ioctl_config_ni data;
1322 int rc = LUSTRE_CFG_RC_NO_ERR, i;
1323 char err_str[LNET_MAX_STR_LEN];
1324 lnet_nid_t *nids = NULL;
1326 struct lnet_dlc_intf_descr *intf_descr, *tmp;
1328 if (LNET_NETTYP(nw_descr->nw_id) == LOLND)
1329 return LUSTRE_CFG_RC_NO_ERR;
1331 snprintf(err_str, sizeof(err_str), "\"success\"");
1333 if (nw_descr == NULL) {
1336 "\"missing mandatory parameter\"");
1337 rc = LUSTRE_CFG_RC_MISSING_PARAM;
1341 if (nw_descr->nw_id == LNET_NIDNET(LNET_NID_ANY)) {
1344 "\"cannot parse net '%s'\"",
1345 libcfs_net2str(nw_descr->nw_id));
1346 rc = LUSTRE_CFG_RC_BAD_PARAM;
1350 rc = lustre_lnet_intf2nids(nw_descr, &nids, &nnids);
1352 snprintf(err_str, sizeof(err_str),
1353 "\"bad parameter\"");
1354 rc = LUSTRE_CFG_RC_BAD_PARAM;
1359 * no interfaces just the nw_id is specified
1362 nids = calloc(1, sizeof(*nids));
1364 snprintf(err_str, sizeof(err_str),
1365 "\"out of memory\"");
1366 rc = LUSTRE_CFG_RC_OUT_OF_MEM;
1369 nids[0] = LNET_MKNID(nw_descr->nw_id, 0);
1373 for (i = 0; i < nnids; i++) {
1374 LIBCFS_IOC_INIT_V2(data, lic_cfg_hdr);
1375 data.lic_nid = nids[i];
1377 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_DEL_LOCAL_NI, &data);
1382 "\"cannot del network: %s\"", strerror(errno));
1386 list_for_each_entry_safe(intf_descr, tmp, &nw_descr->nw_intflist,
1388 if (intf_descr->cpt_expr != NULL)
1389 cfs_expr_list_free(intf_descr->cpt_expr);
1394 cYAML_build_error(rc, seq_no, DEL_CMD, "net", err_str, err_rc);
1402 int lustre_lnet_show_net(char *nw, int detail, int seq_no,
1403 struct cYAML **show_rc, struct cYAML **err_rc)
1406 struct lnet_ioctl_config_ni *ni_data;
1407 struct lnet_ioctl_config_lnd_tunables *lnd;
1408 struct lnet_ioctl_element_stats *stats;
1409 __u32 net = LNET_NIDNET(LNET_NID_ANY);
1410 __u32 prev_net = LNET_NIDNET(LNET_NID_ANY);
1411 int rc = LUSTRE_CFG_RC_OUT_OF_MEM, i, j;
1413 struct cYAML *root = NULL, *tunables = NULL,
1414 *net_node = NULL, *interfaces = NULL,
1415 *item = NULL, *first_seq = NULL,
1416 *tmp = NULL, *statistics = NULL;
1417 int str_buf_len = LNET_MAX_SHOW_NUM_CPT * 2;
1418 char str_buf[str_buf_len];
1420 char err_str[LNET_MAX_STR_LEN];
1421 bool exist = false, new_net = true;
1423 size_t buf_size = sizeof(*ni_data) + sizeof(*lnd) + sizeof(*stats);
1425 snprintf(err_str, sizeof(err_str), "\"out of memory\"");
1427 buf = calloc(1, buf_size);
1431 ni_data = (struct lnet_ioctl_config_ni *)buf;
1434 net = libcfs_str2net(nw);
1435 if (net == LNET_NIDNET(LNET_NID_ANY)) {
1438 "\"cannot parse net '%s'\"", nw);
1439 rc = LUSTRE_CFG_RC_BAD_PARAM;
1444 root = cYAML_create_object(NULL, NULL);
1448 net_node = cYAML_create_seq(root, "net");
1449 if (net_node == NULL)
1456 memset(buf, 0, buf_size);
1458 LIBCFS_IOC_INIT_V2(*ni_data, lic_cfg_hdr);
1460 * set the ioc_len to the proper value since INIT assumes
1463 ni_data->lic_cfg_hdr.ioc_len = buf_size;
1464 ni_data->lic_idx = i;
1466 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_LOCAL_NI, ni_data);
1472 rc_net = LNET_NIDNET(ni_data->lic_nid);
1474 /* filter on provided data */
1475 if (net != LNET_NIDNET(LNET_NID_ANY) &&
1479 /* default rc to -1 in case we hit the goto */
1483 stats = (struct lnet_ioctl_element_stats *)ni_data->lic_bulk;
1484 lnd = (struct lnet_ioctl_config_lnd_tunables *)
1485 (ni_data->lic_bulk + sizeof(*stats));
1487 if (rc_net != prev_net) {
1494 if (!cYAML_create_string(net_node, "net type",
1495 libcfs_net2str(rc_net)))
1498 tmp = cYAML_create_seq(net_node, "local NI(s)");
1504 /* create the tree to be printed. */
1505 item = cYAML_create_seq_item(tmp);
1509 if (first_seq == NULL)
1512 if (cYAML_create_string(item, "nid",
1513 libcfs_nid2str(ni_data->lic_nid)) == NULL)
1516 if (cYAML_create_string(item,
1518 (ni_data->lic_status ==
1519 LNET_NI_STATUS_UP) ?
1520 "up" : "down") == NULL)
1523 /* don't add interfaces unless there is at least one
1525 if (strlen(ni_data->lic_ni_intf[0]) > 0) {
1526 interfaces = cYAML_create_object(item, "interfaces");
1527 if (interfaces == NULL)
1530 for (j = 0; j < LNET_MAX_INTERFACES; j++) {
1531 if (strlen(ni_data->lic_ni_intf[j]) > 0) {
1533 sizeof(str_buf), "%d", j);
1534 if (cYAML_create_string(interfaces,
1536 ni_data->lic_ni_intf[j]) ==
1546 statistics = cYAML_create_object(item, "statistics");
1547 if (statistics == NULL)
1550 if (cYAML_create_number(statistics, "send_count",
1555 if (cYAML_create_number(statistics, "recv_count",
1560 if (cYAML_create_number(statistics, "drop_count",
1565 tunables = cYAML_create_object(item, "tunables");
1569 rc = lustre_net_show_tunables(tunables, &lnd->lt_cmn);
1570 if (rc != LUSTRE_CFG_RC_NO_ERR)
1573 tunables = cYAML_create_object(item, "lnd tunables");
1574 if (tunables == NULL)
1577 rc = lustre_ni_show_tunables(tunables, LNET_NETTYP(rc_net),
1579 if (rc != LUSTRE_CFG_RC_NO_ERR)
1582 if (cYAML_create_number(item, "tcp bonding",
1583 ni_data->lic_tcp_bonding)
1587 if (cYAML_create_number(item, "dev cpt",
1588 ni_data->lic_dev_cpt) == NULL)
1591 /* out put the CPTs in the format: "[x,x,x,...]" */
1592 limit = str_buf + str_buf_len - 3;
1593 pos += snprintf(pos, limit - pos, "\"[");
1594 for (j = 0 ; ni_data->lic_ncpts >= 1 &&
1595 j < ni_data->lic_ncpts &&
1597 pos += snprintf(pos, limit - pos,
1598 "%d", ni_data->lic_cpts[j]);
1599 if ((j + 1) < ni_data->lic_ncpts)
1600 pos += snprintf(pos, limit - pos, ",");
1602 pos += snprintf(pos, 3, "]\"");
1604 if (ni_data->lic_ncpts >= 1 &&
1605 cYAML_create_string(item, "CPT",
1611 /* Print out the net information only if show_rc is not provided */
1612 if (show_rc == NULL)
1613 cYAML_print_tree(root);
1615 if (l_errno != ENOENT) {
1618 "\"cannot get networks: %s\"",
1623 rc = LUSTRE_CFG_RC_NO_ERR;
1625 snprintf(err_str, sizeof(err_str), "\"success\"");
1627 if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR || !exist) {
1628 cYAML_free_tree(root);
1629 } else if (show_rc != NULL && *show_rc != NULL) {
1630 struct cYAML *show_node;
1631 /* find the net node, if one doesn't exist
1632 * then insert one. Otherwise add to the one there
1634 show_node = cYAML_get_object_item(*show_rc, "net");
1635 if (show_node != NULL && cYAML_is_sequence(show_node)) {
1636 cYAML_insert_child(show_node, first_seq);
1639 } else if (show_node == NULL) {
1640 cYAML_insert_sibling((*show_rc)->cy_child,
1644 cYAML_free_tree(root);
1650 cYAML_build_error(rc, seq_no, SHOW_CMD, "net", err_str, err_rc);
1655 int lustre_lnet_enable_routing(int enable, int seq_no, struct cYAML **err_rc)
1657 struct lnet_ioctl_config_data data;
1658 int rc = LUSTRE_CFG_RC_NO_ERR;
1659 char err_str[LNET_MAX_STR_LEN];
1661 snprintf(err_str, sizeof(err_str), "\"success\"");
1663 LIBCFS_IOC_INIT_V2(data, cfg_hdr);
1664 data.cfg_config_u.cfg_buffers.buf_enable = (enable) ? 1 : 0;
1666 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_CONFIG_RTR, &data);
1671 "\"cannot %s routing %s\"",
1672 (enable) ? "enable" : "disable", strerror(errno));
1677 cYAML_build_error(rc, seq_no,
1678 (enable) ? ADD_CMD : DEL_CMD,
1679 "routing", err_str, err_rc);
1684 int lustre_lnet_config_numa_range(int range, int seq_no, struct cYAML **err_rc)
1686 struct lnet_ioctl_numa_range data;
1687 int rc = LUSTRE_CFG_RC_NO_ERR;
1688 char err_str[LNET_MAX_STR_LEN];
1690 snprintf(err_str, sizeof(err_str), "\"success\"");
1695 "\"range must be >= 0\"");
1696 rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
1700 LIBCFS_IOC_INIT_V2(data, nr_hdr);
1701 data.nr_range = range;
1703 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_SET_NUMA_RANGE, &data);
1708 "\"cannot configure buffers: %s\"", strerror(errno));
1713 cYAML_build_error(rc, seq_no, ADD_CMD, "numa_range", err_str, err_rc);
1718 int lustre_lnet_config_buffers(int tiny, int small, int large, int seq_no,
1719 struct cYAML **err_rc)
1721 struct lnet_ioctl_config_data data;
1722 int rc = LUSTRE_CFG_RC_NO_ERR;
1723 char err_str[LNET_MAX_STR_LEN];
1725 snprintf(err_str, sizeof(err_str), "\"success\"");
1727 /* -1 indicates to ignore changes to this field */
1728 if (tiny < -1 || small < -1 || large < -1) {
1731 "\"tiny, small and large must be >= 0\"");
1732 rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
1736 LIBCFS_IOC_INIT_V2(data, cfg_hdr);
1737 data.cfg_config_u.cfg_buffers.buf_tiny = tiny;
1738 data.cfg_config_u.cfg_buffers.buf_small = small;
1739 data.cfg_config_u.cfg_buffers.buf_large = large;
1741 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_ADD_BUF, &data);
1746 "\"cannot configure buffers: %s\"", strerror(errno));
1751 cYAML_build_error(rc, seq_no, ADD_CMD, "buf", err_str, err_rc);
1756 int lustre_lnet_show_routing(int seq_no, struct cYAML **show_rc,
1757 struct cYAML **err_rc)
1759 struct lnet_ioctl_config_data *data;
1760 struct lnet_ioctl_pool_cfg *pool_cfg = NULL;
1761 int rc = LUSTRE_CFG_RC_OUT_OF_MEM;
1764 char *pools[LNET_NRBPOOLS] = {"tiny", "small", "large"};
1765 int buf_count[LNET_NRBPOOLS] = {0};
1766 struct cYAML *root = NULL, *pools_node = NULL,
1767 *type_node = NULL, *item = NULL, *cpt = NULL,
1768 *first_seq = NULL, *buffers = NULL;
1770 char err_str[LNET_MAX_STR_LEN];
1771 char node_name[LNET_MAX_STR_LEN];
1774 snprintf(err_str, sizeof(err_str), "\"out of memory\"");
1776 buf = calloc(1, sizeof(*data) + sizeof(*pool_cfg));
1780 data = (struct lnet_ioctl_config_data *)buf;
1782 root = cYAML_create_object(NULL, NULL);
1786 pools_node = cYAML_create_seq(root, "routing");
1787 if (pools_node == NULL)
1791 LIBCFS_IOC_INIT_V2(*data, cfg_hdr);
1792 data->cfg_hdr.ioc_len = sizeof(struct lnet_ioctl_config_data) +
1793 sizeof(struct lnet_ioctl_pool_cfg);
1794 data->cfg_count = i;
1796 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_BUF, data);
1804 pool_cfg = (struct lnet_ioctl_pool_cfg *)data->cfg_bulk;
1806 snprintf(node_name, sizeof(node_name), "cpt[%d]", i);
1807 item = cYAML_create_seq_item(pools_node);
1811 if (first_seq == NULL)
1814 cpt = cYAML_create_object(item, node_name);
1818 /* create the tree and print */
1819 for (j = 0; j < LNET_NRBPOOLS; j++) {
1820 type_node = cYAML_create_object(cpt, pools[j]);
1821 if (type_node == NULL)
1823 if (cYAML_create_number(type_node, "npages",
1824 pool_cfg->pl_pools[j].pl_npages)
1827 if (cYAML_create_number(type_node, "nbuffers",
1828 pool_cfg->pl_pools[j].
1829 pl_nbuffers) == NULL)
1831 if (cYAML_create_number(type_node, "credits",
1832 pool_cfg->pl_pools[j].
1833 pl_credits) == NULL)
1835 if (cYAML_create_number(type_node, "mincredits",
1836 pool_cfg->pl_pools[j].
1837 pl_mincredits) == NULL)
1839 /* keep track of the total count for each of the
1840 * tiny, small and large buffers */
1841 buf_count[j] += pool_cfg->pl_pools[j].pl_nbuffers;
1845 if (pool_cfg != NULL) {
1846 item = cYAML_create_seq_item(pools_node);
1850 if (cYAML_create_number(item, "enable", pool_cfg->pl_routing) ==
1855 /* create a buffers entry in the show. This is necessary so that
1856 * if the YAML output is used to configure a node, the buffer
1857 * configuration takes hold */
1858 buffers = cYAML_create_object(root, "buffers");
1859 if (buffers == NULL)
1862 for (i = 0; i < LNET_NRBPOOLS; i++) {
1863 if (cYAML_create_number(buffers, pools[i], buf_count[i]) == NULL)
1867 if (show_rc == NULL)
1868 cYAML_print_tree(root);
1870 if (l_errno != ENOENT) {
1873 "\"cannot get routing information: %s\"",
1878 rc = LUSTRE_CFG_RC_NO_ERR;
1880 snprintf(err_str, sizeof(err_str), "\"success\"");
1881 rc = LUSTRE_CFG_RC_NO_ERR;
1885 if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR || !exist) {
1886 cYAML_free_tree(root);
1887 } else if (show_rc != NULL && *show_rc != NULL) {
1888 struct cYAML *routing_node;
1889 /* there should exist only one routing block and one
1890 * buffers block. If there already exists a previous one
1891 * then don't add another */
1892 routing_node = cYAML_get_object_item(*show_rc, "routing");
1893 if (routing_node == NULL) {
1894 cYAML_insert_sibling((*show_rc)->cy_child,
1898 cYAML_free_tree(root);
1904 cYAML_build_error(rc, seq_no, SHOW_CMD, "routing", err_str, err_rc);
1909 int lustre_lnet_show_peer(char *knid, int seq_no, struct cYAML **show_rc,
1910 struct cYAML **err_rc)
1912 struct lnet_ioctl_peer_cfg *peer_info;
1913 struct lnet_peer_ni_credit_info *lpni_cri;
1914 struct lnet_ioctl_element_stats *lpni_stats;
1915 int rc = LUSTRE_CFG_RC_OUT_OF_MEM, ncpt = 0, i = 0, j = 0;
1917 struct cYAML *root = NULL, *peer = NULL, *peer_ni = NULL,
1918 *first_seq = NULL, *peer_root = NULL, *tmp = NULL;
1919 char err_str[LNET_MAX_STR_LEN];
1920 lnet_nid_t prev_primary_nid = LNET_NID_ANY, primary_nid = LNET_NID_ANY;
1921 int data_size = sizeof(*peer_info) + sizeof(*lpni_cri) +
1922 sizeof(*lpni_stats);
1923 char *data = calloc(data_size, 1);
1924 bool new_peer = true;
1926 snprintf(err_str, sizeof(err_str),
1927 "\"out of memory\"");
1932 peer_info = (struct lnet_ioctl_peer_cfg *)data;
1934 /* create struct cYAML root object */
1935 root = cYAML_create_object(NULL, NULL);
1939 peer_root = cYAML_create_seq(root, "peer");
1940 if (peer_root == NULL)
1944 primary_nid = libcfs_str2nid(knid);
1948 memset(data, 0, data_size);
1949 LIBCFS_IOC_INIT_V2(*peer_info, prcfg_hdr);
1950 peer_info->prcfg_hdr.ioc_len = data_size;
1951 peer_info->prcfg_idx = i;
1953 rc = l_ioctl(LNET_DEV_ID,
1954 IOC_LIBCFS_GET_PEER_NI, peer_info);
1960 if (primary_nid != LNET_NID_ANY &&
1961 primary_nid != peer_info->prcfg_key_nid)
1964 lpni_cri = (struct lnet_peer_ni_credit_info*)peer_info->prcfg_bulk;
1965 lpni_stats = (struct lnet_ioctl_element_stats *)
1966 (peer_info->prcfg_bulk +
1969 peer = cYAML_create_seq_item(peer_root);
1973 if (peer_info->prcfg_key_nid != prev_primary_nid) {
1974 prev_primary_nid = peer_info->prcfg_key_nid;
1979 lnet_nid_t pnid = peer_info->prcfg_key_nid;
1980 if (cYAML_create_string(peer, "primary nid",
1981 libcfs_nid2str(pnid))
1984 tmp = cYAML_create_seq(peer, "peer ni");
1990 if (first_seq == NULL)
1993 peer_ni = cYAML_create_seq_item(tmp);
1994 if (peer_ni == NULL)
1997 if (cYAML_create_string(peer_ni, "nid",
1999 (peer_info->prcfg_cfg_nid))
2003 if (cYAML_create_string(peer_ni, "state",
2004 lpni_cri->cr_aliveness)
2008 if (cYAML_create_number(peer_ni, "refcount",
2009 lpni_cri->cr_refcount) == NULL)
2012 if (cYAML_create_number(peer_ni, "max_ni_tx_credits",
2013 lpni_cri->cr_ni_peer_tx_credits)
2017 if (cYAML_create_number(peer_ni, "available_tx_credits",
2018 lpni_cri->cr_peer_tx_credits)
2022 if (cYAML_create_number(peer_ni, "available_rtr_credits",
2023 lpni_cri->cr_peer_rtr_credits)
2027 if (cYAML_create_number(peer_ni, "min_rtr_credits",
2028 lpni_cri->cr_peer_min_rtr_credits)
2032 if (cYAML_create_number(peer_ni, "tx_q_num_of_buf",
2033 lpni_cri->cr_peer_tx_qnob)
2037 if (cYAML_create_number(peer_ni, "send_count",
2038 lpni_stats->send_count)
2042 if (cYAML_create_number(peer_ni, "recv_count",
2043 lpni_stats->recv_count)
2047 if (cYAML_create_number(peer_ni, "drop_count",
2048 lpni_stats->drop_count)
2053 if (l_errno != ENOENT) {
2056 "\"cannot get peer information: %s\"",
2065 /* print output iff show_rc is not provided */
2066 if (show_rc == NULL)
2067 cYAML_print_tree(root);
2069 snprintf(err_str, sizeof(err_str), "\"success\"");
2070 rc = LUSTRE_CFG_RC_NO_ERR;
2073 if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR) {
2074 cYAML_free_tree(root);
2075 } else if (show_rc != NULL && *show_rc != NULL) {
2076 struct cYAML *show_node;
2077 /* find the peer node, if one doesn't exist then
2078 * insert one. Otherwise add to the one there
2080 show_node = cYAML_get_object_item(*show_rc,
2082 if (show_node != NULL && cYAML_is_sequence(show_node)) {
2083 cYAML_insert_child(show_node, first_seq);
2086 } else if (show_node == NULL) {
2087 cYAML_insert_sibling((*show_rc)->cy_child,
2091 cYAML_free_tree(root);
2097 cYAML_build_error(rc, seq_no, SHOW_CMD, "peer", err_str,
2103 int lustre_lnet_show_numa_range(int seq_no, struct cYAML **show_rc,
2104 struct cYAML **err_rc)
2106 struct lnet_ioctl_numa_range data;
2107 int rc = LUSTRE_CFG_RC_OUT_OF_MEM;
2109 char err_str[LNET_MAX_STR_LEN];
2110 struct cYAML *root = NULL, *range = NULL;
2112 snprintf(err_str, sizeof(err_str), "\"out of memory\"");
2114 LIBCFS_IOC_INIT_V2(data, nr_hdr);
2116 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_NUMA_RANGE, &data);
2121 "\"cannot get numa range: %s\"",
2127 root = cYAML_create_object(NULL, NULL);
2131 range = cYAML_create_object(root, "numa");
2135 if (cYAML_create_number(range, "range",
2136 data.nr_range) == NULL)
2139 if (show_rc == NULL)
2140 cYAML_print_tree(root);
2142 snprintf(err_str, sizeof(err_str), "\"success\"");
2144 if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR) {
2145 cYAML_free_tree(root);
2146 } else if (show_rc != NULL && *show_rc != NULL) {
2147 cYAML_insert_sibling((*show_rc)->cy_child,
2154 cYAML_build_error(rc, seq_no, SHOW_CMD, "numa", err_str, err_rc);
2159 int lustre_lnet_show_stats(int seq_no, struct cYAML **show_rc,
2160 struct cYAML **err_rc)
2162 struct lnet_ioctl_lnet_stats data;
2163 int rc = LUSTRE_CFG_RC_OUT_OF_MEM;
2165 char err_str[LNET_MAX_STR_LEN];
2166 struct cYAML *root = NULL, *stats = NULL;
2168 snprintf(err_str, sizeof(err_str), "\"out of memory\"");
2170 LIBCFS_IOC_INIT_V2(data, st_hdr);
2172 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_LNET_STATS, &data);
2177 "\"cannot get lnet statistics: %s\"",
2183 root = cYAML_create_object(NULL, NULL);
2187 stats = cYAML_create_object(root, "statistics");
2191 if (cYAML_create_number(stats, "msgs_alloc",
2192 data.st_cntrs.msgs_alloc) == NULL)
2195 if (cYAML_create_number(stats, "msgs_max",
2196 data.st_cntrs.msgs_max) == NULL)
2199 if (cYAML_create_number(stats, "errors",
2200 data.st_cntrs.errors) == NULL)
2203 if (cYAML_create_number(stats, "send_count",
2204 data.st_cntrs.send_count) == NULL)
2207 if (cYAML_create_number(stats, "recv_count",
2208 data.st_cntrs.recv_count) == NULL)
2211 if (cYAML_create_number(stats, "route_count",
2212 data.st_cntrs.route_count) == NULL)
2215 if (cYAML_create_number(stats, "drop_count",
2216 data.st_cntrs.drop_count) == NULL)
2219 if (cYAML_create_number(stats, "send_length",
2220 data.st_cntrs.send_length) == NULL)
2223 if (cYAML_create_number(stats, "recv_length",
2224 data.st_cntrs.recv_length) == NULL)
2227 if (cYAML_create_number(stats, "route_length",
2228 data.st_cntrs.route_length) == NULL)
2231 if (cYAML_create_number(stats, "drop_length",
2232 data.st_cntrs.drop_length) == NULL)
2235 if (show_rc == NULL)
2236 cYAML_print_tree(root);
2238 snprintf(err_str, sizeof(err_str), "\"success\"");
2240 if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR) {
2241 cYAML_free_tree(root);
2242 } else if (show_rc != NULL && *show_rc != NULL) {
2243 cYAML_insert_sibling((*show_rc)->cy_child,
2250 cYAML_build_error(rc, seq_no, SHOW_CMD, "statistics", err_str, err_rc);
2255 typedef int (*cmd_handler_t)(struct cYAML *tree,
2256 struct cYAML **show_rc,
2257 struct cYAML **err_rc);
2259 static int handle_yaml_config_route(struct cYAML *tree, struct cYAML **show_rc,
2260 struct cYAML **err_rc)
2262 struct cYAML *net, *gw, *hop, *prio, *seq_no;
2264 net = cYAML_get_object_item(tree, "net");
2265 gw = cYAML_get_object_item(tree, "gateway");
2266 hop = cYAML_get_object_item(tree, "hop");
2267 prio = cYAML_get_object_item(tree, "priority");
2268 seq_no = cYAML_get_object_item(tree, "seq_no");
2270 return lustre_lnet_config_route((net) ? net->cy_valuestring : NULL,
2271 (gw) ? gw->cy_valuestring : NULL,
2272 (hop) ? hop->cy_valueint : -1,
2273 (prio) ? prio->cy_valueint : -1,
2274 (seq_no) ? seq_no->cy_valueint : -1,
2278 static void yaml_free_string_array(char **array, int num)
2281 char **sub_array = array;
2283 for (i = 0; i < num; i++) {
2284 if (*sub_array != NULL)
2293 * 0: <intf_name>['['<expr>']']
2294 * 1: <intf_name>['['<expr>']']
2296 static int yaml_copy_intf_info(struct cYAML *intf_tree,
2297 struct lnet_dlc_network_descr *nw_descr)
2299 struct cYAML *child = NULL;
2300 int intf_num = 0, rc = LUSTRE_CFG_RC_NO_ERR;
2301 struct lnet_dlc_intf_descr *intf_descr, *tmp;
2303 if (intf_tree == NULL || nw_descr == NULL)
2304 return LUSTRE_CFG_RC_BAD_PARAM;
2306 /* now grab all the interfaces and their cpts */
2307 child = intf_tree->cy_child;
2308 while (child != NULL) {
2309 if (child->cy_valuestring == NULL) {
2310 child = child->cy_next;
2314 if (strlen(child->cy_valuestring) >= LNET_MAX_STR_LEN)
2317 rc = lustre_lnet_add_intf_descr(&nw_descr->nw_intflist,
2318 child->cy_valuestring,
2319 strlen(child->cy_valuestring));
2320 if (rc != LUSTRE_CFG_RC_NO_ERR)
2324 child = child->cy_next;
2328 return LUSTRE_CFG_RC_MISSING_PARAM;
2333 list_for_each_entry_safe(intf_descr, tmp, &nw_descr->nw_intflist,
2335 if (intf_descr->cpt_expr != NULL)
2336 cfs_expr_list_free(intf_descr->cpt_expr);
2344 yaml_extract_cmn_tunables(struct cYAML *tree,
2345 struct lnet_ioctl_config_lnd_cmn_tunables *tunables,
2346 int *num_global_cpts,
2347 struct cfs_expr_list **global_cpts)
2349 struct cYAML *tun, *item, *smp;
2351 tun = cYAML_get_object_item(tree, "tunables");
2353 item = cYAML_get_object_item(tun, "peer_timeout");
2355 tunables->lct_peer_timeout = item->cy_valueint;
2356 item = cYAML_get_object_item(tun, "peer_credits");
2358 tunables->lct_peer_tx_credits = item->cy_valueint;
2359 item = cYAML_get_object_item(tun, "peer_buffer_credits");
2361 tunables->lct_peer_rtr_credits = item->cy_valueint;
2362 item = cYAML_get_object_item(tun, "credits");
2364 tunables->lct_max_tx_credits = item->cy_valueint;
2365 smp = cYAML_get_object_item(tun, "CPT");
2368 cfs_expr_list_parse(smp->cy_valuestring,
2369 strlen(smp->cy_valuestring),
2370 0, UINT_MAX, global_cpts);
2380 yaml_extract_tunables(struct cYAML *tree,
2381 struct lnet_ioctl_config_lnd_tunables *tunables,
2382 int *num_global_cpts,
2383 struct cfs_expr_list **global_cpts,
2388 rc = yaml_extract_cmn_tunables(tree, &tunables->lt_cmn,
2389 num_global_cpts, global_cpts);
2394 lustre_yaml_extract_lnd_tunables(tree, net_type,
2402 * - net type: <net>[<NUM>]
2404 * - nid: <ip>@<net>[<NUM>]
2407 * 0: <intf_name>['['<expr>']']
2408 * 1: <intf_name>['['<expr>']']
2410 * peer_timeout: <NUM>
2411 * peer_credits: <NUM>
2412 * peer_buffer_credits: <NUM>
2415 * peercredits_hiw: <NUM>
2416 * map_on_demand: <NUM>
2417 * concurrent_sends: <NUM>
2418 * fmr_pool_size: <NUM>
2419 * fmr_flush_trigger: <NUM>
2422 * At least one interface is required. If no interfaces are provided the
2423 * network interface can not be configured.
2425 static int handle_yaml_config_ni(struct cYAML *tree, struct cYAML **show_rc,
2426 struct cYAML **err_rc)
2428 struct cYAML *net, *intf, *seq_no, *ip2net = NULL, *local_nis = NULL,
2430 int num_entries = 0, num_global_cpts = 0, rc;
2431 struct lnet_dlc_network_descr nw_descr;
2432 struct cfs_expr_list *global_cpts = NULL;
2433 struct lnet_ioctl_config_lnd_tunables tunables;
2436 memset(&tunables, 0, sizeof(tunables));
2438 INIT_LIST_HEAD(&nw_descr.network_on_rule);
2439 INIT_LIST_HEAD(&nw_descr.nw_intflist);
2441 ip2net = cYAML_get_object_item(tree, "ip2net");
2442 net = cYAML_get_object_item(tree, "net type");
2444 nw_descr.nw_id = libcfs_str2net(net->cy_valuestring);
2447 * if neither net nor ip2nets are present, then we can not
2448 * configure the network.
2450 if (!net && !ip2net)
2451 return LUSTRE_CFG_RC_MISSING_PARAM;
2453 local_nis = cYAML_get_object_item(tree, "local NI(s)");
2454 if (local_nis == NULL)
2455 return LUSTRE_CFG_RC_MISSING_PARAM;
2457 if (!cYAML_is_sequence(local_nis))
2458 return LUSTRE_CFG_RC_BAD_PARAM;
2460 while (cYAML_get_next_seq_item(local_nis, &item) != NULL) {
2461 intf = cYAML_get_object_item(item, "interfaces");
2464 num_entries = yaml_copy_intf_info(intf, &nw_descr);
2465 if (num_entries <= 0) {
2466 cYAML_build_error(num_entries, -1, "ni", "add",
2467 "bad interface list",
2469 return LUSTRE_CFG_RC_BAD_PARAM;
2473 found = yaml_extract_tunables(tree, &tunables, &num_global_cpts,
2475 LNET_NETTYP(nw_descr.nw_id));
2476 seq_no = cYAML_get_object_item(tree, "seq_no");
2478 rc = lustre_lnet_config_ni(&nw_descr,
2479 (num_global_cpts > 0) ? global_cpts: NULL,
2480 (ip2net) ? ip2net->cy_valuestring : NULL,
2481 (found) ? &tunables: NULL,
2482 (seq_no) ? seq_no->cy_valueint : -1,
2485 if (global_cpts != NULL)
2486 cfs_expr_list_free(global_cpts);
2493 * - net-spec: <tcp|o2ib|gni>[NUM]
2495 * 0: <intf name>['['<expr>']']
2496 * 1: <intf name>['['<expr>']']
2498 * 0: <expr.expr.expr.expr>
2499 * 1: <expr.expr.expr.expr>
2501 static int handle_yaml_config_ip2nets(struct cYAML *tree,
2502 struct cYAML **show_rc,
2503 struct cYAML **err_rc)
2505 struct cYAML *net, *ip_range, *item = NULL, *intf = NULL,
2507 struct lustre_lnet_ip2nets ip2nets;
2508 struct lustre_lnet_ip_range_descr *ip_range_descr = NULL,
2510 int rc = LUSTRE_CFG_RC_NO_ERR, num_global_cpts = 0;
2511 struct cfs_expr_list *global_cpts = NULL;
2512 struct cfs_expr_list *el, *el_tmp;
2513 struct lnet_ioctl_config_lnd_tunables tunables;
2514 struct lnet_dlc_intf_descr *intf_descr, *intf_tmp;
2517 memset(&tunables, 0, sizeof(tunables));
2519 /* initialize all lists */
2520 INIT_LIST_HEAD(&ip2nets.ip2nets_ip_ranges);
2521 INIT_LIST_HEAD(&ip2nets.ip2nets_net.network_on_rule);
2522 INIT_LIST_HEAD(&ip2nets.ip2nets_net.nw_intflist);
2524 net = cYAML_get_object_item(tree, "net-spec");
2526 return LUSTRE_CFG_RC_BAD_PARAM;
2528 if (net != NULL && net->cy_valuestring == NULL)
2529 return LUSTRE_CFG_RC_BAD_PARAM;
2531 /* assign the network id */
2532 ip2nets.ip2nets_net.nw_id = libcfs_str2net(net->cy_valuestring);
2533 if (ip2nets.ip2nets_net.nw_id == LNET_NID_ANY)
2534 return LUSTRE_CFG_RC_BAD_PARAM;
2536 seq_no = cYAML_get_object_item(tree, "seq_no");
2538 intf = cYAML_get_object_item(tree, "interfaces");
2540 rc = yaml_copy_intf_info(intf, &ip2nets.ip2nets_net);
2542 return LUSTRE_CFG_RC_BAD_PARAM;
2545 ip_range = cYAML_get_object_item(tree, "ip-range");
2546 if (ip_range != NULL) {
2547 item = ip_range->cy_child;
2548 while (item != NULL) {
2549 if (item->cy_valuestring == NULL) {
2550 item = item->cy_next;
2554 rc = lustre_lnet_add_ip_range(&ip2nets.ip2nets_ip_ranges,
2555 item->cy_valuestring);
2557 if (rc != LUSTRE_CFG_RC_NO_ERR)
2560 item = item->cy_next;
2564 found = yaml_extract_tunables(tree, &tunables, &num_global_cpts,
2566 LNET_NETTYP(ip2nets.ip2nets_net.nw_id));
2568 rc = lustre_lnet_config_ip2nets(&ip2nets,
2569 (found) ? &tunables : NULL,
2570 (num_global_cpts > 0) ? global_cpts : NULL,
2571 (seq_no) ? seq_no->cy_valueint : -1,
2575 * don't stop because there was no match. Continue processing the
2576 * rest of the rules. If non-match then nothing is configured
2578 if (rc == LUSTRE_CFG_RC_NO_MATCH)
2579 rc = LUSTRE_CFG_RC_NO_ERR;
2581 list_for_each_entry_safe(intf_descr, intf_tmp,
2582 &ip2nets.ip2nets_net.nw_intflist,
2584 if (intf_descr->cpt_expr != NULL)
2585 cfs_expr_list_free(intf_descr->cpt_expr);
2589 list_for_each_entry_safe(ip_range_descr, tmp,
2590 &ip2nets.ip2nets_ip_ranges,
2592 list_for_each_entry_safe(el, el_tmp, &ip_range_descr->ipr_expr,
2594 cfs_expr_list_free(el);
2595 free(ip_range_descr);
2601 static int handle_yaml_del_ni(struct cYAML *tree, struct cYAML **show_rc,
2602 struct cYAML **err_rc)
2604 struct cYAML *net = NULL, *intf = NULL, *seq_no = NULL, *item = NULL,
2606 int num_entries, rc;
2607 struct lnet_dlc_network_descr nw_descr;
2609 INIT_LIST_HEAD(&nw_descr.network_on_rule);
2610 INIT_LIST_HEAD(&nw_descr.nw_intflist);
2612 net = cYAML_get_object_item(tree, "net type");
2614 nw_descr.nw_id = libcfs_str2net(net->cy_valuestring);
2616 local_nis = cYAML_get_object_item(tree, "local NI(s)");
2617 if (local_nis == NULL)
2618 return LUSTRE_CFG_RC_MISSING_PARAM;
2620 if (!cYAML_is_sequence(local_nis))
2621 return LUSTRE_CFG_RC_BAD_PARAM;
2623 while (cYAML_get_next_seq_item(local_nis, &item) != NULL) {
2624 intf = cYAML_get_object_item(item, "interfaces");
2627 num_entries = yaml_copy_intf_info(intf, &nw_descr);
2628 if (num_entries <= 0) {
2629 cYAML_build_error(num_entries, -1, "ni", "add",
2630 "bad interface list",
2632 return LUSTRE_CFG_RC_BAD_PARAM;
2636 seq_no = cYAML_get_object_item(tree, "seq_no");
2638 rc = lustre_lnet_del_ni((net) ? &nw_descr : NULL,
2639 (seq_no) ? seq_no->cy_valueint : -1,
2645 static int yaml_copy_peer_nids(struct cYAML *tree, char ***nidsppp)
2647 struct cYAML *nids_entry = NULL, *child;
2649 int num = 0, rc = LUSTRE_CFG_RC_NO_ERR;
2651 nids_entry = cYAML_get_object_item(tree, "nids");
2652 if (nids_entry != NULL) {
2654 child = nids_entry->cy_child;
2655 while (child != NULL) {
2657 child = child->cy_next;
2661 return LUSTRE_CFG_RC_MISSING_PARAM;
2663 nids = calloc(sizeof(*nids) * num, 1);
2665 return LUSTRE_CFG_RC_OUT_OF_MEM;
2667 /* now grab all the nids */
2668 child = nids_entry->cy_child;
2670 while (child != NULL) {
2671 nids[num] = calloc(strlen(child->cy_valuestring) + 1,
2673 if (nids[num] == NULL) {
2674 rc = LUSTRE_CFG_RC_OUT_OF_MEM;
2677 strncpy(nids[num], child->cy_valuestring,
2678 strlen(child->cy_valuestring));
2679 child = child->cy_next;
2684 rc = LUSTRE_CFG_RC_MISSING_PARAM;
2693 yaml_free_string_array(nids, num);
2698 static int handle_yaml_config_peer(struct cYAML *tree, struct cYAML **show_rc,
2699 struct cYAML **err_rc)
2703 struct cYAML *seq_no, *key_nid, *non_mr;
2705 num = yaml_copy_peer_nids(tree, &nids);
2709 seq_no = cYAML_get_object_item(tree, "seq_no");
2710 key_nid = cYAML_get_object_item(tree, "key_nid");
2711 non_mr = cYAML_get_object_item(tree, "non_mr");
2713 rc = lustre_lnet_config_peer_nid((key_nid) ? key_nid->cy_valuestring : NULL,
2715 (non_mr) ? false : true,
2716 (seq_no) ? seq_no->cy_valueint : -1,
2719 yaml_free_string_array(nids, num);
2723 static int handle_yaml_del_peer(struct cYAML *tree, struct cYAML **show_rc,
2724 struct cYAML **err_rc)
2728 struct cYAML *seq_no, *key_nid;
2730 num = yaml_copy_peer_nids(tree, &nids);
2734 seq_no = cYAML_get_object_item(tree, "seq_no");
2735 key_nid = cYAML_get_object_item(tree, "key_nid");
2737 rc = lustre_lnet_del_peer_nid((key_nid) ? key_nid->cy_valuestring : NULL,
2739 (seq_no) ? seq_no->cy_valueint : -1,
2742 yaml_free_string_array(nids, num);
2746 static int handle_yaml_config_buffers(struct cYAML *tree,
2747 struct cYAML **show_rc,
2748 struct cYAML **err_rc)
2751 struct cYAML *tiny, *small, *large, *seq_no;
2753 tiny = cYAML_get_object_item(tree, "tiny");
2754 small = cYAML_get_object_item(tree, "small");
2755 large = cYAML_get_object_item(tree, "large");
2756 seq_no = cYAML_get_object_item(tree, "seq_no");
2758 rc = lustre_lnet_config_buffers((tiny) ? tiny->cy_valueint : -1,
2759 (small) ? small->cy_valueint : -1,
2760 (large) ? large->cy_valueint : -1,
2761 (seq_no) ? seq_no->cy_valueint : -1,
2767 static int handle_yaml_config_routing(struct cYAML *tree,
2768 struct cYAML **show_rc,
2769 struct cYAML **err_rc)
2771 int rc = LUSTRE_CFG_RC_NO_ERR;
2772 struct cYAML *seq_no, *enable;
2774 seq_no = cYAML_get_object_item(tree, "seq_no");
2775 enable = cYAML_get_object_item(tree, "enable");
2778 rc = lustre_lnet_enable_routing(enable->cy_valueint,
2780 seq_no->cy_valueint : -1,
2787 static int handle_yaml_del_route(struct cYAML *tree, struct cYAML **show_rc,
2788 struct cYAML **err_rc)
2792 struct cYAML *seq_no;
2794 net = cYAML_get_object_item(tree, "net");
2795 gw = cYAML_get_object_item(tree, "gateway");
2796 seq_no = cYAML_get_object_item(tree, "seq_no");
2798 return lustre_lnet_del_route((net) ? net->cy_valuestring : NULL,
2799 (gw) ? gw->cy_valuestring : NULL,
2800 (seq_no) ? seq_no->cy_valueint : -1,
2804 static int handle_yaml_del_routing(struct cYAML *tree, struct cYAML **show_rc,
2805 struct cYAML **err_rc)
2807 struct cYAML *seq_no;
2809 seq_no = cYAML_get_object_item(tree, "seq_no");
2811 return lustre_lnet_enable_routing(0, (seq_no) ?
2812 seq_no->cy_valueint : -1,
2816 static int handle_yaml_show_route(struct cYAML *tree, struct cYAML **show_rc,
2817 struct cYAML **err_rc)
2823 struct cYAML *detail;
2824 struct cYAML *seq_no;
2826 net = cYAML_get_object_item(tree, "net");
2827 gw = cYAML_get_object_item(tree, "gateway");
2828 hop = cYAML_get_object_item(tree, "hop");
2829 prio = cYAML_get_object_item(tree, "priority");
2830 detail = cYAML_get_object_item(tree, "detail");
2831 seq_no = cYAML_get_object_item(tree, "seq_no");
2833 return lustre_lnet_show_route((net) ? net->cy_valuestring : NULL,
2834 (gw) ? gw->cy_valuestring : NULL,
2835 (hop) ? hop->cy_valueint : -1,
2836 (prio) ? prio->cy_valueint : -1,
2837 (detail) ? detail->cy_valueint : 0,
2838 (seq_no) ? seq_no->cy_valueint : -1,
2843 static int handle_yaml_show_net(struct cYAML *tree, struct cYAML **show_rc,
2844 struct cYAML **err_rc)
2846 struct cYAML *net, *detail, *seq_no;
2848 net = cYAML_get_object_item(tree, "net");
2849 detail = cYAML_get_object_item(tree, "detail");
2850 seq_no = cYAML_get_object_item(tree, "seq_no");
2852 return lustre_lnet_show_net((net) ? net->cy_valuestring : NULL,
2853 (detail) ? detail->cy_valueint : 0,
2854 (seq_no) ? seq_no->cy_valueint : -1,
2859 static int handle_yaml_show_routing(struct cYAML *tree, struct cYAML **show_rc,
2860 struct cYAML **err_rc)
2862 struct cYAML *seq_no;
2864 seq_no = cYAML_get_object_item(tree, "seq_no");
2866 return lustre_lnet_show_routing((seq_no) ? seq_no->cy_valueint : -1,
2870 static int handle_yaml_show_credits(struct cYAML *tree, struct cYAML **show_rc,
2871 struct cYAML **err_rc)
2873 struct cYAML *seq_no, *key_nid;
2875 seq_no = cYAML_get_object_item(tree, "seq_no");
2876 key_nid = cYAML_get_object_item(tree, "key_nid");
2878 return lustre_lnet_show_peer((key_nid) ? key_nid->cy_valuestring : NULL,
2879 (seq_no) ? seq_no->cy_valueint : -1,
2883 static int handle_yaml_show_stats(struct cYAML *tree, struct cYAML **show_rc,
2884 struct cYAML **err_rc)
2886 struct cYAML *seq_no;
2888 seq_no = cYAML_get_object_item(tree, "seq_no");
2890 return lustre_lnet_show_stats((seq_no) ? seq_no->cy_valueint : -1,
2894 struct lookup_cmd_hdlr_tbl {
2899 static struct lookup_cmd_hdlr_tbl lookup_config_tbl[] = {
2900 {"route", handle_yaml_config_route},
2901 {"net", handle_yaml_config_ni},
2902 {"ip2nets", handle_yaml_config_ip2nets},
2903 {"peer", handle_yaml_config_peer},
2904 {"routing", handle_yaml_config_routing},
2905 {"buffers", handle_yaml_config_buffers},
2909 static struct lookup_cmd_hdlr_tbl lookup_del_tbl[] = {
2910 {"route", handle_yaml_del_route},
2911 {"net", handle_yaml_del_ni},
2912 {"peer", handle_yaml_del_peer},
2913 {"routing", handle_yaml_del_routing},
2917 static struct lookup_cmd_hdlr_tbl lookup_show_tbl[] = {
2918 {"route", handle_yaml_show_route},
2919 {"net", handle_yaml_show_net},
2920 {"buffers", handle_yaml_show_routing},
2921 {"routing", handle_yaml_show_routing},
2922 {"credits", handle_yaml_show_credits},
2923 {"statistics", handle_yaml_show_stats},
2927 static cmd_handler_t lookup_fn(char *key,
2928 struct lookup_cmd_hdlr_tbl *tbl)
2934 for (i = 0; tbl[i].name != NULL; i++) {
2935 if (strncmp(key, tbl[i].name, strlen(tbl[i].name)) == 0)
2942 static int lustre_yaml_cb_helper(char *f, struct lookup_cmd_hdlr_tbl *table,
2943 struct cYAML **show_rc, struct cYAML **err_rc)
2945 struct cYAML *tree, *item = NULL, *head, *child;
2947 char err_str[LNET_MAX_STR_LEN];
2948 int rc = LUSTRE_CFG_RC_NO_ERR, return_rc = LUSTRE_CFG_RC_NO_ERR;
2950 tree = cYAML_build_tree(f, NULL, 0, err_rc, false);
2952 return LUSTRE_CFG_RC_BAD_PARAM;
2954 child = tree->cy_child;
2955 while (child != NULL) {
2956 cb = lookup_fn(child->cy_string, table);
2958 snprintf(err_str, sizeof(err_str),
2959 "\"call back for '%s' not found\"",
2961 cYAML_build_error(LUSTRE_CFG_RC_BAD_PARAM, -1,
2962 "yaml", "helper", err_str, err_rc);
2966 if (cYAML_is_sequence(child)) {
2967 while ((head = cYAML_get_next_seq_item(child, &item))
2969 rc = cb(head, show_rc, err_rc);
2970 if (rc != LUSTRE_CFG_RC_NO_ERR)
2974 rc = cb(child, show_rc, err_rc);
2975 if (rc != LUSTRE_CFG_RC_NO_ERR)
2979 child = child->cy_next;
2983 cYAML_free_tree(tree);
2988 int lustre_yaml_config(char *f, struct cYAML **err_rc)
2990 return lustre_yaml_cb_helper(f, lookup_config_tbl,
2994 int lustre_yaml_del(char *f, struct cYAML **err_rc)
2996 return lustre_yaml_cb_helper(f, lookup_del_tbl,
3000 int lustre_yaml_show(char *f, struct cYAML **show_rc, struct cYAML **err_rc)
3002 return lustre_yaml_cb_helper(f, lookup_show_tbl,
3006 int lustre_lnet_send_dbg_task(enum lnet_dbg_task dbg_task,
3007 struct lnet_dbg_task_info *dbg_info,
3008 struct cYAML **show_rc,
3009 struct cYAML **err_rc)
3011 struct lnet_ioctl_dbg *dbg;
3012 struct lnet_dbg_task_info *info;
3013 int rc = LUSTRE_CFG_RC_NO_ERR;
3014 char err_str[LNET_MAX_STR_LEN];
3016 snprintf(err_str, sizeof(err_str), "\"success\"");
3018 dbg = calloc(1, sizeof(*dbg) + sizeof(*info));
3020 snprintf(err_str, sizeof(err_str), "\"out of memory\"");
3021 rc = LUSTRE_CFG_RC_OUT_OF_MEM;
3025 info = (struct lnet_dbg_task_info *)dbg->dbg_bulk;
3027 LIBCFS_IOC_INIT_V2(*dbg, dbg_hdr);
3029 dbg->dbg_task = dbg_task;
3031 memcpy(info, dbg_info, sizeof(*info));
3033 rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_DBG, dbg);
3038 "\"debug task failed %s\"", strerror(errno));
3043 cYAML_build_error(rc, -1, DBG_CMD,
3044 "debug", err_str, err_rc);