From 26bd423dd62d90b53491b869e2c663581f7789ab Mon Sep 17 00:00:00 2001 From: chrfranke <chrfranke@4ea69e1a-61f1-4043-bf83-b5c94c648137> Date: Sat, 21 Jul 2007 20:59:41 +0000 Subject: [PATCH] Added '-F swapid' to fix ATA identify string byte ordering. Added '-q noserial' to suppress serial number output. git-svn-id: https://smartmontools.svn.sourceforge.net/svnroot/smartmontools/trunk@2417 4ea69e1a-61f1-4043-bf83-b5c94c648137 --- sm5/CHANGELOG | 5 ++++- sm5/atacmds.cpp | 41 ++++++++++++++++++++++++++++++++--------- sm5/ataprint.cpp | 32 ++++++++++++++------------------ sm5/extern.h | 4 +++- sm5/scsiprint.cpp | 36 +++++++++++++++++++----------------- sm5/smartctl.8.in | 18 +++++++++++++----- sm5/smartctl.cpp | 23 +++++++++++++++-------- 7 files changed, 100 insertions(+), 59 deletions(-) diff --git a/sm5/CHANGELOG b/sm5/CHANGELOG index ecb7bffcb..b53788111 100644 --- a/sm5/CHANGELOG +++ b/sm5/CHANGELOG @@ -1,6 +1,6 @@ CHANGELOG for smartmontools -$Id: CHANGELOG,v 1.623 2007/07/20 21:00:42 chrfranke Exp $ +$Id: CHANGELOG,v 1.624 2007/07/21 20:59:41 chrfranke Exp $ The most recent version of this file is: http://smartmontools.cvs.sourceforge.net/smartmontools/sm5/CHANGELOG?view=markup @@ -33,6 +33,9 @@ NOTES FOR FUTURE RELEASES: see TODO file. <DEVELOPERS: ADDITIONS TO THE CHANGE LOG GO JUST BELOW HERE, PLEASE> + [CF] smartctl: Added '-F swapid' to fix ATA identify string byte + ordering. Added '-q noserial' to suppress serial number output. + [CF] Windows: Added '/dev/n?st<n>' as alternate device names for SCSI tapes. These names are also used by Cygwin's /dev emulation layer. Thanks to Corinna Vinschen (Cygwin project lead) for pointing this diff --git a/sm5/atacmds.cpp b/sm5/atacmds.cpp index 740fb4bbc..a3af95fd9 100644 --- a/sm5/atacmds.cpp +++ b/sm5/atacmds.cpp @@ -36,7 +36,7 @@ #include "extern.h" #include "utility.h" -const char *atacmds_c_cvsid="$Id: atacmds.cpp,v 1.185 2007/07/18 21:18:09 chrfranke Exp $" +const char *atacmds_c_cvsid="$Id: atacmds.cpp,v 1.186 2007/07/21 20:59:41 chrfranke Exp $" ATACMDS_H_CVSID CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID SCSIATA_H_CVSID UTILITY_H_CVSID; // to hold onto exit code for atexit routine @@ -514,6 +514,25 @@ void swap8(char *location){ return; } +// Invalidate serial number and adjust checksum in IDENTIFY data +static void invalidate_serno(ata_identify_device * id){ + unsigned char sum = 0; + for (unsigned i = 0; i < sizeof(id->serial_no); i++) { + sum += id->serial_no[i]; sum -= id->serial_no[i] = 'X'; + } +#ifndef __NetBSD__ + bool must_swap = !!isbigendian(); + if (must_swap) + swapx(id->words088_255+255-88); +#endif + if ((id->words088_255[255-88] & 0x00ff) == 0x00a5) + id->words088_255[255-88] += sum << 8; +#ifndef __NetBSD__ + if (must_swap) + swapx(id->words088_255+255-88); +#endif +} + static char *commandstrings[]={ "SMART ENABLE", "SMART DISABLE", @@ -532,15 +551,15 @@ static char *commandstrings[]={ "WARNING (UNDEFINED COMMAND -- CONTACT DEVELOPERS AT " PACKAGE_BUGREPORT ")\n" }; -void prettyprint(unsigned char *stuff, char *name){ - int i,j; +static void prettyprint(const unsigned char *p, const char *name){ pout("\n===== [%s] DATA START (BASE-16) =====\n", name); - for (i=0; i<32; i++){ - pout("%03d-%03d: ", 16*i, 16*(i+1)-1); - for (j=0; j<15; j++) - pout("%02x ",*stuff++); - pout("%02x\n",*stuff++); - } + for (int i=0; i<512; i+=16, p+=16) + // print complete line to avoid slow tty output and extra lines in syslog. + pout("%03d-%03d: %02x %02x %02x %02x %02x %02x %02x %02x " + "%02x %02x %02x %02x %02x %02x %02x %02x\n", + i, i+16-1, + p[ 0], p[ 1], p[ 2], p[ 3], p[ 4], p[ 5], p[ 6], p[ 7], + p[ 8], p[ 9], p[10], p[11], p[12], p[13], p[14], p[15]); pout("===== [%s] DATA END (512 Bytes) =====\n\n", name); } @@ -621,6 +640,10 @@ int smartcommandhandler(int device, smart_command_set command, int select, char retval=ata_command_interface(device, command, select, data); } + // If requested, invalidate serial number before any printing is done + if ((command == IDENTIFY || command == PIDENTIFY) && !retval && con->dont_print_serial) + invalidate_serno((ata_identify_device *)data); + // If reporting is enabled, say what output was produced by the command if (con->reportataioctl){ if (errno) diff --git a/sm5/ataprint.cpp b/sm5/ataprint.cpp index 28a6f2008..72bef8942 100644 --- a/sm5/ataprint.cpp +++ b/sm5/ataprint.cpp @@ -41,7 +41,7 @@ #include "utility.h" #include "knowndrives.h" -const char *ataprint_c_cvsid="$Id: ataprint.cpp,v 1.182 2007/07/20 15:56:42 shattered Exp $" +const char *ataprint_c_cvsid="$Id: ataprint.cpp,v 1.183 2007/07/21 20:59:41 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 @@ -93,27 +93,25 @@ void trim(char *out, const char *in) // Convenience function for formatting strings from ata_identify_device void format_ata_string(char *out, const char *in, int n) { - char tmp[65]; - - n = n > 64 ? 64 : n; + bool must_swap = !con->fixswappedid; #ifndef __NetBSD__ - swapbytes(tmp, in, n); -#else /* NetBSD kernel delivers IDENTIFY data in host byte order (but all else is LE) */ if (isbigendian()) + must_swap = !must_swap; +#endif + + char tmp[65]; + n = n > 64 ? 64 : n; + if (!must_swap) strncpy(tmp, in, n); else swapbytes(tmp, in, n); -#endif tmp[n] = '\0'; trim(out, tmp); } -void infofound(char *output) { - if (*output) - pout("%s\n", output); - else - pout("[No Information Found]\n"); +static const char * infofound(const char *output) { + return (*output ? output : "[No Information Found]"); } @@ -532,12 +530,10 @@ int ataPrintDriveInfo (struct ata_identify_device *drive){ if (drivetype>=0 && knowndrives[drivetype].modelfamily) pout("Model Family: %s\n", knowndrives[drivetype].modelfamily); - pout("Device Model: "); - infofound(model); - pout("Serial Number: "); - infofound(serial); - pout("Firmware Version: "); - infofound(firm); + pout("Device Model: %s\n", infofound(model)); + if (!con->dont_print_serial) + pout("Serial Number: %s\n", infofound(serial)); + pout("Firmware Version: %s\n", infofound(firm)); if (determine_capacity(drive, capacity)) pout("User Capacity: %s bytes\n", capacity); diff --git a/sm5/extern.h b/sm5/extern.h index 69a1ac1c7..97e3bcfd3 100644 --- a/sm5/extern.h +++ b/sm5/extern.h @@ -25,7 +25,7 @@ #ifndef EXTERN_H_ #define EXTERN_H_ -#define EXTERN_H_CVSID "$Id: extern.h,v 1.52 2007/02/12 21:58:31 chrfranke Exp $\n" +#define EXTERN_H_CVSID "$Id: extern.h,v 1.53 2007/07/21 20:59:41 chrfranke Exp $\n" // Possible values for fixfirmwarebug. If user has NOT specified -F at // all, then value is 0. @@ -87,6 +87,7 @@ typedef struct smartmonctrl_s { unsigned char smartautosavedisable; unsigned char printing_switchable; unsigned char dont_print; + unsigned char dont_print_serial; unsigned char permissive; unsigned char conservative; unsigned char checksumfail; @@ -94,6 +95,7 @@ typedef struct smartmonctrl_s { unsigned char reportataioctl; unsigned char reportscsiioctl; unsigned char fixfirmwarebug; + unsigned char fixswappedid; unsigned char satpassthrulen; // Controller type (device type) has been specified explicitly unsigned char controller_explicit; diff --git a/sm5/scsiprint.cpp b/sm5/scsiprint.cpp index 4f7c5b372..6423ee7eb 100644 --- a/sm5/scsiprint.cpp +++ b/sm5/scsiprint.cpp @@ -3,11 +3,11 @@ * * Home page of code is: http://smartmontools.sourceforge.net * - * Copyright (C) 2002-6 Bruce Allen <smartmontools-support@lists.sourceforge.net> + * Copyright (C) 2002-7 Bruce Allen <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org> * * Additional SCSI work: - * Copyright (C) 2003-6 Douglas Gilbert <dougg@torque.net> + * Copyright (C) 2003-7 Douglas Gilbert <dougg@torque.net> * * 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 @@ -42,7 +42,7 @@ #define GBUF_SIZE 65535 -const char* scsiprint_c_cvsid="$Id: scsiprint.cpp,v 1.119 2006/11/12 04:47:23 dpgilbert Exp $" +const char* scsiprint_c_cvsid="$Id: scsiprint.cpp,v 1.120 2007/07/21 20:59:41 chrfranke Exp $" CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID SCSICMDS_H_CVSID SCSIPRINT_H_CVSID SMARTCTL_H_CVSID UTILITY_H_CVSID; // control block which points to external global control variables @@ -1069,20 +1069,22 @@ static int scsiGetDriveInfo(int device, UINT8 * peripheral_type, int all) } else modese_len = iec.modese_len; - if (0 == (err = scsiInquiryVpd(device, 0x80, gBuf, 64))) { - /* should use VPD page 0x83 and fall back to this page (0x80) - * if 0x83 not supported. NAA requires a lot of decoding code */ - len = gBuf[3]; - gBuf[4 + len] = '\0'; - pout("Serial number: %s\n", &gBuf[4]); - } - else if (con->reportscsiioctl > 0) { - PRINT_ON(con); - if (SIMPLE_ERR_BAD_RESP == err) - pout("Vital Product Data (VPD) bit ignored in INQUIRY\n"); - else - pout("Vital Product Data (VPD) INQUIRY failed [%d]\n", err); - PRINT_OFF(con); + if (!con->dont_print_serial) { + if (0 == (err = scsiInquiryVpd(device, 0x80, gBuf, 64))) { + /* should use VPD page 0x83 and fall back to this page (0x80) + * if 0x83 not supported. NAA requires a lot of decoding code */ + len = gBuf[3]; + gBuf[4 + len] = '\0'; + pout("Serial number: %s\n", &gBuf[4]); + } + else if (con->reportscsiioctl > 0) { + PRINT_ON(con); + if (SIMPLE_ERR_BAD_RESP == err) + pout("Vital Product Data (VPD) bit ignored in INQUIRY\n"); + else + pout("Vital Product Data (VPD) INQUIRY failed [%d]\n", err); + PRINT_OFF(con); + } } // print SCSI peripheral device type diff --git a/sm5/smartctl.8.in b/sm5/smartctl.8.in index 460b37c6f..ece6ffdf1 100644 --- a/sm5/smartctl.8.in +++ b/sm5/smartctl.8.in @@ -1,7 +1,7 @@ .ig Copyright (C) 2002-7 Bruce Allen <smartmontools-support@lists.sourceforge.net> - $Id: smartctl.8.in,v 1.98 2007/07/20 21:00:43 chrfranke Exp $ + $Id: smartctl.8.in,v 1.99 2007/07/21 20:59:41 chrfranke 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 @@ -195,6 +195,10 @@ which failed either now or in the past. .I silent \- print no output. The only way to learn about what was found is to use the exit status of \fBsmartctl\fP (see RETURN VALUES below). + +.I noserial +\- Do not print the serial number of the device. + .TP .B \-d TYPE, \-\-device=TYPE Specifies the type of the device. The valid arguments to this option @@ -925,9 +929,9 @@ value for Attribute 123 in this form. .TP .B \-F TYPE, \-\-firmwarebug=TYPE Modifies the behavior of \fBsmartctl\fP to compensate for some known -and understood device firmware bug. The arguments to this option are -exclusive, so that only the final option given is used. The valid -values are: +and understood device firmware or driver bug. Except \'swapid\', +the arguments to this option are exclusive, so that only the final +option given is used. The valid values are: .I none \- Assume that the device firmware obeys the ATA specifications. This @@ -964,6 +968,10 @@ Note that an explicit \'\-F\' option on the command line will over\-ride any preset values for \'\-F\' (see the \'\-P\' option below). +.I swapid +\- Fixes byte swapped ATA identify strings (device name, serial number, +firmware version) returned by some buggy device drivers. + .TP .B \-P TYPE, \-\-presets=TYPE Specifies whether \fBsmartctl\fP should use any preset options that @@ -1477,7 +1485,7 @@ these documents may be found in the References section of the .SH CVS ID OF THIS PAGE: -$Id: smartctl.8.in,v 1.98 2007/07/20 21:00:43 chrfranke Exp $ +$Id: smartctl.8.in,v 1.99 2007/07/21 20:59:41 chrfranke Exp $ .\" Local Variables: .\" mode: nroff .\" End: diff --git a/sm5/smartctl.cpp b/sm5/smartctl.cpp index bce6e3e11..2fdbec905 100644 --- a/sm5/smartctl.cpp +++ b/sm5/smartctl.cpp @@ -50,7 +50,7 @@ extern const char *os_solaris_ata_s_cvsid; #endif extern const char *atacmdnames_c_cvsid, *atacmds_c_cvsid, *ataprint_c_cvsid, *knowndrives_c_cvsid, *os_XXXX_c_cvsid, *scsicmds_c_cvsid, *scsiprint_c_cvsid, *utility_c_cvsid; -const char* smartctl_c_cvsid="$Id: smartctl.cpp,v 1.164 2007/07/09 01:57:31 ballen4705 Exp $" +const char* smartctl_c_cvsid="$Id: smartctl.cpp,v 1.165 2007/07/21 20:59:41 chrfranke Exp $" ATACMDS_H_CVSID ATAPRINT_H_CVSID CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID KNOWNDRIVES_H_CVSID SCSICMDS_H_CVSID SCSIPRINT_H_CVSID SMARTCTL_H_CVSID UTILITY_H_CVSID; // This is a block containing all the "control variables". We declare @@ -141,7 +141,7 @@ void Usage (void){ #ifdef HAVE_GETOPT_LONG printf( " -q TYPE, --quietmode=TYPE (ATA)\n" -" Set smartctl quiet mode to one of: errorsonly, silent\n\n" +" Set smartctl quiet mode to one of: errorsonly, silent, noserial\n\n" " -d TYPE, --device=TYPE\n" " Specify device type to one of: ata, scsi, marvell, sat, 3ware,N\n\n" " -T TYPE, --tolerance=TYPE (ATA)\n" @@ -155,9 +155,10 @@ void Usage (void){ ); #else printf( -" -q TYPE Set smartctl quiet mode to one of: errorsonly, silent (ATA)\n" +" -q TYPE Set smartctl quiet mode to one of: errorsonly, silent, (ATA)\n" +" noserial\n" " -d TYPE Specify device type to one of: ata, scsi, 3ware,N\n" -" -T TYPE Tolerance: normal, conservative,permissive,verypermissive (ATA\n" +" -T TYPE Tolerance: normal, conservative,permissive,verypermissive (ATA)\n" " -b TYPE Set action on bad checksum to one of: warn, exit, ignore (ATA)\n" " -r TYPE Report transactions (see man page)\n" " -n MODE No check if: never, sleep, standby, idle (see man page) (ATA)\n\n" @@ -195,7 +196,8 @@ void Usage (void){ " -v N,OPTION , --vendorattribute=N,OPTION (ATA)\n" " Set display OPTION for vendor Attribute N (see man page)\n\n" " -F TYPE, --firmwarebug=TYPE (ATA)\n" -" Use firmware bug workaround: none, samsung, samsung2, samsung3\n\n" +" Use firmware bug workaround: none, samsung, samsung2,\n" +" samsung3, swapid\n\n" " -P TYPE, --presets=TYPE (ATA)\n" " Drive-specific presets: use, ignore, show, showall\n\n" ); @@ -207,7 +209,8 @@ void Usage (void){ " -l TYPE Show device log. TYPE: error, selftest, selective, directory,\n" " background, scttemp[sts,hist]\n" " -v N,OPT Set display OPTion for vendor Attribute N (see man page) (ATA)\n" -" -F TYPE Use firmware bug workaround: none, samsung, samsung[23] (ATA)\n" +" -F TYPE Use firmware bug workaround: none, samsung, samsung2, (ATA)\n" +" samsung3, swapid\n" " -P TYPE Drive-specific presets: use, ignore, show, showall (ATA)\n\n" ); #endif @@ -239,7 +242,7 @@ void Usage (void){ const char *getvalidarglist(char opt) { switch (opt) { case 'q': - return "errorsonly, silent"; + return "errorsonly, silent, noserial"; case 'd': return "ata, scsi, marvell, sat, 3ware,N, hpt,L/M/N cciss,N"; case 'T': @@ -259,7 +262,7 @@ const char *getvalidarglist(char opt) { case 't': return "offline, short, long, conveyance, select,M-N, pending,N, afterselect,[on|off], scttempint,N[,p]"; case 'F': - return "none, samsung, samsung2, samsung3"; + return "none, samsung, samsung2, samsung3, swapid"; case 'n': return "never, sleep, standby, idle"; case 'v': @@ -370,6 +373,8 @@ void ParseOpts (int argc, char** argv){ } else if (!strcmp(optarg,"silent")) { con->printing_switchable = FALSE; con->dont_print = TRUE; + } else if (!strcmp(optarg,"noserial")) { + con->dont_print_serial = TRUE; } else { badarg = TRUE; } @@ -592,6 +597,8 @@ void ParseOpts (int argc, char** argv){ con->fixfirmwarebug = FIX_SAMSUNG2; } else if (!strcmp(optarg,"samsung3")) { con->fixfirmwarebug = FIX_SAMSUNG3; + } else if (!strcmp(optarg,"swapid")) { + con->fixswappedid = TRUE; } else { badarg = TRUE; } -- GitLab