From c60f6815fabf07919ae8ca1b5a47d3ebf844af70 Mon Sep 17 00:00:00 2001 From: Alexander Shaduri Date: Fri, 28 Sep 2012 08:52:10 +0000 Subject: [PATCH] Fixed BDRW drive detection (it was detected as a HDD). Added support for recent smartctl -i changes. --- gsmartcontrol/TODO | 4 + gsmartcontrol/gsmartcontrol.spec.in | 2 +- gsmartcontrol/src/applib/smartctl_parser.cpp | 81 +++++++++++--------- gsmartcontrol/src/applib/storage_device.cpp | 8 +- 4 files changed, 55 insertions(+), 40 deletions(-) diff --git a/gsmartcontrol/TODO b/gsmartcontrol/TODO index a935743..ccadaac 100644 --- a/gsmartcontrol/TODO +++ b/gsmartcontrol/TODO @@ -31,6 +31,10 @@ TODO: Investiage the new "-l ssd" and "-l devstat" options (since 5.42) +Check also other options in 5.42 and 5.43. + "-g all" looks promising alongside -i (shows APM and other stuff as well). + +Add --identify option to context menu, for convenience. Add menu item - "update drive database" (not sure about linux, should check if it's supported first; also need to run it in terminal). diff --git a/gsmartcontrol/gsmartcontrol.spec.in b/gsmartcontrol/gsmartcontrol.spec.in index e587c62..6177013 100644 --- a/gsmartcontrol/gsmartcontrol.spec.in +++ b/gsmartcontrol/gsmartcontrol.spec.in @@ -108,7 +108,7 @@ SMART data to determine its health, as well as run various tests on it. # numprocs=1 #fi #make -j$numprocs -make +make %{?_smp_mflags} %install diff --git a/gsmartcontrol/src/applib/smartctl_parser.cpp b/gsmartcontrol/src/applib/smartctl_parser.cpp index 0ac8f49..04542cf 100644 --- a/gsmartcontrol/src/applib/smartctl_parser.cpp +++ b/gsmartcontrol/src/applib/smartctl_parser.cpp @@ -408,52 +408,32 @@ bool SmartctlParser::parse_section_info_property(StorageProperty& p) } - if (app_pcre_match("/Model Family/mi", p.reported_name)) { + if (app_pcre_match("/^Model Family$/mi", p.reported_name)) { p.set_name(p.reported_name, "model_family", "Model Family"); p.value_type = StorageProperty::value_type_string; p.value_string = p.reported_value; - } else if (app_pcre_match("/Device Model/mi", p.reported_name)) { + } else if (app_pcre_match("/^Device Model$/mi", p.reported_name)) { p.set_name(p.reported_name, "device_model", "Device Model"); p.value_type = StorageProperty::value_type_string; p.value_string = p.reported_value; - } else if (app_pcre_match("/Serial Number/mi", p.reported_name)) { + } else if (app_pcre_match("/^Serial Number$/mi", p.reported_name)) { p.set_name(p.reported_name, "serial_number", "Serial Number"); p.value_type = StorageProperty::value_type_string; p.value_string = p.reported_value; - } else if (app_pcre_match("/Firmware Version/mi", p.reported_name)) { - p.set_name(p.reported_name, "firmware_version", "Firmware Version"); - p.value_type = StorageProperty::value_type_string; - p.value_string = p.reported_value; - - } else if (app_pcre_match("/Sector Sizes/mi", p.reported_name)) { - p.set_name(p.reported_name, "sector_sizes", "Sector Sizes"); - p.value_type = StorageProperty::value_type_string; // prints 2 values (phys/logical, if they're different) - p.value_string = p.reported_value; - - } else if (app_pcre_match("/Sector Size/mi", p.reported_name)) { - p.set_name(p.reported_name, "sector_size", "Sector Size"); - p.value_type = StorageProperty::value_type_string; // prints a single value (if it's not 512) - p.value_string = p.reported_value; - - } else if (app_pcre_match("/LU WWN Device Id/mi", p.reported_name)) { + } else if (app_pcre_match("/^LU WWN Device Id$/mi", p.reported_name)) { p.set_name(p.reported_name, "wwn_id", "World Wide Name"); p.value_type = StorageProperty::value_type_string; p.value_string = p.reported_value; - } else if (app_pcre_match("/ATA Standard is/mi", p.reported_name)) { - p.set_name(p.reported_name, "ata_standard", "ATA Standard"); + } else if (app_pcre_match("/^Firmware Version$/mi", p.reported_name)) { + p.set_name(p.reported_name, "firmware_version", "Firmware Version"); p.value_type = StorageProperty::value_type_string; p.value_string = p.reported_value; - } else if (app_pcre_match("/Local Time is/mi", p.reported_name)) { - p.set_name(p.reported_name, "scan_time", "Scanned on"); - p.value_type = StorageProperty::value_type_string; - p.value_string = p.reported_value; - - } else if (app_pcre_match("/User Capacity/mi", p.reported_name)) { + } else if (app_pcre_match("/^User Capacity$/mi", p.reported_name)) { p.set_name(p.reported_name, "capacity", "Capacity"); p.value_type = StorageProperty::value_type_integer; uint64_t v = 0; @@ -463,19 +443,47 @@ bool SmartctlParser::parse_section_info_property(StorageProperty& p) p.value_integer = v; } - } else if (app_pcre_match("/ATA Version is/mi", p.reported_name)) { - p.set_name(p.reported_name, "ata_version", "ATA Version"); - p.value_type = StorageProperty::value_type_integer; - int64_t v = 0; - if (hz::string_is_numeric(p.reported_value, v, true)) // strict mode - p.value_integer = v; + } else if (app_pcre_match("/^Sector Sizes$/mi", p.reported_name)) { + p.set_name(p.reported_name, "sector_sizes", "Sector Sizes"); + p.value_type = StorageProperty::value_type_string; // prints 2 values (phys/logical, if they're different) + p.value_string = p.reported_value; - } else if (app_pcre_match("/Device is/mi", p.reported_name)) { + } else if (app_pcre_match("/^Sector Size$/mi", p.reported_name)) { + p.set_name(p.reported_name, "sector_size", "Sector Size"); + p.value_type = StorageProperty::value_type_string; // prints a single value (if it's not 512) + p.value_string = p.reported_value; + + } else if (app_pcre_match("/^Rotation Rate$/mi", p.reported_name)) { + p.set_name(p.reported_name, "rotation_rate", "Rotation Rate"); + p.value_type = StorageProperty::value_type_string; + p.value_string = p.reported_value; + + } else if (app_pcre_match("/^Device is$/mi", p.reported_name)) { p.set_name(p.reported_name, "in_smartctl_db", "In Smartctl Database"); p.value_type = StorageProperty::value_type_bool; p.value_bool = (!app_pcre_match("/Not in /mi", p.reported_value)); - } else if (app_pcre_match("/SMART support is/mi", p.reported_name)) { + } else if (app_pcre_match("/^ATA Version is$/mi", p.reported_name)) { + p.set_name(p.reported_name, "ata_version", "ATA Version"); + p.value_type = StorageProperty::value_type_string; + p.value_string = p.reported_value; + + } else if (app_pcre_match("/^ATA Standard is$/mi", p.reported_name)) { + p.set_name(p.reported_name, "ata_standard", "ATA Standard"); + p.value_type = StorageProperty::value_type_string; + p.value_string = p.reported_value; + + } else if (app_pcre_match("/^SATA Version is$/mi", p.reported_name)) { + p.set_name(p.reported_name, "sata_version", "SATA Version"); + p.value_type = StorageProperty::value_type_string; + p.value_string = p.reported_value; + + } else if (app_pcre_match("/^Local Time is$/mi", p.reported_name)) { + p.set_name(p.reported_name, "scan_time", "Scanned on"); + p.value_type = StorageProperty::value_type_string; + p.value_string = p.reported_value; + + } else if (app_pcre_match("/^SMART support is$/mi", p.reported_name)) { // There are two different properties with this name - supported and enabled. // Don't put complete messages here - they change across smartctl versions. @@ -499,13 +507,12 @@ bool SmartctlParser::parse_section_info_property(StorageProperty& p) p.value_type = StorageProperty::value_type_bool; p.value_bool = false; - // this should be last - when ambiguous state is detected, usually smartctl + // 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, "smart_supported", "SMART Supported"); p.value_type = StorageProperty::value_type_bool; p.value_bool = true; // let's be optimistic - just hope that it doesn't hurt. - } } else { diff --git a/gsmartcontrol/src/applib/storage_device.cpp b/gsmartcontrol/src/applib/storage_device.cpp index 31bd056..f84d00c 100644 --- a/gsmartcontrol/src/applib/storage_device.cpp +++ b/gsmartcontrol/src/applib/storage_device.cpp @@ -201,8 +201,12 @@ std::string StorageDevice::parse_basic_data(bool do_set_properties, bool emit_si if (!SmartctlParser::parse_version(this->info_output_, version, version_full)) // is this smartctl data at all? return "Cannot get smartctl version information."; - // detect type. note: we can't distinguish between sata and scsi (on linux, for -d ata switch). - if (app_pcre_match("/this device: CD\\/DVD/mi", info_output_)) { + // Detect type. note: we can't distinguish between sata and scsi (on linux, for -d ata switch). + // Sample output line 1 (encountered on a CDRW drive): + // SMART support is: Unavailable - Packet Interface Devices [this device: CD/DVD] don't support ATA SMART + // Sample output line 2 (encountered on a BDRW drive): + // Device type: CD/DVD + if (app_pcre_match("/this device: CD\\/DVD/mi", info_output_) || app_pcre_match("/^Device type:\\s+CD\\/DVD/mi", info_output_)) { this->set_detected_type(detected_type_cddvd); }