0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

nvme-cli

Last updated at Posted at 2023-04-20

Completions

bash

tokunori@tokunori-desktop:~/nvme-cli$ source completions/bash-nvme-completion.sh && source ~/.bashrc

zsh

tokunori@tokunori-desktop:~/nvme-cli$ sudo apt install zsh
...
tokunori@tokunori-desktop:~/nvme-cli$ zsh
if your working shell is zsh...
-------------------------------
create the zsh completions directory if you don't have it
#if [ ! -e "~/.zsh" ]; then
#	mkdir ~/.zsh
#	mkdir ~/.zsh/completion
#fi

#cp `pwd`/_nvme ~/.zsh/completion/_nvme

add compinit if you don't have it in your .zshrc
#echo "autoload -Uz compinit && compinit" >> ~/.zshrc

add nvme autocompletions to your .zshrc
#echo "# source for tab autocompletions" >> ~/.zshrc
#echo "fpath=(~/.zsh/completion $fpath)" >> ~/.zshrc
#echo "source ~/.zsh/completion/_nvme" >> ~/.zshrc

make sure this zsh knows where everything is
#source ~/.zsh/completion/_nvme && source ~/.zshrc

You should be able to autocomplete with the nvme utility now (single TAB press
should get you a completion with descriptions -- sadly, bash doesn't support
descriptions within completions). If autocompletes disappear, just re-source
_nvme and .zshrc. Also, make sure your .zshrc is ordered correctly: we want to
source _nvme before updating our fpath. Both of these should occur before
compinit is loaded.
tokunori-desktop% cp completions/_nvme ~/.zsh/completion/_nvme
tokunori-desktop% source ~/.zsh/completion/_nvme && source ~/.zshrc

.zshrc

tokunori-desktop% nano ~/.zshrc
autoload -Uz compinit && compinit
# source for tab autocompletions
fpath=(~/.zsh/completion /usr/local/share/zsh/site-functions /usr/share/zsh/vendor-functions /usr/share/zsh/vendor-c>
source ~/.zsh/completion/_nvme
setopt interactivecomments
bindkey "^[[3~" delete-char
bindkey "^[[1~" beginning-of-line
bindkey "^[[4~" end-of-line

read

master: nvme version 2.4 (git 2.4-50-g4e7b9fd+) / libnvme version 1.4 (git 1.4-13-gc90eeff)

	if (cfg.metadata_size) {
		err = nvme_cli_identify_ns(dev, cfg.namespace_id, &ns);
		if (err > 0) {
			nvme_show_status(err);
			goto free_buffer;
		} else if (err < 0) {
			nvme_show_error("identify namespace: %s", nvme_strerror(errno));
			goto free_buffer;
		}
	struct nvme_io_args args = {
		.args_size	= sizeof(args),
		.fd		= dev_fd(dev),
		.nsid		= cfg.namespace_id,
		.slba		= cfg.start_block,
		.nlb		= nblocks,
		.control	= control,
		.dsm		= cfg.dsmgmt,
		.sts		= sts,
		.pif		= pif,
		.dspec		= cfg.dspec,
		.reftag_u64	= cfg.ref_tag,
		.apptag		= cfg.app_tag,
		.appmask	= cfg.app_tag_mask,
		.storage_tag	= cfg.storage_tag,
		.data_len	= buffer_size,
		.data		= buffer,
		.metadata_len	= cfg.metadata_size,
		.metadata	= mbuffer,
		.timeout	= NVME_DEFAULT_IOCTL_TIMEOUT,
		.result		= NULL,
	};
struct nvme_passthru_cmd {
	__u8	opcode;
	__u8	flags;
	__u16	rsvd1;
	__u32	nsid;
	__u32	cdw2;
	__u32	cdw3;
	__u64	metadata;
	__u64	addr;
	__u32	metadata_len;
	__u32	data_len;
	__u32	cdw10;
	__u32	cdw11;
	__u32	cdw12;
	__u32	cdw13;
	__u32	cdw14;
	__u32	cdw15;
	__u32	timeout_ms;
	__u32	result;
};
	struct nvme_passthru_cmd cmd = {
		.opcode		= opcode,
		.nsid		= args->nsid,
		.cdw2		= cdw2,
		.cdw3		= cdw3,
		.cdw10		= cdw10,
		.cdw11		= cdw11,
		.cdw12		= cdw12,
		.cdw13		= cdw13,
		.cdw14		= cdw14,
		.cdw15		= cdw15,
		.data_len	= args->data_len,
		.metadata_len	= args->metadata_len,
		.addr		= (__u64)(uintptr_t)args->data,
		.metadata	= (__u64)(uintptr_t)args->metadata,
		.timeout_ms	= args->timeout,
	};
	return nvme_submit_passthru(fd, NVME_IOCTL_IO_CMD, cmd, result);

1.8

	if (cfg.metadata_size) {
		mbuffer = malloc(cfg.metadata_size);
		if (!mbuffer) {
			fprintf(stderr, "can not allocate io metadata "
					"payload: %s\n", strerror(errno));
			err = ENOMEM;
			goto free_buffer;
		}
	}
struct nvme_user_io {
	__u8	opcode;
	__u8	flags;
	__u16	control;
	__u16	nblocks;
	__u16	rsvd;
	__u64	metadata;
	__u64	addr;
	__u64	slba;
	__u32	dsmgmt;
	__u32	reftag;
	__u16	apptag;
	__u16	appmask;
};
	struct nvme_user_io io = {
		.opcode		= opcode,
		.flags		= 0,
		.control	= control,
		.nblocks	= nblocks,
		.rsvd		= 0,
		.metadata	= (__u64)(uintptr_t) metadata,
		.addr		= (__u64)(uintptr_t) data,
		.slba		= slba,
		.dsmgmt		= dsmgmt,
		.reftag		= reftag,
		.appmask	= appmask,
		.apptag		= apptag,
	};
	return ioctl(fd, NVME_IOCTL_SUBMIT_IO, &io);

v1.16: nvme version 1.16

	if (cfg.metadata_size) {
		err = nsid = nvme_get_nsid(fd);
		if (err < 0) {
			perror("get-namespace-id");
			goto close_mfd;
		}
struct nvme_passthru_cmd {
	__u8	opcode;
	__u8	flags;
	__u16	rsvd1;
	__u32	nsid;
	__u32	cdw2;
	__u32	cdw3;
	__u64	metadata;
	__u64	addr;
	__u32	metadata_len;
	__u32	data_len;
	__u32	cdw10;
	__u32	cdw11;
	__u32	cdw12;
	__u32	cdw13;
	__u32	cdw14;
	__u32	cdw15;
	__u32	timeout_ms;
	__u32	result;
};
	struct nvme_passthru_cmd cmd = {
		.opcode		= opcode,
		.nsid		= nsid,
		.metadata	= (__u64)(uintptr_t) metadata,
		.addr		= (__u64)(uintptr_t) data,
		.cdw2		= storage_tag & 0xffffffff,
		.cdw3		= (storage_tag >> 32) & 0xffff,
		.cdw10		= slba & 0xffffffff,
		.cdw11		= slba >> 32,
		.cdw12		= nblocks | (control << 16),
		.cdw13		= dsmgmt,
		.cdw14		= reftag,
		.cdw15		= apptag | (appmask << 16),
		.data_len	= buffer_size,
		.metadata_len	= mbuffer_size,
	};
	return ioctl(fd, NVME_IOCTL_IO_CMD, cmd);

kernel: master

static int nvme_ns_ioctl(struct nvme_ns *ns, unsigned int cmd,
		void __user *argp, unsigned int flags, fmode_t mode)
{
	switch (cmd) {
	case NVME_IOCTL_ID:
		force_successful_syscall_return();
		return ns->head->ns_id;
	case NVME_IOCTL_IO_CMD:
		return nvme_user_cmd(ns->ctrl, ns, argp, flags, mode);
	/*
	 * struct nvme_user_io can have different padding on some 32-bit ABIs.
	 * Just accept the compat version as all fields that are used are the
	 * same size and at the same offset.
	 */
#ifdef COMPAT_FOR_U64_ALIGNMENT
	case NVME_IOCTL_SUBMIT_IO32:
#endif
	case NVME_IOCTL_SUBMIT_IO:
		return nvme_submit_io(ns, argp);
struct nvme_user_io {
	__u8	opcode;
	__u8	flags;
	__u16	control;
	__u16	nblocks;
	__u16	rsvd;
	__u64	metadata;
	__u64	addr;
	__u64	slba;
	__u32	dsmgmt;
	__u32	reftag;
	__u16	apptag;
	__u16	appmask;
};
static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio)
{
	struct nvme_user_io io;
	struct nvme_command c;
	unsigned length, meta_len;
	void __user *metadata;

	if (copy_from_user(&io, uio, sizeof(io)))
		return -EFAULT;
struct nvme_passthru_cmd {
	__u8	opcode;
	__u8	flags;
	__u16	rsvd1;
	__u32	nsid;
	__u32	cdw2;
	__u32	cdw3;
	__u64	metadata;
	__u64	addr;
	__u32	metadata_len;
	__u32	data_len;
	__u32	cdw10;
	__u32	cdw11;
	__u32	cdw12;
	__u32	cdw13;
	__u32	cdw14;
	__u32	cdw15;
	__u32	timeout_ms;
	__u32	result;
};
static int nvme_user_cmd(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
		struct nvme_passthru_cmd __user *ucmd, unsigned int flags,
		fmode_t mode)
{
	struct nvme_passthru_cmd cmd;
	struct nvme_command c;
	unsigned timeout = 0;
	u64 result;
	int status;

	if (copy_from_user(&cmd, ucmd, sizeof(cmd)))
		return -EFAULT;
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?