mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-25 18:40:19 -04:00
Log full SMART attributes
This commit is contained in:
parent
5e98164b64
commit
696ee97754
9 changed files with 95 additions and 26 deletions
|
|
@ -408,7 +408,7 @@ static double smart_afr_value(double* tab, unsigned step, uint64_t value)
|
|||
* we use the maximum rate reported, and we do not sum them,
|
||||
* because the attributes are not independent.
|
||||
*/
|
||||
static double smart_afr(struct smart_struct* smart, const char* model)
|
||||
static double smart_afr(struct smart_attr* smart, const char* model)
|
||||
{
|
||||
double afr = 0;
|
||||
uint64_t mask32 = 0xffffffffU;
|
||||
|
|
@ -556,10 +556,31 @@ static void state_smart_log(devinfo_t* devinfo, double afr)
|
|||
if (afr != 0)
|
||||
log_tag("attr:%s:%s:afr:%g:%g\n", devinfo->file, devinfo->name, afr, poisson_prob_at_least_one_failure(afr));
|
||||
|
||||
for (j = 0; j < 256; ++j)
|
||||
if (devinfo->smart[j].raw != SMART_UNASSIGNED) {
|
||||
log_tag("attr:%s:%s:%u:%" PRIu64 ":%" PRIx64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%s\n", devinfo->file, devinfo->name, j, devinfo->smart[j].raw, devinfo->smart[j].raw, devinfo->smart[j].norm, devinfo->smart[j].worst, devinfo->smart[j].thresh, devinfo->smart[j].name);
|
||||
for (j = 0; j < 256; ++j) {
|
||||
struct smart_attr* attr = &devinfo->smart[j];
|
||||
if (attr->raw != SMART_UNASSIGNED) {
|
||||
const char* type = "";;
|
||||
const char* updated = "";
|
||||
const char* when_failed = "";
|
||||
|
||||
if (attr->flags & SMART_ATTR_TYPE_PREFAIL)
|
||||
type = "prefail";
|
||||
else if (attr->flags & SMART_ATTR_TYPE_OLDAGE)
|
||||
type = "oldage";
|
||||
if (attr->flags & SMART_ATTR_UPDATE_ALWAYS)
|
||||
updated = "always";
|
||||
else if (attr->flags & SMART_ATTR_UPDATE_OFFLINE)
|
||||
updated = "offline";
|
||||
if (attr->flags & SMART_ATTR_WHEN_FAILED_NOW)
|
||||
when_failed = "now";
|
||||
else if (attr->flags & SMART_ATTR_WHEN_FAILED_PAST)
|
||||
when_failed = "past";
|
||||
else if (attr->flags & SMART_ATTR_WHEN_FAILED_NEVER)
|
||||
when_failed = "never";
|
||||
|
||||
log_tag("attr:%s:%s:%u:%" PRIu64 ":%" PRIx64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%s:%s:%s:%s\n", devinfo->file, devinfo->name, j, attr->raw, attr->raw, attr->norm, attr->worst, attr->thresh, attr->name, type, updated, when_failed);
|
||||
}
|
||||
}
|
||||
|
||||
int temp = smart_temp(devinfo);
|
||||
if (temp >= 0)
|
||||
|
|
|
|||
|
|
@ -2506,7 +2506,7 @@ static int devscan(tommy_list* list)
|
|||
/**
|
||||
* Get SMART attributes.
|
||||
*/
|
||||
static int devsmart(uint64_t device, const char* name, const char* smartctl, struct smart_struct* smart, uint64_t* info, char* serial, char* family, char* model, char* inter)
|
||||
static int devsmart(uint64_t device, const char* name, const char* smartctl, struct smart_attr* smart, uint64_t* info, char* serial, char* family, char* model, char* inter)
|
||||
{
|
||||
char conv_buf[CONV_MAX];
|
||||
WCHAR cmd[MAX_PATH + 128];
|
||||
|
|
@ -2738,7 +2738,7 @@ static void devattr(uint64_t device, const char* name, const char* wfile, uint64
|
|||
/**
|
||||
* Get POWER state
|
||||
*/
|
||||
static int devprobe(uint64_t device, const char* name, const char* smartctl, int* power, struct smart_struct* smart, uint64_t* info, char* serial, char* family, char* model, char* interf)
|
||||
static int devprobe(uint64_t device, const char* name, const char* smartctl, int* power, struct smart_attr* smart, uint64_t* info, char* serial, char* family, char* model, char* interf)
|
||||
{
|
||||
char conv_buf[CONV_MAX];
|
||||
WCHAR cmd[MAX_PATH + 128];
|
||||
|
|
|
|||
|
|
@ -502,6 +502,25 @@ int randomize(void* ptr, size_t size);
|
|||
*/
|
||||
#define SMART_UNASSIGNED 0xFFFFFFFFFFFFFFFFULL
|
||||
|
||||
/**
|
||||
* SMART Attribute flags
|
||||
*/
|
||||
#define SMART_ATTR_TYPE_PREFAIL 1
|
||||
#define SMART_ATTR_TYPE_OLDAGE 2
|
||||
#define SMART_ATTR_UPDATE_ALWAYS 4
|
||||
#define SMART_ATTR_UPDATE_OFFLINE 8
|
||||
#define SMART_ATTR_WHEN_FAILED_NOW 16
|
||||
#define SMART_ATTR_WHEN_FAILED_PAST 32
|
||||
#define SMART_ATTR_WHEN_FAILED_NEVER 64
|
||||
|
||||
struct smart_attr {
|
||||
char name[128]; /**< SMART attribute name. */
|
||||
uint64_t raw; /**< SMART attributes raw. */
|
||||
uint64_t norm; /**< SMART attributes normalized. */
|
||||
uint64_t worst; /**< SMART attributes worst. */
|
||||
uint64_t thresh; /**< SMART attributes threshold. */
|
||||
int flags; /**< SMART_ATTR_* flags */
|
||||
};
|
||||
|
||||
/**
|
||||
* Power mode
|
||||
|
|
@ -510,14 +529,6 @@ int randomize(void* ptr, size_t size);
|
|||
#define POWER_ACTIVE 1
|
||||
#define POWER_UNKNOWN -1
|
||||
|
||||
struct smart_struct {
|
||||
char name[128]; /**< SMART attribute name. */
|
||||
uint64_t raw; /**< SMART attributes raw. */
|
||||
uint64_t norm; /**< SMART attributes normalized. */
|
||||
uint64_t worst; /**< SMART attributes worst. */
|
||||
uint64_t thresh; /**< SMART attributes threshold. */
|
||||
};
|
||||
|
||||
/**
|
||||
* Device info entry.
|
||||
*/
|
||||
|
|
@ -533,7 +544,7 @@ struct devinfo_struct {
|
|||
#endif
|
||||
struct devinfo_struct* parent; /**< Pointer at the parent if any. */
|
||||
struct devinfo_struct* split; /**< Pointer at first split if any. */
|
||||
struct smart_struct smart[SMART_COUNT]; /**< All smart values. */
|
||||
struct smart_attr smart[SMART_COUNT]; /**< All smart values. */
|
||||
uint64_t info[INFO_COUNT]; /**< Info attributes. */
|
||||
uint64_t access_stat; /**< Access stat info. */
|
||||
char serial[SMART_MAX]; /**< Serial number. */
|
||||
|
|
|
|||
|
|
@ -1702,11 +1702,11 @@ static int smatch(const char* str, const char* pattern)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int smartctl_attribute(FILE* f, const char* file, const char* name, struct smart_struct* smart, uint64_t* info, char* serial, char* family, char* model, char* inter)
|
||||
int smartctl_attribute(FILE* f, const char* file, const char* name, struct smart_attr* smart, uint64_t* info, char* serial, char* family, char* model, char* inter)
|
||||
{
|
||||
unsigned i;
|
||||
int inside;
|
||||
struct smart_struct dummy_smart[SMART_COUNT];
|
||||
struct smart_attr dummy_smart[SMART_COUNT];
|
||||
uint64_t dummy_info[INFO_COUNT];
|
||||
char dummy_serial[SMART_MAX];
|
||||
char dummy_family[SMART_MAX];
|
||||
|
|
@ -1732,7 +1732,7 @@ int smartctl_attribute(FILE* f, const char* file, const char* name, struct smart
|
|||
*family = 0;
|
||||
*model = 0;
|
||||
*inter = 0;
|
||||
memset(smart, 0, sizeof(struct smart_struct) * SMART_COUNT);
|
||||
memset(smart, 0, sizeof(struct smart_attr) * SMART_COUNT);
|
||||
for (i = 0; i < SMART_COUNT; ++i)
|
||||
smart[i].raw = SMART_UNASSIGNED;
|
||||
for (i = 0; i < INFO_COUNT; ++i)
|
||||
|
|
@ -1851,11 +1851,16 @@ int smartctl_attribute(FILE* f, const char* file, const char* name, struct smart
|
|||
inside = 1;
|
||||
} else if (inside) {
|
||||
char id_name[128] = { 0 };
|
||||
char type[64] = { 0 };
|
||||
char updated[64] = { 0 };
|
||||
char when_failed[64] = { 0 };
|
||||
uint64_t min, max;
|
||||
int minmax;
|
||||
if (sscanf(s, "%u %127s %*s %" SCNu64 " %" SCNu64 " %" SCNu64 " %*s %*s %*s %" SCNu64 " (Min/Max %" SCNu64 "/%" SCNu64 ")", &id, id_name, &norm, &worst, &thresh, &raw, &min, &max) == 8) {
|
||||
int flags;
|
||||
|
||||
if (sscanf(s, "%u %127s %*s %" SCNu64 " %" SCNu64 " %" SCNu64 " %63s %63s %63s %" SCNu64 " (Min/Max %" SCNu64 "/%" SCNu64 ")", &id, id_name, &norm, &worst, &thresh, type, updated, when_failed, &raw, &min, &max) == 11) {
|
||||
minmax = 1;
|
||||
} else if (sscanf(s, "%u %127s %*s %" SCNu64 " %" SCNu64 " %" SCNu64 " %*s %*s %*s %" SCNu64, &id, id_name, &norm, &worst, &thresh, &raw) == 6) {
|
||||
} else if (sscanf(s, "%u %127s %*s %" SCNu64 " %" SCNu64 " %" SCNu64 " %63s %63s %63s %" SCNu64, &id, id_name, &norm, &worst, &thresh, type, updated, when_failed, &raw) == 9) {
|
||||
minmax = 0;
|
||||
} else {
|
||||
log_fatal(EEXTERNAL, "Invalid smartctl line '%s'.\n", s);
|
||||
|
|
@ -1869,6 +1874,22 @@ int smartctl_attribute(FILE* f, const char* file, const char* name, struct smart
|
|||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
flags = 0;
|
||||
if (strcmp(type, "Pre-fail") == 0)
|
||||
flags |= SMART_ATTR_TYPE_PREFAIL;
|
||||
else if (strcmp(type, "Old_age") == 0)
|
||||
flags |= SMART_ATTR_TYPE_OLDAGE;
|
||||
if (strcmp(updated, "Always") == 0)
|
||||
flags |= SMART_ATTR_UPDATE_ALWAYS;
|
||||
else if (strcmp(updated, "Offline") == 0)
|
||||
flags |= SMART_ATTR_UPDATE_OFFLINE;
|
||||
if (strcmp(when_failed, "FAILING_NOW") == 0)
|
||||
flags |= SMART_ATTR_WHEN_FAILED_NOW;
|
||||
else if (strcmp(when_failed, "In_the_past") == 0)
|
||||
flags |= SMART_ATTR_WHEN_FAILED_PAST;
|
||||
else if (strcmp(when_failed, "-") == 0)
|
||||
flags |= SMART_ATTR_WHEN_FAILED_NEVER;
|
||||
|
||||
/* revert the min/max decoding done by smartctl */
|
||||
if (minmax
|
||||
&& raw <= 0xFFFFUL
|
||||
|
|
@ -1882,6 +1903,7 @@ int smartctl_attribute(FILE* f, const char* file, const char* name, struct smart
|
|||
smart[id].norm = norm;
|
||||
smart[id].worst = worst;
|
||||
smart[id].thresh = thresh;
|
||||
smart[id].flags = flags;
|
||||
pathcpy(smart[id].name, sizeof(smart[id].name), id_name);
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -453,7 +453,7 @@ void malloc_fail(size_t size);
|
|||
* Read smartctl attributes from a stream.
|
||||
* Return 0 on success.
|
||||
*/
|
||||
int smartctl_attribute(FILE* f, const char* file, const char* name, struct smart_struct* smart, uint64_t* info, char* serial, char* family, char* model, char* interf);
|
||||
int smartctl_attribute(FILE* f, const char* file, const char* name, struct smart_attr* smart, uint64_t* info, char* serial, char* family, char* model, char* interf);
|
||||
|
||||
/**
|
||||
* Flush smartctl output from a stream.
|
||||
|
|
|
|||
|
|
@ -1479,7 +1479,7 @@ static int devscan(tommy_list* list)
|
|||
* Get SMART attributes.
|
||||
*/
|
||||
#if HAVE_LINUX_DEVICE
|
||||
static int devsmart(dev_t device, const char* name, const char* smartctl, struct smart_struct* smart, uint64_t* info, char* serial, char* family, char* model, char* interface)
|
||||
static int devsmart(dev_t device, const char* name, const char* smartctl, struct smart_attr* smart, uint64_t* info, char* serial, char* family, char* model, char* interface)
|
||||
{
|
||||
char cmd[PATH_MAX + 64];
|
||||
char file[PATH_MAX];
|
||||
|
|
@ -1717,7 +1717,7 @@ static void devattr(dev_t device, uint64_t* info, char* serial, char* family, ch
|
|||
* Get POWER state.
|
||||
*/
|
||||
#if HAVE_LINUX_DEVICE
|
||||
static int devprobe(dev_t device, const char* name, const char* smartctl, int* power, struct smart_struct* smart, uint64_t* info, char* serial, char* family, char* model, char* interface)
|
||||
static int devprobe(dev_t device, const char* name, const char* smartctl, int* power, struct smart_attr* smart, uint64_t* info, char* serial, char* family, char* model, char* interface)
|
||||
{
|
||||
char cmd[PATH_MAX + 64];
|
||||
char file[PATH_MAX];
|
||||
|
|
|
|||
|
|
@ -1794,7 +1794,7 @@ The raw flags value (uint, hexadecimal).
|
|||
.PD
|
||||
.RE
|
||||
.TP
|
||||
.B attr:<device_file>:<disk_name>[/<split_index>]:<id>:<raw_decimal>:<raw_hex>:<norm>:<worst>:<thresh>:<name>
|
||||
.B attr:<device_file>:<disk_name>[/<split_index>]:<id>:<raw_decimal>:<raw_hex>:<norm>:<worst>:<thresh>:<name>:<type>:<updated>:<when_failed>
|
||||
Logs the raw value of any assigned SMART attribute.
|
||||
.RS 4
|
||||
.PD 0
|
||||
|
|
@ -1819,6 +1819,15 @@ The threshold value (uint).
|
|||
.HP 4
|
||||
.I <name>
|
||||
Name of the attribute.
|
||||
.HP 4
|
||||
.I <type>
|
||||
Type of the attribute: \`prefail\` or \`oldage\`.
|
||||
.HP 4
|
||||
.I <updated>
|
||||
Update method of the attribute: \`always\` or \`offline\`.
|
||||
.HP 4
|
||||
.I <when_failed>
|
||||
If and when the attribute failed: \`never\` or \`past\` or \`now\`.
|
||||
.PD
|
||||
.RE
|
||||
.TP
|
||||
|
|
|
|||
|
|
@ -1121,7 +1121,7 @@ Command Smart And Probe Tags
|
|||
<flags_decimal> - The raw flags value (uint, decimal).
|
||||
<flags_hex> - The raw flags value (uint, hexadecimal).
|
||||
|
||||
=attr:<device_file>:<disk_name>[/<split_index>]:<id>:<raw_decimal>:<raw_hex>:<norm>:<worst>:<thresh>:<name>
|
||||
=attr:<device_file>:<disk_name>[/<split_index>]:<id>:<raw_decimal>:<raw_hex>:<norm>:<worst>:<thresh>:<name>:<type>:<updated>:<when_failed>
|
||||
Logs the raw value of any assigned SMART attribute.
|
||||
|
||||
<id> - The SMART attribute ID (uint).
|
||||
|
|
@ -1131,6 +1131,9 @@ Command Smart And Probe Tags
|
|||
<worst> - The worst value (uint).
|
||||
<thresh> - The threshold value (uint).
|
||||
<name> - Name of the attribute.
|
||||
<type> - Type of the attribute: `prefail` or `oldage`.
|
||||
<updated> - Update method of the attribute: `always` or `offline`.
|
||||
<when_failed> - If and when the attribute failed: `never` or `past` or `now`.
|
||||
|
||||
=attr:<device_file>:<disk_name>[/<split_index>]:power:active
|
||||
Logs that the device was confirmed to be in an active power
|
||||
|
|
|
|||
|
|
@ -1167,7 +1167,7 @@ Tags logging specific disk identification and attribute values.
|
|||
<flags_decimal> - The raw flags value (uint, decimal).
|
||||
<flags_hex> - The raw flags value (uint, hexadecimal).
|
||||
|
||||
attr:<device_file>:<disk_name>[/<split_index>]:<id>:<raw_decimal>:<raw_hex>:<norm>:<worst>:<thresh>:<name>
|
||||
attr:<device_file>:<disk_name>[/<split_index>]:<id>:<raw_decimal>:<raw_hex>:<norm>:<worst>:<thresh>:<name>:<type>:<updated>:<when_failed>
|
||||
Logs the raw value of any assigned SMART attribute.
|
||||
|
||||
<id> - The SMART attribute ID (uint).
|
||||
|
|
@ -1177,6 +1177,9 @@ Tags logging specific disk identification and attribute values.
|
|||
<worst> - The worst value (uint).
|
||||
<thresh> - The threshold value (uint).
|
||||
<name> - Name of the attribute.
|
||||
<type> - Type of the attribute: `prefail` or `oldage`.
|
||||
<updated> - Update method of the attribute: `always` or `offline`.
|
||||
<when_failed> - If and when the attribute failed: `never` or `past` or `now`.
|
||||
|
||||
attr:<device_file>:<disk_name>[/<split_index>]:power:active
|
||||
Logs that the device was confirmed to be in an active power
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue