mirror of
https://github.com/ashaduri/gsmartcontrol.git
synced 2026-09-25 21:35:33 +00:00
ATA JSON parser improvements.
This commit is contained in:
@@ -62,8 +62,8 @@ Information not printed in JSON yet:
|
||||
We ignore this in text parser.
|
||||
|
||||
- SMART support and some other Info keys
|
||||
_text_only/smart_supported
|
||||
_text_only/smart_enabled
|
||||
smart_support/available
|
||||
smart_support/enabled
|
||||
_text_only/write_cache_reorder
|
||||
_text_only/power_mode
|
||||
|
||||
@@ -321,6 +321,46 @@ hz::ExpectedVoid<SmartctlParserError> SmartctlJsonAtaParser::parse_section_info(
|
||||
},
|
||||
|
||||
{"local_time/asctime", _("Scanned on"), string_formatter()},
|
||||
|
||||
{"smart_support/available", _("SMART Supported"), bool_formatter(_("Yes"), _("No"))},
|
||||
{"smart_support/enabled", _("SMART Enabled"), bool_formatter(_("Yes"), _("No"))},
|
||||
|
||||
{"ata_aam/enabled", _("AAM Feature"), bool_formatter(_("Enabled"), _("Disabled"))},
|
||||
{"ata_aam/level", _("AAM Level"),
|
||||
[](const nlohmann::json& root_node, const std::string& key, const std::string& displayable_name)
|
||||
-> hz::ExpectedValue<AtaStorageProperty, SmartctlParserError>
|
||||
{
|
||||
int64_t level = get_node_data<int64_t>(root_node, "ata_aam/level").value_or(0);
|
||||
std::string level_string = get_node_data<std::string>(root_node, "ata_aam/string").value_or("");
|
||||
AtaStorageProperty p;
|
||||
p.set_name(key, key, displayable_name);
|
||||
p.readable_value = std::format("{} ({})", level_string, level);
|
||||
p.value = level;
|
||||
return p;
|
||||
}
|
||||
},
|
||||
{"ata_aam/recommended_level", _("AAM Recommended Level"),
|
||||
custom_string_formatter<int64_t>([](int64_t value)
|
||||
{
|
||||
return std::format("{}", value);
|
||||
})
|
||||
},
|
||||
|
||||
{"ata_apm/enabled", _("APM Feature"), bool_formatter(_("Enabled"), _("Disabled"))},
|
||||
{"ata_apm/level", _("APM Level"),
|
||||
[](const nlohmann::json& root_node, const std::string& key, const std::string& displayable_name)
|
||||
-> hz::ExpectedValue<AtaStorageProperty, SmartctlParserError>
|
||||
{
|
||||
int64_t level = get_node_data<int64_t>(root_node, "ata_apm/level").value_or(0);
|
||||
std::string level_string = get_node_data<std::string>(root_node, "ata_apm/string").value_or("");
|
||||
AtaStorageProperty p;
|
||||
p.set_name(key, key, displayable_name);
|
||||
p.readable_value = std::format("{} ({})", level_string, level);
|
||||
p.value = level;
|
||||
return p;
|
||||
}
|
||||
},
|
||||
|
||||
{"read_lookahead/enabled", _("Read Look-Ahead"), bool_formatter(_("Enabled"), _("Disabled"))},
|
||||
{"write_cache/enabled", _("Write Cache"), bool_formatter(_("Enabled"), _("Disabled"))},
|
||||
{"ata_dsn/enabled", _("DSN Feature"), bool_formatter(_("Enabled"), _("Disabled"))},
|
||||
@@ -1200,14 +1240,54 @@ hz::ExpectedVoid<SmartctlParserError> SmartctlJsonAtaParser::parse_section_devst
|
||||
|
||||
hz::ExpectedVoid<SmartctlParserError> SmartctlJsonAtaParser::parse_section_sataphy(const nlohmann::json& json_root_node)
|
||||
{
|
||||
return hz::ExpectedVoid<SmartctlParserError>();
|
||||
}
|
||||
using namespace SmartctlJsonParserHelpers;
|
||||
using namespace std::string_literals;
|
||||
|
||||
bool section_properties_found = false;
|
||||
|
||||
std::vector<std::string> lines;
|
||||
|
||||
hz::ExpectedVoid<SmartctlParserError> SmartctlJsonAtaParser::parse_section_internal_capabilities(AtaStorageProperty& cap_prop)
|
||||
{
|
||||
return hz::ExpectedVoid<SmartctlParserError>();
|
||||
// Table
|
||||
const std::string table_key = "sata_phy_event_counters/table";
|
||||
auto table_node = get_node(json_root_node, table_key);
|
||||
|
||||
// Entries
|
||||
if (table_node.has_value() && table_node->is_array()) {
|
||||
for (const auto& table_entry : table_node.value()) {
|
||||
const uint64_t id = get_node_data<uint64_t>(table_entry, "id").value_or(0);
|
||||
const std::string name = get_node_data<std::string>(table_entry, "name").value_or(std::string());
|
||||
const uint64_t size = get_node_data<uint64_t>(table_entry, "size").value_or(0);
|
||||
const int64_t value = get_node_data<int64_t>(table_entry, "value").value_or(0);
|
||||
// const bool overflow = get_node_data<bool>(table_entry, "overflow").value_or(false);
|
||||
|
||||
lines.emplace_back(std::format(
|
||||
"ID: 0x{:02X} Size: {:8} Value: {:20} Description: {}",
|
||||
id,
|
||||
size,
|
||||
value,
|
||||
name));
|
||||
}
|
||||
|
||||
// The whole section
|
||||
{
|
||||
AtaStorageProperty p;
|
||||
p.set_name("SATA Phy Log", "sata_phy_event_counters/_merged");
|
||||
p.section = AtaStorageProperty::Section::PhyLog;
|
||||
p.reported_value = hz::string_join(lines, "\n");
|
||||
p.value = p.reported_value; // string-type value
|
||||
|
||||
add_property(p);
|
||||
}
|
||||
|
||||
section_properties_found = true;
|
||||
}
|
||||
|
||||
if (!section_properties_found) {
|
||||
return hz::Unexpected(SmartctlParserError::NoSection,
|
||||
std::format("No section {} parsed.", AtaStorageProperty::get_readable_section_name(AtaStorageProperty::Section::PhyLog)));
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -72,10 +72,6 @@ class SmartctlJsonAtaParser : public SmartctlParser {
|
||||
hz::ExpectedVoid<SmartctlParserError> parse_section_sataphy(const nlohmann::json& json_root_node);
|
||||
|
||||
|
||||
/// Check the capabilities for internal properties we can use.
|
||||
hz::ExpectedVoid<SmartctlParserError> parse_section_internal_capabilities(AtaStorageProperty& cap_prop);
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -79,14 +79,14 @@ hz::ExpectedVoid<SmartctlParserError> SmartctlJsonBasicParser::parse_section_bas
|
||||
|
||||
{
|
||||
AtaStorageProperty p;
|
||||
p.set_name("SMART Supported", "_text_only/smart_supported", "SMART Supported");
|
||||
p.set_name("SMART Supported", "smart_support/available", "SMART Supported");
|
||||
p.value = smart_supported;
|
||||
p.section = AtaStorageProperty::Section::Info; // add to info section
|
||||
add_property(p);
|
||||
}
|
||||
{
|
||||
AtaStorageProperty p;
|
||||
p.set_name("SMART Enabled", "_text_only/smart_enabled", "SMART Enabled");
|
||||
p.set_name("SMART Enabled", "smart_support/enabled", "SMART Enabled");
|
||||
p.value = smart_enabled;
|
||||
p.section = AtaStorageProperty::Section::Info; // add to info section
|
||||
add_property(p);
|
||||
|
||||
@@ -532,25 +532,25 @@ hz::ExpectedVoid<SmartctlParserError> SmartctlTextAtaParser::parse_section_info_
|
||||
// Don't put complete messages here - they change across smartctl versions.
|
||||
|
||||
if (app_pcre_match("/Available - device has/mi", p.reported_value)) {
|
||||
p.set_name(p.reported_name, "_text_only/smart_supported", "SMART Supported");
|
||||
p.set_name(p.reported_name, "smart_support/available", "SMART Supported");
|
||||
p.value = true;
|
||||
|
||||
} else if (app_pcre_match("/Enabled/mi", p.reported_value)) {
|
||||
p.set_name(p.reported_name, "_text_only/smart_enabled", "SMART Enabled");
|
||||
p.set_name(p.reported_name, "smart_support/enabled", "SMART Enabled");
|
||||
p.value = true;
|
||||
|
||||
} else if (app_pcre_match("/Disabled/mi", p.reported_value)) {
|
||||
p.set_name(p.reported_name, "_text_only/smart_enabled", "SMART Enabled");
|
||||
p.set_name(p.reported_name, "smart_support/enabled", "SMART Enabled");
|
||||
p.value = false;
|
||||
|
||||
} else if (app_pcre_match("/Unavailable/mi", p.reported_value)) {
|
||||
p.set_name(p.reported_name, "_text_only/smart_supported", "SMART Supported");
|
||||
p.set_name(p.reported_name, "smart_support/available", "SMART Supported");
|
||||
p.value = false;
|
||||
|
||||
// this should be the last - when ambiguous state is detected, usually smartctl
|
||||
// retries with other methods and prints one of the above.
|
||||
} else if (app_pcre_match("/Ambiguous/mi", p.reported_value)) {
|
||||
p.set_name(p.reported_name, "_text_only/smart_supported", "SMART Supported");
|
||||
p.set_name(p.reported_name, "smart_support/available", "SMART Supported");
|
||||
p.value = true; // let's be optimistic - just hope that it doesn't hurt.
|
||||
}
|
||||
|
||||
|
||||
@@ -132,14 +132,14 @@ hz::ExpectedVoid<SmartctlParserError> SmartctlTextBasicParser::parse(std::string
|
||||
|
||||
{
|
||||
AtaStorageProperty p;
|
||||
p.set_name("SMART Supported", "_text_only/smart_supported", "SMART Supported");
|
||||
p.set_name("SMART Supported", "smart_support/available", "SMART Supported");
|
||||
p.value = smart_supported;
|
||||
p.section = AtaStorageProperty::Section::Info; // add to info section
|
||||
add_property(p);
|
||||
}
|
||||
{
|
||||
AtaStorageProperty p;
|
||||
p.set_name("SMART Enabled", "_text_only/smart_enabled", "SMART Enabled");
|
||||
p.set_name("SMART Enabled", "smart_support/enabled", "SMART Enabled");
|
||||
p.value = smart_enabled;
|
||||
p.section = AtaStorageProperty::Section::Info; // add to info section
|
||||
add_property(p);
|
||||
|
||||
@@ -57,8 +57,8 @@ class SmartctlVersionParser {
|
||||
// Can't fully test 5.0-xx, they don't support sata, and I have only sata.
|
||||
static constexpr double minimum_req_text_version = 5.0;
|
||||
|
||||
// JSON in 7.2 is still experimental, but we have to have some cut-off point.
|
||||
static constexpr double minimum_req_json_version = 7.2;
|
||||
// 7.3 adds "smart_support" section in json.
|
||||
static constexpr double minimum_req_json_version = 7.3;
|
||||
|
||||
|
||||
};
|
||||
|
||||
@@ -188,10 +188,10 @@ hz::ExpectedVoid<StorageDeviceError> StorageDevice::parse_basic_data(bool do_set
|
||||
}
|
||||
}
|
||||
|
||||
if (auto prop = basic_property_repo.lookup_property("_text_only/smart_supported"); !prop.empty()) {
|
||||
if (auto prop = basic_property_repo.lookup_property("smart_support/available"); !prop.empty()) {
|
||||
smart_supported_ = prop.get_value<bool>();
|
||||
}
|
||||
if (auto prop = basic_property_repo.lookup_property("_text_only/smart_enabled"); !prop.empty()) {
|
||||
if (auto prop = basic_property_repo.lookup_property("smart_support/enabled"); !prop.empty()) {
|
||||
smart_enabled_ = prop.get_value<bool>();
|
||||
}
|
||||
if (auto prop = basic_property_repo.lookup_property("model_name"); !prop.empty()) {
|
||||
|
||||
Reference in New Issue
Block a user