From 2088f7d8847ff1d24a0192049ea781bf5290f1c9 Mon Sep 17 00:00:00 2001 From: Broc Going Date: Thu, 14 May 2026 13:57:18 -0700 Subject: [PATCH 1/5] micron-nvme: Use libnvme_alloc for log data buffers Updates micron-nvme log buffers to use libnvme_alloc / libnvme_realloc / libnvme_free. Signed-off-by: Broc Going --- plugins/micron/micron-nvme.c | 63 ++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 35 deletions(-) diff --git a/plugins/micron/micron-nvme.c b/plugins/micron/micron-nvme.c index 2c9ab9cb80..e912c86962 100644 --- a/plugins/micron/micron-nvme.c +++ b/plugins/micron/micron-nvme.c @@ -486,19 +486,17 @@ static int NVMEGetLogPage(struct libnvme_transport_handle *hdl, unsigned char uc static int NVMEResetLog(struct libnvme_transport_handle *hdl, unsigned char ucLogID, int nBufferSize, long long llMaxSize) { - unsigned int *pBuffer = NULL; + __cleanup_libnvme_free unsigned int *pBuffer = NULL; int err = 0; - pBuffer = (unsigned int *)calloc(1, nBufferSize); + pBuffer = (unsigned int *)libnvme_alloc(nBufferSize); if (!pBuffer) return err; while (!err && llMaxSize > 0) { err = NVMEGetLogPage(hdl, ucLogID, (unsigned char *)pBuffer, nBufferSize, 0); - if (err) { - free(pBuffer); + if (err) return err; - } if (pBuffer[0] == 0xdeadbeef) break; @@ -506,7 +504,6 @@ static int NVMEResetLog(struct libnvme_transport_handle *hdl, unsigned char ucLo llMaxSize = llMaxSize - nBufferSize; } - free(pBuffer); return err; } @@ -516,7 +513,7 @@ static int GetCommonLogPage(struct libnvme_transport_handle *hdl, unsigned char unsigned char *pTempPtr = NULL; int err = 0; - pTempPtr = (unsigned char *)malloc(nBuffSize); + pTempPtr = (unsigned char *)libnvme_alloc(nBuffSize); if (!pTempPtr) goto exit_status; memset(pTempPtr, 0, nBuffSize); @@ -2195,8 +2192,8 @@ static void GetSmartlogData(struct libnvme_transport_handle *hdl, const char *di static void GetErrorlogData(struct libnvme_transport_handle *hdl, int entries, const char *dir) { int logSize = entries * sizeof(struct nvme_error_log_page); - struct nvme_error_log_page *error_log = - (struct nvme_error_log_page *)calloc(1, logSize); + __cleanup_libnvme_free struct nvme_error_log_page *error_log = + (struct nvme_error_log_page *)libnvme_alloc(logSize); if (!error_log) return; @@ -2204,8 +2201,6 @@ static void GetErrorlogData(struct libnvme_transport_handle *hdl, int entries, c if (!nvme_get_log_error(hdl, NVME_NSID_ALL, entries, error_log)) WriteData((__u8 *)error_log, logSize, dir, "error_information_log.bin", "error log"); - - free(error_log); } static void GetGenericLogs(struct libnvme_transport_handle *hdl, const char *dir) @@ -2317,7 +2312,7 @@ static int micron_telemetry_log(struct libnvme_transport_handle *hdl, __u8 type, unsigned short data_area[4]; unsigned char ctrl_init = (type == 0x8); - __u8 *buffer = (unsigned char *)calloc(bs, 1); + __u8 *buffer = (unsigned char *)libnvme_alloc(bs); if (!buffer) return -1; @@ -2327,7 +2322,7 @@ static int micron_telemetry_log(struct libnvme_transport_handle *hdl, __u8 type, err = nvme_get_log_telemetry_host(hdl, 0, buffer, bs); if (err) { fprintf(stderr, "Failed to get telemetry log header for 0x%X\n", type); - free(buffer); + libnvme_free(buffer); return err; } @@ -2340,7 +2335,7 @@ static int micron_telemetry_log(struct libnvme_transport_handle *hdl, __u8 type, if (!data_area[da]) { fprintf(stderr, "Requested telemetry data for 0x%X is empty\n", type); - free(buffer); + libnvme_free(buffer); buffer = NULL; return -1; } @@ -2348,7 +2343,7 @@ static int micron_telemetry_log(struct libnvme_transport_handle *hdl, __u8 type, *logSize = data_area[da] * bs; offset = bs; err = 0; - buffer = (unsigned char *)realloc(buffer, (size_t)(*logSize)); + buffer = (unsigned char *)libnvme_realloc(buffer, (size_t)(*logSize)); if (buffer) { while (!err && offset != *logSize) { if (ctrl_init) @@ -2363,7 +2358,7 @@ static int micron_telemetry_log(struct libnvme_transport_handle *hdl, __u8 type, *data = buffer; } else { fprintf(stderr, "Failed to get telemetry data for 0x%x\n", type); - free(buffer); + libnvme_free(buffer); } return err; @@ -2388,7 +2383,7 @@ static int GetTelemetryData(struct libnvme_transport_handle *hdl, const char *di sprintf(msg, "telemetry log: 0x%X", tmap[i].log); WriteData(buffer, logSize, dir, tmap[i].file, msg); } - free(buffer); + libnvme_free(buffer); buffer = NULL; logSize = 0; } @@ -3391,7 +3386,7 @@ static int get_common_log(struct libnvme_transport_handle *hdl, uint8_t id, uint * yet reached its max size */ if (hdr.log_size == sizeof(hdr)) { - buffer = (uint8_t *)malloc(sizeof(hdr)); + buffer = (uint8_t *)libnvme_alloc(sizeof(hdr)); if (!buffer) { fprintf(stderr, "malloc of %zu bytes failed for log: 0x%X\n", sizeof(hdr), id); @@ -3399,7 +3394,7 @@ static int get_common_log(struct libnvme_transport_handle *hdl, uint8_t id, uint } memcpy(buffer, (uint8_t *)&hdr, sizeof(hdr)); } else if (hdr.log_size < hdr.max_size) { - buffer = (uint8_t *)malloc(sizeof(hdr) + hdr.log_size); + buffer = (uint8_t *)libnvme_alloc(sizeof(hdr) + hdr.log_size); if (!buffer) { fprintf(stderr, "malloc of %zu bytes failed for log: 0x%X\n", hdr.log_size + sizeof(hdr), id); @@ -3417,7 +3412,7 @@ static int get_common_log(struct libnvme_transport_handle *hdl, uint8_t id, uint * hdr.log_size > hdr.max_size; also ignore over-written log data; we * also ignore collisions for now */ - buffer = (uint8_t *)malloc(hdr.max_size + sizeof(hdr)); + buffer = (uint8_t *)libnvme_alloc(hdr.max_size + sizeof(hdr)); if (!buffer) { fprintf(stderr, "malloc of %zu bytes failed for log: 0x%X\n", hdr.max_size + sizeof(hdr), id); @@ -3432,7 +3427,7 @@ static int get_common_log(struct libnvme_transport_handle *hdl, uint8_t id, uint ret = nvme_get_log_lpo(hdl, id, hdr.write_pointer, chunk, first, buffer + sizeof(hdr)); if (ret) { - free(buffer); + libnvme_free(buffer); fprintf(stderr, "failed to get log: 0x%X\n", id); return ret; } @@ -3443,7 +3438,7 @@ static int get_common_log(struct libnvme_transport_handle *hdl, uint8_t id, uint buffer + sizeof(hdr) + first); if (ret) { fprintf(stderr, "failed to get log: 0x%X\n", id); - free(buffer); + libnvme_free(buffer); return ret; } log_size += second; @@ -3457,10 +3452,10 @@ static int get_common_log(struct libnvme_transport_handle *hdl, uint8_t id, uint static int GetOcpEnhancedTelemetryLog(struct libnvme_transport_handle *hdl, const char *dir, int nLogID) { int err = 0; - unsigned char *pTelemetryDataHeader = 0; + __cleanup_libnvme_free unsigned char *pTelemetryDataHeader = NULL; unsigned int nallocSize = 0; unsigned int nOffset = 0; - unsigned char *pTelemetryBuffer = 0; + unsigned char *pTelemetryBuffer = NULL; unsigned int usAreaLastBlock[4] = {0}; bool bTeleheaderWrite = true; /* Enable ETDAS */ @@ -3478,7 +3473,7 @@ static int GetOcpEnhancedTelemetryLog(struct libnvme_transport_handle *hdl, cons printf("Failed to set ETDAS, Data Area 4 won't be avialable >>> "); /* Read Telemetry header information */ - pTelemetryDataHeader = (unsigned char *)calloc(512, sizeof(unsigned char)); + pTelemetryDataHeader = (unsigned char *)libnvme_alloc(512); if (!pTelemetryDataHeader) { printf("Unable to allocate buffer of size 0x%X bytes for telemetry header", 512); @@ -3515,7 +3510,7 @@ static int GetOcpEnhancedTelemetryLog(struct libnvme_transport_handle *hdl, cons continue; } - pTelemetryBuffer = (unsigned char *)calloc(nallocSize, 1); + pTelemetryBuffer = (unsigned char *)libnvme_alloc(nallocSize); if (!pTelemetryBuffer) { printf( "Unable to allocate buffer of size 0x%X bytes for Data Area %d" @@ -3532,7 +3527,7 @@ static int GetOcpEnhancedTelemetryLog(struct libnvme_transport_handle *hdl, cons "Failed to fetch telemetry data of size : %u from offset : %u!\n" , nallocSize, nOffset ); - free(pTelemetryBuffer); + libnvme_free(pTelemetryBuffer); pTelemetryBuffer = NULL; nOffset += nallocSize; continue; @@ -3565,11 +3560,9 @@ static int GetOcpEnhancedTelemetryLog(struct libnvme_transport_handle *hdl, cons } } - free(pTelemetryBuffer); + libnvme_free(pTelemetryBuffer); pTelemetryBuffer = NULL; } - // free mem of header, all areas - free(pTelemetryDataHeader); return err; } @@ -3734,7 +3727,7 @@ static int micron_internal_logs(int argc, char **argv, struct command *acmd, if (!err && logSize > 0 && buffer) { sprintf(msg, "telemetry log: 0x%X", cfg.log); WriteData(buffer, logSize, dir, cfg.package, msg); - free(buffer); + libnvme_free(buffer); } goto out; } @@ -3810,7 +3803,7 @@ static int micron_internal_logs(int argc, char **argv, struct command *acmd, if (err == 0) { bSize = stWllHdr.uiLength; if (bSize > 0) { - dataBuffer = (unsigned char *)calloc(bSize, 1); + dataBuffer = (unsigned char *)libnvme_alloc(bSize); if (!dataBuffer) { printf( " Memory allocation failed for log id : 0x%02X\n" @@ -3882,7 +3875,7 @@ static int micron_internal_logs(int argc, char **argv, struct command *acmd, if (bSize % (16 * 1024)) bSize += (16 * 1024) - (bSize % (16 * 1024)); } - dataBuffer = (unsigned char *)malloc(bSize); + dataBuffer = (unsigned char *)libnvme_alloc(bSize); if (bSize && dataBuffer) { memset(dataBuffer, 0, bSize); if (eModel == M5410 || eModel == M5407) @@ -3905,7 +3898,7 @@ static int micron_internal_logs(int argc, char **argv, struct command *acmd, default: bSize = aVendorLogs[i].nLogSize; - dataBuffer = (unsigned char *)malloc(bSize); + dataBuffer = (unsigned char *)libnvme_alloc(bSize); if (!dataBuffer) break; memset(dataBuffer, 0, bSize); @@ -3930,7 +3923,7 @@ static int micron_internal_logs(int argc, char **argv, struct command *acmd, WriteData(dataBuffer, bSize, strCtrlDirName, aVendorLogs[i].strFileName, msg); } - free(dataBuffer); + libnvme_free(dataBuffer); dataBuffer = NULL; } From 5d5b3eabd7ec6da46aab036262cf95cd9e9691e8 Mon Sep 17 00:00:00 2001 From: Broc Going Date: Fri, 15 May 2026 07:44:51 -0700 Subject: [PATCH 2/5] micron-nvme: Fix telemetry log reading Fixes telemetry log reading failures caused by the wrong offset and size values being used. Improves error reporting. Signed-off-by: Broc Going --- plugins/micron/micron-nvme.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/micron/micron-nvme.c b/plugins/micron/micron-nvme.c index e912c86962..08e22fe6a3 100644 --- a/plugins/micron/micron-nvme.c +++ b/plugins/micron/micron-nvme.c @@ -2347,9 +2347,9 @@ static int micron_telemetry_log(struct libnvme_transport_handle *hdl, __u8 type, if (buffer) { while (!err && offset != *logSize) { if (ctrl_init) - err = nvme_get_log_telemetry_ctrl(hdl, true, 0, buffer + offset, *logSize); + err = nvme_get_log_telemetry_ctrl(hdl, true, offset, buffer + offset, bs); else - err = nvme_get_log_telemetry_host(hdl, 0, buffer + offset, *logSize); + err = nvme_get_log_telemetry_host(hdl, offset, buffer + offset, bs); offset += bs; } } @@ -2357,7 +2357,7 @@ static int micron_telemetry_log(struct libnvme_transport_handle *hdl, __u8 type, if (!err && buffer) { *data = buffer; } else { - fprintf(stderr, "Failed to get telemetry data for 0x%x\n", type); + nvme_show_err(err, "Failed to get telemetry data for 0x%x\n", type); libnvme_free(buffer); } From 7557f13390aa3ee5d4fc7e692dd035e0fd707355 Mon Sep 17 00:00:00 2001 From: Broc Going Date: Fri, 15 May 2026 07:46:17 -0700 Subject: [PATCH 3/5] micron-nvme: Fix vs-drive-info output format check Fixes format parameter validation logic, which was causing the command to always fail with "Invalid output format". Signed-off-by: Broc Going --- plugins/micron/micron-nvme.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/micron/micron-nvme.c b/plugins/micron/micron-nvme.c index 08e22fe6a3..2b872655d3 100644 --- a/plugins/micron/micron-nvme.c +++ b/plugins/micron/micron-nvme.c @@ -2483,7 +2483,7 @@ static int micron_drive_info(int argc, char **argv, struct command *acmd, return -1; } - if (strcmp(cfg.fmt, "normal") || strcmp(cfg.fmt, "json")) { + if (strcmp(cfg.fmt, "normal") && strcmp(cfg.fmt, "json")) { fprintf(stderr, "Invalid output format\n"); return -1; } From ed1378c10c0bf1af9b11144b845e51a3e48c8f01 Mon Sep 17 00:00:00 2001 From: Broc Going Date: Fri, 15 May 2026 08:03:13 -0700 Subject: [PATCH 4/5] micron-nvme: Clean up vs-nand-stats Removes duplicate id-ctrl and improves error reporting when no log can be read. Signed-off-by: Broc Going --- plugins/micron/micron-nvme.c | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/plugins/micron/micron-nvme.c b/plugins/micron/micron-nvme.c index 2b872655d3..df49673055 100644 --- a/plugins/micron/micron-nvme.c +++ b/plugins/micron/micron-nvme.c @@ -1836,25 +1836,18 @@ static int micron_nand_stats(int argc, char **argv, if (!strcmp(cfg.fmt, "normal")) is_json = false; - err = nvme_identify_ctrl(hdl, &ctrl); - if (err) { - printf("Error %d retrieving controller identification data\n", err); - goto out; - } - /* pull log details based on the model name */ if (sscanf(argv[optind], "/dev/nvme%d", &ctrlIdx) != 1) ctrlIdx = 0; eModel = GetDriveModel(ctrlIdx); if (eModel == UNKNOWN_MODEL) { printf("Unsupported drive model for vs-nand-stats command\n"); - err = -1; - goto out; + return -1; } err = nvme_identify_ctrl(hdl, &ctrl); if (err) { - fprintf(stderr, "ERROR : identify_ctrl() failed with 0x%x\n", err); + nvme_show_err(err, "ERROR : identify_ctrl() failed"); return -1; } @@ -1864,13 +1857,13 @@ static int micron_nand_stats(int argc, char **argv, print_hyperscale_nand_stats((__u8 *)logC0, is_json); goto out; } else if (err < 0) { - printf("Unable to retrieve extended smart log 0xC0 for the drive\n"); + nvme_show_err(err, "Unable to retrieve extended smart log 0xC0 for the drive"); return -1; } } err = nvme_get_log_simple(hdl, 0xD0, extSmartLog, D0_log_size); - has_d0_log = (err == 0); + has_d0_log = !err; /* should check for firmware version if this log is supported or not */ if (eModel != M5407 && eModel != M5410) { @@ -1881,21 +1874,19 @@ static int micron_nand_stats(int argc, char **argv, nsze = (ctrl.vs[987] == 0x12); if (!nsze && nsze_from_oacs) nsze = ((ctrl.oacs >> 3) & 0x1); - err = 0; + if (has_fb_log) { __u8 spec = (eModel == M5410) ? 0 : 1; /* FB spec version */ print_nand_stats_fb((__u8 *)logFB, (__u8 *)extSmartLog, nsze, is_json, spec); + err = 0; } else if (has_d0_log) { print_nand_stats_d0((__u8 *)extSmartLog, nsze, is_json); err = 0; - } else { - printf("Unable to retrieve extended smart log for the drive\n"); - err = -ENOTTY; } out: - if (err > 0) - nvme_show_status(err); + if (err) + nvme_show_err(err, "Unable to retrieve extended smart log for the drive"); return err; } From 98a743169dbbe13c58995ed405a3d5873700e9eb Mon Sep 17 00:00:00 2001 From: Broc Going Date: Fri, 15 May 2026 11:01:57 -0700 Subject: [PATCH 5/5] micron-nvme: Fix error reporting for commands that were failing silently Fixes reporting of positive error values in several commands in the micron-nvme plugin. Cleans up error reporting of positive versus negative error codes by using nvme_show_err. Signed-off-by: Broc Going --- plugins/micron/micron-nvme.c | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/plugins/micron/micron-nvme.c b/plugins/micron/micron-nvme.c index df49673055..23d8c0cf97 100644 --- a/plugins/micron/micron-nvme.c +++ b/plugins/micron/micron-nvme.c @@ -2510,8 +2510,8 @@ static int micron_drive_info(int argc, char **argv, struct command *acmd, dinfo.bs_ver_major = *((__u16 *)(logC0+300)); dinfo.bs_ver_minor = *((__u16 *)(logC0+302)); dinfo.ownership_status = *((__u32 *)(logC0+312)); - } else if (err < 0) { - printf("Unable to retrieve extended smart log 0xC0 for the drive\n"); + } else { + nvme_show_err(err, "Unable to retrieve extended smart log 0xC0 for the drive"); return -1; } } @@ -2800,7 +2800,7 @@ static int micron_fw_activation_history(int argc, char **argv, struct command *a err = nvme_get_log_simple(hdl, 0xC2, logC2, C2_log_size); if (err) { - fprintf(stderr, "Failed to retrieve fw activation history log, error: %x\n", err); + nvme_show_err(err, "Failed to retrieve fw activation history log"); goto out; } @@ -3023,8 +3023,7 @@ static int micron_latency_stats_logs(int argc, char **argv, struct command *acmd memset(&log, 0, sizeof(log)); err = nvme_get_log_simple(hdl, 0xD1, &log, sizeof(log)); if (err) { - if (err < 0) - printf("Unable to retrieve latency stats log the drive\n"); + nvme_show_err(err, "Unable to retrieve latency stats log the drive"); return err; } /* print header and each log entry */ @@ -3108,8 +3107,7 @@ static int micron_latency_stats_info(int argc, char **argv, struct command *acmd memset(&log, 0, sizeof(log)); err = nvme_get_log_simple(hdl, 0xD0, &log, sizeof(log)); if (err) { - if (err < 0) - printf("Unable to retrieve latency stats log the drive\n"); + nvme_show_err(err, "Unable to retrieve latency stats log for the drive"); return err; } printf("Micron IO %s Command Latency Statistics\n" @@ -3174,8 +3172,7 @@ static int micron_ocp_smart_health_logs(int argc, char **argv, struct command *a if (!err) err = nvme_get_log_simple(hdl, 0xFB, logFB, FB_log_size); if (err) { - if (err < 0) - printf("Unable to retrieve smart log 0xFB for the drive\n"); + nvme_show_err(err, "Unable to retrieve smart log 0xFB for the drive"); goto out; } @@ -3197,11 +3194,9 @@ static int micron_ocp_smart_health_logs(int argc, char **argv, struct command *a err = nvme_get_log_simple(hdl, 0xC0, logC0, C0_log_size); if (!err) print_smart_cloud_health_log((__u8 *)logC0, is_json, eModel); - else if (err < 0) - printf("Unable to retrieve extended smart log 0xC0 for the drive\n"); + else + nvme_show_err(err, "Unable to retrieve extended smart log 0xC0 for the drive"); out: - if (err > 0) - nvme_show_status(err); return err; } @@ -3232,7 +3227,7 @@ static int micron_clr_fw_activation_history(int argc, char **argv, if (!err) err = (int)result; else - printf("Failed to clear fw activation history, error = 0x%x\n", err); + nvme_show_err(err, "Failed to clear fw activation history"); return err; } @@ -4036,8 +4031,8 @@ static int micron_cloud_boot_SSD_version(int argc, char **argv, printf("HyperScale Boot Version Spec.%x.%x\n", le16_to_cpu(major) , le16_to_cpu(minor)); - } else if (err < 0) { - printf("Error %d retrieving extended smart log 0xC0 for the drive\n", err); + } else { + nvme_show_err(err, "Error retrieving extended smart log 0xC0 for the drive"); goto out; } out: @@ -4159,7 +4154,7 @@ static int micron_cloud_log(int argc, char **argv, struct command *acmd, err = nvme_get_log_simple(hdl, 0xC0, logC0, C0_log_size); if (err == 0) print_hyperscale_cloud_health_log((__u8 *)logC0, is_json); - else if (err < 0) + else printf("Unable to retrieve extended smart log 0xC0 for the drive\n"); out: