From 9e19366acf617fbe31392ced17a1f2d457c21cda Mon Sep 17 00:00:00 2001 From: chrfranke <chrfranke@4ea69e1a-61f1-4043-bf83-b5c94c648137> Date: Sat, 13 Jun 2009 14:56:20 +0000 Subject: [PATCH] Print General Purpose Logs even if GPL feature bit is missing. Change order of the extended log outputs. git-svn-id: https://smartmontools.svn.sourceforge.net/svnroot/smartmontools/trunk@2800 4ea69e1a-61f1-4043-bf83-b5c94c648137 --- sm5/CHANGELOG | 9 +- sm5/ataprint.cpp | 271 ++++++++++++++++++++++------------------------- 2 files changed, 137 insertions(+), 143 deletions(-) diff --git a/sm5/CHANGELOG b/sm5/CHANGELOG index a22e54df1..8c3a1dad8 100644 --- a/sm5/CHANGELOG +++ b/sm5/CHANGELOG @@ -1,6 +1,6 @@ CHANGELOG for smartmontools -$Id: CHANGELOG,v 1.803 2009/06/12 12:25:02 chrfranke Exp $ +$Id: CHANGELOG,v 1.804 2009/06/13 14:56:20 chrfranke Exp $ The most recent version of this file is: http://smartmontools.cvs.sourceforge.net/smartmontools/sm5/CHANGELOG?view=markup @@ -41,6 +41,13 @@ NOTES FOR FUTURE RELEASES: see TODO file. <DEVELOPERS: ADDITIONS TO THE CHANGE LOG GO JUST BELOW HERE, PLEASE> + [CF] Print General Purpose Logs even if GPL feature bit is missing. + Needed for some older disks which implement READ LOG EXT but + do not report the GPL feature set. + Change order of the extended log outputs ('-l xerror', + '-l xselftest', '-l sataphy'). Extended logs are now printed + before their old versions. + [CF] autogen.sh: automake 1.10.2 and 1.11 are OK. [CF] Fix syntax error in prototype of 'safe_snprintf()'. diff --git a/sm5/ataprint.cpp b/sm5/ataprint.cpp index f9182fa5f..78faf9d9a 100644 --- a/sm5/ataprint.cpp +++ b/sm5/ataprint.cpp @@ -44,7 +44,7 @@ #include "utility.h" #include "knowndrives.h" -const char *ataprint_c_cvsid="$Id: ataprint.cpp,v 1.210 2009/04/16 21:24:08 chrfranke Exp $" +const char *ataprint_c_cvsid="$Id: ataprint.cpp,v 1.211 2009/06/13 14:56:20 chrfranke Exp $" ATACMDNAMES_H_CVSID ATACMDS_H_CVSID ATAPRINT_H_CVSID CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID KNOWNDRIVES_H_CVSID SMARTCTL_H_CVSID UTILITY_H_CVSID; // for passing global control variables @@ -2040,165 +2040,125 @@ int ataPrintMain (ata_device * device, const ata_print_options & options) } // Print SMART and/or GP log Directory and/or logs + // Get #pages for extended SMART logs + ata_smart_log_directory smartlogdir_buf, gplogdir_buf; + const ata_smart_log_directory * smartlogdir = 0, * gplogdir = 0; + if ( options.gp_logdir || options.smart_logdir || options.sataphy || options.smart_ext_error_log || options.smart_ext_selftest_log || !options.log_requests.empty() ) { - - bool gpl_cap = !!isGeneralPurposeLoggingCapable(&drive); - bool gpl_try = gpl_cap; - if (!gpl_try && con->permissive) { - con->permissive--; - gpl_try = true; + PRINT_ON(con); + if (isGeneralPurposeLoggingCapable(&drive)) + pout("General Purpose Logging (GPL) feature set supported\n"); + + // Detect directories needed + bool need_smart_logdir = options.smart_logdir; + bool need_gp_logdir = ( options.gp_logdir + || options.smart_ext_error_log + || options.smart_ext_selftest_log); + unsigned i; + for (i = 0; i < options.log_requests.size(); i++) { + if (options.log_requests[i].gpl) + need_gp_logdir = true; + else + need_smart_logdir = true; } - if (!gpl_try) { - pout("Device does not support General Purpose Loggin (GPL) feature set\n" - "(override with '-T permissive' option)\n"); - failuretest(OPTIONAL_CMD, returnval|=FAILSMART); - } - else { - PRINT_ON(con); - if (gpl_cap) - pout("General Purpose Logging (GPL) feature set supported\n"); - - // Detect directories needed - bool need_smart_logdir = options.smart_logdir; - bool need_gp_logdir = ( options.gp_logdir - || options.smart_ext_error_log - || options.smart_ext_selftest_log); - unsigned i; - for (i = 0; i < options.log_requests.size(); i++) { - if (options.log_requests[i].gpl) - need_gp_logdir = true; - else - need_smart_logdir = true; - } - - ata_smart_log_directory smartlogdir_buf, gplogdir_buf; - const ata_smart_log_directory * smartlogdir = 0, * gplogdir = 0; - - // Read SMART Log directory - if (need_smart_logdir) { - if (ataReadLogDirectory(device, &smartlogdir_buf, false)){ - PRINT_OFF(con); - pout("Read SMART Log Directory failed.\n\n"); - failuretest(OPTIONAL_CMD, returnval|=FAILSMART); - } - else - smartlogdir = &smartlogdir_buf; + // Read SMART Log directory + if (need_smart_logdir) { + if (ataReadLogDirectory(device, &smartlogdir_buf, false)){ + PRINT_OFF(con); + pout("Read SMART Log Directory failed.\n\n"); + failuretest(OPTIONAL_CMD, returnval|=FAILSMART); } - PRINT_ON(con); + else + smartlogdir = &smartlogdir_buf; + } + PRINT_ON(con); - // Read GP Log directory - if (need_gp_logdir) { - if (ataReadLogDirectory(device, &gplogdir_buf, true)){ - PRINT_OFF(con); - pout("Read GP Log Directory failed.\n\n"); - failuretest(OPTIONAL_CMD, returnval|=FAILSMART); - } - else - gplogdir = &gplogdir_buf; + // Read GP Log directory + if (need_gp_logdir) { + if (ataReadLogDirectory(device, &gplogdir_buf, true)){ + PRINT_OFF(con); + pout("Read GP Log Directory failed.\n\n"); + failuretest(OPTIONAL_CMD, returnval|=FAILSMART); } - PRINT_ON(con); + else + gplogdir = &gplogdir_buf; + } + PRINT_ON(con); - // Print log directories - if ((options.gp_logdir && gplogdir) || (options.smart_logdir && smartlogdir)) - PrintLogDirectories(gplogdir, smartlogdir); - PRINT_OFF(con); + // Print log directories + if ((options.gp_logdir && gplogdir) || (options.smart_logdir && smartlogdir)) + PrintLogDirectories(gplogdir, smartlogdir); + PRINT_OFF(con); - // Print log pages - for (i = 0; i < options.log_requests.size(); i++) { - const ata_log_request & req = options.log_requests[i]; + // Print log pages + for (i = 0; i < options.log_requests.size(); i++) { + const ata_log_request & req = options.log_requests[i]; - const char * type; - unsigned max_nsectors; - if (req.gpl) { - type = "General Purpose"; - max_nsectors = GetNumLogSectors(gplogdir, req.logaddr, true); - } - else { - type = "SMART"; - max_nsectors = GetNumLogSectors(smartlogdir, req.logaddr, false); - } + const char * type; + unsigned max_nsectors; + if (req.gpl) { + type = "General Purpose"; + max_nsectors = GetNumLogSectors(gplogdir, req.logaddr, true); + } + else { + type = "SMART"; + max_nsectors = GetNumLogSectors(smartlogdir, req.logaddr, false); + } - if (!max_nsectors) { - if (!con->permissive) { - pout("%s Log 0x%02x does not exist (override with '-T permissive' option)\n", type, req.logaddr); - continue; - } - con->permissive--; - max_nsectors = req.page+1; - } - if (max_nsectors <= req.page) { - pout("%s Log 0x%02x has only %u sectors, output skipped\n", type, req.logaddr, max_nsectors); + if (!max_nsectors) { + if (!con->permissive) { + pout("%s Log 0x%02x does not exist (override with '-T permissive' option)\n", type, req.logaddr); continue; } - - unsigned ns = req.nsectors; - if (ns > max_nsectors - req.page) { - if (req.nsectors != ~0U) // "FIRST-max" - pout("%s Log 0x%02x has only %u sectors, output truncated\n", type, req.logaddr, max_nsectors); - ns = max_nsectors - req.page; - } - - // SMART log don't support sector offset, start with first sector - unsigned offs = (req.gpl ? 0 : req.page); - - raw_buffer log_buf((offs + ns) * 512); - bool ok; - if (req.gpl) - ok = ataReadLogExt(device, req.logaddr, 0x00, req.page, log_buf.data(), ns); - else - ok = ataReadSmartLog(device, req.logaddr, log_buf.data(), offs + ns); - if (!ok) - failuretest(OPTIONAL_CMD, returnval|=FAILSMART); - else - PrintLogPages(type, log_buf.data() + offs*512, req.logaddr, req.page, ns, max_nsectors); + con->permissive--; + max_nsectors = req.page+1; } - - // Print SMART Extendend Comprehensive Error Log - if (options.smart_ext_error_log) { - unsigned nsectors = GetNumLogSectors(gplogdir, 0x03, true); - if (!nsectors) - pout("SMART Extended Comprehensive Error Log (GP Log 0x03) does not exist\n"); - else if (nsectors >= 256) - pout("SMART Extended Comprehensive Error Log size %u not supported\n", nsectors); - else { - raw_buffer log_03_buf(nsectors * 512); - ata_smart_exterrlog * log_03 = (ata_smart_exterrlog *)log_03_buf.data(); - if (!ataReadExtErrorLog(device, log_03, nsectors)) - failuretest(OPTIONAL_CMD, returnval|=FAILSMART); - else - PrintSmartExtErrorLog(log_03, nsectors, options.smart_ext_error_log); - } + if (max_nsectors <= req.page) { + pout("%s Log 0x%02x has only %u sectors, output skipped\n", type, req.logaddr, max_nsectors); + continue; } - // Print SMART Extendend Self-test Log - if (options.smart_ext_selftest_log) { - unsigned nsectors = GetNumLogSectors(gplogdir, 0x07, true); - if (!nsectors) - pout("SMART Extended Self-test Log (GP Log 0x07) does not exist\n"); - else if (nsectors >= 256) - pout("SMART Extended Self-test Log size %u not supported\n", nsectors); - else { - raw_buffer log_07_buf(nsectors * 512); - ata_smart_extselftestlog * log_07 = (ata_smart_extselftestlog *)log_07_buf.data(); - if (!ataReadExtSelfTestLog(device, log_07, nsectors)) - failuretest(OPTIONAL_CMD, returnval|=FAILSMART); - else - PrintSmartExtSelfTestLog(log_07, nsectors, options.smart_ext_selftest_log); - } - } - // Print SATA Phy Event Counters - if (options.sataphy) { - unsigned char log_11[512] = {0, }; - unsigned char features = (options.sataphy_reset ? 0x01 : 0x00); - if (!ataReadLogExt(device, 0x11, features, 0, log_11, 1)) - failuretest(OPTIONAL_CMD, returnval|=FAILSMART); - else - PrintSataPhyEventCounters(log_11, options.sataphy_reset); + unsigned ns = req.nsectors; + if (ns > max_nsectors - req.page) { + if (req.nsectors != ~0U) // "FIRST-max" + pout("%s Log 0x%02x has only %u sectors, output truncated\n", type, req.logaddr, max_nsectors); + ns = max_nsectors - req.page; } + + // SMART log don't support sector offset, start with first sector + unsigned offs = (req.gpl ? 0 : req.page); + + raw_buffer log_buf((offs + ns) * 512); + bool ok; + if (req.gpl) + ok = ataReadLogExt(device, req.logaddr, 0x00, req.page, log_buf.data(), ns); + else + ok = ataReadSmartLog(device, req.logaddr, log_buf.data(), offs + ns); + if (!ok) + failuretest(OPTIONAL_CMD, returnval|=FAILSMART); + else + PrintLogPages(type, log_buf.data() + offs*512, req.logaddr, req.page, ns, max_nsectors); + } + } + + // Print SMART Extendend Comprehensive Error Log + if (options.smart_ext_error_log) { + unsigned nsectors = GetNumLogSectors(gplogdir, 0x03, true); + if (!nsectors) + pout("SMART Extended Comprehensive Error Log (GP Log 0x03) does not exist\n"); + else if (nsectors >= 256) + pout("SMART Extended Comprehensive Error Log size %u not supported\n", nsectors); + else { + raw_buffer log_03_buf(nsectors * 512); + ata_smart_exterrlog * log_03 = (ata_smart_exterrlog *)log_03_buf.data(); + if (!ataReadExtErrorLog(device, log_03, nsectors)) + failuretest(OPTIONAL_CMD, returnval|=FAILSMART); + else + PrintSmartExtErrorLog(log_03, nsectors, options.smart_ext_error_log); } } @@ -2219,7 +2179,24 @@ int ataPrintMain (ata_device * device, const ata_print_options & options) PRINT_OFF(con); } } - + + // Print SMART Extendend Self-test Log + if (options.smart_ext_selftest_log) { + unsigned nsectors = GetNumLogSectors(gplogdir, 0x07, true); + if (!nsectors) + pout("SMART Extended Self-test Log (GP Log 0x07) does not exist\n"); + else if (nsectors >= 256) + pout("SMART Extended Self-test Log size %u not supported\n", nsectors); + else { + raw_buffer log_07_buf(nsectors * 512); + ata_smart_extselftestlog * log_07 = (ata_smart_extselftestlog *)log_07_buf.data(); + if (!ataReadExtSelfTestLog(device, log_07, nsectors)) + failuretest(OPTIONAL_CMD, returnval|=FAILSMART); + else + PrintSmartExtSelfTestLog(log_07, nsectors, options.smart_ext_selftest_log); + } + } + // Print SMART self-test log if (con->smartselftestlog){ if (!isSmartTestLogCapable(&smartval, &drive)){ @@ -2314,6 +2291,16 @@ int ataPrintMain (ata_device * device, const ata_print_options & options) } } + // Print SATA Phy Event Counters + if (options.sataphy) { + unsigned char log_11[512] = {0, }; + unsigned char features = (options.sataphy_reset ? 0x01 : 0x00); + if (!ataReadLogExt(device, 0x11, features, 0, log_11, 1)) + failuretest(OPTIONAL_CMD, returnval|=FAILSMART); + else + PrintSataPhyEventCounters(log_11, options.sataphy_reset); + } + // START OF THE TESTING SECTION OF THE CODE. IF NO TESTING, RETURN if (con->testcase==-1) return returnval; -- GitLab