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
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>
Christian Franke <franke@computer.org>
Guilhem Frézou <guilhem.frezou@catii.fr>
Douglas Gilbert <dougg@torque.net>
Douglas Gilbert <dgilbert@interlog.com>
Guido Guenther <agx@sigxcpu.org>
Geoff Keating <geoffk@geoffk.org>
Dr. David Kirkby <drkirkby@ntlworld.com>

123
CHANGELOG
View File

@ -1,6 +1,6 @@
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:
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>
[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:
- LaCie Desktop Hard Drive
- Prolific PL2507 (unsupported)

View File

@ -1,6 +1,6 @@
## 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@
@ -22,6 +22,13 @@ if ENABLE_ATTRIBUTELOG
AM_CPPFLAGS += -DSMARTMONTOOLS_ATTRIBUTELOG='"$(attributelog)"'
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 \
smartctl
@ -64,6 +71,8 @@ EXTRA_smartd_SOURCES = os_darwin.cpp \
os_netbsd.h \
os_openbsd.cpp \
os_openbsd.h \
os_qnxnto.cpp \
os_qnxnto.h \
os_solaris.cpp \
os_solaris.h \
os_solaris_ata.s \
@ -78,22 +87,13 @@ EXTRA_smartd_SOURCES = os_darwin.cpp \
if OS_WIN32_MINGW
smartd_SOURCES += \
posix/regex.h \
posix/regex.c \
os_win32/daemon_win32.h \
os_win32/daemon_win32.cpp \
os_win32/hostname_win32.h \
os_win32/hostname_win32.cpp \
os_win32/syslog.h \
os_win32/syslog_win32.cpp
# Included by regex.c:
EXTRA_smartd_SOURCES += \
posix/regcomp.c \
posix/regexec.c \
posix/regex_internal.c \
posix/regex_internal.h
smartd_SOURCES += \
os_win32/daemon_win32.cpp \
os_win32/daemon_win32.h \
os_win32/hostname_win32.cpp \
os_win32/hostname_win32.h \
os_win32/syslog_win32.cpp \
os_win32/syslog.h
endif
@ -135,6 +135,8 @@ EXTRA_smartctl_SOURCES = os_linux.cpp \
os_netbsd.h \
os_openbsd.cpp \
os_openbsd.h \
os_qnxnto.cpp \
os_qnxnto.h \
os_solaris.cpp \
os_solaris.h \
os_win32.cpp \
@ -145,19 +147,42 @@ EXTRA_smartctl_SOURCES = os_linux.cpp \
dev_legacy.cpp \
megaraid.h
if OS_WIN32_MINGW
if NEED_GETOPT_LONG
smartctl_SOURCES += \
posix/regex.h \
posix/regex.c \
os_win32/syslog.h
smartctl_SOURCES += \
getopt/getopt.c \
getopt/getopt.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:
EXTRA_smartctl_SOURCES += \
posix/regcomp.c \
posix/regexec.c \
posix/regex_internal.c \
posix/regex_internal.h
EXTRA_smartctl_SOURCES += \
regex/regcomp.c \
regex/regexec.c \
regex/regex_internal.c
EXTRA_smartd_SOURCES += \
regex/regcomp.c \
regex/regexec.c \
regex/regex_internal.c
endif
@ -442,13 +467,13 @@ MAN_ATTRIBUTELOG = sed '/BEGIN ENABLE_ATTRIBUTELOG/,/END ENABLE_ATTRIBUTELOG/d'
endif
MAN_FILTER = \
sed "s|CURRENT_CVS_VERSION|$(releaseversion)|g; \
s|CURRENT_CVS_DATE|`sed -n 's,^.*DATE[^"]*"\([^"]*\)".*$$,\1,p' svnversion.h`|g; \
s|CURRENT_CVS_TIME|`sed -n 's,^.*TIME[^"]*"\([^"]*\)".*$$,\1,p' svnversion.h`|g; \
sed "s|CURRENT_SVN_VERSION|$(releaseversion)|g; \
s|CURRENT_SVN_DATE|`sed -n 's,^.*DATE[^"]*"\([^"]*\)".*$$,\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/sbin/|$(sbindir)/|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/smart_drivedb\\.h|$(sysconfdir)/smart_drivedb\\.h|g" | \
$(MAN_CAPABILITIES) | \

8
NEWS
View File

@ -1,6 +1,6 @@
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:
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'.
- Drive database is in a separate source file 'drivedb.h'
which can be downloaded from SVN.
- USB ID info is now included in 'drivedb.h'.
- New script 'update-smart-drivedb'.
- 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
SCT Error Recovery Control time limit.
- smartctl options '--scan, --scan-open'.
- 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 cross compilation on Linux.
- Fix regression in smartctl option '-t select,M-N'.
- Fix SCT temperature table commands on big endian CPUs.
Date 2010-01-28

View File

@ -37,7 +37,7 @@
#include "utility.h"
#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;
// 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)
{
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;
}
@ -223,7 +229,7 @@ const char * map_old_vendor_opts[][2] = {
{"194,10xCelsius" , "194,temp10x,Temperature_Celsius_x10"},
{"194,unknown" , "194,raw48,Unknown_Attribute"},
{"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
{"200,writeerrorcount" , "200,raw48,Write_Error_Count"},
{"201,detectedtacount" , "201,raw48,Detected_TA_Count"},

View File

@ -44,7 +44,7 @@
#include "utility.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;
// 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)
static void PrintSmartExtSelfTestLog(const ata_smart_extselftestlog * log,
static bool PrintSmartExtSelfTestLog(const ata_smart_extselftestlog * log,
unsigned nsectors, unsigned max_entries)
{
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){
pout("No self-tests have been logged. [To run self-tests, use: smartctl -t]\n\n");
return;
return true;
}
// Check index
@ -1408,7 +1408,7 @@ static void PrintSmartExtSelfTestLog(const ata_smart_extselftestlog * log,
unsigned logidx = log->log_desc_index;
if (logidx > nentries) {
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),
@ -1443,6 +1443,7 @@ static void PrintSmartExtSelfTestLog(const ata_smart_extselftestlog * log,
false /*!print_error_only*/, print_header);
}
pout("\n");
return true;
}
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);
}
// 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 timewait,code;
int returnval=0, retid=0, supported=0, needupdate=0;
const char * powername = 0; char powerchg = 0;
int returnval = 0;
// If requested, check power mode first
const char * powername = 0;
bool powerchg = false;
if (options.powermode) {
unsigned char powerlimit = 0xff;
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.
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");
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);
}
// Was this a packet device?
if (retid>0){
pout("SMART support is: Unavailable - Packet Interface Devices [this device: %s] don't support ATA SMART\n", packetdevicetype(retid-1));
failuretest(MANDATORY_CMD, returnval|=FAILSMART);
}
// if drive does not supports SMART it's time to exit
supported=ataSmartSupport(&drive);
if (supported != 1){
if (supported==0) {
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 {
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);
pout(" Checking for SMART support by trying SMART ENABLE command.\n");
}
// Check and print SMART support and state
int smart_supported = -1, smart_enabled = -1;
if (need_smart_support || options.drive_info) {
if (ataEnableSmart(device)){
pout(" SMART ENABLE failed - this establishes that this device lacks SMART functionality.\n");
failuretest(MANDATORY_CMD, returnval|=FAILSMART);
supported=0;
// Packet device ?
if (retid > 0) {
pout("SMART support is: Unavailable - Packet Interface Devices [this device: %s] don't support ATA SMART\n",
packetdevicetype(retid-1));
}
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");
failuretest(MANDATORY_CMD, returnval|=FAILSMART);
// check SMART support by trying a command
pout(" Checking to be sure by trying SMART RETURN STATUS command.\n");
isenabled=ataDoesSmartWork(device);
}
else {
pout("SMART support is: Available - device has SMART capability.\n");
if (device->ata_identify_is_cached()) {
pout(" %sabled status cached by OS, trying SMART RETURN STATUS cmd.\n",
(isenabled?"En":"Dis"));
isenabled=ataDoesSmartWork(device);
// 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");
if (smart_supported && smart_enabled < 0) {
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);
// check SMART support by trying a command
pout(" Checking to be sure by trying SMART RETURN STATUS command.\n");
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 {
if (options.drive_info)
pout("SMART support is: Available - device has SMART capability.\n");
if (smart_enabled >= 0) {
if (device->ata_identify_is_cached()) {
if (options.drive_info)
pout(" %sabled status cached by OS, trying SMART RETURN STATUS cmd.\n",
(smart_enabled?"En":"Dis"));
smart_enabled = ataDoesSmartWork(device);
}
if (options.drive_info)
pout("SMART support is: %s\n",
(smart_enabled ? "Enabled" : "Disabled"));
}
}
}
}
if (isenabled)
pout("SMART support is: Enabled\n");
else {
if (ison==-1)
pout("SMART support is: Unavailable\n");
else
pout("SMART support is: Disabled\n");
}
// Print remaining drive info
if (options.drive_info) {
// Print the (now possibly changed) power mode if available
if (powername)
pout("Power mode %s %s\n", (powerchg?"was:":"is: "), powername);
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
if ( options.smart_disable || options.smart_enable
|| options.smart_auto_save_disable || options.smart_auto_save_enable
@ -1887,30 +1909,25 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
pout("Smartctl: SMART Enable Failed.\n\n");
failuretest(MANDATORY_CMD, returnval|=FAILSMART);
}
else
else {
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
if (options.smart_disable) {
if (ataDisableSmart(device)) {
pout( "Smartctl: SMART Disable Failed.\n\n");
failuretest(MANDATORY_CMD,returnval|=FAILSMART);
}
pout("SMART Disabled. Use option -s with argument 'on' to enable it.\n");
return returnval;
}
// Let's ALWAYS issue this command to get the SMART status
code=ataSmartStatus2(device);
if (code==-1)
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");
return returnval;
}
// Enable/Disable Auto-save attributes
if (options.smart_auto_save_enable) {
@ -1930,24 +1947,39 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
else
pout("SMART Attribute Autosave Disabled.\n");
}
// for everything else read values and thresholds are needed
if (ataReadSmartValues(device, &smartval)){
pout("Smartctl: SMART Read Values failed.\n\n");
failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
}
if (ataReadSmartThresholds(device, &smartthres)){
pout("Smartctl: SMART Read Thresholds failed.\n\n");
failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
// Read SMART values and thresholds if necessary
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");
failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
}
else {
smart_val_ok = true;
if (options.smart_check_status || options.smart_vendor_attrib) {
if (ataReadSmartThresholds(device, &smartthres)){
pout("Smartctl: SMART Read Thresholds failed.\n\n");
failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
}
else
smart_thres_ok = true;
}
}
}
// Enable/Disable Off-line testing
bool needupdate = false;
if (options.smart_auto_offl_enable) {
if (!isSupportAutomaticTimer(&smartval)){
pout("Warning: device does not support SMART Automatic Timers.\n\n");
failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
}
needupdate=1;
needupdate = smart_val_ok;
if (ataEnableAutoOffline(device)){
pout( "Smartctl: SMART Enable Automatic Offline Failed.\n\n");
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");
failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
}
needupdate=1;
needupdate = smart_val_ok;
if (ataDisableAutoOffline(device)){
pout("Smartctl: SMART Disable Automatic Offline Failed.\n\n");
failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
@ -1973,6 +2005,7 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
if (needupdate && ataReadSmartValues(device, &smartval)){
pout("Smartctl: SMART Read Values failed.\n\n");
failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
smart_val_ok = false;
}
// 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 )
pout("=== START OF READ SMART DATA SECTION ===\n");
// Check SMART status (use previously returned value)
// Check SMART status
if (options.smart_check_status) {
switch (code) {
switch (ataSmartStatus2(device)) {
case 0:
// The case where the disk health is OK
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)
pout("See vendor-specific Attribute list for marginal Attributes.\n\n");
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"
"Drive failure expected in less than 24 hours. SAVE ALL DATA.\n");
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;
if (options.smart_vendor_attrib)
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:
default:
// The case where something went wrong with HDIO_DRIVE_TASK ioctl()
if (find_failed_attr(&smartval, &smartthres, options.attribute_defs, 1)){
// Something went wrong with the SMART STATUS command.
// 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);
pout("SMART overall-health self-assessment test result: FAILED!\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 {
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)
pout("See vendor-specific Attribute list for marginal Attributes.\n\n");
else {
@ -2073,11 +2117,11 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
} // end of checking SMART Status
// Print general SMART values
if (options.smart_general_values)
if (smart_val_ok && options.smart_general_values)
PrintGeneralSmartValues(&smartval, &drive, fix_firmwarebug);
// Print vendor-specific attributes
if (options.smart_vendor_attrib) {
if (smart_val_ok && options.smart_vendor_attrib) {
PRINT_ON(con);
PrintSmartAttribWithThres(&smartval, &smartthres, attribute_defs,
(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");
failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
}
ata_smart_errorlog smarterror; memset(&smarterror, 0, sizeof(smarterror));
if (ataReadErrorLog(device, &smarterror, fix_firmwarebug)){
pout("Smartctl: SMART Error Log Read Failed\n");
failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
@ -2248,8 +2293,10 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
if (!ataReadExtSelfTestLog(device, log_07, nsectors))
failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
else {
PrintSmartExtSelfTestLog(log_07, nsectors, options.smart_ext_selftest_log);
ok = true;
if (!PrintSmartExtSelfTestLog(log_07, nsectors, options.smart_ext_selftest_log))
returnval |= FAILLOG;
else
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");
failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
}
ata_smart_selftestlog smartselftest; memset(&smartselftest, 0, sizeof(smartselftest));
if(ataReadSelfTestLog(device, &smartselftest, fix_firmwarebug)){
pout("Smartctl: SMART Self Test Log Read Failed\n");
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
if (options.smart_selftest_type == -1)
if (!smart_val_ok || options.smart_selftest_type == -1)
return returnval;
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
if ((timewait = TestTime(&smartval, options.smart_selftest_type))) {
int timewait = TestTime(&smartval, options.smart_selftest_type);
if (timewait) {
time_t t=time(NULL);
if (options.smart_selftest_type == OFFLINE_FULL_SCAN) {
t+=timewait;

View File

@ -14,7 +14,9 @@
# define _HAVE_CCISS
# endif
# include <asm/byteorder.h>
# define be32toh __be32_to_cpu
# ifndef be32toh
# define be32toh __be32_to_cpu
# endif
#elif defined(__FreeBSD__) && defined(HAVE_DEV_CISS_CISSIO_H)
# include <sys/endian.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.
AC_PREREQ(2.50)
@ -7,7 +7,7 @@ AC_INIT(smartmontools, 5.40, smartmontools-support@lists.sourceforge.net)
AC_CONFIG_SRCDIR(smartctl.cpp)
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_time="21:00:32 UTC"
@ -51,7 +51,7 @@ case "${host}" in
CPPFLAGS="$CPPFLAGS -mno-cygwin"
LDFLAGS="$LDFLAGS -mno-cygwin"
fi
CPPFLAGS="$CPPFLAGS -idirafter ${srcdir}/posix -idirafter ${srcdir}/os_win32"
CPPFLAGS="$CPPFLAGS -I$srcdir/os_win32"
;;
*-*-freebsd*)
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])
dnl Checks for library functions.
AC_CHECK_FUNCS([getopt_long], , [
AC_MSG_NOTICE([smartmontools does no longer support platforms without getopt_long().])
AC_MSG_NOTICE([Please inform ${PACKAGE_BUGREPORT},])
AC_MSG_NOTICE([including details about your build environment.])
AC_MSG_ERROR([function getopt_long() not found])
])
AC_CHECK_FUNCS([getopt_long], [need_getopt_long=no], [need_getopt_long=yes])
AM_CONDITIONAL(NEED_GETOPT_LONG, [test "$need_getopt_long" = "yes"])
AC_CHECK_FUNCS([regcomp], [need_regex=no], [need_regex=yes])
AM_CONDITIONAL(NEED_REGEX, [test "$need_regex" = "yes"])
AC_CHECK_FUNCS([getdomainname])
AC_CHECK_FUNCS([gethostname])
@ -122,6 +120,9 @@ AC_CHECK_FUNCS([sigset])
AC_CHECK_FUNCS([strtoull])
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
AH_TEMPLATE(HAVE_WORKING_SNPRINTF, [Define to 1 if the `snprintf' function is sane])
AC_MSG_CHECKING([for working snprintf])
@ -409,15 +410,60 @@ AC_SUBST(CXXFLAGS)
AC_OUTPUT(Makefile examplescripts/Makefile)
AC_PROG_MAKE_SET
# Print note that the docdir default value has changed
# TODO: Remove this after next release
if test "$docdir_is_default" = "yes"; then
old_def_docdir='${prefix}/share/doc/${PACKAGE}-${VERSION}'
old_def_docdir_eval="`eval eval eval echo $old_def_docdir`"
docdir_eval="`eval eval eval echo $docdir`"
AC_MSG_NOTICE([********** PLEASE NOTE **********])
AC_MSG_NOTICE(['docdir' default has changed])
AC_MSG_NOTICE([from: $old_def_docdir_eval])
AC_MSG_NOTICE([to: $docdir_eval])
AC_MSG_NOTICE([*********************************])
fi
echo "-----------------------------------------------------------------------------" >&AS_MESSAGE_FD
echo "${PACKAGE}-${VERSION} configuration:" >&AS_MESSAGE_FD
echo "host operating system: $host" >&AS_MESSAGE_FD
echo "C++ compiler: $CXX" >&AS_MESSAGE_FD
echo "preprocessor flags: $CPPFLAGS" >&AS_MESSAGE_FD
echo "C++ compiler flags: $CXXFLAGS" >&AS_MESSAGE_FD
echo "linker flags: $LDFLAGS" >&AS_MESSAGE_FD
case "$host_os" in
mingw*)
if test -n "$drivedbdir"; then
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
*
* 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
* it under the terms of the GNU General Public License as published by
@ -24,7 +24,7 @@
#include "dev_interface.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;
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 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++)
FreeNonZero(devnames[i], -1,__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");
return 0;
}
if (!(0 <= disknum && disknum <= 15)) {
set_err(EINVAL, "Option -d cciss,N (N=%d) must have 0 <= N <= 15", disknum);
if (!(0 <= disknum && disknum <= 127)) {
set_err(EINVAL, "Option -d cciss,N (N=%d) must have 0 <= N <= 127", disknum);
return 0;
}
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
* device. Set to "" if no info (apart from device id)
* 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
* a device. This should never be "".
* 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,
* so the order in the table is important for distinct entries that could match
* 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[] = {
*/
{ "$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",
""
@ -74,6 +91,7 @@ const drive_settings builtin_knowndrives[] = {
{ "SuperTalent UltraDrive GX SSD",
"STT_FT[MD](28|32|56|64)GX25H",
"", "",
" -v 1,raw64"
" -v 9,raw64"
" -v 12,raw64"
" -v 184,raw64,Initial_Bad_Block_Count"
@ -92,10 +110,15 @@ const drive_settings builtin_knowndrives[] = {
" -v 207,raw64,Max_Erase_Count"
" -v 208,raw64,Average_Erase_Count"
" -v 209,raw64,Remaining_Lifetime_Perc"
" -v 210,raw64"
" -v 211,raw64"
" -v 212,raw64"
" -v 213,raw64"
},
{ "Patriot Torqx SSD",
"Patriot[ -]Torqx.*",
"", "",
" -v 1,raw64"
" -v 9,raw64"
" -v 12,raw64"
" -v 184,raw64,Initial_Bad_Block_Count"
@ -114,10 +137,15 @@ const drive_settings builtin_knowndrives[] = {
" -v 207,raw64,Max_Erase_Count"
" -v 208,raw64,Average_Erase_Count"
" -v 209,raw64,Remaining_Lifetime_Perc"
" -v 210,raw64"
" -v 211,raw64"
" -v 212,raw64"
" -v 213,raw64"
},
{ "OCZ Vertex SSD",
"OCZ[ -]VERTEX.*",
"", "",
" -v 1,raw64"
" -v 9,raw64"
" -v 12,raw64"
" -v 184,raw64,Initial_Bad_Block_Count"
@ -136,10 +164,15 @@ const drive_settings builtin_knowndrives[] = {
" -v 207,raw64,Max_Erase_Count"
" -v 208,raw64,Average_Erase_Count"
" -v 209,raw64,Remaining_Lifetime_Perc"
" -v 210,raw64"
" -v 211,raw64"
" -v 212,raw64"
" -v 213,raw64"
},
{ "OCZ Agility SSD",
"OCZ[ -]AGILITY",
"OCZ[ -]AGILITY.*",
"", "",
" -v 1,raw64"
" -v 9,raw64"
" -v 12,raw64"
" -v 184,raw64,Initial_Bad_Block_Count"
@ -158,6 +191,10 @@ const drive_settings builtin_knowndrives[] = {
" -v 207,raw64,Max_Erase_Count"
" -v 208,raw64,Average_Erase_Count"
" -v 209,raw64,Remaining_Lifetime_Perc"
" -v 210,raw64"
" -v 211,raw64"
" -v 212,raw64"
" -v 213,raw64"
},
{ "Crucial M225 SSD",
"CRUCIAL_CT(64|128|256)M225",
@ -183,6 +220,8 @@ const drive_settings builtin_knowndrives[] = {
" -v 209,raw64,Remaining_Lifetime_Perc"
" -v 210,raw64"
" -v 211,raw64"
" -v 212,raw64"
" -v 213,raw64"
},
{ "Intel X25-E SSD",
"SSDSA2SH(032|064)G1.* INTEL", // G1 = first generation
@ -190,16 +229,30 @@ const drive_settings builtin_knowndrives[] = {
"-v 225,raw48,Host_Writes_Count"
},
{ "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"
},
{ "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)",
"", "", ""
},
{ "Transcend Solid-State Drive V series",
{ "Transcend SATA Solid State Drive",
"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)",
@ -240,8 +293,8 @@ const drive_settings builtin_knowndrives[] = {
"http://www.ibm.com/pc/support/site.wss/MIGR-42215.html",
""
},
{ "", // ExcelStor J240, J340, J360, J680, and J880
"ExcelStor Technology J(24|34|36|68|88)0",
{ "", // ExcelStor J240, J340, J360, J680, J880 and J8160
"ExcelStor Technology J(24|34|36|68|88|816)0",
"", "", ""
},
{ "", // Fujitsu M1623TAU
@ -519,6 +572,12 @@ const drive_settings builtin_knowndrives[] = {
"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.
// 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 Travelstar 5K80 family",
{ "Hitachi Travelstar 5K80",
"(Hitachi )?HTS5480[8642]0M9AT00",
"", "", ""
},
{ "Hitachi Travelstar 5K100 series",
{ "Hitachi Travelstar 5K100",
"(Hitachi )?HTS5410[1864]0G9(AT|SA)00",
"", "", ""
},
{ "Hitachi Travelstar E5K100 series",
{ "Hitachi Travelstar E5K100",
"(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 Travelstar 5K160 series",
{ "Hitachi Travelstar 5K160",
"(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 Travelstar 5K250 series",
{ "Hitachi Travelstar 5K250",
"(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 Travelstar 5K500.B",
"(Hitachi )?HT[ES]5450(12|16|25|32|40|50)B9A30[01]",
"", "", ""
},
{ "Hitachi Travelstar 7K60",
"(Hitachi )?HTS726060M9AT00",
"", "", ""
@ -961,7 +1024,7 @@ const drive_settings builtin_knowndrives[] = {
"(IBM-)?IC35L(030|060|090|120|180)AVV207-[01]",
"", "", ""
},
{ "Hitachi Deskstar 7K80 series",
{ "Hitachi Deskstar 7K80",
"(Hitachi )?HDS7280([48]0PLAT20|(40)?PLA320|80PLA380).*",
"", "", ""
},
@ -969,7 +1032,7 @@ const drive_settings builtin_knowndrives[] = {
"(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)",
"", "", ""
},
@ -977,19 +1040,19 @@ const drive_settings builtin_knowndrives[] = {
"HITACHI HDS7225SBSUN250G.*",
"", "", ""
},
{ "Hitachi Deskstar T7K250 series",
{ "Hitachi Deskstar T7K250",
"(Hitachi )?HDT7225((25|20|16)DLA(T80|380))",
"", "", ""
},
{ "Hitachi Deskstar 7K400 series",
{ "Hitachi Deskstar 7K400",
"(Hitachi )?HDS724040KL(AT|SA)80",
"", "", ""
},
{ "Hitachi Deskstar 7K500 series",
{ "Hitachi Deskstar 7K500",
"(Hitachi )?HDS725050KLA(360|T80)",
"", "", ""
},
{ "Hitachi Deskstar P7K500 series",
{ "Hitachi Deskstar P7K500",
"(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 Deskstar 7K1000.C",
"(Hitachi )?HDS7210((16|25)CLA382|(32|50)CLA362|(64|75|10)CLA332)",
"", "", ""
},
{ "Hitachi Deskstar 7K2000",
"Hitachi HDS722020ALA330",
"", "", ""
@ -1013,6 +1080,10 @@ const drive_settings builtin_knowndrives[] = {
"(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 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)-.*",
"", "", ""
},
{ "Western Digital Caviar Green (Adv. Format) family",
"WDC WD((64|80)00A|(10|15|20)E)ARS-.*",
"", "", ""
},
{ "Western Digital Caviar Black family",
"WDC WD((500|640|750)1AA|1001FA)LS-.*",
"", "", ""
@ -1392,11 +1467,11 @@ const drive_settings builtin_knowndrives[] = {
"", "", ""
},
{ "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",
"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",
@ -1432,7 +1507,7 @@ const drive_settings builtin_knowndrives[] = {
"", "", ""
},
{ "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)",
@ -1487,6 +1562,400 @@ const drive_settings builtin_knowndrives[] = {
"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[]
*/

View File

@ -4,8 +4,8 @@
* Home page of code is: http://smartmontools.sourceforge.net
* Address of support mailing list: smartmontools-support@lists.sourceforge.net
*
* Copyright (C) 2003-9 Philip Williams, Bruce Allen
* Copyright (C) 2008-9 Christian Franke <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2003-10 Philip Williams, Bruce Allen
* Copyright (C) 2008-10 Christian Franke <smartmontools-support@lists.sourceforge.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -35,7 +35,7 @@
#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;
#define MODEL_STRING_LENGTH 40
@ -140,6 +140,18 @@ const char * drive_database::copy_string(const char * src)
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.
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 = "";
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].
if (!match(knowndrives[i].modelregexp, model))
continue;
@ -190,9 +206,10 @@ const drive_settings * lookup_drive(const char * model, const char * firmware)
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,
unsigned char & fix_firmwarebug)
// Parse drive or USB options in preset string, return false on error.
static bool parse_db_presets(const char * presets, ata_vendor_attr_defs * defs,
unsigned char * fix_firmwarebug, std::string * type)
{
for (int i = 0; ; ) {
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;
if (!(sscanf(presets+i, "-%c %40[^ ]%n", &opt, arg, &len) >= 2 && len > 0))
return false;
if (opt == 'v') {
if (opt == 'v' && defs) {
// Parse "-v N,format[,name]"
if (!parse_attribute_def(arg, defs, PRIOR_DATABASE))
if (!parse_attribute_def(arg, *defs, PRIOR_DATABASE))
return false;
}
else if (opt == 'F') {
else if (opt == 'F' && fix_firmwarebug) {
unsigned char fix;
if (!strcmp(arg, "samsung"))
fix = FIX_SAMSUNG;
@ -217,8 +234,12 @@ static bool parse_presets(const char * presets, ata_vendor_attr_defs & defs,
else
return false;
// Set only if not set by user
if (fix_firmwarebug == FIX_NOTSPECIFIED)
fix_firmwarebug = fix;
if (*fix_firmwarebug == FIX_NOTSPECIFIED)
*fix_firmwarebug = fix;
}
else if (opt == 'd' && type) {
// TODO: Check valid types
*type = arg;
}
else
return false;
@ -228,6 +249,83 @@ static bool parse_presets(const char * presets, ata_vendor_attr_defs & defs,
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.
static int showonepreset(const drive_settings * dbentry)
{
@ -242,60 +340,80 @@ static int showonepreset(const drive_settings * dbentry)
"this error to smartmontools developers at " PACKAGE_BUGREPORT ".\n");
return 1;
}
bool usb = is_usb_entry(dbentry);
// print and check model and firmware regular expressions
int errcnt = 0;
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))
errcnt++;
pout("%-*s %s\n", TABLEPRINTWIDTH, "FIRMWARE REGEXP:", *dbentry->firmwareregexp ?
dbentry->firmwareregexp : ".*"); // preserve old output (TODO: Change)
pout("%-*s %s\n", TABLEPRINTWIDTH, (!usb ? "FIRMWARE REGEXP:" : "USB bcdDevice:"),
*dbentry->firmwareregexp ? dbentry->firmwareregexp : ".*"); // preserve old output (TODO: Change)
if (*dbentry->firmwareregexp && !compile(regex, dbentry->firmwareregexp))
errcnt++;
pout("%-*s %s\n", TABLEPRINTWIDTH, "MODEL FAMILY:", dbentry->modelfamily);
if (!usb) {
pout("%-*s %s\n", TABLEPRINTWIDTH, "MODEL FAMILY:", dbentry->modelfamily);
// if there are any presets, then show them
unsigned char fix_firmwarebug = 0;
bool first_preset = true;
if (*dbentry->presets) {
ata_vendor_attr_defs defs;
if (!parse_presets(dbentry->presets, defs, fix_firmwarebug)) {
pout("Syntax error in preset option string \"%s\"\n", dbentry->presets);
errcnt++;
}
for (int i = 0; i < MAX_ATTRIBUTE_NUM; i++) {
if (defs[i].priority != PRIOR_DEFAULT) {
// Use leading zeros instead of spaces so that everything lines up.
pout("%-*s %03d %s\n", TABLEPRINTWIDTH, first_preset ? "ATTRIBUTE OPTIONS:" : "",
i, ata_get_smart_attr_name(i, defs).c_str());
first_preset = false;
// if there are any presets, then show them
unsigned char fix_firmwarebug = 0;
bool first_preset = true;
if (*dbentry->presets) {
ata_vendor_attr_defs defs;
if (!parse_presets(dbentry->presets, defs, fix_firmwarebug)) {
pout("Syntax error in preset option string \"%s\"\n", dbentry->presets);
errcnt++;
}
for (int i = 0; i < MAX_ATTRIBUTE_NUM; i++) {
if (defs[i].priority != PRIOR_DEFAULT) {
// Use leading zeros instead of spaces so that everything lines up.
pout("%-*s %03d %s\n", TABLEPRINTWIDTH, first_preset ? "ATTRIBUTE OPTIONS:" : "",
i, ata_get_smart_attr_name(i, defs).c_str());
first_preset = false;
}
}
}
}
if (first_preset)
pout("%-*s %s\n", TABLEPRINTWIDTH, "ATTRIBUTE OPTIONS:", "None preset; no -v options are required.");
if (first_preset)
pout("%-*s %s\n", TABLEPRINTWIDTH, "ATTRIBUTE OPTIONS:", "None preset; no -v options are required.");
// describe firmwarefix
if (fix_firmwarebug) {
const char * fixdesc;
switch (fix_firmwarebug) {
case FIX_SAMSUNG:
fixdesc = "Fixes byte order in some SMART data (same as -F samsung)";
break;
case FIX_SAMSUNG2:
fixdesc = "Fixes byte order in some SMART data (same as -F samsung2)";
break;
case FIX_SAMSUNG3:
fixdesc = "Fixes completed self-test reported as in progress (same as -F samsung3)";
break;
default:
fixdesc = "UNKNOWN"; errcnt++;
break;
// describe firmwarefix
if (fix_firmwarebug) {
const char * fixdesc;
switch (fix_firmwarebug) {
case FIX_SAMSUNG:
fixdesc = "Fixes byte order in some SMART data (same as -F samsung)";
break;
case FIX_SAMSUNG2:
fixdesc = "Fixes byte order in some SMART data (same as -F samsung2)";
break;
case FIX_SAMSUNG3:
fixdesc = "Fixes completed self-test reported as in progress (same as -F samsung3)";
break;
default:
fixdesc = "UNKNOWN"; errcnt++;
break;
}
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
@ -633,10 +751,19 @@ static bool parse_drive_database(parse_ptr src, drive_database & db, const char
break;
case 4:
if (!token.value.empty()) {
ata_vendor_attr_defs defs; unsigned char fix = 0;
if (!parse_presets(token.value.c_str(), defs, fix)) {
pout("%s(%d): Syntax error in preset option string\n", path, token.line);
ok = false;
if (!is_usb_modelfamily(values[0].c_str())) {
ata_vendor_attr_defs defs; unsigned char fix = 0;
if (!parse_presets(token.value.c_str(), defs, fix)) {
pout("%s(%d): Syntax error in preset option string\n", path, token.line);
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;
@ -687,23 +814,45 @@ bool read_drive_database(const char * 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.
bool read_default_drive_databases()
{
#ifndef _WIN32
// Read file for local additions: /{,usr/local/}etc/smart_drivedb.h
static const char db1[] = SMARTMONTOOLS_SYSCONFDIR"/smart_drivedb.h";
#else
static const char db1[] = "./smart_drivedb.h";
#endif
const char * db1 = get_drivedb_path_add();
if (!access(db1, 0)) {
if (!read_drive_database(db1))
return false;
}
#ifdef SMARTMONTOOLS_DRIVEDBDIR
// Read file from package: // /usr/{,local/}share/smartmontools/drivedb.h
static const char db2[] = SMARTMONTOOLS_DRIVEDBDIR"/drivedb.h";
// Read file from package: /usr/{,local/}share/smartmontools/drivedb.h
const char * db2 = get_drivedb_path_default();
if (!access(db2, 0)) {
if (!read_drive_database(db2))
return false;

View File

@ -4,8 +4,8 @@
* Home page of code is: http://smartmontools.sourceforge.net
* Address of support mailing list: smartmontools-support@lists.sourceforge.net
*
* Copyright (C) 2003-9 Philip Williams, Bruce Allen
* Copyright (C) 2008-9 Christian Franke <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2003-10 Philip Williams, Bruce Allen
* Copyright (C) 2008-10 Christian Franke <smartmontools-support@lists.sourceforge.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -21,7 +21,7 @@
#ifndef 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.
struct drive_settings {
@ -36,6 +36,18 @@ struct drive_settings {
// string.
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.
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,
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.
bool read_drive_database(const char * path);

View File

@ -63,13 +63,20 @@ typedef struct
uint8_t status;
} __attribute__((packed)) megacmd_t;
typedef struct {
typedef union {
uint8_t *pointer;
#if BITS_PER_LONG == 32
uint8_t pad[4];
#endif
uint8_t pad[8];
} 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
{
uint32_t inlen;

View File

@ -71,9 +71,9 @@
#define PATHINQ_SETTINGS_SIZE 128
#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;
extern smartmonctrl * con;
@ -121,7 +121,7 @@ void printwarning(int msgNo, const char* extra) {
// global variable holding byte count of allocated memory
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;
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");
return 0;
}
if (!(0 <= disknum && disknum <= 15)) {
set_err(EINVAL, "Option -d cciss,N (N=%d) must have 0 <= N <= 15", disknum);
if (!(0 <= disknum && disknum <= 127)) {
set_err(EINVAL, "Option -d cciss,N (N=%d) must have 0 <= N <= 127", disknum);
return 0;
}
return new freebsd_cciss_device(this, name, disknum);

View File

@ -4,7 +4,7 @@
* Home page of code is: http://smartmontools.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 Oliver Bock <brevilo@users.sourceforge.net>
* Copyright (C) 2008-10 Christian Franke <smartmontools-support@lists.sourceforge.net>
@ -90,7 +90,7 @@
#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;
/* 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");
return 0;
}
if (!(0 <= disknum && disknum <= 15)) {
set_err(EINVAL, "Option -d cciss,N (N=%d) must have 0 <= N <= 15", disknum);
if (!(0 <= disknum && disknum <= 127)) {
set_err(EINVAL, "Option -d cciss,N (N=%d) must have 0 <= N <= 127", disknum);
return 0;
}
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
// appearing with #include "*.h" above. Please list these (below) in
// 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;
@ -624,7 +624,7 @@ struct cam_pass_thru cpt;
cpt.cam_timeout=cpt.cam_timeout?cpt.cam_timeout:CAM_TIME_DEFAULT;
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);
icnt++;
}

View File

@ -69,7 +69,7 @@ extern smartmonctrl * con; // con->permissive,reportataioctl
#define SELECT_WIN_32_64(x32, x64) (x64)
#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.
#ifdef _WIN64
@ -1740,9 +1740,9 @@ static int storage_query_property_ioctl(HANDLE hdevice, STORAGE_DEVICE_DESCRIPTO
" Revision: \"%s\"\n"
" Removable: %s\n"
" BusType: 0x%02x\n",
(data->desc.VendorIdOffset ? data->raw+data->desc.VendorIdOffset : ""),
(data->desc.ProductIdOffset ? data->raw+data->desc.ProductIdOffset : ""),
(data->desc.ProductRevisionOffset ? data->raw+data->desc.ProductRevisionOffset : ""),
(data->desc.VendorIdOffset ? data->raw+data->desc.VendorIdOffset : "(null)"),
(data->desc.ProductIdOffset ? data->raw+data->desc.ProductIdOffset : "(null)"),
(data->desc.ProductRevisionOffset ? data->raw+data->desc.ProductRevisionOffset : "(null)"),
(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;
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)
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->cfs_enable_1 = 0x0001; id->csf_default = 0x4000; // SMART enabled, words 85,87 valid
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
Name="VCCLCompilerTool"
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"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@ -116,7 +116,7 @@
/>
<Tool
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"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
@ -302,22 +302,10 @@
</File>
</Filter>
<Filter
Name="posix"
Name="regex"
>
<File
RelativePath="..\posix\getopt.c"
>
</File>
<File
RelativePath="..\posix\getopt.h"
>
</File>
<File
RelativePath="..\posix\getopt1.c"
>
</File>
<File
RelativePath="..\posix\regcomp.c"
RelativePath="..\regex\regcomp.c"
>
<FileConfiguration
Name="Debug|Win32"
@ -337,15 +325,15 @@
</FileConfiguration>
</File>
<File
RelativePath="..\posix\regex.c"
RelativePath="..\regex\regex.c"
>
</File>
<File
RelativePath="..\posix\regex.h"
RelativePath="..\regex\regex.h"
>
</File>
<File
RelativePath="..\posix\regex_internal.c"
RelativePath="..\regex\regex_internal.c"
>
<FileConfiguration
Name="Debug|Win32"
@ -365,11 +353,11 @@
</FileConfiguration>
</File>
<File
RelativePath="..\posix\regex_internal.h"
RelativePath="..\regex\regex_internal.h"
>
</File>
<File
RelativePath="..\posix\regexec.c"
RelativePath="..\regex\regexec.c"
>
<FileConfiguration
Name="Debug|Win32"
@ -389,6 +377,22 @@
</FileConfiguration>
</File>
</Filter>
<Filter
Name="getopt"
>
<File
RelativePath="..\getopt\getopt.c"
>
</File>
<File
RelativePath="..\getopt\getopt.h"
>
</File>
<File
RelativePath="..\getopt\getopt1.c"
>
</File>
</Filter>
<File
RelativePath="..\atacmdnames.cpp"
>

View File

@ -40,7 +40,7 @@
<Tool
Name="VCCLCompilerTool"
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"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@ -116,7 +116,7 @@
/>
<Tool
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"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
@ -206,22 +206,10 @@
</File>
</Filter>
<Filter
Name="posix"
Name="regex"
>
<File
RelativePath="..\posix\getopt.c"
>
</File>
<File
RelativePath="..\posix\getopt.h"
>
</File>
<File
RelativePath="..\posix\getopt1.c"
>
</File>
<File
RelativePath="..\posix\regcomp.c"
RelativePath="..\regex\regcomp.c"
>
<FileConfiguration
Name="Debug|Win32"
@ -241,15 +229,15 @@
</FileConfiguration>
</File>
<File
RelativePath="..\posix\regex.c"
RelativePath="..\regex\regex.c"
>
</File>
<File
RelativePath="..\posix\regex.h"
RelativePath="..\regex\regex.h"
>
</File>
<File
RelativePath="..\posix\regex_internal.c"
RelativePath="..\regex\regex_internal.c"
>
<FileConfiguration
Name="Debug|Win32"
@ -269,11 +257,11 @@
</FileConfiguration>
</File>
<File
RelativePath="..\posix\regex_internal.h"
RelativePath="..\regex\regex_internal.h"
>
</File>
<File
RelativePath="..\posix\regexec.c"
RelativePath="..\regex\regexec.c"
>
<FileConfiguration
Name="Debug|Win32"
@ -293,6 +281,22 @@
</FileConfiguration>
</File>
</Filter>
<Filter
Name="getopt"
>
<File
RelativePath="..\getopt\getopt.c"
>
</File>
<File
RelativePath="..\getopt\getopt.h"
>
</File>
<File
RelativePath="..\getopt\getopt1.c"
>
</File>
</Filter>
<File
RelativePath="..\atacmdnames.cpp"
>

View File

@ -3,7 +3,7 @@
*
* 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>
*
* This program is free software; you can redistribute it and/or modify
@ -56,12 +56,13 @@
#include "extern.h"
#include "scsicmds.h"
#include "atacmds.h" // ataReadHDIdentity()
#include "knowndrives.h" // lookup_usb_device()
#include "utility.h"
#include "dev_interface.h"
#include "dev_ata_cmd_set.h" // ata_device_with_command_set
#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 */
extern smartmonctrl *con;
@ -1321,99 +1322,6 @@ ata_device * smart_interface::autodetect_sat_device(scsi_device * scsidev,
/////////////////////////////////////////////////////////////////////////////
// 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
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,
int version /*= -1*/)
{
const usb_id_entry * entry = 0;
bool state = false;
usb_dev_info info, info2;
int n = lookup_usb_device(vendor_id, product_id, version, info, info2);
for (unsigned i = 0; i < num_usb_ids; i++) {
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) {
if (n <= 0) {
set_err(EINVAL, "Unknown USB bridge %s",
format_usb_id(vendor_id, product_id, version).c_str());
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",
format_usb_id(vendor_id, product_id, version).c_str());
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>
*
* 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
* it under the terms of the GNU General Public License as published by
@ -49,7 +49,7 @@
#include "dev_interface.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;
/* for passing global control variables */

View File

@ -7,7 +7,7 @@
* Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
*
* 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
* it under the terms of the GNU General Public License as published by
@ -32,7 +32,7 @@
#ifndef 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 <stdlib.h>

View File

@ -7,7 +7,7 @@
* Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
*
* 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
* it under the terms of the GNU General Public License as published by
@ -43,7 +43,7 @@
#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;
// control block which points to external global control variables

View File

@ -7,7 +7,7 @@
* Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
*
* 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
* it under the terms of the GNU General Public License as published by
@ -29,7 +29,7 @@
#ifndef 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
// TODO: Move remaining options from con->* to here.

View File

@ -1,7 +1,7 @@
.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
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/
..
.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
\fBsmartctl\fP \- Control and Monitor Utility for SMART Disks
@ -29,7 +29,7 @@
.B /usr/local/sbin/smartctl
.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
\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,
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
.B SHOW INFORMATION OPTIONS:
.TP
@ -195,6 +191,18 @@ and for SCSI, this is equivalent to
.nf
\'\-H \-i \-A \-l error \-l selftest \-l background \-l sasphy\'.
.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
.B RUN\-TIME BEHAVIOR OPTIONS:
@ -218,7 +226,6 @@ use the exit status of \fBsmartctl\fP (see RETURN VALUES below).
.I noserial
\- Do not print the serial number of the device.
.TP
.B \-d TYPE, \-\-device=TYPE
Specifies the type of the device. The valid arguments to this option
@ -406,7 +413,6 @@ of the HighPoint RocketRAID controller.
.B HighPoint RocketRAID controllers are currently ONLY supported under Linux and FreeBSD.
.B cciss controllers are currently ONLY supported under Linux and FreeBSD.
.TP
.B \-T TYPE, \-\-tolerance=TYPE
[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:
ignore failures of \fBany number\fP of \fBmandatory\fP SMART commands.
Please see the note above.
.TP
.B \-b TYPE, \-\-badsum=TYPE
[ATA only] Specifies the action \fBsmartctl\fP should take if a checksum
@ -466,7 +471,6 @@ default.
.I ignore
\- continue silently without issuing a warning.
.TP
.B \-r TYPE, \-\-report=TYPE
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.
Then \fBsmartctl\fP internally simulates an ATA device with the same
behaviour. This is does not work for SCSI devices yet.
.TP
.B \-n POWERMODE, \-\-nocheck=POWERMODE
[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.
.TP
.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
and \fIoff\fP. Note that this feature is preserved across disk power
cycles, so you should only need to issue it once.
For SCSI devices this toggles the value of the Global Logging Target
Save Disabled (GLTSD) bit in the Control Mode Page. Some disk
The ATA standard does not specify a method to check whether SMART
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,
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
@ -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.
Please note that some recent (e.g. Samsung) drives report errors only
in the Comprehensive SMART error log. The Summary SMART error log can
be read but is always empty.
in the Extended Comprehensive SMART error log. The Summary SMART error
log can be read but is always empty.
.I selftest
\- [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
and descriptions of the SCT Error Recovery Control settings. These
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
disable the feature, other values less than 65 are probably not
supported. For RAID configurations, this is typically set to
@ -1025,7 +1032,6 @@ This command:
.fi
writes a binary representation of the one sector log 0x11
(SATA Phy Event Counters) to file log.bin.
.TP
.B \-v ID,FORMAT[:BYTEORDER][,NAME], \-\-vendorattribute=ID,FORMAT[:BYTEORDER][,NAME]
[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
corresponds to temperature, can be found at:
\fBhttp://www.guzu.net/linux/hddtemp.db\fP
.TP
.B \-F TYPE, \-\-firmwarebug=TYPE
[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.
.I samsung2
\- In more recent Samsung disks (firmware revisions ending in "\-23")
the number of ATA errors reported is byte swapped. Enabling this
option tells \fBsmartctl\fP to evaluate this quantity in
\- In some Samsung disks the number of ATA errors reported is byte swapped.
Enabling this option tells \fBsmartctl\fP to evaluate this quantity in
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
very large number of errors in the SMART error log. This is because
@ -1240,7 +1244,6 @@ below).
.I swapid
\- Fixes byte swapped ATA identify strings (device name, serial number,
firmware version) returned by some buggy device drivers.
.TP
.B \-P TYPE, \-\-presets=TYPE
[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\'
.fi
lists all entries for this MODEL and a specific FIRMWARE version.
.TP
.B \-B [+]FILE, \-\-drivedb=[+]FILE
[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.
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
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.
Run the script \fB/usr/local/sbin/update-smart-drivedb\fP to update this
@ -1339,6 +1342,14 @@ Example:
"", // No warning.
"" // 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
@ -1358,13 +1369,12 @@ self\-test will either be aborted or will resume automatically.
The valid arguments to this option are:
.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
normal system operation. The effects of this test are visible only in
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\'
option. [In the case of SCSI devices runs the default self test in
foreground. No entry is placed in the self test log.]
option.
If the \'\-c\' option to \fBsmartctl\fP shows that the device has the
"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
the test.
.I offline
\- [SCSI] runs the default self test in foreground. No entry is placed
in the self test log.
.I short
\- 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.]
\- [ATA] runs SMART Short Self Test (usually under ten minutes).
This command can be given during normal system operation (unless run in
captive mode \- see the \'\-C\' option below). This is a
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
use the \'\-c\' option to monitor progress.
.I short
\- [SCSI] runs the "Background short" self\-test.
.I long
\- runs SMART Extended Self Test (tens of minutes).
[Note: in the case of SCSI devices,
this command option runs the "Background long" self\-test.]
This is a
\- [ATA] runs SMART Extended Self Test (tens of minutes). This is a
longer and more thorough version of the Short Self Test described
above. Note that this command can be given during normal
system operation (unless run in captive mode \- see the \'\-C\' option below).
.I long
\- [SCSI] runs the "Background long" self\-test.
.I conveyance
\- [ATA only] runs a SMART Conveyance Self Test (minutes). This
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
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
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.
This command also clears the temperature history table. See
\'\-l scttemp\' above for more information about SCT temperature logging.
.TP
.B \-C, \-\-captive
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
SCSI devices, this command option runs the self\-test in "Foreground"
mode.]
[ATA] Runs self\-tests in captive mode. This has no effect with \'\-t
offline\' or if the \'\-t\' option is not used.
\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
mounted partitions!\fP
[SCSI] Runs the self\-test in "Foreground" mode.
.TP
.B \-X, \-\-abort
Aborts non\-captive SMART Self Tests. Note that this
@ -1830,30 +1839,26 @@ REFERENCES FOR SMART
.fi
An introductory article about smartmontools is \fIMonitoring Hard
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.
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
volume of the \'AT Attachment with Packet Interface\-7\' (ATA/ATAPI\-7)
specification. This documents the SMART functionality which the
\fBsmartmontools\fP utilities provide access to. You can find
Revision 4b of this document at
\fBhttp://www.t13.org/docs2004/d1532v1r4b-ATA-ATAPI-7.pdf\fP .
Earlier and later versions of this Specification are available from
specification Revision 4b. This documents the SMART functionality which the
\fBsmartmontools\fP utilities provide access to.
This and other versions of this Specification are available from
the T13 web site \fBhttp://www.t13.org/\fP .
.fi
The functioning of SMART was originally defined by the SFF\-8035i
revision 2 and the SFF\-8055i revision 1.4 specifications. These are
publications of the Small Form Factors (SFF) Committee. Links to
these documents may be found in the References section of the
\fBsmartmontools\fP home page at
\fBhttp://smartmontools.sourceforge.net/\fP .
publications of the Small Form Factors (SFF) Committee.
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
SVN ID OF THIS PAGE:
$Id: smartctl.8.in 3072 2010-03-04 21:56:41Z chrfranke $
.\" Local Variables:
.\" mode: nroff
.\" End:
$Id: smartctl.8.in 3119 2010-06-11 16:21:25Z chrfranke $

View File

@ -56,7 +56,7 @@
#include "smartctl.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;
// 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"
" -x, --xall\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(
"================================== SMARTCTL RUN-TIME BEHAVIOR OPTIONS =====\n\n"
@ -138,12 +142,18 @@ void Usage (void){
" Drive-specific presets: use, ignore, show, showall\n\n"
" -B [+]FILE, --drivedb=[+]FILE (ATA)\n"
" Read and replace [add] drive database from FILE\n"
#ifdef SMARTMONTOOLS_DRIVEDBDIR
" [default is "SMARTMONTOOLS_DRIVEDBDIR"/drivedb.h]\n"
#endif
"\n"
" [default is +%s",
get_drivedb_path_add()
);
#ifdef SMARTMONTOOLS_DRIVEDBDIR
printf(
"\n"
" and then %s",
get_drivedb_path_default()
);
#endif
printf(
"]\n\n"
"============================================ DEVICE SELF-TEST OPTIONS =====\n\n"
" -t TEST, --test=TEST\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 void scan_devices(const char * type, bool with_open, const char * pattern);
/* Takes command options and sets features to be run */
const char * parse_options(int argc, char** argv,
ata_print_options & ataopts,
@ -229,6 +241,7 @@ const char * parse_options(int argc, char** argv,
// 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:";
// Please update getvalidarglist() if you edit longopts
enum { opt_scan = 1000, opt_scan_open = 1001 };
struct option longopts[] = {
{ "help", 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' },
{ "nocheck", required_argument, 0, 'n' },
{ "drivedb", required_argument, 0, 'B' },
{ "scan", no_argument, 0, opt_scan },
{ "scan-open", no_argument, 0, opt_scan_open },
{ 0, 0, 0, 0 }
};
@ -268,16 +283,14 @@ const char * parse_options(int argc, char** argv,
const char * type = 0; // set to -d optarg
bool no_defaultdb = false; // set true on '-B FILE'
int scan = 0; // set by --scan, --scan-open
bool badarg = false, captive = false;
int testcnt = 0; // number of self-tests requested
int optchar;
char *arg;
// This miserable construction is needed to get emacs to do proper indenting. Sorry!
while (-1 != (optchar =
getopt_long(argc, argv, shortopts, longopts, NULL)
)){
while ((optchar = getopt_long(argc, argv, shortopts, longopts, 0)) != -1) {
switch (optchar){
case 'V':
con->dont_print = false;
@ -616,7 +629,8 @@ const char * parse_options(int argc, char** argv,
ataopts.smart_selective_args.pending_time = i+1;
}
} else if (!strncmp(optarg,"select",strlen("select"))) {
testcnt++;
if (ataopts.smart_selective_args.num_spans == 0)
testcnt++;
// parse range of LBAs to test
uint64_t start, stop; int mode;
if (split_selective_arg(optarg, &start, &stop, &mode)) {
@ -690,6 +704,12 @@ const char * parse_options(int argc, char** argv,
Usage();
EXIT(0);
break;
case opt_scan:
case opt_scan_open:
scan = optchar;
break;
case '?':
default:
con->dont_print = false;
@ -741,6 +761,13 @@ const char * parse_options(int argc, char** argv,
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
// print output is switchable, then start with the print output
// 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
int main_worker(int argc, char **argv)
{
// Throw if CPU endianess does not match compile time test.
check_endianness();
// Initialize interface
smart_interface::init();
if (!smi())

View File

@ -1,7 +1,7 @@
.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
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,
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
\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
.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
\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
every 30 minutes (configurable), logging SMART errors and changes of
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
command-line option described below.
@ -61,7 +62,7 @@ every 30 minutes. See the \fB\'\-i\'\fP option below for additional
details.
\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
can be told to re-read the configuration file by sending it a
\fBHUP\fP signal, for example with the command:
@ -126,8 +127,6 @@ below).
.SH
OPTIONS
Long options are not supported on all systems. Use \fB\'smartd
\-h\'\fP to see the available options.
.TP
.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\-\'),
then files 'nameMODEL\-SERIAL.ata.csv' are created in directory '/path/'.
The path must be absolute, except if debug mode is enabled.
.TP
.B \-B [+]FILE, \-\-drivedb=[+]FILE
[NEW EXPERIMENTAL SMARTD FEATURE] Read the drive database from FILE.
The new database replaces the built in database by default. If \'+\' is
specified, then the new entries prepend the built in entries.
Please see the \fBsmartctl\fP(8) man page for further details.
.TP
.B \-c FILE, \-\-configfile=FILE
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
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.
@ -174,14 +171,12 @@ input. This is useful for commands like:
.B echo /dev/hdb \-m user@home \-M test | smartd \-c \- \-q onecheck
.fi
to perform quick and simple checks without a configuration file.
.\" BEGIN ENABLE_CAPABILITIES
.TP
.B \-C, \-\-capabilities
Use \fBcapabilities(7)\fP (EXPERIMENTAL).
Warning: Mail notification does not work when used.
.\" END ENABLE_CAPABILITIES
.TP
.B \-d, \-\-debug
@ -207,7 +202,6 @@ appear in the configuration file following the device name.
.TP
.B \-h, \-\-help, \-\-usage
Prints usage message to STDOUT and exits.
.TP
.B \-i N, \-\-interval=N
Sets the interval between disk checks to \fIN\fP seconds, where
@ -229,7 +223,6 @@ also use:
for the same purpose.
.fi
(Windows: See NOTES below.)
.TP
.B \-l FACILITY, \-\-logfacility=FACILITY
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.
If you would like to have \fBsmartd\fP messages logged somewhere other
than the default \fB/var/log/messages\fP location, this can typically
be accomplished with (for example) the following steps:
than the default location, this can typically be accomplished with
(for example) the following steps:
.RS 7
.IP \fB[1]\fP 4
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\'
to register, \'\fBsyslogevt -u smartd\fP\' to unregister and
\'\fBsyslogevt\fP\' for more help.
.TP
.B \-n, \-\-no\-fork
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.
On Windows, this option is not available, use \'\-\-service\' instead.
.TP
.B \-p NAME, \-\-pidfile=NAME
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
The default level is 1, so \'\-r ataioctl,1\' and \'\-r ataioctl\' are
equivalent.
.TP
.B \-s PREFIX, \-\-savestates=PREFIX
[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
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.
.TP
.B \-\-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
argument. It should not be used from console.
See NOTES below for details.
.TP
.B \-V, \-\-version, \-\-license, \-\-copyright
Prints version, copyright, license, home page and SVN revision
@ -448,8 +436,7 @@ smartd
.fi
Runs the daemon in forked mode. This is the normal way to run
\fBsmartd\fP.
Entries are logged to SYSLOG (by default
.B /var/log/messages.)
Entries are logged to SYSLOG.
.B
smartd -d -i 30
@ -477,16 +464,6 @@ you can start \fBsmartd\fP by giving the command:
and stop it by using the command:
.nf
.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
.\" 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
.B smartmontools
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
follows:
.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
smartmontools must be used; Please see the \fBsmartctl\fP(8) man page
for further details.
.TP
.B \-d TYPE
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
\fBsmartd\fP is started. This Directive may be used in conjunction
with the other \'\-d\' Directives.
.TP
.B \-n POWERMODE[,N][,q]
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.
Both \',N\' and \',q\' can be specified together.
.TP
.B \-T TYPE
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
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
.B \'LOG_CRITICAL\'
.B \'LOG_CRIT\'
will be logged to syslog. [Please see the
.B smartctl \-H
command-line option.]
.TP
.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:
.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.
.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
\- report if the number of failed tests reported in the SMART
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
in \fBREGEXP\fP that appear to indicate that you have made this
mistake.
.TP
.B \-m ADD
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
is used. If running as a service, a service notification message box
(always shown on current visible desktop) is used.
.TP
.B \-M TYPE
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
executable hangs, then \fBsmartd\fP will also hang. Some sample
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
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.
.nf
.fi
\fITemperature\fP: Temperature reached critical limit (see \-W directive).
.nf
.fi
\fIFailedHealthCheck\fP: the SMART health status command failed.
.nf
.fi
@ -1395,8 +1380,7 @@ discarded.
Some EXAMPLES of scripts that can be used with the \'\-M exec\'
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
.B \-f
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
value is considered critical. The report will be logged as LOG_CRIT
and a warning email will be sent if \'-m\' is specified.
.TP
.B \-R ID[!]
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
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.
.TP
.B \-C ID[+]
[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
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
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
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
device substitute a spare good sector for the bad one) but at the
price of losing the 512 bytes of data stored there.
.TP
.B \-U ID[+]
[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
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
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
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
need to read it, the read will fail. Please see the previous \'\-C\'
option for more details.
.TP
.B \-W DIFF[,INFO[,CRIT]]
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
\fBINFO\fP or \fBCRIT\fP degrees Celsius.
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
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
by default. This can be changed to Attribute 9 or 220 by the drive
database or by the \'-v\' directive, see below.
.TP
.B \-F TYPE
[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:
.I none
\- Assume that the device firmware obeys the ATA specifications. This is
the default, unless the device has presets for \'\-F\' in the device
database.
\- Assume that the device firmware obeys the ATA specifications. This
is the default, unless the device has presets for \'\-F\' in the
device database.
.I samsung
\- In some Samsung disks (example: model SV4012H Firmware Version:
RM100-08) some of the two- and four-byte quantities in the SMART data
structures are byte-swapped (relative to the ATA specification).
RM100\-08) some of the two\- and four\-byte quantities in the SMART data
structures are byte\-swapped (relative to the ATA specification).
Enabling this option tells \fBsmartd\fP to evaluate these quantities
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;
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;
(2) very large numbers of ATA errors reported in the ATA error log;
(3) strange and impossible values for the ATA error log timestamps.
.I samsung2
\- In more recent Samsung disks (firmware revisions ending in "\-23") the
number of ATA errors reported is byte swapped. Enabling this option
tells \fBsmartd\fP to evaluate this quantity in byte-reversed order.
\- In some Samsung disks the number of ATA errors reported is byte swapped.
Enabling this option tells \fBsmartd\fP to evaluate this quantity in
byte\-reversed order.
.I samsung3
\- 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
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).
[Please see the \fBsmartctl \-F\fP command-line option.]
.TP
.B \-v ID,FORMAT[:BYTEORDER][,NAME]
[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
reset if uncorrectable sector are reallocated. This sets \'-U 198+\'
if no other \'-U\' directive is specified.
.TP
.B \-P TYPE
Specifies whether
@ -1653,7 +1634,6 @@ valid arguments to this Directive are:
[Please see the
.B smartctl \-P
command-line option.]
.TP
.B \-a
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
Directives is given, then \-a is assumed.
.TP
.B #
Comment: ignore the remainder of the line.
@ -1780,7 +1759,7 @@ sleep 30
.fi
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
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
.SH AUTHOR
\fBBruce Allen\fP smartmontools-support@lists.sourceforge.net
\fBBruce Allen\fP smartmontools\-support@lists.sourceforge.net
.fi
University of Wisconsin \- Milwaukee Physics Department
@ -2036,8 +2015,8 @@ Many other individuals have made smaller contributions and corrections.
.SH CREDITS
.fi
This code was derived from the smartsuite package, written by Michael
Cornwell, and from the previous ucsc smartsuite package. It extends
these to cover ATA-5 disks. This code was originally developed as a
Cornwell, and from the previous UCSC smartsuite package. It extends
these to cover ATA\-5 disks. This code was originally developed as a
Senior Thesis by Michael Cornwell at the Concurrent Systems Laboratory
(now part of the Storage Systems Research Center), Jack Baskin School
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
reports and patches: \fBhttp://smartmontools.sourceforge.net/\fP
.SH SEE ALSO:
.SH
SEE ALSO:
\fBsmartd.conf\fP(5), \fBsmartctl\fP(8), \fBsyslogd\fP(8),
\fBsyslog.conf\fP(5), \fBbadblocks\fP(8), \fBide\-smart\fP(8), \fBregex\fP(7).
@ -2057,26 +2037,26 @@ REFERENCES FOR SMART
.fi
An introductory article about smartmontools is \fIMonitoring Hard
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.
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
volume of the \'AT Attachment with Packet Interface-7\' (ATA/ATAPI-7)
specification. This documents the SMART functionality which the
\fBsmartmontools\fP utilities provide access to. You can find
Revision 4b of this document at
\fBhttp://www.t13.org/docs2004/d1532v1r4b-ATA-ATAPI-7.pdf\fP .
Earlier and later versions of this Specification are available from
volume of the \'AT Attachment with Packet Interface\-7\' (ATA/ATAPI\-7)
specification Revision 4b. This documents the SMART functionality which the
\fBsmartmontools\fP utilities provide access to.
This and other versions of this Specification are available from
the T13 web site \fBhttp://www.t13.org/\fP .
.fi
The functioning of SMART was originally defined by the SFF-8035i
revision 2 and the SFF-8055i revision 1.4 specifications. These are
publications of the Small Form Factors (SFF) Committee. Links to
these documents may be found in the References section of the
smartmontools home page at \fBhttp://smartmontools.sourceforge.net/#references\fP .
The functioning of SMART was originally defined by the SFF\-8035i
revision 2 and the SFF\-8055i revision 1.4 specifications. These are
publications of the Small Form Factors (SFF) Committee.
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
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
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
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
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
\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
.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
\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
.B smartmontools
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
follows:
.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
smartmontools must be used; Please see the \fBsmartctl\fP(8) man page
for further details.
.TP
.B \-d TYPE
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
\fBsmartd\fP is started. This Directive may be used in conjunction
with the other \'\-d\' Directives.
.TP
.B \-n POWERMODE[,N][,q]
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.
Both \',N\' and \',q\' can be specified together.
.TP
.B \-T TYPE
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
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
.B \'LOG_CRITICAL\'
.B \'LOG_CRIT\'
will be logged to syslog. [Please see the
.B smartctl \-H
command-line option.]
.TP
.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:
.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.
.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
\- report if the number of failed tests reported in the SMART
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
in \fBREGEXP\fP that appear to indicate that you have made this
mistake.
.TP
.B \-m ADD
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
is used. If running as a service, a service notification message box
(always shown on current visible desktop) is used.
.TP
.B \-M TYPE
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
executable hangs, then \fBsmartd\fP will also hang. Some sample
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
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.
.nf
.fi
\fITemperature\fP: Temperature reached critical limit (see \-W directive).
.nf
.fi
\fIFailedHealthCheck\fP: the SMART health status command failed.
.nf
.fi
@ -948,8 +956,7 @@ discarded.
Some EXAMPLES of scripts that can be used with the \'\-M exec\'
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
.B \-f
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
value is considered critical. The report will be logged as LOG_CRIT
and a warning email will be sent if \'-m\' is specified.
.TP
.B \-R ID[!]
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
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.
.TP
.B \-C ID[+]
[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
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
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
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
device substitute a spare good sector for the bad one) but at the
price of losing the 512 bytes of data stored there.
.TP
.B \-U ID[+]
[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
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
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
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
need to read it, the read will fail. Please see the previous \'\-C\'
option for more details.
.TP
.B \-W DIFF[,INFO[,CRIT]]
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
\fBINFO\fP or \fBCRIT\fP degrees Celsius.
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
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
by default. This can be changed to Attribute 9 or 220 by the drive
database or by the \'-v\' directive, see below.
.TP
.B \-F TYPE
[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:
.I none
\- Assume that the device firmware obeys the ATA specifications. This is
the default, unless the device has presets for \'\-F\' in the device
database.
\- Assume that the device firmware obeys the ATA specifications. This
is the default, unless the device has presets for \'\-F\' in the
device database.
.I samsung
\- In some Samsung disks (example: model SV4012H Firmware Version:
RM100-08) some of the two- and four-byte quantities in the SMART data
structures are byte-swapped (relative to the ATA specification).
RM100\-08) some of the two\- and four\-byte quantities in the SMART data
structures are byte\-swapped (relative to the ATA specification).
Enabling this option tells \fBsmartd\fP to evaluate these quantities
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;
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;
(2) very large numbers of ATA errors reported in the ATA error log;
(3) strange and impossible values for the ATA error log timestamps.
.I samsung2
\- In more recent Samsung disks (firmware revisions ending in "\-23") the
number of ATA errors reported is byte swapped. Enabling this option
tells \fBsmartd\fP to evaluate this quantity in byte-reversed order.
\- In some Samsung disks the number of ATA errors reported is byte swapped.
Enabling this option tells \fBsmartd\fP to evaluate this quantity in
byte\-reversed order.
.I samsung3
\- 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
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).
[Please see the \fBsmartctl \-F\fP command-line option.]
.TP
.B \-v ID,FORMAT[:BYTEORDER][,NAME]
[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
reset if uncorrectable sector are reallocated. This sets \'-U 198+\'
if no other \'-U\' directive is specified.
.TP
.B \-P TYPE
Specifies whether
@ -1206,7 +1210,6 @@ valid arguments to this Directive are:
[Please see the
.B smartctl \-P
command-line option.]
.TP
.B \-a
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
Directives is given, then \-a is assumed.
.TP
.B #
Comment: ignore the remainder of the line.
@ -1333,7 +1335,7 @@ sleep 30
.fi
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
that they read/write should not be writable by ordinary users or
@ -1351,7 +1353,7 @@ The remainder is flushed.
.PP
.SH AUTHOR
\fBBruce Allen\fP smartmontools-support@lists.sourceforge.net
\fBBruce Allen\fP smartmontools\-support@lists.sourceforge.net
.fi
University of Wisconsin \- Milwaukee Physics Department
@ -1380,8 +1382,8 @@ Many other individuals have made smaller contributions and corrections.
.SH CREDITS
.fi
This code was derived from the smartsuite package, written by Michael
Cornwell, and from the previous ucsc smartsuite package. It extends
these to cover ATA-5 disks. This code was originally developed as a
Cornwell, and from the previous UCSC smartsuite package. It extends
these to cover ATA\-5 disks. This code was originally developed as a
Senior Thesis by Michael Cornwell at the Concurrent Systems Laboratory
(now part of the Storage Systems Research Center), Jack Baskin School
of Engineering, University of California, Santa
@ -1390,10 +1392,7 @@ Cruz. \fBhttp://ssrc.soe.ucsc.edu/\fP .
HOME PAGE FOR SMARTMONTOOLS:
.fi
Please see the following web site for updates, further documentation, bug
reports and patches:
.nf
.B
http://smartmontools.sourceforge.net/
reports and patches: \fBhttp://smartmontools.sourceforge.net/\fP
.SH
SEE ALSO:
@ -1402,4 +1401,4 @@ SEE ALSO:
.SH
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))
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;
extern const char *reportbug;
@ -171,13 +171,7 @@ static std::string attrlog_path_prefix
;
// configuration file name
#define CONFIGFILENAME "smartd.conf"
#ifndef _WIN32
static const char *configfile = SMARTMONTOOLS_SYSCONFDIR "/" CONFIGFILENAME ;
#else
static const char *configfile = "./" CONFIGFILENAME ;
#endif
static const char * configfile;
// configuration file "name" if read from stdin
static const char * const configfile_stdin = "<stdin>";
// path of alternate configuration file
@ -264,6 +258,7 @@ struct dev_config
bool usage; // Track changes in Usage Attributes
bool selftest; // Monitor number of selftest 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
char autosave; // 1=disable, 2=enable Autosave Attributes
char autoofflinetest; // 1=disable, 2=enable Auto Offline Test
@ -305,6 +300,7 @@ dev_config::dev_config()
usage(false),
selftest(false),
errorlog(false),
xerrorlog(false),
permissive(false),
autosave(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
#endif
persistent_dev_state new_state;
int good = 0, bad = 0;
char line[256];
while (fgets(line, sizeof(line), f)) {
const char * s = line + strspn(line, " \t");
if (!*s || *s == '#')
continue;
if (!parse_dev_state_line(line, state))
if (!parse_dev_state_line(line, new_state))
bad++;
else
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);
}
// This sets the values missing in the file to 0.
state = new_state;
return true;
}
@ -1412,7 +1412,7 @@ void Directives() {
" -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"
" -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"
" -m ADD Send email warning to address ADD\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," -B [+]FILE, --drivedb=[+]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
PrintOut(LOG_INFO," [default is "SMARTMONTOOLS_DRIVEDBDIR"/drivedb.h]\n");
#endif
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," 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
PrintOut(LOG_INFO," -C, --capabilities\n");
PrintOut(LOG_INFO," Use capabilities (EXPERIMENTAL).\n"
@ -1545,19 +1548,28 @@ static bool not_allowed_in_filename(char c)
|| ('a' <= c && c <= 'z'));
}
// returns <0 on failure
static int ATAErrorCount(ata_device * device, const char * name,
unsigned char fix_firmwarebug)
// Read error count from Summary or Extended Comprehensive SMART error log
// Return -1 on error
static int read_ata_error_count(ata_device * device, const char * name,
unsigned char fix_firmwarebug, bool extended)
{
struct ata_smart_errorlog log;
if (ataReadErrorLog(device, &log, fix_firmwarebug)){
PrintOut(LOG_INFO,"Device: %s, Read SMART Error Log Failed\n",name);
return -1;
if (!extended) {
ata_smart_errorlog log;
if (ataReadErrorLog(device, &log, fix_firmwarebug)){
PrintOut(LOG_INFO,"Device: %s, Read Summary SMART Error Log failed\n",name);
return -1;
}
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);
}
// return current number of ATA errors
return log.error_log_pointer?log.ata_error_count:0;
}
// 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?
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.tempdiff || cfg.tempinfo || cfg.tempcrit
|| 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
if (cfg.errorlog) {
int val;
if (cfg.errorlog || cfg.xerrorlog) {
// start with service disabled, and re-enable it if all works OK
cfg.errorlog = false;
state.ataerrorcount=0;
if (!smart_val_ok)
PrintOut(LOG_INFO, "Device: %s, no SMART Error log (SMART READ DATA failed); disabling -l error\n", name);
else if (!cfg.permissive && !isSmartErrorLogCapable(&state.smartval, &drive))
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);
if (!(cfg.permissive || (smart_val_ok && isSmartErrorLogCapable(&state.smartval, &drive)))) {
PrintOut(LOG_INFO, "Device: %s, no SMART Error Log (%s), ignoring -l [x]error (override with -T permissive)\n",
name, (!smart_val_ok ? "SMART READ DATA failed" : "capability missing"));
cfg.errorlog = cfg.xerrorlog = false;
}
else {
cfg.errorlog = true;
state.ataerrorcount=val;
int errcnt1 = -1, errcnt2 = -1;
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 (!(cfg.errorlog || cfg.selftest || cfg.smartcheck ||
cfg.usagefailed || cfg.prefail || cfg.usage ||
cfg.tempdiff || cfg.tempinfo || cfg.tempcrit )) {
if (!( cfg.smartcheck || cfg.selftest
|| cfg.errorlog || cfg.xerrorlog
|| cfg.usagefailed || cfg.prefail || cfg.usage
|| cfg.tempdiff || cfg.tempinfo || cfg.tempcrit)) {
CloseDevice(atadev, name);
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",
name, oldc, newc);
state.must_write = true;
} else if (oldh!=newh) {
}
else if (newc > 0 && oldh != newh) {
// more recent error
// a 'more recent' error might actually be a smaller hour number,
// if the hour number has wrapped.
@ -2072,7 +2097,12 @@ static void CheckSelfTestLogs(const dev_config & cfg, dev_state & state, int new
name, newh);
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
// also have changed.
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));
// 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
newc = ATAErrorCount(atadev, name, cfg.fix_firmwarebug);
// new number of errors is max of both logs
int newc = (errcnt1 >= errcnt2 ? errcnt1 : errcnt2);
// did command fail?
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);
// has error count increased?
int oldc = state.ataerrorcount;
if (newc>oldc){
PrintOut(LOG_CRIT, "Device: %s, ATA error count increased from %d to %d\n",
name, oldc, newc);
@ -2784,8 +2819,7 @@ static int ATACheckDevice(const dev_config & cfg, dev_state & state, ata_device
name, oldc, newc);
state.must_write = true;
}
// this last line is probably not needed, count always increases
if (newc>=0)
state.ataerrorcount=newc;
}
@ -3213,6 +3247,9 @@ static int ParseToken(char * token, dev_config & cfg)
} else if (!strcmp(arg, "error")) {
// track changes in ATA error log
cfg.errorlog = true;
} else if (!strcmp(arg, "xerror")) {
// track changes in Extended Comprehensive SMART error log
cfg.xerrorlog = true;
} else {
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 (!(cfg.smartcheck || cfg.usagefailed || cfg.prefail ||
cfg.usage || cfg.selftest || cfg.errorlog ||
cfg.tempdiff || cfg.tempinfo || cfg.tempcrit )) {
if (!( cfg.smartcheck || cfg.selftest
|| cfg.errorlog || cfg.xerrorlog
|| 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",
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
// version/license/copyright messages
void ParseOpts(int argc, char **argv){
int optchar;
char *tailptr;
long lchecktime;
void ParseOpts(int argc, char **argv)
{
// Init default configfile path
#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
static const char shortopts[] = "c:l:q:dDni:p:r:s:A:B:Vh?"
#ifdef HAVE_LIBCAP_NG
"C"
#endif
;
char *arg;
// Please update GetValidArgList() if you edit longopts
struct option longopts[] = {
{ "configfile", required_argument, 0, 'c' },
@ -3765,12 +3808,13 @@ void ParseOpts(int argc, char **argv){
bool badarg = false;
bool no_defaultdb = false; // set true on '-B FILE'
// Parse input options. This horrible construction is so that emacs
// indents properly. Sorry.
while (-1 != (optchar =
getopt_long(argc, argv, shortopts, longopts, NULL)
)) {
// Parse input options.
int optchar;
while ((optchar = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) {
char *arg;
char *tailptr;
long lchecktime;
switch(optchar) {
case 'q':
// when to quit

View File

@ -50,7 +50,7 @@
#include "atacmds.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;
const char * packet_types[] = {
@ -259,15 +259,23 @@ const char *packetdevicetype(int type){
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
// rather than a compile-time function. We could do it at
// compile-time but in principle there are architectures that can run
// with either byte-ordering.
int isbigendian(){
short i=0x0100;
char *tmp=(char *)&i;
return *tmp;
int big = -1;
switch (x.i) {
case 0x01020304: big = 1; break;
case 0x04030201: big = 0; break;
}
if (big != (isbigendian() ? 1 : 0))
throw std::logic_error("CPU endianness does not match compile time test");
}
// 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
*
* Copyright (C) 2002-9 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2008-9 Christian Franke <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2002-10 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2008-10 Christian Franke <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
*
* This program is free software; you can redistribute it and/or modify
@ -26,7 +26,7 @@
#ifndef 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 <sys/types.h> // for regex.h (according to POSIX)
@ -144,8 +144,19 @@ inline T * CheckFree(T * address, int whatline, const char* file)
// appropriate.]
void PrintOut(int priority, const char *fmt, ...) __attribute__ ((format(printf, 2, 3)));
// run time, determine byte ordering
int isbigendian();
// Compile time check of byte ordering
// (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
// 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_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
// possible values for controller_type in extern.h
#define CONTROLLER_UNKNOWN 0x00