From 876e29973cafb8435e8deee2fe063b936cf55ff3 Mon Sep 17 00:00:00 2001 From: Alexander Shaduri Date: Mon, 15 Apr 2024 16:29:51 +0400 Subject: [PATCH] Simplified AtaStorageProperty by mergin Section and SubSection. --- src/applib/ata_storage_property.cpp | 73 +++++------ src/applib/ata_storage_property.h | 33 ++--- src/applib/ata_storage_property_descr.cpp | 133 +++++++++++---------- src/applib/selftest.cpp | 3 +- src/applib/smartctl_json_ata_parser.cpp | 3 +- src/applib/smartctl_text_ata_parser.cpp | 47 +++----- src/applib/smartctl_version_parser.h | 1 - src/applib/storage_device.cpp | 2 +- src/applib/storage_property_repository.cpp | 6 +- src/applib/storage_property_repository.h | 6 +- src/gsc_info_window.cpp | 39 +++--- 11 files changed, 156 insertions(+), 190 deletions(-) diff --git a/src/applib/ata_storage_property.cpp b/src/applib/ata_storage_property.cpp index de0f1cbe..a7909fd1 100644 --- a/src/applib/ata_storage_property.cpp +++ b/src/applib/ata_storage_property.cpp @@ -10,17 +10,19 @@ License: GNU General Public License v3.0 only /// @{ #include "local_glibmm.h" +#include #include #include // not iosfwd - it doesn't work #include -#include #include +#include +#include + #include "hz/string_num.h" // number_to_string #include "hz/stream_cast.h" // stream_cast<> #include "hz/format_unit.h" // format_time_length #include "hz/string_algo.h" // string_join -#include "hz/string_num.h" // number_to_string #include "ata_storage_property.h" @@ -39,7 +41,7 @@ std::ostream& operator<< (std::ostream& os, const AtaStorageCapability& p) -std::string AtaStorageAttribute::get_attr_type_name(AtaStorageAttribute::AttributeType type) +std::string AtaStorageAttribute::get_readable_attribute_type_name(AttributeType type) { static const std::unordered_map m { {AttributeType::Unknown, "[unknown]"}, @@ -54,7 +56,7 @@ std::string AtaStorageAttribute::get_attr_type_name(AtaStorageAttribute::Attribu -std::string AtaStorageAttribute::get_update_type_name(AtaStorageAttribute::UpdateType type) +std::string AtaStorageAttribute::get_readable_update_type_name(UpdateType type) { static const std::unordered_map m { {UpdateType::Unknown, "[unknown]"}, @@ -69,7 +71,7 @@ std::string AtaStorageAttribute::get_update_type_name(AtaStorageAttribute::Updat -std::string AtaStorageAttribute::get_fail_time_name(AtaStorageAttribute::FailTime type) +std::string AtaStorageAttribute::get_readable_fail_time_name(FailTime type) { static const std::unordered_map m { {FailTime::Unknown, "[unknown]"}, @@ -152,7 +154,7 @@ std::ostream& operator<<(std::ostream& os, const AtaStorageStatistic& p) -std::string AtaStorageErrorBlock::get_displayable_error_types(const std::vector& types) +std::string AtaStorageErrorBlock::format_readable_error_types(const std::vector& types) { static const std::map m = { {"ABRT", _("Command aborted")}, @@ -176,9 +178,9 @@ std::string AtaStorageErrorBlock::get_displayable_error_types(const std::vector< if (m.find(type) != m.end()) { sv.push_back(m.at(type)); } else { - std::string name = _("Uknown type"); + std::string name = _("Unknown type"); if (!type.empty()) { - name = Glib::ustring::compose(_("Uknown type: %1"), type); + name = Glib::ustring::compose(_("Unknown type: %1"), type); } sv.push_back(name); } @@ -235,13 +237,13 @@ std::ostream& operator<< (std::ostream& os, const AtaStorageErrorBlock& b) { os << "Error number " << b.error_num << ": " << hz::string_join(b.reported_types, ", ") - << " [" << AtaStorageErrorBlock::get_displayable_error_types(b.reported_types) << "]"; + << " [" << AtaStorageErrorBlock::format_readable_error_types(b.reported_types) << "]"; return os; } -std::string AtaStorageSelftestEntry::get_status_displayable_name(AtaStorageSelftestEntry::Status s) +std::string AtaStorageSelftestEntry::get_readable_status_name(Status s) { static const std::unordered_map m { {Status::Unknown, "[unknown]"}, @@ -289,9 +291,9 @@ AtaStorageSelftestEntry::StatusSeverity AtaStorageSelftestEntry::get_status_seve -std::string AtaStorageSelftestEntry::get_status_str() const +std::string AtaStorageSelftestEntry::get_readable_status() const { - return (status == Status::Unknown ? status_str : get_status_displayable_name(status)); + return (status == Status::Unknown ? status_str : get_readable_status_name(status)); } @@ -314,18 +316,28 @@ std::string AtaStorageSelftestEntry::format_lifetime_hours() const std::ostream& operator<< (std::ostream& os, const AtaStorageSelftestEntry& b) { os << "Test entry " << b.test_num << ": " - << b.type << ", status: " << b.get_status_str() << ", remaining: " << int(b.remaining_percent); + << b.type << ", status: " << b.get_readable_status() << ", remaining: " << int(b.remaining_percent); return os; } -std::string AtaStorageProperty::get_section_name(AtaStorageProperty::Section s) +std::string AtaStorageProperty::get_readable_section_name(Section s) { static const std::unordered_map m { {Section::Unknown, "unknown"}, {Section::Info, "info"}, - {Section::Data, "data"}, + {Section::Health, "health"}, + {Section::Capabilities, "capabilities"}, + {Section::Attributes, "attributes"}, + {Section::Devstat, "devstat"}, + {Section::ErrorLog, "error_log"}, + {Section::SelftestLog, "selftest_log"}, + {Section::SelectiveSelftestLog, "selective_selftest_log"}, + {Section::TemperatureLog, "temperature_log"}, + {Section::ErcLog, "erc_log"}, + {Section::PhyLog, "phy_log"}, + {Section::DirectoryLog, "directory_log"}, {Section::Internal, "internal"}, }; if (auto iter = m.find(s); iter != m.end()) { @@ -336,31 +348,7 @@ std::string AtaStorageProperty::get_section_name(AtaStorageProperty::Section s) -std::string AtaStorageProperty::get_subsection_name(AtaStorageProperty::SubSection s) -{ - static const std::unordered_map m { - {SubSection::Unknown, "unknown"}, - {SubSection::Health, "health"}, - {SubSection::Capabilities, "capabilities"}, - {SubSection::Attributes, "attributes"}, - {SubSection::Devstat, "devstat"}, - {SubSection::ErrorLog, "error_log"}, - {SubSection::SelftestLog, "selftest_log"}, - {SubSection::SelectiveSelftestLog, "selective_selftest_log"}, - {SubSection::TemperatureLog, "temperature_log"}, - {SubSection::ErcLog, "erc_log"}, - {SubSection::PhyLog, "phy_log"}, - {SubSection::DirectoryLog, "directory_log"}, - }; - if (auto iter = m.find(s); iter != m.end()) { - return iter->second; - } - return "[internal_error]"; -} - - - -std::string AtaStorageProperty::get_value_type_name() const +std::string AtaStorageProperty::get_storable_value_type_name() const { if (std::holds_alternative(value)) return "empty"; @@ -398,11 +386,10 @@ void AtaStorageProperty::dump(std::ostream& os, std::size_t internal_offset) con { const std::string offset(internal_offset, ' '); - os << offset << "[" << get_section_name(section) - << (section == Section::Data ? (", " + get_subsection_name(subsection)) : "") << "]" + os << offset << "[" << get_readable_section_name(section) << "]" << " " << generic_name // << (generic_name == reported_name ? "" : (" (" + reported_name + ")")) - << ": [" << get_value_type_name() << "] "; + << ": [" << get_storable_value_type_name() << "] "; // if (!readable_value.empty()) // os << readable_value; diff --git a/src/applib/ata_storage_property.h b/src/applib/ata_storage_property.h index 1d3e678a..0bc4922e 100644 --- a/src/applib/ata_storage_property.h +++ b/src/applib/ata_storage_property.h @@ -12,6 +12,7 @@ License: GNU General Public License v3.0 only #ifndef ATA_STORAGE_PROPERTY_H #define ATA_STORAGE_PROPERTY_H +#include // std::size_t #include #include #include @@ -19,7 +20,6 @@ License: GNU General Public License v3.0 only #include #include #include -#include #include "warning_level.h" @@ -62,7 +62,7 @@ class AtaStorageAttribute { }; /// Get readable attribute type name - [[nodiscard]] static std::string get_attr_type_name(AttributeType type); + [[nodiscard]] static std::string get_readable_attribute_type_name(AttributeType type); /// Attribute when-updated type @@ -73,7 +73,7 @@ class AtaStorageAttribute { }; /// Get readable when-updated type name - [[nodiscard]] static std::string get_update_type_name(UpdateType type); + [[nodiscard]] static std::string get_readable_update_type_name(UpdateType type); /// Attribute when-failed type @@ -85,7 +85,7 @@ class AtaStorageAttribute { }; /// Get a readable when-failed type name - [[nodiscard]] static std::string get_fail_time_name(FailTime type); + [[nodiscard]] static std::string get_readable_fail_time_name(FailTime type); /// Format raw value with commas (if it's a number) @@ -141,7 +141,7 @@ class AtaStorageErrorBlock { public: /// Get readable error types from reported types - [[nodiscard]] static std::string get_displayable_error_types(const std::vector& types); + [[nodiscard]] static std::string format_readable_error_types(const std::vector& types); /// Get warning level (Warning) for an error type [[nodiscard]] static WarningLevel get_warning_level_for_error_type(const std::string& type); @@ -192,14 +192,14 @@ class AtaStorageSelftestEntry { }; /// Get log entry status displayable name - [[nodiscard]] static std::string get_status_displayable_name(Status s); + [[nodiscard]] static std::string get_readable_status_name(Status s); /// Get severity of error status [[nodiscard]] static StatusSeverity get_status_severity(Status s); /// Get error status as a string - [[nodiscard]] std::string get_status_str() const; + [[nodiscard]] std::string get_readable_status() const; /// Format lifetime hours with comma @@ -230,17 +230,6 @@ class AtaStorageProperty { enum class Section { Unknown, ///< Used when searching in all sections Info, ///< Short info (--info) - Data, ///< SMART DATA - Internal ///< Internal application-specific data - }; - - /// Get displayable section type name - [[nodiscard]] static std::string get_section_name(Section s); - - - /// Subsections in smart data section - enum class SubSection { - Unknown, ///< Used when searching in all subsections Health, ///< Overall-health (-H, --health) Capabilities, ///< General SMART Values, aka Capabilities (-c, --capabilities) Attributes, ///< Attributes (-A, --attributes). These need decoding. @@ -252,14 +241,15 @@ class AtaStorageProperty { ErcLog, ///< SCT Error Recovery Control settings (--log=scterc) PhyLog, ///< Phy log (--log=sataphy) DirectoryLog, ///< Directory log (--log=directory) + Internal ///< Internal application-specific data }; - /// Get displayable subsection type name - [[nodiscard]] static std::string get_subsection_name(SubSection s); + /// Get displayable section type name + [[nodiscard]] static std::string get_readable_section_name(Section s); /// Get displayable value type name - [[nodiscard]] std::string get_value_type_name() const; + [[nodiscard]] std::string get_storable_value_type_name() const; /// Check if this is an empty object with no value set. @@ -303,7 +293,6 @@ class AtaStorageProperty { std::string description; ///< Property description (for tooltips, etc...). May contain markup. Section section = Section::Unknown; ///< Section this property belongs to - SubSection subsection = SubSection::Unknown; ///< Subsection this property belongs to std::string reported_value; ///< String representation of the value as reported std::string readable_value; ///< User-friendly readable representation of value. if empty, use the other members. diff --git a/src/applib/ata_storage_property_descr.cpp b/src/applib/ata_storage_property_descr.cpp index 55070279..44af7967 100644 --- a/src/applib/ata_storage_property_descr.cpp +++ b/src/applib/ata_storage_property_descr.cpp @@ -1571,37 +1571,37 @@ bool ata_storage_property_autoset_description(AtaStorageProperty& p, AtaStorageA found = true; // Section Info - } else if (p.section == AtaStorageProperty::Section::Info) { - found = auto_set(p, "model_family", "Model family (from smartctl database)") - || auto_set(p, "model_name", "Device model") - || auto_set(p, "serial_number", "Serial number, unique to each physical drive") - || auto_set(p, "user_capacity/bytes", "User-serviceable drive capacity as reported to an operating system") - || auto_set(p, "in_smartctl_database", "Whether the device is in smartctl database or not. " - "If it is, additional information may be provided; otherwise, Raw values of some attributes may be incorrectly formatted.") - || auto_set(p, "_custom/smart_supported", "Whether the device supports SMART. If not, then only very limited information will be available.") - || auto_set(p, "_custom/smart_enabled", "Whether the device has SMART enabled. If not, most of the reported values will be incorrect.") - || auto_set(p, "ata_aam/enabled", "Automatic Acoustic Management (AAM) feature") - || auto_set(p, "ata_aam/level", "Automatic Acoustic Management (AAM) level") - || auto_set(p, "ata_apm/enabled", "Automatic Power Management (APM) feature") - || auto_set(p, "ata_apm/level", "Advanced Power Management (APM) level") - || auto_set(p, "ata_dsn/enabled", "Device Statistics Notification (DSN) feature") - || auto_set(p, "power_mode", "Power mode at the time of query"); - - // set just its name as a tooltip - if (!found) { - p.set_description(p.displayable_name); - found = true; - } - - } else if (p.section == AtaStorageProperty::Section::Data) { + } else { + switch (p.section) { + case AtaStorageProperty::Section::Info: + found = auto_set(p, "model_family", "Model family (from smartctl database)") + || auto_set(p, "model_name", "Device model") + || auto_set(p, "serial_number", "Serial number, unique to each physical drive") + || auto_set(p, "user_capacity/bytes", "User-serviceable drive capacity as reported to an operating system") + || auto_set(p, "in_smartctl_database", "Whether the device is in smartctl database or not. " + "If it is, additional information may be provided; otherwise, Raw values of some attributes may be incorrectly formatted.") + || auto_set(p, "_custom/smart_supported", "Whether the device supports SMART. If not, then only very limited information will be available.") + || auto_set(p, "_custom/smart_enabled", "Whether the device has SMART enabled. If not, most of the reported values will be incorrect.") + || auto_set(p, "ata_aam/enabled", "Automatic Acoustic Management (AAM) feature") + || auto_set(p, "ata_aam/level", "Automatic Acoustic Management (AAM) level") + || auto_set(p, "ata_apm/enabled", "Automatic Power Management (APM) feature") + || auto_set(p, "ata_apm/level", "Advanced Power Management (APM) level") + || auto_set(p, "ata_dsn/enabled", "Device Statistics Notification (DSN) feature") + || auto_set(p, "power_mode", "Power mode at the time of query"); + + // set just its name as a tooltip + if (!found) { + p.set_description(p.displayable_name); + found = true; + } + break; - switch (p.subsection) { - case AtaStorageProperty::SubSection::Health: + case AtaStorageProperty::Section::Health: found = auto_set(p, "smart_status/passed", "Overall health self-assessment test result. Note: If the drive passes this test, it doesn't mean it's OK. " "However, if the drive doesn't pass it, then it's either already dead, or it's predicting its own failure within the next 24 hours. In this case do a backup immediately!"); break; - case AtaStorageProperty::SubSection::Capabilities: + case AtaStorageProperty::Section::Capabilities: found = auto_set(p, "ata_smart_data/offline_data_collection/status/_group", "Offline Data Collection (a.k.a. Offline test) is usually automatically performed when the device is idle or every fixed amount of time. " "This should show if Automatic Offline Data Collection is enabled.") || auto_set(p, "ata_smart_data/offline_data_collection/completion_seconds", "Offline Data Collection (a.k.a. Offline test) is usually automatically performed when the device is idle or every fixed amount of time. " @@ -1617,7 +1617,7 @@ bool ata_storage_property_autoset_description(AtaStorageProperty& p, AtaStorageA || auto_set(p, "ata_sct_capabilities/_group", "Drive properties related to temperature information."); break; - case AtaStorageProperty::SubSection::Attributes: + case AtaStorageProperty::Section::Attributes: found = auto_set(p, "ata_smart_attributes/revision", p.displayable_name.c_str()); if (!found) { auto_set_attr(p, disk_type); @@ -1625,41 +1625,43 @@ bool ata_storage_property_autoset_description(AtaStorageProperty& p, AtaStorageA } break; - case AtaStorageProperty::SubSection::Devstat: + case AtaStorageProperty::Section::Devstat: found = auto_set_statistic(p); break; - case AtaStorageProperty::SubSection::ErrorLog: + case AtaStorageProperty::Section::ErrorLog: found = auto_set(p, "ata_smart_error_log/extended/revision", p.displayable_name.c_str()) || auto_set(p, "ata_smart_error_log/extended/count", "Number of errors in error log. Note: Some manufacturers may list completely harmless errors in this log " "(e.g., command invalid, not implemented, etc...)."); // || auto_set(p, "error_log_unsupported", "This device does not support error logging."); // the property text already says that if (p.is_value_type()) { for (size_t i = 0; i < p.get_value().reported_types.size(); ++i) { - p.set_description(AtaStorageErrorBlock::get_displayable_error_types(p.get_value().reported_types)); + p.set_description(AtaStorageErrorBlock::format_readable_error_types( + p.get_value().reported_types)); found = true; } } break; - case AtaStorageProperty::SubSection::SelftestLog: + case AtaStorageProperty::Section::SelftestLog: found = auto_set(p, "ata_smart_self_test_log/extended/revision", p.displayable_name.c_str()) || auto_set(p, "ata_smart_self_test_log/extended/table/count", "Number of tests in selftest log. Note: The number of entries may be limited to the newest manual tests."); // || auto_set(p, "ata_smart_self_test_log/_present", "This device does not support self-test logging."); // the property text already says that break; - case AtaStorageProperty::SubSection::SelectiveSelftestLog: + case AtaStorageProperty::Section::SelectiveSelftestLog: // nothing here break; - case AtaStorageProperty::SubSection::TemperatureLog: + case AtaStorageProperty::Section::TemperatureLog: found = auto_set(p, "ata_sct_status/_not_present", "SCT support is needed for SCT temperature logging."); break; - case AtaStorageProperty::SubSection::ErcLog: - case AtaStorageProperty::SubSection::PhyLog: - case AtaStorageProperty::SubSection::DirectoryLog: - case AtaStorageProperty::SubSection::Unknown: + case AtaStorageProperty::Section::ErcLog: + case AtaStorageProperty::Section::PhyLog: + case AtaStorageProperty::Section::DirectoryLog: + case AtaStorageProperty::Section::Unknown: + case AtaStorageProperty::Section::Internal: // nothing break; } @@ -1683,36 +1685,36 @@ WarningLevel ata_storage_property_autoset_warning(AtaStorageProperty& p) // Section Info - } else if (p.section == AtaStorageProperty::Section::Info) { - if (name_match(p, "_custom/smart_supported") && !p.get_value()) { - w = WarningLevel::Notice; - reason = "SMART is not supported. You won't be able to read any SMART information from this drive."; - - } else if (name_match(p, "_custom/smart_enabled") && !p.get_value()) { - w = WarningLevel::Notice; - reason = "SMART is disabled. You should enable it to read any SMART information from this drive. " - "Additionally, some drives do not log useful data with SMART disabled, so it's advisable to keep it always enabled."; - - } else if (name_match(p, "_text_only/info_warning")) { - w = WarningLevel::Notice; - reason = "Your drive may be affected by the warning, please see the details."; - } + } else { + switch (p.section) { + case AtaStorageProperty::Section::Info: + if (name_match(p, "_custom/smart_supported") && !p.get_value()) { + w = WarningLevel::Notice; + reason = "SMART is not supported. You won't be able to read any SMART information from this drive."; + + } else if (name_match(p, "_custom/smart_enabled") && !p.get_value()) { + w = WarningLevel::Notice; + reason = "SMART is disabled. You should enable it to read any SMART information from this drive. " + "Additionally, some drives do not log useful data with SMART disabled, so it's advisable to keep it always enabled."; - } else if (p.section == AtaStorageProperty::Section::Data) { + } else if (name_match(p, "_text_only/info_warning")) { + w = WarningLevel::Notice; + reason = "Your drive may be affected by the warning, please see the details."; + } + break; - switch(p.subsection) { - case AtaStorageProperty::SubSection::Health: + case AtaStorageProperty::Section::Health: if (name_match(p, "smart_status/passed") && !p.get_value()) { w = WarningLevel::Alert; reason = "The drive is reporting that it will FAIL very soon. Please back up as soon as possible!"; } break; - case AtaStorageProperty::SubSection::Capabilities: + case AtaStorageProperty::Section::Capabilities: // nothing break; - case AtaStorageProperty::SubSection::Attributes: + case AtaStorageProperty::Section::Attributes: { if (p.is_value_type()) { @@ -1811,7 +1813,7 @@ WarningLevel ata_storage_property_autoset_warning(AtaStorageProperty& p) break; } - case AtaStorageProperty::SubSection::Devstat: + case AtaStorageProperty::Section::Devstat: { if (p.is_value_type()) { const auto& statistic = p.get_value(); @@ -1887,7 +1889,7 @@ WarningLevel ata_storage_property_autoset_warning(AtaStorageProperty& p) break; } - case AtaStorageProperty::SubSection::ErrorLog: + case AtaStorageProperty::Section::ErrorLog: { // Note: The error list table doesn't display any descriptions, so if any // error-entry related descriptions are added here, don't forget to enable @@ -1924,7 +1926,7 @@ WarningLevel ata_storage_property_autoset_warning(AtaStorageProperty& p) break; } - case AtaStorageProperty::SubSection::SelftestLog: + case AtaStorageProperty::Section::SelftestLog: { // Note: The error list table doesn't display any descriptions, so if any // error-entry related descriptions are added here, don't forget to enable @@ -1940,11 +1942,11 @@ WarningLevel ata_storage_property_autoset_warning(AtaStorageProperty& p) break; } - case AtaStorageProperty::SubSection::SelectiveSelftestLog: + case AtaStorageProperty::Section::SelectiveSelftestLog: // nothing here break; - case AtaStorageProperty::SubSection::TemperatureLog: + case AtaStorageProperty::Section::TemperatureLog: // Don't highlight SCT Unsupported as warning, it's harmless. // if (name_match(p, "ata_sct_status/_not_present") && p.value_bool) { // w = WarningLevel::notice; @@ -1958,10 +1960,11 @@ WarningLevel ata_storage_property_autoset_warning(AtaStorageProperty& p) } break; - case AtaStorageProperty::SubSection::ErcLog: - case AtaStorageProperty::SubSection::PhyLog: - case AtaStorageProperty::SubSection::DirectoryLog: - case AtaStorageProperty::SubSection::Unknown: + case AtaStorageProperty::Section::ErcLog: + case AtaStorageProperty::Section::PhyLog: + case AtaStorageProperty::Section::DirectoryLog: + case AtaStorageProperty::Section::Unknown: + case AtaStorageProperty::Section::Internal: // nothing here break; } diff --git a/src/applib/selftest.cpp b/src/applib/selftest.cpp index afcf3b90..1fa4b9f5 100644 --- a/src/applib/selftest.cpp +++ b/src/applib/selftest.cpp @@ -77,7 +77,7 @@ std::chrono::seconds SelfTest::get_min_duration_seconds() const } const AtaStorageProperty p = drive_->get_property_repository().lookup_property(prop_name, - AtaStorageProperty::Section::Data, AtaStorageProperty::SubSection::Capabilities); + AtaStorageProperty::Section::Capabilities); // p stores it as uint64_t return (total_duration_ = (p.empty() ? 0s : p.get_value())); @@ -272,7 +272,6 @@ hz::ExpectedVoid SelfTest::update(const std::shared_ptr() || e.get_value().test_num != 0 || e.generic_name != "ata_smart_data/self_test/status/passed") diff --git a/src/applib/smartctl_json_ata_parser.cpp b/src/applib/smartctl_json_ata_parser.cpp index 00575518..155183c5 100644 --- a/src/applib/smartctl_json_ata_parser.cpp +++ b/src/applib/smartctl_json_ata_parser.cpp @@ -244,8 +244,7 @@ hz::ExpectedVoid SmartctlJsonAtaParser::parse_section_healt auto p = retrieval_func(json_root_node, key, displayable_name); if (p.has_value()) { // ignore if not found - p->section = AtaStorageProperty::Section::Data; - p->subsection = AtaStorageProperty::SubSection::Health; + p->section = AtaStorageProperty::Section::Health; add_property(p.value()); } } diff --git a/src/applib/smartctl_text_ata_parser.cpp b/src/applib/smartctl_text_ata_parser.cpp index 317e6166..65b631b3 100644 --- a/src/applib/smartctl_text_ata_parser.cpp +++ b/src/applib/smartctl_text_ata_parser.cpp @@ -36,22 +36,21 @@ namespace { inline AtaStorageProperty app_get_checksum_error_property(const std::string& name) { AtaStorageProperty p; - p.section = AtaStorageProperty::Section::Data; if (name == "Attribute Data") { - p.subsection = AtaStorageProperty::SubSection::Attributes; + p.section = AtaStorageProperty::Section::Attributes; p.set_name(name, "_text_only/attribute_data_checksum_error"); } else if (name == "Attribute Thresholds") { - p.subsection = AtaStorageProperty::SubSection::Attributes; + p.section = AtaStorageProperty::Section::Attributes; p.set_name(name, "_text_only/attribute_thresholds_checksum_error"); } else if (name == "ATA Error Log") { - p.subsection = AtaStorageProperty::SubSection::ErrorLog; + p.section = AtaStorageProperty::Section::ErrorLog; p.set_name(name, "_text_only/ata_error_log_checksum_error"); } else if (name == "Self-Test Log") { - p.subsection = AtaStorageProperty::SubSection::SelftestLog; + p.section = AtaStorageProperty::Section::SelftestLog; p.set_name(name, "_text_only/selftest_log_checksum_error"); } @@ -776,8 +775,7 @@ Device is: In smartctl database [for details use: -P show] */ AtaStorageProperty pt; // template for easy copying - pt.section = AtaStorageProperty::Section::Data; - pt.subsection = AtaStorageProperty::SubSection::Health; + pt.section = AtaStorageProperty::Section::Health; std::string name, value; if (app_pcre_match("/^([^:\\n]+):[ \\t]*(.*)$/mi", sub, &name, &value)) { @@ -842,8 +840,7 @@ SCT capabilities: (0x003d) SCT Status supported. */ AtaStorageProperty pt; // template for easy copying - pt.section = AtaStorageProperty::Section::Data; - pt.subsection = AtaStorageProperty::SubSection::Capabilities; + pt.section = AtaStorageProperty::Section::Capabilities; std::string sub = sub_initial; @@ -1027,7 +1024,7 @@ hz::ExpectedVoid SmartctlTextAtaParser::parse_section_data_ const pcrecpp::RE re_selftest_long_time = app_pcre_re("/^(Extended self-test routine recommended polling time)/mi"); const pcrecpp::RE re_conv_selftest_time = app_pcre_re("/^(Conveyance self-test routine recommended polling time)/mi"); - if (cap_prop.section != AtaStorageProperty::Section::Data || cap_prop.subsection != AtaStorageProperty::SubSection::Capabilities) { + if (cap_prop.section != AtaStorageProperty::Section::Capabilities) { debug_out_error("app", DBG_FUNC_MSG << "Non-capability property passed.\n"); return hz::Unexpected(SmartctlParserError::DataError, "Non-capability property passed."); } @@ -1244,8 +1241,7 @@ hz::ExpectedVoid SmartctlTextAtaParser::parse_section_data_ hz::ExpectedVoid SmartctlTextAtaParser::parse_section_data_subsection_attributes(const std::string& sub) { AtaStorageProperty pt; // template for easy copying - pt.section = AtaStorageProperty::Section::Data; - pt.subsection = AtaStorageProperty::SubSection::Attributes; + pt.section = AtaStorageProperty::Section::Attributes; // split to lines std::vector lines; @@ -1465,8 +1461,7 @@ ID# ATTRIBUTE_NAME FLAGS VALUE WORST THRESH FAIL RAW_VALUE hz::ExpectedVoid SmartctlTextAtaParser::parse_section_data_subsection_directory_log(const std::string& sub) { AtaStorageProperty pt; // template for easy copying - pt.section = AtaStorageProperty::Section::Data; - pt.subsection = AtaStorageProperty::SubSection::DirectoryLog; + pt.section = AtaStorageProperty::Section::DirectoryLog; // Directory log contains: /* @@ -1517,8 +1512,7 @@ Address Access R/W Size Description hz::ExpectedVoid SmartctlTextAtaParser::parse_section_data_subsection_error_log(const std::string& sub) { AtaStorageProperty pt; // template for easy copying - pt.section = AtaStorageProperty::Section::Data; - pt.subsection = AtaStorageProperty::SubSection::ErrorLog; + pt.section = AtaStorageProperty::Section::ErrorLog; // Note: The format of this section was changed somewhere between 5.0-x and 5.30. // The old format is doesn't really give any useful info, and whatever's left is somewhat @@ -1714,8 +1708,7 @@ Error 1 [0] occurred at disk power-on lifetime: 1 hours (0 days + 1 hours) hz::ExpectedVoid SmartctlTextAtaParser::parse_section_data_subsection_selftest_log(const std::string& sub) { AtaStorageProperty pt; // template for easy copying - pt.section = AtaStorageProperty::Section::Data; - pt.subsection = AtaStorageProperty::SubSection::SelftestLog; + pt.section = AtaStorageProperty::Section::SelftestLog; // Self-test log contains: // * structure revision number @@ -1893,8 +1886,7 @@ Num Test_Description Status Remaining LifeTime(hours) LBA hz::ExpectedVoid SmartctlTextAtaParser::parse_section_data_subsection_selective_selftest_log(const std::string& sub) { AtaStorageProperty pt; // template for easy copying - pt.section = AtaStorageProperty::Section::Data; - pt.subsection = AtaStorageProperty::SubSection::SelectiveSelftestLog; + pt.section = AtaStorageProperty::Section::SelectiveSelftestLog; // Selective self-test log contains: /* @@ -1950,8 +1942,7 @@ If Selective self-test is pending on power-up, resume after 0 minute delay. hz::ExpectedVoid SmartctlTextAtaParser::parse_section_data_subsection_scttemp_log(const std::string& sub) { AtaStorageProperty pt; // template for easy copying - pt.section = AtaStorageProperty::Section::Data; - pt.subsection = AtaStorageProperty::SubSection::TemperatureLog; + pt.section = AtaStorageProperty::Section::TemperatureLog; // scttemp log contains: /* @@ -2017,8 +2008,7 @@ Index Estimated Time Temperature Celsius std::string name, value; if (app_pcre_match("/^(Current Temperature):[ \\t]+(.*) Celsius$/mi", sub, &name, &value)) { AtaStorageProperty p; - p.section = AtaStorageProperty::Section::Data; - p.subsection = AtaStorageProperty::SubSection::TemperatureLog; + p.section = AtaStorageProperty::Section::TemperatureLog; p.set_name("Current Temperature", "ata_sct_status/temperature/current"); p.reported_value = value; p.value = hz::string_to_number_nolocale(value); // integer @@ -2040,8 +2030,7 @@ Index Estimated Time Temperature Celsius hz::ExpectedVoid SmartctlTextAtaParser::parse_section_data_subsection_scterc_log(const std::string& sub) { AtaStorageProperty pt; // template for easy copying - pt.section = AtaStorageProperty::Section::Data; - pt.subsection = AtaStorageProperty::SubSection::ErcLog; + pt.section = AtaStorageProperty::Section::ErcLog; // scterc log contains: /* @@ -2089,8 +2078,7 @@ SCT Error Recovery Control: hz::ExpectedVoid SmartctlTextAtaParser::parse_section_data_subsection_devstat(const std::string& sub) { AtaStorageProperty pt; // template for easy copying - pt.section = AtaStorageProperty::Section::Data; - pt.subsection = AtaStorageProperty::SubSection::Devstat; + pt.section = AtaStorageProperty::Section::Devstat; // devstat log contains: /* @@ -2260,8 +2248,7 @@ Page Offset Size Value Description hz::ExpectedVoid SmartctlTextAtaParser::parse_section_data_subsection_sataphy(const std::string& sub) { AtaStorageProperty pt; // template for easy copying - pt.section = AtaStorageProperty::Section::Data; - pt.subsection = AtaStorageProperty::SubSection::PhyLog; + pt.section = AtaStorageProperty::Section::PhyLog; // sataphy log contains: /* diff --git a/src/applib/smartctl_version_parser.h b/src/applib/smartctl_version_parser.h index faea8641..681654cc 100644 --- a/src/applib/smartctl_version_parser.h +++ b/src/applib/smartctl_version_parser.h @@ -15,7 +15,6 @@ License: GNU General Public License v3.0 only #include "local_glibmm.h" #include -#include #include #include "smartctl_parser_types.h" diff --git a/src/applib/storage_device.cpp b/src/applib/storage_device.cpp index d2b87383..a7405792 100644 --- a/src/applib/storage_device.cpp +++ b/src/applib/storage_device.cpp @@ -532,7 +532,7 @@ AtaStorageProperty StorageDevice::get_health_property() const return health_property_.value(); AtaStorageProperty p = property_repository_.lookup_property("smart_status/passed", - AtaStorageProperty::Section::Data, AtaStorageProperty::SubSection::Health); + AtaStorageProperty::Section::Health); if (!p.empty()) health_property_ = p; // store to cache diff --git a/src/applib/storage_property_repository.cpp b/src/applib/storage_property_repository.cpp index cea0fa5a..7416fa5f 100644 --- a/src/applib/storage_property_repository.cpp +++ b/src/applib/storage_property_repository.cpp @@ -4,6 +4,8 @@ License: GNU General Public License v3.0 only (C) 2008 - 2024 Alexander Shaduri ******************************************************************************/ +#include + #include "storage_property_repository.h" @@ -24,13 +26,11 @@ std::vector& StoragePropertyRepository::get_properties_ref() AtaStorageProperty StoragePropertyRepository::lookup_property( - const std::string& generic_name, AtaStorageProperty::Section section, AtaStorageProperty::SubSection subsection) const + const std::string& generic_name, AtaStorageProperty::Section section) const { for (const auto& p : properties_) { if (section != AtaStorageProperty::Section::Unknown && p.section != section) continue; - if (subsection != AtaStorageProperty::SubSection::Unknown && p.subsection != subsection) - continue; if (p.generic_name == generic_name) return p; diff --git a/src/applib/storage_property_repository.h b/src/applib/storage_property_repository.h index f9a51c76..ced5fe2d 100644 --- a/src/applib/storage_property_repository.h +++ b/src/applib/storage_property_repository.h @@ -21,10 +21,10 @@ class StoragePropertyRepository { [[nodiscard]] std::vector& get_properties_ref(); - /// Find a property + /// Find a property. + /// If section is Section::Unknown, search in all sections. [[nodiscard]] AtaStorageProperty lookup_property(const std::string& generic_name, - AtaStorageProperty::Section section = AtaStorageProperty::Section::Unknown, // if unknown, search in all. - AtaStorageProperty::SubSection subsection = AtaStorageProperty::SubSection::Unknown) const; + AtaStorageProperty::Section section = AtaStorageProperty::Section::Unknown) const; /// Set properties diff --git a/src/gsc_info_window.cpp b/src/gsc_info_window.cpp index c56e4078..8f72b50d 100644 --- a/src/gsc_info_window.cpp +++ b/src/gsc_info_window.cpp @@ -853,7 +853,7 @@ void GscInfoWindow::fill_ui_general(const std::vector& props } else { id_props.push_back(p); } - } else if (p.section == AtaStorageProperty::Section::Data && p.subsection == AtaStorageProperty::SubSection::Health) { + } else if (p.section == AtaStorageProperty::Section::Health) { health_props.push_back(p); } } @@ -1011,7 +1011,7 @@ void GscInfoWindow::fill_ui_attributes(const std::vector& pr std::vector label_strings; // outside-of-tree properties for (const auto& p : props) { - if (p.section != AtaStorageProperty::Section::Data || p.subsection != AtaStorageProperty::SubSection::Attributes) + if (p.section != AtaStorageProperty::Section::Attributes) continue; // add non-attribute-type properties to label above @@ -1033,9 +1033,11 @@ void GscInfoWindow::fill_ui_attributes(const std::vector& pr row[attribute_table_columns.worst] = Glib::Markup::escape_text(attr.worst.has_value() ? hz::number_to_string_locale(attr.worst.value()) : "-"); row[attribute_table_columns.threshold] = Glib::Markup::escape_text(attr.threshold.has_value() ? hz::number_to_string_locale(attr.threshold.value()) : "-"); row[attribute_table_columns.raw] = Glib::Markup::escape_text(attr.format_raw_value()); - row[attribute_table_columns.type] = Glib::Markup::escape_text(AtaStorageAttribute::get_attr_type_name(attr.attr_type)); + row[attribute_table_columns.type] = Glib::Markup::escape_text( + AtaStorageAttribute::get_readable_attribute_type_name(attr.attr_type)); // row[attribute_table_columns.updated] = Glib::Markup::escape_text(AtaStorageAttribute::get_update_type_name(attr.update_type)); - row[attribute_table_columns.when_failed] = Glib::Markup::escape_text(AtaStorageAttribute::get_fail_time_name(attr.when_failed)); + row[attribute_table_columns.when_failed] = Glib::Markup::escape_text( + AtaStorageAttribute::get_readable_fail_time_name(attr.when_failed)); row[attribute_table_columns.tooltip] = p.get_description(); // markup row[attribute_table_columns.storage_property] = &p; @@ -1102,7 +1104,7 @@ void GscInfoWindow::fill_ui_statistics(const std::vector& pr std::vector label_strings; // outside-of-tree properties for (const auto& p : props) { - if (p.section != AtaStorageProperty::Section::Data || p.subsection != AtaStorageProperty::SubSection::Devstat) + if (p.section != AtaStorageProperty::Section::Devstat) continue; // add non-entry-type properties to label above @@ -1280,7 +1282,7 @@ void GscInfoWindow::fill_ui_self_test_log(const std::vector& std::vector label_strings; // outside-of-tree properties for (auto&& p : props) { - if (p.section != AtaStorageProperty::Section::Data || p.subsection != AtaStorageProperty::SubSection::SelftestLog) + if (p.section != AtaStorageProperty::Section::SelftestLog) continue; if (p.generic_name == "ata_smart_self_test_log/_merged") // the whole section, we don't need it @@ -1301,7 +1303,7 @@ void GscInfoWindow::fill_ui_self_test_log(const std::vector& row[self_test_log_table_columns.log_entry_index] = sse.test_num; row[self_test_log_table_columns.type] = Glib::Markup::escape_text(sse.type); - row[self_test_log_table_columns.status] = Glib::Markup::escape_text(sse.get_status_str()); + row[self_test_log_table_columns.status] = Glib::Markup::escape_text(sse.get_readable_status()); row[self_test_log_table_columns.percent] = Glib::Markup::escape_text(hz::number_to_string_locale(100 - sse.remaining_percent) + "%"); row[self_test_log_table_columns.hours] = Glib::Markup::escape_text(sse.format_lifetime_hours()); row[self_test_log_table_columns.lba] = Glib::Markup::escape_text(sse.lba_of_first_error); @@ -1377,7 +1379,7 @@ void GscInfoWindow::fill_ui_error_log(const std::vector& pro std::vector label_strings; // outside-of-tree properties for (auto&& p : props) { - if (p.section != AtaStorageProperty::Section::Data || p.subsection != AtaStorageProperty::SubSection::ErrorLog) + if (p.section != AtaStorageProperty::Section::ErrorLog) continue; // Note: Don't use property description as a tooltip here. It won't be available if there's no property. @@ -1429,7 +1431,8 @@ void GscInfoWindow::fill_ui_error_log(const std::vector& pro row[error_log_table_columns.log_entry_index] = eb.error_num; row[error_log_table_columns.hours] = Glib::Markup::escape_text(eb.format_lifetime_hours()); row[error_log_table_columns.state] = Glib::Markup::escape_text(eb.device_state); - row[error_log_table_columns.type] = Glib::Markup::escape_text(AtaStorageErrorBlock::get_displayable_error_types(eb.reported_types)); + row[error_log_table_columns.type] = Glib::Markup::escape_text( + AtaStorageErrorBlock::format_readable_error_types(eb.reported_types)); row[error_log_table_columns.details] = Glib::Markup::escape_text(type_details.empty() ? "-" : type_details); // e.g. OBS has no details row[error_log_table_columns.tooltip] = p.get_description(); // markup row[error_log_table_columns.storage_property] = &p; @@ -1484,7 +1487,7 @@ void GscInfoWindow::fill_ui_temperature_log(const std::vector()) { // only show if unsupported @@ -1571,7 +1574,7 @@ WarningLevel GscInfoWindow::fill_ui_capabilities(const std::vector buffer = textview->get_buffer(); buffer->set_text("\n" + Glib::ustring::compose(_("Complete selective self-test log: %1"), "\n\n" + p.get_value())); @@ -1674,7 +1677,7 @@ WarningLevel GscInfoWindow::fill_ui_physical(const std::vector(data); - DBG_ASSERT(self); + DBG_ASSERT_RETURN(self, false); if (!self->current_test) // shouldn't happen return FALSE; // stop @@ -2024,7 +2027,7 @@ gboolean GscInfoWindow::test_idle_callback(void* data) } else { result_msg = Glib::ustring::compose(_("Test result: %1."), - Glib::Markup::escape_text(AtaStorageSelftestEntry::get_status_displayable_name(status))); + Glib::Markup::escape_text(AtaStorageSelftestEntry::get_readable_status_name(status))); // It may not reach 100% somehow, so do it manually. if (test_completion_progressbar)