if (c != 0) {
if (c == '?' || c == 'h') {
argconfig_print_help(program_desc, options);
- goto exit;
+ goto out;
}
for (option_index = 0; option_index < options_count;
option_index++) {
fprintf(stderr,
"Expected integer argument for '%s' but got '%s'!\n",
long_opts[option_index].name, optarg);
- goto exit;
+ goto out;
}
} else if (s->config_type == CFG_INT) {
*((int *)value_addr) = strtol(optarg, &endptr, 0);
fprintf(stderr,
"Expected integer argument for '%s' but got '%s'!\n",
long_opts[option_index].name, optarg);
- goto exit;
+ goto out;
}
} else if (s->config_type == CFG_BOOL) {
int tmp = strtol(optarg, &endptr, 0);
fprintf(stderr,
"Expected 0 or 1 argument for '%s' but got '%s'!\n",
long_opts[option_index].name, optarg);
- goto exit;
+ goto out;
}
*((int *)value_addr) = tmp;
} else if (s->config_type == CFG_BYTE) {
fprintf(stderr,
"Expected byte argument for '%s' but got '%s'!\n",
long_opts[option_index].name, optarg);
- goto exit;
+ goto out;
}
*((uint8_t *) value_addr) = tmp;
} else if (s->config_type == CFG_SHORT) {
fprintf(stderr,
"Expected short argument for '%s' but got '%s'!\n",
long_opts[option_index].name, optarg);
- goto exit;
+ goto out;
}
*((uint16_t *) value_addr) = tmp;
} else if (s->config_type == CFG_POSITIVE) {
fprintf(stderr,
"Expected word argument for '%s' but got '%s'!\n",
long_opts[option_index].name, optarg);
- goto exit;
+ goto out;
}
*((uint32_t *) value_addr) = tmp;
} else if (s->config_type == CFG_INCREMENT) {
fprintf(stderr,
"Expected long integer argument for '%s' but got '%s'!\n",
long_opts[option_index].name, optarg);
- goto exit;
+ goto out;
}
} else if (s->config_type == CFG_LONG_SUFFIX) {
*((long *)value_addr) = suffix_binary_parse(optarg);
fprintf(stderr,
"Expected long suffixed integer argument for '%s' but got '%s'!\n",
long_opts[option_index].name, optarg);
- goto exit;
+ goto out;
}
} else if (s->config_type == CFG_DOUBLE) {
*((double *)value_addr) = strtod(optarg, &endptr);
fprintf(stderr,
"Expected float argument for '%s' but got '%s'!\n",
long_opts[option_index].name, optarg);
- goto exit;
+ goto out;
}
} else if (s->config_type == CFG_SUBOPTS) {
char **opts = ((char **)value_addr);
if (r == 2) {
fprintf(stderr,
"Error Parsing Sub-Options: Too many options!\n");
- goto exit;
+ goto out;
} else if (r) {
fprintf(stderr, "Error Parsing Sub-Options\n");
- goto exit;
+ goto out;
}
} else if (s->config_type == CFG_FILE_A ||
s->config_type == CFG_FILE_R ||
if (f == NULL) {
fprintf(stderr, "Unable to open %s file: %s\n",
s->option, optarg);
- goto exit;
+ goto out;
}
*((FILE **) value_addr) = f;
}
free(long_opts);
return 0;
- exit:
+ out:
free(short_opts);
free(long_opts);
- exit(1);
+ return -EINVAL;
}
int argconfig_parse_subopt_string(char *string, char **options,
return 0;
val[ret] = strtol(tmp, &p, 0);
-
if (*p != 0)
- exit(1);
+ return -1;
ret++;
-
while (1) {
tmp = strtok(NULL, ",");
return ret;
if (ret >= max_length)
- exit(1);
+ return -1;
val[ret] = strtol(tmp, &p, 0);
if (*p != 0)
- exit(1);
-
+ return -1;
ret++;
}
-
}
unsigned argconfig_parse_comma_sep_array_long(char *string,
val[ret] = strtoll(tmp, &p, 0);
if (*p != 0)
- exit(1);
+ return -1;
ret++;
while (1) {
tmp = strtok(NULL, ",");
return ret;
if (ret >= max_length)
- exit(1);
+ return -1;
val[ret] = strtoll(tmp, &p, 0);
if (*p != 0)
- exit(1);
+ return -1;
ret++;
}
}
}
}
}
-
-void argconfig_parse_subopt(char *const opts[], const char *module,
- const struct argconfig_sub_options *options,
- void *config_out, size_t config_size)
-{
- int enddefault = 0;
- int tmp;
- const struct argconfig_sub_options *s;
- char *const *o;
-
- errno = 0;
-
- for (o = opts; o != NULL && *o != NULL; o += 2) {
- if (*o == END_DEFAULT) {
- enddefault = 1;
- continue;
- }
-
- for (s = options; s->option != NULL; s++)
- if (strcmp(o[0], s->option) == 0)
- break;
-
- if (s->option == NULL && enddefault) {
- fprintf(stderr, "%s: Invalid sub-option '%s'.\n",
- module, o[0]);
- exit(1);
- } else if (s->option == NULL) {
- continue;
- }
-
- void *value_addr = (void *)(char *)s->default_value;
-
- if (s->config_type == CFG_STRING) {
- *((char **)value_addr) = o[1];
- } else if (s->config_type == CFG_INT) {
- *((int *)value_addr) = (int)strtol(o[1], NULL, 0);
- } else if (s->config_type == CFG_SIZE) {
- *((size_t *) value_addr) =
- (size_t) strtol(o[1], NULL, 0);
- } else if (s->config_type == CFG_LONG) {
- *((long *)value_addr) = strtol(o[1], NULL, 0);
- } else if (s->config_type == CFG_LONG_SUFFIX) {
- *((long *)value_addr) = suffix_binary_parse(o[1]);
- } else if (s->config_type == CFG_DOUBLE) {
- *((double *)value_addr) = strtod(o[1], NULL);
- } else if (s->config_type == CFG_BOOL) {
- tmp = strtol(o[1], NULL, 0);
-
- if (tmp < 0 || tmp > 1)
- errno = 1;
-
- *((int *)value_addr) = (int)tmp;
- } else if (s->config_type == CFG_POSITIVE) {
- tmp = strtol(o[1], NULL, 0);
-
- if (tmp < 0)
- errno = 1;
-
- *((int *)value_addr) = (int)tmp;
- } else if (s->config_type == CFG_FILE_A ||
- s->config_type == CFG_FILE_R ||
- s->config_type == CFG_FILE_W ||
- s->config_type == CFG_FILE_AP ||
- s->config_type == CFG_FILE_RP ||
- s->config_type == CFG_FILE_WP) {
- const char *fopts = "";
- if (s->config_type == CFG_FILE_A)
- fopts = "a";
- else if (s->config_type == CFG_FILE_R)
- fopts = "r";
- else if (s->config_type == CFG_FILE_W)
- fopts = "w";
- else if (s->config_type == CFG_FILE_AP)
- fopts = "a+";
- else if (s->config_type == CFG_FILE_RP)
- fopts = "r+";
- else if (s->config_type == CFG_FILE_WP)
- fopts = "w+";
-
- FILE *f = fopen(o[1], fopts);
-
- if (f == NULL) {
- fprintf(stderr, "Unable to open %s file: %s\n",
- s->option, o[1]);
- exit(1);
- }
-
- *((FILE **) value_addr) = f;
- }
-
- if (errno) {
- fprintf(stderr,
- "%s: Invalid value '%s' for option '%s'.\n",
- module, o[1], o[0]);
- exit(1);
- }
- }
-}
-
-int argconfig_set_subopt(const char *opt,
- const struct argconfig_sub_options *options,
- void *config_out, va_list argp)
-{
- const struct argconfig_sub_options *s;
- for (s = options; s->option != NULL; s++)
- if (strcmp(opt, s->option) == 0)
- break;
-
- if (s->option == NULL)
- return 1;
-
- void *value_addr = (void *)(char *)s->default_value;
-
- if (s->config_type == CFG_STRING) {
- *((char **)value_addr) = va_arg(argp, char *);
- } else if (s->config_type == CFG_INT ||
- s->config_type == CFG_BOOL ||
- s->config_type == CFG_POSITIVE) {
- *((int *)value_addr) = va_arg(argp, int);
- } else if (s->config_type == CFG_SIZE) {
- *((size_t *) value_addr) = va_arg(argp, size_t);
- } else if (s->config_type == CFG_LONG) {
- *((long *)value_addr) = va_arg(argp, long);
- } else if (s->config_type == CFG_LONG_SUFFIX) {
- *((long *)value_addr) = va_arg(argp, long);
- } else if (s->config_type == CFG_DOUBLE) {
- *((double *)value_addr) = va_arg(argp, double);
- } else if (s->config_type == CFG_FILE_A ||
- s->config_type == CFG_FILE_R ||
- s->config_type == CFG_FILE_W ||
- s->config_type == CFG_FILE_AP ||
- s->config_type == CFG_FILE_RP ||
- s->config_type == CFG_FILE_WP) {
-
- *((FILE **) value_addr) = va_arg(argp, FILE *);
- }
-
- return 0;
-}
-
-int argconfig_get_subopt(const char *opt,
- const struct argconfig_sub_options *options,
- void *config_out, va_list argp)
-{
- const struct argconfig_sub_options *s;
- for (s = options; s->option != NULL; s++)
- if (strcmp(opt, s->option) == 0)
- break;
-
- if (s->option == NULL)
- return 1;
-
- void *value_addr = (void *)(char *)s->default_value;
-
- if (s->config_type == CFG_STRING) {
- *va_arg(argp, char **) = *((char **)value_addr);
- } else if (s->config_type == CFG_INT ||
- s->config_type == CFG_BOOL ||
- s->config_type == CFG_POSITIVE) {
- *va_arg(argp, int *) = *((int *)value_addr);
- } else if (s->config_type == CFG_SIZE) {
- *va_arg(argp, size_t *) = *((size_t *) value_addr);
- } else if (s->config_type == CFG_LONG) {
- *va_arg(argp, long *) = *((long *)value_addr);
- } else if (s->config_type == CFG_LONG_SUFFIX) {
- *va_arg(argp, long *) = *((long *)value_addr);
- } else if (s->config_type == CFG_DOUBLE) {
- *va_arg(argp, double *) = *((double *)value_addr);
- } else if (s->config_type == CFG_FILE_A ||
- s->config_type == CFG_FILE_R ||
- s->config_type == CFG_FILE_W ||
- s->config_type == CFG_FILE_AP ||
- s->config_type == CFG_FILE_RP ||
- s->config_type == CFG_FILE_WP) {
- *va_arg(argp, FILE **) = *((FILE **) value_addr);
- }
-
- return 0;
-}
#define min(x, y) (x) > (y) ? (y) : (x)
#define max(x, y) (x) > (y) ? (x) : (y)
-static int fd;
static struct stat nvme_stat;
const char *devicename;
return ret;
}
-static void open_dev(const char *dev)
+static int open_dev(const char *dev)
{
- int err;
+ int err, fd;
+
devicename = basename(dev);
- fd = open(dev, O_RDONLY);
- if (fd < 0)
+ err = open(dev, O_RDONLY);
+ if (err < 0)
goto perror;
+ fd = err;
err = fstat(fd, &nvme_stat);
if (err < 0)
goto perror;
if (!S_ISCHR(nvme_stat.st_mode) && !S_ISBLK(nvme_stat.st_mode)) {
fprintf(stderr, "%s is not a block or character device\n", dev);
- exit(ENODEV);
+ return -ENODEV;
}
- return;
+ return fd;
perror:
perror(dev);
- exit(errno);
+ return err;
}
-static void check_arg_dev(int argc, char **argv)
+static int check_arg_dev(int argc, char **argv)
{
if (optind >= argc) {
errno = EINVAL;
perror(argv[0]);
- exit(errno);
+ return -EINVAL;
}
+ return 0;
}
-static void get_dev(int argc, char **argv)
+static int get_dev(int argc, char **argv)
{
- check_arg_dev(argc, argv);
- open_dev((const char *)argv[optind]);
+ int ret;
+
+ ret = check_arg_dev(argc, argv);
+ if (ret) {
+ fprintf(stderr, "expected nvme device (ex: /dev/nvme0), none provided\n");
+ return ret;
+ }
+
+ return open_dev((const char *)argv[optind]);
}
int parse_and_open(int argc, char **argv, const char *desc,
const struct argconfig_commandline_options *clo, void *cfg, size_t size)
{
- argconfig_parse(argc, argv, desc, clo, cfg, size);
- get_dev(argc, argv);
- return fd;
+ int ret;
+
+ ret = argconfig_parse(argc, argv, desc, clo, cfg, size);
+ if (ret)
+ return ret;
+
+ return get_dev(argc, argv);
}
static const char *output_format = "Output format: normal|json|binary";
"(default) or binary.";
const char *namespace = "(optional) desired namespace";
const char *raw = "output in binary format";
- int err, fmt;
+ int err, fmt, fd;
struct config {
__u32 namespace_id;
{NULL}
};
- parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ if (fd < 0)
+ return fd;
fmt = validate_output_format(cfg.output_format);
if (fmt < 0)
else if (err > 0)
fprintf(stderr, "NVMe Status:%s(%x)\n",
nvme_status_to_string(err), err);
+ else
+ perror("smart log");
return err;
}
static int get_additional_smart_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
struct nvme_additional_smart_log smart_log;
- int err, fmt;
+ int err, fmt, fd;
char *desc = "Get Intel vendor specific additional smart log (optionally, "\
"for the specified namespace), and show it.";
const char *namespace = "(optional) desired namespace";
{NULL}
};
- parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ if (fd < 0)
+ return fd;
+
fmt = validate_output_format(cfg.output_format);
if (fmt < 0)
return fmt;
else if (err > 0)
fprintf(stderr, "NVMe Status:%s(%x)\n",
nvme_status_to_string(err), err);
+ else
+ perror("intel smart log");
return err;
}
const char *log_entries = "number of entries to retrieve";
const char *raw_binary = "dump in binary format";
struct nvme_id_ctrl ctrl;
- int err, fmt;
+ int err, fmt, fd;
struct config {
__u32 namespace_id;
{NULL}
};
- parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ if (fd < 0)
+ return fd;
fmt = validate_output_format(cfg.output_format);
if (fmt < 0)
}
err = nvme_identify_ctrl(fd, &ctrl);
- cfg.log_entries = min(cfg.log_entries, ctrl.elpe + 1);
- if (err) {
+ if (err < 0)
+ perror("identify controller");
+ else if (err) {
fprintf(stderr, "could not identify controller\n");
- return ENODEV;
+ err = ENODEV;
} else {
struct nvme_error_log_page *err_log;
+ cfg.log_entries = min(cfg.log_entries, ctrl.elpe + 1);
err_log = calloc(cfg.log_entries, sizeof(struct nvme_error_log_page));
if (!err_log) {
fprintf(stderr, "could not alloc buffer for error log\n");
else if (err > 0)
fprintf(stderr, "NVMe Status:%s(%x)\n",
nvme_status_to_string(err), err);
+ else
+ perror("error log");
free(err_log);
}
return err;
const char *desc = "Retrieve the firmware log for the "\
"specified device in either decoded format (default) or binary.";
const char *raw_binary = "use binary output";
- int err, fmt;
+ int err, fmt, fd;
struct nvme_firmware_log_page fw_log;
struct config {
{NULL}
};
- parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ if (fd < 0)
+ return fd;
fmt = validate_output_format(cfg.output_format);
if (fmt < 0)
const char *log_id = "identifier of log to retrieve";
const char *log_len = "how many bytes to retrieve";
const char *raw_binary = "output in raw format";
- int err;
+ int err, fd;
struct config {
__u32 namespace_id;
{NULL}
};
- parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ if (fd < 0)
+ return fd;
if (!cfg.log_len) {
fprintf(stderr, "non-zero log-len is required param\n");
} else if (err > 0)
fprintf(stderr, "NVMe Status:%s(%x)\n",
nvme_status_to_string(err), err);
+ else
+ perror("log page");
free(log);
return err;
}
"given device is part of, or optionally controllers attached to a specific namespace.";
const char *controller = "controller to display";
const char *namespace_id = "optional namespace attached to controller";
- int err, i;
+ int err, i, fd;
struct nvme_controller_list *cntlist;
struct config {
{NULL}
};
- parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ if (fd < 0)
+ return fd;
- if (posix_memalign((void *)&cntlist, getpagesize(), 0x1000))
+ if (posix_memalign((void *)&cntlist, getpagesize(), 0x1000)) {
+ fprintf(stderr, "can not allocate controller list payload\n");
return ENOMEM;
+ }
err = nvme_identify_ctrl_list(fd, cfg.namespace_id, cfg.cntid, cntlist);
if (!err) {
else if (err > 0)
fprintf(stderr, "NVMe Status:%s(%x) cntid:%d\n",
nvme_status_to_string(err), err, cfg.cntid);
+ else
+ perror("id controller list");
return err;
}
"namespace list in a NVMe subsystem, optionally starting with a given namespace";
const char *namespace_id = "namespace number returned list should to start after";
const char *all = "show all namespaces in the subsystem, whether attached or inactive";
- int err, i;
+ int err, i, fd;
__u32 ns_list[1024];
struct config {
{NULL}
};
- parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ if (fd < 0)
+ return fd;
err = nvme_identify_ns_list(fd, cfg.namespace_id, !!cfg.all, ns_list);
if (!err) {
else if (err > 0)
fprintf(stderr, "NVMe Status:%s(%x) NSID:%d\n",
nvme_status_to_string(err), err, cfg.namespace_id);
+ else
+ perror("id namespace list");
return err;
}
"becomes inactive when that namespace is detached or, if "\
"the namespace is not already inactive, once deleted.";
const char *namespace_id = "namespace to delete";
- int err;
+ int err, fd;
struct config {
__u32 namespace_id;
{NULL}
};
- parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ if (fd < 0)
+ return fd;
if (!cfg.namespace_id) {
fprintf(stderr, "%s: namespace-id parameter required\n",
fprintf(stderr, "NVMe Status:%s(%x)\n",
nvme_status_to_string(err), err);
else
- fprintf(stderr, "system error:(%x)\n", err);
+ perror("delete namespace");
return err;
}
static int nvme_attach_ns(int argc, char **argv, int attach, const char *desc, struct command *cmd)
{
- int err, num, i, list[2048];
+ int err, num, i, fd, list[2048];
__u16 ctrlist[2048];
const char *namespace_id = "namespace to attach";
{NULL}
};
- parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ if (fd < 0)
+ return fd;
if (!cfg.namespace_id) {
fprintf(stderr, "%s: namespace-id parameter required\n",
fprintf(stderr, "NVMe Status:%s(%x)\n",
nvme_status_to_string(err), err);
else
- fprintf(stderr, "system error:(%x)\n", err);
+ perror(attach ? "attach namespace" : "detach namespace");
return err;
}
"parameters. The next available namespace ID is used for the "\
"create operation. Note that create-ns does not attach the "\
"namespace to a controller, the attach-ns command is needed.";
- int err = 0;
+ int err = 0, fd;
__u32 nsid;
struct config {
{NULL}
};
- parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ if (fd < 0)
+ return fd;
err = nvme_ns_create(fd, cfg.nsze, cfg.ncap, cfg.flbas, cfg.dps, cfg.nmic, &nsid);
if (!err)
else if (err > 0)
fprintf(stderr, "NVMe Status:%s(%x)\n",
nvme_status_to_string(err), err);
+ else
+ perror("create namespace");
return err;
}
if (strncmp("nvme", block, 4)) {
fprintf(stderr, "Device %s is not a nvme device.", block);
- exit(-1);
+ return NULL;
}
sscanf(block, "nvme%d", &len);
}
if (pci_fd < 0) {
fprintf(stderr, "%s did not find a pci resource\n", base);
- exit(ENODEV);
+ return NULL;
}
membase = mmap(NULL, getpagesize(), PROT_READ, MAP_SHARED, pci_fd, 0);
if (membase == MAP_FAILED) {
fprintf(stderr, "%s failed to map\n", base);
- exit(ENODEV);
+ return NULL;
}
return membase;
}
required_argument, "Output Format: normal|json"},
{NULL}
};
+
argconfig_parse(argc, argv, desc, opts, &cfg, sizeof(cfg));
fmt = validate_output_format(cfg.output_format);
return n;
list_items = calloc(n, sizeof(*list_items));
- if (!list_items)
+ if (!list_items) {
+ fprintf(stderr, "can not allocate controller list payload\n");
return ENOMEM;
+ }
for (i = 0; i < n; i++) {
snprintf(path, sizeof(path), "%s%s", dev, devices[i]->d_name);
return 0;
}
-static int get_nsid(void)
+static int get_nsid(int fd)
{
int nsid = nvme_get_nsid(fd);
fprintf(stderr,
"%s: failed to return namespace id\n",
devicename);
- exit(errno);
+ return errno;
}
return nsid;
}
const char *vendor_specific = "dump binary vendor infos";
const char *raw_binary = "show infos in binary format";
const char *human_readable = "show infos in readable format";
- int err, fmt;
+ int err, fmt, fd;
unsigned int flags = 0;
struct nvme_id_ctrl ctrl;
{NULL}
};
- parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ if (fd < 0)
+ return fd;
fmt = validate_output_format(cfg.output_format);
if (fmt < 0)
else if (err > 0)
fprintf(stderr, "NVMe Status:%s(%x)\n",
nvme_status_to_string(err), err);
+ else
+ perror("identify controller");
return err;
}
const char *human_readable = "show infos in readable format";
const char *namespace_id = "identifier of desired namespace";
struct nvme_id_ns ns;
- int err, fmt;
+ int err, fmt, fd;
unsigned int flags = 0;
struct config {
{NULL}
};
- parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ if (fd < 0)
+ return fd;
fmt = validate_output_format(cfg.output_format);
if (fmt < 0)
if (cfg.human_readable)
flags |= HUMAN;
if (!cfg.namespace_id)
- cfg.namespace_id = get_nsid();
+ cfg.namespace_id = get_nsid(fd);
err = nvme_identify_ns(fd, cfg.namespace_id, cfg.force, &ns);
if (!err) {
else if (err > 0)
fprintf(stderr, "NVMe Status:%s(%x) NSID:%d\n",
nvme_status_to_string(err), err, cfg.namespace_id);
+ else
+ perror("identify namespace");
return err;
}
static int get_ns_id(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- int nsid;
+ int nsid, fd;
- open_dev(argv[1]);
+ fd = open_dev(argv[1]);
nsid = nvme_get_nsid(fd);
if (nsid <= 0) {
perror(devicename);
- exit(errno);
+ return errno;
}
printf("%s: namespace-id:%d\n", devicename, nsid);
return 0;
const char *data_len = "buffer len (if) data is returned";
const char *cdw11 = "dword 11 for interrupt vector config";
const char *human_readable = "show infos in readable format";
- int err;
+ int err, fd;
__u32 result;
void *buf = NULL;
{NULL}
};
- parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ if (fd < 0)
+ return fd;
if (cfg.sel > 7) {
fprintf(stderr, "invalid 'select' param:%d\n", cfg.sel);
}
if (cfg.data_len) {
- if (posix_memalign(&buf, getpagesize(), cfg.data_len))
- exit(ENOMEM);
+ if (posix_memalign(&buf, getpagesize(), cfg.data_len)) {
+ fprintf(stderr, "can not allocate feature payload\n");
+ return ENOMEM;
+ }
memset(buf, 0, cfg.data_len);
}
d(buf, cfg.data_len, 16, 1);
} else if (buf)
d_raw(buf, cfg.data_len);
- } else if (err > 0)
+ } else if (err > 0) {
fprintf(stderr, "NVMe Status:%s(%x)\n",
nvme_status_to_string(err), err);
+ } else
+ perror("get-feature");
if (buf)
free(buf);
const char *fw = "firmware file (required)";
const char *xfer = "transfer chunksize limit";
const char *offset = "starting dword offset, default 0";
- int err, fw_fd = -1;
+ int err, fd, fw_fd = -1;
unsigned int fw_size;
struct stat sb;
void *fw_buf;
{NULL}
};
- parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ if (fd < 0)
+ return fd;
fw_fd = open(cfg.fw, O_RDONLY);
cfg.offset <<= 2;
fprintf(stderr, "no firmware file provided\n");
return EINVAL;
}
+
err = fstat(fw_fd, &sb);
if (err < 0) {
perror("fstat");
- exit(errno);
+ return errno;
}
fw_size = sb.st_size;
err = nvme_fw_download(fd, cfg.offset, cfg.xfer, fw_buf);
if (err < 0) {
perror("fw-download");
- exit(errno);
+ break;
} else if (err != 0) {
fprintf(stderr, "NVME Admin command error:%s(%x)\n",
nvme_status_to_string(err), err);
"Ensure nvmeX is the device you just activated before reset.";
const char *slot = "firmware slot to activate";
const char *action = "[0-2]: replacement action";
- int err;
+ int err, fd;
struct config {
__u8 slot;
{NULL}
};
- parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ if (fd < 0)
+ return fd;
if (cfg.slot > 7) {
fprintf(stderr, "invalid slot:%d\n", cfg.slot);
return err;
}
-static void clear_args(int argc, char **argv)
+static int clear_args(int argc, char **argv)
{
int opt, long_index;
+
while ((opt = getopt_long(argc, (char **)argv, "", NULL,
&long_index)) != -1);
- get_dev(argc, argv);
+ return get_dev(argc, argv);
}
static int subsystem_reset(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- int err;
- clear_args(argc, argv);
+ int err, fd;
+
+ fd = clear_args(argc, argv);
err = nvme_subsystem_reset(fd);
if (err < 0) {
perror("Subsystem-reset");
static int reset(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- int err;
- clear_args(argc, argv);
+ int err, fd;
+
+ fd = clear_args(argc, argv);
err = nvme_reset_controller(fd);
if (err < 0) {
perror("Reset");
const char *desc = "Reads and shows the defined NVMe controller registers "\
"in binary or human-readable format";
const char *human_readable = "show info in readable format";
+ void *bar;
uint64_t cap, asq, acq;
uint32_t vs, intms, intmc, cc, csts, nssr, aqa, cmbsz, cmbloc;
- void *bar;
+ int fd;
struct config {
int human_readable;
{NULL}
};
- parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ if (fd < 0)
+ return fd;
bar = get_registers();
+ if (!bar)
+ return ENODEV;
+
cap = mmio_read64(bar + NVME_REG_CAP);
vs = mmio_read32(bar + NVME_REG_VS);
intms = mmio_read32(bar + NVME_REG_INTMS);
const char *ms = "[0-1]: extended format off/on";
const char *reset = "Automatically reset the controller after successful format";
const char *timeout = "timeout value, in milliseconds";
- int err;
+ int err, fd;
struct config {
__u32 namespace_id;
{NULL}
};
- parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
/* ses & pi checks set to 7 for forward-compatibility */
if (cfg.ses > 7) {
return EINVAL;
}
if (S_ISBLK(nvme_stat.st_mode))
- cfg.namespace_id = get_nsid();
+ cfg.namespace_id = get_nsid(fd);
err = nvme_format(fd, cfg.namespace_id, cfg.lbaf, cfg.ses, cfg.pi,
cfg.pil, cfg.ms, cfg.timeout);
int err;
__u32 result;
void *buf = NULL;
- int ffd = STDIN_FILENO;
+ int fd, ffd = STDIN_FILENO;
struct config {
char *file;
{NULL}
};
- parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
if (!cfg.feature_id) {
fprintf(stderr, "feature-id required param\n");
if (cfg.feature_id == NVME_FEAT_LBA_RANGE)
cfg.data_len = 4096;
if (cfg.data_len) {
- if (posix_memalign(&buf, getpagesize(), cfg.data_len))
- exit(ENOMEM);
+ if (posix_memalign(&buf, getpagesize(), cfg.data_len)) {
+ fprintf(stderr, "can not allocate feature payload\n");
+ return ENOMEM;
+ }
memset(buf, 0, cfg.data_len);
}
else
d(buf, cfg.data_len, 16, 1);
}
- } else
+ } else if (err > 0)
fprintf(stderr, "NVMe Status:%s(%x)\n",
nvme_status_to_string(err), err);
if (buf)
const char *tl = "transfer length (cf. SPC-4)";
const char *namespace_id = "desired namespace";
const char *nssf = "NVMe Security Specific Field";
- int err, sec_fd = -1;
+ int err, fd, sec_fd = -1;
void *sec_buf;
unsigned int sec_size;
__u32 result;
{NULL}
};
- parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
sec_fd = open(cfg.file, O_RDONLY);
if (sec_fd < 0) {
err = nvme_sec_send(fd, cfg.namespace_id, cfg.nssf, cfg.spsp, cfg.secp,
cfg.tl, sec_size, sec_buf, &result);
if (err < 0)
- return errno;
+ perror("security-send");
else if (err != 0)
fprintf(stderr, "NVME Security Send Command Error:%d\n", err);
else
static int write_uncor(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- int err;
+ int err, fd;
const char *desc = "The Write Uncorrectable command is used to set a "\
"range of logical blocks to invalid.";
const char *namespace_id = "desired namespace";
{NULL}
};
- parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
if (!cfg.namespace_id)
- cfg.namespace_id = get_nsid();
+ cfg.namespace_id = get_nsid(fd);
err = nvme_write_uncorrectable(fd, cfg.namespace_id, cfg.start_block,
cfg.block_count);
if (err < 0)
- return errno;
+ perror("write uncorrectable");
else if (err != 0)
fprintf(stderr, "NVME IO command error:%s(%x)\n",
nvme_status_to_string(err), err);
static int write_zeroes(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- int err;
+ int err, fd;
__u16 control = 0;
const char *desc = "The Write Zeroes command is used to set a "\
"range of logical blocks to zero.";
{NULL}
};
- parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
if (cfg.prinfo > 0xf)
return EINVAL;
if (cfg.force_unit_access)
control |= NVME_RW_FUA;
if (!cfg.namespace_id)
- cfg.namespace_id = get_nsid();
+ cfg.namespace_id = get_nsid(fd);
err = nvme_write_zeros(fd, cfg.namespace_id, cfg.start_block, cfg.block_count,
control, cfg.ref_tag, cfg.app_tag, cfg.app_tag_mask);
if (err < 0)
- return errno;
+ perror("write-zeroes");
else if (err != 0)
fprintf(stderr, "NVME IO command error:%s(%x)\n",
nvme_status_to_string(err), err);
const char *idr = "Attribute Integral Dataset for Read";
const char *cdw11 = "All the command DWORD 11 attributes. Use instead of specifying individual attributes";
- int err;
+ int err, fd;
uint16_t nr, nc, nb, ns;
int ctx_attrs[256] = {0,};
int nlbs[256] = {0,};
{NULL}
};
- parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
nc = argconfig_parse_comma_sep_array(cfg.ctx_attrs, ctx_attrs, array_len(ctx_attrs));
nb = argconfig_parse_comma_sep_array(cfg.blocks, nlbs, array_len(nlbs));
}
if (!cfg.namespace_id)
- cfg.namespace_id = get_nsid();
+ cfg.namespace_id = get_nsid(fd);
if (!cfg.cdw11)
cfg.cdw11 = (cfg.ad << 2) | (cfg.idw << 1) | (cfg.idr << 0);
dsm = nvme_setup_dsm_range((__u32 *)ctx_attrs, (__u32 *)nlbs, (__u64 *)slbas, nr);
+ if (!dsm) {
+ fprintf(stderr, "failed to allocate data set payload\n");
+ return ENOMEM;
+ }
err = nvme_dsm(fd, cfg.namespace_id, cfg.cdw11, dsm, nr);
- if (err < 0) {
- fprintf(stderr, "error:%x\n", err);
- return errno;
- } else if (err != 0)
+ if (err < 0)
+ perror("data-set management");
+ else if (err != 0)
fprintf(stderr, "NVME IO command error:%s(%x)\n",
nvme_status_to_string(err), err);
else
"flushed by the controller, from any namespace, depending on controller and "\
"associated namespace status.";
const char *namespace_id = "identifier of desired namespace";
- int err;
+ int err, fd;
struct config {
__u32 namespace_id;
{NULL}
};
- parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
err = nvme_flush(fd, cfg.namespace_id);
if (err < 0)
- return errno;
+ perror("flush");
else if (err != 0)
fprintf(stderr, "NVME IO command error:%s(%x)\n",
nvme_status_to_string(err), err);
const char *rtype = "hex reservation type";
const char *racqa = "reservation acquiry action";
const char *iekey = "ignore existing res. key";
- int err;
+ int err, fd;
struct config {
__u32 namespace_id;
{NULL}
};
- parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
if (!cfg.namespace_id)
- cfg.namespace_id = get_nsid();
+ cfg.namespace_id = get_nsid(fd);
if (cfg.racqa > 7) {
fprintf(stderr, "invalid racqa:%d\n", cfg.racqa);
return EINVAL;
err = nvme_resv_acquire(fd, cfg.namespace_id, cfg.rtype, cfg.racqa,
!!cfg.iekey, cfg.crkey, cfg.prkey);
if (err < 0)
- return errno;
+ perror("reservation acquire");
else if (err != 0)
fprintf(stderr, "NVME IO command error:%04x\n", err);
else
const char *nrkey = "new reservation key";
const char *rrega = "reservation registration action";
const char *cptpl = "change persistence through power loss setting";
- int err;
+ int err, fd;
struct config {
__u32 namespace_id;
{NULL}
};
- parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
if (!cfg.namespace_id)
- cfg.namespace_id = get_nsid();
+ cfg.namespace_id = get_nsid(fd);
if (cfg.cptpl > 3) {
fprintf(stderr, "invalid cptpl:%d\n", cfg.cptpl);
return EINVAL;
err = nvme_resv_register(fd, cfg.namespace_id, cfg.rrega, cfg.cptpl,
!!cfg.iekey, cfg.crkey, cfg.nrkey);
if (err < 0)
- return errno;
+ perror("reservation register");
else if (err != 0)
fprintf(stderr, "NVME IO command error:%04x\n", err);
else
const char *iekey = "ignore existing res. key";
const char *rtype = "hex reservation type";
const char *rrela = "reservation release action";
- int err;
+ int err, fd;
struct config {
__u32 namespace_id;
{NULL}
};
- parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
if (!cfg.namespace_id)
- cfg.namespace_id = get_nsid();
+ cfg.namespace_id = get_nsid(fd);
if (cfg.iekey > 1) {
fprintf(stderr, "invalid iekey:%d\n", cfg.iekey);
return EINVAL;
err = nvme_resv_release(fd, cfg.namespace_id, cfg.rtype, cfg.rrela,
!!cfg.iekey, cfg.crkey);
if (err < 0)
- return errno;
+ perror("reservation release");
else if (err != 0)
fprintf(stderr, "NVME IO command error:%04x\n", err);
else
const char *numd = "number of dwords to transfer";
const char *raw_binary = "dump output in binary format";
- int err, fmt;
+ int err, fmt, fd;
struct nvme_reservation_status *status;
struct config {
{NULL}
};
- parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
fmt = validate_output_format(cfg.output_format);
if (fmt < 0)
fmt = BINARY;
if (!cfg.namespace_id)
- cfg.namespace_id = get_nsid();
+ cfg.namespace_id = get_nsid(fd);
if (!cfg.numd || cfg.numd > (0x1000 >> 2))
cfg.numd = 0x1000 >> 2;
err = nvme_resv_report(fd, cfg.namespace_id, cfg.numd, status);
if (err < 0)
- return errno;
+ perror("reservation report");
else if (err != 0)
fprintf(stderr, "NVME IO command error:%04x\n", err);
else {
struct timeval start_time, end_time;
void *buffer, *mbuffer = NULL;
int err = 0;
- int dfd, mfd;
+ int dfd, mfd, fd;
int flags = opcode & 1 ? O_RDONLY : O_WRONLY | O_CREAT;
int mode = S_IRUSR | S_IWUSR |S_IRGRP | S_IWGRP| S_IROTH;
__u16 control = 0;
{NULL}
};
- parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
dfd = mfd = opcode & 1 ? STDIN_FILENO : STDOUT_FILENO;
if (cfg.prinfo > 0xf)
buffer_size = cfg.data_size;
}
- if (posix_memalign(&buffer, getpagesize(), buffer_size))
+ if (posix_memalign(&buffer, getpagesize(), buffer_size)) {
+ fprintf(stderr, "can not allocate io payload\n");
return ENOMEM;
+ }
memset(buffer, 0, cfg.data_size);
if (cfg.metadata_size) {
mbuffer = malloc(cfg.metadata_size);
if (!mbuffer) {
free(buffer);
+ fprintf(stderr, "can not allocate io metadata payload\n");
return ENOMEM;
}
}
const char *raw_binary = "dump output in binary format";
const char *namespace_id = "desired namespace";
const char *nssf = "NVMe Security Specific Field";
- int err;
+ int err, fd;
void *sec_buf = NULL;
__u32 result;
{NULL}
};
- parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
if (cfg.size) {
if (posix_memalign(&sec_buf, getpagesize(), cfg.size)) {
err = nvme_sec_recv(fd, cfg.namespace_id, cfg.nssf, cfg.spsp,
cfg.secp, cfg.al, cfg.size, sec_buf, &result);
if (err < 0)
- return errno;
+ perror("security receive");
else if (err != 0)
fprintf(stderr, "NVME Security Receive Command Error:%d\n",
err);
static int passthru(int argc, char **argv, int ioctl_cmd, const char *desc, struct command *cmd)
{
void *data = NULL, *metadata = NULL;
- int err = 0, wfd = STDIN_FILENO;
+ int err = 0, wfd = STDIN_FILENO, fd;
__u32 result;
struct config {
{NULL}
};
- parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
+ fd = parse_and_open(argc, argv, desc, command_line_options, &cfg, sizeof(cfg));
if (strlen(cfg.input_file)){
wfd = open(cfg.input_file, O_RDONLY,
if (cfg.metadata_len)
metadata = malloc(cfg.metadata_len);
if (cfg.data_len) {
- if (posix_memalign(&data, getpagesize(), cfg.data_len))
- exit(ENOMEM);
+ if (posix_memalign(&data, getpagesize(), cfg.data_len)) {
+ fprintf(stderr, "can not allocate data payload\n");
+ return ENOMEM;
+ }
memset(data, cfg.prefill, cfg.data_len);
if (!cfg.read && !cfg.write) {