mirror of
https://github.com/ashaduri/gsmartcontrol.git
synced 2026-09-25 13:25:37 +00:00
Simplified AtaStorageProperty by mergin Section and SubSection.
This commit is contained in:
@@ -10,17 +10,19 @@ Copyright:
|
||||
/// @{
|
||||
|
||||
#include "local_glibmm.h"
|
||||
#include <ios>
|
||||
#include <map>
|
||||
#include <ostream> // not iosfwd - it doesn't work
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <locale>
|
||||
#include <stdexcept>
|
||||
#include <unordered_map>
|
||||
|
||||
|
||||
#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<AttributeType, std::string> 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<UpdateType, std::string> 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<FailTime, std::string> 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<std::string>& types)
|
||||
std::string AtaStorageErrorBlock::format_readable_error_types(const std::vector<std::string>& types)
|
||||
{
|
||||
static const std::map<std::string, std::string> 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<Status, std::string> 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<Section, std::string> 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<SubSection, std::string> 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<std::monostate>(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;
|
||||
|
||||
@@ -12,6 +12,7 @@ Copyright:
|
||||
#ifndef ATA_STORAGE_PROPERTY_H
|
||||
#define ATA_STORAGE_PROPERTY_H
|
||||
|
||||
#include <cstddef> // std::size_t
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iosfwd>
|
||||
@@ -19,7 +20,6 @@ Copyright:
|
||||
#include <optional>
|
||||
#include <chrono>
|
||||
#include <variant>
|
||||
#include <unordered_map>
|
||||
|
||||
#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<std::string>& types);
|
||||
[[nodiscard]] static std::string format_readable_error_types(const std::vector<std::string>& 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.
|
||||
|
||||
@@ -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");
|
||||
} 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;
|
||||
}
|
||||
// set just its name as a tooltip
|
||||
if (!found) {
|
||||
p.set_description(p.displayable_name);
|
||||
found = true;
|
||||
}
|
||||
break;
|
||||
|
||||
} else if (p.section == AtaStorageProperty::Section::Data) {
|
||||
|
||||
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<AtaStorageErrorBlock>()) {
|
||||
for (size_t i = 0; i < p.get_value<AtaStorageErrorBlock>().reported_types.size(); ++i) {
|
||||
p.set_description(AtaStorageErrorBlock::get_displayable_error_types(p.get_value<AtaStorageErrorBlock>().reported_types));
|
||||
p.set_description(AtaStorageErrorBlock::format_readable_error_types(
|
||||
p.get_value<AtaStorageErrorBlock>().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<bool>()) {
|
||||
w = WarningLevel::Notice;
|
||||
reason = "SMART is not supported. You won't be able to read any SMART information from this drive.";
|
||||
} else {
|
||||
switch (p.section) {
|
||||
case AtaStorageProperty::Section::Info:
|
||||
if (name_match(p, "_custom/smart_supported") && !p.get_value<bool>()) {
|
||||
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<bool>()) {
|
||||
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, "_custom/smart_enabled") && !p.get_value<bool>()) {
|
||||
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 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;
|
||||
|
||||
} else if (p.section == AtaStorageProperty::Section::Data) {
|
||||
|
||||
switch(p.subsection) {
|
||||
case AtaStorageProperty::SubSection::Health:
|
||||
case AtaStorageProperty::Section::Health:
|
||||
if (name_match(p, "smart_status/passed") && !p.get_value<bool>()) {
|
||||
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<AtaStorageAttribute>()) {
|
||||
|
||||
@@ -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<AtaStorageStatistic>()) {
|
||||
const auto& statistic = p.get_value<AtaStorageStatistic>();
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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<std::chrono::seconds>()));
|
||||
@@ -272,7 +272,6 @@ hz::ExpectedVoid<SelfTestError> SelfTest::update(const std::shared_ptr<CommandEx
|
||||
// we use the "self-test status" capability.
|
||||
AtaStorageProperty p;
|
||||
for (const auto& e : property_repo.get_properties()) {
|
||||
// if (e.section != AtaStorageProperty::Section::data || e.subsection != AtaStorageProperty::SubSection::selftest_log
|
||||
if (e.section != AtaStorageProperty::Section::Internal
|
||||
|| !e.is_value_type<AtaStorageSelftestEntry>() || e.get_value<AtaStorageSelftestEntry>().test_num != 0
|
||||
|| e.generic_name != "ata_smart_data/self_test/status/passed")
|
||||
|
||||
@@ -244,8 +244,7 @@ hz::ExpectedVoid<SmartctlParserError> 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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<SmartctlParserError> 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<SmartctlParserError> SmartctlTextAtaParser::parse_section_data_
|
||||
hz::ExpectedVoid<SmartctlParserError> 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<std::string> lines;
|
||||
@@ -1465,8 +1461,7 @@ ID# ATTRIBUTE_NAME FLAGS VALUE WORST THRESH FAIL RAW_VALUE
|
||||
hz::ExpectedVoid<SmartctlParserError> 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<SmartctlParserError> 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<SmartctlParserError> 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<SmartctlParserError> 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<SmartctlParserError> 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<int64_t>(value); // integer
|
||||
@@ -2040,8 +2030,7 @@ Index Estimated Time Temperature Celsius
|
||||
hz::ExpectedVoid<SmartctlParserError> 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<SmartctlParserError> 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<SmartctlParserError> 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:
|
||||
/*
|
||||
|
||||
@@ -15,7 +15,6 @@ Copyright:
|
||||
#include "local_glibmm.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
|
||||
#include "smartctl_parser_types.h"
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ Copyright:
|
||||
(C) 2008 - 2024 Alexander Shaduri <ashaduri@gmail.com>
|
||||
******************************************************************************/
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "storage_property_repository.h"
|
||||
|
||||
|
||||
@@ -24,13 +26,11 @@ std::vector<AtaStorageProperty>& 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;
|
||||
|
||||
@@ -21,10 +21,10 @@ class StoragePropertyRepository {
|
||||
[[nodiscard]] std::vector<AtaStorageProperty>& 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
|
||||
|
||||
+21
-18
@@ -853,7 +853,7 @@ void GscInfoWindow::fill_ui_general(const std::vector<AtaStorageProperty>& 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<AtaStorageProperty>& pr
|
||||
std::vector<PropertyLabel> 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<AtaStorageProperty>& 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<AtaStorageProperty>& pr
|
||||
std::vector<PropertyLabel> 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<AtaStorageProperty>&
|
||||
std::vector<PropertyLabel> 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<AtaStorageProperty>&
|
||||
|
||||
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<AtaStorageProperty>& pro
|
||||
std::vector<PropertyLabel> 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<AtaStorageProperty>& 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<AtaStorageProperty
|
||||
temp_prop_source = temp_attr2;
|
||||
}
|
||||
|
||||
if (p.section != AtaStorageProperty::Section::Data || p.subsection != AtaStorageProperty::SubSection::TemperatureLog)
|
||||
if (p.section != AtaStorageProperty::Section::TemperatureLog)
|
||||
continue;
|
||||
|
||||
if (p.generic_name == "ata_sct_status/_not_present" && p.get_value<bool>()) { // only show if unsupported
|
||||
@@ -1571,7 +1574,7 @@ WarningLevel GscInfoWindow::fill_ui_capabilities(const std::vector<AtaStoragePro
|
||||
int index = 1;
|
||||
|
||||
for (auto&& p : props) {
|
||||
if (p.section != AtaStorageProperty::Section::Data || p.subsection != AtaStorageProperty::SubSection::Capabilities)
|
||||
if (p.section != AtaStorageProperty::Section::Capabilities)
|
||||
continue;
|
||||
|
||||
std::string flag_value;
|
||||
@@ -1614,7 +1617,7 @@ WarningLevel GscInfoWindow::fill_ui_error_recovery(const std::vector<AtaStorageP
|
||||
WarningLevel max_tab_warning = WarningLevel::None;
|
||||
|
||||
for (auto&& p : props) {
|
||||
if (p.section != AtaStorageProperty::Section::Data || p.subsection != AtaStorageProperty::SubSection::ErcLog)
|
||||
if (p.section != AtaStorageProperty::Section::ErcLog)
|
||||
continue;
|
||||
|
||||
// Note: Don't use property description as a tooltip here. It won't be available if there's no property.
|
||||
@@ -1644,11 +1647,11 @@ WarningLevel GscInfoWindow::fill_ui_selective_self_test_log(const std::vector<At
|
||||
WarningLevel max_tab_warning = WarningLevel::None;
|
||||
|
||||
for (auto&& p : props) {
|
||||
if (p.section != AtaStorageProperty::Section::Data || p.subsection != AtaStorageProperty::SubSection::SelectiveSelftestLog)
|
||||
if (p.section != AtaStorageProperty::Section::SelectiveSelftestLog)
|
||||
continue;
|
||||
|
||||
// Note: Don't use property description as a tooltip here. It won't be available if there's no property.
|
||||
if (p.generic_name == "SubSection::ata_smart_selective_self_test_log/_merged") {
|
||||
if (p.generic_name == "ata_smart_selective_self_test_log/_merged") {
|
||||
Glib::RefPtr<Gtk::TextBuffer> buffer = textview->get_buffer();
|
||||
buffer->set_text("\n" + Glib::ustring::compose(_("Complete selective self-test log: %1"), "\n\n" + p.get_value<std::string>()));
|
||||
|
||||
@@ -1674,7 +1677,7 @@ WarningLevel GscInfoWindow::fill_ui_physical(const std::vector<AtaStoragePropert
|
||||
WarningLevel max_tab_warning = WarningLevel::None;
|
||||
|
||||
for (auto&& p : props) {
|
||||
if (p.section != AtaStorageProperty::Section::Data || p.subsection != AtaStorageProperty::SubSection::PhyLog)
|
||||
if (p.section != AtaStorageProperty::Section::PhyLog)
|
||||
continue;
|
||||
|
||||
// Note: Don't use property description as a tooltip here. It won't be available if there's no property.
|
||||
@@ -1704,7 +1707,7 @@ WarningLevel GscInfoWindow::fill_ui_directory(const std::vector<AtaStorageProper
|
||||
WarningLevel max_tab_warning = WarningLevel::None;
|
||||
|
||||
for (auto&& p : props) {
|
||||
if (p.section != AtaStorageProperty::Section::Data || p.subsection != AtaStorageProperty::SubSection::DirectoryLog)
|
||||
if (p.section != AtaStorageProperty::Section::DirectoryLog)
|
||||
continue;
|
||||
|
||||
// Note: Don't use property description as a tooltip here. It won't be available if there's no property.
|
||||
@@ -1909,7 +1912,7 @@ void GscInfoWindow::cell_renderer_for_capabilities(Gtk::CellRenderer* cr,
|
||||
gboolean GscInfoWindow::test_idle_callback(void* data)
|
||||
{
|
||||
auto* self = static_cast<GscInfoWindow*>(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(_("<b>Test result:</b> %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)
|
||||
|
||||
Reference in New Issue
Block a user