Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Step:15-SP2
nvme-cli.7759
0011-nvme-cli-add-minimal-ana-log-page-support....
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0011-nvme-cli-add-minimal-ana-log-page-support.patch of Package nvme-cli.7759
From 9a0aa45c58dfaab6ae14c3bc5717792bf5c46efa Mon Sep 17 00:00:00 2001 From: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com> Date: Wed, 1 Aug 2018 20:28:18 -0700 Subject: [PATCH] nvme-cli: add minimal ana-log page support This patch adds a new command to retrieve the ANA Log page. We update identify ctrl/ns data structure to support this command. We also add ana based error codes and different identifiers to the linux/nvme.h header file in order to support this command. Signed-off-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com> Signed-off-by: Hannes Reinecke <hare@suse.com> --- linux/nvme.h | 55 ++++++++++++++++-- nvme-builtin.h | 1 + nvme-ioctl.c | 8 +++ nvme-ioctl.h | 1 + nvme-print.c | 177 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- nvme-print.h | 2 + nvme.c | 79 +++++++++++++++++++++++++ 7 files changed, 317 insertions(+), 6 deletions(-) diff --git a/linux/nvme.h b/linux/nvme.h index 162b1e0..b7a3c31 100644 --- a/linux/nvme.h +++ b/linux/nvme.h @@ -239,7 +239,13 @@ struct nvme_id_ctrl { __le32 sanicap; __le32 hmminds; __le16 hmmaxd; - __u8 rsvd338[174]; + __le16 nsetidmax; + __u8 rsvd340[2]; + __u8 anatt; + __u8 anacap; + __le32 anagrpmax; + __le32 nanagrpid; + __u8 rsvd352[160]; __u8 sqes; __u8 cqes; __le16 maxcmd; @@ -255,7 +261,8 @@ struct nvme_id_ctrl { __le16 acwu; __u8 rsvd534[2]; __le32 sgls; - __u8 rsvd540[228]; + __le32 mnan; + __u8 rsvd544[224]; char subnqn[256]; __u8 rsvd1024[768]; __le32 ioccsz; @@ -309,7 +316,11 @@ struct nvme_id_ns { __le16 nabspf; __le16 noiob; __u8 nvmcap[16]; - __u8 rsvd64[40]; + __u8 rsvd64[28]; + __le32 anagrpid; + __u8 rsvd96[4]; + __le16 nvmsetid; + __le16 endgid; __u8 nguid[16]; __u8 eui64[8]; struct nvme_lbaf lbaf[16]; @@ -426,6 +437,32 @@ struct nvme_effects_log { __u8 resv[2048]; }; +enum nvme_ana_state { + NVME_ANA_OPTIMIZED = 0x01, + NVME_ANA_NONOPTIMIZED = 0x02, + NVME_ANA_INACCESSIBLE = 0x03, + NVME_ANA_PERSISTENT_LOSS = 0x04, + NVME_ANA_CHANGE = 0x0f, +}; + +struct nvme_ana_group_desc { + __le32 grpid; + __le32 nnsids; + __le64 chgcnt; + __u8 state; + __u8 rsvd17[7]; + __le32 nsids[]; +}; + +/* flag for the log specific field of the ANA log */ +#define NVME_ANA_LOG_RGO (1 << 0) + +struct nvme_ana_rsp_hdr { + __le64 chgcnt; + __le16 ngrps; + __le16 rsvd10[3]; +}; + enum { NVME_SMART_CRIT_SPARE = 1 << 0, NVME_SMART_CRIT_TEMPERATURE = 1 << 1, @@ -441,6 +478,7 @@ enum { NVME_AER_VS = 7, NVME_AER_NOTICE_NS_CHANGED = 0x0002, NVME_AER_NOTICE_FW_ACT_STARTING = 0x0102, + NVME_AER_NOTICE_ANA = 0x03, }; struct nvme_lba_range_type { @@ -768,6 +806,7 @@ enum { NVME_LOG_SMART = 0x02, NVME_LOG_FW_SLOT = 0x03, NVME_LOG_CMD_EFFECTS = 0x05, + NVME_LOG_ANA = 0x0c, NVME_LOG_DISC = 0x70, NVME_LOG_RESERVATION = 0x80, NVME_LOG_SANITIZE = 0x81, @@ -779,6 +818,7 @@ enum { enum { NVME_NO_LOG_LSP = 0x0, NVME_NO_LOG_LPO = 0x0, + NVME_LOG_ANA_LSP_RGO = 0x1, }; /* Sanitize and Sanitize Monitor/Log */ @@ -916,7 +956,7 @@ struct nvme_get_log_page_command { __u64 rsvd2[2]; union nvme_data_ptr dptr; __u8 lid; - __u8 rsvd10; + __u8 lsp; __le16 numdl; __le16 numdu; __u16 rsvd11; @@ -1230,6 +1270,13 @@ enum { NVME_SC_ACCESS_DENIED = 0x286, NVME_SC_UNWRITTEN_BLOCK = 0x287, + /* + * Path-related Errors: + */ + NVME_SC_ANA_PERSISTENT_LOSS = 0x301, + NVME_SC_ANA_INACCESSIBLE = 0x302, + NVME_SC_ANA_TRANSITION = 0x303, + NVME_SC_DNR = 0x4000, }; diff --git a/nvme-builtin.h b/nvme-builtin.h index 85f9f0f..4a474ec 100644 --- a/nvme-builtin.h +++ b/nvme-builtin.h @@ -22,6 +22,7 @@ COMMAND_LIST( ENTRY("get-log", "Generic NVMe get log, returns log in raw format", get_log) ENTRY("fw-log", "Retrieve FW Log, show it", get_fw_log) ENTRY("smart-log", "Retrieve SMART Log, show it", get_smart_log) + ENTRY("ana-log", "Retrieve ANA Log, show it", get_ana_log) ENTRY("error-log", "Retrieve Error Log, show it", get_error_log) ENTRY("effects-log", "Retrieve Command Effects Log, show it", get_effects_log) ENTRY("get-feature", "Get feature and show the resulting value", get_feature) diff --git a/nvme-ioctl.c b/nvme-ioctl.c index 780ee50..eea33ca 100644 --- a/nvme-ioctl.c +++ b/nvme-ioctl.c @@ -427,6 +427,14 @@ int nvme_smart_log(int fd, __u32 nsid, struct nvme_smart_log *smart_log) return nvme_get_log(fd, nsid, NVME_LOG_SMART, sizeof(*smart_log), smart_log); } +int nvme_ana_log(int fd, void *ana_log, size_t ana_log_len, int rgo) +{ + __u64 lpo = 0; + + return nvme_get_log13(fd, NVME_NSID_ALL, NVME_LOG_ANA, rgo, lpo, 0, + true, ana_log_len, ana_log); +} + int nvme_discovery_log(int fd, struct nvmf_disc_rsp_page_hdr *log, __u32 size) { return nvme_get_log(fd, 0, NVME_LOG_DISC, size, log); diff --git a/nvme-ioctl.h b/nvme-ioctl.h index 1f804c2..1b0619a 100644 --- a/nvme-ioctl.h +++ b/nvme-ioctl.h @@ -87,6 +87,7 @@ int nvme_fw_log(int fd, struct nvme_firmware_log_page *fw_log); int nvme_error_log(int fd, __u32 nsid, int entries, struct nvme_error_log_page *err_log); int nvme_smart_log(int fd, __u32 nsid, struct nvme_smart_log *smart_log); +int nvme_ana_log(int fd, void *ana_log, size_t ana_log_len, int rgo); int nvme_discovery_log(int fd, struct nvmf_disc_rsp_page_hdr *log, __u32 size); int nvme_feature(int fd, __u8 opcode, __u32 nsid, __u32 cdw10, diff --git a/nvme-print.c b/nvme-print.c index 04253d2..8510cb3 100644 --- a/nvme-print.c +++ b/nvme-print.c @@ -7,6 +7,23 @@ #include "json.h" #include "nvme-models.h" +static const char *nvme_ana_state_to_string(enum nvme_ana_state state) +{ + switch (state) { + case NVME_ANA_OPTIMIZED: + return "optimized"; + case NVME_ANA_NONOPTIMIZED: + return "non-optimized"; + case NVME_ANA_INACCESSIBLE: + return "inaccessible"; + case NVME_ANA_PERSISTENT_LOSS: + return "persistent-loss"; + case NVME_ANA_CHANGE: + return "change"; + } + return "invalid state"; +} + static long double int128_to_double(__u8 *data) { int i; @@ -77,12 +94,15 @@ static void format(char *formatter, size_t fmt_sz, char *tofmt, size_t tofmtsz) static void show_nvme_id_ctrl_cmic(__u8 cmic) { - __u8 rsvd = (cmic & 0xF8) >> 3; + __u8 rsvd = (cmic & 0xF0) >> 4; + __u8 ana = (cmic & 0x8) >> 3; __u8 sriov = (cmic & 0x4) >> 2; __u8 mctl = (cmic & 0x2) >> 1; __u8 mp = cmic & 0x1; + if (rsvd) - printf(" [7:3] : %#x\tReserved\n", rsvd); + printf(" [7:4] : %#x\tReserved\n", rsvd); + printf(" [3:3] : %#x\tANA %ssupported\n", ana, ana ? "" : "not "); printf(" [2:2] : %#x\t%s\n", sriov, sriov ? "SR-IOV" : "PCI"); printf(" [1:1] : %#x\t%s Controller\n", mctl, mctl ? "Multi" : "Single"); @@ -261,6 +281,37 @@ static void show_nvme_id_ctrl_sanicap(__le32 ctrl_sanicap) printf("\n"); } + +static void show_nvme_id_ctrl_anacap(__u8 anacap) +{ + __u8 nz = (anacap & 0x80) >> 7; + __u8 grpid_change = (anacap & 0x40) >> 6; + __u8 rsvd = (anacap & 0x20) >> 5; + __u8 ana_change = (anacap & 0x10) >> 4; + __u8 ana_persist_loss = (anacap & 0x08) >> 3; + __u8 ana_inaccessible = (anacap & 0x04) >> 2; + __u8 ana_nonopt = (anacap & 0x02) >> 1; + __u8 ana_opt = (anacap & 0x01); + + printf(" [7:7] : %#x\tNon-zero group ID %sSupported\n", + nz, nz ? "" : "Not "); + printf(" [6:6] : %#x\tGroup ID does %schange\n", + grpid_change, grpid_change ? "" : "not "); + if (rsvd) + printf(" [5:5] : %#x\tReserved\n", rsvd); + printf(" [4:4] : %#x\tANA Change state %sSupported\n", + ana_change, ana_change ? "" : "Not "); + printf(" [3:3] : %#x\tANA Persistent Loss state %sSupported\n", + ana_persist_loss, ana_persist_loss ? "" : "Not "); + printf(" [2:2] : %#x\tANA Inaccessible state %sSupported\n", + ana_inaccessible, ana_inaccessible ? "" : "Not "); + printf(" [1:1] : %#x\tANA Non-optimized state %sSupported\n", + ana_nonopt, ana_nonopt ? "" : "Not "); + printf(" [0:0] : %#x\tANA Optimized state %sSupported\n", + ana_opt, ana_opt ? "" : "Not "); + printf("\n"); +} + static void show_nvme_id_ctrl_sqes(__u8 sqes) { __u8 msqes = (sqes & 0xF0) >> 4; @@ -600,6 +651,9 @@ void show_nvme_id_ns(struct nvme_id_ns *ns, unsigned int mode) printf("nabspf : %d\n", le16_to_cpu(ns->nabspf)); printf("noiob : %d\n", le16_to_cpu(ns->noiob)); printf("nvmcap : %.0Lf\n", int128_to_double(ns->nvmcap)); + printf("nvmsetid: %d\n", le16_to_cpu(ns->nvmsetid)); + printf("anagrpid: %d\n", le32_to_cpu(ns->anagrpid)); + printf("endgid : %d\n", le16_to_cpu(ns->endgid)); printf("nguid : "); for (i = 0; i < 16; i++) @@ -876,6 +930,13 @@ void __show_nvme_id_ctrl(struct nvme_id_ctrl *ctrl, unsigned int mode, void (*ve show_nvme_id_ctrl_sanicap(ctrl->sanicap); printf("hmminds : %d\n", le32_to_cpu(ctrl->hmminds)); printf("hmmaxd : %d\n", le16_to_cpu(ctrl->hmmaxd)); + printf("nsetidmax : %d\n", le16_to_cpu(ctrl->nsetidmax)); + printf("anatt : %d\n", ctrl->anatt); + printf("anacap : %d\n", ctrl->anacap); + if (human) + show_nvme_id_ctrl_anacap(ctrl->anacap); + printf("anagrpmax : %d\n", ctrl->anagrpmax); + printf("nanagrpid : %d\n", le32_to_cpu(ctrl->nanagrpid)); printf("sqes : %#x\n", ctrl->sqes); if (human) show_nvme_id_ctrl_sqes(ctrl->sqes); @@ -903,6 +964,7 @@ void __show_nvme_id_ctrl(struct nvme_id_ctrl *ctrl, unsigned int mode, void (*ve show_nvme_id_ctrl_nvscc(ctrl->nvscc); printf("acwu : %d\n", le16_to_cpu(ctrl->acwu)); printf("sgls : %x\n", le32_to_cpu(ctrl->sgls)); + printf("mnan : %d\n", le32_to_cpu(ctrl->mnan)); if (human) show_nvme_id_ctrl_sgls(ctrl->sgls); printf("subnqn : %-.*s\n", (int)sizeof(ctrl->subnqn), ctrl->subnqn); @@ -1100,6 +1162,44 @@ void show_smart_log(struct nvme_smart_log *smart, unsigned int nsid, const char printf("Thermal Management T2 Total Time : %u\n", le32_to_cpu(smart->thm_temp2_total_time)); } +void show_ana_log(struct nvme_ana_rsp_hdr *ana_log, const char *devname) +{ + int offset = sizeof(struct nvme_ana_rsp_hdr); + struct nvme_ana_rsp_hdr *hdr = ana_log; + struct nvme_ana_group_desc *desc; + size_t nsid_buf_size; + void *base = ana_log; + __u32 nr_nsids; + int i; + int j; + + printf("Asynchronous Namespace Access Log for NVMe device: %s\n", + devname); + printf("ANA LOG HEADER :-\n"); + printf("chgcnt : %"PRIu64"\n", + (uint64_t)le64_to_cpu(hdr->chgcnt)); + printf("ngrps : %u\n", le16_to_cpu(hdr->ngrps)); + printf("ANA Log Desc :-\n"); + + for (i = 0; i < le16_to_cpu(ana_log->ngrps); i++) { + desc = base + offset; + nr_nsids = le32_to_cpu(desc->nnsids); + nsid_buf_size = nr_nsids * sizeof(__le32); + + offset += sizeof(*desc); + printf("grpid : %u\n", le32_to_cpu(desc->grpid)); + printf("nnsids : %u\n", le32_to_cpu(desc->nnsids)); + printf("chgcnt : %llu\n", le64_to_cpu(desc->chgcnt)); + printf("state : %s\n", + nvme_ana_state_to_string(desc->state)); + for (j = 0; j < le32_to_cpu(desc->nnsids); j++) + printf(" nsid : %u\n", + le32_to_cpu(desc->nsids[j])); + printf("\n"); + offset += nsid_buf_size; + } +} + char *nvme_feature_to_string(int feature) { switch (feature) { @@ -1216,6 +1316,10 @@ char *nvme_status_to_string(__u32 status) case NVME_SC_COMPARE_FAILED: return "COMPARE_FAILED"; case NVME_SC_ACCESS_DENIED: return "ACCESS_DENIED"; case NVME_SC_UNWRITTEN_BLOCK: return "UNWRITTEN_BLOCK"; + + case NVME_SC_ANA_PERSISTENT_LOSS: return "ANA_PERSISTENT_LOSS"; + case NVME_SC_ANA_INACCESSIBLE: return "ANA_INACCESSIBLE"; + case NVME_SC_ANA_TRANSITION: return "ANA_TRANSITION"; default: return "Unknown"; } } @@ -1566,6 +1670,9 @@ void json_nvme_id_ns(struct nvme_id_ns *ns, unsigned int mode) json_object_add_value_int(root, "nabspf", le16_to_cpu(ns->nabspf)); json_object_add_value_int(root, "noiob", le16_to_cpu(ns->noiob)); json_object_add_value_float(root, "nvmcap", nvmcap); + json_object_add_value_int(root, "nvmsetid", le16_to_cpu(ns->nvmsetid)); + json_object_add_value_int(root, "anagrpid", le32_to_cpu(ns->anagrpid)); + json_object_add_value_int(root, "endgid", le16_to_cpu(ns->endgid)); memset(eui64, 0, sizeof(eui64_buf)); for (i = 0; i < sizeof(ns->eui64); i++) @@ -1657,6 +1764,13 @@ void json_nvme_id_ctrl(struct nvme_id_ctrl *ctrl, unsigned int mode, void (*vs)( json_object_add_value_int(root, "mntmt", le16_to_cpu(ctrl->mntmt)); json_object_add_value_int(root, "mxtmt", le16_to_cpu(ctrl->mxtmt)); json_object_add_value_int(root, "sanicap", le32_to_cpu(ctrl->sanicap)); + json_object_add_value_int(root, "hmminds", le32_to_cpu(ctrl->hmminds)); + json_object_add_value_int(root, "hmmaxd", le16_to_cpu(ctrl->hmmaxd)); + json_object_add_value_int(root, "nsetidmax", le16_to_cpu(ctrl->nsetidmax)); + json_object_add_value_int(root, "anatt",ctrl->anatt); + json_object_add_value_int(root, "anacap", ctrl->anacap); + json_object_add_value_int(root, "anagrpmax", le32_to_cpu(ctrl->anagrpmax)); + json_object_add_value_int(root, "nanagrpid", le32_to_cpu(ctrl->nanagrpid)); json_object_add_value_int(root, "sqes", ctrl->sqes); json_object_add_value_int(root, "cqes", ctrl->cqes); json_object_add_value_int(root, "maxcmd", le16_to_cpu(ctrl->maxcmd)); @@ -1901,6 +2015,65 @@ void json_smart_log(struct nvme_smart_log *smart, unsigned int nsid, const char json_free_object(root); } +void json_ana_log(struct nvme_ana_rsp_hdr *ana_log, const char *devname) +{ + int offset = sizeof(struct nvme_ana_rsp_hdr); + struct nvme_ana_rsp_hdr *hdr = ana_log; + struct nvme_ana_group_desc *ana_desc; + struct json_array *desc_list; + struct json_array *ns_list; + struct json_object *desc; + struct json_object *nsid; + struct json_object *root; + size_t nsid_buf_size; + void *base = ana_log; + __u32 nr_nsids; + int i; + int j; + + root = json_create_object(); + json_object_add_value_string(root, + "Asynchronous Namespace Access Log for NVMe device:", + devname); + json_object_add_value_uint(root, "chgcnt", + (uint64_t)le64_to_cpu(hdr->chgcnt)); + json_object_add_value_uint(root, "ngrps", le16_to_cpu(hdr->ngrps)); + + desc_list = json_create_array(); + for (i = 0; i < le16_to_cpu(ana_log->ngrps); i++) { + desc = json_create_object(); + ana_desc = base + offset; + nr_nsids = le32_to_cpu(ana_desc->nnsids); + nsid_buf_size = nr_nsids * sizeof(__le32); + + offset += sizeof(*ana_desc); + json_object_add_value_uint(desc, "grpid", + le32_to_cpu(ana_desc->grpid)); + json_object_add_value_uint(desc, "nnsids", + le32_to_cpu(ana_desc->nnsids)); + json_object_add_value_uint(desc, "chgcnt", + le64_to_cpu(ana_desc->chgcnt)); + json_object_add_value_string(desc, "state", + nvme_ana_state_to_string(ana_desc->state)); + + ns_list = json_create_array(); + for (j = 0; j < le32_to_cpu(ana_desc->nnsids); j++) { + nsid = json_create_object(); + json_object_add_value_uint(nsid, "nsid", + le32_to_cpu(ana_desc->nsids[j])); + json_array_add_value_object(ns_list, nsid); + } + json_object_add_value_array(desc, "NSIDS", ns_list); + offset += nsid_buf_size; + json_array_add_value_object(desc_list, desc); + } + + json_object_add_value_array(root, "ANA DESC LIST ", desc_list); + json_print_object(root, NULL); + printf("\n"); + json_free_object(root); +} + void json_print_nvme_subsystem_list(struct subsys_list_item *slist, int n) { struct json_object *root; diff --git a/nvme-print.h b/nvme-print.h index 926c196..5f1d570 100644 --- a/nvme-print.h +++ b/nvme-print.h @@ -24,6 +24,7 @@ void show_nvme_resv_report(struct nvme_reservation_status *status, int bytes, __ void show_lba_range(struct nvme_lba_range_type *lbrt, int nr_ranges); void show_error_log(struct nvme_error_log_page *err_log, int entries, const char *devname); void show_smart_log(struct nvme_smart_log *smart, unsigned int nsid, const char *devname); +void show_ana_log(struct nvme_ana_rsp_hdr *ana_log, const char *devname); void show_fw_log(struct nvme_firmware_log_page *fw_log, const char *devname); void show_effects_log(struct nvme_effects_log_page *effects); void show_ctrl_registers(void *bar, unsigned int mode, bool fabrics); @@ -41,6 +42,7 @@ void json_nvme_id_ns(struct nvme_id_ns *ns, unsigned int flags); void json_nvme_resv_report(struct nvme_reservation_status *status, int bytes, __u32 cdw11); void json_error_log(struct nvme_error_log_page *err_log, int entries, const char *devname); void json_smart_log(struct nvme_smart_log *smart, unsigned int nsid, const char *devname); +void json_ana_log(struct nvme_ana_rsp_hdr *ana_log, const char *devname); void json_fw_log(struct nvme_firmware_log_page *fw_log, const char *devname); void json_print_list_items(struct list_item *items, unsigned amnt); void json_nvme_id_ns_descs(void *data); diff --git a/nvme.c b/nvme.c index 274871a..8f26aed 100644 --- a/nvme.c +++ b/nvme.c @@ -220,6 +220,85 @@ static int get_smart_log(int argc, char **argv, struct command *cmd, struct plug nvme_status_to_string(err), err); else perror("smart log"); + + return err; +} + +static int get_ana_log(int argc, char **argv, struct command *cmd, + struct plugin *plugin) +{ + const char *desc = "Retrieve ANA log for the given device" \ + "in either decoded format "\ + "(default) or binary."; + const char *raw = "output in binary format"; + void *ana_log; + int err, fmt, fd; + int groups = 0; /* Right now get all the per ANA group NSIDS */ + size_t ana_log_len; + struct nvme_id_ctrl ctrl; + + struct config { + int raw_binary; + char *output_format; + }; + + struct config cfg = { + .output_format = "normal", + }; + + const struct argconfig_commandline_options command_line_options[] = { + {"output-format", 'o', "FMT", CFG_STRING, &cfg.output_format, required_argument, output_format }, + {"raw-binary", 'b', "", CFG_NONE, &cfg.raw_binary, no_argument, raw}, + {NULL} + }; + + fd = parse_and_open(argc, argv, desc, command_line_options, NULL, 0); + if (fd < 0) + return fd; + + fmt = validate_output_format(cfg.output_format); + if (fmt < 0) { + err = fmt; + goto close_fd; + } + + if (cfg.raw_binary) + fmt = BINARY; + + memset(&ctrl, 0, sizeof (struct nvme_id_ctrl)); + err = nvme_identify_ctrl(fd, &ctrl); + if (err) { + fprintf(stderr, "ERROR : nvme_identify_ctrl() failed 0x%x\n", + err); + goto close_fd; + } + ana_log_len = sizeof(struct nvme_ana_rsp_hdr) + + le32_to_cpu(ctrl.nanagrpid) * sizeof(struct nvme_ana_group_desc); + if (!(ctrl.anacap & (1 << 6))) + ana_log_len += ctrl.mnan * sizeof(__le32); + + ana_log = malloc(ana_log_len); + if (!ana_log) { + perror("malloc : "); + err = -ENOMEM; + goto close_fd; + } + + err = nvme_ana_log(fd, ana_log, ana_log_len, groups ? NVME_ANA_LOG_RGO : 0); + if (!err) { + if (fmt == BINARY) + d_raw((unsigned char *)ana_log, ana_log_len); + else if (fmt == JSON) + json_ana_log(ana_log, devicename); + else + show_ana_log(ana_log, devicename); + } else if (err > 0) + fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(err), err); + else + perror("ana-log"); + free(ana_log); +close_fd: + close(fd); return err; } -- 2.13.7
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor