diff --git a/cmdline/device.c b/cmdline/device.c index 59564ac9..c0480a35 100644 --- a/cmdline/device.c +++ b/cmdline/device.c @@ -408,26 +408,26 @@ 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(uint64_t* smart, const char* model) +static double smart_afr(struct smart_struct* smart, const char* model) { double afr = 0; uint64_t mask32 = 0xffffffffU; uint64_t mask16 = 0xffffU; /* do not estimate for not rotational */ - if (smart[INFO_ROTATION_RATE] == 0) + if (smart[INFO_ROTATION_RATE].raw == 0) return 0; - if (smart[5] != SMART_UNASSIGNED) { - double r = smart_afr_value(SMART_5_R, SMART_5_STEP, smart[5] & mask32); + if (smart[5].raw != SMART_UNASSIGNED) { + double r = smart_afr_value(SMART_5_R, SMART_5_STEP, smart[5].raw & mask32); if (afr < r) afr = r; } - if (smart[187] != SMART_UNASSIGNED) { + if (smart[187].raw != SMART_UNASSIGNED) { /* with some disks, only the lower 16 bits are significant */ /* See: http://web.archive.org/web/20130507072056/http://media.kingston.com/support/downloads/MKP_306_SMART_attribute.pdf */ - double r = smart_afr_value(SMART_187_R, SMART_187_STEP, smart[187] & mask16); + double r = smart_afr_value(SMART_187_R, SMART_187_STEP, smart[187].raw & mask16); if (afr < r) afr = r; } @@ -440,23 +440,23 @@ static double smart_afr(uint64_t* smart, const char* model) * and IronWolf disks to be a not significant test as * this value increases too often also on sane disks. */ - strncmp(model, "ST", 2) != 0 && smart[188] != SMART_UNASSIGNED + strncmp(model, "ST", 2) != 0 && smart[188].raw != SMART_UNASSIGNED ) { /* with Seagate disks, there are three different 16 bits value reported */ /* the lowest one is the most significant */ - double r = smart_afr_value(SMART_188_R, SMART_188_STEP, smart[188] & mask16); + double r = smart_afr_value(SMART_188_R, SMART_188_STEP, smart[188].raw & mask16); if (afr < r) afr = r; } - if (smart[197] != SMART_UNASSIGNED) { - double r = smart_afr_value(SMART_197_R, SMART_197_STEP, smart[197] & mask32); + if (smart[197].raw != SMART_UNASSIGNED) { + double r = smart_afr_value(SMART_197_R, SMART_197_STEP, smart[197].raw & mask32); if (afr < r) afr = r; } - if (smart[198] != SMART_UNASSIGNED) { - double r = smart_afr_value(SMART_198_R, SMART_198_STEP, smart[198] & mask32); + if (smart[198].raw != SMART_UNASSIGNED) { + double r = smart_afr_value(SMART_198_R, SMART_198_STEP, smart[198].raw & mask32); if (afr < r) afr = r; } @@ -544,21 +544,22 @@ 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_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_WEAR_LEVEL] != SMART_UNASSIGNED) - log_tag("attr:%s:%s:wear_level:%" PRIu64 "\n", devinfo->file, devinfo->name, devinfo->smart[SMART_WEAR_LEVEL]); - 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]); + if (devinfo->smart[SMART_ERROR_PROTOCOL].raw != SMART_UNASSIGNED) + log_tag("attr:%s:%s:error_protocol:%" PRIu64 "\n", devinfo->file, devinfo->name, devinfo->smart[SMART_ERROR_PROTOCOL].raw); + if (devinfo->smart[SMART_ERROR_MEDIUM].raw != SMART_UNASSIGNED) + log_tag("attr:%s:%s:error_medium:%" PRIu64 "\n", devinfo->file, devinfo->name, devinfo->smart[SMART_ERROR_MEDIUM].raw); + if (devinfo->smart[SMART_WEAR_LEVEL].raw != SMART_UNASSIGNED) + log_tag("attr:%s:%s:wear_level:%" PRIu64 "\n", devinfo->file, devinfo->name, devinfo->smart[SMART_WEAR_LEVEL].raw); + if (devinfo->smart[SMART_FLAGS].raw != SMART_UNASSIGNED) + log_tag("attr:%s:%s:flags:%" PRIu64 ":%" PRIx64 "\n", devinfo->file, devinfo->name, devinfo->smart[SMART_FLAGS].raw, devinfo->smart[SMART_FLAGS].raw); 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] != SMART_UNASSIGNED) - log_tag("attr:%s:%s:%u:%" PRIu64 ":%" PRIx64 "\n", devinfo->file, devinfo->name, j, devinfo->smart[j], devinfo->smart[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); + } int temp = smart_temp(devinfo); if (temp >= 0) @@ -627,8 +628,8 @@ static void state_smart(struct snapraid_state* state, unsigned n, tommy_list* lo /* clear attributes to ignore */ for (j = 0; j < SMART_IGNORE_MAX; ++j) { - devinfo->smart[state->smartignore[j]] = SMART_UNASSIGNED; - devinfo->smart[devinfo->smartignore[j]] = SMART_UNASSIGNED; + devinfo->smart[state->smartignore[j]].raw = SMART_UNASSIGNED; + devinfo->smart[devinfo->smartignore[j]].raw = SMART_UNASSIGNED; } int temp = smart_temp(devinfo); @@ -637,18 +638,18 @@ static void state_smart(struct snapraid_state* state, unsigned n, tommy_list* lo else printf(" -"); - if (devinfo->smart[SMART_POWER_ON_HOURS] != SMART_UNASSIGNED) - printf("%7" PRIu64, (devinfo->smart[SMART_POWER_ON_HOURS] & mask32) / 24); + if (devinfo->smart[SMART_POWER_ON_HOURS].raw != SMART_UNASSIGNED) + printf("%7" PRIu64, (devinfo->smart[SMART_POWER_ON_HOURS].raw & mask32) / 24); 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]; + if (devinfo->smart[SMART_ERROR_PROTOCOL].raw != SMART_UNASSIGNED && devinfo->smart[SMART_ERROR_PROTOCOL].raw != 0) + error_count += devinfo->smart[SMART_ERROR_PROTOCOL].raw; + if (devinfo->smart[SMART_ERROR_MEDIUM].raw != SMART_UNASSIGNED && devinfo->smart[SMART_ERROR_MEDIUM].raw != 0) + error_count += devinfo->smart[SMART_ERROR_MEDIUM].raw; + if (devinfo->smart[SMART_FLAGS].raw != SMART_UNASSIGNED) + flag = devinfo->smart[SMART_FLAGS].raw; else flag = 0; @@ -697,8 +698,8 @@ static void state_smart(struct snapraid_state* state, unsigned n, tommy_list* lo } } - if (devinfo->smart[SMART_WEAR_LEVEL] != SMART_UNASSIGNED) { - printf(" %3" PRIu64 "%%", devinfo->smart[SMART_WEAR_LEVEL]); + if (devinfo->smart[SMART_WEAR_LEVEL].raw != SMART_UNASSIGNED) { + printf(" %3" PRIu64 "%%", devinfo->smart[SMART_WEAR_LEVEL].raw); } else { printf(" -"); } @@ -910,10 +911,14 @@ int devtest(tommy_list* high, tommy_list* low, int operation) for (j = 0; j < 256; ++j) { switch (count) { - case 0 : entry->smart[j] = 0; break; - case 1 : entry->smart[j] = SMART_UNASSIGNED; break; + case 0 : + entry->smart[j].raw = 0; + break; + case 1 : + entry->smart[j].raw = SMART_UNASSIGNED; + break; default : - entry->smart[j] = 0; + entry->smart[j].raw = 0; break; } } @@ -926,21 +931,21 @@ 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_MEDIUM] = 0; - entry->smart[SMART_ERROR_PROTOCOL] = 0; - entry->smart[SMART_FLAGS] = SMART_UNASSIGNED; - entry->smart[SMART_TEMPERATURE_CELSIUS] = 27; + entry->smart[SMART_ERROR_MEDIUM].raw = 0; + entry->smart[SMART_ERROR_PROTOCOL].raw = 0; + entry->smart[SMART_FLAGS].raw = SMART_UNASSIGNED; + entry->smart[SMART_TEMPERATURE_CELSIUS].raw = 27; switch (count) { - 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; - case 7 : entry->smart[SMART_FLAGS] = SMARTCTL_FLAG_FAIL; break; - case 8 : entry->smart[SMART_FLAGS] = SMARTCTL_FLAG_PREFAIL; break; - case 9 : entry->smart[SMART_FLAGS] = SMARTCTL_FLAG_PREFAIL_LOGGED; break; - case 10 : entry->smart[SMART_FLAGS] = SMARTCTL_FLAG_ERROR_LOGGED; break; - case 11 : entry->smart[SMART_FLAGS] = SMARTCTL_FLAG_SELFERROR_LOGGED; break; + case 3 : entry->smart[SMART_ERROR_PROTOCOL].raw = 1; break; + case 4 : entry->smart[SMART_FLAGS].raw = SMARTCTL_FLAG_UNSUPPORTED; break; + case 5 : entry->smart[SMART_FLAGS].raw = SMARTCTL_FLAG_COMMAND; break; + case 6 : entry->smart[SMART_FLAGS].raw = SMARTCTL_FLAG_OPEN; break; + case 7 : entry->smart[SMART_FLAGS].raw = SMARTCTL_FLAG_FAIL; break; + case 8 : entry->smart[SMART_FLAGS].raw = SMARTCTL_FLAG_PREFAIL; break; + case 9 : entry->smart[SMART_FLAGS].raw = SMARTCTL_FLAG_PREFAIL_LOGGED; break; + case 10 : entry->smart[SMART_FLAGS].raw = SMARTCTL_FLAG_ERROR_LOGGED; break; + case 11 : entry->smart[SMART_FLAGS].raw = SMARTCTL_FLAG_SELFERROR_LOGGED; break; } entry->power = POWER_ACTIVE; diff --git a/cmdline/mingw.c b/cmdline/mingw.c index 6faa1ef6..4c6885ab 100644 --- a/cmdline/mingw.c +++ b/cmdline/mingw.c @@ -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, uint64_t* 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_struct* smart, uint64_t* info, char* serial, char* family, char* model, char* inter) { char conv_buf[CONV_MAX]; WCHAR cmd[MAX_PATH + 128]; @@ -2574,7 +2574,7 @@ retry: * Note that getting error 4 is instead very common, even with full info gathering. */ if ((ret == 0 || ret == 2) - && smart[9] == SMART_UNASSIGNED + && smart[SMART_POWER_ON_HOURS].raw == SMART_UNASSIGNED && info[INFO_SIZE] == SMART_UNASSIGNED && info[INFO_ROTATION_RATE] == SMART_UNASSIGNED ) { @@ -2587,7 +2587,7 @@ retry: } /* store the smartctl return value */ - smart[SMART_FLAGS] = ret; + smart[SMART_FLAGS].raw = ret; return 0; } @@ -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, uint64_t* 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_struct* smart, uint64_t* info, char* serial, char* family, char* model, char* interf) { char conv_buf[CONV_MAX]; WCHAR cmd[MAX_PATH + 128]; @@ -2819,7 +2819,7 @@ retry: *power = POWER_ACTIVE; /* store the return smartctl return value */ - smart[SMART_FLAGS] = WEXITSTATUS(ret); + smart[SMART_FLAGS].raw = WEXITSTATUS(ret); } return 0; diff --git a/cmdline/portable.h b/cmdline/portable.h index 61f593ae..dd572020 100644 --- a/cmdline/portable.h +++ b/cmdline/portable.h @@ -422,6 +422,7 @@ int randomize(void* ptr, size_t size); * Standard SMART attributes. */ #define SMART_REALLOCATED_SECTOR_COUNT 5 +#define SMART_POWER_ON_HOURS 9 #define SMART_UNCORRECTABLE_ERROR_CNT 187 #define SMART_COMMAND_TIMEOUT 188 #define SMART_CURRENT_PENDING_SECTOR 197 @@ -509,6 +510,14 @@ 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. */ @@ -524,7 +533,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. */ - uint64_t smart[SMART_COUNT]; /**< SMART attributes. */ + struct smart_struct 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. */ diff --git a/cmdline/support.c b/cmdline/support.c index ecdb51c9..725803cb 100644 --- a/cmdline/support.c +++ b/cmdline/support.c @@ -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, uint64_t* 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_struct* smart, uint64_t* info, char* serial, char* family, char* model, char* inter) { unsigned i; int inside; - uint64_t dummy_smart[SMART_COUNT]; + struct smart_struct dummy_smart[SMART_COUNT]; uint64_t dummy_info[INFO_COUNT]; char dummy_serial[SMART_MAX]; char dummy_family[SMART_MAX]; @@ -1732,8 +1732,9 @@ int smartctl_attribute(FILE* f, const char* file, const char* name, uint64_t* sm *family = 0; *model = 0; *inter = 0; + memset(smart, 0, sizeof(struct smart_struct) * SMART_COUNT); for (i = 0; i < SMART_COUNT; ++i) - smart[i] = SMART_UNASSIGNED; + smart[i].raw = SMART_UNASSIGNED; for (i = 0; i < INFO_COUNT; ++i) info[i] = SMART_UNASSIGNED; @@ -1743,7 +1744,9 @@ int smartctl_attribute(FILE* f, const char* file, const char* name, uint64_t* sm char buf[256]; unsigned id; uint64_t raw; - uint64_t normalized; + uint64_t norm; + uint64_t worst; + uint64_t thresh; char* s; s = fgets(buf, sizeof(buf), f); @@ -1810,16 +1813,16 @@ int smartctl_attribute(FILE* f, const char* file, const char* name, uint64_t* sm strcpy(inter, "PCIe"); else strcpy(inter, "SCSI"); - } else if (sscanf(s, "Elements in grown defect list: %" SCNu64, &smart[SMART_REALLOCATED_SECTOR_COUNT]) == 1) { - } else if (sscanf(s, "Current Drive Temperature: %" SCNu64, &smart[SMART_TEMPERATURE_CELSIUS]) == 1) { - } else if (sscanf(s, "Drive Trip Temperature: %" SCNu64, &smart[SMART_AIRFLOW_TEMPERATURE_CELSIUS]) == 1) { - } else if (sscanf(s, "Accumulated start-stop cycles: %" SCNu64, &smart[SMART_START_STOP_COUNT]) == 1) { - } else if (sscanf(s, "Accumulated load-unload cycles: %" SCNu64, &smart[SMART_LOAD_CYCLE_COUNT]) == 1) { - } else if (sscanf(s, " number of hours powered up = %" SCNu64, &smart[SMART_POWER_ON_HOURS]) == 1) { /* note "n" of "number" lower case */ + } else if (sscanf(s, "Elements in grown defect list: %" SCNu64, &smart[SMART_REALLOCATED_SECTOR_COUNT].raw) == 1) { + } else if (sscanf(s, "Current Drive Temperature: %" SCNu64, &smart[SMART_TEMPERATURE_CELSIUS].raw) == 1) { + } else if (sscanf(s, "Drive Trip Temperature: %" SCNu64, &smart[SMART_AIRFLOW_TEMPERATURE_CELSIUS].raw) == 1) { + } else if (sscanf(s, "Accumulated start-stop cycles: %" SCNu64, &smart[SMART_START_STOP_COUNT].raw) == 1) { + } else if (sscanf(s, "Accumulated load-unload cycles: %" SCNu64, &smart[SMART_LOAD_CYCLE_COUNT].raw) == 1) { + } else if (sscanf(s, " number of hours powered up = %" SCNu64, &smart[SMART_POWER_ON_HOURS].raw) == 1) { /* note "n" of "number" lower case */ } else if (sscanf(s, "Non-medium error count: %" SCNu64, &raw) == 1) { - smart[SMART_ERROR_PROTOCOL] = raw; + smart[SMART_ERROR_PROTOCOL].raw = raw; } else if (sscanf(s, "Medium error count: %" SCNu64, &raw) == 1) { - smart[SMART_ERROR_MEDIUM] = raw; + smart[SMART_ERROR_MEDIUM].raw = raw; /* ATA */ } else if (smatch(s, "ATA Version is:") == 0) { strcpy(inter, "ATA"); @@ -1830,24 +1833,25 @@ int smartctl_attribute(FILE* f, const char* file, const char* name, uint64_t* sm } else if (smatch(s, "Transport Type: Parallel") == 0) { strcpy(inter, "PATA"); } else if (smatch(s, "No Errors Logged") == 0) { - smart[SMART_ERROR_PROTOCOL] = 0; + smart[SMART_ERROR_PROTOCOL].raw = 0; } else if (sscanf(s, "ATA Error Count: %" SCNu64, &raw) == 1) { - smart[SMART_ERROR_PROTOCOL] = raw; + smart[SMART_ERROR_PROTOCOL].raw = raw; /* NVME */ } else if (smatch(s, "NVMe Version:") == 0) { strcpy(inter, "NVMe"); } else if (sscanf(s, "Media and Data Integrity Errors: %" SCNu64, &raw) == 1) { - smart[SMART_ERROR_MEDIUM] = raw; + smart[SMART_ERROR_MEDIUM].raw = raw; } else if (sscanf(s, "Error Information Log Entries: %" SCNu64, &raw) == 1) { - smart[SMART_ERROR_PROTOCOL] = raw; + smart[SMART_ERROR_PROTOCOL].raw = raw; } else if (sscanf(s, "Percentage Used: %" SCNu64 "%%", &raw) == 1) { /* NVME */ if (raw <= 100) - smart[SMART_WEAR_LEVEL] = raw; + smart[SMART_WEAR_LEVEL].raw = raw; /* Attributes */ } else if (smatch(s, "ID#") == 0) { inside = 1; } else if (inside) { - if (sscanf(s, "%u %*s %*s %" SCNu64 " %*s %*s %*s %*s %*s %" SCNu64, &id, &normalized, &raw) != 3) { + char id_name[128] = { 0 }; + if (sscanf(s, "%u %127s %*s %" SCNu64 " %" SCNu64 " %" SCNu64 " %*s %*s %*s %" SCNu64, &id, id_name, &norm, &worst, &thresh, &raw) != 6) { log_fatal(EEXTERNAL, "Invalid smartctl line '%s'.\n", s); return -1; } @@ -1859,7 +1863,11 @@ int smartctl_attribute(FILE* f, const char* file, const char* name, uint64_t* sm /* LCOV_EXCL_STOP */ } - smart[id] = raw; + smart[id].raw = raw; + smart[id].norm = norm; + smart[id].worst = worst; + smart[id].thresh = thresh; + pathcpy(smart[id].name, sizeof(smart[id].name), id_name); /* * Map normalized health percentage to our unified wear level for SSDs @@ -1867,12 +1875,12 @@ int smartctl_attribute(FILE* f, const char* file, const char* name, uint64_t* sm * 231: SSD_Life_Left (Kingston/WD) * 233: Media_Wearout_Indicator (Intel) */ - if (normalized <= 100) { + if (norm <= 100) { switch (id) { case 177 : case 233 : case 231 : - smart[SMART_WEAR_LEVEL] = 100 - normalized; + smart[SMART_WEAR_LEVEL].raw = 100 - norm; break; } } @@ -1904,9 +1912,9 @@ int smartctl_flush(FILE* f, const char* file, const char* name) int smart_temp(devinfo_t* devinfo) { - uint64_t t = devinfo->smart[SMART_TEMPERATURE_CELSIUS] & 0xFFFF; + uint64_t t = devinfo->smart[SMART_TEMPERATURE_CELSIUS].raw & 0xFFFF; if (t == SMART_UNASSIGNED) - t = devinfo->smart[SMART_AIRFLOW_TEMPERATURE_CELSIUS] & 0xFFFF; + t = devinfo->smart[SMART_AIRFLOW_TEMPERATURE_CELSIUS].raw & 0xFFFF; /* validate temperature */ if (t == SMART_UNASSIGNED) diff --git a/cmdline/support.h b/cmdline/support.h index 679c872a..e2cb5b22 100644 --- a/cmdline/support.h +++ b/cmdline/support.h @@ -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, uint64_t* 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_struct* smart, uint64_t* info, char* serial, char* family, char* model, char* interf); /** * Flush smartctl output from a stream. diff --git a/cmdline/unix.c b/cmdline/unix.c index 51774f79..d1192930 100644 --- a/cmdline/unix.c +++ b/cmdline/unix.c @@ -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, uint64_t* 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_struct* smart, uint64_t* info, char* serial, char* family, char* model, char* interface) { char cmd[PATH_MAX + 64]; char file[PATH_MAX]; @@ -1550,7 +1550,7 @@ static int devsmart(dev_t device, const char* name, const char* smartctl, uint64 } /* store the return smartctl return value */ - smart[SMART_FLAGS] = WEXITSTATUS(ret); + smart[SMART_FLAGS].raw = WEXITSTATUS(ret); return 0; } @@ -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, uint64_t* 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_struct* smart, uint64_t* info, char* serial, char* family, char* model, char* interface) { char cmd[PATH_MAX + 64]; char file[PATH_MAX]; @@ -1795,7 +1795,7 @@ static int devprobe(dev_t device, const char* name, const char* smartctl, int* p *power = POWER_ACTIVE; /* store the return smartctl return value */ - smart[SMART_FLAGS] = WEXITSTATUS(ret); + smart[SMART_FLAGS].raw = WEXITSTATUS(ret); } return 0; diff --git a/doc/snapraid_log.1 b/doc/snapraid_log.1 index bb649ce8..60a5920b 100644 --- a/doc/snapraid_log.1 +++ b/doc/snapraid_log.1 @@ -1794,7 +1794,7 @@ The raw flags value (uint, hexadecimal). .PD .RE .TP -.B attr::[/]::: +.B attr::[/]::::::: Logs the raw value of any assigned SMART attribute. .RS 4 .PD 0 @@ -1802,11 +1802,23 @@ Logs the raw value of any assigned SMART attribute. .I The SMART attribute ID (uint). .HP 4 -.I +.I The raw attribute value (uint, decimal). .HP 4 -.I +.I The raw attribute value (uint, hexadecimal). +.HP 4 +.I +The normalized value (uint). +.HP 4 +.I +The worst value (uint). +.HP 4 +.I +The threshold value (uint). +.HP 4 +.I +Name of the attribute. .PD .RE .TP diff --git a/doc/snapraid_log.d b/doc/snapraid_log.d index 88a5f9ff..cf312e36 100644 --- a/doc/snapraid_log.d +++ b/doc/snapraid_log.d @@ -1121,12 +1121,16 @@ Command Smart And Probe Tags - The raw flags value (uint, decimal). - The raw flags value (uint, hexadecimal). - =attr::[/]::: + =attr::[/]::::::: Logs the raw value of any assigned SMART attribute. - The SMART attribute ID (uint). - - The raw attribute value (uint, decimal). - - The raw attribute value (uint, hexadecimal). + - The raw attribute value (uint, decimal). + - The raw attribute value (uint, hexadecimal). + - The normalized value (uint). + - The worst value (uint). + - The threshold value (uint). + - Name of the attribute. =attr::[/]:power:active Logs that the device was confirmed to be in an active power diff --git a/doc/snapraid_log.txt b/doc/snapraid_log.txt index c56f491e..8119e686 100644 --- a/doc/snapraid_log.txt +++ b/doc/snapraid_log.txt @@ -1167,12 +1167,16 @@ Tags logging specific disk identification and attribute values. - The raw flags value (uint, decimal). - The raw flags value (uint, hexadecimal). - attr::[/]::: + attr::[/]::::::: Logs the raw value of any assigned SMART attribute. - The SMART attribute ID (uint). - - The raw attribute value (uint, decimal). - - The raw attribute value (uint, hexadecimal). + - The raw attribute value (uint, decimal). + - The raw attribute value (uint, hexadecimal). + - The normalized value (uint). + - The worst value (uint). + - The threshold value (uint). + - Name of the attribute. attr::[/]:power:active Logs that the device was confirmed to be in an active power