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 */

View file

@ -1611,8 +1611,27 @@ The disk size in bytes (uint).
.PD
.RE
.TP
.B attr:<device_file>:<disk_name>[/<split_index>]:error:<error_count>
Logs the total error count.
.B attr:<device_file>:<disk_name>[/<split_index>]:error_protocol:<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.
.RS 4
.PD 0
.HP 4
.I <error_count>
The total error count (uint).
.PD
.RE
.TP
.B attr:<device_file>:<disk_name>[/<split_index>]:error_medium:<error_count>
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.
.RS 4
.PD 0
.HP 4

View file

@ -1018,8 +1018,22 @@ Command Smart And Probe Tags
<size_bytes> - The disk size in bytes (uint).
=attr:<device_file>:<disk_name>[/<split_index>]:error:<error_count>
Logs the total error count.
=attr:<device_file>:<disk_name>[/<split_index>]:error_protocol:<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.
<error_count> - The total error count (uint).
=attr:<device_file>:<disk_name>[/<split_index>]:error_medium:<error_count>
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.
<error_count> - The total error count (uint).

View file

@ -1064,8 +1064,22 @@ Tags logging specific disk identification and attribute values.
<size_bytes> - The disk size in bytes (uint).
attr:<device_file>:<disk_name>[/<split_index>]:error:<error_count>
Logs the total error count.
attr:<device_file>:<disk_name>[/<split_index>]:error_protocol:<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.
<error_count> - The total error count (uint).
attr:<device_file>:<disk_name>[/<split_index>]:error_medium:<error_count>
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.
<error_count> - The total error count (uint).