diff --git a/cmdline/device.c b/cmdline/device.c index b1aa8438..59564ac9 100644 --- a/cmdline/device.c +++ b/cmdline/device.c @@ -414,6 +414,10 @@ static double smart_afr(uint64_t* smart, const char* model) uint64_t mask32 = 0xffffffffU; uint64_t mask16 = 0xffffU; + /* do not estimate for not rotational */ + if (smart[INFO_ROTATION_RATE] == 0) + return 0; + if (smart[5] != SMART_UNASSIGNED) { double r = smart_afr_value(SMART_5_R, SMART_5_STEP, smart[5] & mask32); if (afr < r) @@ -555,6 +559,10 @@ static void state_smart_log(devinfo_t* devinfo, double 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]); + + int temp = smart_temp(devinfo); + if (temp >= 0) + log_tag("attr:%s:%s:temperature:%d\n", devinfo->file, devinfo->name, temp); } static void state_smart(struct snapraid_state* state, unsigned n, tommy_list* low) @@ -568,7 +576,6 @@ static void state_smart(struct snapraid_state* state, unsigned n, tommy_list* lo double p_at_least_one_failure; int make_it_fail = 0; uint64_t mask32 = 0xffffffffU; - uint64_t mask16 = 0xffffU; /* compute lengths for padding */ device_pad = 0; @@ -624,10 +631,9 @@ static void state_smart(struct snapraid_state* state, unsigned n, tommy_list* lo devinfo->smart[devinfo->smartignore[j]] = SMART_UNASSIGNED; } - if (devinfo->smart[SMART_TEMPERATURE_CELSIUS] != SMART_UNASSIGNED) - printf("%7" PRIu64, devinfo->smart[SMART_TEMPERATURE_CELSIUS] & mask16); - else if (devinfo->smart[SMART_AIRFLOW_TEMPERATURE_CELSIUS] != SMART_UNASSIGNED) - printf("%7" PRIu64, devinfo->smart[SMART_AIRFLOW_TEMPERATURE_CELSIUS] & mask16); + int temp = smart_temp(devinfo); + if (temp >= 0) + printf("%7d", temp); else printf(" -"); @@ -781,7 +787,7 @@ bail: } } -static void state_up(struct snapraid_state* state, tommy_list* low) +void state_attr(struct snapraid_state* state, tommy_list* low) { tommy_node* i; @@ -1057,7 +1063,7 @@ void state_device(struct snapraid_state* state, int operation, tommy_list* filte state_probe(state, &low); if (operation == DEVICE_UP) - state_up(state, &low); + state_attr(state, &low); } tommy_list_foreach(&high, free); diff --git a/cmdline/state.h b/cmdline/state.h index c0cc8c4d..6f2f489a 100644 --- a/cmdline/state.h +++ b/cmdline/state.h @@ -411,6 +411,11 @@ int state_thermal_begin(struct snapraid_state* state, time_t now); */ void state_load_ignore_file(tommy_list* filter_list, const char* path, const char* sub); +/** + * Report attributes into the log + */ +void state_attr(struct snapraid_state* state, tommy_list* low); + /****************************************************************************/ /* misc */ diff --git a/cmdline/support.c b/cmdline/support.c index ca2dcbb6..ecdb51c9 100644 --- a/cmdline/support.c +++ b/cmdline/support.c @@ -1902,6 +1902,23 @@ int smartctl_flush(FILE* f, const char* file, const char* name) return 0; } +int smart_temp(devinfo_t* devinfo) +{ + uint64_t t = devinfo->smart[SMART_TEMPERATURE_CELSIUS] & 0xFFFF; + if (t == SMART_UNASSIGNED) + t = devinfo->smart[SMART_AIRFLOW_TEMPERATURE_CELSIUS] & 0xFFFF; + + /* validate temperature */ + if (t == SMART_UNASSIGNED) + return -1; + if (t == 0) + return -1; + if (t > 100) + return -1; + + return t; +} + /****************************************************************************/ /* thread */ diff --git a/cmdline/support.h b/cmdline/support.h index 7c481407..679c872a 100644 --- a/cmdline/support.h +++ b/cmdline/support.h @@ -460,6 +460,12 @@ int smartctl_attribute(FILE* f, const char* file, const char* name, uint64_t* sm */ int smartctl_flush(FILE* f, const char* file, const char* name); +/** + * Extract the temperature from the SMART info. + * Return -1 if missing + */ +int smart_temp(devinfo_t* devinfo); + /****************************************************************************/ /* thread */ diff --git a/cmdline/thermal.c b/cmdline/thermal.c index 68339cb0..a5fb6b53 100644 --- a/cmdline/thermal.c +++ b/cmdline/thermal.c @@ -122,23 +122,6 @@ struct snapraid_thermal_params fit_thermal_model(const struct snapraid_thermal_p return model; } -static int smart_temp(devinfo_t* devinfo) -{ - uint64_t t = devinfo->smart[SMART_TEMPERATURE_CELSIUS] & 0xFFFFFFFF; - if (t == SMART_UNASSIGNED) - t = devinfo->smart[SMART_AIRFLOW_TEMPERATURE_CELSIUS] & 0xFFFFFFFF; - - /* validate temperature */ - if (t == SMART_UNASSIGNED) - return -1; - if (t == 0) - return -1; - if (t > 100) - return -1; - - return t; -} - void state_thermal(struct snapraid_state* state, time_t now) { tommy_node* i; @@ -206,6 +189,9 @@ void state_thermal(struct snapraid_state* state, time_t now) if (tommy_list_empty(&low)) return; + /* report new attribute */ + state_attr(state, &low); + /* if ambient temperature is not set, set it now with the lowest HD temperature */ if (state->thermal_ambient_temperature == 0) { state->thermal_ambient_temperature = ambient_temperature();