Log both protocol and medium errors

This commit is contained in:
Andrea Mazzoleni 2026-01-19 14:33:55 +01:00
parent 58ca0b7057
commit e99f43c8ca
6 changed files with 97 additions and 20 deletions

View file

@ -565,8 +565,10 @@ static void state_smart_log(devinfo_t* devinfo, double afr)
unsigned j;
log_tag("smart:%s:%s\n", devinfo->file, devinfo->name);
if (devinfo->smart[SMART_ERROR] != SMART_UNASSIGNED)
log_tag("attr:%s:%s:error:%" PRIu64 "\n", devinfo->file, devinfo->name, devinfo->smart[SMART_ERROR]);
if (devinfo->smart[SMART_ERROR_PROTOCOL] != SMART_UNASSIGNED)
log_tag("attr:%s:%s:error_protocol:%" PRIu64 "\n", devinfo->file, devinfo->name, devinfo->smart[SMART_ERROR_PROTOCOL]);
if (devinfo->smart[SMART_ERROR_MEDIUM] != SMART_UNASSIGNED)
log_tag("attr:%s:%s:error_medium:%" PRIu64 "\n", devinfo->file, devinfo->name, devinfo->smart[SMART_ERROR_MEDIUM]);
if (devinfo->smart[SMART_FLAGS] != SMART_UNASSIGNED)
log_tag("attr:%s:%s:flags:%" PRIu64 ":%" PRIx64 "\n", devinfo->file, devinfo->name, devinfo->smart[SMART_FLAGS], devinfo->smart[SMART_FLAGS]);
@ -655,25 +657,28 @@ static void state_smart(struct snapraid_state* state, unsigned n, tommy_list* lo
else
printf(" -");
uint64_t error_count = 0;
if (devinfo->smart[SMART_ERROR_PROTOCOL] != SMART_UNASSIGNED && devinfo->smart[SMART_ERROR_PROTOCOL] != 0)
error_count += devinfo->smart[SMART_ERROR_PROTOCOL];
if (devinfo->smart[SMART_ERROR_MEDIUM] != SMART_UNASSIGNED && devinfo->smart[SMART_ERROR_MEDIUM] != 0)
error_count += devinfo->smart[SMART_ERROR_MEDIUM];
if (devinfo->smart[SMART_FLAGS] != SMART_UNASSIGNED)
flag = devinfo->smart[SMART_FLAGS];
else
flag = 0;
if (flag & SMARTCTL_FLAG_FAIL)
printf(" FAIL");
else if (flag & SMARTCTL_FLAG_PREFAIL)
printf(" PREFAIL");
else if (flag & SMARTCTL_FLAG_PREFAIL_LOGGED)
printf(" logfail");
else if (devinfo->smart[SMART_ERROR] != SMART_UNASSIGNED
&& devinfo->smart[SMART_ERROR] != 0)
printf("%8" PRIu64, devinfo->smart[SMART_ERROR]);
else if (flag & SMARTCTL_FLAG_ERROR)
else if (error_count != 0) {
printf("%8" PRIu64, error_count);
} else if (flag & SMARTCTL_FLAG_ERROR)
printf(" logerr");
else if (flag & SMARTCTL_FLAG_ERROR_LOGGED)
printf(" selferr");
else if (devinfo->smart[SMART_ERROR] == 0)
printf(" 0");
else
printf(" -");
@ -910,12 +915,13 @@ int devtest(tommy_list* high, tommy_list* low, int operation)
pathcpy(entry->name, sizeof(entry->name), devinfo->name);
entry->info[INFO_SIZE] = count * TERA;
entry->info[INFO_ROTATION_RATE] = 7200;
entry->smart[SMART_ERROR] = 0;
entry->smart[SMART_ERROR_MEDIUM] = 0;
entry->smart[SMART_ERROR_PROTOCOL] = 0;
entry->smart[SMART_FLAGS] = SMART_UNASSIGNED;
entry->smart[SMART_TEMPERATURE_CELSIUS] = 27;
switch (count) {
case 3 : entry->smart[SMART_ERROR] = 1; break;
case 3 : entry->smart[SMART_ERROR_PROTOCOL] = 1; break;
case 4 : entry->smart[SMART_FLAGS] = SMARTCTL_FLAG_UNSUPPORTED; break;
case 5 : entry->smart[SMART_FLAGS] = SMARTCTL_FLAG_COMMAND; break;
case 6 : entry->smart[SMART_FLAGS] = SMARTCTL_FLAG_OPEN; break;

View file

@ -433,12 +433,28 @@ int randomize(void* ptr, size_t size);
#define SMART_TEMPERATURE_CELSIUS 194
#define SMART_FLAGS 256 /**< Flags returned by smartctl. */
#define SMART_ERROR 257 /**< ATA Error count. */
/*
* Counts command, transport, or controller-level errors reported by the device.
* These reflect failed I/O operations not directly caused by media defects
* (for example interface, firmware, or power-related errors).
* This counter is cumulative and never resets to zero, even if the underlying
* error condition is resolved.
*/
#define SMART_ERROR_PROTOCOL 257
/*
* Counts media-level errors where data could not be reliably read or written.
* These indicate actual storage surface or flash failures and may imply data loss.
* This counter is cumulative and never resets to zero, even if the underlying
* error condition is resolved.
*/
#define SMART_ERROR_MEDIUM 258
/**
* SMART attributes count.
*/
#define SMART_COUNT 258
#define SMART_COUNT 259
/**
* Info attributes.

View file

@ -1779,9 +1779,17 @@ int smartctl_attribute(FILE* f, const char* file, const char* name, uint64_t* sm
} else if (smatch(s, "ID#") == 0) {
inside = 1;
} else if (smatch(s, "No Errors Logged") == 0) {
smart[SMART_ERROR] = 0;
smart[SMART_ERROR_PROTOCOL] = 0;
} else if (sscanf(s, "ATA Error Count: %" SCNu64, &raw) == 1) {
smart[SMART_ERROR] = raw;
smart[SMART_ERROR_PROTOCOL] = raw;
} else if (sscanf(s, "Media and Data Integrity Errors: %" SCNu64, &raw) == 1) {
smart[SMART_ERROR_MEDIUM] = raw;
} else if (sscanf(s, "Error Information Log Entries: %" SCNu64, &raw) == 1) {
smart[SMART_ERROR_PROTOCOL] = raw;
} else if (sscanf(s, "Medium error count: %" SCNu64, &raw) == 1) {
smart[SMART_ERROR_MEDIUM] = raw;
} else if (sscanf(s, "Non-medium error count: %" SCNu64, &raw) == 1) {
smart[SMART_ERROR_PROTOCOL] = raw;
} else if (inside) {
if (sscanf(s, "%u %*s %*s %*s %*s %*s %*s %*s %*s %" SCNu64, &id, &raw) != 2) {
/* LCOV_EXCL_START */