From 7287b406427df952684258e471d8e9b7cd7c286f Mon Sep 17 00:00:00 2001 From: ballen4705 <ballen4705@4ea69e1a-61f1-4043-bf83-b5c94c648137> Date: Fri, 2 Apr 2004 05:57:40 +0000 Subject: [PATCH] Better format for Selective self-test log; improved man page for smartctl git-svn-id: https://smartmontools.svn.sourceforge.net/svnroot/smartmontools/trunk@1633 4ea69e1a-61f1-4043-bf83-b5c94c648137 --- sm5/ataprint.c | 103 ++++++++++++++++++++++++++++++---------------- sm5/ataprint.cpp | 103 ++++++++++++++++++++++++++++++---------------- sm5/smartctl.8.in | 90 +++++++++++++++++++++------------------- 3 files changed, 181 insertions(+), 115 deletions(-) diff --git a/sm5/ataprint.c b/sm5/ataprint.c index 5fefddbe8..4ba9dba67 100644 --- a/sm5/ataprint.c +++ b/sm5/ataprint.c @@ -35,7 +35,7 @@ #include "knowndrives.h" #include "config.h" -const char *ataprint_c_cvsid="$Id: ataprint.c,v 1.148 2004/03/29 00:26:03 ballen4705 Exp $" +const char *ataprint_c_cvsid="$Id: ataprint.c,v 1.149 2004/04/02 05:57:40 ballen4705 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 @@ -486,44 +486,44 @@ void ataPrintDriveInfo (struct ata_identify_device *drive){ } -/* prints verbose value Off-line data collection status byte */ -void PrintSmartOfflineStatus(struct ata_smart_values *data){ - char *message=NULL; - - // the final 7 bits - unsigned char stat=data->offline_data_collection_status & 0x7f; +const char *OfflineDataCollectionStatus(unsigned char status_byte){ + unsigned char stat=status_byte & 0x7f; - pout("Offline data collection status: (0x%02x)\t", - (int)data->offline_data_collection_status); - switch(stat){ case 0x00: - message="never started"; - break; + return "was never started"; case 0x02: - message="completed without error"; - break; + return "was completed without error"; + case 0x03: + if (status_byte == 0x03) + return "is in progress"; + else + return "is in a Reserved state"; case 0x04: - message="suspended by an interrupting command from host"; - break; + return "was suspended by an interrupting command from host"; case 0x05: - message="aborted by an interrupting command from host"; - break; + return "was aborted by an interrupting command from host"; case 0x06: - message="aborted by the device with a fatal error"; - break; + return "was aborted by the device with a fatal error"; default: if (stat >= 0x40) - pout("Vendor Specific.\n"); + return "is in a Vendor Specific state\n"; else - pout("Reserved.\n"); + return "is in a Reserved state\n"; } +} + + + /* prints verbose value Off-line data collection status byte */ + void PrintSmartOfflineStatus(struct ata_smart_values *data){ - if (message) - // Off-line data collection status byte is not a reserved - // or vendor specific value - pout("Offline data collection activity was\n" - "\t\t\t\t\t%s.\n", message); + pout("Offline data collection status: (0x%02x)\t", + (int)data->offline_data_collection_status); + + // Off-line data collection status byte is not a reserved + // or vendor specific value + pout("Offline data collection activity\n" + "\t\t\t\t\t%s.\n", OfflineDataCollectionStatus(data->offline_data_collection_status)); // Report on Automatic Data Collection Status. Only IBM documents // this bit. See SFF 8035i Revision 2 for details. @@ -1018,8 +1018,10 @@ int ataPrintSmartErrorlog(struct ata_smart_errorlog *data){ } void ataPrintSelectiveSelfTestLog(struct ata_selective_self_test_log *log, struct ata_smart_values *sv) { - int i; + int i,field1,field2; char *msg; + char tmp[64]; + uint64_t maxl=0,maxr=0; uint64_t current=log->currentlba; uint64_t currentend=current+65535; @@ -1053,23 +1055,52 @@ void ataPrintSelectiveSelfTestLog(struct ata_selective_self_test_log *log, struc break; } - // print the five test spans - pout("Span STARTING_LBA ENDING_LBA CURRENT_TEST_STATUS\n"); + // find the number of columns needed for printing + for (i=0; i<5; i++) { + uint64_t start=log->span[i].start; + uint64_t end =log->span[i].end; + + if (start>maxl) + maxl=start; + if (end > maxr) + maxr=end; + } + if (current>maxl) + maxl=current; + if (currentend>maxr) + maxr=currentend; + + // we need at least 7 characters wide fields to accomodate the + // labels + if ((field1=snprintf(tmp,64, "%"PRIu64, maxl))<7) + field1=7; + if ((field2=snprintf(tmp,64, "%"PRIu64, maxr))<7) + field2=7; + + // now print the five test spans + pout(" SPAN %*s %*s CURRENT_TEST_STATUS\n", field1, "MIN_LBA", field2, "MAX_LBA"); + for (i=0; i<5; i++) { uint64_t start=log->span[i].start; uint64_t end=log->span[i].end; if ((i+1)==(int)log->currentspan) // this span is currently under test - pout(" %d %20"PRIu64" %20"PRIu64" %s (%"PRIu64"-%"PRIu64")\n", - i+1, start, end, msg, current, currentend); + pout(" %d %*"PRIu64" %*"PRIu64" %s [%01d0%% left] (%"PRIu64"-%"PRIu64")\n", + i+1, field1, start, field2, end, msg, + (int)(sv->self_test_exec_status & 0x7), current, currentend); else // this span is not currently under test - pout(" %d %20"PRIu64" %20"PRIu64" Not_testing\n", i+1, start, end); + pout(" %d %*"PRIu64" %*"PRIu64" Not_testing\n", + i+1, field1, start, field2, end); } - if ((log->flags & SELECTIVE_FLAG_DOSCAN) && (log->flags & SELECTIVE_FLAG_ACTIVE) && log->currentspan>5) - pout("%4d %20"PRIu64" %20"PRIu64" Read_scanning\n", (int)log->currentspan, current, currentend); + // if we are currently read-scanning, print LBAs and the status of + // the read scan + if (log->currentspan>5) + pout("%5d %*"PRIu64" %*"PRIu64" Read_scanning %s\n", + (int)log->currentspan, field1, current, field2, currentend, + OfflineDataCollectionStatus(sv->offline_data_collection_status)); /* Print selective self-test flags. Possible flag combinations are (numbering bits from 0-15): @@ -1094,7 +1125,7 @@ void ataPrintSelectiveSelfTestLog(struct ata_selective_self_test_log *log, struc } else pout(" After scanning selected spans, do NOT read-scan remainder of disk.\n"); - + // print pending time pout("If Selective self-test is pending on power-up, resume after %d minute delay.\n", (int)log->pendingtime); diff --git a/sm5/ataprint.cpp b/sm5/ataprint.cpp index 656237010..09a4d440a 100644 --- a/sm5/ataprint.cpp +++ b/sm5/ataprint.cpp @@ -35,7 +35,7 @@ #include "knowndrives.h" #include "config.h" -const char *ataprint_c_cvsid="$Id: ataprint.cpp,v 1.148 2004/03/29 00:26:03 ballen4705 Exp $" +const char *ataprint_c_cvsid="$Id: ataprint.cpp,v 1.149 2004/04/02 05:57:40 ballen4705 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 @@ -486,44 +486,44 @@ void ataPrintDriveInfo (struct ata_identify_device *drive){ } -/* prints verbose value Off-line data collection status byte */ -void PrintSmartOfflineStatus(struct ata_smart_values *data){ - char *message=NULL; - - // the final 7 bits - unsigned char stat=data->offline_data_collection_status & 0x7f; +const char *OfflineDataCollectionStatus(unsigned char status_byte){ + unsigned char stat=status_byte & 0x7f; - pout("Offline data collection status: (0x%02x)\t", - (int)data->offline_data_collection_status); - switch(stat){ case 0x00: - message="never started"; - break; + return "was never started"; case 0x02: - message="completed without error"; - break; + return "was completed without error"; + case 0x03: + if (status_byte == 0x03) + return "is in progress"; + else + return "is in a Reserved state"; case 0x04: - message="suspended by an interrupting command from host"; - break; + return "was suspended by an interrupting command from host"; case 0x05: - message="aborted by an interrupting command from host"; - break; + return "was aborted by an interrupting command from host"; case 0x06: - message="aborted by the device with a fatal error"; - break; + return "was aborted by the device with a fatal error"; default: if (stat >= 0x40) - pout("Vendor Specific.\n"); + return "is in a Vendor Specific state\n"; else - pout("Reserved.\n"); + return "is in a Reserved state\n"; } +} + + + /* prints verbose value Off-line data collection status byte */ + void PrintSmartOfflineStatus(struct ata_smart_values *data){ - if (message) - // Off-line data collection status byte is not a reserved - // or vendor specific value - pout("Offline data collection activity was\n" - "\t\t\t\t\t%s.\n", message); + pout("Offline data collection status: (0x%02x)\t", + (int)data->offline_data_collection_status); + + // Off-line data collection status byte is not a reserved + // or vendor specific value + pout("Offline data collection activity\n" + "\t\t\t\t\t%s.\n", OfflineDataCollectionStatus(data->offline_data_collection_status)); // Report on Automatic Data Collection Status. Only IBM documents // this bit. See SFF 8035i Revision 2 for details. @@ -1018,8 +1018,10 @@ int ataPrintSmartErrorlog(struct ata_smart_errorlog *data){ } void ataPrintSelectiveSelfTestLog(struct ata_selective_self_test_log *log, struct ata_smart_values *sv) { - int i; + int i,field1,field2; char *msg; + char tmp[64]; + uint64_t maxl=0,maxr=0; uint64_t current=log->currentlba; uint64_t currentend=current+65535; @@ -1053,23 +1055,52 @@ void ataPrintSelectiveSelfTestLog(struct ata_selective_self_test_log *log, struc break; } - // print the five test spans - pout("Span STARTING_LBA ENDING_LBA CURRENT_TEST_STATUS\n"); + // find the number of columns needed for printing + for (i=0; i<5; i++) { + uint64_t start=log->span[i].start; + uint64_t end =log->span[i].end; + + if (start>maxl) + maxl=start; + if (end > maxr) + maxr=end; + } + if (current>maxl) + maxl=current; + if (currentend>maxr) + maxr=currentend; + + // we need at least 7 characters wide fields to accomodate the + // labels + if ((field1=snprintf(tmp,64, "%"PRIu64, maxl))<7) + field1=7; + if ((field2=snprintf(tmp,64, "%"PRIu64, maxr))<7) + field2=7; + + // now print the five test spans + pout(" SPAN %*s %*s CURRENT_TEST_STATUS\n", field1, "MIN_LBA", field2, "MAX_LBA"); + for (i=0; i<5; i++) { uint64_t start=log->span[i].start; uint64_t end=log->span[i].end; if ((i+1)==(int)log->currentspan) // this span is currently under test - pout(" %d %20"PRIu64" %20"PRIu64" %s (%"PRIu64"-%"PRIu64")\n", - i+1, start, end, msg, current, currentend); + pout(" %d %*"PRIu64" %*"PRIu64" %s [%01d0%% left] (%"PRIu64"-%"PRIu64")\n", + i+1, field1, start, field2, end, msg, + (int)(sv->self_test_exec_status & 0x7), current, currentend); else // this span is not currently under test - pout(" %d %20"PRIu64" %20"PRIu64" Not_testing\n", i+1, start, end); + pout(" %d %*"PRIu64" %*"PRIu64" Not_testing\n", + i+1, field1, start, field2, end); } - if ((log->flags & SELECTIVE_FLAG_DOSCAN) && (log->flags & SELECTIVE_FLAG_ACTIVE) && log->currentspan>5) - pout("%4d %20"PRIu64" %20"PRIu64" Read_scanning\n", (int)log->currentspan, current, currentend); + // if we are currently read-scanning, print LBAs and the status of + // the read scan + if (log->currentspan>5) + pout("%5d %*"PRIu64" %*"PRIu64" Read_scanning %s\n", + (int)log->currentspan, field1, current, field2, currentend, + OfflineDataCollectionStatus(sv->offline_data_collection_status)); /* Print selective self-test flags. Possible flag combinations are (numbering bits from 0-15): @@ -1094,7 +1125,7 @@ void ataPrintSelectiveSelfTestLog(struct ata_selective_self_test_log *log, struc } else pout(" After scanning selected spans, do NOT read-scan remainder of disk.\n"); - + // print pending time pout("If Selective self-test is pending on power-up, resume after %d minute delay.\n", (int)log->pendingtime); diff --git a/sm5/smartctl.8.in b/sm5/smartctl.8.in index 76a2624db..5ee7f350b 100644 --- a/sm5/smartctl.8.in +++ b/sm5/smartctl.8.in @@ -1,7 +1,7 @@ .ig Copyright (C) 2002-4 Bruce Allen <smartmontools-support@lists.sourceforge.net> - $Id: smartctl.8.in,v 1.40 2004/03/25 15:39:25 ballen4705 Exp $ + $Id: smartctl.8.in,v 1.41 2004/04/02 05:57:40 ballen4705 Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free @@ -517,54 +517,55 @@ some common types of errors, the Error Register (ER) and Status Register (SR) values are decoded and printed as text. The meanings of these are: .nf - \fBABRT\fP: Aborted - \fBAMNF\fP: Address Mark Not Found - \fBCCTO\fP: Command Completion Timed Out - \fBEOM\fP: End Of Media - \fBICRC\fP: Interface CRC error - \fBIDNF\fP: Id Not Found + \fBABRT\fP: Command \fBAB\fPo\fBRT\fPed + \fBAMNF\fP: \fBA\fPddress \fBM\fPark \fBN\fPot \fBF\fPound + \fBCCTO\fP: \fBC\fPommand \fBC\fPompletion \fBT\fPimed \fBO\fPut + \fBEOM\fP: \fBE\fPnd \fBO\fPf \fBM\fPedia + \fBICRC\fP: \fBI\fPnterface \fBC\fPyclic \fBR\fPedundancy \fBC\fPode (CRC) error + \fBIDNF\fP: \fBID\fPentity \fBN\fPot \fBF\fPound \fBILI\fP: (packet command-set specific) - \fBMC\fP: Media Changed - \fBMCR\fP: Media Change Request - \fBNM\fP: No Media - \fBobs\fP: Obsolete - \fBTK0NF\fP: Track 0 Not Found - \fBUNC\fP: Uncorrectable - \fBWP\fP: Write Protected + \fBMC\fP: \fBM\fPedia \fBC\fPhanged + \fBMCR\fP: \fBM\fPedia \fBC\fPhange \fBR\fPequest + \fBNM\fP: \fBN\fPo \fBM\fPedia + \fBobs\fP: \fBobs\fPolete + \fBTK0NF\fP: \fBT\fPrac\fBK 0 N\fPot \fBF\fPound + \fBUNC\fP: \fBUNC\fPorrectable Error in Data + \fBWP\fP: Media is \fBW\fPrite \fBP\fProtected .fi In addition, up to the last five commands that preceded the error are -listed, along with a timestamp measured in seconds from the start of -the corresponding power cycle. [Note: this time stamp wraps after -2^32 milliseconds, or 49 days 17 hours 2 minutes and 47.296 seconds.] -The key ATA disk registers are also recorded in the log. The final -column of the error log is a text-string description of the ATA -command defined by the Command Register (CR) and Feature Register (FR) -values. Commands that are obsolete in the most current (ATA-7) spec -are listed like this: \fBREAD LONG (w/ retry) [OBS-4]\fP, indicating -that the command became obsolete with or in the ATA-4 specification. -Similarly, the notation \fB[RET-\fP\fIN\fP\fB]\fP is used to indicate -that a command was retired in the ATA-\fIN\fP specification. Some -commands are not defined in any version of the ATA specification but -are in common use nonetheless; these are marked \fB[NS]\fP, meaning -non-standard. - - -The ATA Specification (ATA-5 Revision 1c, Section 8.41.6.8.2 to be -precise) says: -\fB"Error log structures shall include UNC errors, IDNF -errors for which the address requested was valid, servo errors, write -fault errors, etc. Error log data structures shall not include errors +listed, along with a timestamp measured from the start of the +corresponding power cycle. This is displayed in the form +Dd+HH:MM:SS.msec where D is the number of days, HH is hours, MM is +minutes, SS is seconds and msec is milliseconds. [Note: this time +stamp wraps after 2^32 milliseconds, or 49 days 17 hours 2 minutes and +47.296 seconds.] The key ATA disk registers are also recorded in the +log. The final column of the error log is a text-string description +of the ATA command defined by the Command Register (CR) and Feature +Register (FR) values. Commands that are obsolete in the most current +(ATA-7) spec are listed like this: \fBREAD LONG (w/ retry) [OBS-4]\fP, +indicating that the command became obsolete with or in the ATA-4 +specification. Similarly, the notation \fB[RET-\fP\fIN\fP\fB]\fP is +used to indicate that a command was retired in the ATA-\fIN\fP +specification. Some commands are not defined in any version of the +ATA specification but are in common use nonetheless; these are marked +\fB[NS]\fP, meaning non-standard. + +The ATA Specification (ATA-5 Revision 1c, Section 8.41.6.8.2) says: +\fB"Error log structures shall include UNC errors, IDNF errors for +which the address requested was valid, servo errors, write fault +errors, etc. Error log data structures shall not include errors attributed to the receipt of faulty commands such as command codes not implemented by the device or requests with invalid parameters or -invalid addresses."\fP -The definitions of these terms are: -.fi -\fBUNC\fP (\fBUNC\fPorrectable): data is uncorrectable. -.fi - +invalid addresses."\fP The definitions of these terms are: +.br +\fBUNC\fP (\fBUNC\fPorrectable): data is uncorrectable. This refers +to data which as been read from the disk, but for which the Error +Checking and Correction (ECC) codes are inconsistent. In effect, this +means that the data can not be read. +.br \fBIDNF\fP (\fBID N\fPot \fBF\fPound): user-accessible address could not be found. For READ LOG type commands, \fBIDNF\fP can also indicate -that a device data log structure checksum was incorrect. +that a device data log structure checksum was incorrect. If the command that caused the error was a READ or WRITE command, then the Logical Block Address (LBA) at which the error occured will be @@ -1131,4 +1132,7 @@ these documents may be found in the References section of the .SH CVS ID OF THIS PAGE: -$Id: smartctl.8.in,v 1.40 2004/03/25 15:39:25 ballen4705 Exp $ +$Id: smartctl.8.in,v 1.41 2004/04/02 05:57:40 ballen4705 Exp $ +.\" Local Variables: +.\" mode: nroff +.\" End: -- GitLab