From 33028f81d9c2de022aa29d5708beb2070acbeec1 Mon Sep 17 00:00:00 2001 From: Alexander Shaduri Date: Mon, 4 Sep 2017 13:43:40 +0000 Subject: [PATCH] Fixed a few parser issues. SCT temperature overrides all others now. --- gsmartcontrol/TODO | 9 +++- gsmartcontrol/src/applib/smartctl_parser.cpp | 25 ++++++++--- .../src/applib/smartctl_parser_test.cpp | 4 +- gsmartcontrol/src/gsc_info_window.cpp | 45 ++++++++++--------- 4 files changed, 55 insertions(+), 28 deletions(-) diff --git a/gsmartcontrol/TODO b/gsmartcontrol/TODO index 14eb73b..715a1cc 100644 --- a/gsmartcontrol/TODO +++ b/gsmartcontrol/TODO @@ -42,15 +42,22 @@ Testing: -Devstat warnings (identify by offset/page). +Devstat warnings. Per-line selftest error highlighting. Tab highlighting according to error severity. +Increase tab sizes in Windows. + +Check why temperature is not SCT by default. + +add .txt to saved output files. + Document RAID support. + Check it first (in code). ??RAID: http://sourceforge.net/apps/trac/smartmontools/wiki/Supported_RAID-Controllers diff --git a/gsmartcontrol/src/applib/smartctl_parser.cpp b/gsmartcontrol/src/applib/smartctl_parser.cpp index 26cf13a..8ba0f72 100644 --- a/gsmartcontrol/src/applib/smartctl_parser.cpp +++ b/gsmartcontrol/src/applib/smartctl_parser.cpp @@ -140,22 +140,25 @@ bool SmartctlParser::parse_full(const std::string& full, StorageAttribute::DiskT // If the device doesn't support many things, the warnings aren't separated (for sections). - // Fix that. + // Fix that. This affects old smartctl only (at least 6.5 fixed the warnings). { pcrecpp::RE re1 = app_pcre_re("/^(Warning: device does not support Error Logging)$/mi"); pcrecpp::RE re2 = app_pcre_re("/^(Warning: device does not support Self Test Logging)$/mi"); pcrecpp::RE re3 = app_pcre_re("/^(Device does not support Selective Self Tests\\/Logging)$/mi"); + pcrecpp::RE re4 = app_pcre_re("/^(Warning: device does not support SCT Commands)$/mi"); std::string match; if (app_pcre_match(re1, s, &match)) - app_pcre_replace(re1, "\n" + match, s); // add an extra newline + app_pcre_replace(re1, "\n" + match + "\n", s); // add extra newlines if (app_pcre_match(re2, s, &match)) - app_pcre_replace(re2, "\n" + match, s); // add an extra newline + app_pcre_replace(re2, "\n" + match + "\n", s); // add extra newlines if (app_pcre_match(re3, s, &match)) - app_pcre_replace(re3, "\n" + match, s); // add an extra newline + app_pcre_replace(re3, "\n" + match + "\n", s); // add extra newlines + if (app_pcre_match(re4, s, &match)) + app_pcre_replace(re4, "\n" + match + "\n", s); // add extra newlines } @@ -439,6 +442,11 @@ bool SmartctlParser::parse_section_info_property(StorageProperty& p) p.value_type = StorageProperty::value_type_string; p.value_string = p.reported_value; + } else if (app_pcre_match("/^Compliance$/mi", p.reported_name)) { // From scsi/usb + p.set_name(p.reported_name, "device_type", "Compliance"); + p.value_type = StorageProperty::value_type_string; + p.value_string = p.reported_value; + } else if (app_pcre_match("/^Serial Number$/mi", p.reported_name)) { p.set_name(p.reported_name, "serial_number", "Serial Number"); p.value_type = StorageProperty::value_type_string; @@ -711,7 +719,8 @@ bool SmartctlParser::parse_section_data(const std::string& body) // "SCT Commands not supported" // "SCT Commands not supported if ATA Security is LOCKED" || app_pcre_match("/SCT Commands not supported/mi", sub) - || app_pcre_match("/SCT Data Table command not supported/mi", sub) ) { + || app_pcre_match("/SCT Data Table command not supported/mi", sub) + || app_pcre_match("/Warning: device does not support SCT Commands/mi", sub) ) { // old smartctl status = parse_section_data_subsection_scttemp_log(sub) || status; } else if (app_pcre_match("/^SCT Error Recovery Control/mi", sub) @@ -2079,6 +2088,7 @@ Page Offset Size Value Flags Description */ // supported / unsupported + bool supported = true; { StorageProperty p(pt); p.set_name("Device statistics supported", "devstat_supported"); @@ -2086,10 +2096,15 @@ Page Offset Size Value Flags Description // p.reported_value; // nothing p.value_type = StorageProperty::value_type_bool; p.value_bool = !app_pcre_match("/Device Statistics \\(GP\\/SMART Log 0x04\\) not supported/mi", sub); + supported = p.value_bool; add_property(p); } + if (!supported) { + return false; + } + bool entries_found = false; // at least one entry was found // split to lines diff --git a/gsmartcontrol/src/applib/smartctl_parser_test.cpp b/gsmartcontrol/src/applib/smartctl_parser_test.cpp index d7dc560..3d834f2 100644 --- a/gsmartcontrol/src/applib/smartctl_parser_test.cpp +++ b/gsmartcontrol/src/applib/smartctl_parser_test.cpp @@ -18,7 +18,7 @@ #include #include -#include "hz/debug.h" +#include "libdebug/libdebug.h" #include "hz/fs_file.h" #include "storage_property.h" #include "smartctl_parser.h" @@ -33,6 +33,8 @@ int main(int argc, char** argv) return EXIT_FAILURE; } + debug_register_domain("app"); + std::string file_str = argv[1]; hz::File file(file_str); diff --git a/gsmartcontrol/src/gsc_info_window.cpp b/gsmartcontrol/src/gsc_info_window.cpp index 51b8b7c..525863d 100644 --- a/gsmartcontrol/src/gsc_info_window.cpp +++ b/gsmartcontrol/src/gsc_info_window.cpp @@ -643,7 +643,7 @@ void GscInfoWindow::fill_ui_with_info(bool scan, bool clear_ui, bool clear_tests Gtk::TreeModelColumn col_flag_value; model_columns.add(col_flag_value); num_tree_cols = app_gtkmm_create_tree_view_column(col_flag_value, *treeview, - "Flag", "Flag value\n\n" + "Flags", "Flags\n\n" "If given in POSRCK+ format, the presence of each letter indicates that the flag is on.\n" "P: pre-failure attribute (if the attribute failed, the drive is failing)\n" "O: updated continuously (as opposed to updated on offline data collection)\n" @@ -1191,30 +1191,33 @@ void GscInfoWindow::fill_ui_with_info(bool scan, bool clear_ui, bool clear_tests StorageProperty::warning_t max_tab_warning = StorageProperty::warning_none; label_list_t label_strings; // outside-of-tree properties + std::string temperature; - bool temp_found = false; StorageProperty temp_property; + enum { temp_attr2 = 1, temp_attr1, temp_stat, temp_sct }; // less important to more important + int temp_prop_source = 0; for (prop_iterator iter = props.begin(); iter != props.end(); ++iter) { // Find temperature - if (!temp_found) { - if (iter->generic_name == "sct_temperature_celsius") { - temperature = hz::number_to_string(iter->value_integer); - temp_property = *iter; - temp_found = true; - } else if (iter->generic_name == "stat_temperature_celsius") { - temperature = hz::number_to_string(iter->value_statistic.value_int); - temp_property = *iter; - temp_found = true; - } else if (iter->generic_name == "attr_temperature_celsius") { - temperature = hz::number_to_string(iter->value_attribute.raw_value_int); - temp_property = *iter; - temp_found = true; - } else if (iter->generic_name == "attr_temperature_celsius_x10") { - temperature = hz::number_to_string(iter->value_attribute.raw_value_int / 10); - temp_property = *iter; - temp_found = true; - } + if (temp_prop_source < temp_sct && iter->generic_name == "sct_temperature_celsius") { + temperature = hz::number_to_string(iter->value_integer); + temp_property = *iter; + temp_prop_source = temp_sct; + } + if (temp_prop_source < temp_stat && iter->generic_name == "stat_temperature_celsius") { + temperature = hz::number_to_string(iter->value_statistic.value_int); + temp_property = *iter; + temp_prop_source = temp_stat; + } + if (temp_prop_source < temp_attr1 && iter->generic_name == "attr_temperature_celsius") { + temperature = hz::number_to_string(iter->value_attribute.raw_value_int); + temp_property = *iter; + temp_prop_source = temp_attr1; + } + if (temp_prop_source < temp_attr2 && iter->generic_name == "attr_temperature_celsius_x10") { + temperature = hz::number_to_string(iter->value_attribute.raw_value_int / 10); + temp_property = *iter; + temp_prop_source = temp_attr2; } if (iter->section != StorageProperty::section_data || iter->subsection != StorageProperty::subsection_temperature_log) @@ -1287,7 +1290,7 @@ void GscInfoWindow::fill_ui_with_info(bool scan, bool clear_ui, bool clear_tests Gtk::TreeModelColumn col_flag_value; model_columns.add(col_flag_value); - num_tree_cols = app_gtkmm_create_tree_view_column(col_flag_value, *treeview, "Flag", "Flag value", false); + num_tree_cols = app_gtkmm_create_tree_view_column(col_flag_value, *treeview, "Flags", "Flags", false); Gtk::TreeModelColumn col_str_values; model_columns.add(col_str_values);