mirror of
https://git.proxmox.com/git/mirror_smartmontools-debian
synced 2025-08-05 18:05:23 +00:00
Imported Upstream version 5.39.1+svn3124
This commit is contained in:
parent
7f0798ef6f
commit
e9583e0c22
4
AUTHORS
4
AUTHORS
@ -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
123
CHANGELOG
@ -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)
|
||||
|
87
Makefile.am
87
Makefile.am
@ -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
8
NEWS
@ -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
|
||||
|
12
atacmds.cpp
12
atacmds.cpp
@ -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"},
|
||||
|
269
ataprint.cpp
269
ataprint.cpp
@ -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;
|
||||
|
@ -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>
|
||||
|
88
configure.in
88
configure.in
@ -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
|
||||
|
@ -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
517
drivedb.h
@ -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[]
|
||||
*/
|
||||
|
273
knowndrives.cpp
273
knowndrives.cpp
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
15
megaraid.h
15
megaraid.h
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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++;
|
||||
}
|
||||
|
58
os_win32.cpp
58
os_win32.cpp
@ -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
|
||||
|
@ -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"
|
||||
>
|
||||
|
@ -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"
|
||||
>
|
||||
|
144
scsiata.cpp
144
scsiata.cpp
@ -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();
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
127
smartctl.8.in
127
smartctl.8.in
@ -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 $
|
||||
|
88
smartctl.cpp
88
smartctl.cpp
@ -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())
|
||||
|
154
smartd.8.in
154
smartd.8.in
@ -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 $
|
||||
|
@ -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 $
|
||||
|
170
smartd.cpp
170
smartd.cpp
@ -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
|
||||
|
26
utility.cpp
26
utility.cpp
@ -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
|
||||
|
28
utility.h
28
utility.h
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user