mirror of
https://github.com/ashaduri/gsmartcontrol.git
synced 2026-09-26 13:55:34 +00:00
Use -l xerror,error and -l xselftest,selftest by default.
Implemented parsing of xerror, xselftest sections.
This commit is contained in:
+1
-4
@@ -23,6 +23,7 @@ TODO:
|
||||
|
||||
Don't rely on smartctl return code (2), parse the output instead.
|
||||
This will allow us to show the Info page.
|
||||
Need usage cases.
|
||||
|
||||
|
||||
Areca detection
|
||||
@@ -69,10 +70,6 @@ Testing:
|
||||
Pre-failure: P, old age: -.
|
||||
Maybe get rid of Type and Updated columns and print only decoded flags?
|
||||
|
||||
use -l xerror,error -l xselftest,selftest by default (the output is similar).
|
||||
Maybe increase default number of entries (50?).
|
||||
Change this text: "Note: Usually only the last five errors are stored."
|
||||
|
||||
Add a tab for -l devstat - it shows interesting statistics.
|
||||
Some of this stuff is better than attributes, maybe show them before attributes.
|
||||
Also needs the warnings and descriptions.
|
||||
|
||||
@@ -645,12 +645,14 @@ bool SmartctlParser::parse_section_data(const std::string& body)
|
||||
} else if (app_pcre_match("/SMART Attributes Data Structure/mi", sub)) {
|
||||
status = parse_section_data_subsection_attributes(sub) || status;
|
||||
|
||||
} else if (app_pcre_match("/SMART Error Log Version/mi", sub)
|
||||
} else if (app_pcre_match("/SMART Error Log Version/mi", sub) // -l error
|
||||
|| app_pcre_match("/SMART Extended Comprehensive Error Log Version/mi", sub) // -l xerror
|
||||
|| app_pcre_match("/Warning: device does not support Error Logging/mi", sub)
|
||||
|| app_pcre_match("/SMART Error Log not supported/mi", sub)) {
|
||||
status = parse_section_data_subsection_error_log(sub) || status;
|
||||
|
||||
} else if (app_pcre_match("/SMART Self-test log/mi", sub)
|
||||
} else if (app_pcre_match("/SMART Self-test log/mi", sub) // -l selftest
|
||||
|| app_pcre_match("/SMART Extended Self-test Log Version/mi", sub) // -l error xselftest
|
||||
|| app_pcre_match("/Warning: device does not support Self Test Logging/mi", sub)
|
||||
|| app_pcre_match("/SMART Self-test Log not supported/mi", sub)) {
|
||||
status = parse_section_data_subsection_selftest_log(sub) || status;
|
||||
@@ -1350,7 +1352,9 @@ bool SmartctlParser::parse_section_data_subsection_error_log(const std::string&
|
||||
|
||||
// Error log version
|
||||
{
|
||||
pcrecpp::RE re = app_pcre_re("/^(SMART Error Log Version):[ \\t]*(.*)$/mi");
|
||||
// SMART Error Log Version: 1
|
||||
// SMART Extended Comprehensive Error Log Version: 1 (1 sectors)
|
||||
pcrecpp::RE re = app_pcre_re("/^(SMART (Extended Comprehensive )?Error Log Version): ([0-9]+).*?$/mi");
|
||||
|
||||
std::string name, value;
|
||||
if (re.PartialMatch(sub, &name, &value)) {
|
||||
@@ -1384,7 +1388,7 @@ bool SmartctlParser::parse_section_data_subsection_error_log(const std::string&
|
||||
}
|
||||
}
|
||||
|
||||
// Error log enty count
|
||||
// Error log entry count
|
||||
{
|
||||
// note: these represent the same information
|
||||
pcrecpp::RE re1 = app_pcre_re("/^ATA Error Count:[ \\t]*([0-9]+)/mi");
|
||||
@@ -1413,14 +1417,17 @@ bool SmartctlParser::parse_section_data_subsection_error_log(const std::string&
|
||||
// individual errors
|
||||
{
|
||||
// split by blocks
|
||||
pcrecpp::RE re_block = app_pcre_re("/^((Error[ \\t]*([0-9]+))[ \\t]*occurred at disk power-on lifetime:[ \\t]*([0-9]+) hours.*(?:\\n(?: |\\n ).*)*)/mi");
|
||||
// "Error 1 [0] occurred at disk power-on lifetime: 1 hours (0 days + 1 hours)"
|
||||
// "Error 25 occurred at disk power-on lifetime: 14799 hours"
|
||||
pcrecpp::RE re_block = app_pcre_re("/^((Error[ \\t]*([0-9]+))[ \\t]*(?:\\[[0-9]+\\][ \\t])?occurred at disk power-on lifetime:[ \\t]*([0-9]+) hours(?:[^\\n]*)?.*(?:\\n(?: |\\n ).*)*)/mi");
|
||||
|
||||
// " When the command that caused the error occurred, the device was active or idle."
|
||||
// Note: For "in an unknown state" - remove first two words.
|
||||
pcrecpp::RE re_state = app_pcre_re("/occurred, the device was[ \\t]*(?: in)?(?: an?)?[ \\t]+([^.\\n]*)\\.?/mi");
|
||||
// " 84 51 2c 71 cd 3f e6 Error: ICRC, ABRT 44 sectors at LBA = 0x063fcd71 = 104844657"
|
||||
// " 40 51 00 f5 41 61 e0 Error: UNC at LBA = 0x006141f5 = 6373877"
|
||||
pcrecpp::RE re_type = app_pcre_re("/[ \\t]+Error:[ \\t]*([ ,a-z]+)[ \\t]+((?:[0-9]+|at )[ \\t]*.*)$/mi");
|
||||
// " 02 -- 51 00 00 00 00 00 00 00 00 00 00 Error: TK0NF"
|
||||
pcrecpp::RE re_type = app_pcre_re("/[ \\t]+Error:[ \\t]*([ ,a-z0-9]+)(?:[ \\t]+((?:[0-9]+|at )[ \\t]*.*))?$/mi");
|
||||
|
||||
std::string block, name, value_num, value_time;
|
||||
pcrecpp::StringPiece input(sub); // position tracker
|
||||
@@ -1504,7 +1511,7 @@ bool SmartctlParser::parse_section_data_subsection_selftest_log(const std::strin
|
||||
// The whole subsection
|
||||
{
|
||||
StorageProperty p(pt);
|
||||
p.set_name("SMART Self-test log", "selftest_log");
|
||||
p.set_name("SMART Self-Test Log", "selftest_log");
|
||||
p.reported_value = sub;
|
||||
p.value_type = StorageProperty::value_type_string;
|
||||
p.value_string = p.reported_value;
|
||||
@@ -1529,13 +1536,15 @@ bool SmartctlParser::parse_section_data_subsection_selftest_log(const std::strin
|
||||
|
||||
// Self-test log version
|
||||
{
|
||||
// newer smartctl (since smartctl 5.1-16)
|
||||
// SMART Self-test log structure revision number 1
|
||||
// SMART Extended Self-test Log Version: 1 (1 sectors)
|
||||
pcrecpp::RE re1 = app_pcre_re("/(SMART Self-test log structure[^\\n0-9]*)([^ \\n]+)[ \\t]*$/mi");
|
||||
// older smartctl
|
||||
pcrecpp::RE re1_ex = app_pcre_re("/(SMART Extended Self-test Log Version: ([0-9]+).*$/mi");
|
||||
// older smartctl (pre 5.1-16)
|
||||
pcrecpp::RE re2 = app_pcre_re("/(SMART Self-test log, version number[^\\n0-9]*)([^ \\n]+)[ \\t]*$/mi");
|
||||
|
||||
std::string name, value;
|
||||
if (re1.PartialMatch(sub, &name, &value) || re2.PartialMatch(sub, &name, &value)) {
|
||||
if (re1.PartialMatch(sub, &name, &value) || re1_ex.PartialMatch(sub, &name, &value) || re2.PartialMatch(sub, &name, &value)) {
|
||||
hz::string_trim(value);
|
||||
|
||||
StorageProperty p(pt);
|
||||
|
||||
@@ -324,10 +324,10 @@ std::string StorageDevice::fetch_data_and_parse(hz::intrusive_ptr<CmdexSync> sma
|
||||
if (this->get_type_argument() == "scsi") { // not sure about correctness... FIXME probably fails with RAID/scsi
|
||||
// This doesn't do much yet, but just in case...
|
||||
// SCSI equivalent of -a --get=all:
|
||||
error_msg = execute_device_smartctl("--health --info --get=all --attributes --log=error --log=selftest", smartctl_ex, output);
|
||||
error_msg = execute_device_smartctl("--health --info --get=all --attributes --log=xerror,50,error --log=xselftest,50,selftest", smartctl_ex, output);
|
||||
} else {
|
||||
// ATA equivalent of -a --get=all:
|
||||
error_msg = execute_device_smartctl("--health --info --get=all --capabilities --attributes --log=error --log=selftest --log=selective",
|
||||
error_msg = execute_device_smartctl("--health --info --get=all --capabilities --attributes --log=xerror,50,error --log=xselftest,50,selftest --log=selective",
|
||||
smartctl_ex, output, true); // set type to invalid if needed
|
||||
}
|
||||
// See notes above (in fetch_basic_data_and_parse()).
|
||||
|
||||
@@ -339,8 +339,8 @@ class StorageProperty {
|
||||
subsection_health, ///< Overall-health (-H, --health)
|
||||
subsection_capabilities, ///< General SMART Values, aka Capabilities (-c, --capabilities)
|
||||
subsection_attributes, ///< Attributes (-A, --attributes). These need decoding.
|
||||
subsection_error_log, ///< Error Log (-l error)
|
||||
subsection_selftest_log, ///< Self-test log (-l selftest)
|
||||
subsection_error_log, ///< Error Log (--log=error)
|
||||
subsection_selftest_log, ///< Self-test log (--log=selftest)
|
||||
subsection_selective_selftest_log ///< Selective self-test log and settings
|
||||
};
|
||||
|
||||
|
||||
@@ -849,7 +849,7 @@ void GscInfoWindow::fill_ui_with_info(bool scan, bool clear_ui, bool clear_tests
|
||||
} else if (iter->value_type != StorageProperty::value_type_error_block) {
|
||||
label_strings.push_back(PropertyLabel(iter->readable_name + ": " + iter->format_value(), &(*iter)));
|
||||
if (iter->generic_name == "error_count")
|
||||
label_strings.back().label += " (Note: Usually only the last five errors are stored.)";
|
||||
label_strings.back().label += " (Note: The number of entries may be limited to the newest ones)";
|
||||
|
||||
} else {
|
||||
std::string type_details = iter->value_error_block.type_more_info;
|
||||
|
||||
@@ -197,6 +197,7 @@
|
||||
<object class="GtkBox" id="attributes_label_vbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">3</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
@@ -380,6 +381,7 @@
|
||||
<object class="GtkBox" id="error_log_label_vbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="spacing">3</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
@@ -938,8 +940,8 @@ Selective self-test log is also presented here.</property>
|
||||
<property name="receives_default">True</property>
|
||||
<property name="tooltip_text" translatable="yes">Re-read all the information</property>
|
||||
<property name="use_stock">True</property>
|
||||
<accelerator key="R" signal="clicked" modifiers="GDK_CONTROL_MASK"/>
|
||||
<accelerator key="F5" signal="clicked"/>
|
||||
<accelerator key="R" signal="clicked" modifiers="GDK_CONTROL_MASK"/>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
|
||||
Reference in New Issue
Block a user