Incorporate feedback from bde@ based on r252672 changes:
* Use 0/1 instead of sysexits. Man pages are confusing on this topic, but 0/1 is sufficient for nvmecontrol. * Use err function family where possible instead of fprintf/exit. * Fix some typing errors. * Clean up some error message inconsistencies. Sponsored by: Intel Submitted by: bde (parts of firmware.c changes) MFC after: 3 days
This commit is contained in:
parent
ec526ea90b
commit
821ef73ca6
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=253109
@ -29,13 +29,12 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
|
||||||
#include <errno.h>
|
#include <err.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sysexits.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "nvmecontrol.h"
|
#include "nvmecontrol.h"
|
||||||
@ -45,7 +44,7 @@ devlist_usage(void)
|
|||||||
{
|
{
|
||||||
fprintf(stderr, "usage:\n");
|
fprintf(stderr, "usage:\n");
|
||||||
fprintf(stderr, DEVLIST_USAGE);
|
fprintf(stderr, DEVLIST_USAGE);
|
||||||
exit(EX_USAGE);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t
|
static inline uint32_t
|
||||||
@ -62,9 +61,7 @@ devlist(int argc, char *argv[])
|
|||||||
struct nvme_namespace_data nsdata;
|
struct nvme_namespace_data nsdata;
|
||||||
char name[64];
|
char name[64];
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
int ch, ctrlr, exit_code, fd, found;
|
int ch, ctrlr, fd, found, ret;
|
||||||
|
|
||||||
exit_code = EX_OK;
|
|
||||||
|
|
||||||
while ((ch = getopt(argc, argv, "")) != -1) {
|
while ((ch = getopt(argc, argv, "")) != -1) {
|
||||||
switch ((char)ch) {
|
switch ((char)ch) {
|
||||||
@ -80,14 +77,14 @@ devlist(int argc, char *argv[])
|
|||||||
ctrlr++;
|
ctrlr++;
|
||||||
sprintf(name, "%s%d", NVME_CTRLR_PREFIX, ctrlr);
|
sprintf(name, "%s%d", NVME_CTRLR_PREFIX, ctrlr);
|
||||||
|
|
||||||
exit_code = open_dev(name, &fd, 0, 0);
|
ret = open_dev(name, &fd, 0, 0);
|
||||||
|
|
||||||
if (exit_code == EX_NOINPUT)
|
if (ret != 0) {
|
||||||
break;
|
if (fd < 0) {
|
||||||
else if (exit_code == EX_NOPERM) {
|
warnx("could not open /dev/%s\n", name);
|
||||||
printf("Could not open /dev/%s, errno = %d (%s)\n",
|
|
||||||
name, errno, strerror(errno));
|
|
||||||
continue;
|
continue;
|
||||||
|
} else
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
found++;
|
found++;
|
||||||
@ -111,5 +108,5 @@ devlist(int argc, char *argv[])
|
|||||||
if (found == 0)
|
if (found == 0)
|
||||||
printf("No NVMe controllers found.\n");
|
printf("No NVMe controllers found.\n");
|
||||||
|
|
||||||
exit(EX_OK);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
@ -36,14 +36,14 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <errno.h>
|
#include <err.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <inttypes.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sysexits.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "nvmecontrol.h"
|
#include "nvmecontrol.h"
|
||||||
@ -64,60 +64,58 @@ slot_has_valid_firmware(int fd, int slot)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
read_image_file(char *path, void **buf, ssize_t *size)
|
read_image_file(char *path, void **buf, int32_t *size)
|
||||||
{
|
{
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
|
int32_t filesize;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
*size = 0;
|
*size = 0;
|
||||||
*buf = NULL;
|
*buf = NULL;
|
||||||
|
|
||||||
if ((fd = open(path, O_RDONLY)) < 0) {
|
if ((fd = open(path, O_RDONLY)) < 0)
|
||||||
fprintf(stderr, "Unable to open '%s'.\n", path);
|
err(1, "unable to open '%s'", path);
|
||||||
exit(EX_IOERR);
|
if (fstat(fd, &sb) < 0)
|
||||||
}
|
err(1, "unable to stat '%s'", path);
|
||||||
if (fstat(fd, &sb) < 0) {
|
|
||||||
fprintf(stderr, "Unable to stat '%s'.\n", path);
|
/*
|
||||||
close(fd);
|
* The NVMe spec does not explicitly state a maximum firmware image
|
||||||
exit(EX_IOERR);
|
* size, although one can be inferred from the dword size limitation
|
||||||
}
|
* for the size and offset fields in the Firmware Image Download
|
||||||
if ((*buf = malloc(sb.st_size)) == NULL) {
|
* command.
|
||||||
fprintf(stderr, "Unable to malloc %jd bytes.\n",
|
*
|
||||||
sb.st_size);
|
* Technically, the max is UINT32_MAX * sizeof(uint32_t), since the
|
||||||
close(fd);
|
* size and offsets are specified in terms of dwords (not bytes), but
|
||||||
exit(EX_IOERR);
|
* realistically INT32_MAX is sufficient here and simplifies matters
|
||||||
}
|
* a bit.
|
||||||
if ((*size = read(fd, *buf, sb.st_size)) < 0) {
|
*/
|
||||||
fprintf(stderr, "Error reading '%s', errno=%d (%s)\n",
|
if (sb.st_size > INT32_MAX)
|
||||||
path, errno, strerror(errno));
|
errx(1, "size of file '%s' is too large (%jd bytes)",
|
||||||
close(fd);
|
path, (intmax_t)sb.st_size);
|
||||||
exit(EX_IOERR);
|
filesize = (int32_t)sb.st_size;
|
||||||
}
|
if ((*buf = malloc(filesize)) == NULL)
|
||||||
if (*size != sb.st_size) {
|
errx(1, "unable to malloc %zd bytes", filesize);
|
||||||
fprintf(stderr, "Error reading '%s', "
|
if ((*size = read(fd, *buf, filesize)) < 0)
|
||||||
"read %zd bytes, requested %jd bytes\n",
|
err(1, "error reading '%s'", path);
|
||||||
path, *size, sb.st_size);
|
/* XXX assuming no short reads */
|
||||||
close(fd);
|
if (*size != filesize)
|
||||||
exit(EX_IOERR);
|
errx(1,
|
||||||
}
|
"error reading '%s' (read %d bytes, requested %d bytes)",
|
||||||
|
path, *size, filesize);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_firmware(int fd, uint8_t *payload, uint32_t payload_size)
|
update_firmware(int fd, uint8_t *payload, int32_t payload_size)
|
||||||
{
|
{
|
||||||
struct nvme_pt_command pt;
|
struct nvme_pt_command pt;
|
||||||
size_t size;
|
int32_t off, resid, size;
|
||||||
void *chunk;
|
void *chunk;
|
||||||
uint32_t off, resid;
|
|
||||||
int exit_code = EX_OK;
|
|
||||||
|
|
||||||
off = 0;
|
off = 0;
|
||||||
resid = payload_size;
|
resid = payload_size;
|
||||||
|
|
||||||
if ((chunk = malloc((size_t)NVME_MAX_XFER_SIZE)) == NULL) {
|
if ((chunk = malloc(NVME_MAX_XFER_SIZE)) == NULL)
|
||||||
printf("Unable to malloc %d bytes.\n", NVME_MAX_XFER_SIZE);
|
errx(1, "unable to malloc %d bytes", NVME_MAX_XFER_SIZE);
|
||||||
exit(EX_IOERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (resid > 0) {
|
while (resid > 0) {
|
||||||
size = (resid >= NVME_MAX_XFER_SIZE) ?
|
size = (resid >= NVME_MAX_XFER_SIZE) ?
|
||||||
@ -132,26 +130,15 @@ update_firmware(int fd, uint8_t *payload, uint32_t payload_size)
|
|||||||
pt.len = size;
|
pt.len = size;
|
||||||
pt.is_read = 0;
|
pt.is_read = 0;
|
||||||
|
|
||||||
if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) {
|
if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
|
||||||
printf("Firmware image download request failed. "
|
err(1, "firmware download request failed");
|
||||||
"errno=%d (%s)\n",
|
|
||||||
errno, strerror(errno));
|
|
||||||
exit_code = EX_IOERR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nvme_completion_is_error(&pt.cpl)) {
|
if (nvme_completion_is_error(&pt.cpl))
|
||||||
printf("Passthrough command returned error.\n");
|
errx(1, "firmware download request returned error");
|
||||||
exit_code = EX_IOERR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
resid -= size;
|
resid -= size;
|
||||||
off += size;
|
off += size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exit_code != EX_OK)
|
|
||||||
exit(exit_code);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -164,16 +151,11 @@ activate_firmware(int fd, int slot, int activate_action)
|
|||||||
pt.cmd.cdw10 = (activate_action << 3) | slot;
|
pt.cmd.cdw10 = (activate_action << 3) | slot;
|
||||||
pt.is_read = 0;
|
pt.is_read = 0;
|
||||||
|
|
||||||
if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) {
|
if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
|
||||||
printf("Firmware activate request failed. errno=%d (%s)\n",
|
err(1, "firmware activate request failed");
|
||||||
errno, strerror(errno));
|
|
||||||
exit(EX_IOERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nvme_completion_is_error(&pt.cpl)) {
|
if (nvme_completion_is_error(&pt.cpl))
|
||||||
printf("Passthrough command returned error.\n");
|
errx(1, "firmware activate request returned error");
|
||||||
exit(EX_IOERR);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -181,7 +163,7 @@ firmware_usage(void)
|
|||||||
{
|
{
|
||||||
fprintf(stderr, "usage:\n");
|
fprintf(stderr, "usage:\n");
|
||||||
fprintf(stderr, FIRMWARE_USAGE);
|
fprintf(stderr, FIRMWARE_USAGE);
|
||||||
exit(EX_USAGE);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -192,7 +174,7 @@ firmware(int argc, char *argv[])
|
|||||||
char ch, *p, *image = NULL;
|
char ch, *p, *image = NULL;
|
||||||
char *controller = NULL, prompt[64];
|
char *controller = NULL, prompt[64];
|
||||||
void *buf = NULL;
|
void *buf = NULL;
|
||||||
ssize_t size;
|
int32_t size = 0;
|
||||||
struct nvme_controller_data cdata;
|
struct nvme_controller_data cdata;
|
||||||
|
|
||||||
a_flag = s_flag = f_flag = false;
|
a_flag = s_flag = f_flag = false;
|
||||||
@ -252,34 +234,24 @@ firmware(int argc, char *argv[])
|
|||||||
open_dev(controller, &fd, 1, 1);
|
open_dev(controller, &fd, 1, 1);
|
||||||
read_controller_data(fd, &cdata);
|
read_controller_data(fd, &cdata);
|
||||||
|
|
||||||
if (cdata.oacs.firmware == 0) {
|
if (cdata.oacs.firmware == 0)
|
||||||
fprintf(stderr,
|
errx(1,
|
||||||
"Controller does not support firmware "
|
"controller does not support firmware activate/download");
|
||||||
"activate/download.\n");
|
|
||||||
exit(EX_IOERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (f_flag && slot == 1 && cdata.frmw.slot1_ro) {
|
if (f_flag && slot == 1 && cdata.frmw.slot1_ro)
|
||||||
fprintf(stderr, "Slot %d is marked as read only.\n", slot);
|
errx(1, "slot %d is marked as read only", slot);
|
||||||
exit(EX_IOERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (slot > cdata.frmw.num_slots) {
|
if (slot > cdata.frmw.num_slots)
|
||||||
fprintf(stderr,
|
errx(1,
|
||||||
"Slot %d was specified but controller only "
|
"slot %d specified but controller only supports %d slots",
|
||||||
"supports %d firmware slots.\n",
|
|
||||||
slot, cdata.frmw.num_slots);
|
slot, cdata.frmw.num_slots);
|
||||||
exit(EX_IOERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!slot_has_valid_firmware(fd, slot)) {
|
if (!slot_has_valid_firmware(fd, slot))
|
||||||
fprintf(stderr,
|
errx(1,
|
||||||
"Slot %d does not contain valid firmware.\n"
|
"slot %d does not contain valid firmware,\n"
|
||||||
"Try 'nvmecontrol logpage -p 3 %s' to get a list "
|
"try 'nvmecontrol logpage -p 3 %s' to get a list "
|
||||||
"of available firmware images.\n",
|
"of available images\n",
|
||||||
slot, controller);
|
slot, controller);
|
||||||
exit(EX_IOERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (f_flag && a_flag)
|
if (f_flag && a_flag)
|
||||||
printf("You are about to download and activate "
|
printf("You are about to download and activate "
|
||||||
@ -305,7 +277,7 @@ firmware(int argc, char *argv[])
|
|||||||
if (strncasecmp(prompt, "yes", 3) == 0)
|
if (strncasecmp(prompt, "yes", 3) == 0)
|
||||||
break;
|
break;
|
||||||
if (strncasecmp(prompt, "no", 2) == 0)
|
if (strncasecmp(prompt, "no", 2) == 0)
|
||||||
exit(EX_OK);
|
exit(1);
|
||||||
printf("Please answer \"yes\" or \"no\". ");
|
printf("Please answer \"yes\" or \"no\". ");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -331,5 +303,5 @@ firmware(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
exit(EX_OK);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
@ -30,13 +30,13 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sysexits.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "nvmecontrol.h"
|
#include "nvmecontrol.h"
|
||||||
@ -139,7 +139,7 @@ identify_usage(void)
|
|||||||
{
|
{
|
||||||
fprintf(stderr, "usage:\n");
|
fprintf(stderr, "usage:\n");
|
||||||
fprintf(stderr, IDENTIFY_USAGE);
|
fprintf(stderr, IDENTIFY_USAGE);
|
||||||
exit(EX_USAGE);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -177,16 +177,16 @@ identify_ctrlr(int argc, char *argv[])
|
|||||||
hexlength = offsetof(struct nvme_controller_data,
|
hexlength = offsetof(struct nvme_controller_data,
|
||||||
reserved5);
|
reserved5);
|
||||||
print_hex(&cdata, hexlength);
|
print_hex(&cdata, hexlength);
|
||||||
exit(EX_OK);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verboseflag == 1) {
|
if (verboseflag == 1) {
|
||||||
printf("-v not currently supported without -x.\n");
|
fprintf(stderr, "-v not currently supported without -x\n");
|
||||||
identify_usage();
|
identify_usage();
|
||||||
}
|
}
|
||||||
|
|
||||||
print_controller(&cdata);
|
print_controller(&cdata);
|
||||||
exit(EX_OK);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -231,10 +231,8 @@ identify_ns(int argc, char *argv[])
|
|||||||
nsloc = strnstr(argv[optind], NVME_NS_PREFIX, 10);
|
nsloc = strnstr(argv[optind], NVME_NS_PREFIX, 10);
|
||||||
if (nsloc != NULL)
|
if (nsloc != NULL)
|
||||||
nsid = strtol(nsloc + 2, NULL, 10);
|
nsid = strtol(nsloc + 2, NULL, 10);
|
||||||
if (nsloc == NULL || (nsid == 0 && errno != 0)) {
|
if (nsloc == NULL || (nsid == 0 && errno != 0))
|
||||||
printf("Invalid namespace ID %s.\n", argv[optind]);
|
errx(1, "invalid namespace ID '%s'", argv[optind]);
|
||||||
exit(EX_IOERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We send IDENTIFY commands to the controller, not the namespace,
|
* We send IDENTIFY commands to the controller, not the namespace,
|
||||||
@ -253,16 +251,16 @@ identify_ns(int argc, char *argv[])
|
|||||||
hexlength = offsetof(struct nvme_namespace_data,
|
hexlength = offsetof(struct nvme_namespace_data,
|
||||||
reserved6);
|
reserved6);
|
||||||
print_hex(&nsdata, hexlength);
|
print_hex(&nsdata, hexlength);
|
||||||
exit(EX_OK);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verboseflag == 1) {
|
if (verboseflag == 1) {
|
||||||
printf("-v not currently supported without -x.\n");
|
fprintf(stderr, "-v not currently supported without -x\n");
|
||||||
identify_usage();
|
identify_usage();
|
||||||
}
|
}
|
||||||
|
|
||||||
print_namespace(&nsdata);
|
print_namespace(&nsdata);
|
||||||
exit(EX_OK);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <sys/ioccom.h>
|
#include <sys/ioccom.h>
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
@ -41,7 +42,6 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sysexits.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "nvmecontrol.h"
|
#include "nvmecontrol.h"
|
||||||
@ -52,14 +52,13 @@ __FBSDID("$FreeBSD$");
|
|||||||
typedef void (*print_fn_t)(void *buf, uint32_t size);
|
typedef void (*print_fn_t)(void *buf, uint32_t size);
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
get_log_buffer(size_t size)
|
get_log_buffer(uint32_t size)
|
||||||
{
|
{
|
||||||
void *buf;
|
void *buf;
|
||||||
|
|
||||||
if ((buf = malloc(size)) == NULL) {
|
if ((buf = malloc(size)) == NULL)
|
||||||
fprintf(stderr, "Unable to malloc %zd bytes\n", size);
|
errx(1, "unable to malloc %u bytes", size);
|
||||||
exit(EX_IOERR);
|
|
||||||
}
|
|
||||||
memset(buf, 0, size);
|
memset(buf, 0, size);
|
||||||
return (buf);
|
return (buf);
|
||||||
}
|
}
|
||||||
@ -79,16 +78,11 @@ read_logpage(int fd, uint8_t log_page, int nsid, void *payload,
|
|||||||
pt.len = payload_size;
|
pt.len = payload_size;
|
||||||
pt.is_read = 1;
|
pt.is_read = 1;
|
||||||
|
|
||||||
if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) {
|
if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
|
||||||
printf("Get log page request failed. errno=%d (%s)\n",
|
err(1, "get log page request failed");
|
||||||
errno, strerror(errno));
|
|
||||||
exit(EX_IOERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nvme_completion_is_error(&pt.cpl)) {
|
if (nvme_completion_is_error(&pt.cpl))
|
||||||
printf("Passthrough command returned error.\n");
|
errx(1, "get log page request returned error");
|
||||||
exit(EX_IOERR);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -242,7 +236,7 @@ logpage_usage(void)
|
|||||||
{
|
{
|
||||||
fprintf(stderr, "usage:\n");
|
fprintf(stderr, "usage:\n");
|
||||||
fprintf(stderr, LOGPAGE_USAGE);
|
fprintf(stderr, LOGPAGE_USAGE);
|
||||||
exit(EX_USAGE);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -254,7 +248,7 @@ logpage(int argc, char *argv[])
|
|||||||
int allow_ns = false;
|
int allow_ns = false;
|
||||||
char ch, *p, *nsloc = NULL;
|
char ch, *p, *nsloc = NULL;
|
||||||
char *cname = NULL;
|
char *cname = NULL;
|
||||||
size_t size;
|
uint32_t size;
|
||||||
void *buf;
|
void *buf;
|
||||||
struct logpage_function *f;
|
struct logpage_function *f;
|
||||||
struct nvme_controller_data cdata;
|
struct nvme_controller_data cdata;
|
||||||
@ -313,28 +307,20 @@ logpage(int argc, char *argv[])
|
|||||||
/* If a namespace id was specified, validate it's use */
|
/* If a namespace id was specified, validate it's use */
|
||||||
if (strstr(argv[optind], NVME_NS_PREFIX) != NULL) {
|
if (strstr(argv[optind], NVME_NS_PREFIX) != NULL) {
|
||||||
if (!allow_ns) {
|
if (!allow_ns) {
|
||||||
if (log_page != NVME_LOG_HEALTH_INFORMATION) {
|
if (log_page != NVME_LOG_HEALTH_INFORMATION)
|
||||||
fprintf(stderr,
|
errx(1,
|
||||||
"Namespace ID not valid for log page %d.\n",
|
"log page %d valid only at controller level",
|
||||||
log_page);
|
log_page);
|
||||||
} else if (cdata.lpa.ns_smart == 0) {
|
else if (cdata.lpa.ns_smart == 0)
|
||||||
fprintf(stderr,
|
errx(1,
|
||||||
"Controller does not support per "
|
"controller does not support per "
|
||||||
"namespace SMART/Health information.\n");
|
"namespace smart/health information");
|
||||||
}
|
|
||||||
close(fd);
|
|
||||||
exit(EX_IOERR);
|
|
||||||
}
|
}
|
||||||
nsloc = strnstr(argv[optind], NVME_NS_PREFIX, 10);
|
nsloc = strnstr(argv[optind], NVME_NS_PREFIX, 10);
|
||||||
if (nsloc != NULL)
|
if (nsloc != NULL)
|
||||||
nsid = strtol(nsloc + 2, NULL, 10);
|
nsid = strtol(nsloc + 2, NULL, 10);
|
||||||
if (nsloc == NULL || (nsid == 0 && errno != 0)) {
|
if (nsloc == NULL || (nsid == 0 && errno != 0))
|
||||||
fprintf(stderr,
|
errx(1, "invalid namespace id '%s'", argv[optind]);
|
||||||
"Invalid namespace ID %s.\n",
|
|
||||||
argv[optind]);
|
|
||||||
close(fd);
|
|
||||||
exit(EX_IOERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* User is asking for per namespace log page information
|
* User is asking for per namespace log page information
|
||||||
@ -384,5 +370,5 @@ logpage(int argc, char *argv[])
|
|||||||
print_fn(buf, size);
|
print_fn(buf, size);
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
exit(EX_OK);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
@ -32,14 +32,13 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <errno.h>
|
#include <err.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sysexits.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "nvmecontrol.h"
|
#include "nvmecontrol.h"
|
||||||
@ -71,7 +70,7 @@ usage(void)
|
|||||||
fprintf(stderr, "%s", f->usage);
|
fprintf(stderr, "%s", f->usage);
|
||||||
f++;
|
f++;
|
||||||
}
|
}
|
||||||
exit(EX_USAGE);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -134,16 +133,11 @@ read_controller_data(int fd, struct nvme_controller_data *cdata)
|
|||||||
pt.len = sizeof(*cdata);
|
pt.len = sizeof(*cdata);
|
||||||
pt.is_read = 1;
|
pt.is_read = 1;
|
||||||
|
|
||||||
if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) {
|
if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
|
||||||
printf("Identify request failed. errno=%d (%s)\n",
|
err(1, "identify request failed");
|
||||||
errno, strerror(errno));
|
|
||||||
exit(EX_IOERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nvme_completion_is_error(&pt.cpl)) {
|
if (nvme_completion_is_error(&pt.cpl))
|
||||||
printf("Passthrough command returned error.\n");
|
errx(1, "identify request returned error");
|
||||||
exit(EX_IOERR);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -158,16 +152,11 @@ read_namespace_data(int fd, int nsid, struct nvme_namespace_data *nsdata)
|
|||||||
pt.len = sizeof(*nsdata);
|
pt.len = sizeof(*nsdata);
|
||||||
pt.is_read = 1;
|
pt.is_read = 1;
|
||||||
|
|
||||||
if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) {
|
if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
|
||||||
printf("Identify request failed. errno=%d (%s)\n",
|
err(1, "identify request failed");
|
||||||
errno, strerror(errno));
|
|
||||||
exit(EX_IOERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nvme_completion_is_error(&pt.cpl)) {
|
if (nvme_completion_is_error(&pt.cpl))
|
||||||
printf("Passthrough command returned error.\n");
|
errx(1, "identify request returned error");
|
||||||
exit(EX_IOERR);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -178,38 +167,35 @@ open_dev(const char *str, int *fd, int show_error, int exit_on_error)
|
|||||||
|
|
||||||
if (!strnstr(str, NVME_CTRLR_PREFIX, strlen(NVME_CTRLR_PREFIX))) {
|
if (!strnstr(str, NVME_CTRLR_PREFIX, strlen(NVME_CTRLR_PREFIX))) {
|
||||||
if (show_error)
|
if (show_error)
|
||||||
fprintf(stderr,
|
warnx("controller/namespace ids must begin with '%s'",
|
||||||
"Controller/namespace IDs must begin with '%s'.\n",
|
|
||||||
NVME_CTRLR_PREFIX);
|
NVME_CTRLR_PREFIX);
|
||||||
if (exit_on_error)
|
if (exit_on_error)
|
||||||
exit(EX_USAGE);
|
exit(1);
|
||||||
else
|
else
|
||||||
return (EX_USAGE);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(full_path, sizeof(full_path), "/dev/%s", str);
|
snprintf(full_path, sizeof(full_path), "/dev/%s", str);
|
||||||
if (stat(full_path, &devstat) != 0) {
|
if (stat(full_path, &devstat) != 0) {
|
||||||
if (show_error)
|
if (show_error)
|
||||||
fprintf(stderr, "Could not stat %s. errno=%d (%s)\n",
|
warn("could not stat %s", full_path);
|
||||||
full_path, errno, strerror(errno));
|
|
||||||
if (exit_on_error)
|
if (exit_on_error)
|
||||||
exit(EX_NOINPUT);
|
exit(1);
|
||||||
else
|
else
|
||||||
return (EX_NOINPUT);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
*fd = open(full_path, O_RDWR);
|
*fd = open(full_path, O_RDWR);
|
||||||
if (*fd < 0) {
|
if (*fd < 0) {
|
||||||
if (show_error)
|
if (show_error)
|
||||||
fprintf(stderr, "Could not open %s. errno=%d (%s)\n",
|
warn("could not open %s", full_path);
|
||||||
full_path, errno, strerror(errno));
|
|
||||||
if (exit_on_error)
|
if (exit_on_error)
|
||||||
exit(EX_NOPERM);
|
exit(1);
|
||||||
else
|
else
|
||||||
return (EX_NOPERM);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (EX_OK);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -31,14 +31,13 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <sys/ioccom.h>
|
#include <sys/ioccom.h>
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <errno.h>
|
#include <err.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sysexits.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "nvmecontrol.h"
|
#include "nvmecontrol.h"
|
||||||
@ -72,7 +71,7 @@ perftest_usage(void)
|
|||||||
{
|
{
|
||||||
fprintf(stderr, "usage:\n");
|
fprintf(stderr, "usage:\n");
|
||||||
fprintf(stderr, PERFTEST_USAGE);
|
fprintf(stderr, PERFTEST_USAGE);
|
||||||
exit(EX_USAGE);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -168,14 +167,10 @@ perftest(int argc, char *argv[])
|
|||||||
perftest_usage();
|
perftest_usage();
|
||||||
|
|
||||||
open_dev(argv[optind], &fd, 1, 1);
|
open_dev(argv[optind], &fd, 1, 1);
|
||||||
if (ioctl(fd, ioctl_cmd, &io_test) < 0) {
|
if (ioctl(fd, ioctl_cmd, &io_test) < 0)
|
||||||
fprintf(stderr, "NVME_IO_TEST failed. errno=%d (%s)\n", errno,
|
err(1, "ioctl NVME_IO_TEST failed");
|
||||||
strerror(errno));
|
|
||||||
close(fd);
|
|
||||||
exit(EX_IOERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
print_perftest(&io_test, perthread);
|
print_perftest(&io_test, perthread);
|
||||||
exit(EX_OK);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
@ -30,12 +30,11 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/ioccom.h>
|
#include <sys/ioccom.h>
|
||||||
|
|
||||||
#include <errno.h>
|
#include <err.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sysexits.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "nvmecontrol.h"
|
#include "nvmecontrol.h"
|
||||||
@ -45,7 +44,7 @@ reset_usage(void)
|
|||||||
{
|
{
|
||||||
fprintf(stderr, "usage:\n");
|
fprintf(stderr, "usage:\n");
|
||||||
fprintf(stderr, RESET_USAGE);
|
fprintf(stderr, RESET_USAGE);
|
||||||
exit(EX_USAGE);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -65,11 +64,8 @@ reset(int argc, char *argv[])
|
|||||||
reset_usage();
|
reset_usage();
|
||||||
|
|
||||||
open_dev(argv[optind], &fd, 1, 1);
|
open_dev(argv[optind], &fd, 1, 1);
|
||||||
if (ioctl(fd, NVME_RESET_CONTROLLER) < 0) {
|
if (ioctl(fd, NVME_RESET_CONTROLLER) < 0)
|
||||||
printf("Reset request to %s failed. errno=%d (%s)\n",
|
err(1, "reset request to %s failed", argv[optind]);
|
||||||
argv[optind], errno, strerror(errno));
|
|
||||||
exit(EX_IOERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
exit(EX_OK);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user