コード例 #1
0
ファイル: fabrics.c プロジェクト: safl/nvme-cli
int connect(const char *desc, int argc, char **argv)
{
	char argstr[BUF_SIZE];
	int instance, ret;
	const struct argconfig_commandline_options command_line_options[] = {
		{"transport",       't', "LIST", CFG_STRING, &cfg.transport,       required_argument, "transport type" },
		{"nqn",             'n', "LIST", CFG_STRING, &cfg.nqn,             required_argument, "nqn name" },
		{"traddr",          'a', "LIST", CFG_STRING, &cfg.traddr,          required_argument, "transport address" },
		{"trsvcid",         's', "LIST", CFG_STRING, &cfg.trsvcid,         required_argument, "transport service id (e.g. IP port)" },
		{"host-traddr",     'w', "LIST", CFG_STRING, &cfg.host_traddr,     required_argument, "host traddr (e.g. FC WWN's)" },
		{"hostnqn",         'q', "LIST", CFG_STRING, &cfg.hostnqn,         required_argument, "user-defined hostnqn" },
		{"nr-io-queues",    'i', "LIST", CFG_STRING, &cfg.nr_io_queues,    required_argument, "number of io queues to use (default is core count)" },
		{"keep-alive-tmo",  'k', "LIST", CFG_STRING, &cfg.keep_alive_tmo,  required_argument, "keep alive timeout period in seconds" },
		{"reconnect-delay", 'c', "LIST", CFG_STRING, &cfg.reconnect_delay, required_argument, "reconnect timeout period in seconds" },
		{NULL},
	};

	argconfig_parse(argc, argv, desc, command_line_options, &cfg,
			sizeof(cfg));

	ret = build_options(argstr, BUF_SIZE);
	if (ret)
		return ret;

	if (!cfg.nqn) {
		fprintf(stderr, "need a -n argument\n");
		return -EINVAL;
	}

	instance = add_ctrl(argstr);
	if (instance < 0)
		return instance;
	return 0;
}
コード例 #2
0
ファイル: fabrics.c プロジェクト: safl/nvme-cli
static int discover_from_conf_file(const char *desc, char *argstr,
		const struct argconfig_commandline_options *opts, bool connect)
{
	FILE *f;
	char line[256], *ptr, *args, **argv;
	int argc, err, ret = 0;

	f = fopen(PATH_NVMF_DISC, "r");
	if (f == NULL) {
		fprintf(stderr, "No discover params given and no %s conf\n",
			PATH_NVMF_DISC);
		return -EINVAL;
	}

	while (fgets(line, sizeof(line), f) != NULL) {
		if (line[0] == '#' || line[0] == '\n')
			continue;

		args = strdup(line);
		if (!args) {
			fprintf(stderr, "failed to strdup args\n");
			ret = -ENOMEM;
			goto out;
		}

		argv = calloc(MAX_DISC_ARGS, BUF_SIZE);
		if (!argv) {
			fprintf(stderr, "failed to allocate argv vector\n");
			free(args);
			ret = -ENOMEM;
			goto out;
		}

		argc = 0;
		argv[argc++] = "discover";
		while ((ptr = strsep(&args, " =\n")) != NULL)
			argv[argc++] = ptr;

		argconfig_parse(argc, argv, desc, opts, &cfg, sizeof(cfg));

		err = build_options(argstr, BUF_SIZE);
		if (err) {
			ret = err;
			continue;
		}

		err = do_discover(argstr, connect);
		if (err) {
			ret = err;
			continue;
		}

		free(args);
		free(argv);
	}

out:
	fclose(f);
	return ret;
}
コード例 #3
0
ファイル: fabrics.c プロジェクト: safl/nvme-cli
int discover(const char *desc, int argc, char **argv, bool connect)
{
	char argstr[BUF_SIZE];
	int ret;
	const struct argconfig_commandline_options command_line_options[] = {
		{"transport",   't', "LIST", CFG_STRING, &cfg.transport,   required_argument, "transport type" },
		{"traddr",      'a', "LIST", CFG_STRING, &cfg.traddr,      required_argument, "transport address" },
		{"trsvcid",     's', "LIST", CFG_STRING, &cfg.trsvcid,     required_argument, "transport service id (e.g. IP port)" },
		{"host-traddr", 'w', "LIST", CFG_STRING, &cfg.host_traddr, required_argument, "host traddr (e.g. FC WWN's)" },
		{"hostnqn",     'q', "LIST", CFG_STRING, &cfg.hostnqn,     required_argument, "user-defined hostnqn (if default not used)" },
		{"raw",         'r', "LIST", CFG_STRING, &cfg.raw,         required_argument, "raw output file" },
		{NULL},
	};

	argconfig_parse(argc, argv, desc, command_line_options, &cfg,
			sizeof(cfg));

	cfg.nqn = NVME_DISC_SUBSYS_NAME;

	if (!cfg.transport && !cfg.traddr) {
		return discover_from_conf_file(desc, argstr,
				command_line_options, connect);
	} else {
		ret = build_options(argstr, BUF_SIZE);
		if (ret)
			return ret;

		return do_discover(argstr, connect);
	}
}
コード例 #4
0
ファイル: fabrics.c プロジェクト: safl/nvme-cli
int disconnect(const char *desc, int argc, char **argv)
{
	const char *nqn = "nqn name";
	const char *device = "nvme device";
	int ret = 0;

	const struct argconfig_commandline_options command_line_options[] = {
		{"nqn",    'n', "LIST", CFG_STRING, &cfg.nqn,    required_argument, nqn},
		{"device", 'd', "LIST", CFG_STRING, &cfg.device, required_argument, device},
		{NULL},
	};

	argconfig_parse(argc, argv, desc, command_line_options, &cfg,
			sizeof(cfg));
	if (!cfg.nqn && !cfg.device) {
		fprintf(stderr, "need a -n or -d argument\n");
		return -EINVAL;
	}

	if (cfg.nqn) {
		ret = disconnect_by_nqn(cfg.nqn);
		if (ret < 0)
			fprintf(stderr, "Failed to disconnect by NQN: %s\n",
				cfg.nqn);
		else
			printf("NQN:%s disconnected %d controller(s)\n", cfg.nqn, ret);
	}

	if (cfg.device) {
		ret = disconnect_by_device(cfg.device);
		if (ret)
			fprintf(stderr,
				"Failed to disconnect by device name: %s\n",
				cfg.device);
	}

	return ret;
}
コード例 #5
0
ファイル: lnvm-nvme.c プロジェクト: YuanDdQiao/nvme-cli
static int lnvm_init(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
	const char *desc = "Initialize LightNVM device. A LightNVM/Open-Channel SSD"\
			   " must have a media manager associated before it can "\
			   " be exposed to the user. The default is to initialize"
			   " the general media manager on top of the device.\n\n"
			   "Example:"
			   " lnvm-init -d nvme0n1";
	const char *devname = "identifier of desired device. e.g. nvme0n1.";
	const char *mmtype = "media manager to initialize on top of device. Default: gennvm.";
	int ret;

	struct config
	{
		char *devname;
		char *mmtype;
	};

	struct config cfg = {
		.devname = "",
		.mmtype = "gennvm",
	};

	const struct argconfig_commandline_options command_line_options[] = {
		{"device-name",   'd', "DEVICE", CFG_STRING, &cfg.devname, required_argument, devname},
		{"mediamgr-name", 'm', "MM",     CFG_STRING, &cfg.mmtype,  required_argument, mmtype},
		{NULL}
	};

	ret = argconfig_parse(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
	if (ret < 0)
		return ret;

	if (!strlen(cfg.devname)) {
		fprintf(stderr, "device name missing %d\n", (int)strlen(cfg.devname));
		return -EINVAL;
	}

	return lnvm_do_init(cfg.devname, cfg.mmtype);
}

static int lnvm_list(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
	const char *desc = "List all devices registered with LightNVM.";
	int ret;

	const struct argconfig_commandline_options command_line_options[] = {
		{NULL}
	};

	ret = argconfig_parse(argc, argv, desc, command_line_options, NULL, 0);
	if (ret < 0)
		return ret;

	return lnvm_do_list_devices();
}

static int lnvm_info(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
	const char *desc = "Show general information and registered target types with LightNVM";
	int ret;

	const struct argconfig_commandline_options command_line_options[] = {
		{NULL}
	};

	ret = argconfig_parse(argc, argv, desc, command_line_options, NULL, 0);
	if (ret < 0)
		return ret;

	return lnvm_do_info();
}

static int lnvm_id_ns(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
	const char *desc = "Send an Identify Geometry command to the "\
		"given LightNVM device, returns properties of the specified "\
		"namespace in either human-readable or binary format.";
	const char *raw_binary = "show infos in binary format";
	const char *human_readable = "show infos in readable format";
	const char *namespace_id = "identifier of desired namespace. default: 1";
	unsigned int fd, flags = 0;

	struct config {
		__u32 namespace_id;
		int   raw_binary;
		int   human_readable;
	};

	struct config cfg = {
		.namespace_id    = 1,
	};

	const struct argconfig_commandline_options command_line_options[] = {
		{"namespace-id",    'n', "NUM",  CFG_POSITIVE, &cfg.namespace_id,    required_argument, namespace_id},
		{"raw-binary",      'b', "FLAG", CFG_NONE,     &cfg.raw_binary,      no_argument,       raw_binary},
		{"human-readable",  'H', "FLAG", CFG_NONE,     &cfg.human_readable,  no_argument,       human_readable},
		{NULL}
	};

	fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
	if (fd < 0)
		return fd;

	if (cfg.human_readable)
		flags |= HUMAN;
	else if (cfg.raw_binary)
		flags |= RAW;

	return lnvm_do_id_ns(fd, cfg.namespace_id, flags);
}

static int lnvm_create_tgt(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
	const char *desc = "Instantiate a target on top of a LightNVM enabled device.";
	const char *devname = "identifier of desired device. e.g. nvme0n1.";
	const char *tgtname = "target name of the device to initialize. e.g. target0.";
	const char *tgttype = "identifier of target type. e.g. pblk.";
	const char *lun_begin = "Define begin of luns to use for target.";
	const char *lun_end = "Define set of luns to use for target.";
	const char *over_prov = "Define over-provision percentage for target.";
	const char *flag_factory = "Create target in factory mode";
	int flags;
	int ret;

	struct config
	{
		char *devname;
		char *tgtname;
		char *tgttype;
		__u32 lun_begin;
		__u32 lun_end;
		__u32 over_prov;

		/* flags */
		__u32 factory;
	};

	struct config cfg = {
		.devname = "",
		.tgtname = "",
		.tgttype = "",
		.lun_begin = -1,
		.lun_end = -1,
		.over_prov = -1,
		.factory = 0,
	};

	const struct argconfig_commandline_options command_line_options[] = {
		{"device-name",   'd', "DEVICE", CFG_STRING,    &cfg.devname,   required_argument, devname},
		{"target-name",   'n', "TARGET", CFG_STRING,    &cfg.tgtname,   required_argument, tgtname},
		{"target-type",   't', "TARGETTYPE",  CFG_STRING,    &cfg.tgttype,   required_argument, tgttype},
		{"lun-begin",     'b', "NUM",    CFG_POSITIVE,  &cfg.lun_begin,      required_argument,       lun_begin},
		{"lun-end",       'e', "NUM",    CFG_POSITIVE,  &cfg.lun_end,   required_argument,       lun_end},
		{"over-prov",     'o', "NUM",    CFG_POSITIVE,  &cfg.over_prov, required_argument,  over_prov},
		{"factory",       'f', "FLAG",   CFG_NONE,  &cfg.factory,   no_argument,  flag_factory},
		{NULL}
	};

	ret = argconfig_parse(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
	if (ret < 0)
		return ret;

	if (!strlen(cfg.devname)) {
		fprintf(stderr, "device name missing %d\n", (int)strlen(cfg.devname));
		return -EINVAL;
	}
	if (!strlen(cfg.tgtname)) {
		fprintf(stderr, "target name missing\n");
		return -EINVAL;
	}
	if (!strlen(cfg.tgttype)) {
		fprintf(stderr, "target type missing\n");
		return -EINVAL;
	}

	flags = 0;
	if (cfg.factory)
		flags |= NVM_TARGET_FACTORY;

	return lnvm_do_create_tgt(cfg.devname, cfg.tgtname, cfg.tgttype, cfg.lun_begin, cfg.lun_end, cfg.over_prov, flags);
}

static int lnvm_remove_tgt(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
	const char *desc = "Remove an initialized LightNVM target.";
	const char *tgtname = "target name of the device to initialize. e.g. target0.";
	int ret;

	struct config
	{
		char *tgtname;
	};

	struct config cfg = {
		.tgtname = "",
	};

	const struct argconfig_commandline_options command_line_options[] = {
		{"target-name",   'n', "TARGET", CFG_STRING,    &cfg.tgtname,   required_argument, tgtname},
		{NULL}
	};

	ret = argconfig_parse(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
	if (ret < 0)
		return ret;

	if (!strlen(cfg.tgtname)) {
		fprintf(stderr, "target name missing\n");
		return -EINVAL;
	}

	return lnvm_do_remove_tgt(cfg.tgtname);
}

static int lnvm_factory_init(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
	const char *desc = "Factory initialize a LightNVM enabled device.";
	const char *devname = "identifier of desired device. e.g. nvme0n1.";
	const char *erase_only_marked = "only erase marked blocks. default: all blocks.";
	const char *host_marks = "remove host side blocks list. default: keep.";
	const char *bb_marks = "remove grown bad blocks list. default: keep";
	int ret;

	struct config
	{
		char *devname;
		int  erase_only_marked;
		int  clear_host_marks;
		int  clear_bb_marks;
	};

	struct config cfg = {
		.devname = "",
	};

	const struct argconfig_commandline_options command_line_options[] = {
		{"device-name",          'd', "DEVICE", CFG_STRING, &cfg.devname,           required_argument, devname},
		{"erase-only-marked",    'e', "",       CFG_NONE,   &cfg.erase_only_marked, no_argument,       erase_only_marked},
		{"clear-host-side-blks", 's', "",       CFG_NONE,   &cfg.clear_host_marks,  no_argument,       host_marks},
		{"clear-bb-blks",        'b', "",       CFG_NONE,   &cfg.clear_bb_marks,    no_argument,       bb_marks},
		{NULL}
	};

	ret = argconfig_parse(argc, argv, desc, command_line_options, &cfg,
								sizeof(cfg));
	if (ret < 0)
		return ret;

	if (!strlen(cfg.devname)) {
		fprintf(stderr, "device name missing %d\n", (int)strlen(cfg.devname));
		return -EINVAL;
	}

	return lnvm_do_factory_init(cfg.devname, cfg.erase_only_marked,
				cfg.clear_host_marks, cfg.clear_bb_marks);
}

static int lnvm_get_bbtbl(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
	const char *desc = "Receive bad block table from a LightNVM compatible"\
			   " device.";
	const char *namespace = "(optional) desired namespace";
	const char *ch = "channel identifier";
	const char *lun = "lun identifier (within a channel)";
	const char *raw_binary = "show infos in binary format";
	unsigned int fd, flags = 0;

	struct config
	{
		__u32 namespace_id;
		__u16 lunid;
		__u16 chid;
		int   raw_binary;
	};

	struct config cfg = {
		.namespace_id = 1,
		.lunid = 0,
		.chid = 0,
	};

	const struct argconfig_commandline_options command_line_options[] = {
		{"namespace-id", 'n', "NUM",  CFG_POSITIVE, &cfg.namespace_id, required_argument, namespace},
		{"channel-id",   'c', "",     CFG_SHORT,    &cfg.chid,         required_argument, ch},
		{"lun-id",       'l', "",     CFG_SHORT,    &cfg.lunid,        required_argument, lun},
		{"raw-binary",   'b', "FLAG", CFG_NONE,     &cfg.raw_binary,   no_argument,       raw_binary},
		{NULL}
	};

	fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));

	if (cfg.raw_binary)
		flags |= RAW;

	return lnvm_do_get_bbtbl(fd, cfg.namespace_id, cfg.lunid, cfg.chid,
									flags);
}

static int lnvm_set_bbtbl(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
	const char *desc = "Update bad block table on a LightNVM compatible"\
			   " device.";
	const char *namespace = "(optional) desired namespace";
	const char *ch = "channel identifier";
	const char *lun = "lun identifier (within a channel)";
	const char *pln = "plane identifier (within a lun)";
	const char *blk = "block identifier (within a plane)";
	const char *value = "value to update the specific block to.";
	int fd;

	struct config
	{
		__u32 namespace_id;
		__u16 lunid;
		__u16 chid;
		__u16 plnid;
		__u16 blkid;
		__u16 value;
	};

	struct config cfg = {
		.namespace_id = 1,
		.lunid = 0,
		.chid = 0,
		.plnid = 0,
		.blkid = 0,
		.value = 0,
	};

	const struct argconfig_commandline_options command_line_options[] = {
		{"namespace-id", 'n', "NUM",  CFG_POSITIVE, &cfg.namespace_id, required_argument, namespace},
		{"channel-id",   'c', "NUM",     CFG_SHORT,    &cfg.chid,         required_argument, ch},
		{"lun-id",       'l', "NUM",     CFG_SHORT,    &cfg.lunid,        required_argument, lun},
		{"plane-id",     'p', "NUM",     CFG_SHORT,    &cfg.plnid,        required_argument, pln},
		{"block-id",     'b', "NUM",     CFG_SHORT,    &cfg.blkid,        required_argument, blk},
		{"value",        'v', "NUM",     CFG_SHORT,    &cfg.value,        required_argument, value},
		{NULL}
	};

	fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));

	printf("Updating: Ch.: %u LUN: %u Plane: %u Block: %u -> %u\n",
			cfg.chid, cfg.lunid, cfg.plnid, cfg.blkid, cfg.value);

	return lnvm_do_set_bbtbl(fd, cfg.namespace_id,
				 cfg.chid, cfg.lunid, cfg.plnid, cfg.blkid,
				 cfg.value);
}