Imported Upstream version 5.39.1+svn3124

This commit is contained in:
Giuseppe Iuculano 2010-07-13 12:51:24 +02:00
parent 7f0798ef6f
commit e9583e0c22
40 changed files with 1715 additions and 741 deletions

View File

@ -1,4 +1,4 @@
$Id: AUTHORS,v 1.22 2008/09/23 23:55:29 jharg Exp $ $Id: AUTHORS 3096 2010-04-30 14:32:49Z chrfranke $
This code was originally developed as a Senior Thesis by Michael This code was originally developed as a Senior Thesis by Michael
Cornwell at the Concurrent Systems Laboratory (now part of the Storage Cornwell at the Concurrent Systems Laboratory (now part of the Storage
@ -17,7 +17,7 @@ Peter Cassidy <pcassidy@mac.com>
Casper Dik <casper@holland.sun.com> Casper Dik <casper@holland.sun.com>
Christian Franke <franke@computer.org> Christian Franke <franke@computer.org>
Guilhem Frézou <guilhem.frezou@catii.fr> Guilhem Frézou <guilhem.frezou@catii.fr>
Douglas Gilbert <dougg@torque.net> Douglas Gilbert <dgilbert@interlog.com>
Guido Guenther <agx@sigxcpu.org> Guido Guenther <agx@sigxcpu.org>
Geoff Keating <geoffk@geoffk.org> Geoff Keating <geoffk@geoffk.org>
Dr. David Kirkby <drkirkby@ntlworld.com> Dr. David Kirkby <drkirkby@ntlworld.com>

123
CHANGELOG
View File

@ -1,6 +1,6 @@
CHANGELOG for smartmontools CHANGELOG for smartmontools
$Id: CHANGELOG 3077 2010-03-16 20:48:06Z chrfranke $ $Id: CHANGELOG 3124 2010-07-12 19:21:00Z chrfranke $
The most recent version of this file is: The most recent version of this file is:
http://smartmontools.svn.sourceforge.net/viewvc/smartmontools/trunk/smartmontools/CHANGELOG?view=markup http://smartmontools.svn.sourceforge.net/viewvc/smartmontools/trunk/smartmontools/CHANGELOG?view=markup
@ -43,6 +43,127 @@ NOTES FOR FUTURE RELEASES: see TODO file.
<DEVELOPERS: ADDITIONS TO THE CHANGE LOG GO JUST BELOW HERE, PLEASE> <DEVELOPERS: ADDITIONS TO THE CHANGE LOG GO JUST BELOW HERE, PLEASE>
[CF] drivedb.h USB updates:
- Iomega LDHD-UP (ticket #83)
- WD Elements Desktop 2TB
- Maxtor OneTouch (0x0d49:0x7300)
[MS] drivedb.h updates:
- Intel X25-M SSD first Generation
- ExcelStor J8160
- OCZ Agility2
[CF] drivedb.h updates:
- Transcend Solid State Drives (ticket #80)
[CF] drivedb.h USB update:
- LaCie Rugged Hard Drive
[CF] smartctl: Add options '--scan, --scan-open'.
[CF] Windows: Use also VendorId from IOCTL_STORAGE_QUERY_PROPERTY.
[CF] smartd: Change defaults of '-C' and '-U' directives to 0 (disabled)
if attribute name is changed by '-v 19[78],...' directive.
[CF] configure.in: Fix include path for MinGW.
[CF] Move 'posix/reg*' to 'regex/reg*'.
Add configure check for regex.
[MS] cciss.cpp: avoid redefining be32toh
megaraid.h: replace use of undefined preprocessor macro BITS_PER_LONG
by union construct (thanks to [DL]).
Add assert for sizeof(ptr_t) == 8 (thanks to [CF]).
[CF] Makefile.am: Add os_qnxnto.* to EXTRA_smart*_SOURCES.
[MS] drivedb.h update:
- WD My Passport Essential SE 1TB variant (USB interface)
[CF] Use getopt_long() from getopt/getopt* if necessary.
Add missing cast to os_qnxnto.cpp.
This fixes build on QNX (ticket #1).
Thanks to Stefan (stevestereo) for testing.
[CF] drivedb.h update:
- WD Caviar Green (Adv. Format) family
[CF] drivedb.h USB update:
- Verbatim External Hard Drive 47519
[DL] Fix regression in smartctl option '-t select,M-N' which prevents
that more than one test span can be specified (ticket #75).
[CF] drivedb.h updates:
- Add raw64 attributes 1, 210-213 to all SSD drives with
64-bit attribute format.
[CF] Support smartd '-l xerror' also for disks which use reserved
byte as log index.
[CF] Fix initialization of values missing in smartd '.state' files.
[CF] Add smartd directive '-l xerror' to check error count from
the Extended Comprehensive SMART Error Log (ticket #34).
[CF] Fix max number of cciss devices, 128 devices are supported
again (ticket #49). Regression was introduced during migration
to new interface.
[CF] Update man pages (include Debian patch
60_remove-redhatism.diff and Debian Bug 570892).
[CF] Add SVN revision number to man pages.
[CF] Windows: Read default drivedb.h and smartd.conf from exe
directory instead of current directory.
[CF] drivedb.h update:
- SAMSUNG SpinPoint M series
[CF] Replace runtime check of byte ordering by compile time check.
[CF] drivedb.h USB updates:
- ALi M5621 (unsupported)
- LaCie with JMicron (ticket #69)
- JMicron (0x2352)
- Enable 48-bit commands for Hitachi drive
[CF] Read USB ID info from drivedb.h (ticket #44).
[CF] Create branch RELEASE_5_39_DRIVEDB with last drivedb.h file
compatible with smartmontools 5.39[.1].
[MS] drivedb.h updates:
- WD Raptor 80GB variant
- correct Regex for some WD AV-GP variants
- Hitachi Ultrastar A7K2000
- Hitachi Travelstar 5K500.B
- Hitachi Deskstar 7K1000.C
- adjust naming of Hitachi Travelstar and Deskstar drives
[CF] Move 'posix/getopt*' to 'getopt/getopt*'. Can be used for
platforms with regex() but without getopt_long() (QNX, ticket #1).
[CF] smartd '-l selftest' directive: Print info if error count
decreased. Avoid misleading warning if error count decreased
to zero (ticket #67).
[CF] smartctl: Rework ataPrintMain(). Issue ATA SMART commands only if
necessary. Improve handling of SMART STATUS command failure when
ATA output registers are missing (ticket #27).
[CF] USB ID updates:
- A-DATA SH93
- Hitachi/SimpleTech 1TB
[CF] configure.in: Print configuration summary.
[CF] smartctl -l xselftest,selftest: Print old log if extended self-test
log index is out of range. Workaround for bad log data from Intel
X25-M G2 (ticket #66).
[CF] USB ID updates: [CF] USB ID updates:
- LaCie Desktop Hard Drive - LaCie Desktop Hard Drive
- Prolific PL2507 (unsupported) - Prolific PL2507 (unsupported)

View File

@ -1,6 +1,6 @@
## Process this file with automake to produce Makefile.in ## Process this file with automake to produce Makefile.in
# #
# $Id: Makefile.am 3074 2010-03-05 23:00:30Z chrfranke $ # $Id: Makefile.am 3115 2010-06-02 17:23:05Z chrfranke $
# #
@SET_MAKE@ @SET_MAKE@
@ -22,6 +22,13 @@ if ENABLE_ATTRIBUTELOG
AM_CPPFLAGS += -DSMARTMONTOOLS_ATTRIBUTELOG='"$(attributelog)"' AM_CPPFLAGS += -DSMARTMONTOOLS_ATTRIBUTELOG='"$(attributelog)"'
endif endif
if NEED_GETOPT_LONG
AM_CPPFLAGS += -I$(srcdir)/getopt -DHAVE_GETOPT_LONG -D__GNU_LIBRARY__
endif
if NEED_REGEX
AM_CPPFLAGS += -I$(srcdir)/regex
endif
sbin_PROGRAMS = smartd \ sbin_PROGRAMS = smartd \
smartctl smartctl
@ -64,6 +71,8 @@ EXTRA_smartd_SOURCES = os_darwin.cpp \
os_netbsd.h \ os_netbsd.h \
os_openbsd.cpp \ os_openbsd.cpp \
os_openbsd.h \ os_openbsd.h \
os_qnxnto.cpp \
os_qnxnto.h \
os_solaris.cpp \ os_solaris.cpp \
os_solaris.h \ os_solaris.h \
os_solaris_ata.s \ os_solaris_ata.s \
@ -79,21 +88,12 @@ EXTRA_smartd_SOURCES = os_darwin.cpp \
if OS_WIN32_MINGW if OS_WIN32_MINGW
smartd_SOURCES += \ smartd_SOURCES += \
posix/regex.h \
posix/regex.c \
os_win32/daemon_win32.h \
os_win32/daemon_win32.cpp \ os_win32/daemon_win32.cpp \
os_win32/hostname_win32.h \ os_win32/daemon_win32.h \
os_win32/hostname_win32.cpp \ os_win32/hostname_win32.cpp \
os_win32/syslog.h \ os_win32/hostname_win32.h \
os_win32/syslog_win32.cpp os_win32/syslog_win32.cpp \
os_win32/syslog.h
# Included by regex.c:
EXTRA_smartd_SOURCES += \
posix/regcomp.c \
posix/regexec.c \
posix/regex_internal.c \
posix/regex_internal.h
endif endif
@ -135,6 +135,8 @@ EXTRA_smartctl_SOURCES = os_linux.cpp \
os_netbsd.h \ os_netbsd.h \
os_openbsd.cpp \ os_openbsd.cpp \
os_openbsd.h \ os_openbsd.h \
os_qnxnto.cpp \
os_qnxnto.h \
os_solaris.cpp \ os_solaris.cpp \
os_solaris.h \ os_solaris.h \
os_win32.cpp \ os_win32.cpp \
@ -145,19 +147,42 @@ EXTRA_smartctl_SOURCES = os_linux.cpp \
dev_legacy.cpp \ dev_legacy.cpp \
megaraid.h megaraid.h
if OS_WIN32_MINGW if NEED_GETOPT_LONG
smartctl_SOURCES += \ smartctl_SOURCES += \
posix/regex.h \ getopt/getopt.c \
posix/regex.c \ getopt/getopt.h \
os_win32/syslog.h getopt/getopt1.c
smartd_SOURCES += \
getopt/getopt.c \
getopt/getopt.h \
getopt/getopt1.c
endif
if NEED_REGEX
smartctl_SOURCES += \
regex/regex.c \
regex/regex.h \
regex/regex_internal.h
smartd_SOURCES += \
regex/regex.c \
regex/regex.h \
regex/regex_internal.h
# Included by regex.c: # Included by regex.c:
EXTRA_smartctl_SOURCES += \ EXTRA_smartctl_SOURCES += \
posix/regcomp.c \ regex/regcomp.c \
posix/regexec.c \ regex/regexec.c \
posix/regex_internal.c \ regex/regex_internal.c
posix/regex_internal.h
EXTRA_smartd_SOURCES += \
regex/regcomp.c \
regex/regexec.c \
regex/regex_internal.c
endif endif
@ -442,13 +467,13 @@ MAN_ATTRIBUTELOG = sed '/BEGIN ENABLE_ATTRIBUTELOG/,/END ENABLE_ATTRIBUTELOG/d'
endif endif
MAN_FILTER = \ MAN_FILTER = \
sed "s|CURRENT_CVS_VERSION|$(releaseversion)|g; \ sed "s|CURRENT_SVN_VERSION|$(releaseversion)|g; \
s|CURRENT_CVS_DATE|`sed -n 's,^.*DATE[^"]*"\([^"]*\)".*$$,\1,p' svnversion.h`|g; \ s|CURRENT_SVN_DATE|`sed -n 's,^.*DATE[^"]*"\([^"]*\)".*$$,\1,p' svnversion.h`|g; \
s|CURRENT_CVS_TIME|`sed -n 's,^.*TIME[^"]*"\([^"]*\)".*$$,\1,p' svnversion.h`|g; \ s|CURRENT_SVN_REV|`sed -n 's,^.*REV[^"]*"\([^"]*\)".*$$,r\1,p' svnversion.h`|g; \
s|/usr/local/share/man/|$(mandir)/|g; \ s|/usr/local/share/man/|$(mandir)/|g; \
s|/usr/local/sbin/|$(sbindir)/|g; \ s|/usr/local/sbin/|$(sbindir)/|g; \
s|/usr/local/etc/rc\\.d/init.d/|$(initddir)/|g; \ s|/usr/local/etc/rc\\.d/init.d/|$(initddir)/|g; \
s|/usr/local/share/doc/smartmontools-5.1/|$(docsdir)/|g; \ s|/usr/local/share/doc/smartmontools/|$(docsdir)/|g; \
s|/usr/local/etc/smartd\\.conf|$(sysconfdir)/smartd.conf|g; \ s|/usr/local/etc/smartd\\.conf|$(sysconfdir)/smartd.conf|g; \
s|/usr/local/etc/smart_drivedb\\.h|$(sysconfdir)/smart_drivedb\\.h|g" | \ s|/usr/local/etc/smart_drivedb\\.h|$(sysconfdir)/smart_drivedb\\.h|g" | \
$(MAN_CAPABILITIES) | \ $(MAN_CAPABILITIES) | \

8
NEWS
View File

@ -1,6 +1,6 @@
smartmontools NEWS smartmontools NEWS
------------------ ------------------
$Id: NEWS 3076 2010-03-12 22:23:08Z chrfranke $ $Id: NEWS 3119 2010-06-11 16:21:25Z chrfranke $
The most up-to-date version of this file is: The most up-to-date version of this file is:
http://smartmontools.svn.sourceforge.net/viewvc/smartmontools/trunk/smartmontools/NEWS?view=markup http://smartmontools.svn.sourceforge.net/viewvc/smartmontools/trunk/smartmontools/NEWS?view=markup
@ -13,13 +13,19 @@ Summary: smartmontools release 5.40
- configure: New default value for '--with-docdir'. - configure: New default value for '--with-docdir'.
- Drive database is in a separate source file 'drivedb.h' - Drive database is in a separate source file 'drivedb.h'
which can be downloaded from SVN. which can be downloaded from SVN.
- USB ID info is now included in 'drivedb.h'.
- New script 'update-smart-drivedb'. - New script 'update-smart-drivedb'.
- smartd libcap-ng support, option '-C, --capabilities'. - smartd libcap-ng support, option '-C, --capabilities'.
- smartd directive '-l xerror' to check Extended Comprehensive
SMART Error Log.
- smartctl option '-l scterc[,...]' to get/set the - smartctl option '-l scterc[,...]' to get/set the
SCT Error Recovery Control time limit. SCT Error Recovery Control time limit.
- smartctl options '--scan, --scan-open'.
- Linux: Add '/dev/sd[a-c][a-z]' to smartd DEVICESCAN. - Linux: Add '/dev/sd[a-c][a-z]' to smartd DEVICESCAN.
- Windows: Read 'drivedb.h' and 'smartd.conf' from exe directory.
- Windows: Support for 64-bit executables. - Windows: Support for 64-bit executables.
- Windows: Support for cross compilation on Linux. - Windows: Support for cross compilation on Linux.
- Fix regression in smartctl option '-t select,M-N'.
- Fix SCT temperature table commands on big endian CPUs. - Fix SCT temperature table commands on big endian CPUs.
Date 2010-01-28 Date 2010-01-28

View File

@ -37,7 +37,7 @@
#include "utility.h" #include "utility.h"
#include "dev_ata_cmd_set.h" // for parsed_ata_device #include "dev_ata_cmd_set.h" // for parsed_ata_device
const char * atacmds_cpp_cvsid = "$Id: atacmds.cpp 3065 2010-02-10 22:16:50Z chrfranke $" const char * atacmds_cpp_cvsid = "$Id: atacmds.cpp 3117 2010-06-08 15:41:04Z chrfranke $"
ATACMDS_H_CVSID; ATACMDS_H_CVSID;
// for passing global control variables // for passing global control variables
@ -153,7 +153,13 @@ unsigned char get_unc_attr_id(bool offline, const ata_vendor_attr_defs & defs,
bool & increase) bool & increase)
{ {
unsigned char id = (!offline ? 197 : 198); unsigned char id = (!offline ? 197 : 198);
increase = !!(defs[id].flags & ATTRFLAG_INCREASING); const ata_vendor_attr_defs::entry & def = defs[id];
if (def.flags & ATTRFLAG_INCREASING)
increase = true; // '-v 19[78],increasing' option
else if (def.name.empty() || (id == 198 && def.name == "Offline_Scan_UNC_SectCt"))
increase = false; // no or '-v 198,offlinescanuncsectorct' option
else
id = 0; // other '-v 19[78],...' option
return id; return id;
} }
@ -223,7 +229,7 @@ const char * map_old_vendor_opts[][2] = {
{"194,10xCelsius" , "194,temp10x,Temperature_Celsius_x10"}, {"194,10xCelsius" , "194,temp10x,Temperature_Celsius_x10"},
{"194,unknown" , "194,raw48,Unknown_Attribute"}, {"194,unknown" , "194,raw48,Unknown_Attribute"},
{"197,increasing" , "197,raw48+,Total_Pending_Sectors"}, // '+' sets flag {"197,increasing" , "197,raw48+,Total_Pending_Sectors"}, // '+' sets flag
{"198,offlinescanuncsectorct" , "198,raw48,Offline_Scan_UNC_SectCt"}, {"198,offlinescanuncsectorct" , "198,raw48,Offline_Scan_UNC_SectCt"}, // see also get_unc_attr_id() above
{"198,increasing" , "198,raw48+,Total_Offl_Uncorrectabl"}, // '+' sets flag {"198,increasing" , "198,raw48+,Total_Offl_Uncorrectabl"}, // '+' sets flag
{"200,writeerrorcount" , "200,raw48,Write_Error_Count"}, {"200,writeerrorcount" , "200,raw48,Write_Error_Count"},
{"201,detectedtacount" , "201,raw48,Detected_TA_Count"}, {"201,detectedtacount" , "201,raw48,Detected_TA_Count"},

View File

@ -44,7 +44,7 @@
#include "utility.h" #include "utility.h"
#include "knowndrives.h" #include "knowndrives.h"
const char * ataprint_cpp_cvsid = "$Id: ataprint.cpp 3065 2010-02-10 22:16:50Z chrfranke $" const char * ataprint_cpp_cvsid = "$Id: ataprint.cpp 3081 2010-04-03 19:39:11Z chrfranke $"
ATAPRINT_H_CVSID; ATAPRINT_H_CVSID;
// for passing global control variables // for passing global control variables
@ -1392,7 +1392,7 @@ static int PrintSmartExtErrorLog(const ata_smart_exterrlog * log,
} }
// Print SMART Extended Self-test Log (GP Log 0x07) // Print SMART Extended Self-test Log (GP Log 0x07)
static void PrintSmartExtSelfTestLog(const ata_smart_extselftestlog * log, static bool PrintSmartExtSelfTestLog(const ata_smart_extselftestlog * log,
unsigned nsectors, unsigned max_entries) unsigned nsectors, unsigned max_entries)
{ {
pout("SMART Extended Self-test Log Version: %u (%u sectors)\n", pout("SMART Extended Self-test Log Version: %u (%u sectors)\n",
@ -1400,7 +1400,7 @@ static void PrintSmartExtSelfTestLog(const ata_smart_extselftestlog * log,
if (!log->log_desc_index){ if (!log->log_desc_index){
pout("No self-tests have been logged. [To run self-tests, use: smartctl -t]\n\n"); pout("No self-tests have been logged. [To run self-tests, use: smartctl -t]\n\n");
return; return true;
} }
// Check index // Check index
@ -1408,7 +1408,7 @@ static void PrintSmartExtSelfTestLog(const ata_smart_extselftestlog * log,
unsigned logidx = log->log_desc_index; unsigned logidx = log->log_desc_index;
if (logidx > nentries) { if (logidx > nentries) {
pout("Invalid Self-test Log index = 0x%04x (reserved = 0x%02x)\n", logidx, log->reserved1); pout("Invalid Self-test Log index = 0x%04x (reserved = 0x%02x)\n", logidx, log->reserved1);
return; return false;
} }
// Index base is not clearly specified by ATA8-ACS (T13/1699-D Revision 6a), // Index base is not clearly specified by ATA8-ACS (T13/1699-D Revision 6a),
@ -1443,6 +1443,7 @@ static void PrintSmartExtSelfTestLog(const ata_smart_extselftestlog * log,
false /*!print_error_only*/, print_header); false /*!print_error_only*/, print_header);
} }
pout("\n"); pout("\n");
return true;
} }
static void ataPrintSelectiveSelfTestLog(const ata_selective_self_test_log * log, const ata_smart_values * sv) static void ataPrintSelectiveSelfTestLog(const ata_selective_self_test_log * log, const ata_smart_values * sv)
@ -1740,20 +1741,13 @@ void failuretest(int type, int returnvalue){
EXIT(returnvalue|FAILCMD); EXIT(returnvalue|FAILCMD);
} }
// Initialize to zero just in case some SMART routines don't work
static ata_identify_device drive;
static ata_smart_values smartval;
static ata_smart_thresholds_pvt smartthres;
static ata_smart_errorlog smarterror;
static ata_smart_selftestlog smartselftest;
int ataPrintMain (ata_device * device, const ata_print_options & options) int ataPrintMain (ata_device * device, const ata_print_options & options)
{ {
int timewait,code; int returnval = 0;
int returnval=0, retid=0, supported=0, needupdate=0;
const char * powername = 0; char powerchg = 0;
// If requested, check power mode first // If requested, check power mode first
const char * powername = 0;
bool powerchg = false;
if (options.powermode) { if (options.powermode) {
unsigned char powerlimit = 0xff; unsigned char powerlimit = 0xff;
int powermode = ataCheckPowerMode(device); int powermode = ataCheckPowerMode(device);
@ -1783,8 +1777,39 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
} }
} }
// SMART values needed ?
bool need_smart_val = (
options.smart_check_status
|| options.smart_general_values
|| options.smart_vendor_attrib
|| options.smart_error_log
|| options.smart_selftest_log
|| options.smart_selective_selftest_log
|| options.smart_ext_error_log
|| options.smart_ext_selftest_log
|| options.smart_auto_offl_enable
|| options.smart_auto_offl_disable
|| options.smart_selftest_type != -1
);
// SMART must be enabled ?
bool need_smart_enabled = (
need_smart_val
|| options.smart_auto_save_enable
|| options.smart_auto_save_disable
);
// SMART feature set needed ?
bool need_smart_support = (
need_smart_enabled
|| options.smart_enable
|| options.smart_disable
);
// Start by getting Drive ID information. We need this, to know if SMART is supported. // Start by getting Drive ID information. We need this, to know if SMART is supported.
if ((retid=ataReadHDIdentity(device,&drive))<0){ ata_identify_device drive; memset(&drive, 0, sizeof(drive));
int retid = ataReadHDIdentity(device,&drive);
if (retid < 0) {
pout("Smartctl: Device Read Identity Failed (not an ATA/ATAPI device)\n\n"); pout("Smartctl: Device Read Identity Failed (not an ATA/ATAPI device)\n\n");
failuretest(MANDATORY_CMD, returnval|=FAILID); failuretest(MANDATORY_CMD, returnval|=FAILID);
} }
@ -1808,73 +1833,70 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
known = PrintDriveInfo(&drive, options.fix_swapped_id); known = PrintDriveInfo(&drive, options.fix_swapped_id);
} }
// Was this a packet device? // Check and print SMART support and state
if (retid>0){ int smart_supported = -1, smart_enabled = -1;
pout("SMART support is: Unavailable - Packet Interface Devices [this device: %s] don't support ATA SMART\n", packetdevicetype(retid-1)); if (need_smart_support || options.drive_info) {
failuretest(MANDATORY_CMD, returnval|=FAILSMART);
}
// if drive does not supports SMART it's time to exit // Packet device ?
supported=ataSmartSupport(&drive); if (retid > 0) {
if (supported != 1){ pout("SMART support is: Unavailable - Packet Interface Devices [this device: %s] don't support ATA SMART\n",
if (supported==0) { packetdevicetype(retid-1));
pout("SMART support is: Unavailable - device lacks SMART capability.\n");
failuretest(MANDATORY_CMD, returnval|=FAILSMART);
pout(" Checking to be sure by trying SMART ENABLE command.\n");
} }
else { else {
// Disk device: SMART supported and enabled ?
smart_supported = ataSmartSupport(&drive);
smart_enabled = ataIsSmartEnabled(&drive);
if (smart_supported < 0)
pout("SMART support is: Ambiguous - ATA IDENTIFY DEVICE words 82-83 don't show if SMART supported.\n"); pout("SMART support is: Ambiguous - ATA IDENTIFY DEVICE words 82-83 don't show if SMART supported.\n");
if (!known) failuretest(MANDATORY_CMD, returnval|=FAILSMART); if (smart_supported && smart_enabled < 0) {
pout(" Checking for SMART support by trying SMART ENABLE command.\n");
}
if (ataEnableSmart(device)){
pout(" SMART ENABLE failed - this establishes that this device lacks SMART functionality.\n");
failuretest(MANDATORY_CMD, returnval|=FAILSMART);
supported=0;
}
else {
pout(" SMART ENABLE appeared to work! Continuing.\n");
supported=1;
}
if (!options.drive_info)
pout("\n");
}
// Now print remaining drive info: is SMART enabled?
if (options.drive_info) {
int ison=ataIsSmartEnabled(&drive),isenabled=ison;
if (ison==-1) {
pout("SMART support is: Ambiguous - ATA IDENTIFY DEVICE words 85-87 don't show if SMART is enabled.\n"); pout("SMART support is: Ambiguous - ATA IDENTIFY DEVICE words 85-87 don't show if SMART is enabled.\n");
if (need_smart_support) {
failuretest(MANDATORY_CMD, returnval|=FAILSMART); failuretest(MANDATORY_CMD, returnval|=FAILSMART);
// check SMART support by trying a command // check SMART support by trying a command
pout(" Checking to be sure by trying SMART RETURN STATUS command.\n"); pout(" Checking to be sure by trying SMART RETURN STATUS command.\n");
isenabled=ataDoesSmartWork(device); if (ataDoesSmartWork(device))
smart_supported = smart_enabled = 1;
} }
}
else if (smart_supported < 0 && (smart_enabled > 0 || known))
// Assume supported if enabled or in drive database
smart_supported = 1;
if (smart_supported < 0)
pout("SMART support is: Unknown - Try option -s with argument 'on' to enable it.");
else if (!smart_supported)
pout("SMART support is: Unavailable - device lacks SMART capability.\n");
else { else {
if (options.drive_info)
pout("SMART support is: Available - device has SMART capability.\n"); pout("SMART support is: Available - device has SMART capability.\n");
if (smart_enabled >= 0) {
if (device->ata_identify_is_cached()) { if (device->ata_identify_is_cached()) {
if (options.drive_info)
pout(" %sabled status cached by OS, trying SMART RETURN STATUS cmd.\n", pout(" %sabled status cached by OS, trying SMART RETURN STATUS cmd.\n",
(isenabled?"En":"Dis")); (smart_enabled?"En":"Dis"));
isenabled=ataDoesSmartWork(device); smart_enabled = ataDoesSmartWork(device);
}
if (options.drive_info)
pout("SMART support is: %s\n",
(smart_enabled ? "Enabled" : "Disabled"));
}
}
} }
} }
if (isenabled) // Print remaining drive info
pout("SMART support is: Enabled\n"); if (options.drive_info) {
else {
if (ison==-1)
pout("SMART support is: Unavailable\n");
else
pout("SMART support is: Disabled\n");
}
// Print the (now possibly changed) power mode if available // Print the (now possibly changed) power mode if available
if (powername) if (powername)
pout("Power mode %s %s\n", (powerchg?"was:":"is: "), powername); pout("Power mode %s %s\n", (powerchg?"was:":"is: "), powername);
pout("\n"); pout("\n");
} }
// Exit if SMART is not supported but must be available to proceed
if (smart_supported <= 0 && need_smart_support)
failuretest(MANDATORY_CMD, returnval|=FAILSMART);
// START OF THE ENABLE/DISABLE SECTION OF THE CODE // START OF THE ENABLE/DISABLE SECTION OF THE CODE
if ( options.smart_disable || options.smart_enable if ( options.smart_disable || options.smart_enable
|| options.smart_auto_save_disable || options.smart_auto_save_enable || options.smart_auto_save_disable || options.smart_auto_save_enable
@ -1887,14 +1909,10 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
pout("Smartctl: SMART Enable Failed.\n\n"); pout("Smartctl: SMART Enable Failed.\n\n");
failuretest(MANDATORY_CMD, returnval|=FAILSMART); failuretest(MANDATORY_CMD, returnval|=FAILSMART);
} }
else else {
pout("SMART Enabled.\n"); pout("SMART Enabled.\n");
smart_enabled = 1;
} }
// From here on, every command requires that SMART be enabled...
if (!ataDoesSmartWork(device)) {
pout("SMART Disabled. Use option -s with argument 'on' to enable it.\n");
return returnval;
} }
// Turn off SMART on device // Turn off SMART on device
@ -1903,15 +1921,14 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
pout( "Smartctl: SMART Disable Failed.\n\n"); pout( "Smartctl: SMART Disable Failed.\n\n");
failuretest(MANDATORY_CMD,returnval|=FAILSMART); failuretest(MANDATORY_CMD,returnval|=FAILSMART);
} }
}
// Exit if SMART is disabled but must be enabled to proceed
if (options.smart_disable || (smart_enabled <= 0 && need_smart_enabled)) {
pout("SMART Disabled. Use option -s with argument 'on' to enable it.\n"); pout("SMART Disabled. Use option -s with argument 'on' to enable it.\n");
return returnval; return returnval;
} }
// Let's ALWAYS issue this command to get the SMART status
code=ataSmartStatus2(device);
if (code==-1)
failuretest(MANDATORY_CMD, returnval|=FAILSMART);
// Enable/Disable Auto-save attributes // Enable/Disable Auto-save attributes
if (options.smart_auto_save_enable) { if (options.smart_auto_save_enable) {
if (ataEnableAutoSave(device)){ if (ataEnableAutoSave(device)){
@ -1931,23 +1948,38 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
pout("SMART Attribute Autosave Disabled.\n"); pout("SMART Attribute Autosave Disabled.\n");
} }
// for everything else read values and thresholds are needed // Read SMART values and thresholds if necessary
if (ataReadSmartValues(device, &smartval)){ ata_smart_values smartval; memset(&smartval, 0, sizeof(smartval));
ata_smart_thresholds_pvt smartthres; memset(&smartthres, 0, sizeof(smartthres));
bool smart_val_ok = false, smart_thres_ok = false;
if (need_smart_val) {
if (ataReadSmartValues(device, &smartval)) {
pout("Smartctl: SMART Read Values failed.\n\n"); pout("Smartctl: SMART Read Values failed.\n\n");
failuretest(OPTIONAL_CMD, returnval|=FAILSMART); failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
} }
else {
smart_val_ok = true;
if (options.smart_check_status || options.smart_vendor_attrib) {
if (ataReadSmartThresholds(device, &smartthres)){ if (ataReadSmartThresholds(device, &smartthres)){
pout("Smartctl: SMART Read Thresholds failed.\n\n"); pout("Smartctl: SMART Read Thresholds failed.\n\n");
failuretest(OPTIONAL_CMD, returnval|=FAILSMART); failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
} }
else
smart_thres_ok = true;
}
}
}
// Enable/Disable Off-line testing // Enable/Disable Off-line testing
bool needupdate = false;
if (options.smart_auto_offl_enable) { if (options.smart_auto_offl_enable) {
if (!isSupportAutomaticTimer(&smartval)){ if (!isSupportAutomaticTimer(&smartval)){
pout("Warning: device does not support SMART Automatic Timers.\n\n"); pout("Warning: device does not support SMART Automatic Timers.\n\n");
failuretest(OPTIONAL_CMD, returnval|=FAILSMART); failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
} }
needupdate=1; needupdate = smart_val_ok;
if (ataEnableAutoOffline(device)){ if (ataEnableAutoOffline(device)){
pout( "Smartctl: SMART Enable Automatic Offline Failed.\n\n"); pout( "Smartctl: SMART Enable Automatic Offline Failed.\n\n");
failuretest(OPTIONAL_CMD, returnval|=FAILSMART); failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
@ -1961,7 +1993,7 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
pout("Warning: device does not support SMART Automatic Timers.\n\n"); pout("Warning: device does not support SMART Automatic Timers.\n\n");
failuretest(OPTIONAL_CMD, returnval|=FAILSMART); failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
} }
needupdate=1; needupdate = smart_val_ok;
if (ataDisableAutoOffline(device)){ if (ataDisableAutoOffline(device)){
pout("Smartctl: SMART Disable Automatic Offline Failed.\n\n"); pout("Smartctl: SMART Disable Automatic Offline Failed.\n\n");
failuretest(OPTIONAL_CMD, returnval|=FAILSMART); failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
@ -1973,6 +2005,7 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
if (needupdate && ataReadSmartValues(device, &smartval)){ if (needupdate && ataReadSmartValues(device, &smartval)){
pout("Smartctl: SMART Read Values failed.\n\n"); pout("Smartctl: SMART Read Values failed.\n\n");
failuretest(OPTIONAL_CMD, returnval|=FAILSMART); failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
smart_val_ok = false;
} }
// all this for a newline! // all this for a newline!
@ -1989,14 +2022,15 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
|| options.sct_temp_sts || options.sct_temp_hist ) || options.sct_temp_sts || options.sct_temp_hist )
pout("=== START OF READ SMART DATA SECTION ===\n"); pout("=== START OF READ SMART DATA SECTION ===\n");
// Check SMART status (use previously returned value) // Check SMART status
if (options.smart_check_status) { if (options.smart_check_status) {
switch (code) {
switch (ataSmartStatus2(device)) {
case 0: case 0:
// The case where the disk health is OK // The case where the disk health is OK
pout("SMART overall-health self-assessment test result: PASSED\n"); pout("SMART overall-health self-assessment test result: PASSED\n");
if (find_failed_attr(&smartval, &smartthres, options.attribute_defs, 0)){ if (smart_thres_ok && find_failed_attr(&smartval, &smartthres, attribute_defs, 0)) {
if (options.smart_vendor_attrib) if (options.smart_vendor_attrib)
pout("See vendor-specific Attribute list for marginal Attributes.\n\n"); pout("See vendor-specific Attribute list for marginal Attributes.\n\n");
else { else {
@ -2016,7 +2050,7 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
pout("SMART overall-health self-assessment test result: FAILED!\n" pout("SMART overall-health self-assessment test result: FAILED!\n"
"Drive failure expected in less than 24 hours. SAVE ALL DATA.\n"); "Drive failure expected in less than 24 hours. SAVE ALL DATA.\n");
PRINT_OFF(con); PRINT_OFF(con);
if (find_failed_attr(&smartval, &smartthres, options.attribute_defs, 1)){ if (smart_thres_ok && find_failed_attr(&smartval, &smartthres, attribute_defs, 1)) {
returnval|=FAILATTR; returnval|=FAILATTR;
if (options.smart_vendor_attrib) if (options.smart_vendor_attrib)
pout("See vendor-specific Attribute list for failed Attributes.\n\n"); pout("See vendor-specific Attribute list for failed Attributes.\n\n");
@ -2034,8 +2068,17 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
case -1: case -1:
default: default:
// The case where something went wrong with HDIO_DRIVE_TASK ioctl() // Something went wrong with the SMART STATUS command.
if (find_failed_attr(&smartval, &smartthres, options.attribute_defs, 1)){ // The ATA SMART RETURN STATUS command provides the result in the ATA output
// registers. Buggy ATA/SATA drivers and SAT Layers often do not properly
// return the registers values.
failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
if (!(smart_val_ok && smart_thres_ok)) {
PRINT_ON(con);
pout("SMART overall-health self-assessment test result: UNKNOWN!\n"
"SMART Status, Attributes and Thresholds cannot be read.\n\n");
}
else if (find_failed_attr(&smartval, &smartthres, attribute_defs, 1)) {
PRINT_ON(con); PRINT_ON(con);
pout("SMART overall-health self-assessment test result: FAILED!\n" pout("SMART overall-health self-assessment test result: FAILED!\n"
"Drive failure expected in less than 24 hours. SAVE ALL DATA.\n"); "Drive failure expected in less than 24 hours. SAVE ALL DATA.\n");
@ -2052,7 +2095,8 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
} }
else { else {
pout("SMART overall-health self-assessment test result: PASSED\n"); pout("SMART overall-health self-assessment test result: PASSED\n");
if (find_failed_attr(&smartval, &smartthres, options.attribute_defs, 0)){ pout("Warning: This result is based on an Attribute check.\n");
if (find_failed_attr(&smartval, &smartthres, attribute_defs, 0)) {
if (options.smart_vendor_attrib) if (options.smart_vendor_attrib)
pout("See vendor-specific Attribute list for marginal Attributes.\n\n"); pout("See vendor-specific Attribute list for marginal Attributes.\n\n");
else { else {
@ -2073,11 +2117,11 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
} // end of checking SMART Status } // end of checking SMART Status
// Print general SMART values // Print general SMART values
if (options.smart_general_values) if (smart_val_ok && options.smart_general_values)
PrintGeneralSmartValues(&smartval, &drive, fix_firmwarebug); PrintGeneralSmartValues(&smartval, &drive, fix_firmwarebug);
// Print vendor-specific attributes // Print vendor-specific attributes
if (options.smart_vendor_attrib) { if (smart_val_ok && options.smart_vendor_attrib) {
PRINT_ON(con); PRINT_ON(con);
PrintSmartAttribWithThres(&smartval, &smartthres, attribute_defs, PrintSmartAttribWithThres(&smartval, &smartthres, attribute_defs,
(con->printing_switchable ? 2 : 0)); (con->printing_switchable ? 2 : 0));
@ -2221,6 +2265,7 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
pout("Warning: device does not support Error Logging\n"); pout("Warning: device does not support Error Logging\n");
failuretest(OPTIONAL_CMD, returnval|=FAILSMART); failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
} }
ata_smart_errorlog smarterror; memset(&smarterror, 0, sizeof(smarterror));
if (ataReadErrorLog(device, &smarterror, fix_firmwarebug)){ if (ataReadErrorLog(device, &smarterror, fix_firmwarebug)){
pout("Smartctl: SMART Error Log Read Failed\n"); pout("Smartctl: SMART Error Log Read Failed\n");
failuretest(OPTIONAL_CMD, returnval|=FAILSMART); failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
@ -2248,7 +2293,9 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
if (!ataReadExtSelfTestLog(device, log_07, nsectors)) if (!ataReadExtSelfTestLog(device, log_07, nsectors))
failuretest(OPTIONAL_CMD, returnval|=FAILSMART); failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
else { else {
PrintSmartExtSelfTestLog(log_07, nsectors, options.smart_ext_selftest_log); if (!PrintSmartExtSelfTestLog(log_07, nsectors, options.smart_ext_selftest_log))
returnval |= FAILLOG;
else
ok = true; ok = true;
} }
} }
@ -2267,6 +2314,7 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
pout("Warning: device does not support Self Test Logging\n"); pout("Warning: device does not support Self Test Logging\n");
failuretest(OPTIONAL_CMD, returnval|=FAILSMART); failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
} }
ata_smart_selftestlog smartselftest; memset(&smartselftest, 0, sizeof(smartselftest));
if(ataReadSelfTestLog(device, &smartselftest, fix_firmwarebug)){ if(ataReadSelfTestLog(device, &smartselftest, fix_firmwarebug)){
pout("Smartctl: SMART Self Test Log Read Failed\n"); pout("Smartctl: SMART Self Test Log Read Failed\n");
failuretest(OPTIONAL_CMD, returnval|=FAILSMART); failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
@ -2419,7 +2467,7 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
} }
// START OF THE TESTING SECTION OF THE CODE. IF NO TESTING, RETURN // START OF THE TESTING SECTION OF THE CODE. IF NO TESTING, RETURN
if (options.smart_selftest_type == -1) if (!smart_val_ok || options.smart_selftest_type == -1)
return returnval; return returnval;
pout("=== START OF OFFLINE IMMEDIATE AND SELF-TEST SECTION ===\n"); pout("=== START OF OFFLINE IMMEDIATE AND SELF-TEST SECTION ===\n");
@ -2482,7 +2530,8 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
} }
// Now say how long the test will take to complete // Now say how long the test will take to complete
if ((timewait = TestTime(&smartval, options.smart_selftest_type))) { int timewait = TestTime(&smartval, options.smart_selftest_type);
if (timewait) {
time_t t=time(NULL); time_t t=time(NULL);
if (options.smart_selftest_type == OFFLINE_FULL_SCAN) { if (options.smart_selftest_type == OFFLINE_FULL_SCAN) {
t+=timewait; t+=timewait;

View File

@ -14,7 +14,9 @@
# define _HAVE_CCISS # define _HAVE_CCISS
# endif # endif
# include <asm/byteorder.h> # include <asm/byteorder.h>
# ifndef be32toh
# define be32toh __be32_to_cpu # define be32toh __be32_to_cpu
# endif
#elif defined(__FreeBSD__) && defined(HAVE_DEV_CISS_CISSIO_H) #elif defined(__FreeBSD__) && defined(HAVE_DEV_CISS_CISSIO_H)
# include <sys/endian.h> # include <sys/endian.h>
# include <dev/ciss/cissio.h> # include <dev/ciss/cissio.h>

View File

@ -1,5 +1,5 @@
# #
# $Id: configure.in 3074 2010-03-05 23:00:30Z chrfranke $ # $Id: configure.in 3116 2010-06-03 11:03:29Z chrfranke $
# #
dnl Process this file with autoconf to produce a configure script. dnl Process this file with autoconf to produce a configure script.
AC_PREREQ(2.50) AC_PREREQ(2.50)
@ -7,7 +7,7 @@ AC_INIT(smartmontools, 5.40, smartmontools-support@lists.sourceforge.net)
AC_CONFIG_SRCDIR(smartctl.cpp) AC_CONFIG_SRCDIR(smartctl.cpp)
smartmontools_configure_date=`date -u +'%Y-%m-%d %T %Z'` smartmontools_configure_date=`date -u +'%Y-%m-%d %T %Z'`
smartmontools_cvs_tag=`echo '$Id: configure.in 3074 2010-03-05 23:00:30Z chrfranke $'` smartmontools_cvs_tag=`echo '$Id: configure.in 3116 2010-06-03 11:03:29Z chrfranke $'`
smartmontools_release_date=2009-12-09 smartmontools_release_date=2009-12-09
smartmontools_release_time="21:00:32 UTC" smartmontools_release_time="21:00:32 UTC"
@ -51,7 +51,7 @@ case "${host}" in
CPPFLAGS="$CPPFLAGS -mno-cygwin" CPPFLAGS="$CPPFLAGS -mno-cygwin"
LDFLAGS="$LDFLAGS -mno-cygwin" LDFLAGS="$LDFLAGS -mno-cygwin"
fi fi
CPPFLAGS="$CPPFLAGS -idirafter ${srcdir}/posix -idirafter ${srcdir}/os_win32" CPPFLAGS="$CPPFLAGS -I$srcdir/os_win32"
;; ;;
*-*-freebsd*) *-*-freebsd*)
CPPFLAGS="$CPPFLAGS -I/usr/src/sys" CPPFLAGS="$CPPFLAGS -I/usr/src/sys"
@ -107,12 +107,10 @@ dnl Checks for typedefs, structures, and compiler characteristics.
AC_CHECK_TYPES([int64_t, uint64_t]) AC_CHECK_TYPES([int64_t, uint64_t])
dnl Checks for library functions. dnl Checks for library functions.
AC_CHECK_FUNCS([getopt_long], , [ AC_CHECK_FUNCS([getopt_long], [need_getopt_long=no], [need_getopt_long=yes])
AC_MSG_NOTICE([smartmontools does no longer support platforms without getopt_long().]) AM_CONDITIONAL(NEED_GETOPT_LONG, [test "$need_getopt_long" = "yes"])
AC_MSG_NOTICE([Please inform ${PACKAGE_BUGREPORT},]) AC_CHECK_FUNCS([regcomp], [need_regex=no], [need_regex=yes])
AC_MSG_NOTICE([including details about your build environment.]) AM_CONDITIONAL(NEED_REGEX, [test "$need_regex" = "yes"])
AC_MSG_ERROR([function getopt_long() not found])
])
AC_CHECK_FUNCS([getdomainname]) AC_CHECK_FUNCS([getdomainname])
AC_CHECK_FUNCS([gethostname]) AC_CHECK_FUNCS([gethostname])
@ -122,6 +120,9 @@ AC_CHECK_FUNCS([sigset])
AC_CHECK_FUNCS([strtoull]) AC_CHECK_FUNCS([strtoull])
AC_CHECK_FUNCS([uname]) AC_CHECK_FUNCS([uname])
# Check byte ordering (defines WORDS_BIGENDIAN)
AC_C_BIGENDIAN
# Check whether snprintf appends null char and returns expected length on overflow # Check whether snprintf appends null char and returns expected length on overflow
AH_TEMPLATE(HAVE_WORKING_SNPRINTF, [Define to 1 if the `snprintf' function is sane]) AH_TEMPLATE(HAVE_WORKING_SNPRINTF, [Define to 1 if the `snprintf' function is sane])
AC_MSG_CHECKING([for working snprintf]) AC_MSG_CHECKING([for working snprintf])
@ -409,15 +410,60 @@ AC_SUBST(CXXFLAGS)
AC_OUTPUT(Makefile examplescripts/Makefile) AC_OUTPUT(Makefile examplescripts/Makefile)
AC_PROG_MAKE_SET AC_PROG_MAKE_SET
# Print note that the docdir default value has changed echo "-----------------------------------------------------------------------------" >&AS_MESSAGE_FD
# TODO: Remove this after next release echo "${PACKAGE}-${VERSION} configuration:" >&AS_MESSAGE_FD
if test "$docdir_is_default" = "yes"; then echo "host operating system: $host" >&AS_MESSAGE_FD
old_def_docdir='${prefix}/share/doc/${PACKAGE}-${VERSION}' echo "C++ compiler: $CXX" >&AS_MESSAGE_FD
old_def_docdir_eval="`eval eval eval echo $old_def_docdir`" echo "preprocessor flags: $CPPFLAGS" >&AS_MESSAGE_FD
docdir_eval="`eval eval eval echo $docdir`" echo "C++ compiler flags: $CXXFLAGS" >&AS_MESSAGE_FD
AC_MSG_NOTICE([********** PLEASE NOTE **********]) echo "linker flags: $LDFLAGS" >&AS_MESSAGE_FD
AC_MSG_NOTICE(['docdir' default has changed])
AC_MSG_NOTICE([from: $old_def_docdir_eval]) case "$host_os" in
AC_MSG_NOTICE([to: $docdir_eval]) mingw*)
AC_MSG_NOTICE([*********************************]) if test -n "$drivedbdir"; then
fi echo "drive database file: EXEDIR/drivedb.h" >&AS_MESSAGE_FD
else
echo "drive database file: [[disabled]]" >&AS_MESSAGE_FD
fi
if test -n "$savestates"; then
echo "smartd save files: `eval eval eval echo $savestates`MODEL-SERIAL.TYPE.state" >&AS_MESSAGE_FD
fi
if test -n "$attributelog"; then
echo "smartd attribute logs: `eval eval eval echo $attributelog`MODEL-SERIAL.TYPE.csv" >&AS_MESSAGE_FD
fi
;;
*)
echo "binary install path: `eval eval eval echo $sbindir`" >&AS_MESSAGE_FD
echo "man page install path: `eval eval eval echo $mandir`" >&AS_MESSAGE_FD
echo "doc file install path: `eval eval eval echo $docdir`" >&AS_MESSAGE_FD
if test "$docdir_is_default" = "yes"; then
echo "(NOTE: old default was: `eval eval eval echo ${prefix}/share/doc/${PACKAGE}-${VERSION}`)" >&AS_MESSAGE_FD
fi
if test -n "$drivedbdir"; then
echo "drive database file: `eval eval eval echo $drivedbdir`/drivedb.h" >&AS_MESSAGE_FD
echo "database update script: `eval eval eval echo $sbindir`/update-smart-drivedb" >&AS_MESSAGE_FD
else
echo "drive database file: [[disabled]]" >&AS_MESSAGE_FD
echo "database update script: [[disabled]]" >&AS_MESSAGE_FD
fi
echo "local drive database: `eval eval eval echo $sysconfdir`/smart_drivedb.h" >&AS_MESSAGE_FD
echo "smartd config file: `eval eval eval echo $sysconfdir`/smartd.conf${smartd_suffix}" >&AS_MESSAGE_FD
echo "smartd initd script: `eval eval eval echo $initddir`/smartd${smartd_suffix}" >&AS_MESSAGE_FD
if test -n "$savestates"; then
echo "smartd save files: `eval eval eval echo $savestates`MODEL-SERIAL.TYPE.state" >&AS_MESSAGE_FD
else
echo "smartd save files: [[disabled]]" >&AS_MESSAGE_FD
fi
if test -n "$attributelog"; then
echo "smartd attribute logs: `eval eval eval echo $attributelog`MODEL-SERIAL.TYPE.csv" >&AS_MESSAGE_FD
else
echo "smartd attribute logs: [[disabled]]" >&AS_MESSAGE_FD
fi
echo "libcap-ng support: $use_libcap_ng" >&AS_MESSAGE_FD
case "$host_os" in
linux*) echo "SELinux support: ${with_selinux-no}" >&AS_MESSAGE_FD ;;
esac
;;
esac
echo "-----------------------------------------------------------------------------" >&AS_MESSAGE_FD

View File

@ -3,7 +3,7 @@
* *
* Home page of code is: http://smartmontools.sourceforge.net * Home page of code is: http://smartmontools.sourceforge.net
* *
* Copyright (C) 2008-9 Christian Franke <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2008-10 Christian Franke <smartmontools-support@lists.sourceforge.net>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -24,7 +24,7 @@
#include "dev_interface.h" #include "dev_interface.h"
#include "dev_ata_cmd_set.h" #include "dev_ata_cmd_set.h"
const char * dev_legacy_cpp_cvsid = "$Id: dev_legacy.cpp 2973 2009-10-26 22:38:19Z chrfranke $" const char * dev_legacy_cpp_cvsid = "$Id: dev_legacy.cpp 3098 2010-04-30 17:35:35Z chrfranke $"
DEV_INTERFACE_H_CVSID; DEV_INTERFACE_H_CVSID;
extern smartmonctrl * con; // con->reportscsiioctl extern smartmonctrl * con; // con->reportscsiioctl
@ -516,7 +516,7 @@ smart_device * legacy_smart_interface::autodetect_smart_device(const char * name
static void free_devnames(char * * devnames, int numdevs) static void free_devnames(char * * devnames, int numdevs)
{ {
static const char version[] = "$Id: dev_legacy.cpp 2973 2009-10-26 22:38:19Z chrfranke $"; static const char version[] = "$Id: dev_legacy.cpp 3098 2010-04-30 17:35:35Z chrfranke $";
for (int i = 0; i < numdevs; i++) for (int i = 0; i < numdevs; i++)
FreeNonZero(devnames[i], -1,__LINE__, version); FreeNonZero(devnames[i], -1,__LINE__, version);
FreeNonZero(devnames, (sizeof (char*) * numdevs),__LINE__, version); FreeNonZero(devnames, (sizeof (char*) * numdevs),__LINE__, version);
@ -639,8 +639,8 @@ smart_device * legacy_smart_interface::get_custom_smart_device(const char * name
set_err(EINVAL, "Option -d cciss,N requires N to be a non-negative integer"); set_err(EINVAL, "Option -d cciss,N requires N to be a non-negative integer");
return 0; return 0;
} }
if (!(0 <= disknum && disknum <= 15)) { if (!(0 <= disknum && disknum <= 127)) {
set_err(EINVAL, "Option -d cciss,N (N=%d) must have 0 <= N <= 15", disknum); set_err(EINVAL, "Option -d cciss,N (N=%d) must have 0 <= N <= 127", disknum);
return 0; return 0;
} }
return new legacy_cciss_device(this, name, disknum); return new legacy_cciss_device(this, name, disknum);

517
drivedb.h
View File

@ -32,7 +32,7 @@
* modelfamily Informal string about the model family/series of a * modelfamily Informal string about the model family/series of a
* device. Set to "" if no info (apart from device id) * device. Set to "" if no info (apart from device id)
* known. The entry is ignored if this string starts with * known. The entry is ignored if this string starts with
* a dollar sign. * a dollar sign. Must not start with "USB:", see below.
* modelregexp POSIX extended regular expression to match the model of * modelregexp POSIX extended regular expression to match the model of
* a device. This should never be "". * a device. This should never be "".
* firmwareregexp POSIX extended regular expression to match a devices's * firmwareregexp POSIX extended regular expression to match a devices's
@ -53,12 +53,29 @@
* The table will be searched from the start to end or until the first match, * The table will be searched from the start to end or until the first match,
* so the order in the table is important for distinct entries that could match * so the order in the table is important for distinct entries that could match
* the same drive. * the same drive.
*
*
* Format for USB ID entries:
*
* modelfamily String with format "USB: DEVICE; BRIDGE" where
* DEVICE is the name of the device and BRIDGE is
* the name of the USB bridge. Both may be empty
* if no info known.
* modelregexp POSIX extended regular expression to match the USB
* vendor:product ID in hex notation ("0x1234:0xabcd").
* This should never be "".
* firmwareregexp POSIX extended regular expression to match the USB
* bcdDevice info. Only compared during search if other
* entries with same USB vendor:product ID exist.
* warningmsg Not used yet.
* presets String with one device type ('-d') option.
*
*/ */
/* /*
const drive_settings builtin_knowndrives[] = { const drive_settings builtin_knowndrives[] = {
*/ */
{ "$Id: drivedb.h 3071 2010-03-04 21:17:09Z manfred99 $", { "$Id: drivedb.h 3124 2010-07-12 19:21:00Z chrfranke $",
"-", "-", "-", "-",
"This is a dummy entry to hold the SVN-Id of drivedb.h", "This is a dummy entry to hold the SVN-Id of drivedb.h",
"" ""
@ -74,6 +91,7 @@ const drive_settings builtin_knowndrives[] = {
{ "SuperTalent UltraDrive GX SSD", { "SuperTalent UltraDrive GX SSD",
"STT_FT[MD](28|32|56|64)GX25H", "STT_FT[MD](28|32|56|64)GX25H",
"", "", "", "",
" -v 1,raw64"
" -v 9,raw64" " -v 9,raw64"
" -v 12,raw64" " -v 12,raw64"
" -v 184,raw64,Initial_Bad_Block_Count" " -v 184,raw64,Initial_Bad_Block_Count"
@ -92,10 +110,15 @@ const drive_settings builtin_knowndrives[] = {
" -v 207,raw64,Max_Erase_Count" " -v 207,raw64,Max_Erase_Count"
" -v 208,raw64,Average_Erase_Count" " -v 208,raw64,Average_Erase_Count"
" -v 209,raw64,Remaining_Lifetime_Perc" " -v 209,raw64,Remaining_Lifetime_Perc"
" -v 210,raw64"
" -v 211,raw64"
" -v 212,raw64"
" -v 213,raw64"
}, },
{ "Patriot Torqx SSD", { "Patriot Torqx SSD",
"Patriot[ -]Torqx.*", "Patriot[ -]Torqx.*",
"", "", "", "",
" -v 1,raw64"
" -v 9,raw64" " -v 9,raw64"
" -v 12,raw64" " -v 12,raw64"
" -v 184,raw64,Initial_Bad_Block_Count" " -v 184,raw64,Initial_Bad_Block_Count"
@ -114,10 +137,15 @@ const drive_settings builtin_knowndrives[] = {
" -v 207,raw64,Max_Erase_Count" " -v 207,raw64,Max_Erase_Count"
" -v 208,raw64,Average_Erase_Count" " -v 208,raw64,Average_Erase_Count"
" -v 209,raw64,Remaining_Lifetime_Perc" " -v 209,raw64,Remaining_Lifetime_Perc"
" -v 210,raw64"
" -v 211,raw64"
" -v 212,raw64"
" -v 213,raw64"
}, },
{ "OCZ Vertex SSD", { "OCZ Vertex SSD",
"OCZ[ -]VERTEX.*", "OCZ[ -]VERTEX.*",
"", "", "", "",
" -v 1,raw64"
" -v 9,raw64" " -v 9,raw64"
" -v 12,raw64" " -v 12,raw64"
" -v 184,raw64,Initial_Bad_Block_Count" " -v 184,raw64,Initial_Bad_Block_Count"
@ -136,10 +164,15 @@ const drive_settings builtin_knowndrives[] = {
" -v 207,raw64,Max_Erase_Count" " -v 207,raw64,Max_Erase_Count"
" -v 208,raw64,Average_Erase_Count" " -v 208,raw64,Average_Erase_Count"
" -v 209,raw64,Remaining_Lifetime_Perc" " -v 209,raw64,Remaining_Lifetime_Perc"
" -v 210,raw64"
" -v 211,raw64"
" -v 212,raw64"
" -v 213,raw64"
}, },
{ "OCZ Agility SSD", { "OCZ Agility SSD",
"OCZ[ -]AGILITY", "OCZ[ -]AGILITY.*",
"", "", "", "",
" -v 1,raw64"
" -v 9,raw64" " -v 9,raw64"
" -v 12,raw64" " -v 12,raw64"
" -v 184,raw64,Initial_Bad_Block_Count" " -v 184,raw64,Initial_Bad_Block_Count"
@ -158,6 +191,10 @@ const drive_settings builtin_knowndrives[] = {
" -v 207,raw64,Max_Erase_Count" " -v 207,raw64,Max_Erase_Count"
" -v 208,raw64,Average_Erase_Count" " -v 208,raw64,Average_Erase_Count"
" -v 209,raw64,Remaining_Lifetime_Perc" " -v 209,raw64,Remaining_Lifetime_Perc"
" -v 210,raw64"
" -v 211,raw64"
" -v 212,raw64"
" -v 213,raw64"
}, },
{ "Crucial M225 SSD", { "Crucial M225 SSD",
"CRUCIAL_CT(64|128|256)M225", "CRUCIAL_CT(64|128|256)M225",
@ -183,6 +220,8 @@ const drive_settings builtin_knowndrives[] = {
" -v 209,raw64,Remaining_Lifetime_Perc" " -v 209,raw64,Remaining_Lifetime_Perc"
" -v 210,raw64" " -v 210,raw64"
" -v 211,raw64" " -v 211,raw64"
" -v 212,raw64"
" -v 213,raw64"
}, },
{ "Intel X25-E SSD", { "Intel X25-E SSD",
"SSDSA2SH(032|064)G1.* INTEL", // G1 = first generation "SSDSA2SH(032|064)G1.* INTEL", // G1 = first generation
@ -190,16 +229,30 @@ const drive_settings builtin_knowndrives[] = {
"-v 225,raw48,Host_Writes_Count" "-v 225,raw48,Host_Writes_Count"
}, },
{ "Intel X25-M SSD", { "Intel X25-M SSD",
"INTEL SSDSA2M(080|160)G2.*", // G2 = second generation "INTEL SSDSA2MH(080|160)G1.*", // G1 = first generation, 50nm
"", "", "", "",
"-v 225,raw48,Host_Writes_Count" "-v 225,raw48,Host_Writes_Count"
}, },
{ "Transcend Solid-State Drive", { "Intel X25-M SSD",
"INTEL SSDSA2M(080|160)G2.*", // G2 = second generation, 34nm
"", "",
"-v 225,raw48,Host_Writes_Count"
},
{ "Transcend IDE Solid State Drive",
"TS(8|16|32|64|128)GSSD25-(M|S)", "TS(8|16|32|64|128)GSSD25-(M|S)",
"", "", "" "", "", ""
}, },
{ "Transcend Solid-State Drive V series", { "Transcend SATA Solid State Drive",
"TS(8|16|32|64|128|192)GSSD25S-(M|S)", "TS(8|16|32|64|128|192)GSSD25S-(M|S)",
"", "",
"-v 229,hex64,Halt_System_ID "
"-v 232,hex64,Firmware_Version_information "
"-v 233,hex64,ECC_Fail_Record "
"-v 234,raw24/raw24,Erase_Count_Avg/Max "
"-v 235,raw24/raw24,Block_Count_Good/System"
},
{ "Transcend Ultra Series Solid State Drive (SATA II)",
"TS(60|120)GSSD25D-M",
"", "", "" "", "", ""
}, },
{ "Marvell SSD SD88SA024BA0 (SUN branded)", { "Marvell SSD SD88SA024BA0 (SUN branded)",
@ -240,8 +293,8 @@ const drive_settings builtin_knowndrives[] = {
"http://www.ibm.com/pc/support/site.wss/MIGR-42215.html", "http://www.ibm.com/pc/support/site.wss/MIGR-42215.html",
"" ""
}, },
{ "", // ExcelStor J240, J340, J360, J680, and J880 { "", // ExcelStor J240, J340, J360, J680, J880 and J8160
"ExcelStor Technology J(24|34|36|68|88)0", "ExcelStor Technology J(24|34|36|68|88|816)0",
"", "", "" "", "", ""
}, },
{ "", // Fujitsu M1623TAU { "", // Fujitsu M1623TAU
@ -519,6 +572,12 @@ const drive_settings builtin_knowndrives[] = {
"SAMSUNG HM((061|080)G|(121|160)H|250J)I", "SAMSUNG HM((061|080)G|(121|160)H|250J)I",
"", "", "" "", "", ""
}, },
{ "SAMSUNG SpinPoint M series", // tested with MP0402H/UC100-11
"SAMSUNG MP0(302|402|603|804)H",
"",
"",
"-v 9,halfminutes"
},
/* /*
// TODO: Make the entries below more specific. // TODO: Make the entries below more specific.
// These entries produce misleading results, because newer // These entries produce misleading results, because newer
@ -881,15 +940,15 @@ const drive_settings builtin_knowndrives[] = {
"(Hitachi )?(HTS4212(60|80|10|12)H9AT00|HTS421260G9AT00)", "(Hitachi )?(HTS4212(60|80|10|12)H9AT00|HTS421260G9AT00)",
"", "", "" "", "", ""
}, },
{ "Hitachi Travelstar 5K80 family", { "Hitachi Travelstar 5K80",
"(Hitachi )?HTS5480[8642]0M9AT00", "(Hitachi )?HTS5480[8642]0M9AT00",
"", "", "" "", "", ""
}, },
{ "Hitachi Travelstar 5K100 series", { "Hitachi Travelstar 5K100",
"(Hitachi )?HTS5410[1864]0G9(AT|SA)00", "(Hitachi )?HTS5410[1864]0G9(AT|SA)00",
"", "", "" "", "", ""
}, },
{ "Hitachi Travelstar E5K100 series", { "Hitachi Travelstar E5K100",
"(Hitachi )?HTE541040G9(AT|SA)00", "(Hitachi )?HTE541040G9(AT|SA)00",
"", "", "" "", "", ""
}, },
@ -897,22 +956,26 @@ const drive_settings builtin_knowndrives[] = {
"(Hitachi )?HTS5412(60|80|10|12)H9(AT|SA)00", "(Hitachi )?HTS5412(60|80|10|12)H9(AT|SA)00",
"", "", "" "", "", ""
}, },
{ "Hitachi Travelstar 5K160 series", { "Hitachi Travelstar 5K160",
"(Hitachi |HITACHI )?HTS5416([468]0|1[26])J9(AT|SA)00", "(Hitachi |HITACHI )?HTS5416([468]0|1[26])J9(AT|SA)00",
"", "", "" "", "", ""
}, },
{ "Hitachi Travelstar E5K160 series", { "Hitachi Travelstar E5K160",
"(Hitachi )?HTE5416(12|16|60|80)J9(AT|SA)00", "(Hitachi )?HTE5416(12|16|60|80)J9(AT|SA)00",
"", "", "" "", "", ""
}, },
{ "Hitachi Travelstar 5K250 series", { "Hitachi Travelstar 5K250",
"(Hitachi |HITACHI )?HTS5425(80|12|16|20|25)K9(A3|SA)00", "(Hitachi |HITACHI )?HTS5425(80|12|16|20|25)K9(A3|SA)00",
"", "", "" "", "", ""
}, },
{ "Hitachi Travelstar 5K320 series", { "Hitachi Travelstar 5K320",
"(Hitachi |HITACHI )?HT(S|E)5432(80|12|16|25|32)L9(A3(00)?|SA01)", "(Hitachi |HITACHI )?HT(S|E)5432(80|12|16|25|32)L9(A3(00)?|SA01)",
"", "", "" "", "", ""
}, },
{ "Hitachi Travelstar 5K500.B",
"(Hitachi )?HT[ES]5450(12|16|25|32|40|50)B9A30[01]",
"", "", ""
},
{ "Hitachi Travelstar 7K60", { "Hitachi Travelstar 7K60",
"(Hitachi )?HTS726060M9AT00", "(Hitachi )?HTS726060M9AT00",
"", "", "" "", "", ""
@ -961,7 +1024,7 @@ const drive_settings builtin_knowndrives[] = {
"(IBM-)?IC35L(030|060|090|120|180)AVV207-[01]", "(IBM-)?IC35L(030|060|090|120|180)AVV207-[01]",
"", "", "" "", "", ""
}, },
{ "Hitachi Deskstar 7K80 series", { "Hitachi Deskstar 7K80",
"(Hitachi )?HDS7280([48]0PLAT20|(40)?PLA320|80PLA380).*", "(Hitachi )?HDS7280([48]0PLAT20|(40)?PLA320|80PLA380).*",
"", "", "" "", "", ""
}, },
@ -969,7 +1032,7 @@ const drive_settings builtin_knowndrives[] = {
"(Hitachi )?HDS7216(80|16)PLA[3T]80.*", "(Hitachi )?HDS7216(80|16)PLA[3T]80.*",
"", "", "" "", "", ""
}, },
{ "Hitachi Deskstar 7K250 series", { "Hitachi Deskstar 7K250",
"(Hitachi )?HDS7225((40|80|12|16)VLAT20|(12|16|25)VLAT80|(80|12|16|25)VLSA80)", "(Hitachi )?HDS7225((40|80|12|16)VLAT20|(12|16|25)VLAT80|(80|12|16|25)VLSA80)",
"", "", "" "", "", ""
}, },
@ -977,19 +1040,19 @@ const drive_settings builtin_knowndrives[] = {
"HITACHI HDS7225SBSUN250G.*", "HITACHI HDS7225SBSUN250G.*",
"", "", "" "", "", ""
}, },
{ "Hitachi Deskstar T7K250 series", { "Hitachi Deskstar T7K250",
"(Hitachi )?HDT7225((25|20|16)DLA(T80|380))", "(Hitachi )?HDT7225((25|20|16)DLA(T80|380))",
"", "", "" "", "", ""
}, },
{ "Hitachi Deskstar 7K400 series", { "Hitachi Deskstar 7K400",
"(Hitachi )?HDS724040KL(AT|SA)80", "(Hitachi )?HDS724040KL(AT|SA)80",
"", "", "" "", "", ""
}, },
{ "Hitachi Deskstar 7K500 series", { "Hitachi Deskstar 7K500",
"(Hitachi )?HDS725050KLA(360|T80)", "(Hitachi )?HDS725050KLA(360|T80)",
"", "", "" "", "", ""
}, },
{ "Hitachi Deskstar P7K500 series", { "Hitachi Deskstar P7K500",
"(Hitachi )?HDP7250(16|25|32|40|50)GLA(36|38|T8)0", "(Hitachi )?HDP7250(16|25|32|40|50)GLA(36|38|T8)0",
"", "", "" "", "", ""
}, },
@ -1005,6 +1068,10 @@ const drive_settings builtin_knowndrives[] = {
"(Hitachi )?HDT7210((16|25)SLA380|(32|50|64|75|10)SLA360)", "(Hitachi )?HDT7210((16|25)SLA380|(32|50|64|75|10)SLA360)",
"", "", "" "", "", ""
}, },
{ "Hitachi Deskstar 7K1000.C",
"(Hitachi )?HDS7210((16|25)CLA382|(32|50)CLA362|(64|75|10)CLA332)",
"", "", ""
},
{ "Hitachi Deskstar 7K2000", { "Hitachi Deskstar 7K2000",
"Hitachi HDS722020ALA330", "Hitachi HDS722020ALA330",
"", "", "" "", "", ""
@ -1013,6 +1080,10 @@ const drive_settings builtin_knowndrives[] = {
"(Hitachi )?HUA7210(50|75|10)KLA330", "(Hitachi )?HUA7210(50|75|10)KLA330",
"", "", "" "", "", ""
}, },
{ "Hitachi Ultrastar A7K2000",
"(Hitachi )?HUA7220((50|10)C|20A)LA33[01]",
"", "", ""
},
{ "Toshiba 2.5\" HDD series (10-20 GB)", { "Toshiba 2.5\" HDD series (10-20 GB)",
"TOSHIBA MK(101[67]GAP|15[67]GAP|20(1[678]GAP|(18|23)GAS))", "TOSHIBA MK(101[67]GAP|15[67]GAP|20(1[678]GAP|(18|23)GAS))",
"", "", "" "", "", ""
@ -1383,6 +1454,10 @@ const drive_settings builtin_knowndrives[] = {
"WDC WD((50|64|75)00AA(C|V)S|(50|64|75)00AADS|10EA(C|V)S|(10|15|20)EADS)-.*", "WDC WD((50|64|75)00AA(C|V)S|(50|64|75)00AADS|10EA(C|V)S|(10|15|20)EADS)-.*",
"", "", "" "", "", ""
}, },
{ "Western Digital Caviar Green (Adv. Format) family",
"WDC WD((64|80)00A|(10|15|20)E)ARS-.*",
"", "", ""
},
{ "Western Digital Caviar Black family", { "Western Digital Caviar Black family",
"WDC WD((500|640|750)1AA|1001FA)LS-.*", "WDC WD((500|640|750)1AA|1001FA)LS-.*",
"", "", "" "", "", ""
@ -1392,11 +1467,11 @@ const drive_settings builtin_knowndrives[] = {
"", "", "" "", "", ""
}, },
{ "Western Digital AV-GP family", { "Western Digital AV-GP family",
"WDC WD((16|25|32|50|64|75)00AVVS|(50|75)00AVCS|10EVVS|(10|20)EVCS|WD(10|15|20)EVDS)-.*", "WDC WD((16|25|32|50|64|75)00AVVS|(50|75)00AVCS|10EVVS|(10|20)EVCS|(10|15|20)EVDS)-.*",
"", "", "" "", "", ""
}, },
{ "Western Digital Raptor family", { "Western Digital Raptor family",
"WDC WD((360|740|800)GD|(360|740|1500)ADF[DS])-.*", "WDC WD((360|740|800)GD|(360|740|800|1500)ADF[DS])-.*",
"", "", "" "", "", ""
}, },
{ "Western Digital Raptor X", { "Western Digital Raptor X",
@ -1432,7 +1507,7 @@ const drive_settings builtin_knowndrives[] = {
"", "", "" "", "", ""
}, },
{ "Western Digital My Passport Essential SE hard drive (USB interface)", { "Western Digital My Passport Essential SE hard drive (USB interface)",
"WDC WD7500KMVV-.*", "WDC WD(7500K|10T)MVV-.*",
"", "", "" "", "", ""
}, },
{ "Western Digital My Passport hard drive (USB interface)", { "Western Digital My Passport hard drive (USB interface)",
@ -1487,6 +1562,400 @@ const drive_settings builtin_knowndrives[] = {
"QUANTUM FIREBALLP KA(9|10).1", "QUANTUM FIREBALLP KA(9|10).1",
"", "", "" "", "", ""
}, },
////////////////////////////////////////////////////
// USB ID entries
////////////////////////////////////////////////////
// ALi
{ "USB: ; ALi M5621", // USB->PATA
"0x0402:0x5621",
"",
"",
"" // unsupported
},
// Cypress
{ "USB: ; Cypress CY7C68300A (AT2)",
"0x04b4:0x6830",
"0x0001",
"",
"" // unsupported
},
{ "USB: ; Cypress CY7C68300B/C (AT2LP)",
"0x04b4:0x6830",
"0x0240",
"",
"-d usbcypress"
},
// Myson Century
{ "USB: ; Myson Century CS8818",
"0x04cf:0x8818",
"0xb007",
"",
"" // unsupported
},
// Samsung
{ "USB: Samsung Story Station; ",
"0x04e8:0x5f06",
"",
"",
"-d sat"
},
// Sunplus
{ "USB: ; SunPlus SPDIF215",
"0x04fc:0x0c15",
"0xf615",
"",
"-d usbsunplus"
},
{ "USB: ; SunPlus SPDIF225", // USB+SATA->SATA
"0x04fc:0x0c25",
"0x0103",
"",
"-d usbsunplus"
},
// Iomega
{ "USB: Iomega LPHD080-0; ",
"0x059b:0x0272",
"",
"",
"-d usbcypress"
},
{ "USB: Iomega MDHD500-U; ",
"0x059b:0x0275",
"0x0001",
"",
"" // unsupported
},
{ "USB: Iomega LDHD-UP; Sunplus",
"0x059b:0x0370",
"",
"",
"-d usbsunplus"
},
// LaCie
{ "USB: LaCie hard disk (FA Porsche design);",
"0x059f:0x0651",
"",
"",
"" // unsupported
},
{ "USB: LaCie hard disk; JMicron",
"0x059f:0x0951",
"",
"",
"-d usbjmicron"
},
{ "USB: LaCie hard disk (Neil Poulton design);",
"0x059f:0x1018",
"",
"",
"-d sat"
},
{ "USB: LaCie Desktop Hard Drive; JMicron",
"0x059f:0x1019",
"",
"",
"-d usbjmicron"
},
{ "USB: LaCie Rugged Hard Drive; JMicron",
"0x059f:0x101d",
"0x0001",
"",
"-d usbjmicron,x"
},
// In-System Design
{ "USB: ; In-System/Cypress ISD-300A1",
"0x05ab:0x0060",
"0x1101",
"",
"-d usbcypress"
},
// Genesys Logic
{ "USB: ; Genesys Logic GL881E",
"0x05e3:0x0702",
"",
"",
"" // unsupported
},
{ "USB: ; Genesys Logic", // TODO: requires '-T permissive'
"0x05e3:0x0718",
"0x0041",
"",
"-d sat"
},
// Prolific
{ "USB: ; Prolific PL2507", // USB->PATA
"0x067b:0x2507",
"",
"",
"" // unsupported
},
{ "USB: ; Prolific PL3507", // USB+IEE1394->PATA
"0x067b:0x3507",
"0x0001",
"",
"" // unsupported
},
// Freecom
{ "USB: Freecom Hard Drive XS; Sunplus",
"0x07ab:0xfc8e",
"0x010f",
"",
"-d usbsunplus"
},
// Toshiba
{ "USB: Toshiba PX1270E-1G16; Sunplus",
"0x0930:0x0b03",
"",
"",
"-d usbsunplus"
},
{ "USB: Toshiba PX1396E-3T01; Sunplus", // similar to Dura Micro 501
"0x0930:0x0b09",
"",
"",
"-d usbsunplus"
},
// Seagate
{ "USB: Seagate FreeAgent Go; ",
"0x0bc2:0x2(000|100|101)",
"",
"",
"-d sat"
},
{ "USB: Seagate FreeAgent Go FW; ",
"0x0bc2:0x2200",
"",
"",
"-d sat"
},
{ "USB: Seagate Expansion Portable; ",
"0x0bc2:0x2300",
"",
"",
"-d sat"
},
{ "USB: Seagate FreeAgent Desktop; ",
"0x0bc2:0x3000",
"",
"",
"-d sat"
},
{ "USB: Seagate FreeAgent Desk; ",
"0x0bc2:0x3001",
"",
"",
"-d sat"
},
// Dura Micro
{ "USB: Dura Micro 509; Sunplus",
"0x0c0b:0xb159",
"0x0103",
"",
"-d usbsunplus"
},
// Maxtor
{ "USB: Maxtor OneTouch; ",
"0x0d49:0x7300",
"0x0121",
"",
"-d sat"
},
{ "USB: Maxtor OneTouch 4; ",
"0x0d49:0x7310",
"0x0125",
"",
"-d sat"
},
{ "USB: Maxtor OneTouch 4 Mini; ",
"0x0d49:0x7350",
"0x0125",
"",
"-d sat"
},
{ "USB: Maxtor Basics Desktop; ",
"0x0d49:0x7410",
"0x0122",
"",
"-d sat"
},
{ "USB: Maxtor Basics Portable; ",
"0x0d49:0x7450",
"0x0122",
"",
"-d sat"
},
// Western Digital
{ "USB: WD My Passport (IDE); Cypress",
"0x1058:0x0701",
"0x0240",
"",
"-d usbcypress"
},
{ "USB: WD My Passport Portable; ",
"0x1058:0x0702",
"0x0102",
"",
"-d sat"
},
{ "USB: WD My Passport Essential; ",
"0x1058:0x0704",
"0x0175",
"",
"-d sat"
},
{ "USB: WD My Passport Elite; ",
"0x1058:0x0705",
"0x0175",
"",
"-d sat"
},
{ "USB: WD My Passport 070A; ",
"0x1058:0x070a",
"0x1028",
"",
"-d sat"
},
{ "USB: WD My Book ES; ",
"0x1058:0x0906",
"0x0012",
"",
"-d sat"
},
{ "USB: WD Elements Desktop; ",
"0x1058:0x1001",
"0x0104",
"",
"-d sat"
},
{ "USB: WD Elements Desktop WDE1UBK...; ",
"0x1058:0x1003",
"0x0175",
"",
"-d sat"
},
{ "USB: WD Elements; ",
"0x1058:0x1010",
"0x0105",
"",
"-d sat"
},
{ "USB: WD Elements Desktop; ", // 2TB
"0x1058:0x1021",
"0x2002",
"",
"-d sat"
},
{ "USB: WD My Book Essential; ",
"0x1058:0x1100",
"0x0165",
"",
"-d sat"
},
{ "USB: WD My Book; ",
"0x1058:0x1102",
"0x1028",
"",
"-d sat"
},
{ "USB: WD My Book Essential; ",
"0x1058:0x1110",
"0x1030",
"",
"-d sat"
},
// A-DATA
{ "USB: A-DATA SH93; Cypress",
"0x125f:0xa93a",
"0x0150",
"",
"-d usbcypress"
},
// Initio
{ "USB: ; Initio 316000",
"0x13fd:0x0540",
"",
"",
"" // unsupported
},
{ "USB: ; Initio", // USB->SATA
"0x13fd:0x1240",
"0x0104",
"",
"-d sat"
},
{ "USB: ; Initio", // USB+SATA->SATA
"0x13fd:0x1340",
"0x0208",
"",
"-d sat"
},
// JMicron
{ "USB: ; JMicron JM20329", // USB->SATA
"0x152d:0x2329",
"0x0100",
"",
"-d usbjmicron"
},
{ "USB: ; JMicron JM20336", // USB+SATA->SATA, USB->2xSATA
"0x152d:0x2336",
"0x0100",
"",
"-d usbjmicron,x"
},
{ "USB: ; JMicron JM20337/8", // USB->SATA+PATA, USB+SATA->PATA
"0x152d:0x2338",
"0x0100",
"",
"-d usbjmicron"
},
{ "USB: ; JMicron JM20339", // USB->SATA
"0x152d:0x2339",
"0x0100",
"",
"-d usbjmicron,x"
},
{ "USB: ; JMicron", // USB->SATA
"0x152d:0x2352",
"0x0100",
"",
"-d usbjmicron,x"
},
// Verbatim
{ "USB: Verbatim FW/USB160; Oxford OXUF934SSA-LQAG", // USB+IEE1394->SATA
"0x18a5:0x0215",
"0x0001",
"",
"-d sat"
},
{ "USB: Verbatim External Hard Drive 47519; Sunplus", // USB->SATA
"0x18a5:0x0216",
"",
"",
"-d usbsunplus"
},
// SunplusIT
{ "USB: ; SunplusIT",
"0x1bcf:0x0c31",
"",
"",
"-d usbsunplus"
},
// Hitachi/SimpleTech
{ "USB: Hitachi/SimpleTech; JMicron", // 1TB
"0x4971:0xce17",
"",
"",
"-d usbjmicron,x"
},
// OnSpec
{ "USB: ; OnSpec", // USB->PATA
"0x55aa:0x2b00",
"0x0100",
"",
"" // unsupported
},
/* /*
}; // builtin_knowndrives[] }; // builtin_knowndrives[]
*/ */

View File

@ -4,8 +4,8 @@
* Home page of code is: http://smartmontools.sourceforge.net * Home page of code is: http://smartmontools.sourceforge.net
* Address of support mailing list: smartmontools-support@lists.sourceforge.net * Address of support mailing list: smartmontools-support@lists.sourceforge.net
* *
* Copyright (C) 2003-9 Philip Williams, Bruce Allen * Copyright (C) 2003-10 Philip Williams, Bruce Allen
* Copyright (C) 2008-9 Christian Franke <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2008-10 Christian Franke <smartmontools-support@lists.sourceforge.net>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -35,7 +35,7 @@
#include <stdexcept> #include <stdexcept>
const char * knowndrives_cpp_cvsid = "$Id: knowndrives.cpp 3004 2009-12-19 19:39:12Z chrfranke $" const char * knowndrives_cpp_cvsid = "$Id: knowndrives.cpp 3093 2010-04-30 09:57:36Z chrfranke $"
KNOWNDRIVES_H_CVSID; KNOWNDRIVES_H_CVSID;
#define MODEL_STRING_LENGTH 40 #define MODEL_STRING_LENGTH 40
@ -140,6 +140,18 @@ const char * drive_database::copy_string(const char * src)
static drive_database knowndrives; static drive_database knowndrives;
// Return true if modelfamily string describes entry for USB ID
static bool is_usb_modelfamily(const char * modelfamily)
{
return !strncmp(modelfamily, "USB:", 4);
}
// Return true if entry for USB ID
static inline bool is_usb_entry(const drive_settings * dbentry)
{
return is_usb_modelfamily(dbentry->modelfamily);
}
// Compile regular expression, print message on failure. // Compile regular expression, print message on failure.
static bool compile(regular_expression & regex, const char *pattern) static bool compile(regular_expression & regex, const char *pattern)
{ {
@ -173,6 +185,10 @@ const drive_settings * lookup_drive(const char * model, const char * firmware)
firmware = ""; firmware = "";
for (unsigned i = 0; i < knowndrives.size(); i++) { for (unsigned i = 0; i < knowndrives.size(); i++) {
// Skip USB entries
if (is_usb_entry(&knowndrives[i]))
continue;
// Check whether model matches the regular expression in knowndrives[i]. // Check whether model matches the regular expression in knowndrives[i].
if (!match(knowndrives[i].modelregexp, model)) if (!match(knowndrives[i].modelregexp, model))
continue; continue;
@ -190,9 +206,10 @@ const drive_settings * lookup_drive(const char * model, const char * firmware)
return 0; return 0;
} }
// Parse '-v' and '-F' options in preset string, return false on error.
static bool parse_presets(const char * presets, ata_vendor_attr_defs & defs, // Parse drive or USB options in preset string, return false on error.
unsigned char & fix_firmwarebug) static bool parse_db_presets(const char * presets, ata_vendor_attr_defs * defs,
unsigned char * fix_firmwarebug, std::string * type)
{ {
for (int i = 0; ; ) { for (int i = 0; ; ) {
i += strspn(presets+i, " \t"); i += strspn(presets+i, " \t");
@ -201,12 +218,12 @@ static bool parse_presets(const char * presets, ata_vendor_attr_defs & defs,
char opt, arg[40+1+13]; int len = -1; char opt, arg[40+1+13]; int len = -1;
if (!(sscanf(presets+i, "-%c %40[^ ]%n", &opt, arg, &len) >= 2 && len > 0)) if (!(sscanf(presets+i, "-%c %40[^ ]%n", &opt, arg, &len) >= 2 && len > 0))
return false; return false;
if (opt == 'v') { if (opt == 'v' && defs) {
// Parse "-v N,format[,name]" // Parse "-v N,format[,name]"
if (!parse_attribute_def(arg, defs, PRIOR_DATABASE)) if (!parse_attribute_def(arg, *defs, PRIOR_DATABASE))
return false; return false;
} }
else if (opt == 'F') { else if (opt == 'F' && fix_firmwarebug) {
unsigned char fix; unsigned char fix;
if (!strcmp(arg, "samsung")) if (!strcmp(arg, "samsung"))
fix = FIX_SAMSUNG; fix = FIX_SAMSUNG;
@ -217,8 +234,12 @@ static bool parse_presets(const char * presets, ata_vendor_attr_defs & defs,
else else
return false; return false;
// Set only if not set by user // Set only if not set by user
if (fix_firmwarebug == FIX_NOTSPECIFIED) if (*fix_firmwarebug == FIX_NOTSPECIFIED)
fix_firmwarebug = fix; *fix_firmwarebug = fix;
}
else if (opt == 'd' && type) {
// TODO: Check valid types
*type = arg;
} }
else else
return false; return false;
@ -228,6 +249,83 @@ static bool parse_presets(const char * presets, ata_vendor_attr_defs & defs,
return true; return true;
} }
// Parse '-v' and '-F' options in preset string, return false on error.
static inline bool parse_presets(const char * presets,
ata_vendor_attr_defs & defs,
unsigned char & fix_firmwarebug)
{
return parse_db_presets(presets, &defs, &fix_firmwarebug, 0);
}
// Parse '-d' option in preset string, return false on error.
static inline bool parse_usb_type(const char * presets, std::string & type)
{
return parse_db_presets(presets, 0, 0, &type);
}
// Parse "USB: [DEVICE] ; [BRIDGE]" string
static void parse_usb_names(const char * names, usb_dev_info & info)
{
int n1 = -1, n2 = -1, n3 = -1;
sscanf(names, "USB: %n%*[^;]%n; %n", &n1, &n2, &n3);
if (0 < n1 && n1 < n2)
info.usb_device.assign(names+n1, n2-n1);
else
sscanf(names, "USB: ; %n", &n3);
if (0 < n3)
info.usb_bridge = names+n3;
}
// Search drivedb for USB device with vendor:product ID.
int lookup_usb_device(int vendor_id, int product_id, int bcd_device,
usb_dev_info & info, usb_dev_info & info2)
{
// Format strings to match
char usb_id_str[16], bcd_dev_str[16];
snprintf(usb_id_str, sizeof(usb_id_str), "0x%04x:0x%04x", vendor_id, product_id);
if (bcd_device >= 0)
snprintf(bcd_dev_str, sizeof(bcd_dev_str), "0x%04x", bcd_device);
else
bcd_dev_str[0] = 0;
int found = 0;
bool bcd_match = false;
for (unsigned i = 0; i < knowndrives.size(); i++) {
const drive_settings & dbentry = knowndrives[i];
// Skip drive entries
if (!is_usb_entry(&dbentry))
continue;
// Check whether USB vendor:product ID matches
if (!match(dbentry.modelregexp, usb_id_str))
continue;
// Parse '-d type'
usb_dev_info d;
if (!parse_usb_type(dbentry.presets, d.usb_type))
return 0; // Syntax error
parse_usb_names(dbentry.modelfamily, d);
// If two entries with same vendor:product ID have different
// types, use bcd_device (if provided by OS) to select entry.
bool bm = ( *bcd_dev_str && *dbentry.firmwareregexp
&& match(dbentry.firmwareregexp, bcd_dev_str));
if (found == 0 || bm > bcd_match) {
info = d; found = 1;
bcd_match = bm;
}
else if (info.usb_type != d.usb_type && bm == bcd_match) {
// two different entries found
info2 = d; found = 2;
break;
}
}
return found;
}
// Shows one entry of knowndrives[], returns #errors. // Shows one entry of knowndrives[], returns #errors.
static int showonepreset(const drive_settings * dbentry) static int showonepreset(const drive_settings * dbentry)
{ {
@ -243,18 +341,22 @@ static int showonepreset(const drive_settings * dbentry)
return 1; return 1;
} }
bool usb = is_usb_entry(dbentry);
// print and check model and firmware regular expressions // print and check model and firmware regular expressions
int errcnt = 0; int errcnt = 0;
regular_expression regex; regular_expression regex;
pout("%-*s %s\n", TABLEPRINTWIDTH, "MODEL REGEXP:", dbentry->modelregexp); pout("%-*s %s\n", TABLEPRINTWIDTH, (!usb ? "MODEL REGEXP:" : "USB Vendor:Product:"),
dbentry->modelregexp);
if (!compile(regex, dbentry->modelregexp)) if (!compile(regex, dbentry->modelregexp))
errcnt++; errcnt++;
pout("%-*s %s\n", TABLEPRINTWIDTH, "FIRMWARE REGEXP:", *dbentry->firmwareregexp ? pout("%-*s %s\n", TABLEPRINTWIDTH, (!usb ? "FIRMWARE REGEXP:" : "USB bcdDevice:"),
dbentry->firmwareregexp : ".*"); // preserve old output (TODO: Change) *dbentry->firmwareregexp ? dbentry->firmwareregexp : ".*"); // preserve old output (TODO: Change)
if (*dbentry->firmwareregexp && !compile(regex, dbentry->firmwareregexp)) if (*dbentry->firmwareregexp && !compile(regex, dbentry->firmwareregexp))
errcnt++; errcnt++;
if (!usb) {
pout("%-*s %s\n", TABLEPRINTWIDTH, "MODEL FAMILY:", dbentry->modelfamily); pout("%-*s %s\n", TABLEPRINTWIDTH, "MODEL FAMILY:", dbentry->modelfamily);
// if there are any presets, then show them // if there are any presets, then show them
@ -297,6 +399,22 @@ static int showonepreset(const drive_settings * dbentry)
} }
pout("%-*s %s\n", TABLEPRINTWIDTH, "OTHER PRESETS:", fixdesc); pout("%-*s %s\n", TABLEPRINTWIDTH, "OTHER PRESETS:", fixdesc);
} }
}
else {
// Print USB info
usb_dev_info info; parse_usb_names(dbentry->modelfamily, info);
pout("%-*s %s\n", TABLEPRINTWIDTH, "USB Device:",
(!info.usb_device.empty() ? info.usb_device.c_str() : "[unknown]"));
pout("%-*s %s\n", TABLEPRINTWIDTH, "USB Bridge:",
(!info.usb_bridge.empty() ? info.usb_bridge.c_str() : "[unknown]"));
if (*dbentry->presets && !parse_usb_type(dbentry->presets, info.usb_type)) {
pout("Syntax error in USB type string \"%s\"\n", dbentry->presets);
errcnt++;
}
pout("%-*s %s\n", TABLEPRINTWIDTH, "USB Type",
(!info.usb_type.empty() ? info.usb_type.c_str() : "[unsupported]"));
}
// Print any special warnings // Print any special warnings
if (*dbentry->warningmsg) if (*dbentry->warningmsg)
@ -633,12 +751,21 @@ static bool parse_drive_database(parse_ptr src, drive_database & db, const char
break; break;
case 4: case 4:
if (!token.value.empty()) { if (!token.value.empty()) {
if (!is_usb_modelfamily(values[0].c_str())) {
ata_vendor_attr_defs defs; unsigned char fix = 0; ata_vendor_attr_defs defs; unsigned char fix = 0;
if (!parse_presets(token.value.c_str(), defs, fix)) { if (!parse_presets(token.value.c_str(), defs, fix)) {
pout("%s(%d): Syntax error in preset option string\n", path, token.line); pout("%s(%d): Syntax error in preset option string\n", path, token.line);
ok = false; ok = false;
} }
} }
else {
std::string type;
if (!parse_usb_type(token.value.c_str(), type)) {
pout("%s(%d): Syntax error in USB type string\n", path, token.line);
ok = false;
}
}
}
break; break;
} }
values[field] = token.value; values[field] = token.value;
@ -687,23 +814,45 @@ bool read_drive_database(const char * path)
return parse_drive_database(parse_ptr(f), knowndrives, path); return parse_drive_database(parse_ptr(f), knowndrives, path);
} }
// Get path for additional database file
const char * get_drivedb_path_add()
{
#ifndef _WIN32
return SMARTMONTOOLS_SYSCONFDIR"/smart_drivedb.h";
#else
static std::string path = get_exe_dir() + "/drivedb-add.h";
return path.c_str();
#endif
}
#ifdef SMARTMONTOOLS_DRIVEDBDIR
// Get path for default database file
const char * get_drivedb_path_default()
{
#ifndef _WIN32
return SMARTMONTOOLS_DRIVEDBDIR"/drivedb.h";
#else
static std::string path = get_exe_dir() + "/drivedb.h";
return path.c_str();
#endif
}
#endif
// Read drive databases from standard places. // Read drive databases from standard places.
bool read_default_drive_databases() bool read_default_drive_databases()
{ {
#ifndef _WIN32
// Read file for local additions: /{,usr/local/}etc/smart_drivedb.h // Read file for local additions: /{,usr/local/}etc/smart_drivedb.h
static const char db1[] = SMARTMONTOOLS_SYSCONFDIR"/smart_drivedb.h"; const char * db1 = get_drivedb_path_add();
#else
static const char db1[] = "./smart_drivedb.h";
#endif
if (!access(db1, 0)) { if (!access(db1, 0)) {
if (!read_drive_database(db1)) if (!read_drive_database(db1))
return false; return false;
} }
#ifdef SMARTMONTOOLS_DRIVEDBDIR #ifdef SMARTMONTOOLS_DRIVEDBDIR
// Read file from package: // /usr/{,local/}share/smartmontools/drivedb.h // Read file from package: /usr/{,local/}share/smartmontools/drivedb.h
static const char db2[] = SMARTMONTOOLS_DRIVEDBDIR"/drivedb.h"; const char * db2 = get_drivedb_path_default();
if (!access(db2, 0)) { if (!access(db2, 0)) {
if (!read_drive_database(db2)) if (!read_drive_database(db2))
return false; return false;

View File

@ -4,8 +4,8 @@
* Home page of code is: http://smartmontools.sourceforge.net * Home page of code is: http://smartmontools.sourceforge.net
* Address of support mailing list: smartmontools-support@lists.sourceforge.net * Address of support mailing list: smartmontools-support@lists.sourceforge.net
* *
* Copyright (C) 2003-9 Philip Williams, Bruce Allen * Copyright (C) 2003-10 Philip Williams, Bruce Allen
* Copyright (C) 2008-9 Christian Franke <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2008-10 Christian Franke <smartmontools-support@lists.sourceforge.net>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -21,7 +21,7 @@
#ifndef KNOWNDRIVES_H_ #ifndef KNOWNDRIVES_H_
#define KNOWNDRIVES_H_ #define KNOWNDRIVES_H_
#define KNOWNDRIVES_H_CVSID "$Id: knowndrives.h 2998 2009-12-11 22:51:04Z chrfranke $\n" #define KNOWNDRIVES_H_CVSID "$Id: knowndrives.h 3093 2010-04-30 09:57:36Z chrfranke $\n"
// Structure to store drive database entries, see drivedb.h for a description. // Structure to store drive database entries, see drivedb.h for a description.
struct drive_settings { struct drive_settings {
@ -36,6 +36,18 @@ struct drive_settings {
// string. // string.
const drive_settings * lookup_drive(const char * model, const char * firmware); const drive_settings * lookup_drive(const char * model, const char * firmware);
// info returned by lookup_usb_device()
struct usb_dev_info
{
std::string usb_device; // Device name, empty if unknown
std::string usb_bridge; // USB bridge name, empty if unknown
std::string usb_type; // Type string ('-d' option).
};
// Search drivedb for USB device with vendor:product ID.
int lookup_usb_device(int vendor_id, int product_id, int bcd_device,
usb_dev_info & info, usb_dev_info & info2);
// Shows the presets (if any) that are available for the given drive. // Shows the presets (if any) that are available for the given drive.
void show_presets(const ata_identify_device * drive, bool fix_swapped_id); void show_presets(const ata_identify_device * drive, bool fix_swapped_id);
@ -54,6 +66,14 @@ int showmatchingpresets(const char *model, const char *firmware);
bool apply_presets(const ata_identify_device * drive, ata_vendor_attr_defs & defs, bool apply_presets(const ata_identify_device * drive, ata_vendor_attr_defs & defs,
unsigned char & fix_firmwarebug, bool fix_swapped_id); unsigned char & fix_firmwarebug, bool fix_swapped_id);
// Get path for additional database file
const char * get_drivedb_path_add();
#ifdef SMARTMONTOOLS_DRIVEDBDIR
// Get path for default database file
const char * get_drivedb_path_default();
#endif
// Read drive database from file. // Read drive database from file.
bool read_drive_database(const char * path); bool read_drive_database(const char * path);

View File

@ -63,13 +63,20 @@ typedef struct
uint8_t status; uint8_t status;
} __attribute__((packed)) megacmd_t; } __attribute__((packed)) megacmd_t;
typedef struct { typedef union {
uint8_t *pointer; uint8_t *pointer;
#if BITS_PER_LONG == 32 uint8_t pad[8];
uint8_t pad[4];
#endif
} ptr_t; } ptr_t;
// The above definition assumes sizeof(void*) <= 8.
// This assumption also exists in the linux megaraid device driver.
// So define a macro to check expected size of ptr_t at compile time using
// a dummy typedef. On size mismatch, compiler reports a negative array
// size. If you see an error message of this form, it means that
// you have an unexpected pointer size on your platform and can not
// use megaraid support in smartmontools.
typedef char assert_sizeof_ptr_t[sizeof(ptr_t) == 8 ? 1 : -1];
struct uioctl_t struct uioctl_t
{ {
uint32_t inlen; uint32_t inlen;

View File

@ -71,9 +71,9 @@
#define PATHINQ_SETTINGS_SIZE 128 #define PATHINQ_SETTINGS_SIZE 128
#endif #endif
static __unused const char *filenameandversion="$Id: os_freebsd.cpp 3066 2010-02-15 23:10:49Z samm2 $"; static __unused const char *filenameandversion="$Id: os_freebsd.cpp 3098 2010-04-30 17:35:35Z chrfranke $";
const char *os_XXXX_c_cvsid="$Id: os_freebsd.cpp 3066 2010-02-15 23:10:49Z samm2 $" \ const char *os_XXXX_c_cvsid="$Id: os_freebsd.cpp 3098 2010-04-30 17:35:35Z chrfranke $" \
ATACMDS_H_CVSID CCISS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_FREEBSD_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID; ATACMDS_H_CVSID CCISS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_FREEBSD_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
extern smartmonctrl * con; extern smartmonctrl * con;
@ -121,7 +121,7 @@ void printwarning(int msgNo, const char* extra) {
// global variable holding byte count of allocated memory // global variable holding byte count of allocated memory
long long bytes; long long bytes;
const char * dev_freebsd_cpp_cvsid = "$Id: os_freebsd.cpp 3066 2010-02-15 23:10:49Z samm2 $" const char * dev_freebsd_cpp_cvsid = "$Id: os_freebsd.cpp 3098 2010-04-30 17:35:35Z chrfranke $"
DEV_INTERFACE_H_CVSID; DEV_INTERFACE_H_CVSID;
extern smartmonctrl * con; // con->reportscsiioctl extern smartmonctrl * con; // con->reportscsiioctl
@ -1823,8 +1823,8 @@ smart_device * freebsd_smart_interface::get_custom_smart_device(const char * nam
set_err(EINVAL, "Option -d cciss,N requires N to be a non-negative integer"); set_err(EINVAL, "Option -d cciss,N requires N to be a non-negative integer");
return 0; return 0;
} }
if (!(0 <= disknum && disknum <= 15)) { if (!(0 <= disknum && disknum <= 127)) {
set_err(EINVAL, "Option -d cciss,N (N=%d) must have 0 <= N <= 15", disknum); set_err(EINVAL, "Option -d cciss,N (N=%d) must have 0 <= N <= 127", disknum);
return 0; return 0;
} }
return new freebsd_cciss_device(this, name, disknum); return new freebsd_cciss_device(this, name, disknum);

View File

@ -4,7 +4,7 @@
* Home page of code is: http://smartmontools.sourceforge.net * Home page of code is: http://smartmontools.sourceforge.net
* *
* Copyright (C) 2003-10 Bruce Allen <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2003-10 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2003-10 Doug Gilbert <dougg@torque.net> * Copyright (C) 2003-10 Doug Gilbert <dgilbert@interlog.com>
* Copyright (C) 2008 Hank Wu <hank@areca.com.tw> * Copyright (C) 2008 Hank Wu <hank@areca.com.tw>
* Copyright (C) 2008 Oliver Bock <brevilo@users.sourceforge.net> * Copyright (C) 2008 Oliver Bock <brevilo@users.sourceforge.net>
* Copyright (C) 2008-10 Christian Franke <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2008-10 Christian Franke <smartmontools-support@lists.sourceforge.net>
@ -90,7 +90,7 @@
#define ARGUSED(x) ((void)(x)) #define ARGUSED(x) ((void)(x))
const char *os_XXXX_c_cvsid="$Id: os_linux.cpp 3076 2010-03-12 22:23:08Z chrfranke $" \ const char *os_XXXX_c_cvsid="$Id: os_linux.cpp 3098 2010-04-30 17:35:35Z chrfranke $" \
ATACMDS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_LINUX_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID; ATACMDS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_LINUX_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
/* for passing global control variables */ /* for passing global control variables */
@ -3176,8 +3176,8 @@ smart_device * linux_smart_interface::get_custom_smart_device(const char * name,
set_err(EINVAL, "Option -d cciss,N requires N to be a non-negative integer"); set_err(EINVAL, "Option -d cciss,N requires N to be a non-negative integer");
return 0; return 0;
} }
if (!(0 <= disknum && disknum <= 15)) { if (!(0 <= disknum && disknum <= 127)) {
set_err(EINVAL, "Option -d cciss,N (N=%d) must have 0 <= N <= 15", disknum); set_err(EINVAL, "Option -d cciss,N (N=%d) must have 0 <= N <= 127", disknum);
return 0; return 0;
} }
return new linux_cciss_device(this, name, disknum); return new linux_cciss_device(this, name, disknum);

View File

@ -18,7 +18,7 @@
// should have one *_H_CVSID macro appearing below for each file // should have one *_H_CVSID macro appearing below for each file
// appearing with #include "*.h" above. Please list these (below) in // appearing with #include "*.h" above. Please list these (below) in
// alphabetic/dictionary order. // alphabetic/dictionary order.
const char *os_XXXX_c_cvsid="$Id: os_qnxnto.cpp,v 1.3 2008/06/12 21:46:31 ballen4705 Exp $" \ const char *os_XXXX_c_cvsid="$Id: os_qnxnto.cpp 3110 2010-05-24 20:38:38Z chrfranke $" \
ATACMDS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_QNXNTO_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID; ATACMDS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_QNXNTO_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
@ -624,7 +624,7 @@ struct cam_pass_thru cpt;
cpt.cam_timeout=cpt.cam_timeout?cpt.cam_timeout:CAM_TIME_DEFAULT; cpt.cam_timeout=cpt.cam_timeout?cpt.cam_timeout:CAM_TIME_DEFAULT;
if(cpt.cam_sense_len) if(cpt.cam_sense_len)
{ {
SETIOV(&iov[1],cpt.cam_sense_ptr,cpt.cam_sense_len); SETIOV(&iov[1],(void *)cpt.cam_sense_ptr,cpt.cam_sense_len);
cpt.cam_sense_ptr=sizeof(cpt); cpt.cam_sense_ptr=sizeof(cpt);
icnt++; icnt++;
} }

View File

@ -69,7 +69,7 @@ extern smartmonctrl * con; // con->permissive,reportataioctl
#define SELECT_WIN_32_64(x32, x64) (x64) #define SELECT_WIN_32_64(x32, x64) (x64)
#endif #endif
const char * os_win32_cpp_cvsid = "$Id: os_win32.cpp 3062 2010-02-09 21:02:27Z chrfranke $"; const char * os_win32_cpp_cvsid = "$Id: os_win32.cpp 3118 2010-06-08 17:30:46Z chrfranke $";
// Disable Win9x/ME specific code if no longer supported by compiler. // Disable Win9x/ME specific code if no longer supported by compiler.
#ifdef _WIN64 #ifdef _WIN64
@ -1740,9 +1740,9 @@ static int storage_query_property_ioctl(HANDLE hdevice, STORAGE_DEVICE_DESCRIPTO
" Revision: \"%s\"\n" " Revision: \"%s\"\n"
" Removable: %s\n" " Removable: %s\n"
" BusType: 0x%02x\n", " BusType: 0x%02x\n",
(data->desc.VendorIdOffset ? data->raw+data->desc.VendorIdOffset : ""), (data->desc.VendorIdOffset ? data->raw+data->desc.VendorIdOffset : "(null)"),
(data->desc.ProductIdOffset ? data->raw+data->desc.ProductIdOffset : ""), (data->desc.ProductIdOffset ? data->raw+data->desc.ProductIdOffset : "(null)"),
(data->desc.ProductRevisionOffset ? data->raw+data->desc.ProductRevisionOffset : ""), (data->desc.ProductRevisionOffset ? data->raw+data->desc.ProductRevisionOffset : "(null)"),
(data->desc.RemovableMedia? "Yes":"No"), data->desc.BusType (data->desc.RemovableMedia? "Yes":"No"), data->desc.BusType
); );
} }
@ -1869,10 +1869,32 @@ static int get_identify_from_device_property(HANDLE hdevice, ata_identify_device
return -1; return -1;
memset(id, 0, sizeof(*id)); memset(id, 0, sizeof(*id));
if (data.desc.ProductIdOffset)
copy_swapped(id->model, data.raw+data.desc.ProductIdOffset, sizeof(id->model)); // Some drivers split ATA model string into VendorId and ProductId,
// others return it as ProductId only.
char model[sizeof(id->model) + 1] = "";
unsigned i = 0;
if (data.desc.VendorIdOffset) {
for ( ;i < sizeof(model)-1 && data.raw[data.desc.VendorIdOffset+i]; i++)
model[i] = data.raw[data.desc.VendorIdOffset+i];
}
if (data.desc.ProductIdOffset) {
while (i > 1 && model[i-2] == ' ') // Keep last blank from VendorId
i--;
for (unsigned j = 0; i < sizeof(model)-1 && data.raw[data.desc.ProductIdOffset+j]; i++, j++)
model[i] = data.raw[data.desc.ProductIdOffset+j];
}
while (i > 0 && model[i-1] == ' ')
i--;
model[i] = 0;
copy_swapped(id->model, model, sizeof(id->model));
if (data.desc.ProductRevisionOffset) if (data.desc.ProductRevisionOffset)
copy_swapped(id->fw_rev, data.raw+data.desc.ProductRevisionOffset, sizeof(id->fw_rev)); copy_swapped(id->fw_rev, data.raw+data.desc.ProductRevisionOffset, sizeof(id->fw_rev));
id->command_set_1 = 0x0001; id->command_set_2 = 0x4000; // SMART supported, words 82,83 valid id->command_set_1 = 0x0001; id->command_set_2 = 0x4000; // SMART supported, words 82,83 valid
id->cfs_enable_1 = 0x0001; id->csf_default = 0x4000; // SMART enabled, words 85,87 valid id->cfs_enable_1 = 0x0001; id->csf_default = 0x4000; // SMART enabled, words 85,87 valid
return 0; return 0;
@ -3580,3 +3602,27 @@ void smart_interface::init()
} }
} }
#ifndef __CYGWIN__
// Get exe directory
// (prototype in utiliy.h)
std::string get_exe_dir()
{
char path[MAX_PATH];
// Get path of this exe
if (!GetModuleFileNameA(GetModuleHandleA(0), path, sizeof(path)))
throw std::runtime_error("GetModuleFileName() failed");
// Replace backslash by slash
int sl = -1;
for (int i = 0; path[i]; i++)
if (path[i] == '\\') {
path[i] = '/'; sl = i;
}
// Remove filename
if (sl >= 0)
path[sl] = 0;
return path;
}
#endif

View File

@ -40,7 +40,7 @@
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="0"
AdditionalIncludeDirectories=".,..\posix" AdditionalIncludeDirectories=".,..\getopt,..\regex"
PreprocessorDefinitions="_DEBUG;HAVE_CONFIG_H;_ERRCODE_DEFINED;errno_t=int;_USE_32BIT_TIME_T;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE" PreprocessorDefinitions="_DEBUG;HAVE_CONFIG_H;_ERRCODE_DEFINED;errno_t=int;_USE_32BIT_TIME_T;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE"
MinimalRebuild="true" MinimalRebuild="true"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
@ -116,7 +116,7 @@
/> />
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
AdditionalIncludeDirectories=".,..\posix" AdditionalIncludeDirectories=".,..\getopt,..\regex"
PreprocessorDefinitions="NDEBUG;HAVE_CONFIG_H;_ERRCODE_DEFINED;errno_t=int;_USE_32BIT_TIME_T;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE" PreprocessorDefinitions="NDEBUG;HAVE_CONFIG_H;_ERRCODE_DEFINED;errno_t=int;_USE_32BIT_TIME_T;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE"
RuntimeLibrary="2" RuntimeLibrary="2"
UsePrecompiledHeader="0" UsePrecompiledHeader="0"
@ -302,22 +302,10 @@
</File> </File>
</Filter> </Filter>
<Filter <Filter
Name="posix" Name="regex"
> >
<File <File
RelativePath="..\posix\getopt.c" RelativePath="..\regex\regcomp.c"
>
</File>
<File
RelativePath="..\posix\getopt.h"
>
</File>
<File
RelativePath="..\posix\getopt1.c"
>
</File>
<File
RelativePath="..\posix\regcomp.c"
> >
<FileConfiguration <FileConfiguration
Name="Debug|Win32" Name="Debug|Win32"
@ -337,15 +325,15 @@
</FileConfiguration> </FileConfiguration>
</File> </File>
<File <File
RelativePath="..\posix\regex.c" RelativePath="..\regex\regex.c"
> >
</File> </File>
<File <File
RelativePath="..\posix\regex.h" RelativePath="..\regex\regex.h"
> >
</File> </File>
<File <File
RelativePath="..\posix\regex_internal.c" RelativePath="..\regex\regex_internal.c"
> >
<FileConfiguration <FileConfiguration
Name="Debug|Win32" Name="Debug|Win32"
@ -365,11 +353,11 @@
</FileConfiguration> </FileConfiguration>
</File> </File>
<File <File
RelativePath="..\posix\regex_internal.h" RelativePath="..\regex\regex_internal.h"
> >
</File> </File>
<File <File
RelativePath="..\posix\regexec.c" RelativePath="..\regex\regexec.c"
> >
<FileConfiguration <FileConfiguration
Name="Debug|Win32" Name="Debug|Win32"
@ -389,6 +377,22 @@
</FileConfiguration> </FileConfiguration>
</File> </File>
</Filter> </Filter>
<Filter
Name="getopt"
>
<File
RelativePath="..\getopt\getopt.c"
>
</File>
<File
RelativePath="..\getopt\getopt.h"
>
</File>
<File
RelativePath="..\getopt\getopt1.c"
>
</File>
</Filter>
<File <File
RelativePath="..\atacmdnames.cpp" RelativePath="..\atacmdnames.cpp"
> >

View File

@ -40,7 +40,7 @@
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" Optimization="0"
AdditionalIncludeDirectories=".,..\posix" AdditionalIncludeDirectories=".,..\getopt,..\regex"
PreprocessorDefinitions="_DEBUG;HAVE_CONFIG_H;_ERRCODE_DEFINED;errno_t=int;_USE_32BIT_TIME_T;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE" PreprocessorDefinitions="_DEBUG;HAVE_CONFIG_H;_ERRCODE_DEFINED;errno_t=int;_USE_32BIT_TIME_T;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE"
MinimalRebuild="true" MinimalRebuild="true"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
@ -116,7 +116,7 @@
/> />
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
AdditionalIncludeDirectories=".,..\posix" AdditionalIncludeDirectories=".,..\getopt,..\regex"
PreprocessorDefinitions="NDEBUG;HAVE_CONFIG_H;_ERRCODE_DEFINED;errno_t=int;_USE_32BIT_TIME_T;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE" PreprocessorDefinitions="NDEBUG;HAVE_CONFIG_H;_ERRCODE_DEFINED;errno_t=int;_USE_32BIT_TIME_T;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE"
RuntimeLibrary="2" RuntimeLibrary="2"
UsePrecompiledHeader="0" UsePrecompiledHeader="0"
@ -206,22 +206,10 @@
</File> </File>
</Filter> </Filter>
<Filter <Filter
Name="posix" Name="regex"
> >
<File <File
RelativePath="..\posix\getopt.c" RelativePath="..\regex\regcomp.c"
>
</File>
<File
RelativePath="..\posix\getopt.h"
>
</File>
<File
RelativePath="..\posix\getopt1.c"
>
</File>
<File
RelativePath="..\posix\regcomp.c"
> >
<FileConfiguration <FileConfiguration
Name="Debug|Win32" Name="Debug|Win32"
@ -241,15 +229,15 @@
</FileConfiguration> </FileConfiguration>
</File> </File>
<File <File
RelativePath="..\posix\regex.c" RelativePath="..\regex\regex.c"
> >
</File> </File>
<File <File
RelativePath="..\posix\regex.h" RelativePath="..\regex\regex.h"
> >
</File> </File>
<File <File
RelativePath="..\posix\regex_internal.c" RelativePath="..\regex\regex_internal.c"
> >
<FileConfiguration <FileConfiguration
Name="Debug|Win32" Name="Debug|Win32"
@ -269,11 +257,11 @@
</FileConfiguration> </FileConfiguration>
</File> </File>
<File <File
RelativePath="..\posix\regex_internal.h" RelativePath="..\regex\regex_internal.h"
> >
</File> </File>
<File <File
RelativePath="..\posix\regexec.c" RelativePath="..\regex\regexec.c"
> >
<FileConfiguration <FileConfiguration
Name="Debug|Win32" Name="Debug|Win32"
@ -293,6 +281,22 @@
</FileConfiguration> </FileConfiguration>
</File> </File>
</Filter> </Filter>
<Filter
Name="getopt"
>
<File
RelativePath="..\getopt\getopt.c"
>
</File>
<File
RelativePath="..\getopt\getopt.h"
>
</File>
<File
RelativePath="..\getopt\getopt1.c"
>
</File>
</Filter>
<File <File
RelativePath="..\atacmdnames.cpp" RelativePath="..\atacmdnames.cpp"
> >

View File

@ -3,7 +3,7 @@
* *
* Home page of code is: http://smartmontools.sourceforge.net * Home page of code is: http://smartmontools.sourceforge.net
* *
* Copyright (C) 2006-10 Douglas Gilbert <dougg@torque.net> * Copyright (C) 2006-10 Douglas Gilbert <dgilbert@interlog.com>
* Copyright (C) 2009-10 Christian Franke <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2009-10 Christian Franke <smartmontools-support@lists.sourceforge.net>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -56,12 +56,13 @@
#include "extern.h" #include "extern.h"
#include "scsicmds.h" #include "scsicmds.h"
#include "atacmds.h" // ataReadHDIdentity() #include "atacmds.h" // ataReadHDIdentity()
#include "knowndrives.h" // lookup_usb_device()
#include "utility.h" #include "utility.h"
#include "dev_interface.h" #include "dev_interface.h"
#include "dev_ata_cmd_set.h" // ata_device_with_command_set #include "dev_ata_cmd_set.h" // ata_device_with_command_set
#include "dev_tunnelled.h" // tunnelled_device<> #include "dev_tunnelled.h" // tunnelled_device<>
const char * scsiata_cpp_cvsid = "$Id: scsiata.cpp 3077 2010-03-16 20:48:06Z chrfranke $"; const char * scsiata_cpp_cvsid = "$Id: scsiata.cpp 3095 2010-04-30 12:33:27Z dpgilbert $";
/* for passing global control variables */ /* for passing global control variables */
extern smartmonctrl *con; extern smartmonctrl *con;
@ -1321,99 +1322,6 @@ ata_device * smart_interface::autodetect_sat_device(scsi_device * scsidev,
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// USB device type detection // USB device type detection
struct usb_id_entry {
int vendor_id, product_id, version;
const char * type;
};
const char d_sat[] = "sat";
const char d_cypress[] = "usbcypress";
const char d_jmicron[] = "usbjmicron";
const char d_jmicron_x[] = "usbjmicron,x";
const char d_sunplus[] = "usbsunplus";
const char d_unsup[] = "unsupported";
// Map USB IDs -> '-d type' string
const usb_id_entry usb_ids[] = {
// Cypress
{ 0x04b4, 0x6830, 0x0001, d_unsup }, // Cypress CY7C68300A (AT2)
{ 0x04b4, 0x6830, 0x0240, d_cypress }, // Cypress CY7C68300B/C (AT2LP)
//{ 0x04b4, 0x6831, -1, d_cypress }, // Cypress CY7C68310 (ISD-300LP)
// Myson Century
{ 0x04cf, 0x8818, 0xb007, d_unsup }, // Myson Century CS8818
// Samsung
{ 0x04e8, 0x5f06, -1, d_sat }, // Samsung Story Station
// Sunplus
{ 0x04fc, 0x0c15, 0xf615, d_sunplus }, // SunPlus SPDIF215
{ 0x04fc, 0x0c25, 0x0103, d_sunplus }, // SunPlus SPDIF225 (USB+SATA->SATA)
// Iomega
{ 0x059b, 0x0272, -1, d_cypress }, // Iomega LPHD080-0
{ 0x059b, 0x0275, 0x0001, d_unsup }, // Iomega MDHD500-U
// LaCie
{ 0x059f, 0x0651, -1, d_unsup }, // LaCie hard disk (FA Porsche design)
{ 0x059f, 0x1018, -1, d_sat }, // LaCie hard disk (Neil Poulton design)
{ 0x059f, 0x1019, -1, d_jmicron }, // LaCie Desktop Hard Drive
// In-System Design
{ 0x05ab, 0x0060, 0x1101, d_cypress }, // In-System/Cypress ISD-300A1
// Genesys Logic
{ 0x05e3, 0x0702, -1, d_unsup }, // Genesys Logic GL881E
{ 0x05e3, 0x0718, 0x0041, d_sat }, // Genesys Logic ? (TODO: requires '-T permissive')
// Prolific
{ 0x067b, 0x2507, -1, d_unsup }, // Prolific PL2507 (USB->PATA)
{ 0x067b, 0x3507, 0x0001, d_unsup }, // Prolific PL3507 (USB+IEE1394->PATA)
// Freecom
{ 0x07ab, 0xfc8e, 0x010f, d_sunplus }, // Freecom Hard Drive XS
// Toshiba
{ 0x0930, 0x0b03, -1, d_sunplus }, // Toshiba PX1270E-1G16
{ 0x0930, 0x0b09, -1, d_sunplus }, // Toshiba PX1396E-3T01 (similar to Dura Micro 501)
// Seagate
{ 0x0bc2, 0x2000, -1, d_sat }, // Seagate FreeAgent Go
{ 0x0bc2, 0x2100, -1, d_sat }, // Seagate FreeAgent Go
{ 0x0bc2, 0x2101, -1, d_sat }, // Seagate FreeAgent Go
{ 0x0bc2, 0x2200, -1, d_sat }, // Seagate FreeAgent Go FW
{ 0x0bc2, 0x2300, -1, d_sat }, // Seagate Expansion Portable
{ 0x0bc2, 0x3000, -1, d_sat }, // Seagate FreeAgent Desktop
{ 0x0bc2, 0x3001, -1, d_sat }, // Seagate FreeAgent Desk
// Dura Micro
{ 0x0c0b, 0xb159, 0x0103, d_sunplus }, // Dura Micro 509
// Maxtor
{ 0x0d49, 0x7310, 0x0125, d_sat }, // Maxtor OneTouch 4
{ 0x0d49, 0x7350, 0x0125, d_sat }, // Maxtor OneTouch 4 Mini
{ 0x0d49, 0x7410, 0x0122, d_sat }, // Maxtor Basics Desktop
{ 0x0d49, 0x7450, 0x0122, d_sat }, // Maxtor Basics Portable
// Western Digital
{ 0x1058, 0x0701, 0x0240, d_cypress }, // WD My Passport (IDE)
{ 0x1058, 0x0702, 0x0102, d_sat }, // WD My Passport Portable
{ 0x1058, 0x0704, 0x0175, d_sat }, // WD My Passport Essential
{ 0x1058, 0x0705, 0x0175, d_sat }, // WD My Passport Elite
{ 0x1058, 0x070a, 0x1028, d_sat }, // WD My Passport 070A
{ 0x1058, 0x0906, 0x0012, d_sat }, // WD My Book ES
{ 0x1058, 0x1001, 0x0104, d_sat }, // WD Elements Desktop
{ 0x1058, 0x1003, 0x0175, d_sat }, // WD Elements Desktop WDE1UBK...
{ 0x1058, 0x1010, 0x0105, d_sat }, // WD Elements
{ 0x1058, 0x1100, 0x0165, d_sat }, // WD My Book Essential
{ 0x1058, 0x1102, 0x1028, d_sat }, // WD My Book
{ 0x1058, 0x1110, 0x1030, d_sat }, // WD My Book Essential
// Initio
{ 0x13fd, 0x0540, -1, d_unsup }, // Initio 316000
{ 0x13fd, 0x1240, 0x0104, d_sat }, // Initio ? (USB->SATA)
{ 0x13fd, 0x1340, 0x0208, d_sat }, // Initio ? (USB+SATA->SATA)
// JMicron
{ 0x152d, 0x2329, 0x0100, d_jmicron }, // JMicron JM20329 (USB->SATA)
{ 0x152d, 0x2336, 0x0100, d_jmicron_x},// JMicron JM20336 (USB+SATA->SATA, USB->2xSATA)
{ 0x152d, 0x2338, 0x0100, d_jmicron }, // JMicron JM20337/8 (USB->SATA+PATA, USB+SATA->PATA)
{ 0x152d, 0x2339, 0x0100, d_jmicron_x},// JMicron JM20339 (USB->SATA)
// Verbatim
{ 0x18a5, 0x0215, 0x0001, d_sat }, // Verbatim FW/USB160 - Oxford OXUF934SSA-LQAG (USB+IEE1394->SATA)
// SunplusIT
{ 0x1bcf, 0x0c31, -1, d_sunplus }, // SunplusIT
// OnSpec
{ 0x55aa, 0x2b00, 0x0100, d_unsup } // OnSpec ? (USB->PATA)
};
const unsigned num_usb_ids = sizeof(usb_ids)/sizeof(usb_ids[0]);
// Format USB ID for error messages // Format USB ID for error messages
static std::string format_usb_id(int vendor_id, int product_id, int version) static std::string format_usb_id(int vendor_id, int product_id, int version)
{ {
@ -1427,41 +1335,31 @@ static std::string format_usb_id(int vendor_id, int product_id, int version)
const char * smart_interface::get_usb_dev_type_by_id(int vendor_id, int product_id, const char * smart_interface::get_usb_dev_type_by_id(int vendor_id, int product_id,
int version /*= -1*/) int version /*= -1*/)
{ {
const usb_id_entry * entry = 0; usb_dev_info info, info2;
bool state = false; int n = lookup_usb_device(vendor_id, product_id, version, info, info2);
for (unsigned i = 0; i < num_usb_ids; i++) { if (n <= 0) {
const usb_id_entry & e = usb_ids[i];
if (!(vendor_id == e.vendor_id && product_id == e.product_id))
continue;
// If two entries with same vendor:product ID have different
// types, use version (if provided by OS) to select entry.
bool s = (version >= 0 && version == e.version);
if (entry) {
if (s <= state) {
if (s == state && e.type != entry->type) {
set_err(EINVAL, "USB bridge %s type is ambiguous: '%s' or '%s'",
format_usb_id(vendor_id, product_id, version).c_str(),
e.type, entry->type);
return 0;
}
continue;
}
}
state = s;
entry = &e;
}
if (!entry) {
set_err(EINVAL, "Unknown USB bridge %s", set_err(EINVAL, "Unknown USB bridge %s",
format_usb_id(vendor_id, product_id, version).c_str()); format_usb_id(vendor_id, product_id, version).c_str());
return 0; return 0;
} }
if (entry->type == d_unsup) {
if (n > 1) {
set_err(EINVAL, "USB bridge %s type is ambiguous: '%s' or '%s'",
format_usb_id(vendor_id, product_id, version).c_str(),
(!info.usb_type.empty() ? info.usb_type.c_str() : "[unsupported]"),
(!info2.usb_type.empty() ? info2.usb_type.c_str() : "[unsupported]"));
return 0;
}
if (info.usb_type.empty()) {
set_err(ENOSYS, "Unsupported USB bridge %s", set_err(ENOSYS, "Unsupported USB bridge %s",
format_usb_id(vendor_id, product_id, version).c_str()); format_usb_id(vendor_id, product_id, version).c_str());
return 0; return 0;
} }
return entry->type;
// TODO: change return type to std::string
static std::string type;
type = info.usb_type;
return type.c_str();
} }

View File

@ -7,7 +7,7 @@
* Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org> * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
* *
* Additional SCSI work: * Additional SCSI work:
* Copyright (C) 2003-8 Douglas Gilbert <dougg@torque.net> * Copyright (C) 2003-10 Douglas Gilbert <dgilbert@interlog.com>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -49,7 +49,7 @@
#include "dev_interface.h" #include "dev_interface.h"
#include "utility.h" #include "utility.h"
const char *scsicmds_c_cvsid="$Id: scsicmds.cpp,v 1.98 2009/06/24 04:10:10 dpgilbert Exp $" const char *scsicmds_c_cvsid="$Id: scsicmds.cpp 3096 2010-04-30 14:32:49Z chrfranke $"
CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID; CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
/* for passing global control variables */ /* for passing global control variables */

View File

@ -7,7 +7,7 @@
* Copyright (C) 2000 Michael Cornwell <cornwell@acm.org> * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
* *
* Additional SCSI work: * Additional SCSI work:
* Copyright (C) 2003-8 Douglas Gilbert <dougg@torque.net> * Copyright (C) 2003-10 Douglas Gilbert <dgilbert@interlog.com>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -32,7 +32,7 @@
#ifndef SCSICMDS_H_ #ifndef SCSICMDS_H_
#define SCSICMDS_H_ #define SCSICMDS_H_
#define SCSICMDS_H_CVSID "$Id: scsicmds.h 2924 2009-09-26 20:38:40Z chrfranke $\n" #define SCSICMDS_H_CVSID "$Id: scsicmds.h 3095 2010-04-30 12:33:27Z dpgilbert $\n"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>

View File

@ -7,7 +7,7 @@
* Copyright (C) 2000 Michael Cornwell <cornwell@acm.org> * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
* *
* Additional SCSI work: * Additional SCSI work:
* Copyright (C) 2003-9 Douglas Gilbert <dougg@torque.net> * Copyright (C) 2003-10 Douglas Gilbert <dgilbert@interlog.com>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -43,7 +43,7 @@
#define GBUF_SIZE 65535 #define GBUF_SIZE 65535
const char * scsiprint_c_cvsid = "$Id: scsiprint.cpp 2861 2009-07-24 16:47:03Z chrfranke $" const char * scsiprint_c_cvsid = "$Id: scsiprint.cpp 3095 2010-04-30 12:33:27Z dpgilbert $"
SCSIPRINT_H_CVSID; SCSIPRINT_H_CVSID;
// control block which points to external global control variables // control block which points to external global control variables

View File

@ -7,7 +7,7 @@
* Copyright (C) 2000 Michael Cornwell <cornwell@acm.org> * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
* *
* Additional SCSI work: * Additional SCSI work:
* Copyright (C) 2003-9 Douglas Gilbert <dougg@torque.net> * Copyright (C) 2003-10 Douglas Gilbert <dgilbert@interlog.com>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -29,7 +29,7 @@
#ifndef SCSI_PRINT_H_ #ifndef SCSI_PRINT_H_
#define SCSI_PRINT_H_ #define SCSI_PRINT_H_
#define SCSIPRINT_H_CVSID "$Id: scsiprint.h,v 1.24 2009/06/21 02:39:32 dpgilbert Exp $\n" #define SCSIPRINT_H_CVSID "$Id: scsiprint.h 3096 2010-04-30 14:32:49Z chrfranke $\n"
// Options for scsiPrintMain // Options for scsiPrintMain
// TODO: Move remaining options from con->* to here. // TODO: Move remaining options from con->* to here.

View File

@ -1,7 +1,7 @@
.ig .ig
Copyright (C) 2002-9 Bruce Allen <smartmontools-support@lists.sourceforge.net> Copyright (C) 2002-10 Bruce Allen <smartmontools-support@lists.sourceforge.net>
$Id: smartctl.8.in 3072 2010-03-04 21:56:41Z chrfranke $ $Id: smartctl.8.in 3119 2010-06-11 16:21:25Z chrfranke $
This program is free software; you can redistribute it and/or modify it 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 under the terms of the GNU General Public License as published by the Free
@ -18,7 +18,7 @@
California, Santa Cruz. http://ssrc.soe.ucsc.edu/ California, Santa Cruz. http://ssrc.soe.ucsc.edu/
.. ..
.TH SMARTCTL 8 CURRENT_CVS_DATE CURRENT_CVS_VERSION CURRENT_CVS_DATE .TH SMARTCTL 8 CURRENT_SVN_DATE CURRENT_SVN_VERSION CURRENT_SVN_DATE
.SH NAME .SH NAME
\fBsmartctl\fP \- Control and Monitor Utility for SMART Disks \fBsmartctl\fP \- Control and Monitor Utility for SMART Disks
@ -29,7 +29,7 @@
.B /usr/local/sbin/smartctl .B /usr/local/sbin/smartctl
.SH PACKAGE VERSION .SH PACKAGE VERSION
CURRENT_CVS_VERSION released CURRENT_CVS_DATE at CURRENT_CVS_TIME CURRENT_SVN_VERSION CURRENT_SVN_DATE CURRENT_SVN_REV
.SH DESCRIPTION .SH DESCRIPTION
\fBsmartctl\fP controls the Self\-Monitoring, Analysis and Reporting \fBsmartctl\fP controls the Self\-Monitoring, Analysis and Reporting
@ -143,10 +143,6 @@ The options are grouped below into several categories. \fBsmartctl\fP
will execute the corresponding commands in the order: INFORMATION, will execute the corresponding commands in the order: INFORMATION,
ENABLE/DISABLE, DISPLAY DATA, RUN/ABORT TESTS. ENABLE/DISABLE, DISPLAY DATA, RUN/ABORT TESTS.
Long options are not supported on all systems. Use
.B \'smartctl \-h\'
to see the available options.
.TP .TP
.B SHOW INFORMATION OPTIONS: .B SHOW INFORMATION OPTIONS:
.TP .TP
@ -195,6 +191,18 @@ and for SCSI, this is equivalent to
.nf .nf
\'\-H \-i \-A \-l error \-l selftest \-l background \-l sasphy\'. \'\-H \-i \-A \-l error \-l selftest \-l background \-l sasphy\'.
.fi .fi
.TP
.B \-\-scan
Scans for devices and prints each device name, device type and protocol
([ATA] or [SCSI]) info. May be used in conjunction with \'\-d TYPE\'
to restrict the scan to a specific TYPE. See also info about platform
specific device scan and the \fBDEVICESCAN\fP directive on
\fBsmartd\fP(8) man page.
.TP
.B \-\-scan\-open
Same as \-\-scan, but also tries to open each device before printing
device info. The device open may change the device type due
to autodetection (see also \'\-d test\').
.TP .TP
.B RUN\-TIME BEHAVIOR OPTIONS: .B RUN\-TIME BEHAVIOR OPTIONS:
@ -218,7 +226,6 @@ use the exit status of \fBsmartctl\fP (see RETURN VALUES below).
.I noserial .I noserial
\- Do not print the serial number of the device. \- Do not print the serial number of the device.
.TP .TP
.B \-d TYPE, \-\-device=TYPE .B \-d TYPE, \-\-device=TYPE
Specifies the type of the device. The valid arguments to this option Specifies the type of the device. The valid arguments to this option
@ -406,7 +413,6 @@ of the HighPoint RocketRAID controller.
.B HighPoint RocketRAID controllers are currently ONLY supported under Linux and FreeBSD. .B HighPoint RocketRAID controllers are currently ONLY supported under Linux and FreeBSD.
.B cciss controllers are currently ONLY supported under Linux and FreeBSD. .B cciss controllers are currently ONLY supported under Linux and FreeBSD.
.TP .TP
.B \-T TYPE, \-\-tolerance=TYPE .B \-T TYPE, \-\-tolerance=TYPE
[ATA only] Specifies how tolerant \fBsmartctl\fP should be of ATA and SMART [ATA only] Specifies how tolerant \fBsmartctl\fP should be of ATA and SMART
@ -447,7 +453,6 @@ such cases, contrary to the final message, Feature X \fBis\fP enabled.
\- equivalent to giving a large number of \'\-T permissive\' options: \- equivalent to giving a large number of \'\-T permissive\' options:
ignore failures of \fBany number\fP of \fBmandatory\fP SMART commands. ignore failures of \fBany number\fP of \fBmandatory\fP SMART commands.
Please see the note above. Please see the note above.
.TP .TP
.B \-b TYPE, \-\-badsum=TYPE .B \-b TYPE, \-\-badsum=TYPE
[ATA only] Specifies the action \fBsmartctl\fP should take if a checksum [ATA only] Specifies the action \fBsmartctl\fP should take if a checksum
@ -466,7 +471,6 @@ default.
.I ignore .I ignore
\- continue silently without issuing a warning. \- continue silently without issuing a warning.
.TP .TP
.B \-r TYPE, \-\-report=TYPE .B \-r TYPE, \-\-report=TYPE
Intended primarily to help \fBsmartmontools\fP developers understand Intended primarily to help \fBsmartmontools\fP developers understand
@ -503,7 +507,6 @@ The ATA command input parameters, sector data and return values are
reconstructed from the debug report read from stdin. reconstructed from the debug report read from stdin.
Then \fBsmartctl\fP internally simulates an ATA device with the same Then \fBsmartctl\fP internally simulates an ATA device with the same
behaviour. This is does not work for SCSI devices yet. behaviour. This is does not work for SCSI devices yet.
.TP .TP
.B \-n POWERMODE, \-\-nocheck=POWERMODE .B \-n POWERMODE, \-\-nocheck=POWERMODE
[ATA only] Specifies if \fBsmartctl\fP should exit before performing any [ATA only] Specifies if \fBsmartctl\fP should exit before performing any
@ -621,13 +624,17 @@ connection with the second category just described, e.g. for the
connection with the third category. connection with the third category.
.TP .TP
.B \-S VALUE, \-\-saveauto=VALUE .B \-S VALUE, \-\-saveauto=VALUE
Enables or disables SMART autosave of device vendor\-specific [ATA] Enables or disables SMART autosave of device vendor\-specific
Attributes. The valid arguments to this option are \fIon\fP Attributes. The valid arguments to this option are \fIon\fP
and \fIoff\fP. Note that this feature is preserved across disk power and \fIoff\fP. Note that this feature is preserved across disk power
cycles, so you should only need to issue it once. cycles, so you should only need to issue it once.
For SCSI devices this toggles the value of the Global Logging Target The ATA standard does not specify a method to check whether SMART
Save Disabled (GLTSD) bit in the Control Mode Page. Some disk autosave is enabled. Unlike SCSI (below), smartctl is unable to print
a warning if autosave is disabled.
[SCSI] For SCSI devices this toggles the value of the Global Logging
Target Save Disabled (GLTSD) bit in the Control Mode Page. Some disk
manufacturers set this bit by default. This prevents error counters, manufacturers set this bit by default. This prevents error counters,
power\-up hours and other useful data from being placed in non\-volatile power\-up hours and other useful data from being placed in non\-volatile
storage, so these values may be reset to zero the next time the device storage, so these values may be reset to zero the next time the device
@ -864,8 +871,8 @@ If ',error' is appended and the Extended Comprehensive SMART error
log is not supported, the Summary SMART self-test log is printed. log is not supported, the Summary SMART self-test log is printed.
Please note that some recent (e.g. Samsung) drives report errors only Please note that some recent (e.g. Samsung) drives report errors only
in the Comprehensive SMART error log. The Summary SMART error log can in the Extended Comprehensive SMART error log. The Summary SMART error
be read but is always empty. log can be read but is always empty.
.I selftest .I selftest
\- [ATA] prints the SMART self\-test log. The disk maintains a self\-test \- [ATA] prints the SMART self\-test log. The disk maintains a self\-test
@ -978,7 +985,7 @@ The SCT commands are specified in the proposed ATA\-8 Command Set
\- [ATA only] [NEW EXPERIMENTAL SMARTCTL FEATURE] prints values \- [ATA only] [NEW EXPERIMENTAL SMARTCTL FEATURE] prints values
and descriptions of the SCT Error Recovery Control settings. These and descriptions of the SCT Error Recovery Control settings. These
are equivalent to TLER (as used by Western Digital), CCTL (as used are equivalent to TLER (as used by Western Digital), CCTL (as used
by Samsung and Hitachi) and ERC (as used by Seagate. READTIME and by Samsung and Hitachi) and ERC (as used by Seagate). READTIME and
WRITETIME arguments (deciseconds) set the specified values. Values of 0 WRITETIME arguments (deciseconds) set the specified values. Values of 0
disable the feature, other values less than 65 are probably not disable the feature, other values less than 65 are probably not
supported. For RAID configurations, this is typically set to supported. For RAID configurations, this is typically set to
@ -1025,7 +1032,6 @@ This command:
.fi .fi
writes a binary representation of the one sector log 0x11 writes a binary representation of the one sector log 0x11
(SATA Phy Event Counters) to file log.bin. (SATA Phy Event Counters) to file log.bin.
.TP .TP
.B \-v ID,FORMAT[:BYTEORDER][,NAME], \-\-vendorattribute=ID,FORMAT[:BYTEORDER][,NAME] .B \-v ID,FORMAT[:BYTEORDER][,NAME], \-\-vendorattribute=ID,FORMAT[:BYTEORDER][,NAME]
[ATA only] Sets a vendor\-specific raw value print FORMAT, an optional [ATA only] Sets a vendor\-specific raw value print FORMAT, an optional
@ -1194,7 +1200,6 @@ is not reset if uncorrectable sectors are reallocated
Note: a table of hard drive models, listing which Attribute Note: a table of hard drive models, listing which Attribute
corresponds to temperature, can be found at: corresponds to temperature, can be found at:
\fBhttp://www.guzu.net/linux/hddtemp.db\fP \fBhttp://www.guzu.net/linux/hddtemp.db\fP
.TP .TP
.B \-F TYPE, \-\-firmwarebug=TYPE .B \-F TYPE, \-\-firmwarebug=TYPE
[ATA only] Modifies the behavior of \fBsmartctl\fP to compensate for some [ATA only] Modifies the behavior of \fBsmartctl\fP to compensate for some
@ -1218,9 +1223,8 @@ are (1) no self\-test log printed, even though you have run self\-tests;
(3) strange and impossible values for the ATA error log timestamps. (3) strange and impossible values for the ATA error log timestamps.
.I samsung2 .I samsung2
\- In more recent Samsung disks (firmware revisions ending in "\-23") \- In some Samsung disks the number of ATA errors reported is byte swapped.
the number of ATA errors reported is byte swapped. Enabling this Enabling this option tells \fBsmartctl\fP to evaluate this quantity in
option tells \fBsmartctl\fP to evaluate this quantity in
byte\-reversed order. An indication that your Samsung disk needs this byte\-reversed order. An indication that your Samsung disk needs this
option is that the self\-test log is printed correctly, but there are a option is that the self\-test log is printed correctly, but there are a
very large number of errors in the SMART error log. This is because very large number of errors in the SMART error log. This is because
@ -1240,7 +1244,6 @@ below).
.I swapid .I swapid
\- Fixes byte swapped ATA identify strings (device name, serial number, \- Fixes byte swapped ATA identify strings (device name, serial number,
firmware version) returned by some buggy device drivers. firmware version) returned by some buggy device drivers.
.TP .TP
.B \-P TYPE, \-\-presets=TYPE .B \-P TYPE, \-\-presets=TYPE
[ATA only] Specifies whether \fBsmartctl\fP should use any preset options [ATA only] Specifies whether \fBsmartctl\fP should use any preset options
@ -1301,7 +1304,6 @@ lists all entries matching MODEL, and the command:
smartctl \-P showall \'MODEL\' \'FIRMWARE\' smartctl \-P showall \'MODEL\' \'FIRMWARE\'
.fi .fi
lists all entries for this MODEL and a specific FIRMWARE version. lists all entries for this MODEL and a specific FIRMWARE version.
.TP .TP
.B \-B [+]FILE, \-\-drivedb=[+]FILE .B \-B [+]FILE, \-\-drivedb=[+]FILE
[ATA only] [NEW EXPERIMENTAL SMARTCTL FEATURE] Read the drive database from [ATA only] [NEW EXPERIMENTAL SMARTCTL FEATURE] Read the drive database from
@ -1309,9 +1311,10 @@ FILE. The new database replaces the built in database by default. If \'+\' is
specified, then the new entries prepend the built in entries. specified, then the new entries prepend the built in entries.
If this option is not specified, optional entries are read from the file If this option is not specified, optional entries are read from the file
\fB/usr/local/etc/smart_drivedb.h\fP (Windows: \fB./smart_drivedb.conf\fP). \fB/usr/local/etc/smart_drivedb.h\fP (Windows: \fBEXEDIR/drivedb-add.h\fP).
.\" BEGIN ENABLE_DRIVEDB .\" BEGIN ENABLE_DRIVEDB
If \fB/usr/local/share/smartmontools/drivedb.h\fP is present, the If \fB/usr/local/share/smartmontools/drivedb.h\fP
(Windows: \fBEXEDIR/drivedb.h\fP) is present, the
contents of this file is used instead of the built in table. contents of this file is used instead of the built in table.
Run the script \fB/usr/local/sbin/update-smart-drivedb\fP to update this Run the script \fB/usr/local/sbin/update-smart-drivedb\fP to update this
@ -1339,6 +1342,14 @@ Example:
"", // No warning. "", // No warning.
"" // No options preset. "" // No options preset.
}, },
/* USB ID entry: */
{
"USB: Device; Bridge", // Info about USB device and bridge name.
"0x1234:0xabcd", // Regular expression to match vendor:product ID.
"0x0101", // Regular expression to match bcdDevice.
"", // Not used.
"\-d sat" // String with device type option.
},
/* ... */ /* ... */
.fi .fi
@ -1358,13 +1369,12 @@ self\-test will either be aborted or will resume automatically.
The valid arguments to this option are: The valid arguments to this option are:
.I offline .I offline
\- runs SMART Immediate Offline Test. This immediately \- [ATA] runs SMART Immediate Offline Test. This immediately
starts the test described above. This command can be given during starts the test described above. This command can be given during
normal system operation. The effects of this test are visible only in normal system operation. The effects of this test are visible only in
that it updates the SMART Attribute values, and if errors are that it updates the SMART Attribute values, and if errors are
found they will appear in the SMART error log, visible with the \'\-l error\' found they will appear in the SMART error log, visible with the \'\-l error\'
option. [In the case of SCSI devices runs the default self test in option.
foreground. No entry is placed in the self test log.]
If the \'\-c\' option to \fBsmartctl\fP shows that the device has the If the \'\-c\' option to \fBsmartctl\fP shows that the device has the
"Suspend Offline collection upon new command" capability then you can "Suspend Offline collection upon new command" capability then you can
@ -1375,10 +1385,12 @@ most commands will abort the Immediate Offline Test, so you should not
try to track the progress of the test with \'\-c\', as it will abort try to track the progress of the test with \'\-c\', as it will abort
the test. the test.
.I offline
\- [SCSI] runs the default self test in foreground. No entry is placed
in the self test log.
.I short .I short
\- runs SMART Short Self Test (usually under ten minutes). \- [ATA] runs SMART Short Self Test (usually under ten minutes).
[Note: in the case of SCSI devices,
this command option runs the "Background short" self\-test.]
This command can be given during normal system operation (unless run in This command can be given during normal system operation (unless run in
captive mode \- see the \'\-C\' option below). This is a captive mode \- see the \'\-C\' option below). This is a
test in a different category than the immediate or automatic offline test in a different category than the immediate or automatic offline
@ -1389,15 +1401,18 @@ the \'\-l selftest\' option. Note that on some disks the progress of the
self\-test can be monitored by watching this log during the self\-test; with other disks self\-test can be monitored by watching this log during the self\-test; with other disks
use the \'\-c\' option to monitor progress. use the \'\-c\' option to monitor progress.
.I short
\- [SCSI] runs the "Background short" self\-test.
.I long .I long
\- runs SMART Extended Self Test (tens of minutes). \- [ATA] runs SMART Extended Self Test (tens of minutes). This is a
[Note: in the case of SCSI devices,
this command option runs the "Background long" self\-test.]
This is a
longer and more thorough version of the Short Self Test described longer and more thorough version of the Short Self Test described
above. Note that this command can be given during normal above. Note that this command can be given during normal
system operation (unless run in captive mode \- see the \'\-C\' option below). system operation (unless run in captive mode \- see the \'\-C\' option below).
.I long
\- [SCSI] runs the "Background long" self\-test.
.I conveyance .I conveyance
\- [ATA only] runs a SMART Conveyance Self Test (minutes). This \- [ATA only] runs a SMART Conveyance Self Test (minutes). This
self\-test routine is intended to identify damage incurred during self\-test routine is intended to identify damage incurred during
@ -1450,10 +1465,6 @@ Logical Block Addresses (LBAs).
Selective self\-tests can be run during normal system operation (unless Selective self\-tests can be run during normal system operation (unless
done in captive mode \- see the \'\-C\' option below). done in captive mode \- see the \'\-C\' option below).
[Note: To use this feature on Linux, the kernel must be compiled with
the configuration option CONFIG_IDE_TASKFILE_IO enabled. Please report
unusual or incorrect behavior to the smartmontools\-support mailing list.]
The following variants of the selective self\-test command use spans based The following variants of the selective self\-test command use spans based
on the ranges from past tests already stored on the disk: on the ranges from past tests already stored on the disk:
@ -1538,18 +1549,16 @@ cycles. Otherwise, the setting is volatile and will be reverted to
default (1 minute), or last non-volatile setting by the next hard reset. default (1 minute), or last non-volatile setting by the next hard reset.
This command also clears the temperature history table. See This command also clears the temperature history table. See
\'\-l scttemp\' above for more information about SCT temperature logging. \'\-l scttemp\' above for more information about SCT temperature logging.
.TP .TP
.B \-C, \-\-captive .B \-C, \-\-captive
Runs self\-tests in captive mode. This has no effect with \'\-t [ATA] Runs self\-tests in captive mode. This has no effect with \'\-t
offline\' or if the \'\-t\' option is not used. [Note: in the case of offline\' or if the \'\-t\' option is not used.
SCSI devices, this command option runs the self\-test in "Foreground"
mode.]
\fBWARNING: Tests run in captive mode may busy out the drive for the \fBWARNING: Tests run in captive mode may busy out the drive for the
length of the test. Only run captive tests on drives without any length of the test. Only run captive tests on drives without any
mounted partitions!\fP mounted partitions!\fP
[SCSI] Runs the self\-test in "Foreground" mode.
.TP .TP
.B \-X, \-\-abort .B \-X, \-\-abort
Aborts non\-captive SMART Self Tests. Note that this Aborts non\-captive SMART Self Tests. Note that this
@ -1830,30 +1839,26 @@ REFERENCES FOR SMART
.fi .fi
An introductory article about smartmontools is \fIMonitoring Hard An introductory article about smartmontools is \fIMonitoring Hard
Disks with SMART\fP, by Bruce Allen, Linux Journal, January 2004, Disks with SMART\fP, by Bruce Allen, Linux Journal, January 2004,
pages 74\-77. This is \fBhttp://www.linuxjournal.com/article.php?sid=6983\fP pages 74\-77. This is \fBhttp://www.linuxjournal.com/article/6983\fP
online. online.
If you would like to understand better how SMART works, and what it If you would like to understand better how SMART works, and what it
does, a good place to start is with Sections 4.8 and 6.54 of the first does, a good place to start is with Sections 4.8 and 6.54 of the first
volume of the \'AT Attachment with Packet Interface\-7\' (ATA/ATAPI\-7) volume of the \'AT Attachment with Packet Interface\-7\' (ATA/ATAPI\-7)
specification. This documents the SMART functionality which the specification Revision 4b. This documents the SMART functionality which the
\fBsmartmontools\fP utilities provide access to. You can find \fBsmartmontools\fP utilities provide access to.
Revision 4b of this document at This and other versions of this Specification are available from
\fBhttp://www.t13.org/docs2004/d1532v1r4b-ATA-ATAPI-7.pdf\fP .
Earlier and later versions of this Specification are available from
the T13 web site \fBhttp://www.t13.org/\fP . the T13 web site \fBhttp://www.t13.org/\fP .
.fi .fi
The functioning of SMART was originally defined by the SFF\-8035i The functioning of SMART was originally defined by the SFF\-8035i
revision 2 and the SFF\-8055i revision 1.4 specifications. These are revision 2 and the SFF\-8055i revision 1.4 specifications. These are
publications of the Small Form Factors (SFF) Committee. Links to publications of the Small Form Factors (SFF) Committee.
these documents may be found in the References section of the
\fBsmartmontools\fP home page at Links to these and other documents may be found on the Links page of the
\fBhttp://smartmontools.sourceforge.net/\fP . \fBsmartmontools\fP Wiki at
\fBhttp://sourceforge.net/apps/trac/smartmontools/wiki/Links\fP .
.SH .SH
SVN ID OF THIS PAGE: SVN ID OF THIS PAGE:
$Id: smartctl.8.in 3072 2010-03-04 21:56:41Z chrfranke $ $Id: smartctl.8.in 3119 2010-06-11 16:21:25Z chrfranke $
.\" Local Variables:
.\" mode: nroff
.\" End:

View File

@ -56,7 +56,7 @@
#include "smartctl.h" #include "smartctl.h"
#include "utility.h" #include "utility.h"
const char * smartctl_cpp_cvsid = "$Id: smartctl.cpp 3065 2010-02-10 22:16:50Z chrfranke $" const char * smartctl_cpp_cvsid = "$Id: smartctl.cpp 3119 2010-06-11 16:21:25Z chrfranke $"
CONFIG_H_CVSID EXTERN_H_CVSID SMARTCTL_H_CVSID; CONFIG_H_CVSID EXTERN_H_CVSID SMARTCTL_H_CVSID;
// This is a block containing all the "control variables". We declare // This is a block containing all the "control variables". We declare
@ -90,6 +90,10 @@ void Usage (void){
" Show all SMART information for device\n\n" " Show all SMART information for device\n\n"
" -x, --xall\n" " -x, --xall\n"
" Show all information for device\n\n" " Show all information for device\n\n"
" --scan\n"
" Scan for devices\n\n"
" --scan-open\n"
" Scan for devices and try to open each device\n\n"
); );
printf( printf(
"================================== SMARTCTL RUN-TIME BEHAVIOR OPTIONS =====\n\n" "================================== SMARTCTL RUN-TIME BEHAVIOR OPTIONS =====\n\n"
@ -138,12 +142,18 @@ void Usage (void){
" Drive-specific presets: use, ignore, show, showall\n\n" " Drive-specific presets: use, ignore, show, showall\n\n"
" -B [+]FILE, --drivedb=[+]FILE (ATA)\n" " -B [+]FILE, --drivedb=[+]FILE (ATA)\n"
" Read and replace [add] drive database from FILE\n" " Read and replace [add] drive database from FILE\n"
#ifdef SMARTMONTOOLS_DRIVEDBDIR " [default is +%s",
" [default is "SMARTMONTOOLS_DRIVEDBDIR"/drivedb.h]\n" get_drivedb_path_add()
#endif
"\n"
); );
#ifdef SMARTMONTOOLS_DRIVEDBDIR
printf( printf(
"\n"
" and then %s",
get_drivedb_path_default()
);
#endif
printf(
"]\n\n"
"============================================ DEVICE SELF-TEST OPTIONS =====\n\n" "============================================ DEVICE SELF-TEST OPTIONS =====\n\n"
" -t TEST, --test=TEST\n" " -t TEST, --test=TEST\n"
" Run test. TEST: offline short long conveyance select,M-N\n" " Run test. TEST: offline short long conveyance select,M-N\n"
@ -221,6 +231,8 @@ enum checksum_err_mode_t {
static checksum_err_mode_t checksum_err_mode = CHECKSUM_ERR_WARN; static checksum_err_mode_t checksum_err_mode = CHECKSUM_ERR_WARN;
static void scan_devices(const char * type, bool with_open, const char * pattern);
/* Takes command options and sets features to be run */ /* Takes command options and sets features to be run */
const char * parse_options(int argc, char** argv, const char * parse_options(int argc, char** argv,
ata_print_options & ataopts, ata_print_options & ataopts,
@ -229,6 +241,7 @@ const char * parse_options(int argc, char** argv,
// Please update getvalidarglist() if you edit shortopts // Please update getvalidarglist() if you edit shortopts
const char *shortopts = "h?Vq:d:T:b:r:s:o:S:HcAl:iaxv:P:t:CXF:n:B:"; const char *shortopts = "h?Vq:d:T:b:r:s:o:S:HcAl:iaxv:P:t:CXF:n:B:";
// Please update getvalidarglist() if you edit longopts // Please update getvalidarglist() if you edit longopts
enum { opt_scan = 1000, opt_scan_open = 1001 };
struct option longopts[] = { struct option longopts[] = {
{ "help", no_argument, 0, 'h' }, { "help", no_argument, 0, 'h' },
{ "usage", no_argument, 0, 'h' }, { "usage", no_argument, 0, 'h' },
@ -258,6 +271,8 @@ const char * parse_options(int argc, char** argv,
{ "firmwarebug", required_argument, 0, 'F' }, { "firmwarebug", required_argument, 0, 'F' },
{ "nocheck", required_argument, 0, 'n' }, { "nocheck", required_argument, 0, 'n' },
{ "drivedb", required_argument, 0, 'B' }, { "drivedb", required_argument, 0, 'B' },
{ "scan", no_argument, 0, opt_scan },
{ "scan-open", no_argument, 0, opt_scan_open },
{ 0, 0, 0, 0 } { 0, 0, 0, 0 }
}; };
@ -268,16 +283,14 @@ const char * parse_options(int argc, char** argv,
const char * type = 0; // set to -d optarg const char * type = 0; // set to -d optarg
bool no_defaultdb = false; // set true on '-B FILE' bool no_defaultdb = false; // set true on '-B FILE'
int scan = 0; // set by --scan, --scan-open
bool badarg = false, captive = false; bool badarg = false, captive = false;
int testcnt = 0; // number of self-tests requested int testcnt = 0; // number of self-tests requested
int optchar; int optchar;
char *arg; char *arg;
// This miserable construction is needed to get emacs to do proper indenting. Sorry! while ((optchar = getopt_long(argc, argv, shortopts, longopts, 0)) != -1) {
while (-1 != (optchar =
getopt_long(argc, argv, shortopts, longopts, NULL)
)){
switch (optchar){ switch (optchar){
case 'V': case 'V':
con->dont_print = false; con->dont_print = false;
@ -616,6 +629,7 @@ const char * parse_options(int argc, char** argv,
ataopts.smart_selective_args.pending_time = i+1; ataopts.smart_selective_args.pending_time = i+1;
} }
} else if (!strncmp(optarg,"select",strlen("select"))) { } else if (!strncmp(optarg,"select",strlen("select"))) {
if (ataopts.smart_selective_args.num_spans == 0)
testcnt++; testcnt++;
// parse range of LBAs to test // parse range of LBAs to test
uint64_t start, stop; int mode; uint64_t start, stop; int mode;
@ -690,6 +704,12 @@ const char * parse_options(int argc, char** argv,
Usage(); Usage();
EXIT(0); EXIT(0);
break; break;
case opt_scan:
case opt_scan_open:
scan = optchar;
break;
case '?': case '?':
default: default:
con->dont_print = false; con->dont_print = false;
@ -741,6 +761,13 @@ const char * parse_options(int argc, char** argv,
EXIT(FAILCMD); EXIT(FAILCMD);
} }
} }
// Special handling of --scan, --scanopen
if (scan) {
scan_devices(type, (scan == opt_scan_open), argv[optind]);
EXIT(0);
}
// At this point we have processed all command-line options. If the // At this point we have processed all command-line options. If the
// print output is switchable, then start with the print output // print output is switchable, then start with the print output
// turned off // turned off
@ -884,9 +911,50 @@ static const char * get_protocol_info(const smart_device * dev)
} }
} }
// Device scan
// smartctl [-d type] --scan[-open] [PATTERN]
void scan_devices(const char * type, bool with_open, const char * pattern)
{
bool dont_print = !(con->reportataioctl || con->reportscsiioctl);
smart_device_list devlist;
con->dont_print = dont_print;
bool ok = smi()->scan_smart_devices(devlist, type , pattern);
con->dont_print = false;
if (!ok) {
pout("scan_smart_devices: %s\n", smi()->get_errmsg());
return;
}
for (unsigned i = 0; i < devlist.size(); i++) {
smart_device * dev = devlist.at(i);
std::string openmsg;
if (with_open) {
con->dont_print = dont_print;
dev = dev->autodetect_open();
con->dont_print = false;
if (dev->is_open())
openmsg = " (opened)";
else
openmsg = strprintf(" (open failed: %s)", dev->get_errmsg());
}
pout("%s -d %s [%s]%s\n", dev->get_info_name(), dev->get_dev_type(),
get_protocol_info(dev), openmsg.c_str());
if (dev->is_open())
dev->close();
}
}
// Main program without exception handling // Main program without exception handling
int main_worker(int argc, char **argv) int main_worker(int argc, char **argv)
{ {
// Throw if CPU endianess does not match compile time test.
check_endianness();
// Initialize interface // Initialize interface
smart_interface::init(); smart_interface::init();
if (!smi()) if (!smi())

View File

@ -1,7 +1,7 @@
.ig .ig
Copyright (C) 2002-8 Bruce Allen <smartmontools-support@lists.sourceforge.net> Copyright (C) 2002-10 Bruce Allen <smartmontools-support@lists.sourceforge.net>
$Id: smartd.8.in 3076 2010-03-12 22:23:08Z chrfranke $ $Id: smartd.8.in 3117 2010-06-08 15:41:04Z chrfranke $
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -17,7 +17,7 @@ Cornwell at the Concurrent Systems Laboratory (now part of the Storage
Systems Research Center), Jack Baskin School of Engineering, Systems Research Center), Jack Baskin School of Engineering,
University of California, Santa Cruz. http://ssrc.soe.ucsc.edu/ University of California, Santa Cruz. http://ssrc.soe.ucsc.edu/
.. ..
.TH SMARTD 8 CURRENT_CVS_DATE CURRENT_CVS_VERSION CURRENT_CVS_DATE .TH SMARTD 8 CURRENT_SVN_DATE CURRENT_SVN_VERSION CURRENT_SVN_DATE
.SH NAME .SH NAME
\fBsmartd\fP \- SMART Disk Monitoring Daemon \fBsmartd\fP \- SMART Disk Monitoring Daemon
@ -28,7 +28,7 @@ University of California, Santa Cruz. http://ssrc.soe.ucsc.edu/
.B /usr/local/sbin/smartd .B /usr/local/sbin/smartd
.SH PACKAGE VERSION .SH PACKAGE VERSION
CURRENT_CVS_VERSION released CURRENT_CVS_DATE at CURRENT_CVS_TIME CURRENT_SVN_VERSION CURRENT_SVN_DATE CURRENT_SVN_REV
.SH DESCRIPTION .SH DESCRIPTION
\fBsmartd\fP is a daemon that monitors the Self-Monitoring, Analysis \fBsmartd\fP is a daemon that monitors the Self-Monitoring, Analysis
@ -43,7 +43,8 @@ and to carry out different types of drive self-tests. This version of
(equivalent to \fBsmartctl -s on\fP) and polls these and SCSI devices (equivalent to \fBsmartctl -s on\fP) and polls these and SCSI devices
every 30 minutes (configurable), logging SMART errors and changes of every 30 minutes (configurable), logging SMART errors and changes of
SMART Attributes via the SYSLOG interface. The default location for SMART Attributes via the SYSLOG interface. The default location for
these SYSLOG notifications and warnings is \fB/var/log/messages\fP. these SYSLOG notifications and warnings is system-dependent
(typically \fB/var/log/messages\fP or \fB/var/log/syslog\fP).
To change this default location, please see the \fB\'-l\'\fP To change this default location, please see the \fB\'-l\'\fP
command-line option described below. command-line option described below.
@ -61,7 +62,7 @@ every 30 minutes. See the \fB\'\-i\'\fP option below for additional
details. details.
\fBsmartd\fP can be configured at start-up using the configuration \fBsmartd\fP can be configured at start-up using the configuration
file \fB/usr/local/etc/smartd.conf\fP (Windows: \fB./smartd.conf\fP). file \fB/usr/local/etc/smartd.conf\fP (Windows: \fBEXEDIR/smartd.conf\fP).
If the configuration file is subsequently modified, \fBsmartd\fP If the configuration file is subsequently modified, \fBsmartd\fP
can be told to re-read the configuration file by sending it a can be told to re-read the configuration file by sending it a
\fBHUP\fP signal, for example with the command: \fBHUP\fP signal, for example with the command:
@ -126,8 +127,6 @@ below).
.SH .SH
OPTIONS OPTIONS
Long options are not supported on all systems. Use \fB\'smartd
\-h\'\fP to see the available options.
.TP .TP
.B \-A PREFIX, \-\-attributelog=PREFIX .B \-A PREFIX, \-\-attributelog=PREFIX
@ -152,18 +151,16 @@ files \'MODEL\-SERIAL.ata.csv\' are created in directory \'/path/dir\'.
If the PREFIX has the form \'/path/name\' (e.g. \'/var/lib/misc/attrlog\-\'), If the PREFIX has the form \'/path/name\' (e.g. \'/var/lib/misc/attrlog\-\'),
then files 'nameMODEL\-SERIAL.ata.csv' are created in directory '/path/'. then files 'nameMODEL\-SERIAL.ata.csv' are created in directory '/path/'.
The path must be absolute, except if debug mode is enabled. The path must be absolute, except if debug mode is enabled.
.TP .TP
.B \-B [+]FILE, \-\-drivedb=[+]FILE .B \-B [+]FILE, \-\-drivedb=[+]FILE
[NEW EXPERIMENTAL SMARTD FEATURE] Read the drive database from FILE. [NEW EXPERIMENTAL SMARTD FEATURE] Read the drive database from FILE.
The new database replaces the built in database by default. If \'+\' is The new database replaces the built in database by default. If \'+\' is
specified, then the new entries prepend the built in entries. specified, then the new entries prepend the built in entries.
Please see the \fBsmartctl\fP(8) man page for further details. Please see the \fBsmartctl\fP(8) man page for further details.
.TP .TP
.B \-c FILE, \-\-configfile=FILE .B \-c FILE, \-\-configfile=FILE
Read \fBsmartd\fP configuration Directives from FILE, instead of from Read \fBsmartd\fP configuration Directives from FILE, instead of from
the default location \fB/usr/local/etc/smartd.conf\fP (Windows: \fB./smartd.conf\fP). the default location \fB/usr/local/etc/smartd.conf\fP (Windows: \fBEXEDIR/smartd.conf\fP).
If FILE does \fBnot\fP exist, then \fBsmartd\fP will print an error If FILE does \fBnot\fP exist, then \fBsmartd\fP will print an error
message and exit with nonzero status. Thus, \'\-c /usr/local/etc/smartd.conf\' message and exit with nonzero status. Thus, \'\-c /usr/local/etc/smartd.conf\'
can be used to verify the existence of the default configuration file. can be used to verify the existence of the default configuration file.
@ -174,14 +171,12 @@ input. This is useful for commands like:
.B echo /dev/hdb \-m user@home \-M test | smartd \-c \- \-q onecheck .B echo /dev/hdb \-m user@home \-M test | smartd \-c \- \-q onecheck
.fi .fi
to perform quick and simple checks without a configuration file. to perform quick and simple checks without a configuration file.
.\" BEGIN ENABLE_CAPABILITIES .\" BEGIN ENABLE_CAPABILITIES
.TP .TP
.B \-C, \-\-capabilities .B \-C, \-\-capabilities
Use \fBcapabilities(7)\fP (EXPERIMENTAL). Use \fBcapabilities(7)\fP (EXPERIMENTAL).
Warning: Mail notification does not work when used. Warning: Mail notification does not work when used.
.\" END ENABLE_CAPABILITIES .\" END ENABLE_CAPABILITIES
.TP .TP
.B \-d, \-\-debug .B \-d, \-\-debug
@ -207,7 +202,6 @@ appear in the configuration file following the device name.
.TP .TP
.B \-h, \-\-help, \-\-usage .B \-h, \-\-help, \-\-usage
Prints usage message to STDOUT and exits. Prints usage message to STDOUT and exits.
.TP .TP
.B \-i N, \-\-interval=N .B \-i N, \-\-interval=N
Sets the interval between disk checks to \fIN\fP seconds, where Sets the interval between disk checks to \fIN\fP seconds, where
@ -229,7 +223,6 @@ also use:
for the same purpose. for the same purpose.
.fi .fi
(Windows: See NOTES below.) (Windows: See NOTES below.)
.TP .TP
.B \-l FACILITY, \-\-logfacility=FACILITY .B \-l FACILITY, \-\-logfacility=FACILITY
Uses syslog facility FACILITY to log the messages from \fBsmartd\fP. Uses syslog facility FACILITY to log the messages from \fBsmartd\fP.
@ -239,8 +232,8 @@ then by default messages from \fBsmartd\fP are logged to the facility
\fIdaemon\fP. \fIdaemon\fP.
If you would like to have \fBsmartd\fP messages logged somewhere other If you would like to have \fBsmartd\fP messages logged somewhere other
than the default \fB/var/log/messages\fP location, this can typically than the default location, this can typically be accomplished with
be accomplished with (for example) the following steps: (for example) the following steps:
.RS 7 .RS 7
.IP \fB[1]\fP 4 .IP \fB[1]\fP 4
Modify the script that starts \fBsmartd\fP to include the \fBsmartd\fP Modify the script that starts \fBsmartd\fP to include the \fBsmartd\fP
@ -290,7 +283,6 @@ should be registered as an event message file to avoid error
messages from the event viewer. Use \'\fBsyslogevt -r smartd\fP\' messages from the event viewer. Use \'\fBsyslogevt -r smartd\fP\'
to register, \'\fBsyslogevt -u smartd\fP\' to unregister and to register, \'\fBsyslogevt -u smartd\fP\' to unregister and
\'\fBsyslogevt\fP\' for more help. \'\fBsyslogevt\fP\' for more help.
.TP .TP
.B \-n, \-\-no\-fork .B \-n, \-\-no\-fork
Do not fork into background; this is useful when executed from modern Do not fork into background; this is useful when executed from modern
@ -300,7 +292,6 @@ On Cygwin, this allows running \fBsmartd\fP as service via cygrunsrv,
see NOTES below. see NOTES below.
On Windows, this option is not available, use \'\-\-service\' instead. On Windows, this option is not available, use \'\-\-service\' instead.
.TP .TP
.B \-p NAME, \-\-pidfile=NAME .B \-p NAME, \-\-pidfile=NAME
Writes pidfile \fINAME\fP containing the \fBsmartd\fP Process ID Writes pidfile \fINAME\fP containing the \fBsmartd\fP Process ID
@ -392,7 +383,6 @@ detail that should be reported. The argument should be followed by a
comma then the integer with no spaces. For example, \fIataioctl,2\fP comma then the integer with no spaces. For example, \fIataioctl,2\fP
The default level is 1, so \'\-r ataioctl,1\' and \'\-r ataioctl\' are The default level is 1, so \'\-r ataioctl,1\' and \'\-r ataioctl\' are
equivalent. equivalent.
.TP .TP
.B \-s PREFIX, \-\-savestates=PREFIX .B \-s PREFIX, \-\-savestates=PREFIX
[NEW EXPERIMENTAL SMARTD FEATURE] [ATA ONLY] [NEW EXPERIMENTAL SMARTD FEATURE] [ATA ONLY]
@ -422,7 +412,6 @@ always (re)written after reading the configuration file, before rereading
the configuration file (SIGHUP), before smartd shutdown, and after a check the configuration file (SIGHUP), before smartd shutdown, and after a check
forced by SIGUSR1. After a normal check cycle, a file is only rewritten if forced by SIGUSR1. After a normal check cycle, a file is only rewritten if
an important change (which usually results in a SYSLOG output) occurred. an important change (which usually results in a SYSLOG output) occurred.
.TP .TP
.B \-\-service .B \-\-service
Cygwin and Windows only: Enables \fBsmartd\fP to run as a Windows service. Cygwin and Windows only: Enables \fBsmartd\fP to run as a Windows service.
@ -434,7 +423,6 @@ On Windows, this option enables the buildin service support.
The option must be specified in the service command line as the first The option must be specified in the service command line as the first
argument. It should not be used from console. argument. It should not be used from console.
See NOTES below for details. See NOTES below for details.
.TP .TP
.B \-V, \-\-version, \-\-license, \-\-copyright .B \-V, \-\-version, \-\-license, \-\-copyright
Prints version, copyright, license, home page and SVN revision Prints version, copyright, license, home page and SVN revision
@ -448,8 +436,7 @@ smartd
.fi .fi
Runs the daemon in forked mode. This is the normal way to run Runs the daemon in forked mode. This is the normal way to run
\fBsmartd\fP. \fBsmartd\fP.
Entries are logged to SYSLOG (by default Entries are logged to SYSLOG.
.B /var/log/messages.)
.B .B
smartd -d -i 30 smartd -d -i 30
@ -477,16 +464,6 @@ you can start \fBsmartd\fP by giving the command:
and stop it by using the command: and stop it by using the command:
.nf .nf
.B /usr/local/etc/rc.d/init.d/smartd stop .B /usr/local/etc/rc.d/init.d/smartd stop
.fi
If you want \fBsmartd\fP to start running whenever your machine is
booted, this can be enabled by using the command:
.nf
.B /sbin/chkconfig --add smartd
.fi
and disabled using the command:
.nf
.B /sbin/chkconfig --del smartd
.fi .fi
.\" DO NOT MODIFY THIS OR THE FOLLOWING TWO LINES. THIS MATERIAL .\" DO NOT MODIFY THIS OR THE FOLLOWING TWO LINES. THIS MATERIAL
@ -535,7 +512,7 @@ This file contains a list of devices to monitor, with one device per
line. An example file is included with the line. An example file is included with the
.B smartmontools .B smartmontools
distribution. You will find this sample configuration file in distribution. You will find this sample configuration file in
\fB/usr/local/share/doc/smartmontools-5.1/\fP. For security, the configuration file \fB/usr/local/share/doc/smartmontools/\fP. For security, the configuration file
should not be writable by anyone but root. The syntax of the file is as should not be writable by anyone but root. The syntax of the file is as
follows: follows:
.IP \(bu 4 .IP \(bu 4
@ -732,7 +709,6 @@ normal ATA devices. Hence all the ATA directives can be used for
these disks. Areca firmware version 1.46 or later which supports these disks. Areca firmware version 1.46 or later which supports
smartmontools must be used; Please see the \fBsmartctl\fP(8) man page smartmontools must be used; Please see the \fBsmartctl\fP(8) man page
for further details. for further details.
.TP .TP
.B \-d TYPE .B \-d TYPE
Specifies the type of the device. This Directive may be used multiple Specifies the type of the device. This Directive may be used multiple
@ -861,7 +837,6 @@ that it should continue (instead of exiting, which is the default
behavior) if the device does not appear to be present when behavior) if the device does not appear to be present when
\fBsmartd\fP is started. This Directive may be used in conjunction \fBsmartd\fP is started. This Directive may be used in conjunction
with the other \'\-d\' Directives. with the other \'\-d\' Directives.
.TP .TP
.B \-n POWERMODE[,N][,q] .B \-n POWERMODE[,N][,q]
This \'nocheck\' Directive is used to prevent a disk from being This \'nocheck\' Directive is used to prevent a disk from being
@ -919,7 +894,6 @@ the option \',q\' to POWERMODE (like \'\-n standby,q\').
This prevents a laptop disk from spinning up due to this message. This prevents a laptop disk from spinning up due to this message.
Both \',N\' and \',q\' can be specified together. Both \',N\' and \',q\' can be specified together.
.TP .TP
.B \-T TYPE .B \-T TYPE
Specifies how tolerant Specifies how tolerant
@ -967,19 +941,29 @@ Directive are \fIon\fP and \fIoff\fP. Also affects SCSI devices.
Check the SMART health status of the disk. If any Prefailure Check the SMART health status of the disk. If any Prefailure
Attributes are less than or equal to their threshold values, then disk Attributes are less than or equal to their threshold values, then disk
failure is predicted in less than 24 hours, and a message at loglevel failure is predicted in less than 24 hours, and a message at loglevel
.B \'LOG_CRITICAL\' .B \'LOG_CRIT\'
will be logged to syslog. [Please see the will be logged to syslog. [Please see the
.B smartctl \-H .B smartctl \-H
command-line option.] command-line option.]
.TP .TP
.B \-l TYPE .B \-l TYPE
Reports increases in the number of errors in one of the two SMART logs. The Reports increases in the number of errors in one of three SMART logs. The
valid arguments to this Directive are: valid arguments to this Directive are:
.I error .I error
\- report if the number of ATA errors reported in the ATA Error Log \- report if the number of ATA errors reported in the Summary SMART error log
has increased since the last check. has increased since the last check.
.I xerror
\- [NEW EXPERIMENTAL SMARTD FEATURE] report if the number of ATA errors
reported in the Extended Comprehensive SMART error log has increased since
the last check.
If both \'\-l error\' and \'\-l xerror\' are specified, smartd checks
the maximum of both values.
[Please see the \fBsmartctl \-l xerror\fP command-line option.]
.I selftest .I selftest
\- report if the number of failed tests reported in the SMART \- report if the number of failed tests reported in the SMART
Self-Test Log has increased since the last check, or if the timestamp Self-Test Log has increased since the last check, or if the timestamp
@ -1120,7 +1104,6 @@ file\-name pattern matching by the shell [glob(7)]. \fBsmartd\fP will
issue harmless informational warning messages if it detects characters issue harmless informational warning messages if it detects characters
in \fBREGEXP\fP that appear to indicate that you have made this in \fBREGEXP\fP that appear to indicate that you have made this
mistake. mistake.
.TP .TP
.B \-m ADD .B \-m ADD
Send a warning email to the email address \fBADD\fP if the \'\-H\', Send a warning email to the email address \fBADD\fP if the \'\-H\',
@ -1188,7 +1171,6 @@ if \'\fBmsgbox\fP\' is the first word in the comma separated list.
With \'\fBsysmsgbox\fP\', a system modal (always on top) message box With \'\fBsysmsgbox\fP\', a system modal (always on top) message box
is used. If running as a service, a service notification message box is used. If running as a service, a service notification message box
(always shown on current visible desktop) is used. (always shown on current visible desktop) is used.
.TP .TP
.B \-M TYPE .B \-M TYPE
These Directives modify the behavior of the These Directives modify the behavior of the
@ -1243,7 +1225,7 @@ to all logged-in users, etc.) But please be careful. \fBsmartd\fP
will \fBblock\fP until the executable PATH returns, so if your will \fBblock\fP until the executable PATH returns, so if your
executable hangs, then \fBsmartd\fP will also hang. Some sample executable hangs, then \fBsmartd\fP will also hang. Some sample
scripts are included in scripts are included in
/usr/local/share/doc/smartmontools-5.1/examplescripts/. /usr/local/share/doc/smartmontools/examplescripts/.
The return status of the executable is recorded by \fBsmartd\fP in The return status of the executable is recorded by \fBsmartd\fP in
SYSLOG. The executable is not expected to write to STDOUT or SYSLOG. The executable is not expected to write to STDOUT or
@ -1305,6 +1287,9 @@ read and are marked to be reallocated (replaced with spare sectors).
one or more disk sectors could not be read. one or more disk sectors could not be read.
.nf .nf
.fi .fi
\fITemperature\fP: Temperature reached critical limit (see \-W directive).
.nf
.fi
\fIFailedHealthCheck\fP: the SMART health status command failed. \fIFailedHealthCheck\fP: the SMART health status command failed.
.nf .nf
.fi .fi
@ -1395,8 +1380,7 @@ discarded.
Some EXAMPLES of scripts that can be used with the \'\-M exec\' Some EXAMPLES of scripts that can be used with the \'\-M exec\'
Directive are given below. Some sample scripts are also included in Directive are given below. Some sample scripts are also included in
/usr/local/share/doc/smartmontools-5.1/examplescripts/. /usr/local/share/doc/smartmontools/examplescripts/.
.TP .TP
.B \-f .B \-f
Check for \'failure\' of any Usage Attributes. If these Attributes are Check for \'failure\' of any Usage Attributes. If these Attributes are
@ -1459,7 +1443,6 @@ A common use of this Directive is to track the device Temperature
If the optional flag \'!\' is appended, a change of the Normalized If the optional flag \'!\' is appended, a change of the Normalized
value is considered critical. The report will be logged as LOG_CRIT value is considered critical. The report will be logged as LOG_CRIT
and a warning email will be sent if \'-m\' is specified. and a warning email will be sent if \'-m\' is specified.
.TP .TP
.B \-R ID[!] .B \-R ID[!]
When tracking, report whenever the \fIRaw\fP value of Attribute When tracking, report whenever the \fIRaw\fP value of Attribute
@ -1483,7 +1466,6 @@ If the optional flag \'!\' is appended, a change of the Raw
value is considered critical. The report will be logged as value is considered critical. The report will be logged as
LOG_CRIT and a warning email will be sent if \'-m\' is specified. LOG_CRIT and a warning email will be sent if \'-m\' is specified.
An example is \'-R 5!\' to warn when new sectors are reallocated. An example is \'-R 5!\' to warn when new sectors are reallocated.
.TP .TP
.B \-C ID[+] .B \-C ID[+]
[ATA only] Report if the current number of pending sectors is [ATA only] Report if the current number of pending sectors is
@ -1492,7 +1474,9 @@ value is the Current Pending Sector count. The allowed range of
\fBID\fP is 0 to 255 inclusive. To turn off this reporting, use \fBID\fP is 0 to 255 inclusive. To turn off this reporting, use
ID\ =\ 0. If the \fB\-C ID\fP option is not given, then it defaults to ID\ =\ 0. If the \fB\-C ID\fP option is not given, then it defaults to
\fB\-C 197\fP (since Attribute 197 is generally used to monitor \fB\-C 197\fP (since Attribute 197 is generally used to monitor
pending sectors). pending sectors). If the name of this Attribute is changed by a
\'\-v 197,FORMAT,NAME\' directive, the default is changed to
\fB\-C 0\fP.
If \'+\' is specified, a report is only printed if the number of sectors If \'+\' is specified, a report is only printed if the number of sectors
has increased between two check cycles. Some disks do not reset this has increased between two check cycles. Some disks do not reset this
@ -1510,7 +1494,6 @@ to is operating system and file system specific. You can typically
force the sector to reallocate by writing to it (translation: make the force the sector to reallocate by writing to it (translation: make the
device substitute a spare good sector for the bad one) but at the device substitute a spare good sector for the bad one) but at the
price of losing the 512 bytes of data stored there. price of losing the 512 bytes of data stored there.
.TP .TP
.B \-U ID[+] .B \-U ID[+]
[ATA only] Report if the number of offline uncorrectable sectors is [ATA only] Report if the number of offline uncorrectable sectors is
@ -1519,7 +1502,9 @@ value is the Offline Uncorrectable Sector count. The allowed range of
\fBID\fP is 0 to 255 inclusive. To turn off this reporting, use \fBID\fP is 0 to 255 inclusive. To turn off this reporting, use
ID\ =\ 0. If the \fB\-U ID\fP option is not given, then it defaults to ID\ =\ 0. If the \fB\-U ID\fP option is not given, then it defaults to
\fB\-U 198\fP (since Attribute 198 is generally used to monitor \fB\-U 198\fP (since Attribute 198 is generally used to monitor
offline uncorrectable sectors). offline uncorrectable sectors). If the name of this Attribute is changed
by a \'\-v 198,FORMAT,NAME\' (except \'\-v 198,FORMAT,Offline_Scan_UNC_SectCt\'),
directive, the default is changed to \fB\-U 0\fP.
If \'+\' is specified, a report is only printed if the number of sectors If \'+\' is specified, a report is only printed if the number of sectors
has increased since the last check cycle. Some disks do not reset this has increased since the last check cycle. Some disks do not reset this
@ -1531,7 +1516,6 @@ readable during an off\-line scan or a self\-test. This is important
to know, because if you have data stored in this disk sector, and you to know, because if you have data stored in this disk sector, and you
need to read it, the read will fail. Please see the previous \'\-C\' need to read it, the read will fail. Please see the previous \'\-C\'
option for more details. option for more details.
.TP .TP
.B \-W DIFF[,INFO[,CRIT]] .B \-W DIFF[,INFO[,CRIT]]
Report if the current temperature had changed by at least \fBDIFF\fP Report if the current temperature had changed by at least \fBDIFF\fP
@ -1539,7 +1523,7 @@ degrees since last report, or if new min or max temperature is detected.
Report or Warn if the temperature is greater or equal than one of Report or Warn if the temperature is greater or equal than one of
\fBINFO\fP or \fBCRIT\fP degrees Celsius. \fBINFO\fP or \fBCRIT\fP degrees Celsius.
If the limit \fBCRIT\fP is reached, a message with loglevel If the limit \fBCRIT\fP is reached, a message with loglevel
\fB\'LOG_CRITICAL\'\fP will be logged to syslog and a warning email \fB\'LOG_CRIT\'\fP will be logged to syslog and a warning email
will be send if '-m' is specified. If only the limit \fBINFO\fP is will be send if '-m' is specified. If only the limit \fBINFO\fP is
reached, a message with loglevel \fB\'LOG_INFO\'\fP will be logged. reached, a message with loglevel \fB\'LOG_INFO\'\fP will be logged.
@ -1572,7 +1556,6 @@ To combine all of the above reports, use:
For ATA devices, smartd interprets Attribute 194 as Temperature Celsius For ATA devices, smartd interprets Attribute 194 as Temperature Celsius
by default. This can be changed to Attribute 9 or 220 by the drive by default. This can be changed to Attribute 9 or 220 by the drive
database or by the \'-v\' directive, see below. database or by the \'-v\' directive, see below.
.TP .TP
.B \-F TYPE .B \-F TYPE
[ATA only] Modifies the behavior of \fBsmartd\fP to compensate for [ATA only] Modifies the behavior of \fBsmartd\fP to compensate for
@ -1581,24 +1564,24 @@ Directive are exclusive, so that only the final Directive given is
used. The valid values are: used. The valid values are:
.I none .I none
\- Assume that the device firmware obeys the ATA specifications. This is \- Assume that the device firmware obeys the ATA specifications. This
the default, unless the device has presets for \'\-F\' in the device is the default, unless the device has presets for \'\-F\' in the
database. device database.
.I samsung .I samsung
\- In some Samsung disks (example: model SV4012H Firmware Version: \- In some Samsung disks (example: model SV4012H Firmware Version:
RM100-08) some of the two- and four-byte quantities in the SMART data RM100\-08) some of the two\- and four\-byte quantities in the SMART data
structures are byte-swapped (relative to the ATA specification). structures are byte\-swapped (relative to the ATA specification).
Enabling this option tells \fBsmartd\fP to evaluate these quantities Enabling this option tells \fBsmartd\fP to evaluate these quantities
in byte-reversed order. Some signs that your disk needs this option in byte\-reversed order. Some signs that your disk needs this option
are (1) no self-test log printed, even though you have run self-tests; are (1) no self\-test log printed, even though you have run self\-tests;
(2) very large numbers of ATA errors reported in the ATA error log; (2) very large numbers of ATA errors reported in the ATA error log;
(3) strange and impossible values for the ATA error log timestamps. (3) strange and impossible values for the ATA error log timestamps.
.I samsung2 .I samsung2
\- In more recent Samsung disks (firmware revisions ending in "\-23") the \- In some Samsung disks the number of ATA errors reported is byte swapped.
number of ATA errors reported is byte swapped. Enabling this option Enabling this option tells \fBsmartd\fP to evaluate this quantity in
tells \fBsmartd\fP to evaluate this quantity in byte-reversed order. byte\-reversed order.
.I samsung3 .I samsung3
\- Some Samsung disks (at least SP2514N with Firmware VF100\-37) report \- Some Samsung disks (at least SP2514N with Firmware VF100\-37) report
@ -1606,12 +1589,11 @@ a self\-test still in progress with 0% remaining when the test was already
completed. If this directive is specified, \fBsmartd\fP will not skip the completed. If this directive is specified, \fBsmartd\fP will not skip the
next scheduled self\-test (see Directive \'\-s\' above) in this case. next scheduled self\-test (see Directive \'\-s\' above) in this case.
Note that an explicit \'\-F\' Directive will over-ride any preset Note that an explicit \'\-F\' Directive will over\-ride any preset
values for \'\-F\' (see the \'\-P\' option below). values for \'\-F\' (see the \'\-P\' option below).
[Please see the \fBsmartctl \-F\fP command-line option.] [Please see the \fBsmartctl \-F\fP command-line option.]
.TP .TP
.B \-v ID,FORMAT[:BYTEORDER][,NAME] .B \-v ID,FORMAT[:BYTEORDER][,NAME]
[ATA only] Sets a vendor\-specific raw value print FORMAT, an optional [ATA only] Sets a vendor\-specific raw value print FORMAT, an optional
@ -1630,7 +1612,6 @@ if no other \'-C\' directive is specified.
\- Raw Attribute number 198 (Offline Uncorrectable Sector Count) is not \- Raw Attribute number 198 (Offline Uncorrectable Sector Count) is not
reset if uncorrectable sector are reallocated. This sets \'-U 198+\' reset if uncorrectable sector are reallocated. This sets \'-U 198+\'
if no other \'-U\' directive is specified. if no other \'-U\' directive is specified.
.TP .TP
.B \-P TYPE .B \-P TYPE
Specifies whether Specifies whether
@ -1653,7 +1634,6 @@ valid arguments to this Directive are:
[Please see the [Please see the
.B smartctl \-P .B smartctl \-P
command-line option.] command-line option.]
.TP .TP
.B \-a .B \-a
Equivalent to turning on all of the following Directives: Equivalent to turning on all of the following Directives:
@ -1674,7 +1654,6 @@ to report nonzero values of the offline pending sector count.
Note that \-a is the default for ATA devices. If none of these other Note that \-a is the default for ATA devices. If none of these other
Directives is given, then \-a is assumed. Directives is given, then \-a is assumed.
.TP .TP
.B # .B #
Comment: ignore the remainder of the line. Comment: ignore the remainder of the line.
@ -1780,7 +1759,7 @@ sleep 30
.fi .fi
Some example scripts are distributed with the smartmontools package, Some example scripts are distributed with the smartmontools package,
in /usr/local/share/doc/smartmontools-5.1/examplescripts/. in /usr/local/share/doc/smartmontools/examplescripts/.
Please note that these scripts typically run as root, so any files Please note that these scripts typically run as root, so any files
that they read/write should not be writable by ordinary users or that they read/write should not be writable by ordinary users or
@ -2007,7 +1986,7 @@ is killed by SIGKILL (signal 9) then the exit status is 137.
.PP .PP
.SH AUTHOR .SH AUTHOR
\fBBruce Allen\fP smartmontools-support@lists.sourceforge.net \fBBruce Allen\fP smartmontools\-support@lists.sourceforge.net
.fi .fi
University of Wisconsin \- Milwaukee Physics Department University of Wisconsin \- Milwaukee Physics Department
@ -2036,8 +2015,8 @@ Many other individuals have made smaller contributions and corrections.
.SH CREDITS .SH CREDITS
.fi .fi
This code was derived from the smartsuite package, written by Michael This code was derived from the smartsuite package, written by Michael
Cornwell, and from the previous ucsc smartsuite package. It extends Cornwell, and from the previous UCSC smartsuite package. It extends
these to cover ATA-5 disks. This code was originally developed as a these to cover ATA\-5 disks. This code was originally developed as a
Senior Thesis by Michael Cornwell at the Concurrent Systems Laboratory Senior Thesis by Michael Cornwell at the Concurrent Systems Laboratory
(now part of the Storage Systems Research Center), Jack Baskin School (now part of the Storage Systems Research Center), Jack Baskin School
of Engineering, University of California, Santa of Engineering, University of California, Santa
@ -2048,7 +2027,8 @@ HOME PAGE FOR SMARTMONTOOLS:
Please see the following web site for updates, further documentation, bug Please see the following web site for updates, further documentation, bug
reports and patches: \fBhttp://smartmontools.sourceforge.net/\fP reports and patches: \fBhttp://smartmontools.sourceforge.net/\fP
.SH SEE ALSO: .SH
SEE ALSO:
\fBsmartd.conf\fP(5), \fBsmartctl\fP(8), \fBsyslogd\fP(8), \fBsmartd.conf\fP(5), \fBsmartctl\fP(8), \fBsyslogd\fP(8),
\fBsyslog.conf\fP(5), \fBbadblocks\fP(8), \fBide\-smart\fP(8), \fBregex\fP(7). \fBsyslog.conf\fP(5), \fBbadblocks\fP(8), \fBide\-smart\fP(8), \fBregex\fP(7).
@ -2057,26 +2037,26 @@ REFERENCES FOR SMART
.fi .fi
An introductory article about smartmontools is \fIMonitoring Hard An introductory article about smartmontools is \fIMonitoring Hard
Disks with SMART\fP, by Bruce Allen, Linux Journal, January 2004, Disks with SMART\fP, by Bruce Allen, Linux Journal, January 2004,
pages 74-77. This is \fBhttp://www.linuxjournal.com/article.php?sid=6983\fP pages 74\-77. This is \fBhttp://www.linuxjournal.com/article/6983\fP
online. online.
If you would like to understand better how SMART works, and what it If you would like to understand better how SMART works, and what it
does, a good place to start is with Sections 4.8 and 6.54 of the first does, a good place to start is with Sections 4.8 and 6.54 of the first
volume of the \'AT Attachment with Packet Interface-7\' (ATA/ATAPI-7) volume of the \'AT Attachment with Packet Interface\-7\' (ATA/ATAPI\-7)
specification. This documents the SMART functionality which the specification Revision 4b. This documents the SMART functionality which the
\fBsmartmontools\fP utilities provide access to. You can find \fBsmartmontools\fP utilities provide access to.
Revision 4b of this document at This and other versions of this Specification are available from
\fBhttp://www.t13.org/docs2004/d1532v1r4b-ATA-ATAPI-7.pdf\fP .
Earlier and later versions of this Specification are available from
the T13 web site \fBhttp://www.t13.org/\fP . the T13 web site \fBhttp://www.t13.org/\fP .
.fi .fi
The functioning of SMART was originally defined by the SFF-8035i The functioning of SMART was originally defined by the SFF\-8035i
revision 2 and the SFF-8055i revision 1.4 specifications. These are revision 2 and the SFF\-8055i revision 1.4 specifications. These are
publications of the Small Form Factors (SFF) Committee. Links to publications of the Small Form Factors (SFF) Committee.
these documents may be found in the References section of the
smartmontools home page at \fBhttp://smartmontools.sourceforge.net/#references\fP . Links to these and other documents may be found on the Links page of the
\fBsmartmontools\fP Wiki at
\fBhttp://sourceforge.net/apps/trac/smartmontools/wiki/Links\fP .
.SH .SH
SVN ID OF THIS PAGE: SVN ID OF THIS PAGE:
$Id: smartd.8.in 3076 2010-03-12 22:23:08Z chrfranke $ $Id: smartd.8.in 3117 2010-06-08 15:41:04Z chrfranke $

View File

@ -1,7 +1,7 @@
.ig .ig
Copyright (C) 2002-8 Bruce Allen <smartmontools-support@lists.sourceforge.net> Copyright (C) 2002-10 Bruce Allen <smartmontools-support@lists.sourceforge.net>
$Id: smartd.conf.5.in 3075 2010-03-12 22:01:44Z chrfranke $ $Id: smartd.conf.5.in 3117 2010-06-08 15:41:04Z chrfranke $
This program is free software; you can redistribute it and/or modify it 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 under the terms of the GNU General Public License as published by the Free
@ -17,7 +17,7 @@ at the Concurrent Systems Laboratory (now part of the Storage Systems
Research Center), Jack Baskin School of Engineering, University of Research Center), Jack Baskin School of Engineering, University of
California, Santa Cruz. http://ssrc.soe.ucsc.edu/ California, Santa Cruz. http://ssrc.soe.ucsc.edu/
.. ..
.TH SMARTD.CONF 5 CURRENT_CVS_DATE CURRENT_CVS_VERSION CURRENT_CVS_DATE .TH SMARTD.CONF 5 CURRENT_SVN_DATE CURRENT_SVN_VERSION CURRENT_SVN_DATE
.SH NAME .SH NAME
\fBsmartd.conf\fP \- SMART Disk Monitoring Daemon Configuration File\fP \fBsmartd.conf\fP \- SMART Disk Monitoring Daemon Configuration File\fP
@ -25,7 +25,7 @@ California, Santa Cruz. http://ssrc.soe.ucsc.edu/
.B /usr/local/etc/smartd.conf .B /usr/local/etc/smartd.conf
.SH PACKAGE VERSION .SH PACKAGE VERSION
CURRENT_CVS_VERSION released CURRENT_CVS_DATE at CURRENT_CVS_TIME CURRENT_SVN_VERSION CURRENT_SVN_DATE CURRENT_SVN_REV
.SH DESCRIPTION .SH DESCRIPTION
\fB/usr/local/etc/smartd.conf\fP is the configuration file for the \fBsmartd\fP \fB/usr/local/etc/smartd.conf\fP is the configuration file for the \fBsmartd\fP
@ -88,7 +88,7 @@ This file contains a list of devices to monitor, with one device per
line. An example file is included with the line. An example file is included with the
.B smartmontools .B smartmontools
distribution. You will find this sample configuration file in distribution. You will find this sample configuration file in
\fB/usr/local/share/doc/smartmontools-5.1/\fP. For security, the configuration file \fB/usr/local/share/doc/smartmontools/\fP. For security, the configuration file
should not be writable by anyone but root. The syntax of the file is as should not be writable by anyone but root. The syntax of the file is as
follows: follows:
.IP \(bu 4 .IP \(bu 4
@ -285,7 +285,6 @@ normal ATA devices. Hence all the ATA directives can be used for
these disks. Areca firmware version 1.46 or later which supports these disks. Areca firmware version 1.46 or later which supports
smartmontools must be used; Please see the \fBsmartctl\fP(8) man page smartmontools must be used; Please see the \fBsmartctl\fP(8) man page
for further details. for further details.
.TP .TP
.B \-d TYPE .B \-d TYPE
Specifies the type of the device. This Directive may be used multiple Specifies the type of the device. This Directive may be used multiple
@ -414,7 +413,6 @@ that it should continue (instead of exiting, which is the default
behavior) if the device does not appear to be present when behavior) if the device does not appear to be present when
\fBsmartd\fP is started. This Directive may be used in conjunction \fBsmartd\fP is started. This Directive may be used in conjunction
with the other \'\-d\' Directives. with the other \'\-d\' Directives.
.TP .TP
.B \-n POWERMODE[,N][,q] .B \-n POWERMODE[,N][,q]
This \'nocheck\' Directive is used to prevent a disk from being This \'nocheck\' Directive is used to prevent a disk from being
@ -472,7 +470,6 @@ the option \',q\' to POWERMODE (like \'\-n standby,q\').
This prevents a laptop disk from spinning up due to this message. This prevents a laptop disk from spinning up due to this message.
Both \',N\' and \',q\' can be specified together. Both \',N\' and \',q\' can be specified together.
.TP .TP
.B \-T TYPE .B \-T TYPE
Specifies how tolerant Specifies how tolerant
@ -520,19 +517,29 @@ Directive are \fIon\fP and \fIoff\fP. Also affects SCSI devices.
Check the SMART health status of the disk. If any Prefailure Check the SMART health status of the disk. If any Prefailure
Attributes are less than or equal to their threshold values, then disk Attributes are less than or equal to their threshold values, then disk
failure is predicted in less than 24 hours, and a message at loglevel failure is predicted in less than 24 hours, and a message at loglevel
.B \'LOG_CRITICAL\' .B \'LOG_CRIT\'
will be logged to syslog. [Please see the will be logged to syslog. [Please see the
.B smartctl \-H .B smartctl \-H
command-line option.] command-line option.]
.TP .TP
.B \-l TYPE .B \-l TYPE
Reports increases in the number of errors in one of the two SMART logs. The Reports increases in the number of errors in one of three SMART logs. The
valid arguments to this Directive are: valid arguments to this Directive are:
.I error .I error
\- report if the number of ATA errors reported in the ATA Error Log \- report if the number of ATA errors reported in the Summary SMART error log
has increased since the last check. has increased since the last check.
.I xerror
\- [NEW EXPERIMENTAL SMARTD FEATURE] report if the number of ATA errors
reported in the Extended Comprehensive SMART error log has increased since
the last check.
If both \'\-l error\' and \'\-l xerror\' are specified, smartd checks
the maximum of both values.
[Please see the \fBsmartctl \-l xerror\fP command-line option.]
.I selftest .I selftest
\- report if the number of failed tests reported in the SMART \- report if the number of failed tests reported in the SMART
Self-Test Log has increased since the last check, or if the timestamp Self-Test Log has increased since the last check, or if the timestamp
@ -673,7 +680,6 @@ file\-name pattern matching by the shell [glob(7)]. \fBsmartd\fP will
issue harmless informational warning messages if it detects characters issue harmless informational warning messages if it detects characters
in \fBREGEXP\fP that appear to indicate that you have made this in \fBREGEXP\fP that appear to indicate that you have made this
mistake. mistake.
.TP .TP
.B \-m ADD .B \-m ADD
Send a warning email to the email address \fBADD\fP if the \'\-H\', Send a warning email to the email address \fBADD\fP if the \'\-H\',
@ -741,7 +747,6 @@ if \'\fBmsgbox\fP\' is the first word in the comma separated list.
With \'\fBsysmsgbox\fP\', a system modal (always on top) message box With \'\fBsysmsgbox\fP\', a system modal (always on top) message box
is used. If running as a service, a service notification message box is used. If running as a service, a service notification message box
(always shown on current visible desktop) is used. (always shown on current visible desktop) is used.
.TP .TP
.B \-M TYPE .B \-M TYPE
These Directives modify the behavior of the These Directives modify the behavior of the
@ -796,7 +801,7 @@ to all logged-in users, etc.) But please be careful. \fBsmartd\fP
will \fBblock\fP until the executable PATH returns, so if your will \fBblock\fP until the executable PATH returns, so if your
executable hangs, then \fBsmartd\fP will also hang. Some sample executable hangs, then \fBsmartd\fP will also hang. Some sample
scripts are included in scripts are included in
/usr/local/share/doc/smartmontools-5.1/examplescripts/. /usr/local/share/doc/smartmontools/examplescripts/.
The return status of the executable is recorded by \fBsmartd\fP in The return status of the executable is recorded by \fBsmartd\fP in
SYSLOG. The executable is not expected to write to STDOUT or SYSLOG. The executable is not expected to write to STDOUT or
@ -858,6 +863,9 @@ read and are marked to be reallocated (replaced with spare sectors).
one or more disk sectors could not be read. one or more disk sectors could not be read.
.nf .nf
.fi .fi
\fITemperature\fP: Temperature reached critical limit (see \-W directive).
.nf
.fi
\fIFailedHealthCheck\fP: the SMART health status command failed. \fIFailedHealthCheck\fP: the SMART health status command failed.
.nf .nf
.fi .fi
@ -948,8 +956,7 @@ discarded.
Some EXAMPLES of scripts that can be used with the \'\-M exec\' Some EXAMPLES of scripts that can be used with the \'\-M exec\'
Directive are given below. Some sample scripts are also included in Directive are given below. Some sample scripts are also included in
/usr/local/share/doc/smartmontools-5.1/examplescripts/. /usr/local/share/doc/smartmontools/examplescripts/.
.TP .TP
.B \-f .B \-f
Check for \'failure\' of any Usage Attributes. If these Attributes are Check for \'failure\' of any Usage Attributes. If these Attributes are
@ -1012,7 +1019,6 @@ A common use of this Directive is to track the device Temperature
If the optional flag \'!\' is appended, a change of the Normalized If the optional flag \'!\' is appended, a change of the Normalized
value is considered critical. The report will be logged as LOG_CRIT value is considered critical. The report will be logged as LOG_CRIT
and a warning email will be sent if \'-m\' is specified. and a warning email will be sent if \'-m\' is specified.
.TP .TP
.B \-R ID[!] .B \-R ID[!]
When tracking, report whenever the \fIRaw\fP value of Attribute When tracking, report whenever the \fIRaw\fP value of Attribute
@ -1036,7 +1042,6 @@ If the optional flag \'!\' is appended, a change of the Raw
value is considered critical. The report will be logged as value is considered critical. The report will be logged as
LOG_CRIT and a warning email will be sent if \'-m\' is specified. LOG_CRIT and a warning email will be sent if \'-m\' is specified.
An example is \'-R 5!\' to warn when new sectors are reallocated. An example is \'-R 5!\' to warn when new sectors are reallocated.
.TP .TP
.B \-C ID[+] .B \-C ID[+]
[ATA only] Report if the current number of pending sectors is [ATA only] Report if the current number of pending sectors is
@ -1045,7 +1050,9 @@ value is the Current Pending Sector count. The allowed range of
\fBID\fP is 0 to 255 inclusive. To turn off this reporting, use \fBID\fP is 0 to 255 inclusive. To turn off this reporting, use
ID\ =\ 0. If the \fB\-C ID\fP option is not given, then it defaults to ID\ =\ 0. If the \fB\-C ID\fP option is not given, then it defaults to
\fB\-C 197\fP (since Attribute 197 is generally used to monitor \fB\-C 197\fP (since Attribute 197 is generally used to monitor
pending sectors). pending sectors). If the name of this Attribute is changed by a
\'\-v 197,FORMAT,NAME\' directive, the default is changed to
\fB\-C 0\fP.
If \'+\' is specified, a report is only printed if the number of sectors If \'+\' is specified, a report is only printed if the number of sectors
has increased between two check cycles. Some disks do not reset this has increased between two check cycles. Some disks do not reset this
@ -1063,7 +1070,6 @@ to is operating system and file system specific. You can typically
force the sector to reallocate by writing to it (translation: make the force the sector to reallocate by writing to it (translation: make the
device substitute a spare good sector for the bad one) but at the device substitute a spare good sector for the bad one) but at the
price of losing the 512 bytes of data stored there. price of losing the 512 bytes of data stored there.
.TP .TP
.B \-U ID[+] .B \-U ID[+]
[ATA only] Report if the number of offline uncorrectable sectors is [ATA only] Report if the number of offline uncorrectable sectors is
@ -1072,7 +1078,9 @@ value is the Offline Uncorrectable Sector count. The allowed range of
\fBID\fP is 0 to 255 inclusive. To turn off this reporting, use \fBID\fP is 0 to 255 inclusive. To turn off this reporting, use
ID\ =\ 0. If the \fB\-U ID\fP option is not given, then it defaults to ID\ =\ 0. If the \fB\-U ID\fP option is not given, then it defaults to
\fB\-U 198\fP (since Attribute 198 is generally used to monitor \fB\-U 198\fP (since Attribute 198 is generally used to monitor
offline uncorrectable sectors). offline uncorrectable sectors). If the name of this Attribute is changed
by a \'\-v 198,FORMAT,NAME\' (except \'\-v 198,FORMAT,Offline_Scan_UNC_SectCt\'),
directive, the default is changed to \fB\-U 0\fP.
If \'+\' is specified, a report is only printed if the number of sectors If \'+\' is specified, a report is only printed if the number of sectors
has increased since the last check cycle. Some disks do not reset this has increased since the last check cycle. Some disks do not reset this
@ -1084,7 +1092,6 @@ readable during an off\-line scan or a self\-test. This is important
to know, because if you have data stored in this disk sector, and you to know, because if you have data stored in this disk sector, and you
need to read it, the read will fail. Please see the previous \'\-C\' need to read it, the read will fail. Please see the previous \'\-C\'
option for more details. option for more details.
.TP .TP
.B \-W DIFF[,INFO[,CRIT]] .B \-W DIFF[,INFO[,CRIT]]
Report if the current temperature had changed by at least \fBDIFF\fP Report if the current temperature had changed by at least \fBDIFF\fP
@ -1092,7 +1099,7 @@ degrees since last report, or if new min or max temperature is detected.
Report or Warn if the temperature is greater or equal than one of Report or Warn if the temperature is greater or equal than one of
\fBINFO\fP or \fBCRIT\fP degrees Celsius. \fBINFO\fP or \fBCRIT\fP degrees Celsius.
If the limit \fBCRIT\fP is reached, a message with loglevel If the limit \fBCRIT\fP is reached, a message with loglevel
\fB\'LOG_CRITICAL\'\fP will be logged to syslog and a warning email \fB\'LOG_CRIT\'\fP will be logged to syslog and a warning email
will be send if '-m' is specified. If only the limit \fBINFO\fP is will be send if '-m' is specified. If only the limit \fBINFO\fP is
reached, a message with loglevel \fB\'LOG_INFO\'\fP will be logged. reached, a message with loglevel \fB\'LOG_INFO\'\fP will be logged.
@ -1125,7 +1132,6 @@ To combine all of the above reports, use:
For ATA devices, smartd interprets Attribute 194 as Temperature Celsius For ATA devices, smartd interprets Attribute 194 as Temperature Celsius
by default. This can be changed to Attribute 9 or 220 by the drive by default. This can be changed to Attribute 9 or 220 by the drive
database or by the \'-v\' directive, see below. database or by the \'-v\' directive, see below.
.TP .TP
.B \-F TYPE .B \-F TYPE
[ATA only] Modifies the behavior of \fBsmartd\fP to compensate for [ATA only] Modifies the behavior of \fBsmartd\fP to compensate for
@ -1134,24 +1140,24 @@ Directive are exclusive, so that only the final Directive given is
used. The valid values are: used. The valid values are:
.I none .I none
\- Assume that the device firmware obeys the ATA specifications. This is \- Assume that the device firmware obeys the ATA specifications. This
the default, unless the device has presets for \'\-F\' in the device is the default, unless the device has presets for \'\-F\' in the
database. device database.
.I samsung .I samsung
\- In some Samsung disks (example: model SV4012H Firmware Version: \- In some Samsung disks (example: model SV4012H Firmware Version:
RM100-08) some of the two- and four-byte quantities in the SMART data RM100\-08) some of the two\- and four\-byte quantities in the SMART data
structures are byte-swapped (relative to the ATA specification). structures are byte\-swapped (relative to the ATA specification).
Enabling this option tells \fBsmartd\fP to evaluate these quantities Enabling this option tells \fBsmartd\fP to evaluate these quantities
in byte-reversed order. Some signs that your disk needs this option in byte\-reversed order. Some signs that your disk needs this option
are (1) no self-test log printed, even though you have run self-tests; are (1) no self\-test log printed, even though you have run self\-tests;
(2) very large numbers of ATA errors reported in the ATA error log; (2) very large numbers of ATA errors reported in the ATA error log;
(3) strange and impossible values for the ATA error log timestamps. (3) strange and impossible values for the ATA error log timestamps.
.I samsung2 .I samsung2
\- In more recent Samsung disks (firmware revisions ending in "\-23") the \- In some Samsung disks the number of ATA errors reported is byte swapped.
number of ATA errors reported is byte swapped. Enabling this option Enabling this option tells \fBsmartd\fP to evaluate this quantity in
tells \fBsmartd\fP to evaluate this quantity in byte-reversed order. byte\-reversed order.
.I samsung3 .I samsung3
\- Some Samsung disks (at least SP2514N with Firmware VF100\-37) report \- Some Samsung disks (at least SP2514N with Firmware VF100\-37) report
@ -1159,12 +1165,11 @@ a self\-test still in progress with 0% remaining when the test was already
completed. If this directive is specified, \fBsmartd\fP will not skip the completed. If this directive is specified, \fBsmartd\fP will not skip the
next scheduled self\-test (see Directive \'\-s\' above) in this case. next scheduled self\-test (see Directive \'\-s\' above) in this case.
Note that an explicit \'\-F\' Directive will over-ride any preset Note that an explicit \'\-F\' Directive will over\-ride any preset
values for \'\-F\' (see the \'\-P\' option below). values for \'\-F\' (see the \'\-P\' option below).
[Please see the \fBsmartctl \-F\fP command-line option.] [Please see the \fBsmartctl \-F\fP command-line option.]
.TP .TP
.B \-v ID,FORMAT[:BYTEORDER][,NAME] .B \-v ID,FORMAT[:BYTEORDER][,NAME]
[ATA only] Sets a vendor\-specific raw value print FORMAT, an optional [ATA only] Sets a vendor\-specific raw value print FORMAT, an optional
@ -1183,7 +1188,6 @@ if no other \'-C\' directive is specified.
\- Raw Attribute number 198 (Offline Uncorrectable Sector Count) is not \- Raw Attribute number 198 (Offline Uncorrectable Sector Count) is not
reset if uncorrectable sector are reallocated. This sets \'-U 198+\' reset if uncorrectable sector are reallocated. This sets \'-U 198+\'
if no other \'-U\' directive is specified. if no other \'-U\' directive is specified.
.TP .TP
.B \-P TYPE .B \-P TYPE
Specifies whether Specifies whether
@ -1206,7 +1210,6 @@ valid arguments to this Directive are:
[Please see the [Please see the
.B smartctl \-P .B smartctl \-P
command-line option.] command-line option.]
.TP .TP
.B \-a .B \-a
Equivalent to turning on all of the following Directives: Equivalent to turning on all of the following Directives:
@ -1227,7 +1230,6 @@ to report nonzero values of the offline pending sector count.
Note that \-a is the default for ATA devices. If none of these other Note that \-a is the default for ATA devices. If none of these other
Directives is given, then \-a is assumed. Directives is given, then \-a is assumed.
.TP .TP
.B # .B #
Comment: ignore the remainder of the line. Comment: ignore the remainder of the line.
@ -1333,7 +1335,7 @@ sleep 30
.fi .fi
Some example scripts are distributed with the smartmontools package, Some example scripts are distributed with the smartmontools package,
in /usr/local/share/doc/smartmontools-5.1/examplescripts/. in /usr/local/share/doc/smartmontools/examplescripts/.
Please note that these scripts typically run as root, so any files Please note that these scripts typically run as root, so any files
that they read/write should not be writable by ordinary users or that they read/write should not be writable by ordinary users or
@ -1351,7 +1353,7 @@ The remainder is flushed.
.PP .PP
.SH AUTHOR .SH AUTHOR
\fBBruce Allen\fP smartmontools-support@lists.sourceforge.net \fBBruce Allen\fP smartmontools\-support@lists.sourceforge.net
.fi .fi
University of Wisconsin \- Milwaukee Physics Department University of Wisconsin \- Milwaukee Physics Department
@ -1380,8 +1382,8 @@ Many other individuals have made smaller contributions and corrections.
.SH CREDITS .SH CREDITS
.fi .fi
This code was derived from the smartsuite package, written by Michael This code was derived from the smartsuite package, written by Michael
Cornwell, and from the previous ucsc smartsuite package. It extends Cornwell, and from the previous UCSC smartsuite package. It extends
these to cover ATA-5 disks. This code was originally developed as a these to cover ATA\-5 disks. This code was originally developed as a
Senior Thesis by Michael Cornwell at the Concurrent Systems Laboratory Senior Thesis by Michael Cornwell at the Concurrent Systems Laboratory
(now part of the Storage Systems Research Center), Jack Baskin School (now part of the Storage Systems Research Center), Jack Baskin School
of Engineering, University of California, Santa of Engineering, University of California, Santa
@ -1390,10 +1392,7 @@ Cruz. \fBhttp://ssrc.soe.ucsc.edu/\fP .
HOME PAGE FOR SMARTMONTOOLS: HOME PAGE FOR SMARTMONTOOLS:
.fi .fi
Please see the following web site for updates, further documentation, bug Please see the following web site for updates, further documentation, bug
reports and patches: reports and patches: \fBhttp://smartmontools.sourceforge.net/\fP
.nf
.B
http://smartmontools.sourceforge.net/
.SH .SH
SEE ALSO: SEE ALSO:
@ -1402,4 +1401,4 @@ SEE ALSO:
.SH .SH
SVN ID OF THIS PAGE: SVN ID OF THIS PAGE:
$Id: smartd.conf.5.in 3075 2010-03-12 22:01:44Z chrfranke $ $Id: smartd.conf.5.in 3117 2010-06-08 15:41:04Z chrfranke $

View File

@ -126,7 +126,7 @@ extern "C" int getdomainname(char *, int); // no declaration in header files!
#define ARGUSED(x) ((void)(x)) #define ARGUSED(x) ((void)(x))
const char * smartd_cpp_cvsid = "$Id: smartd.cpp 3075 2010-03-12 22:01:44Z chrfranke $" const char * smartd_cpp_cvsid = "$Id: smartd.cpp 3101 2010-05-04 16:03:18Z chrfranke $"
CONFIG_H_CVSID EXTERN_H_CVSID; CONFIG_H_CVSID EXTERN_H_CVSID;
extern const char *reportbug; extern const char *reportbug;
@ -171,13 +171,7 @@ static std::string attrlog_path_prefix
; ;
// configuration file name // configuration file name
#define CONFIGFILENAME "smartd.conf" static const char * configfile;
#ifndef _WIN32
static const char *configfile = SMARTMONTOOLS_SYSCONFDIR "/" CONFIGFILENAME ;
#else
static const char *configfile = "./" CONFIGFILENAME ;
#endif
// configuration file "name" if read from stdin // configuration file "name" if read from stdin
static const char * const configfile_stdin = "<stdin>"; static const char * const configfile_stdin = "<stdin>";
// path of alternate configuration file // path of alternate configuration file
@ -264,6 +258,7 @@ struct dev_config
bool usage; // Track changes in Usage Attributes bool usage; // Track changes in Usage Attributes
bool selftest; // Monitor number of selftest errors bool selftest; // Monitor number of selftest errors
bool errorlog; // Monitor number of ATA errors bool errorlog; // Monitor number of ATA errors
bool xerrorlog; // Monitor number of ATA errors (Extended Comprehensive error log)
bool permissive; // Ignore failed SMART commands bool permissive; // Ignore failed SMART commands
char autosave; // 1=disable, 2=enable Autosave Attributes char autosave; // 1=disable, 2=enable Autosave Attributes
char autoofflinetest; // 1=disable, 2=enable Auto Offline Test char autoofflinetest; // 1=disable, 2=enable Auto Offline Test
@ -305,6 +300,7 @@ dev_config::dev_config()
usage(false), usage(false),
selftest(false), selftest(false),
errorlog(false), errorlog(false),
xerrorlog(false),
permissive(false), permissive(false),
autosave(0), autosave(0),
autoofflinetest(0), autoofflinetest(0),
@ -593,13 +589,14 @@ static bool read_dev_state(const char * path, persistent_dev_state & state)
setmode(fileno(f), O_TEXT); // Allow files with \r\n setmode(fileno(f), O_TEXT); // Allow files with \r\n
#endif #endif
persistent_dev_state new_state;
int good = 0, bad = 0; int good = 0, bad = 0;
char line[256]; char line[256];
while (fgets(line, sizeof(line), f)) { while (fgets(line, sizeof(line), f)) {
const char * s = line + strspn(line, " \t"); const char * s = line + strspn(line, " \t");
if (!*s || *s == '#') if (!*s || *s == '#')
continue; continue;
if (!parse_dev_state_line(line, state)) if (!parse_dev_state_line(line, new_state))
bad++; bad++;
else else
good++; good++;
@ -612,6 +609,9 @@ static bool read_dev_state(const char * path, persistent_dev_state & state)
} }
pout("%s: %d invalid line(s) ignored\n", path, bad); pout("%s: %d invalid line(s) ignored\n", path, bad);
} }
// This sets the values missing in the file to 0.
state = new_state;
return true; return true;
} }
@ -1412,7 +1412,7 @@ void Directives() {
" -n MODE No check if: never, sleep[,N][,q], standby[,N][,q], idle[,N][,q]\n" " -n MODE No check if: never, sleep[,N][,q], standby[,N][,q], idle[,N][,q]\n"
" -H Monitor SMART Health Status, report if failed\n" " -H Monitor SMART Health Status, report if failed\n"
" -s REG Do Self-Test at time(s) given by regular expression REG\n" " -s REG Do Self-Test at time(s) given by regular expression REG\n"
" -l TYPE Monitor SMART log. Type is one of: error, selftest\n" " -l TYPE Monitor SMART log. Type is one of: error, selftest, xerror\n"
" -f Monitor 'Usage' Attributes, report failures\n" " -f Monitor 'Usage' Attributes, report failures\n"
" -m ADD Send email warning to address ADD\n" " -m ADD Send email warning to address ADD\n"
" -M TYPE Modify email warning behavior (see man page)\n" " -M TYPE Modify email warning behavior (see man page)\n"
@ -1475,12 +1475,15 @@ void Usage (void){
PrintOut(LOG_INFO,"\n"); PrintOut(LOG_INFO,"\n");
PrintOut(LOG_INFO," -B [+]FILE, --drivedb=[+]FILE\n"); PrintOut(LOG_INFO," -B [+]FILE, --drivedb=[+]FILE\n");
PrintOut(LOG_INFO," Read and replace [add] drive database from FILE\n"); PrintOut(LOG_INFO," Read and replace [add] drive database from FILE\n");
PrintOut(LOG_INFO," [default is +%s", get_drivedb_path_add());
#ifdef SMARTMONTOOLS_DRIVEDBDIR #ifdef SMARTMONTOOLS_DRIVEDBDIR
PrintOut(LOG_INFO," [default is "SMARTMONTOOLS_DRIVEDBDIR"/drivedb.h]\n");
#endif
PrintOut(LOG_INFO,"\n"); PrintOut(LOG_INFO,"\n");
PrintOut(LOG_INFO," and then %s", get_drivedb_path_default());
#endif
PrintOut(LOG_INFO,"]\n\n");
PrintOut(LOG_INFO," -c NAME|-, --configfile=NAME|-\n"); PrintOut(LOG_INFO," -c NAME|-, --configfile=NAME|-\n");
PrintOut(LOG_INFO," Read configuration file NAME or stdin [default is %s]\n\n", configfile); PrintOut(LOG_INFO," Read configuration file NAME or stdin\n");
PrintOut(LOG_INFO," [default is %s]\n\n", configfile);
#ifdef HAVE_LIBCAP_NG #ifdef HAVE_LIBCAP_NG
PrintOut(LOG_INFO," -C, --capabilities\n"); PrintOut(LOG_INFO," -C, --capabilities\n");
PrintOut(LOG_INFO," Use capabilities (EXPERIMENTAL).\n" PrintOut(LOG_INFO," Use capabilities (EXPERIMENTAL).\n"
@ -1545,19 +1548,28 @@ static bool not_allowed_in_filename(char c)
|| ('a' <= c && c <= 'z')); || ('a' <= c && c <= 'z'));
} }
// returns <0 on failure // Read error count from Summary or Extended Comprehensive SMART error log
static int ATAErrorCount(ata_device * device, const char * name, // Return -1 on error
unsigned char fix_firmwarebug) static int read_ata_error_count(ata_device * device, const char * name,
unsigned char fix_firmwarebug, bool extended)
{ {
struct ata_smart_errorlog log; if (!extended) {
ata_smart_errorlog log;
if (ataReadErrorLog(device, &log, fix_firmwarebug)){ if (ataReadErrorLog(device, &log, fix_firmwarebug)){
PrintOut(LOG_INFO,"Device: %s, Read SMART Error Log Failed\n",name); PrintOut(LOG_INFO,"Device: %s, Read Summary SMART Error Log failed\n",name);
return -1; return -1;
} }
return (log.error_log_pointer ? log.ata_error_count : 0);
// return current number of ATA errors }
return log.error_log_pointer?log.ata_error_count:0; else {
ata_smart_exterrlog logx;
if (!ataReadExtErrorLog(device, &logx, 1 /*first sector only*/)) {
PrintOut(LOG_INFO,"Device: %s, Read Extended Comprehensive SMART Error Log failed\n",name);
return -1;
}
// Some disks use the reserved byte as index, see ataprint.cpp.
return (logx.error_log_index || logx.reserved1 ? logx.device_error_count : 0);
}
} }
// returns <0 if problem. Otherwise, bottom 8 bits are the self test // returns <0 if problem. Otherwise, bottom 8 bits are the self test
@ -1722,7 +1734,8 @@ static int ATADeviceScan(dev_config & cfg, dev_state & state, ata_device * atade
// do we need to get SMART data? // do we need to get SMART data?
bool smart_val_ok = false; bool smart_val_ok = false;
if ( cfg.autoofflinetest || cfg.errorlog || cfg.selftest if ( cfg.autoofflinetest || cfg.selftest
|| cfg.errorlog || cfg.xerrorlog
|| cfg.usagefailed || cfg.prefail || cfg.usage || cfg.usagefailed || cfg.prefail || cfg.usage
|| cfg.tempdiff || cfg.tempinfo || cfg.tempcrit || cfg.tempdiff || cfg.tempinfo || cfg.tempcrit
|| cfg.curr_pending_id || cfg.offl_pending_id ) { || cfg.curr_pending_id || cfg.offl_pending_id ) {
@ -1806,22 +1819,32 @@ static int ATADeviceScan(dev_config & cfg, dev_state & state, ata_device * atade
} }
// capability check: ATA error log // capability check: ATA error log
if (cfg.errorlog) { if (cfg.errorlog || cfg.xerrorlog) {
int val;
// start with service disabled, and re-enable it if all works OK
cfg.errorlog = false;
state.ataerrorcount=0; state.ataerrorcount=0;
if (!(cfg.permissive || (smart_val_ok && isSmartErrorLogCapable(&state.smartval, &drive)))) {
if (!smart_val_ok) PrintOut(LOG_INFO, "Device: %s, no SMART Error Log (%s), ignoring -l [x]error (override with -T permissive)\n",
PrintOut(LOG_INFO, "Device: %s, no SMART Error log (SMART READ DATA failed); disabling -l error\n", name); name, (!smart_val_ok ? "SMART READ DATA failed" : "capability missing"));
else if (!cfg.permissive && !isSmartErrorLogCapable(&state.smartval, &drive)) cfg.errorlog = cfg.xerrorlog = false;
PrintOut(LOG_INFO, "Device: %s, appears to lack SMART Error log; disabling -l error (override with -T permissive Directive)\n", name); }
else if ((val = ATAErrorCount(atadev, name, cfg.fix_firmwarebug)) < 0)
PrintOut(LOG_INFO, "Device: %s, no SMART Error log; remove -l error Directive from smartd.conf\n", name);
else { else {
cfg.errorlog = true; int errcnt1 = -1, errcnt2 = -1;
state.ataerrorcount=val; if (cfg.errorlog && (errcnt1 = read_ata_error_count(atadev, name, cfg.fix_firmwarebug, false)) < 0) {
PrintOut(LOG_INFO, "Device: %s, no Summary SMART Error Log, ignoring -l error\n", name);
cfg.errorlog = false;
}
if (cfg.xerrorlog && (errcnt2 = read_ata_error_count(atadev, name, cfg.fix_firmwarebug, true)) < 0) {
PrintOut(LOG_INFO, "Device: %s, no Extended Comprehensive SMART Error Log, ignoring -l xerror\n", name);
cfg.xerrorlog = false;
}
if (cfg.errorlog || cfg.xerrorlog) {
if (cfg.errorlog && cfg.xerrorlog && errcnt1 != errcnt2) {
PrintOut(LOG_INFO, "Device: %s, SMART Error Logs report different error counts: %d != %d\n",
name, errcnt1, errcnt2);
}
// Record max error count
state.ataerrorcount = (errcnt1 >= errcnt2 ? errcnt1 : errcnt2);
}
} }
} }
@ -1841,9 +1864,10 @@ static int ATADeviceScan(dev_config & cfg, dev_state & state, ata_device * atade
} }
// If no tests available or selected, return // If no tests available or selected, return
if (!(cfg.errorlog || cfg.selftest || cfg.smartcheck || if (!( cfg.smartcheck || cfg.selftest
cfg.usagefailed || cfg.prefail || cfg.usage || || cfg.errorlog || cfg.xerrorlog
cfg.tempdiff || cfg.tempinfo || cfg.tempcrit )) { || cfg.usagefailed || cfg.prefail || cfg.usage
|| cfg.tempdiff || cfg.tempinfo || cfg.tempcrit)) {
CloseDevice(atadev, name); CloseDevice(atadev, name);
return 3; return 3;
} }
@ -2058,7 +2082,8 @@ static void CheckSelfTestLogs(const dev_config & cfg, dev_state & state, int new
MailWarning(cfg, state, 3, "Device: %s, Self-Test Log error count increased from %d to %d", MailWarning(cfg, state, 3, "Device: %s, Self-Test Log error count increased from %d to %d",
name, oldc, newc); name, oldc, newc);
state.must_write = true; state.must_write = true;
} else if (oldh!=newh) { }
else if (newc > 0 && oldh != newh) {
// more recent error // more recent error
// a 'more recent' error might actually be a smaller hour number, // a 'more recent' error might actually be a smaller hour number,
// if the hour number has wrapped. // if the hour number has wrapped.
@ -2073,6 +2098,11 @@ static void CheckSelfTestLogs(const dev_config & cfg, dev_state & state, int new
state.must_write = true; state.must_write = true;
} }
// Print info if error entries have disappeared
if (oldc > newc)
PrintOut(LOG_INFO, "Device: %s, Self-Test Log error count decreased from %d to %d\n",
name, oldc, newc);
// Needed since self-test error count may DECREASE. Hour might // Needed since self-test error count may DECREASE. Hour might
// also have changed. // also have changed.
state.selflogcount= newc; state.selflogcount= newc;
@ -2764,12 +2794,16 @@ static int ATACheckDevice(const dev_config & cfg, dev_state & state, ata_device
CheckSelfTestLogs(cfg, state, SelfTestErrorCount(atadev, name, cfg.fix_firmwarebug)); CheckSelfTestLogs(cfg, state, SelfTestErrorCount(atadev, name, cfg.fix_firmwarebug));
// check if number of ATA errors has increased // check if number of ATA errors has increased
if (cfg.errorlog) { if (cfg.errorlog || cfg.xerrorlog) {
int newc, oldc= state.ataerrorcount; int errcnt1 = -1, errcnt2 = -1;
if (cfg.errorlog)
errcnt1 = read_ata_error_count(atadev, name, cfg.fix_firmwarebug, false);
if (cfg.xerrorlog)
errcnt2 = read_ata_error_count(atadev, name, cfg.fix_firmwarebug, true);
// new number of errors // new number of errors is max of both logs
newc = ATAErrorCount(atadev, name, cfg.fix_firmwarebug); int newc = (errcnt1 >= errcnt2 ? errcnt1 : errcnt2);
// did command fail? // did command fail?
if (newc<0) if (newc<0)
@ -2777,6 +2811,7 @@ static int ATACheckDevice(const dev_config & cfg, dev_state & state, ata_device
MailWarning(cfg, state, 7, "Device: %s, Read SMART Error Log Failed", name); MailWarning(cfg, state, 7, "Device: %s, Read SMART Error Log Failed", name);
// has error count increased? // has error count increased?
int oldc = state.ataerrorcount;
if (newc>oldc){ if (newc>oldc){
PrintOut(LOG_CRIT, "Device: %s, ATA error count increased from %d to %d\n", PrintOut(LOG_CRIT, "Device: %s, ATA error count increased from %d to %d\n",
name, oldc, newc); name, oldc, newc);
@ -2785,7 +2820,6 @@ static int ATACheckDevice(const dev_config & cfg, dev_state & state, ata_device
state.must_write = true; state.must_write = true;
} }
// this last line is probably not needed, count always increases
if (newc>=0) if (newc>=0)
state.ataerrorcount=newc; state.ataerrorcount=newc;
} }
@ -3213,6 +3247,9 @@ static int ParseToken(char * token, dev_config & cfg)
} else if (!strcmp(arg, "error")) { } else if (!strcmp(arg, "error")) {
// track changes in ATA error log // track changes in ATA error log
cfg.errorlog = true; cfg.errorlog = true;
} else if (!strcmp(arg, "xerror")) {
// track changes in Extended Comprehensive SMART error log
cfg.xerrorlog = true;
} else { } else {
badarg = 1; badarg = 1;
} }
@ -3504,9 +3541,10 @@ static int ParseConfigLine(dev_config_vector & conf_entries, int /*entry*/, int
} }
// If NO monitoring directives are set, then set all of them. // If NO monitoring directives are set, then set all of them.
if (!(cfg.smartcheck || cfg.usagefailed || cfg.prefail || if (!( cfg.smartcheck || cfg.selftest
cfg.usage || cfg.selftest || cfg.errorlog || || cfg.errorlog || cfg.xerrorlog
cfg.tempdiff || cfg.tempinfo || cfg.tempcrit )) { || cfg.usagefailed || cfg.prefail || cfg.usage
|| cfg.tempdiff || cfg.tempinfo || cfg.tempcrit)) {
PrintOut(LOG_INFO,"Drive: %s, implied '-a' Directive on line %d of file %s\n", PrintOut(LOG_INFO,"Drive: %s, implied '-a' Directive on line %d of file %s\n",
cfg.name.c_str(), cfg.lineno, configfile); cfg.name.c_str(), cfg.lineno, configfile);
@ -3720,17 +3758,22 @@ static bool is_abs_path(const char * path)
// Parses input line, prints usage message and // Parses input line, prints usage message and
// version/license/copyright messages // version/license/copyright messages
void ParseOpts(int argc, char **argv){ void ParseOpts(int argc, char **argv)
int optchar; {
char *tailptr; // Init default configfile path
long lchecktime; #ifndef _WIN32
configfile = SMARTMONTOOLS_SYSCONFDIR"/smartd.conf";
#else
static std::string configfile_str = get_exe_dir() + "/smartd.conf";
configfile = configfile_str.c_str();
#endif
// Please update GetValidArgList() if you edit shortopts // Please update GetValidArgList() if you edit shortopts
static const char shortopts[] = "c:l:q:dDni:p:r:s:A:B:Vh?" static const char shortopts[] = "c:l:q:dDni:p:r:s:A:B:Vh?"
#ifdef HAVE_LIBCAP_NG #ifdef HAVE_LIBCAP_NG
"C" "C"
#endif #endif
; ;
char *arg;
// Please update GetValidArgList() if you edit longopts // Please update GetValidArgList() if you edit longopts
struct option longopts[] = { struct option longopts[] = {
{ "configfile", required_argument, 0, 'c' }, { "configfile", required_argument, 0, 'c' },
@ -3765,11 +3808,12 @@ void ParseOpts(int argc, char **argv){
bool badarg = false; bool badarg = false;
bool no_defaultdb = false; // set true on '-B FILE' bool no_defaultdb = false; // set true on '-B FILE'
// Parse input options. This horrible construction is so that emacs // Parse input options.
// indents properly. Sorry. int optchar;
while (-1 != (optchar = while ((optchar = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) {
getopt_long(argc, argv, shortopts, longopts, NULL) char *arg;
)) { char *tailptr;
long lchecktime;
switch(optchar) { switch(optchar) {
case 'q': case 'q':

View File

@ -50,7 +50,7 @@
#include "atacmds.h" #include "atacmds.h"
#include "dev_interface.h" #include "dev_interface.h"
const char * utility_cpp_cvsid = "$Id: utility.cpp 3022 2010-01-01 17:02:00Z chrfranke $" const char * utility_cpp_cvsid = "$Id: utility.cpp 3090 2010-04-28 11:03:11Z chrfranke $"
UTILITY_H_CVSID INT64_H_CVSID; UTILITY_H_CVSID INT64_H_CVSID;
const char * packet_types[] = { const char * packet_types[] = {
@ -259,15 +259,23 @@ const char *packetdevicetype(int type){
return "Unknown"; return "Unknown";
} }
// Runtime check of byte ordering, throws if different from isbigendian().
void check_endianness()
{
union {
// Force compile error if int type is not 32bit.
unsigned char c[sizeof(unsigned) == 4 ? 4 : -1];
unsigned i;
} x = {{1,2,3,4}};
// Returns 1 if machine is big endian, else zero. This is a run-time int big = -1;
// rather than a compile-time function. We could do it at switch (x.i) {
// compile-time but in principle there are architectures that can run case 0x01020304: big = 1; break;
// with either byte-ordering. case 0x04030201: big = 0; break;
int isbigendian(){ }
short i=0x0100;
char *tmp=(char *)&i; if (big != (isbigendian() ? 1 : 0))
return *tmp; throw std::logic_error("CPU endianness does not match compile time test");
} }
// Utility function prints date and time and timezone into a character // Utility function prints date and time and timezone into a character

View File

@ -3,8 +3,8 @@
* *
* Home page of code is: http://smartmontools.sourceforge.net * Home page of code is: http://smartmontools.sourceforge.net
* *
* Copyright (C) 2002-9 Bruce Allen <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2002-10 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2008-9 Christian Franke <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2008-10 Christian Franke <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2000 Michael Cornwell <cornwell@acm.org> * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -26,7 +26,7 @@
#ifndef UTILITY_H_ #ifndef UTILITY_H_
#define UTILITY_H_ #define UTILITY_H_
#define UTILITY_H_CVSID "$Id: utility.h 3020 2009-12-31 01:11:51Z dlukes $" #define UTILITY_H_CVSID "$Id: utility.h 3093 2010-04-30 09:57:36Z chrfranke $"
#include <time.h> #include <time.h>
#include <sys/types.h> // for regex.h (according to POSIX) #include <sys/types.h> // for regex.h (according to POSIX)
@ -144,8 +144,19 @@ inline T * CheckFree(T * address, int whatline, const char* file)
// appropriate.] // appropriate.]
void PrintOut(int priority, const char *fmt, ...) __attribute__ ((format(printf, 2, 3))); void PrintOut(int priority, const char *fmt, ...) __attribute__ ((format(printf, 2, 3)));
// run time, determine byte ordering // Compile time check of byte ordering
int isbigendian(); // (inline const function allows compiler to remove dead code)
inline bool isbigendian()
{
#ifdef WORDS_BIGENDIAN
return true;
#else
return false;
#endif
}
// Runtime check of byte ordering, throws if different from isbigendian().
void check_endianness();
// This value follows the peripheral device type value as defined in // This value follows the peripheral device type value as defined in
// SCSI Primary Commands, ANSI INCITS 301:1997. It is also used in // SCSI Primary Commands, ANSI INCITS 301:1997. It is also used in
@ -316,6 +327,13 @@ private:
#define PRINT_ON(control) {if (control->printing_switchable) control->dont_print=false;} #define PRINT_ON(control) {if (control->printing_switchable) control->dont_print=false;}
#define PRINT_OFF(control) {if (control->printing_switchable) control->dont_print=true;} #define PRINT_OFF(control) {if (control->printing_switchable) control->dont_print=true;}
#ifdef _WIN32
// Get exe directory
//(implemented in os_win32.cpp)
std::string get_exe_dir();
#endif
#ifdef OLD_INTERFACE #ifdef OLD_INTERFACE
// possible values for controller_type in extern.h // possible values for controller_type in extern.h
#define CONTROLLER_UNKNOWN 0x00 #define CONTROLLER_UNKNOWN 0x00