Example #1
0
int lustre_lnet_enable_routing(int enable, int seq_no, struct cYAML **err_rc)
{
	struct lnet_ioctl_config_data data;
	int rc = LUSTRE_CFG_RC_NO_ERR;
	char err_str[LNET_MAX_STR_LEN];

	snprintf(err_str, sizeof(err_str), "\"success\"");

	LIBCFS_IOC_INIT_V2(data, cfg_hdr);
	data.cfg_config_u.cfg_buffers.buf_enable = (enable) ? 1 : 0;

	rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_CONFIG_RTR, &data);
	if (rc != 0) {
		rc = -errno;
		snprintf(err_str,
			 sizeof(err_str),
			 "\"cannot %s routing %s\"",
			 (enable) ? "enable" : "disable", strerror(errno));
		goto out;
	}

out:
	cYAML_build_error(rc, seq_no,
			 (enable) ? ADD_CMD : DEL_CMD,
			 "routing", err_str, err_rc);

	return rc;
}
Example #2
0
/* We can't use the libptlctl library fns because they are not shared-memory
   safe with respect to the ioctl device (cur_dev) */
static int obj_ioctl(int cmd, struct obd_ioctl_data *data, int unpack)
{
        char *buf = NULL;
        int rc;

        //IOC_PACK(cmdname, data);
        if (obd_ioctl_pack(data, &buf, sizeof(*data))) {
                fprintf(stderr, "dev %d invalid ioctl\n", data->ioc_dev);
                rc = EINVAL;
                goto out;
        }

        rc = l_ioctl(OBD_DEV_ID, cmd, buf);

        if (unpack) {
                //IOC_UNPACK(argv[0], data);
                if (obd_ioctl_unpack(data, buf, sizeof(*data))) {
                        fprintf(stderr, "dev %d invalid reply\n", data->ioc_dev);
                        rc = EINVAL;
                        goto out;
                }
        }

out:
        if (buf)
                free(buf);
        return rc;
}
Example #3
0
int lustre_lnet_config_ni_system(bool up, bool load_ni_from_mod,
				 int seq_no, struct cYAML **err_rc)
{
	struct libcfs_ioctl_data data;
	unsigned int opc;
	int rc;
	char err_str[LNET_MAX_STR_LEN];

	snprintf(err_str, sizeof(err_str), "\"Success\"");

	LIBCFS_IOC_INIT(data);

	/* Reverse logic is used here in order not to change
	 * the lctl utility */
	data.ioc_flags = load_ni_from_mod ? 0 : 1;

	opc = up ? IOC_LIBCFS_CONFIGURE : IOC_LIBCFS_UNCONFIGURE;

	rc = l_ioctl(LNET_DEV_ID, opc, &data);
	if (rc != 0) {
		snprintf(err_str,
			sizeof(err_str),
			"\"LNet %s error: %s\"", (up) ? "configure" :
			"unconfigure", strerror(errno));
		rc = -errno;
	}

	cYAML_build_error(rc, seq_no, (up) ? CONFIG_CMD : UNCONFIG_CMD,
			  "lnet", err_str, err_rc);

	return rc;
}
Example #4
0
int jt_lfsck_stop(int argc, char **argv)
{
	struct obd_ioctl_data data;
	char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
	char device[MAX_OBD_NAME];
	char *optstring = "M:h";
	int opt, index, rc;

	memset(&data, 0, sizeof(data));
	memset(device, 0, MAX_OBD_NAME);

	/* Reset the 'optind' for the case of getopt_long() called multiple
	 * times under the same lctl. */
	optind = 0;
	while ((opt = getopt_long(argc, argv, optstring, long_opt_stop,
				  &index)) != EOF) {
		switch (opt) {
		case 'M':
			rc = lfsck_pack_dev(&data, device, optarg);
			if (rc != 0)
				return rc;
			break;
		case 'h':
			usage_stop();
			return 0;
		default:
			fprintf(stderr, "Invalid option, '-h' for help.\n");
			return -EINVAL;
		}
	}

	if (data.ioc_inlbuf4 == NULL) {
		if (lcfg_get_devname() != NULL) {
			rc = lfsck_pack_dev(&data, device, lcfg_get_devname());
			if (rc != 0)
				return rc;
		} else {
			fprintf(stderr,
				"Must specify device to stop LFSCK.\n");
			return -EINVAL;
		}
	}

	memset(buf, 0, sizeof(rawbuf));
	rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
	if (rc) {
		fprintf(stderr, "Fail to pack ioctl data: rc = %d.\n", rc);
		return rc;
	}

	rc = l_ioctl(OBD_DEV_ID, OBD_IOC_STOP_LFSCK, buf);
	if (rc < 0) {
		perror("Fail to stop LFSCK");
		return rc;
	}

	printf("Stopped LFSCK on the device %s.\n", device);
	return 0;
}
Example #5
0
int jt_dbg_mark_debug_buf(int argc, char **argv)
{
	static char		 scratch[MAX_MARK_SIZE] = "";
	struct libcfs_ioctl_data data;
	char			*text;
	int			 rc;

	memset(&data, 0, sizeof(data));

	if (argc > 1) {
		int count, max_size = sizeof(scratch) - 1;

		strncpy(scratch, argv[1], max_size);
		max_size -= strlen(argv[1]);
		for (count = 2; (count < argc) && (max_size > 1); count++) {
			strncat(scratch, " ", max_size);
			max_size -= 1;
			strncat(scratch, argv[count], max_size);
			max_size -= strlen(argv[count]);
		}
		scratch[sizeof(scratch) - 1] = '\0';
		text = scratch;
	} else {
		time_t now = time(NULL);
		text = ctime(&now);
	}

	data.ioc_inllen1 = strlen(text) + 1;
	data.ioc_inlbuf1 = text;

	if (libcfs_ioctl_pack(&data, &buf, max) != 0) {
		fprintf(stderr, "libcfs_ioctl_pack failed.\n");
		return -1;
	}

	rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_MARK_DEBUG, buf);
	if (rc) {
		fprintf(stderr, "IOC_LIBCFS_MARK_DEBUG failed: %s\n",
			strerror(errno));
		return -1;
	}
	return 0;
}
Example #6
0
int lustre_lnet_del_net(char *nw, int seq_no, struct cYAML **err_rc)
{
	struct lnet_ioctl_config_data data;
	__u32 net = LNET_NIDNET(LNET_NID_ANY);
	int rc = LUSTRE_CFG_RC_NO_ERR;
	char err_str[LNET_MAX_STR_LEN];

	snprintf(err_str, sizeof(err_str), "\"success\"");

	if (nw == NULL) {
		snprintf(err_str,
			 sizeof(err_str),
			 "\"missing mandatory parameter\"");
		rc = LUSTRE_CFG_RC_MISSING_PARAM;
		goto out;
	}

	net = libcfs_str2net(nw);
	if (net == LNET_NIDNET(LNET_NID_ANY)) {
		snprintf(err_str,
			 sizeof(err_str),
			 "\"cannot parse net '%s'\"", nw);
		rc = LUSTRE_CFG_RC_BAD_PARAM;
		goto out;
	}

	LIBCFS_IOC_INIT_V2(data, cfg_hdr);
	data.cfg_net = net;

	rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_DEL_NET, &data);
	if (rc != 0) {
		rc = -errno;
		snprintf(err_str,
			 sizeof(err_str),
			 "\"cannot delete network: %s\"", strerror(errno));
		goto out;
	}

out:
	cYAML_build_error(rc, seq_no, DEL_CMD, "net", err_str, err_rc);

	return rc;
}
Example #7
0
int lustre_lnet_config_buffers(int tiny, int small, int large, int seq_no,
			       struct cYAML **err_rc)
{
	struct lnet_ioctl_config_data data;
	int rc = LUSTRE_CFG_RC_NO_ERR;
	char err_str[LNET_MAX_STR_LEN];

	snprintf(err_str, sizeof(err_str), "\"success\"");

	/* -1 indicates to ignore changes to this field */
	if (tiny < -1 || small < -1 || large < -1) {
		snprintf(err_str,
			 sizeof(err_str),
			 "\"tiny, small and large must be >= 0\"");
		rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
		goto out;
	}

	LIBCFS_IOC_INIT_V2(data, cfg_hdr);
	data.cfg_config_u.cfg_buffers.buf_tiny = tiny;
	data.cfg_config_u.cfg_buffers.buf_small = small;
	data.cfg_config_u.cfg_buffers.buf_large = large;

	rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_ADD_BUF, &data);
	if (rc != 0) {
		rc = -errno;
		snprintf(err_str,
			 sizeof(err_str),
			 "\"cannot configure buffers: %s\"", strerror(errno));
		goto out;
	}

out:
	cYAML_build_error(rc, seq_no, ADD_CMD, "buf", err_str, err_rc);

	return rc;
}
Example #8
0
int jt_dbg_panic(int argc, char **argv)
{
	int			 rc;
	struct libcfs_ioctl_data data;

	if (argc != 1) {
		fprintf(stderr, "usage: %s\n", argv[0]);
		return 0;
	}

	memset(&data, 0, sizeof(data));
	if (libcfs_ioctl_pack(&data, &buf, max) != 0) {
		fprintf(stderr, "libcfs_ioctl_pack failed.\n");
		return -1;
	}

	rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_PANIC, buf);
	if (rc) {
		fprintf(stderr, "IOC_LIBCFS_PANIC failed: %s\n",
			strerror(errno));
		return -1;
	}
	return 0;
}
Example #9
0
int lustre_lnet_config_route(char *nw, char *gw, int hops, int prio,
			     int seq_no, struct cYAML **err_rc)
{
	struct lnet_ioctl_config_data data;
	lnet_nid_t gateway_nid;
	int rc = LUSTRE_CFG_RC_NO_ERR;
	__u32 net = LNET_NIDNET(LNET_NID_ANY);
	char err_str[LNET_MAX_STR_LEN];

	snprintf(err_str, sizeof(err_str), "\"Success\"");

	if (nw == NULL || gw == NULL) {
		snprintf(err_str,
			 sizeof(err_str),
			 "\"missing mandatory parameter(s): '%s'\"",
			 (nw == NULL && gw == NULL) ? "network, gateway" :
			 (nw == NULL) ? "network" : "gateway");
		rc = LUSTRE_CFG_RC_MISSING_PARAM;
		goto out;
	}

	net = libcfs_str2net(nw);
	if (net == LNET_NIDNET(LNET_NID_ANY)) {
		snprintf(err_str,
			 sizeof(err_str),
			 "\"cannot parse net %s\"", nw);
		rc = LUSTRE_CFG_RC_BAD_PARAM;
		goto out;
	}

	if (LNET_NETTYP(net) == CIBLND    ||
	    LNET_NETTYP(net) == OPENIBLND ||
	    LNET_NETTYP(net) == IIBLND    ||
	    LNET_NETTYP(net) == VIBLND) {
		snprintf(err_str,
			 sizeof(err_str),
			 "\"obselete LNet type '%s'\"", libcfs_lnd2str(net));
		rc = LUSTRE_CFG_RC_BAD_PARAM;
		goto out;
	}

	gateway_nid = libcfs_str2nid(gw);
	if (gateway_nid == LNET_NID_ANY) {
		snprintf(err_str,
			sizeof(err_str),
			"\"cannot parse gateway NID '%s'\"", gw);
		rc = LUSTRE_CFG_RC_BAD_PARAM;
		goto out;
	}

	if (hops == -1) {
		/* hops is undefined */
		hops = LNET_UNDEFINED_HOPS;
	} else if (hops < 1 || hops > 255) {
		snprintf(err_str,
			sizeof(err_str),
			"\"invalid hop count %d, must be between 1 and 255\"",
			hops);
		rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
		goto out;
	}

	if (prio == -1) {
		prio = 0;
	} else if (prio < 0) {
		snprintf(err_str,
			 sizeof(err_str),
			"\"invalid priority %d, must be greater than 0\"",
			prio);
		rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
		goto out;
	}

	LIBCFS_IOC_INIT_V2(data, cfg_hdr);
	data.cfg_net = net;
	data.cfg_config_u.cfg_route.rtr_hop = hops;
	data.cfg_config_u.cfg_route.rtr_priority = prio;
	data.cfg_nid = gateway_nid;

	rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_ADD_ROUTE, &data);
	if (rc != 0) {
		rc = -errno;
		snprintf(err_str,
			 sizeof(err_str),
			 "\"cannot add route: %s\"", strerror(errno));
		goto out;
	}

out:
	cYAML_build_error(rc, seq_no, ADD_CMD, "route", err_str, err_rc);

	return rc;
}
Example #10
0
int lustre_lnet_show_routing(int seq_no, struct cYAML **show_rc,
			     struct cYAML **err_rc)
{
	struct lnet_ioctl_config_data *data;
	struct lnet_ioctl_pool_cfg *pool_cfg = NULL;
	int rc = LUSTRE_CFG_RC_OUT_OF_MEM;
	int l_errno = 0;
	char *buf;
	char *pools[LNET_NRBPOOLS] = {"tiny", "small", "large"};
	int buf_count[LNET_NRBPOOLS] = {0};
	struct cYAML *root = NULL, *pools_node = NULL,
		     *type_node = NULL, *item = NULL, *cpt = NULL,
		     *first_seq = NULL, *buffers = NULL;
	int i, j;
	char err_str[LNET_MAX_STR_LEN];
	char node_name[LNET_MAX_STR_LEN];
	bool exist = false;

	snprintf(err_str, sizeof(err_str), "\"out of memory\"");

	buf = calloc(1, sizeof(*data) + sizeof(*pool_cfg));
	if (buf == NULL)
		goto out;

	data = (struct lnet_ioctl_config_data *)buf;

	root = cYAML_create_object(NULL, NULL);
	if (root == NULL)
		goto out;

	pools_node = cYAML_create_seq(root, "routing");
	if (pools_node == NULL)
		goto out;

	for (i = 0;; i++) {
		LIBCFS_IOC_INIT_V2(*data, cfg_hdr);
		data->cfg_hdr.ioc_len = sizeof(struct lnet_ioctl_config_data) +
					sizeof(struct lnet_ioctl_pool_cfg);
		data->cfg_count = i;

		rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_BUF, data);
		if (rc != 0) {
			l_errno = errno;
			break;
		}

		exist = true;

		pool_cfg = (struct lnet_ioctl_pool_cfg *)data->cfg_bulk;

		snprintf(node_name, sizeof(node_name), "cpt[%d]", i);
		item = cYAML_create_seq_item(pools_node);
		if (item == NULL)
			goto out;

		if (first_seq == NULL)
			first_seq = item;

		cpt = cYAML_create_object(item, node_name);
		if (cpt == NULL)
			goto out;

		/* create the tree  and print */
		for (j = 0; j < LNET_NRBPOOLS; j++) {
			type_node = cYAML_create_object(cpt, pools[j]);
			if (type_node == NULL)
				goto out;
			if (cYAML_create_number(type_node, "npages",
						pool_cfg->pl_pools[j].pl_npages)
			    == NULL)
				goto out;
			if (cYAML_create_number(type_node, "nbuffers",
						pool_cfg->pl_pools[j].
						  pl_nbuffers) == NULL)
				goto out;
			if (cYAML_create_number(type_node, "credits",
						pool_cfg->pl_pools[j].
						   pl_credits) == NULL)
				goto out;
			if (cYAML_create_number(type_node, "mincredits",
						pool_cfg->pl_pools[j].
						   pl_mincredits) == NULL)
				goto out;
			/* keep track of the total count for each of the
			 * tiny, small and large buffers */
			buf_count[j] += pool_cfg->pl_pools[j].pl_nbuffers;
		}
	}

	if (pool_cfg != NULL) {
		item = cYAML_create_seq_item(pools_node);
		if (item == NULL)
			goto out;

		if (cYAML_create_number(item, "enable", pool_cfg->pl_routing) ==
		    NULL)
			goto out;
	}

	/* create a buffers entry in the show. This is necessary so that
	 * if the YAML output is used to configure a node, the buffer
	 * configuration takes hold */
	buffers = cYAML_create_object(root, "buffers");
	if (buffers == NULL)
		goto out;

	for (i = 0; i < LNET_NRBPOOLS; i++) {
		if (cYAML_create_number(buffers, pools[i], buf_count[i]) == NULL)
			goto out;
	}

	if (show_rc == NULL)
		cYAML_print_tree(root);

	if (l_errno != ENOENT) {
		snprintf(err_str,
			 sizeof(err_str),
			 "\"cannot get routing information: %s\"",
			 strerror(l_errno));
		rc = -l_errno;
		goto out;
	} else
		rc = LUSTRE_CFG_RC_NO_ERR;

	snprintf(err_str, sizeof(err_str), "\"success\"");
	rc = LUSTRE_CFG_RC_NO_ERR;

out:
	free(buf);
	if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR || !exist) {
		cYAML_free_tree(root);
	} else if (show_rc != NULL && *show_rc != NULL) {
		struct cYAML *routing_node;
		/* there should exist only one routing block and one
		 * buffers block. If there already exists a previous one
		 * then don't add another */
		routing_node = cYAML_get_object_item(*show_rc, "routing");
		if (routing_node == NULL) {
			cYAML_insert_sibling((*show_rc)->cy_child,
						root->cy_child);
			free(root);
		} else {
			cYAML_free_tree(root);
		}
	} else {
		*show_rc = root;
	}

	cYAML_build_error(rc, seq_no, SHOW_CMD, "routing", err_str, err_rc);

	return rc;
}
Example #11
0
int jt_lfsck_start(int argc, char **argv)
{
	struct obd_ioctl_data data;
	char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
	char device[MAX_OBD_NAME];
	struct lfsck_start start;
	char *optstring = "Ac::C::e:hM:n::ors:t:w:";
	int opt, index, rc, val, i;

	memset(&data, 0, sizeof(data));
	memset(&start, 0, sizeof(start));
	memset(device, 0, MAX_OBD_NAME);
	start.ls_version = LFSCK_VERSION_V1;
	start.ls_active = LFSCK_TYPES_ALL;

	/* Reset the 'optind' for the case of getopt_long() called multiple
	 * times under the same lctl. */
	optind = 0;
	while ((opt = getopt_long(argc, argv, optstring, long_opt_start,
				  &index)) != EOF) {
		switch (opt) {
		case 'A':
			start.ls_flags |= LPF_ALL_TGT | LPF_BROADCAST;
			break;
		case 'c':
			if (optarg == NULL || strcmp(optarg, "on") == 0) {
				start.ls_flags |= LPF_CREATE_OSTOBJ;
			} else if (strcmp(optarg, "off") != 0) {
				fprintf(stderr, "invalid switch: -c '%s'. "
					"valid switches are:\n"
					"empty ('on'), or 'off' without space. "
					"For example:\n"
					"'-c', '-con', '-coff'\n", optarg);
				return -EINVAL;
			}
			start.ls_valid |= LSV_CREATE_OSTOBJ;
			break;
		case 'C':
			if (optarg == NULL || strcmp(optarg, "on") == 0) {
				start.ls_flags |= LPF_CREATE_MDTOBJ;
			} else if (strcmp(optarg, "off") != 0) {
				fprintf(stderr, "invalid switch: -C '%s'. "
					"valid switches are:\n"
					"empty ('on'), or 'off' without space. "
					"For example:\n"
					"'-C', '-Con', '-Coff'\n", optarg);
				return -EINVAL;
			}
			start.ls_valid |= LSV_CREATE_MDTOBJ;
			break;
		case 'e':
			if (strcmp(optarg, "abort") == 0) {
				start.ls_flags |= LPF_FAILOUT;
			} else if (strcmp(optarg, "continue") != 0) {
				fprintf(stderr, "invalid error mode: -e '%s'."
					"valid modes are: "
					"'continue' or 'abort'.\n", optarg);
				return -EINVAL;
			}
			start.ls_valid |= LSV_ERROR_HANDLE;
			break;
		case 'h':
			usage_start();
			return 0;
		case 'M':
			rc = lfsck_pack_dev(&data, device, optarg);
			if (rc != 0)
				return rc;
			break;
		case 'n':
			if (optarg == NULL || strcmp(optarg, "on") == 0) {
				start.ls_flags |= LPF_DRYRUN;
			} else if (strcmp(optarg, "off") != 0) {
				fprintf(stderr, "invalid switch: -n '%s'. "
					"valid switches are:\n"
					"empty ('on'), or 'off' without space. "
					"For example:\n"
					"'-n', '-non', '-noff'\n", optarg);
				return -EINVAL;
			}
			start.ls_valid |= LSV_DRYRUN;
			break;
		case 'o':
			start.ls_flags |= LPF_ALL_TGT | LPF_BROADCAST |
					  LPF_OST_ORPHAN;
			break;
		case 'r':
			start.ls_flags |= LPF_RESET;
			break;
		case 's':
			val = atoi(optarg);
			start.ls_speed_limit = val;
			start.ls_valid |= LSV_SPEED_LIMIT;
			break;
		case 't': {
			char *typename;

			if (start.ls_active == LFSCK_TYPES_ALL)
				start.ls_active = 0;
			while ((typename = strsep(&optarg, ",")) != NULL) {
				enum lfsck_type type;

				type = lfsck_name2type(typename);
				if (type == -1)
					goto bad_type;
				start.ls_active |= type;
			}
			break;
bad_type:
			fprintf(stderr, "invalid check type -t '%s'. "
				"valid types are:\n", typename);
			for (i = 0; lfsck_types_names[i].ltn_name != NULL; i++)
				fprintf(stderr, "%s%s", i != 0 ? "," : "",
					lfsck_types_names[i].ltn_name);
			fprintf(stderr, "\n");
			return -EINVAL;
		}
		case 'w':
			val = atoi(optarg);
			if (val < 1 || val > LFSCK_ASYNC_WIN_MAX) {
				fprintf(stderr,
					"Invalid async window size that "
					"may cause memory issues. The valid "
					"range is [1 - %u].\n",
					LFSCK_ASYNC_WIN_MAX);
				return -EINVAL;
			}

			start.ls_async_windows = val;
			start.ls_valid |= LSV_ASYNC_WINDOWS;
			break;
		default:
			fprintf(stderr, "Invalid option, '-h' for help.\n");
			return -EINVAL;
		}
	}

	if (start.ls_active == LFSCK_TYPES_ALL)
		start.ls_active = LFSCK_TYPES_DEF;

	if (data.ioc_inlbuf4 == NULL) {
		if (lcfg_get_devname() != NULL) {
			rc = lfsck_pack_dev(&data, device, lcfg_get_devname());
			if (rc != 0)
				return rc;
		} else {
			fprintf(stderr,
				"Must specify device to start LFSCK.\n");
			return -EINVAL;
		}
	}

	data.ioc_inlbuf1 = (char *)&start;
	data.ioc_inllen1 = sizeof(start);
	memset(buf, 0, sizeof(rawbuf));
	rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
	if (rc) {
		fprintf(stderr, "Fail to pack ioctl data: rc = %d.\n", rc);
		return rc;
	}

	rc = l_ioctl(OBD_DEV_ID, OBD_IOC_START_LFSCK, buf);
	if (rc < 0) {
		perror("Fail to start LFSCK");
		return rc;
	}

	obd_ioctl_unpack(&data, buf, sizeof(rawbuf));
	printf("Started LFSCK on the device %s: scrub", device);
	for (i = 0; lfsck_types_names[i].ltn_name != NULL; i++) {
		if (start.ls_active & lfsck_types_names[i].ltn_type) {
			printf(" %s", lfsck_types_names[i].ltn_name);
			start.ls_active &= ~lfsck_types_names[i].ltn_type;
		}
	}
	if (start.ls_active != 0)
		printf(" unknown(0x%x)", start.ls_active);
	printf("\n");

	return 0;
}
Example #12
0
int lustre_lnet_config_net(char *net, char *intf, char *ip2net,
			   int peer_to, int peer_cr, int peer_buf_cr,
			   int credits, char *smp, int seq_no,
			   struct lnet_ioctl_config_lnd_tunables *lnd_tunables,
			   struct cYAML **err_rc)
{
	struct lnet_ioctl_config_lnd_tunables *lnd = NULL;
	struct lnet_ioctl_config_data *data;
	size_t ioctl_size = sizeof(*data);
	char buf[LNET_MAX_STR_LEN];
	int rc = LUSTRE_CFG_RC_NO_ERR;
	char err_str[LNET_MAX_STR_LEN];

	snprintf(err_str, sizeof(err_str), "\"success\"");

	/* No need to register lo */
	if (net != NULL && !strcmp(net, "lo"))
		return 0;

	if (ip2net == NULL && (intf == NULL || net == NULL)) {
		snprintf(err_str,
			 sizeof(err_str),
			 "\"mandatory parameter '%s' not specified."
			 " Optionally specify ip2net parameter\"",
			 (intf == NULL && net == NULL) ? "net, if" :
			 (intf == NULL) ? "if" : "net");
		rc = LUSTRE_CFG_RC_MISSING_PARAM;
		goto out;
	}

	if (peer_to != -1 && peer_to <= 0) {
		snprintf(err_str,
			 sizeof(err_str),
			 "\"peer timeout %d, must be greater than 0\"",
			 peer_to);
		rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
		goto out;
	}

	if (ip2net != NULL && strlen(ip2net) >= sizeof(buf)) {
		snprintf(err_str,
			 sizeof(err_str),
			 "\"ip2net string too long %d\"",
				(int)strlen(ip2net));
		rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
		goto out;
	}

	if (lnd_tunables != NULL)
		ioctl_size += sizeof(*lnd_tunables);

	data = calloc(1, ioctl_size);
	if (data == NULL)
		goto out;

	if (ip2net == NULL)
		snprintf(buf, sizeof(buf) - 1, "%s(%s)%s",
			net, intf,
			(smp) ? smp : "");

	LIBCFS_IOC_INIT_V2(*data, cfg_hdr);
	strncpy(data->cfg_config_u.cfg_net.net_intf,
		(ip2net != NULL) ? ip2net : buf, sizeof(buf));
	data->cfg_config_u.cfg_net.net_peer_timeout = peer_to;
	data->cfg_config_u.cfg_net.net_peer_tx_credits = peer_cr;
	data->cfg_config_u.cfg_net.net_peer_rtr_credits = peer_buf_cr;
	data->cfg_config_u.cfg_net.net_max_tx_credits = credits;
	/* Add in tunable settings if available */
	if (lnd_tunables != NULL) {
		lnd = (struct lnet_ioctl_config_lnd_tunables *)data->cfg_bulk;

		data->cfg_hdr.ioc_len = ioctl_size;
		memcpy(lnd, lnd_tunables, sizeof(*lnd_tunables));
	}

	rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_ADD_NET, data);
	if (rc < 0) {
		rc = -errno;
		snprintf(err_str,
			 sizeof(err_str),
			 "\"cannot add network: %s\"", strerror(errno));
	}
	free(data);

out:
	cYAML_build_error(rc, seq_no, ADD_CMD, "net", err_str, err_rc);

	return rc;
}
Example #13
0
int lustre_lnet_show_route(char *nw, char *gw, int hops, int prio, int detail,
			   int seq_no, struct cYAML **show_rc,
			   struct cYAML **err_rc)
{
	struct lnet_ioctl_config_data data;
	lnet_nid_t gateway_nid;
	int rc = LUSTRE_CFG_RC_OUT_OF_MEM;
	int l_errno = 0;
	__u32 net = LNET_NIDNET(LNET_NID_ANY);
	int i;
	struct cYAML *root = NULL, *route = NULL, *item = NULL;
	struct cYAML *first_seq = NULL;
	char err_str[LNET_MAX_STR_LEN];
	bool exist = false;

	snprintf(err_str, sizeof(err_str),
		 "\"out of memory\"");

	if (nw != NULL) {
		net = libcfs_str2net(nw);
		if (net == LNET_NIDNET(LNET_NID_ANY)) {
			snprintf(err_str,
				 sizeof(err_str),
				 "\"cannot parse net '%s'\"", nw);
			rc = LUSTRE_CFG_RC_BAD_PARAM;
			goto out;
		}

		if (LNET_NETTYP(net) == CIBLND    ||
		    LNET_NETTYP(net) == OPENIBLND ||
		    LNET_NETTYP(net) == IIBLND    ||
		    LNET_NETTYP(net) == VIBLND) {
			snprintf(err_str,
				 sizeof(err_str),
				 "\"obsolete LNet type '%s'\"",
				 libcfs_lnd2str(net));
			rc = LUSTRE_CFG_RC_BAD_PARAM;
			goto out;
		}
	} else {
		/* show all routes without filtering on net */
		net = LNET_NIDNET(LNET_NID_ANY);
	}

	if (gw != NULL) {
		gateway_nid = libcfs_str2nid(gw);
		if (gateway_nid == LNET_NID_ANY) {
			snprintf(err_str,
				 sizeof(err_str),
				 "\"cannot parse gateway NID '%s'\"", gw);
			rc = LUSTRE_CFG_RC_BAD_PARAM;
			goto out;
		}
	} else
		/* show all routes with out filtering on gateway */
		gateway_nid = LNET_NID_ANY;

	if ((hops < 1 && hops != -1) || hops > 255) {
		snprintf(err_str,
			 sizeof(err_str),
			 "\"invalid hop count %d, must be between 0 and 256\"",
			 hops);
		rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM;
		goto out;
	}

	/* create struct cYAML root object */
	root = cYAML_create_object(NULL, NULL);
	if (root == NULL)
		goto out;

	route = cYAML_create_seq(root, "route");
	if (route == NULL)
		goto out;

	for (i = 0;; i++) {
		LIBCFS_IOC_INIT_V2(data, cfg_hdr);
		data.cfg_count = i;

		rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_ROUTE, &data);
		if (rc != 0) {
			l_errno = errno;
			break;
		}

		/* filter on provided data */
		if (net != LNET_NIDNET(LNET_NID_ANY) &&
		    net != data.cfg_net)
			continue;

		if (gateway_nid != LNET_NID_ANY &&
		    gateway_nid != data.cfg_nid)
			continue;

		if (hops != -1 &&
		    hops != data.cfg_config_u.cfg_route.rtr_hop)
			continue;

		if (prio != -1 &&
		    prio != data.cfg_config_u.cfg_route.rtr_priority)
			continue;

		/* default rc to -1 incase we hit the goto */
		rc = -1;
		exist = true;

		item = cYAML_create_seq_item(route);
		if (item == NULL)
			goto out;

		if (first_seq == NULL)
			first_seq = item;

		if (cYAML_create_string(item, "net",
					libcfs_net2str(data.cfg_net)) == NULL)
			goto out;

		if (cYAML_create_string(item, "gateway",
					libcfs_nid2str(data.cfg_nid)) == NULL)
			goto out;

		if (detail) {
			if (cYAML_create_number(item, "hop",
						data.cfg_config_u.cfg_route.
							rtr_hop) ==
			    NULL)
				goto out;

			if (cYAML_create_number(item, "priority",
						data.cfg_config_u.
						cfg_route.rtr_priority) == NULL)
				goto out;

			if (cYAML_create_string(item, "state",
						data.cfg_config_u.cfg_route.
							rtr_flags ?
						"up" : "down") == NULL)
				goto out;
		}
	}

	/* print output iff show_rc is not provided */
	if (show_rc == NULL)
		cYAML_print_tree(root);

	if (l_errno != ENOENT) {
		snprintf(err_str,
			 sizeof(err_str),
			 "\"cannot get routes: %s\"",
			 strerror(l_errno));
		rc = -l_errno;
		goto out;
	} else
		rc = LUSTRE_CFG_RC_NO_ERR;

	snprintf(err_str, sizeof(err_str), "\"success\"");
out:
	if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR || !exist) {
		cYAML_free_tree(root);
	} else if (show_rc != NULL && *show_rc != NULL) {
		struct cYAML *show_node;
		/* find the route node, if one doesn't exist then
		 * insert one.  Otherwise add to the one there
		 */
		show_node = cYAML_get_object_item(*show_rc, "route");
		if (show_node != NULL && cYAML_is_sequence(show_node)) {
			cYAML_insert_child(show_node, first_seq);
			free(route);
			free(root);
		} else if (show_node == NULL) {
			cYAML_insert_sibling((*show_rc)->cy_child,
						route);
			free(root);
		} else {
			cYAML_free_tree(root);
		}
	} else {
		*show_rc = root;
	}

	cYAML_build_error(rc, seq_no, SHOW_CMD, "route", err_str, err_rc);

	return rc;
}
Example #14
0
int lustre_lnet_del_route(char *nw, char *gw,
			  int seq_no, struct cYAML **err_rc)
{
	struct lnet_ioctl_config_data data;
	lnet_nid_t gateway_nid;
	int rc = LUSTRE_CFG_RC_NO_ERR;
	__u32 net = LNET_NIDNET(LNET_NID_ANY);
	char err_str[LNET_MAX_STR_LEN];

	snprintf(err_str, sizeof(err_str), "\"Success\"");

	if (nw == NULL || gw == NULL) {
		snprintf(err_str,
			 sizeof(err_str),
			 "\"missing mandatory parameter(s): '%s'\"",
			 (nw == NULL && gw == NULL) ? "network, gateway" :
			 (nw == NULL) ? "network" : "gateway");
		rc = LUSTRE_CFG_RC_MISSING_PARAM;
		goto out;
	}

	net = libcfs_str2net(nw);
	if (net == LNET_NIDNET(LNET_NID_ANY)) {
		snprintf(err_str,
			 sizeof(err_str),
			 "\"cannot parse net '%s'\"", nw);
		rc = LUSTRE_CFG_RC_BAD_PARAM;
		goto out;
	}

	if (LNET_NETTYP(net) == CIBLND    ||
	    LNET_NETTYP(net) == OPENIBLND ||
	    LNET_NETTYP(net) == IIBLND    ||
	    LNET_NETTYP(net) == VIBLND) {
		snprintf(err_str,
			 sizeof(err_str),
			 "\"obselete LNet type '%s'\"", libcfs_lnd2str(net));
		rc = LUSTRE_CFG_RC_BAD_PARAM;
		goto out;
	}

	gateway_nid = libcfs_str2nid(gw);
	if (gateway_nid == LNET_NID_ANY) {
		snprintf(err_str,
			 sizeof(err_str),
			 "\"cannot parse gateway NID '%s'\"", gw);
		rc = LUSTRE_CFG_RC_BAD_PARAM;
		goto out;
	}

	LIBCFS_IOC_INIT_V2(data, cfg_hdr);
	data.cfg_net = net;
	data.cfg_nid = gateway_nid;

	rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_DEL_ROUTE, &data);
	if (rc != 0) {
		rc = -errno;
		snprintf(err_str,
			 sizeof(err_str),
			 "\"cannot delete route: %s\"", strerror(errno));
		goto out;
	}

out:
	cYAML_build_error(rc, seq_no, DEL_CMD, "route", err_str, err_rc);

	return rc;
}
Example #15
0
int lustre_lnet_show_stats(int seq_no, struct cYAML **show_rc,
			   struct cYAML **err_rc)
{
	struct lnet_ioctl_lnet_stats data;
	int rc = LUSTRE_CFG_RC_OUT_OF_MEM;
	int l_errno;
	char err_str[LNET_MAX_STR_LEN];
	struct cYAML *root = NULL, *stats = NULL;

	snprintf(err_str, sizeof(err_str), "\"out of memory\"");

	LIBCFS_IOC_INIT_V2(data, st_hdr);

	rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_LNET_STATS, &data);
	if (rc != 0) {
		l_errno = errno;
		snprintf(err_str,
			 sizeof(err_str),
			 "\"cannot get lnet statistics: %s\"",
			 strerror(l_errno));
		rc = -l_errno;
		goto out;
	}

	root = cYAML_create_object(NULL, NULL);
	if (root == NULL)
		goto out;

	stats = cYAML_create_object(root, "statistics");
	if (stats == NULL)
		goto out;

	if (cYAML_create_number(stats, "msgs_alloc",
				data.st_cntrs.msgs_alloc) == NULL)
		goto out;

	if (cYAML_create_number(stats, "msgs_max",
				data.st_cntrs.msgs_max) == NULL)
		goto out;

	if (cYAML_create_number(stats, "errors",
				data.st_cntrs.errors) == NULL)
		goto out;

	if (cYAML_create_number(stats, "send_count",
				data.st_cntrs.send_count) == NULL)
		goto out;

	if (cYAML_create_number(stats, "recv_count",
				data.st_cntrs.recv_count) == NULL)
		goto out;

	if (cYAML_create_number(stats, "route_count",
				data.st_cntrs.route_count) == NULL)
		goto out;

	if (cYAML_create_number(stats, "drop_count",
				data.st_cntrs.drop_count) == NULL)
		goto out;

	if (cYAML_create_number(stats, "send_length",
				data.st_cntrs.send_length) == NULL)
		goto out;

	if (cYAML_create_number(stats, "recv_length",
				data.st_cntrs.recv_length) == NULL)
		goto out;

	if (cYAML_create_number(stats, "route_length",
				data.st_cntrs.route_length) == NULL)
		goto out;

	if (cYAML_create_number(stats, "drop_length",
				data.st_cntrs.drop_length) == NULL)
		goto out;

	if (show_rc == NULL)
		cYAML_print_tree(root);

	snprintf(err_str, sizeof(err_str), "\"success\"");
out:
	if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR) {
		cYAML_free_tree(root);
	} else if (show_rc != NULL && *show_rc != NULL) {
		cYAML_insert_sibling((*show_rc)->cy_child,
					root->cy_child);
		free(root);
	} else {
		*show_rc = root;
	}

	cYAML_build_error(rc, seq_no, SHOW_CMD, "statistics", err_str, err_rc);

	return rc;
}
Example #16
0
int lustre_lnet_show_peer_credits(int seq_no, struct cYAML **show_rc,
				  struct cYAML **err_rc)
{
	struct lnet_ioctl_peer peer_info;
	int rc = LUSTRE_CFG_RC_OUT_OF_MEM, ncpt = 0, i = 0, j = 0;
	int l_errno = 0;
	struct cYAML *root = NULL, *peer = NULL, *first_seq = NULL,
		     *peer_root = NULL;
	char err_str[LNET_MAX_STR_LEN];
	bool ncpt_set = false;

	snprintf(err_str, sizeof(err_str),
		 "\"out of memory\"");

	/* create struct cYAML root object */
	root = cYAML_create_object(NULL, NULL);
	if (root == NULL)
		goto out;

	peer_root = cYAML_create_seq(root, "peer");
	if (peer_root == NULL)
		goto out;

	do {
		for (i = 0;; i++) {
			LIBCFS_IOC_INIT_V2(peer_info, pr_hdr);
			peer_info.pr_count = i;
			peer_info.pr_lnd_u.pr_peer_credits.cr_ncpt = j;
			rc = l_ioctl(LNET_DEV_ID,
				     IOC_LIBCFS_GET_PEER_INFO, &peer_info);
			if (rc != 0) {
				l_errno = errno;
				break;
			}

			if (ncpt_set != 0) {
				ncpt = peer_info.pr_lnd_u.pr_peer_credits.
					cr_ncpt;
				ncpt_set = true;
			}

			peer = cYAML_create_seq_item(peer_root);
			if (peer == NULL)
				goto out;

			if (first_seq == NULL)
				first_seq = peer;

			if (cYAML_create_string(peer, "nid",
						libcfs_nid2str
						 (peer_info.pr_nid)) == NULL)
				goto out;

			if (cYAML_create_string(peer, "state",
						peer_info.pr_lnd_u.
						  pr_peer_credits.
							cr_aliveness) ==
			    NULL)
				goto out;

			if (cYAML_create_number(peer, "refcount",
						peer_info.pr_lnd_u.
						  pr_peer_credits.
							cr_refcount) == NULL)
				goto out;

			if (cYAML_create_number(peer, "max_ni_tx_credits",
						peer_info.pr_lnd_u.
						  pr_peer_credits.
						    cr_ni_peer_tx_credits)
			    == NULL)
				goto out;

			if (cYAML_create_number(peer, "available_tx_credits",
						peer_info.pr_lnd_u.
						  pr_peer_credits.
						    cr_peer_tx_credits)
			    == NULL)
				goto out;

			if (cYAML_create_number(peer, "available_rtr_credits",
						peer_info.pr_lnd_u.
						  pr_peer_credits.
						    cr_peer_rtr_credits)
			    == NULL)
				goto out;

			if (cYAML_create_number(peer, "min_rtr_credits",
						peer_info.pr_lnd_u.
						  pr_peer_credits.
						    cr_peer_min_rtr_credits)
			    == NULL)
				goto out;

			if (cYAML_create_number(peer, "tx_q_num_of_buf",
						peer_info.pr_lnd_u.
						  pr_peer_credits.
						    cr_peer_tx_qnob)
			    == NULL)
				goto out;
		}

		if (l_errno != ENOENT) {
			snprintf(err_str,
				sizeof(err_str),
				"\"cannot get peer information: %s\"",
				strerror(l_errno));
			rc = -l_errno;
			goto out;
		}

		j++;
	} while (j < ncpt);

	/* print output iff show_rc is not provided */
	if (show_rc == NULL)
		cYAML_print_tree(root);

	snprintf(err_str, sizeof(err_str), "\"success\"");
	rc = LUSTRE_CFG_RC_NO_ERR;

out:
	if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR) {
		cYAML_free_tree(root);
	} else if (show_rc != NULL && *show_rc != NULL) {
		struct cYAML *show_node;
		/* find the peer node, if one doesn't exist then
		 * insert one.  Otherwise add to the one there
		 */
		show_node = cYAML_get_object_item(*show_rc,
						  "peer_credits");
		if (show_node != NULL && cYAML_is_sequence(show_node)) {
			cYAML_insert_child(show_node, first_seq);
			free(peer_root);
			free(root);
		} else if (show_node == NULL) {
			cYAML_insert_sibling((*show_rc)->cy_child,
					     peer_root);
			free(root);
		} else {
			cYAML_free_tree(root);
		}
	} else {
		*show_rc = root;
	}

	cYAML_build_error(rc, seq_no, SHOW_CMD, "peer_credits", err_str,
			  err_rc);

	return rc;
}
Example #17
0
int jt_lfsck_start(int argc, char **argv)
{
	struct obd_ioctl_data data;
	char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
	char device[MAX_OBD_NAME];
	struct lfsck_start start;
	char *optstring = "M:e:hn:rs:t:";
	int opt, index, rc, val, i, type;

	memset(&data, 0, sizeof(data));
	memset(&start, 0, sizeof(start));
	memset(device, 0, MAX_OBD_NAME);
	start.ls_version = LFSCK_VERSION_V1;
	start.ls_active = LFSCK_TYPES_DEF;

	/* Reset the 'optind' for the case of getopt_long() called multiple
	 * times under the same lctl. */
	optind = 0;
	while ((opt = getopt_long(argc, argv, optstring, long_opt_start,
				  &index)) != EOF) {
		switch (opt) {
		case 'M':
			rc = lfsck_pack_dev(&data, device, optarg);
			if (rc != 0)
				return rc;
			break;
		case 'e':
			if (strcmp(optarg, "abort") == 0) {
				start.ls_flags |= LPF_FAILOUT;
			} else if (strcmp(optarg, "continue") != 0) {
				fprintf(stderr, "Invalid error handler: %s. "
					"The valid value should be: 'continue'"
					"(default) or 'abort'.\n", optarg);
				return -EINVAL;
			}
			start.ls_valid |= LSV_ERROR_HANDLE;
			break;
		case 'h':
			usage_start();
			return 0;
		case 'n':
			if (strcmp(optarg, "on") == 0) {
				start.ls_flags |= LPF_DRYRUN;
			} else if (strcmp(optarg, "off") != 0) {
				fprintf(stderr, "Invalid dryrun switch: %s. "
					"The valid value shou be: 'off'"
					"(default) or 'on'\n", optarg);
				return -EINVAL;
			}
			start.ls_valid |= LSV_DRYRUN;
			break;
		case 'r':
			start.ls_flags |= LPF_RESET;
			break;
		case 's':
			val = atoi(optarg);
			start.ls_speed_limit = val;
			start.ls_valid |= LSV_SPEED_LIMIT;
			break;
		case 't': {
			char *str = optarg, *p, c;

			start.ls_active = 0;
			while (*str) {
				while (*str == ' ' || *str == ',')
					str++;

				if (*str == 0)
					break;

				p = str;
				while (*p != 0 && *p != ' ' && *p != ',')
					p++;

				c = *p;
				*p = 0;
				type = lfsck_name2type(str, strlen(str));
				if (type == 0) {
					fprintf(stderr, "Invalid type (%s).\n"
						"The valid value should be "
						"'layout', 'DNE' or "
						"'namespace'.\n", str);
					*p = c;
					return -EINVAL;
				}

				*p = c;
				str = p;

				start.ls_active |= type;
			}
			if (start.ls_active == 0) {
				fprintf(stderr, "Miss LFSCK type(s).\n"
					"The valid value should be "
					"'layout', 'DNE' or 'namespace'.\n");
				return -EINVAL;
			}
			break;
		}
		default:
			fprintf(stderr, "Invalid option, '-h' for help.\n");
			return -EINVAL;
		}
	}

	if (data.ioc_inlbuf4 == NULL) {
		fprintf(stderr,
			"Must sepcify MDT device to start LFSCK.\n");
		return -EINVAL;
	}

	data.ioc_inlbuf1 = (char *)&start;
	data.ioc_inllen1 = sizeof(start);
	memset(buf, 0, sizeof(rawbuf));
	rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
	if (rc) {
		fprintf(stderr, "Fail to pack ioctl data: rc = %d.\n", rc);
		return rc;
	}

	rc = l_ioctl(OBD_DEV_ID, OBD_IOC_START_LFSCK, buf);
	if (rc < 0) {
		perror("Fail to start LFSCK");
		return rc;
	}

	obd_ioctl_unpack(&data, buf, sizeof(rawbuf));
	if (start.ls_active == 0) {
		printf("Started LFSCK on the MDT device %s", device);
	} else {
		printf("Started LFSCK on the MDT device %s:", device);
		i = 0;
		while (lfsck_types_names[i].name != NULL) {
			if (start.ls_active & lfsck_types_names[i].type) {
				printf(" %s", lfsck_types_names[i].name);
				start.ls_active &= ~lfsck_types_names[i].type;
			}
			i++;
		}
		if (start.ls_active != 0)
			printf(" unknown(0x%x)", start.ls_active);
	}
	printf(".\n");
	return 0;
}
Example #18
0
int lustre_lnet_show_net(char *nw, int detail, int seq_no,
			 struct cYAML **show_rc, struct cYAML **err_rc)
{
	char *buf;
	struct lnet_ioctl_config_lnd_tunables *lnd_cfg;
	struct lnet_ioctl_config_data *data;
	struct lnet_ioctl_net_config *net_config;
	__u32 net = LNET_NIDNET(LNET_NID_ANY);
	int rc = LUSTRE_CFG_RC_OUT_OF_MEM, i, j;
	int l_errno = 0;
	struct cYAML *root = NULL, *tunables = NULL, *net_node = NULL,
		*interfaces = NULL, *item = NULL, *first_seq = NULL;
	int str_buf_len = LNET_MAX_SHOW_NUM_CPT * 2;
	char str_buf[str_buf_len];
	char *pos;
	char err_str[LNET_MAX_STR_LEN];
	bool exist = false;
	size_t buf_len;

	snprintf(err_str, sizeof(err_str), "\"out of memory\"");

	buf_len = sizeof(*data) + sizeof(*net_config) + sizeof(*lnd_cfg);
	buf = calloc(1, buf_len);
	if (buf == NULL)
		goto out;

	data = (struct lnet_ioctl_config_data *)buf;

	if (nw != NULL) {
		net = libcfs_str2net(nw);
		if (net == LNET_NIDNET(LNET_NID_ANY)) {
			snprintf(err_str,
				 sizeof(err_str),
				 "\"cannot parse net '%s'\"", nw);
			rc = LUSTRE_CFG_RC_BAD_PARAM;
			goto out;
		}
	}

	root = cYAML_create_object(NULL, NULL);
	if (root == NULL)
		goto out;

	net_node = cYAML_create_seq(root, "net");
	if (net_node == NULL)
		goto out;

	for (i = 0;; i++) {
		pos = str_buf;

		memset(buf, 0, buf_len);

		LIBCFS_IOC_INIT_V2(*data, cfg_hdr);
		/*
		 * set the ioc_len to the proper value since INIT assumes
		 * size of data
		 */
		data->cfg_hdr.ioc_len = buf_len;
		data->cfg_count = i;

		rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_NET, data);
		if (rc != 0) {
			l_errno = errno;
			break;
		}

		/* filter on provided data */
		if (net != LNET_NIDNET(LNET_NID_ANY) &&
		    net != LNET_NIDNET(data->cfg_nid))
			continue;

		/* default rc to -1 in case we hit the goto */
		rc = -1;
		exist = true;

		net_config = (struct lnet_ioctl_net_config *)data->cfg_bulk;

		/* create the tree to be printed. */
		item = cYAML_create_seq_item(net_node);
		if (item == NULL)
			goto out;

		if (first_seq == NULL)
			first_seq = item;

		if (cYAML_create_string(item, "net",
					libcfs_net2str(
						LNET_NIDNET(data->cfg_nid)))
		    == NULL)
			goto out;

		if (cYAML_create_string(item, "nid",
					libcfs_nid2str(data->cfg_nid)) == NULL)
			goto out;

		if (cYAML_create_string(item, "status",
					(net_config->ni_status ==
					  LNET_NI_STATUS_UP) ?
					    "up" : "down") == NULL)
			goto out;

		/* don't add interfaces unless there is at least one
		 * interface */
		if (strlen(net_config->ni_interfaces[0]) > 0) {
			interfaces = cYAML_create_object(item, "interfaces");
			if (interfaces == NULL)
				goto out;

			for (j = 0; j < LNET_MAX_INTERFACES; j++) {
				if (lustre_interface_show_net(interfaces, j,
							      detail, data,
							      net_config) < 0)
					goto out;
			}
		}

		if (detail) {
			char *limit;

			tunables = cYAML_create_object(item, "tunables");
			if (tunables == NULL)
				goto out;

			if (cYAML_create_number(tunables, "peer_timeout",
						data->cfg_config_u.cfg_net.
						net_peer_timeout) == NULL)
				goto out;

			if (cYAML_create_number(tunables, "peer_credits",
						data->cfg_config_u.cfg_net.
						net_peer_tx_credits) == NULL)
				goto out;

			if (cYAML_create_number(tunables,
						"peer_buffer_credits",
						data->cfg_config_u.cfg_net.
						net_peer_rtr_credits) == NULL)
				goto out;

			if (cYAML_create_number(tunables, "credits",
						data->cfg_config_u.cfg_net.
						net_max_tx_credits) == NULL)
				goto out;

			/* out put the CPTs in the format: "[x,x,x,...]" */
			limit = str_buf + str_buf_len - 3;
			pos += snprintf(pos, limit - pos, "\"[");
			for (j = 0 ; data->cfg_ncpts > 1 &&
				j < data->cfg_ncpts &&
				pos < limit; j++) {
				pos += snprintf(pos, limit - pos,
						"%d", net_config->ni_cpts[j]);
				if ((j + 1) < data->cfg_ncpts)
					pos += snprintf(pos, limit - pos, ",");
			}
			pos += snprintf(pos, 3, "]\"");

			if (data->cfg_ncpts > 1 &&
			    cYAML_create_string(tunables, "CPT",
						str_buf) == NULL)
				goto out;
		}
	}

	/* Print out the net information only if show_rc is not provided */
	if (show_rc == NULL)
		cYAML_print_tree(root);

	if (l_errno != ENOENT) {
		snprintf(err_str,
			 sizeof(err_str),
			 "\"cannot get networks: %s\"",
			 strerror(l_errno));
		rc = -l_errno;
		goto out;
	} else
		rc = LUSTRE_CFG_RC_NO_ERR;

	snprintf(err_str, sizeof(err_str), "\"success\"");
out:
	if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR || !exist) {
		cYAML_free_tree(root);
	} else if (show_rc != NULL && *show_rc != NULL) {
		struct cYAML *show_node;
		/* find the net node, if one doesn't exist
		 * then insert one.  Otherwise add to the one there
		 */
		show_node = cYAML_get_object_item(*show_rc, "net");
		if (show_node != NULL && cYAML_is_sequence(show_node)) {
			cYAML_insert_child(show_node, first_seq);
			free(net_node);
			free(root);
		} else if (show_node == NULL) {
			cYAML_insert_sibling((*show_rc)->cy_child,
						net_node);
			free(root);
		} else {
			cYAML_free_tree(root);
		}
	} else {
		*show_rc = root;
	}

	cYAML_build_error(rc, seq_no, SHOW_CMD, "net", err_str, err_rc);

	return rc;
}