From 5dc463f9a5abf311e886e0000e5df1428415bbbf Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Fri, 13 Nov 2020 02:05:45 +0000 Subject: [PATCH] Improve nvmecontrol error reporting. MFC after: 1 week Sponsored by: iXsystems, Inc. --- sbin/nvmecontrol/comnd.c | 13 +++-- sbin/nvmecontrol/devlist.c | 9 ++- sbin/nvmecontrol/firmware.c | 38 ++++++------ sbin/nvmecontrol/format.c | 21 ++++--- sbin/nvmecontrol/identify.c | 7 ++- sbin/nvmecontrol/logpage.c | 16 +++--- sbin/nvmecontrol/modules/wdc/wdc.c | 42 +++++++------- sbin/nvmecontrol/ns.c | 92 +++++++++++++++++------------- sbin/nvmecontrol/nvmecontrol.c | 19 +++--- sbin/nvmecontrol/nvmecontrol.h | 4 +- sbin/nvmecontrol/passthru.c | 11 ++-- sbin/nvmecontrol/perftest.c | 3 +- sbin/nvmecontrol/power.c | 12 ++-- sbin/nvmecontrol/reset.c | 3 +- sbin/nvmecontrol/resv.c | 17 +++--- sbin/nvmecontrol/sanitize.c | 16 +++--- 16 files changed, 180 insertions(+), 143 deletions(-) diff --git a/sbin/nvmecontrol/comnd.c b/sbin/nvmecontrol/comnd.c index 4233384eb1e..b8c9abc8684 100644 --- a/sbin/nvmecontrol/comnd.c +++ b/sbin/nvmecontrol/comnd.c @@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include "comnd.h" @@ -77,7 +78,7 @@ gen_usage(const struct cmd *t) SLIST_FOREACH(walker, &t->subcmd, link) { print_usage(walker); } - exit(1); + exit(EX_USAGE); } int @@ -158,7 +159,7 @@ arg_help(int argc __unused, char * const *argv, const struct cmd *f) fprintf(stderr, "%-30.30s - %s\n", buf, opts[i].descr); } } - exit(1); + exit(EX_USAGE); } static int @@ -188,10 +189,10 @@ arg_parse(int argc, char * const * argv, const struct cmd *f) n++; lopts = malloc((n + 2) * sizeof(struct option)); if (lopts == NULL) - err(1, "option memory"); + err(EX_OSERR, "option memory"); p = shortopts = malloc((2 * n + 3) * sizeof(char)); if (shortopts == NULL) - err(1, "shortopts memory"); + err(EX_OSERR, "shortopts memory"); idx = 0; for (i = 0; i < n; i++) { lopts[i].name = opts[i].long_arg; @@ -279,7 +280,7 @@ arg_parse(int argc, char * const * argv, const struct cmd *f) fprintf(stderr, "Bad value to --%s: %s\n", opts[idx].long_arg, optarg); free(lopts); free(shortopts); - exit(1); + exit(EX_USAGE); } /* @@ -301,7 +302,7 @@ cmd_load_dir(const char *dir __unused, cmd_load_cb_t cb __unused, void *argp __u continue; asprintf(&path, "%s/%s", dir, dent->d_name); if (path == NULL) - err(1, "Can't malloc for path, giving up."); + err(EX_OSERR, "Can't malloc for path, giving up."); if ((h = dlopen(path, RTLD_NOW | RTLD_GLOBAL)) == NULL) warnx("Can't load %s: %s", path, dlerror()); else { diff --git a/sbin/nvmecontrol/devlist.c b/sbin/nvmecontrol/devlist.c index bae2fc36129..35dd1b47a81 100644 --- a/sbin/nvmecontrol/devlist.c +++ b/sbin/nvmecontrol/devlist.c @@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include "nvmecontrol.h" @@ -102,12 +103,14 @@ devlist(const struct cmd *f, int argc, char *argv[]) continue; found++; - read_controller_data(fd, &cdata); + if (read_controller_data(fd, &cdata)) + continue; nvme_strvis(mn, cdata.mn, sizeof(mn), NVME_MODEL_NUMBER_LENGTH); printf("%6s: %s\n", name, mn); for (i = 0; i < cdata.nn; i++) { - read_namespace_data(fd, i + 1, &nsdata); + if (read_namespace_data(fd, i + 1, &nsdata)) + continue; if (nsdata.nsze == 0) continue; sprintf(name, "%s%d%s%d", NVME_CTRLR_PREFIX, ctrlr, @@ -124,7 +127,7 @@ devlist(const struct cmd *f, int argc, char *argv[]) if (found == 0) { printf("No NVMe controllers found.\n"); - exit(1); + exit(EX_UNAVAILABLE); } exit(0); diff --git a/sbin/nvmecontrol/firmware.c b/sbin/nvmecontrol/firmware.c index 970765f646f..d35ef895b59 100644 --- a/sbin/nvmecontrol/firmware.c +++ b/sbin/nvmecontrol/firmware.c @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include "nvmecontrol.h" @@ -123,9 +124,9 @@ read_image_file(const char *path, void **buf, int32_t *size) *buf = NULL; if ((fd = open(path, O_RDONLY)) < 0) - err(1, "unable to open '%s'", path); + err(EX_NOINPUT, "unable to open '%s'", path); if (fstat(fd, &sb) < 0) - err(1, "unable to stat '%s'", path); + err(EX_NOINPUT, "unable to stat '%s'", path); /* * The NVMe spec does not explicitly state a maximum firmware image @@ -139,16 +140,16 @@ read_image_file(const char *path, void **buf, int32_t *size) * a bit. */ if (sb.st_size > INT32_MAX) - errx(1, "size of file '%s' is too large (%jd bytes)", + errx(EX_USAGE, "size of file '%s' is too large (%jd bytes)", path, (intmax_t)sb.st_size); filesize = (int32_t)sb.st_size; if ((*buf = malloc(filesize)) == NULL) - errx(1, "unable to malloc %d bytes", filesize); + errx(EX_OSERR, "unable to malloc %d bytes", filesize); if ((*size = read(fd, *buf, filesize)) < 0) - err(1, "error reading '%s'", path); + err(EX_IOERR, "error reading '%s'", path); /* XXX assuming no short reads */ if (*size != filesize) - errx(1, + errx(EX_IOERR, "error reading '%s' (read %d bytes, requested %d bytes)", path, *size, filesize); close(fd); @@ -168,12 +169,12 @@ update_firmware(int fd, uint8_t *payload, int32_t payload_size, uint8_t fwug) if (fwug != 0 && fwug != 0xFF) max_xfer_size = ((uint64_t)fwug << 12); else if (ioctl(fd, NVME_GET_MAX_XFER_SIZE, &max_xfer_size) < 0) - err(1, "query max transfer size failed"); + err(EX_IOERR, "query max transfer size failed"); if (max_xfer_size > NVME_MAX_XFER_SIZE) max_xfer_size = NVME_MAX_XFER_SIZE; if ((chunk = aligned_alloc(PAGE_SIZE, max_xfer_size)) == NULL) - errx(1, "unable to malloc %zd bytes", (size_t)max_xfer_size); + errx(EX_OSERR, "unable to malloc %zd bytes", (size_t)max_xfer_size); while (resid > 0) { size = (resid >= (int32_t)max_xfer_size) ? @@ -189,10 +190,10 @@ update_firmware(int fd, uint8_t *payload, int32_t payload_size, uint8_t fwug) pt.is_read = 0; if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) - err(1, "firmware download request failed"); + err(EX_IOERR, "firmware download request failed"); if (nvme_completion_is_error(&pt.cpl)) - errx(1, "firmware download request returned error"); + errx(EX_IOERR, "firmware download request returned error"); resid -= size; off += size; @@ -212,7 +213,7 @@ activate_firmware(int fd, int slot, int activate_action) pt.is_read = 0; if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) - err(1, "firmware activate request failed"); + err(EX_IOERR, "firmware activate request failed"); sct = NVME_STATUS_GET_SCT(pt.cpl.status); sc = NVME_STATUS_GET_SC(pt.cpl.status); @@ -222,7 +223,7 @@ activate_firmware(int fd, int slot, int activate_action) return 1; if (nvme_completion_is_error(&pt.cpl)) - errx(1, "firmware activate request returned error"); + errx(EX_IOERR, "firmware activate request returned error"); return 0; } @@ -278,32 +279,33 @@ firmware(const struct cmd *f, int argc, char *argv[]) } free(path); - read_controller_data(fd, &cdata); + if (read_controller_data(fd, &cdata)) + errx(EX_IOERR, "Identify request failed"); oacs_fw = (cdata.oacs >> NVME_CTRLR_DATA_OACS_FIRMWARE_SHIFT) & NVME_CTRLR_DATA_OACS_FIRMWARE_MASK; if (oacs_fw == 0) - errx(1, + errx(EX_UNAVAILABLE, "controller does not support firmware activate/download"); fw_slot1_ro = (cdata.frmw >> NVME_CTRLR_DATA_FRMW_SLOT1_RO_SHIFT) & NVME_CTRLR_DATA_FRMW_SLOT1_RO_MASK; if (opt.fw_img && opt.slot == 1 && fw_slot1_ro) - errx(1, "slot %d is marked as read only", opt.slot); + errx(EX_UNAVAILABLE, "slot %d is marked as read only", opt.slot); fw_num_slots = (cdata.frmw >> NVME_CTRLR_DATA_FRMW_NUM_SLOTS_SHIFT) & NVME_CTRLR_DATA_FRMW_NUM_SLOTS_MASK; if (opt.slot > fw_num_slots) - errx(1, + errx(EX_UNAVAILABLE, "slot %d specified but controller only supports %d slots", opt.slot, fw_num_slots); if (opt.activate && opt.fw_img == NULL && !slot_has_valid_firmware(fd, opt.slot)) - errx(1, + errx(EX_UNAVAILABLE, "slot %d does not contain valid firmware,\n" "try 'nvmecontrol logpage -p 3 %s' to get a list " "of available images\n", @@ -336,7 +338,7 @@ firmware(const struct cmd *f, int argc, char *argv[]) if (strncasecmp(prompt, "yes", 3) == 0) break; if (strncasecmp(prompt, "no", 2) == 0) - exit(1); + exit(EX_DATAERR); printf("Please answer \"yes\" or \"no\". "); } diff --git a/sbin/nvmecontrol/format.c b/sbin/nvmecontrol/format.c index d2231a27678..a9ab8056203 100644 --- a/sbin/nvmecontrol/format.c +++ b/sbin/nvmecontrol/format.c @@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include "nvmecontrol.h" @@ -159,29 +160,31 @@ format(const struct cmd *f, int argc, char *argv[]) free(path); /* Check that controller can execute this command. */ - read_controller_data(fd, &cd); + if (read_controller_data(fd, &cd)) + errx(EX_IOERR, "Identify request failed"); if (((cd.oacs >> NVME_CTRLR_DATA_OACS_FORMAT_SHIFT) & NVME_CTRLR_DATA_OACS_FORMAT_MASK) == 0) - errx(1, "controller does not support format"); + errx(EX_UNAVAILABLE, "controller does not support format"); if (((cd.fna >> NVME_CTRLR_DATA_FNA_CRYPTO_ERASE_SHIFT) & NVME_CTRLR_DATA_FNA_CRYPTO_ERASE_MASK) == 0 && ses == SES_CRYPTO) - errx(1, "controller does not support cryptographic erase"); + errx(EX_UNAVAILABLE, "controller does not support cryptographic erase"); if (nsid != NVME_GLOBAL_NAMESPACE_TAG) { if (((cd.fna >> NVME_CTRLR_DATA_FNA_FORMAT_ALL_SHIFT) & NVME_CTRLR_DATA_FNA_FORMAT_ALL_MASK) && ses == SES_NONE) - errx(1, "controller does not support per-NS format"); + errx(EX_UNAVAILABLE, "controller does not support per-NS format"); if (((cd.fna >> NVME_CTRLR_DATA_FNA_ERASE_ALL_SHIFT) & NVME_CTRLR_DATA_FNA_ERASE_ALL_MASK) && ses != SES_NONE) - errx(1, "controller does not support per-NS erase"); + errx(EX_UNAVAILABLE, "controller does not support per-NS erase"); /* Try to keep previous namespace parameters. */ - read_namespace_data(fd, nsid, &nsd); + if (read_namespace_data(fd, nsid, &nsd)) + errx(EX_IOERR, "Identify request failed"); if (lbaf < 0) lbaf = (nsd.flbas >> NVME_NS_DATA_FLBAS_FORMAT_SHIFT) & NVME_NS_DATA_FLBAS_FORMAT_MASK; if (lbaf > nsd.nlbaf) - errx(1, "LBA format is out of range"); + errx(EX_USAGE, "LBA format is out of range"); if (ms < 0) ms = (nsd.flbas >> NVME_NS_DATA_FLBAS_EXTENDED_SHIFT) & NVME_NS_DATA_FLBAS_EXTENDED_MASK; @@ -211,10 +214,10 @@ format(const struct cmd *f, int argc, char *argv[]) (ms << 4) + lbaf); if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) - err(1, "format request failed"); + err(EX_IOERR, "format request failed"); if (nvme_completion_is_error(&pt.cpl)) - errx(1, "format request returned error"); + errx(EX_IOERR, "format request returned error"); close(fd); exit(0); } diff --git a/sbin/nvmecontrol/identify.c b/sbin/nvmecontrol/identify.c index 04aff36917a..86b7369883f 100644 --- a/sbin/nvmecontrol/identify.c +++ b/sbin/nvmecontrol/identify.c @@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include "nvmecontrol.h" @@ -191,7 +192,8 @@ identify_ctrlr(int fd) struct nvme_controller_data cdata; int hexlength; - read_controller_data(fd, &cdata); + if (read_controller_data(fd, &cdata)) + errx(EX_IOERR, "Identify request failed"); close(fd); if (opt.hex) { @@ -214,7 +216,8 @@ identify_ns(int fd, uint32_t nsid) struct nvme_namespace_data nsdata; int hexlength; - read_namespace_data(fd, nsid, &nsdata); + if (read_namespace_data(fd, nsid, &nsdata)) + errx(EX_IOERR, "Identify request failed"); close(fd); if (opt.hex) { diff --git a/sbin/nvmecontrol/logpage.c b/sbin/nvmecontrol/logpage.c index 0acd843860b..2f7cec00559 100644 --- a/sbin/nvmecontrol/logpage.c +++ b/sbin/nvmecontrol/logpage.c @@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -183,7 +184,7 @@ get_log_buffer(uint32_t size) void *buf; if ((buf = malloc(size)) == NULL) - errx(1, "unable to malloc %u bytes", size); + errx(EX_OSERR, "unable to malloc %u bytes", size); memset(buf, 0, size); return (buf); @@ -217,7 +218,7 @@ read_logpage(int fd, uint8_t log_page, uint32_t nsid, uint8_t lsp, pt.is_read = 1; if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) - err(1, "get log page request failed"); + err(EX_IOERR, "get log page request failed"); /* Convert data to host endian */ switch (log_page) { @@ -259,7 +260,7 @@ read_logpage(int fd, uint8_t log_page, uint32_t nsid, uint8_t lsp, } if (nvme_completion_is_error(&pt.cpl)) - errx(1, "get log page request returned error"); + errx(EX_IOERR, "get log page request returned error"); } static void @@ -659,7 +660,7 @@ logpage_help(void) fprintf(stderr, "0x%02x %-10s %s\n", f->log_page, v, f->name); } - exit(1); + exit(EX_USAGE); } static void @@ -697,7 +698,8 @@ logpage(const struct cmd *f, int argc, char *argv[]) } free(path); - read_controller_data(fd, &cdata); + if (read_controller_data(fd, &cdata)) + errx(EX_IOERR, "Identify request failed"); ns_smart = (cdata.lpa >> NVME_CTRLR_DATA_LPA_NS_SMART_SHIFT) & NVME_CTRLR_DATA_LPA_NS_SMART_MASK; @@ -709,10 +711,10 @@ logpage(const struct cmd *f, int argc, char *argv[]) */ if (nsid != NVME_GLOBAL_NAMESPACE_TAG) { if (opt.page != NVME_LOG_HEALTH_INFORMATION) - errx(1, "log page %d valid only at controller level", + errx(EX_USAGE, "log page %d valid only at controller level", opt.page); if (ns_smart == 0) - errx(1, + errx(EX_UNAVAILABLE, "controller does not support per namespace " "smart/health information"); } diff --git a/sbin/nvmecontrol/modules/wdc/wdc.c b/sbin/nvmecontrol/modules/wdc/wdc.c index 7b5ea03cbd0..3f4bc597d1b 100644 --- a/sbin/nvmecontrol/modules/wdc/wdc.c +++ b/sbin/nvmecontrol/modules/wdc/wdc.c @@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -123,7 +124,8 @@ wdc_append_serial_name(int fd, char *buf, size_t len, const char *suffix) len -= strlen(buf); buf += strlen(buf); - read_controller_data(fd, &cdata); + if (read_controller_data(fd, &cdata)) + errx(EX_IOERR, "Identify request failed"); memcpy(sn, cdata.sn, NVME_SERIAL_NUMBER_LENGTH); walker = sn + NVME_SERIAL_NUMBER_LENGTH - 1; while (walker > sn && *walker == ' ') @@ -151,9 +153,9 @@ wdc_get_data(int fd, uint32_t opcode, uint32_t len, uint32_t off, uint32_t cmd, pt.is_read = 1; if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) - err(1, "wdc_get_data request failed"); + err(EX_IOERR, "wdc_get_data request failed"); if (nvme_completion_is_error(&pt.cpl)) - errx(1, "wdc_get_data request returned error"); + errx(EX_IOERR, "wdc_get_data request returned error"); } static void @@ -174,7 +176,7 @@ wdc_do_dump_e6(int fd, char *tmpl, const char *suffix, uint32_t opcode, offset = 0; hdr = malloc(len); if (hdr == NULL) - errx(1, "Can't get buffer to read dump"); + errx(EX_OSERR, "Can't get buffer to read dump"); wdc_get_data(fd, opcode, len, offset, cmd, hdr, len, false); if (memcmp("E6LG", hdr, 4) == 0) { e6lg_flag = true; @@ -183,10 +185,10 @@ wdc_do_dump_e6(int fd, char *tmpl, const char *suffix, uint32_t opcode, /* XXX overwrite protection? */ fd2 = open(tmpl, O_WRONLY | O_CREAT | O_TRUNC, 0644); if (fd2 < 0) - err(1, "open %s", tmpl); + err(EX_CANTCREAT, "open %s", tmpl); buf = aligned_alloc(PAGE_SIZE, NVME_MAX_XFER_SIZE); if (buf == NULL) - errx(1, "Can't get buffer to read dump"); + errx(EX_OSERR, "Can't get buffer to read dump"); offset = 0; len = NVME_MAX_XFER_SIZE; first = 1; @@ -198,7 +200,7 @@ wdc_do_dump_e6(int fd, char *tmpl, const char *suffix, uint32_t opcode, if (first) { len = be32dec(buf + len_off); if (len == 0) - errx(1, "No data for %s", suffix); + errx(EX_PROTOCOL, "No data for %s", suffix); printf("Dumping %d bytes of version %d.%d log to %s\n", len, buf[8], buf[9], tmpl); @@ -212,7 +214,7 @@ wdc_do_dump_e6(int fd, char *tmpl, const char *suffix, uint32_t opcode, first = 0; } if (write(fd2, buf, resid) != (ssize_t)resid) - err(1, "write"); + err(EX_IOERR, "write"); offset += resid; len -= resid; } while (len > 0); @@ -238,9 +240,9 @@ wdc_get_data_dui(int fd, uint32_t opcode, uint32_t len, uint64_t off, pt.is_read = 1; if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) - err(1, "wdc_get_data_dui request failed"); + err(EX_IOERR, "wdc_get_data_dui request failed"); if (nvme_completion_is_error(&pt.cpl)) - errx(1, "wdc_get_data_dui request returned error"); + errx(EX_IOERR, "wdc_get_data_dui request returned error"); } static uint8_t @@ -274,7 +276,7 @@ wdc_get_dui_log_size(int fd, uint32_t opcode, uint8_t data_area, len = 1024; hdr = (uint8_t*)malloc(len); if (hdr == NULL) - errx(1, "Can't get buffer to read header"); + errx(EX_OSERR, "Can't get buffer to read header"); wdc_get_data_dui(fd, opcode, len, 0, hdr, len); hdr += len_off; @@ -307,7 +309,7 @@ wdc_get_dui_log_size(int fd, uint32_t opcode, uint8_t data_area, } } else - errx(1, "ERROR : No valid header "); + errx(EX_PROTOCOL, "ERROR : No valid header "); *log_size = dui_size; free(hdr); @@ -326,13 +328,13 @@ wdc_do_dump_dui(int fd, char *tmpl, uint8_t data_area, wdc_append_serial_name(fd, tmpl, MAXPATHLEN, suffix); wdc_get_dui_log_size(fd, opcode, data_area, &log_len, len_off); if (log_len == 0) - errx(1, "No data for %s", suffix); + errx(EX_PROTOCOL, "No data for %s", suffix); fd2 = open(tmpl, O_WRONLY | O_CREAT | O_TRUNC, 0644); if (fd2 < 0) - err(1, "open %s", tmpl); + err(EX_CANTCREAT, "open %s", tmpl); buf = aligned_alloc(PAGE_SIZE, NVME_MAX_XFER_SIZE); if (buf == NULL) - errx(1, "Can't get buffer to read dump"); + errx(EX_OSERR, "Can't get buffer to read dump"); offset = 0; first = 1; @@ -347,7 +349,7 @@ wdc_do_dump_dui(int fd, char *tmpl, uint8_t data_area, first = 0; } if (write(fd2, buf, resid) != (ssize_t)resid) - err(1, "write"); + err(EX_IOERR, "write"); offset += resid; log_len -= resid; } @@ -376,7 +378,8 @@ wdc_cap_diag(const struct cmd *f, int argc, char *argv[]) } strlcpy(tmpl, opt.template, sizeof(tmpl)); open_dev(opt.dev, &fd, 1, 1); - read_controller_data(fd, &cdata); + if (read_controller_data(fd, &cdata)) + errx(EX_IOERR, "Identify request failed"); vid = cdata.vid; switch (vid) { @@ -390,11 +393,10 @@ wdc_cap_diag(const struct cmd *f, int argc, char *argv[]) WDC_NVME_CAP_DIAG_OPCODE_FA, 512); break; default: - errx(1, "ERROR : WDC: unsupported device (%#x) for this command", vid); + errx(EX_UNAVAILABLE, "ERROR : WDC: unsupported device (%#x) for this command", vid); } close(fd); - - exit(1); + exit(0); } static void diff --git a/sbin/nvmecontrol/ns.c b/sbin/nvmecontrol/ns.c index 0e8589fdc14..dd20e4e4796 100644 --- a/sbin/nvmecontrol/ns.c +++ b/sbin/nvmecontrol/ns.c @@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include "nvmecontrol.h" @@ -414,12 +415,13 @@ nsactive(const struct cmd *f, int argc, char *argv[]) open_dev(path, &fd, 0, 1); } free(path); - read_controller_data(fd, &cd); + if (read_controller_data(fd, &cd)) + errx(EX_IOERR, "Identify request failed"); /* Check that controller can execute this command. */ if (((cd.oacs >> NVME_CTRLR_DATA_OACS_NSMGMT_SHIFT) & NVME_CTRLR_DATA_OACS_NSMGMT_MASK) == 0) - errx(1, "controller does not support namespace management"); + errx(EX_UNAVAILABLE, "controller does not support namespace management"); memset(&pt, 0, sizeof(pt)); pt.cmd.opc = NVME_OPC_IDENTIFY; @@ -429,9 +431,9 @@ nsactive(const struct cmd *f, int argc, char *argv[]) pt.len = sizeof(list); pt.is_read = 1; if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) - err(1, "identify request failed"); + err(EX_IOERR, "identify request failed"); if (nvme_completion_is_error(&pt.cpl)) - errx(1, "identify request returned error"); + errx(EX_IOERR, "identify request returned error"); printf("Active namespaces:\n"); for (i = 0; list[i] != 0; i++) @@ -459,12 +461,13 @@ nsallocated(const struct cmd *f, int argc, char *argv[]) open_dev(path, &fd, 0, 1); } free(path); - read_controller_data(fd, &cd); + if (read_controller_data(fd, &cd)) + errx(EX_IOERR, "Identify request failed"); /* Check that controller can execute this command. */ if (((cd.oacs >> NVME_CTRLR_DATA_OACS_NSMGMT_SHIFT) & NVME_CTRLR_DATA_OACS_NSMGMT_MASK) == 0) - errx(1, "controller does not support namespace management"); + errx(EX_UNAVAILABLE, "controller does not support namespace management"); memset(&pt, 0, sizeof(pt)); pt.cmd.opc = NVME_OPC_IDENTIFY; @@ -474,9 +477,9 @@ nsallocated(const struct cmd *f, int argc, char *argv[]) pt.len = sizeof(list); pt.is_read = 1; if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) - err(1, "identify request failed"); + err(EX_IOERR, "identify request failed"); if (nvme_completion_is_error(&pt.cpl)) - errx(1, "identify request returned error"); + errx(EX_IOERR, "identify request returned error"); printf("Allocated namespaces:\n"); for (i = 0; list[i] != 0; i++) @@ -504,12 +507,13 @@ nscontrollers(const struct cmd *f, int argc, char *argv[]) open_dev(path, &fd, 0, 1); } free(path); - read_controller_data(fd, &cd); + if (read_controller_data(fd, &cd)) + errx(EX_IOERR, "Identify request failed"); /* Check that controller can execute this command. */ if (((cd.oacs >> NVME_CTRLR_DATA_OACS_NSMGMT_SHIFT) & NVME_CTRLR_DATA_OACS_NSMGMT_MASK) == 0) - errx(1, "controller does not support namespace management"); + errx(EX_UNAVAILABLE, "controller does not support namespace management"); memset(&pt, 0, sizeof(pt)); pt.cmd.opc = NVME_OPC_IDENTIFY; @@ -518,9 +522,9 @@ nscontrollers(const struct cmd *f, int argc, char *argv[]) pt.len = sizeof(clist); pt.is_read = 1; if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) - err(1, "identify request failed"); + err(EX_IOERR, "identify request failed"); if (nvme_completion_is_error(&pt.cpl)) - errx(1, "identify request returned error"); + errx(EX_IOERR, "identify request returned error"); n = le16toh(clist[0]); printf("NVM subsystem includes %d controller(s):\n", n); @@ -565,12 +569,13 @@ nscreate(const struct cmd *f, int argc, char *argv[]) open_dev(path, &fd, 1, 1); } free(path); - read_controller_data(fd, &cd); + if (read_controller_data(fd, &cd)) + errx(EX_IOERR, "Identify request failed"); /* Check that controller can execute this command. */ if (((cd.oacs >> NVME_CTRLR_DATA_OACS_NSMGMT_SHIFT) & NVME_CTRLR_DATA_OACS_NSMGMT_MASK) == 0) - errx(1, "controller does not support namespace management"); + errx(EX_UNAVAILABLE, "controller does not support namespace management"); /* Allow namespaces sharing if Multi-Path I/O is supported. */ if (create_opt.nmic == NONE) { @@ -605,10 +610,10 @@ nscreate(const struct cmd *f, int argc, char *argv[]) pt.len = sizeof(struct nvme_namespace_data); pt.is_read = 0; /* passthrough writes data to ctrlr */ if ((result = ioctl(fd, NVME_PASSTHROUGH_CMD, &pt)) < 0) - errx(1, "ioctl request to %s failed: %d", create_opt.dev, result); + errx(EX_IOERR, "ioctl request to %s failed: %d", create_opt.dev, result); if (nvme_completion_is_error(&pt.cpl)) { - errx(1, "namespace creation failed: %s", + errx(EX_IOERR, "namespace creation failed: %s", get_res_str((pt.cpl.status >> NVME_STATUS_SC_SHIFT) & NVME_STATUS_SC_MASK)); } @@ -642,12 +647,13 @@ nsdelete(const struct cmd *f, int argc, char *argv[]) if (delete_opt.nsid != NONE) nsid = delete_opt.nsid; free(path); - read_controller_data(fd, &cd); + if (read_controller_data(fd, &cd)) + errx(EX_IOERR, "Identify request failed"); /* Check that controller can execute this command. */ if (((cd.oacs >> NVME_CTRLR_DATA_OACS_NSMGMT_SHIFT) & NVME_CTRLR_DATA_OACS_NSMGMT_MASK) == 0) - errx(1, "controller does not support namespace management"); + errx(EX_UNAVAILABLE, "controller does not support namespace management"); memset(&pt, 0, sizeof(pt)); pt.cmd.opc = NVME_OPC_NAMESPACE_MANAGEMENT; @@ -658,10 +664,10 @@ nsdelete(const struct cmd *f, int argc, char *argv[]) pt.cmd.nsid = nsid; if ((result = ioctl(fd, NVME_PASSTHROUGH_CMD, &pt)) < 0) - errx(1, "ioctl request to %s failed: %d", delete_opt.dev, result); + errx(EX_IOERR, "ioctl request to %s failed: %d", delete_opt.dev, result); if (nvme_completion_is_error(&pt.cpl)) { - errx(1, "namespace deletion failed: %s", + errx(EX_IOERR, "namespace deletion failed: %s", get_res_str((pt.cpl.status >> NVME_STATUS_SC_SHIFT) & NVME_STATUS_SC_MASK)); } @@ -708,12 +714,13 @@ nsattach(const struct cmd *f, int argc, char *argv[]) } if (attach_opt.nsid != NONE) nsid = attach_opt.nsid; - read_controller_data(fd, &cd); + if (read_controller_data(fd, &cd)) + errx(EX_IOERR, "Identify request failed"); /* Check that controller can execute this command. */ if (((cd.oacs >> NVME_CTRLR_DATA_OACS_NSMGMT_SHIFT) & NVME_CTRLR_DATA_OACS_NSMGMT_MASK) == 0) - errx(1, "controller does not support namespace management"); + errx(EX_UNAVAILABLE, "controller does not support namespace management"); if (attach_opt.ctrlrid == NONE) { /* Get full list of controllers to attach to. */ @@ -724,9 +731,9 @@ nsattach(const struct cmd *f, int argc, char *argv[]) pt.len = sizeof(clist); pt.is_read = 1; if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) - err(1, "identify request failed"); + err(EX_IOERR, "identify request failed"); if (nvme_completion_is_error(&pt.cpl)) - errx(1, "identify request returned error"); + errx(EX_IOERR, "identify request returned error"); } else { /* By default attach to this controller. */ if (attach_opt.ctrlrid == NONE - 1) @@ -744,10 +751,10 @@ nsattach(const struct cmd *f, int argc, char *argv[]) pt.len = sizeof(clist); if ((result = ioctl(fd, NVME_PASSTHROUGH_CMD, &pt)) < 0) - errx(1, "ioctl request to %s failed: %d", attach_opt.dev, result); + errx(EX_IOERR, "ioctl request to %s failed: %d", attach_opt.dev, result); if (nvme_completion_is_error(&pt.cpl)) { - errx(1, "namespace attach failed: %s", + errx(EX_IOERR, "namespace attach failed: %s", get_res_str((pt.cpl.status >> NVME_STATUS_SC_SHIFT) & NVME_STATUS_SC_MASK)); } @@ -779,12 +786,13 @@ nsdetach(const struct cmd *f, int argc, char *argv[]) } if (detach_opt.nsid != NONE) nsid = detach_opt.nsid; - read_controller_data(fd, &cd); + if (read_controller_data(fd, &cd)) + errx(EX_IOERR, "Identify request failed"); /* Check that controller can execute this command. */ if (((cd.oacs >> NVME_CTRLR_DATA_OACS_NSMGMT_SHIFT) & NVME_CTRLR_DATA_OACS_NSMGMT_MASK) == 0) - errx(1, "controller does not support namespace management"); + errx(EX_UNAVAILABLE, "controller does not support namespace management"); if (detach_opt.ctrlrid == NONE) { /* Get list of controllers this namespace attached to. */ @@ -796,9 +804,9 @@ nsdetach(const struct cmd *f, int argc, char *argv[]) pt.len = sizeof(clist); pt.is_read = 1; if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) - err(1, "identify request failed"); + err(EX_IOERR, "identify request failed"); if (nvme_completion_is_error(&pt.cpl)) - errx(1, "identify request returned error"); + errx(EX_IOERR, "identify request returned error"); if (clist[0] == 0) { detach_opt.ctrlrid = cd.ctrlr_id; memset(&clist, 0, sizeof(clist)); @@ -822,10 +830,10 @@ nsdetach(const struct cmd *f, int argc, char *argv[]) pt.len = sizeof(clist); if ((result = ioctl(fd, NVME_PASSTHROUGH_CMD, &pt)) < 0) - errx(1, "ioctl request to %s failed: %d", detach_opt.dev, result); + errx(EX_IOERR, "ioctl request to %s failed: %d", detach_opt.dev, result); if (nvme_completion_is_error(&pt.cpl)) { - errx(1, "namespace detach failed: %s", + errx(EX_IOERR, "namespace detach failed: %s", get_res_str((pt.cpl.status >> NVME_STATUS_SC_SHIFT) & NVME_STATUS_SC_MASK)); } @@ -857,12 +865,13 @@ nsattached(const struct cmd *f, int argc, char *argv[]) } if (attached_opt.nsid != NONE) nsid = attached_opt.nsid; - read_controller_data(fd, &cd); + if (read_controller_data(fd, &cd)) + errx(EX_IOERR, "Identify request failed"); /* Check that controller can execute this command. */ if (((cd.oacs >> NVME_CTRLR_DATA_OACS_NSMGMT_SHIFT) & NVME_CTRLR_DATA_OACS_NSMGMT_MASK) == 0) - errx(1, "controller does not support namespace management"); + errx(EX_UNAVAILABLE, "controller does not support namespace management"); memset(&pt, 0, sizeof(pt)); pt.cmd.opc = NVME_OPC_IDENTIFY; @@ -872,9 +881,9 @@ nsattached(const struct cmd *f, int argc, char *argv[]) pt.len = sizeof(clist); pt.is_read = 1; if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) - err(1, "identify request failed"); + err(EX_IOERR, "identify request failed"); if (nvme_completion_is_error(&pt.cpl)) - errx(1, "identify request returned error"); + errx(EX_IOERR, "identify request returned error"); n = le16toh(clist[0]); printf("Attached %d controller(s):\n", n); @@ -910,12 +919,13 @@ nsidentify(const struct cmd *f, int argc, char *argv[]) } if (identify_opt.nsid != NONE) nsid = identify_opt.nsid; - read_controller_data(fd, &cd); + if (read_controller_data(fd, &cd)) + errx(EX_IOERR, "Identify request failed"); /* Check that controller can execute this command. */ if (((cd.oacs >> NVME_CTRLR_DATA_OACS_NSMGMT_SHIFT) & NVME_CTRLR_DATA_OACS_NSMGMT_MASK) == 0) - errx(1, "controller does not support namespace management"); + errx(EX_UNAVAILABLE, "controller does not support namespace management"); memset(&pt, 0, sizeof(pt)); pt.cmd.opc = NVME_OPC_IDENTIFY; @@ -926,10 +936,10 @@ nsidentify(const struct cmd *f, int argc, char *argv[]) pt.is_read = 1; if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) - err(1, "identify request failed"); + err(EX_IOERR, "identify request failed"); if (nvme_completion_is_error(&pt.cpl)) - errx(1, "identify request returned error"); + errx(EX_IOERR, "identify request returned error"); close(fd); @@ -939,7 +949,7 @@ nsidentify(const struct cmd *f, int argc, char *argv[]) break; } if (i == sizeof(nsdata)) - errx(1, "namespace %d is not allocated", nsid); + errx(EX_UNAVAILABLE, "namespace %d is not allocated", nsid); /* Convert data to host endian */ nvme_namespace_data_swapbytes(&nsdata); diff --git a/sbin/nvmecontrol/nvmecontrol.c b/sbin/nvmecontrol/nvmecontrol.c index c88ea1ac29a..758822f2e25 100644 --- a/sbin/nvmecontrol/nvmecontrol.c +++ b/sbin/nvmecontrol/nvmecontrol.c @@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include "nvmecontrol.h" @@ -96,7 +97,7 @@ print_hex(void *data, uint32_t length) print_bytes(data, length); } -void +int read_controller_data(int fd, struct nvme_controller_data *cdata) { struct nvme_pt_command pt; @@ -109,16 +110,17 @@ read_controller_data(int fd, struct nvme_controller_data *cdata) pt.is_read = 1; if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) - err(1, "identify request failed"); + return (errno); /* Convert data to host endian */ nvme_controller_data_swapbytes(cdata); if (nvme_completion_is_error(&pt.cpl)) - errx(1, "identify request returned error"); + return (EIO); + return (0); } -void +int read_namespace_data(int fd, uint32_t nsid, struct nvme_namespace_data *nsdata) { struct nvme_pt_command pt; @@ -132,13 +134,14 @@ read_namespace_data(int fd, uint32_t nsid, struct nvme_namespace_data *nsdata) pt.is_read = 1; if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) - err(1, "identify request failed"); + return (errno); /* Convert data to host endian */ nvme_namespace_data_swapbytes(nsdata); if (nvme_completion_is_error(&pt.cpl)) - errx(1, "identify request returned error"); + return (EIO); + return (0); } int @@ -150,7 +153,7 @@ open_dev(const char *str, int *fd, int write, int exit_on_error) *fd = open(full_path, write ? O_RDWR : O_RDONLY); if (*fd < 0) { if (exit_on_error) { - err(1, "could not open %s%s", full_path, + err(EX_OSFILE, "could not open %s%s", full_path, write ? " for write" : ""); } else return (errno); @@ -165,7 +168,7 @@ get_nsid(int fd, char **ctrlr_str, uint32_t *nsid) struct nvme_get_nsid gnsid; if (ioctl(fd, NVME_GET_NSID, &gnsid) < 0) - err(1, "NVME_GET_NSID ioctl failed"); + err(EX_OSERR, "NVME_GET_NSID ioctl failed"); if (ctrlr_str != NULL) *ctrlr_str = strndup(gnsid.cdev, sizeof(gnsid.cdev)); if (nsid != NULL) diff --git a/sbin/nvmecontrol/nvmecontrol.h b/sbin/nvmecontrol/nvmecontrol.h index 67fcac94b82..c1daaf6730d 100644 --- a/sbin/nvmecontrol/nvmecontrol.h +++ b/sbin/nvmecontrol/nvmecontrol.h @@ -70,8 +70,8 @@ void logpage_register(struct logpage_function *p); int open_dev(const char *str, int *fd, int write, int exit_on_error); void get_nsid(int fd, char **ctrlr_str, uint32_t *nsid); -void read_controller_data(int fd, struct nvme_controller_data *cdata); -void read_namespace_data(int fd, uint32_t nsid, struct nvme_namespace_data *nsdata); +int read_controller_data(int fd, struct nvme_controller_data *cdata); +int read_namespace_data(int fd, uint32_t nsid, struct nvme_namespace_data *nsdata); void print_hex(void *data, uint32_t length); void print_namespace(struct nvme_namespace_data *nsdata); void read_logpage(int fd, uint8_t log_page, uint32_t nsid, uint8_t lsp, diff --git a/sbin/nvmecontrol/passthru.c b/sbin/nvmecontrol/passthru.c index abdee4ef5f8..add6cf1cc7c 100644 --- a/sbin/nvmecontrol/passthru.c +++ b/sbin/nvmecontrol/passthru.c @@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include "nvmecontrol.h" @@ -167,9 +168,9 @@ passthru(const struct cmd *f, int argc, char *argv[]) open_dev(opt.dev, &fd, 1, 1); if (opt.read && opt.write) - errx(1, "need exactly one of --read or --write"); + errx(EX_USAGE, "need exactly one of --read or --write"); if (opt.data_len != 0 && !opt.read && !opt.write) - errx(1, "need exactly one of --read or --write"); + errx(EX_USAGE, "need exactly one of --read or --write"); if (*opt.ifn && (ifd = open(opt.ifn, O_RDONLY)) == -1) { warn("open %s", opt.ifn); goto cleanup; @@ -183,7 +184,7 @@ passthru(const struct cmd *f, int argc, char *argv[]) } #else if (opt.metadata_len != 0) - errx(1, "metadata not supported on FreeBSD"); + errx(EX_UNAVAILABLE, "metadata not supported on FreeBSD"); #endif if (opt.data_len) { if (posix_memalign(&data, getpagesize(), opt.data_len)) { @@ -244,7 +245,7 @@ passthru(const struct cmd *f, int argc, char *argv[]) errno = 0; if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) - err(1, "passthrough request failed"); + err(EX_IOERR, "passthrough request failed"); /* XXX report status */ if (opt.read) { if (opt.binary) @@ -260,7 +261,7 @@ passthru(const struct cmd *f, int argc, char *argv[]) if (ifd > -1) close(ifd); if (errno) - exit(1); + exit(EX_IOERR); } static void diff --git a/sbin/nvmecontrol/perftest.c b/sbin/nvmecontrol/perftest.c index cc3beece553..0223bf3b5d5 100644 --- a/sbin/nvmecontrol/perftest.c +++ b/sbin/nvmecontrol/perftest.c @@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include "nvmecontrol.h" @@ -180,7 +181,7 @@ perftest(const struct cmd *f, int argc, char *argv[]) io_test.size = opt.size; open_dev(opt.dev, &fd, 1, 1); if (ioctl(fd, ioctl_cmd, &io_test) < 0) - err(1, "ioctl NVME_IO_TEST failed"); + err(EX_IOERR, "ioctl NVME_IO_TEST failed"); close(fd); print_perftest(&io_test, opt.perthread); diff --git a/sbin/nvmecontrol/power.c b/sbin/nvmecontrol/power.c index 0b87d51fd73..47ebc9c8c15 100644 --- a/sbin/nvmecontrol/power.c +++ b/sbin/nvmecontrol/power.c @@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include "nvmecontrol.h" @@ -115,10 +116,10 @@ power_set(int fd, int power_val, int workload, int perm) pt.cmd.cdw11 = htole32(power_val | (workload << 5)); if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) - err(1, "set feature power mgmt request failed"); + err(EX_IOERR, "set feature power mgmt request failed"); if (nvme_completion_is_error(&pt.cpl)) - errx(1, "set feature power mgmt request returned error"); + errx(EX_IOERR, "set feature power mgmt request returned error"); } static void @@ -131,10 +132,10 @@ power_show(int fd) pt.cmd.cdw10 = htole32(NVME_FEAT_POWER_MANAGEMENT); if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) - err(1, "set feature power mgmt request failed"); + err(EX_IOERR, "set feature power mgmt request failed"); if (nvme_completion_is_error(&pt.cpl)) - errx(1, "set feature power mgmt request returned error"); + errx(EX_IOERR, "set feature power mgmt request returned error"); printf("Current Power Mode is %d\n", pt.cpl.cdw0); } @@ -164,7 +165,8 @@ power(const struct cmd *f, int argc, char *argv[]) free(path); if (opt.list) { - read_controller_data(fd, &cdata); + if (read_controller_data(fd, &cdata)) + errx(EX_IOERR, "Identify request failed"); power_list(&cdata); goto out; } diff --git a/sbin/nvmecontrol/reset.c b/sbin/nvmecontrol/reset.c index 89e64c603b0..f5ab7265c98 100644 --- a/sbin/nvmecontrol/reset.c +++ b/sbin/nvmecontrol/reset.c @@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include "nvmecontrol.h" @@ -70,7 +71,7 @@ reset(const struct cmd *f, int argc, char *argv[]) free(path); if (ioctl(fd, NVME_RESET_CONTROLLER) < 0) - err(1, "reset request to %s failed", opt.dev); + err(EX_IOERR, "reset request to %s failed", opt.dev); exit(0); } diff --git a/sbin/nvmecontrol/resv.c b/sbin/nvmecontrol/resv.c index 1acd9ac405e..adb3b64c9ec 100644 --- a/sbin/nvmecontrol/resv.c +++ b/sbin/nvmecontrol/resv.c @@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include "nvmecontrol.h" @@ -261,10 +262,10 @@ resvacquire(const struct cmd *f, int argc, char *argv[]) pt.is_read = 0; if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) - err(1, "acquire request failed"); + err(EX_IOERR, "acquire request failed"); if (nvme_completion_is_error(&pt.cpl)) - errx(1, "acquire request returned error"); + errx(EX_IOERR, "acquire request returned error"); close(fd); exit(0); @@ -299,10 +300,10 @@ resvregister(const struct cmd *f, int argc, char *argv[]) pt.is_read = 0; if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) - err(1, "register request failed"); + err(EX_IOERR, "register request failed"); if (nvme_completion_is_error(&pt.cpl)) - errx(1, "register request returned error"); + errx(EX_IOERR, "register request returned error"); close(fd); exit(0); @@ -336,10 +337,10 @@ resvrelease(const struct cmd *f, int argc, char *argv[]) pt.is_read = 0; if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) - err(1, "release request failed"); + err(EX_IOERR, "release request failed"); if (nvme_completion_is_error(&pt.cpl)) - errx(1, "release request returned error"); + errx(EX_IOERR, "release request returned error"); close(fd); exit(0); @@ -375,10 +376,10 @@ resvreport(const struct cmd *f, int argc, char *argv[]) pt.is_read = 1; if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) - err(1, "report request failed"); + err(EX_IOERR, "report request failed"); if (nvme_completion_is_error(&pt.cpl)) - errx(1, "report request returned error"); + errx(EX_IOERR, "report request returned error"); close(fd); diff --git a/sbin/nvmecontrol/sanitize.c b/sbin/nvmecontrol/sanitize.c index b1cb6cb0cda..d5f649959d7 100644 --- a/sbin/nvmecontrol/sanitize.c +++ b/sbin/nvmecontrol/sanitize.c @@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include "nvmecontrol.h" @@ -154,23 +155,24 @@ sanitize(const struct cmd *f, int argc, char *argv[]) goto wait; /* Check that controller can execute this command. */ - read_controller_data(fd, &cd); + if (read_controller_data(fd, &cd)) + errx(EX_IOERR, "Identify request failed"); if (((cd.sanicap >> NVME_CTRLR_DATA_SANICAP_BES_SHIFT) & NVME_CTRLR_DATA_SANICAP_BES_MASK) == 0 && sanact == 2) - errx(1, "controller does not support Block Erase"); + errx(EX_UNAVAILABLE, "controller does not support Block Erase"); if (((cd.sanicap >> NVME_CTRLR_DATA_SANICAP_OWS_SHIFT) & NVME_CTRLR_DATA_SANICAP_OWS_MASK) == 0 && sanact == 3) - errx(1, "controller does not support Overwrite"); + errx(EX_UNAVAILABLE, "controller does not support Overwrite"); if (((cd.sanicap >> NVME_CTRLR_DATA_SANICAP_CES_SHIFT) & NVME_CTRLR_DATA_SANICAP_CES_MASK) == 0 && sanact == 4) - errx(1, "controller does not support Crypto Erase"); + errx(EX_UNAVAILABLE, "controller does not support Crypto Erase"); /* * If controller supports only one namespace, we may sanitize it. * If there can be more, make user explicit in his commands. */ if (nsid != 0 && cd.nn > 1) - errx(1, "can't sanitize one of namespaces, specify controller"); + errx(EX_UNAVAILABLE, "can't sanitize one of namespaces, specify controller"); memset(&pt, 0, sizeof(pt)); pt.cmd.opc = NVME_OPC_SANITIZE; @@ -179,10 +181,10 @@ sanitize(const struct cmd *f, int argc, char *argv[]) pt.cmd.cdw11 = htole32(opt.ovrpat); if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) - err(1, "sanitize request failed"); + err(EX_IOERR, "sanitize request failed"); if (nvme_completion_is_error(&pt.cpl)) - errx(1, "sanitize request returned error"); + errx(EX_IOERR, "sanitize request returned error"); wait: read_logpage(fd, NVME_LOG_SANITIZE_STATUS, -- 2.45.0