Imported Upstream version 6.3+svn3990

This commit is contained in:
Giuseppe Iuculano 2014-10-05 09:03:54 +02:00
parent 3d17a85c7b
commit d2e702cfb9
46 changed files with 3056 additions and 1341 deletions

517
ChangeLog
View File

@ -1,4 +1,519 @@
$Id: ChangeLog 3841 2013-07-26 17:38:57Z chrfranke $ $Id: ChangeLog 3990 2014-09-29 17:59:37Z samm2 $
2014-09-29 Alex Samorukov <samm@os2.kiev.ua>
drivedb.h: Added Seagate Backup Plus Slim Portable USB 3.0 drive
2014-08-29 Christian Franke <franke@computer.org>
drivedb.h: Fix regex syntax error (regression from r3988).
2014-08-22 Alex Samorukov <samm@os2.kiev.ua>
drivedb.h:
- fixed SanDisk X210 regular expression
2014-08-21 Alex Samorukov <samm@os2.kiev.ua>
drivedb.h:
- added SanDisk X300s SSD
- extended Apacer SSD support based on APSDM004G13AN-AT user report
2014-08-16 Alex Samorukov <samm@os2.kiev.ua>
ataprint.cpp: '-l devstat' - workaround for buggy firmware by provided
Christian Franke
2014-08-15 Alex Samorukov <samm@os2.kiev.ua>
ataprint.cpp: device statistic - use smart log if GP log is not available
2014-08-15 Alex Samorukov <samm@os2.kiev.ua>
os_darwin.cpp:
- Migrated to the new interface
- Added multisector support
- Fixed smart autosave processing
2014-07-26 Christian Franke <franke@computer.org>
smartmontools 6.3
2014-07-25 Christian Franke <franke@computer.org>
drivedb.h:
- Apple SD/SM/TS...E/F SSDs: Rename, add TS*[EF]
- JMicron based SSDs: Fix regex for Apple TS*C
- Marvell based SanDisk SSDs: X210
2014-07-25 Alex Samorukov <samm@os2.kiev.ua>
drivedb.h: Apple SM* SSD - add attribute 173 description (guessed)
2014-07-23 Christian Franke <franke@computer.org>
ataprint.cpp: Print SCT Status regardless of SCT Data Table support.
atacmds.cpp: ataReadSCTTempHist(): Do not reread initial SCT Status.
configure.ac: Fix typo in help text. Add MinGW comment.
2014-07-22 Christian Franke <franke@computer.org>
drivedb.h:
- Apple SD/SM...E/F SSDs (ticket #342)
- Apple SSD SM128, Asus-Phison SSD: Remove (missing attribute info)
2014-07-20 Christian Franke <franke@computer.org>
atacmds.cpp: Rework heuristics for 'tempminmax' format.
Now supports negative values (ticket #291) and WDC over temperature
counter.
Change default for Head_Flying_Hours to 'raw24(raw8)'. This provides
more reasonable output for Seagate HDDs missing in drivedb.h.
drivedb.h: Comment new default for Head_Flying_Hours.
smartctl.8.in, smartd.8.in, smartd.conf.5.in:
Fix usage of line breaks and empty lines.
2014-07-19 Christian Franke <franke@computer.org>
smartctl.8.in, smartd.8.in, smartd.conf.5.in, update-smart-drivedb.8.in:
Add FILES section. Move FULL PATH info to FILES section.
Rename REFERENCES section. Move HOME PAGE info to REFERENCES section.
Remove AUTHORS section from smartd.conf man page.
Update or remove various outdated info.
2014-07-18 Christian Franke <franke@computer.org>
configure.ac: Use 'email' instead of 'mail' on Cygwin.
Remove outdated '-mno-cygwin' error check.
Makefile.am, smartd.conf.5.in: Replace 'mail' by actual platform
specific mailer.
examplescripts/README, examplescripts/Example[123]: Remove bashisms.
Use '/usr/bin/mail' instead of '/bin/mail'.
os_win32/daemon_win32.cpp: Support older MinGW headers with missing
struct SERVICE_DELAYED_AUTO_START_INFO.
2014-07-17 Christian Franke <franke@computer.org>
drivedb.h:
- Crucial/Micron MX100/M500/M510/M550 Client SSDs: Rename, add MX100,
update MX510/550
- Indilinx Barefoot based SSDs: OCZ Vertex 1.10
- Intel 320 Series SSDs: 'L' variant
- JMicron based SSDs: Transcend *18M-M variant
- Plextor M3/M5 (Pro) Series SSDs: M5M (mSATA) variant
- Samsung based SSDs: 840 EVO
2014-07-16 Christian Franke <franke@computer.org>
drivedb.h:
- Marvell based SanDisk SSDs: Extreme II (ticket #334), others
- SanDisk based SSDs: iSSD P4 (ticket #272), U100 (ticket #337), others
- USB: Iomega (0x059b:0x047a)
- USB: WD My Passport: Merge entries
- USB: WD My Passport USB 3.0 (0x1058:0x074a, 0x1058:0x0820)
- USB: ADATA (0x125f:0xa[13]1a)
- USB: JMicron JMS539 (0x152d:0x0539): New FW supports SAT (ticket #338)
- USB: TrekStor Datastation (0x1e68:0x0050) (Red Hat Bugzilla 954162)
2014-07-13 Christian Franke <franke@computer.org>
atacmds.cpp: Add missing const and initialization.
Don't print extra '\n' if self-test log is empty.
ataprint.cpp: Add new ACS-4 log.
cciss.cpp: Fix C++11 builds on Linux. GCC and CLang do not
predefine 'linux' when in '-std=c++11' mode.
smartd.cpp: Update description of Windows smartd service.
README: Update license info. Remove outdated ATA references.
2014-07-10 Christian Franke <franke@computer.org>
Makefile.am: Rework build of Solaris specific man pages.
This fixes some bogus and some missing replacements.
smartctl.8.in, smartd.8.in, smartd.conf.5.in: Minor typo and syntax
fixes.
2014-07-09 Christian Franke <franke@computer.org>
smartctl.8.in, smartd.8.in, smartd.conf.5.in: Avoid '.SH' macros with no
argument. Remove colons from section names.
Merge sections CONTRIBUTORS and CREDITS with AUTHORS.
Update SEE ALSO sections.
2014-07-05 Christian Franke <franke@computer.org>
configure.ac: Remove snprintf() compile time test.
Add '--with-working-snprintf' configure option.
Add __USE_MINGW_ANSI_STDIO test for MinGW GCC.
utility.cpp: Add snprintf() runtime test.
Add GCC version to output of -V option.
Makefile.am: Add update-smart-drivedb.1m for Solaris.
2014-06-30 Christian Franke <franke@computer.org>
configure.ac: Update macros as suggested by 'autoconf --warnings=obsolete'.
Makefile.am: Add creation of empty directories to install targets.
2014-06-29 Christian Franke <franke@computer.org>
configure.ac, Makefile.am, smartd.cpp, smartd_warning.sh.in:
Add '--with-smartdscriptdir' configure option to change location of
smartd_warning.sh (Debian bug 710815).
Add '--with-smartdplugindir' configure option to change (or disable)
smartd_warning.sh plugin location.
smartd.conf.5.in: Optionally hide the plugin documentation.
2014-06-27 Christian Franke <franke@computer.org>
Makefile.am: Add update-smart-drivedb.8 target.
update-smart-drivedb.8.in: Add copyright and version info.
Adjust path names for make target.
Add FreeBSD/OpenBSD specific info.
2014-06-27 Hannes von Haugwitz <hannes@vonhaugwitz.com>
update-smart-drivedb.8.in: New man page (Debian bug 708433).
2014-06-27 Christian Franke <franke@computer.org>
configure.ac: Suppress pkg-config warnings about missing 'systemd.pc'.
Makefile.am: Silence build of man pages and svnversion.h.
This makes '--enable-silent-rules' or 'make V=0' more effective
(available since automake 1.13).
2014-06-27 Christian Franke <franke@computer.org>
drivedb.h:
- Crucial/Micron RealSSD C300/M500: New attributes (ticket #326)
- SandForce Driven SSDs: ADATA XM11, Corsair Force LS, OWC Aura Pro 6G
OWC Mercury Electra Pro 3G, PNY Prevail Elite, Transcend SSD320/720
2014-06-25 Christian Franke <franke@computer.org>
os_win32.cpp: Fix calculation of SCSI resid.
2014-06-23 Christian Franke <franke@computer.org>
scsiata.cpp: usbjmicron_device: Fix SMART Status check for USB bridges
which always return 0x01. Add JMicron specific error messages.
2014-06-22 Christian Franke <franke@computer.org>
atacmds.cpp, ataprint.cpp: Improve messages for unsupported SMART Status
command.
ataprint.cpp: Print form factor.
2014-06-21 Christian Franke <franke@computer.org>
drivedb.h:
- Crucial/Micron M500/M510/M550 Client SSDs
- Micron M500DC Enterprise SSDs
Based on patch provided by Clayton Hawkings from Micron.
2014-06-20 Christian Franke <franke@computer.org>
autogen.sh: automake 1.14.1 works.
2014-06-20 Christian Franke <franke@computer.org>
scsiata.cpp: usbjmicron_device: Check SCSI resid for SMART STATUS.
Some (Prolific) USB bridges do not transfer a status byte.
os_win32.cpp: Include SCSI resid in debug output.
2014-06-19 Douglas Gilbert <dgilbert@interlog.com>
scsiprint.cpp:
- minor comment clean-up
2014-06-19 Christian Franke <franke@computer.org>
drivedb.h:
- Intel 730 and DC S3500/S3700 Series SSDs: rename, add 730 and S3700.
Remove extra S3700 entry. Based on patch provided by Tim Small.
2014-06-18 Christian Franke <franke@computer.org>
os_win32.cpp: Fix CSMI support for older Intel RST drivers which set
bPortIdentifier=0xff (regression from r3888).
os_win32/installer.nsi: Create standard InstallLocation registry entry.
Keep old Install_Dir entry if needed for GSmartControl.
Update links in registry and shortcuts.
2014-06-18 Christian Franke <franke@computer.org>
drivedb.h:
- USB: Buffalo MiniStationHD-PCFU3 (0x0411:0x0240)
- USB: Toshiba Stor.E Plus (0x0480:0xa00a) (Debian bug 734395)
- USB: Samsung D3 Station (0x04e8:0x6124) (ticket #332)
- USB: Samsung M3 Portable (0x04e8:0x61b[45])
- USB: Seagate Expansion Portable (0x0bc2:0x2312)
- USB: Seagate Expansion External (0x0bc2:0x3312) (ticket #320)
- USB: WD Elements (0x1058:0x10[ab]8) (ticket #331)
- USB: ASMedia AS2105 (0x174c:0x5136)
2014-06-16 Christian Franke <franke@computer.org>
drivedb.h:
- Seagate Laptop Thin HDD
- Seagate Barracuda 7200.14 (AF): *DM000 variant
- Seagate Barracuda Green (AF): no warnings for newer firmware versions
- Seagate Constellation.2 (SATA)
- Seagate NAS HDD
- Seagate Video 3.5 HDD
2014-06-15 Christian Franke <franke@computer.org>
drivedb.h, smartctl.8.in, smartd.8.in, INSTALL, NEWS, TODO, WARNINGS:
Fix old Trac links.
2014-05-23 Alex Samorukov <samm@os2.kiev.ua>
os_freebsd.cpp: fixed #321 (compiler warning on 32 bit architectures),
patch provided by tijl
2014-05-01 Christian Franke <franke@computer.org>
os_linux.cpp: Clarify copyright info in GPL header.
smartctl.8.in, smartd.conf.5.in: Update '-d aacraid' info.
2014-04-30 Douglas Gilbert <dgilbert@interlog.com>
scsiprint.cpp:
- Lowest aligned LBA > 0 not common so only output in that case
2014-04-28 Christian Franke <franke@computer.org>
autogen.sh: Allow automake 1.14, suppress 'subdir-objects' warning.
Makefile.am: Add new 'compile' script to target 'maintainer-clean'.
2014-04-28 Douglas Gilbert <dgilbert@interlog.com>
scsicmds.h, scsicmds.cpp, scsiprint.h:
- improve handling of modern SCSI disks (SAS SSDs)
show compliance (SCSI version), show 12 Gbps SAS-3
speed, and flag ZBC presence
2014-04-27 Alex Samorukov <samm@os2.kiev.ua>
drivedb.h:
- Toshiba 3.5" MG03ACAxxx(Y) Enterprise HDD
2014-04-27 Christian Franke <franke@computer.org>
Fixes for aacraid patch:
aacraid.h: Fix typo which breaks 32-bit build.
os_linux.cpp: Remove useless member variable afd.
Fix error handling of /proc/devices parsing.
Avoid unsafe sprintf(). Fix help text.
2014-04-27 Raghava Aditya <raghava.aditya@pmcs.com>
os_linux.cpp:
- Added support for aacraid drivers
- Created a new interface for aacraid
smartctl -d aacraid,H,L,ID /dev/sdx
2014-04-18 Douglas Gilbert <dgilbert@interlog.com>
scsicmds.cpp:
- supported_vpd_pages(): lower response length to stop sense data
noise on old disks (pre SPC-3)
2014-04-17 Christian Franke <franke@computer.org>
drivedb.h:
- Western Digital RE4 (SATA 6Gb/s): WD2000FYYX
- Western Digital Se
- Western Digital Caviar Green (AF, SATA 6Gb/s): 4TB
- Western Digital Black: Rename, add 3TB, AF, remove extra AF entry
- Western Digital Red: 4TB (ticket #322)
- Western Digital Blue Mobile
2014-04-10 Christian Franke <franke@computer.org>
os_win32.cpp: Rework CSMI port scanning.
Use bPortIdentifier instead of Phy array index for addressing.
Ignore possibly bogus bNumberOfPhys (ticket #325).
2014-04-09 Douglas Gilbert <dgilbert@interlog.com>
scsiprint.cpp:
- add guard to scsiPrintSasPhy() invocation; resolve ticket #204
2014-04-06 Christian Franke <franke@computer.org>
WARNINGS: Remove all entries. Add link to Warnings page in Wiki.
2014-03-13 Christian Franke <franke@computer.org>
drivedb.h:
- Crucial/Micron RealSSD C300/M500: *SSD1 variant
- SandForce Driven SSDs: ADATA SP300, ADATA SP800, ADATA SP900 DL2,
Corsair Force SSD, Kingston SE50S3, Kingston SKC380S3,
Smart Storage XceedIOPS2, VisionTek GoDrive
- Indilinx Barefoot 3 based SSDs: OCZ VERTEX 450
- JMicron based SSDs: ADATA SP600
- Plextor M3/M5 (Pro) Series SSDs: Rename, add M5S (ticket #297), M5Pro
2014-03-06 Christian Franke <franke@computer.org>
drivedb.h:
- OCZ Intrepid 3000 SSDs
- Intel 320 Series SSDs: 'D' variant (ticket #315)
- Intel DC S3500 Series SSDs: 'T' variant (ticket #315)
2014-03-05 Christian Franke <franke@computer.org>
ataprint.cpp: Check SCT Feature Control support bit for '-g/-s wcreorder'.
This prevents bogus error messages if SCT support excludes SCT Feature
Control command.
atacmds.cpp: Fix error message text for SCT Feature Control command.
2014-03-03 Christian Franke <franke@computer.org>
smartctl.8.in, smartd.8.in, smartd.conf.5.in: Remove bashisms from
shell script examples.
2014-03-03 Christian Franke <franke@computer.org>
Makefile.am, os_win32/smart*_res.rc.in: Set Copyright year in
Windows VERSIONINFO resource.
2014-03-03 Christian Franke <franke@computer.org>
os_linux.cpp: Fix glob(3) max path count (ticket #317).
2014-03-03 Christian Franke <franke@computer.org>
configure.ac, Makefile.am: Add '--with-systemdenvfile=[FILE|no]'
configure option to change or remove (ticket #316) the systemd
EnvironmentFile setting.
smartd.service.in: Add a reference to documentation (ticket #316).
2014-02-18 Alex Samorukov <samm@os2.kiev.ua>
os_freebsd.cpp: use %lu for iop->resp_sense_len
2014-02-16 Alex Samorukov <samm@os2.kiev.ua>
os_freebsd.cpp: mass updates, provided by Tijl Coosemans
- Remove some unused private fields from some classes (found by Clang)
- In freebsd_scsi_device::scsi_pass_through:
* Make sure this function returns false on error instead of an error
code that gets converted to true.
* Put printing of the "Incoming data" debug info right after the
cam_send_ccb() call and before the error checking to make debugging
easier.
* When copying sense data make sure the fields in the CCB are actually
valid with CAM_AUTOSNS_VALID. Also make sure that the size of the
sense data doesn't overflow max_sense_len. This was the real cause for
the crash in ports/181836.
* Add some debug printing on the sense data.
2014-02-03 Christian Franke <franke@computer.org>
dev_areca.cpp: Check cmds index before use (ticket #312).
Make cmds array static const.
2014-01-01 Christian Franke <franke@computer.org>
Happy New Year! Update copyright year in version info.
2013-12-21 Christian Franke <franke@computer.org>
drivedb.h:
- Intel 525 Series SSDs
- Intel 530 Series SSDs (ticket #308)
2013-12-19 Christian Franke <franke@computer.org>
drivedb.h:
- Seagate Samsung Spinpoint F4
- Seagate Desktop SSHD
- Seagate Constellation CS
- Western Digital Red: *JFCX variant
- Western Digital Green Mobile
- Western Digital Elements / My Passport (USB): rename
2013-12-19 Christian Franke <franke@computer.org>
autogen.sh: automake 1.13.3 works.
2013-12-14 Christian Franke <franke@computer.org>
drivedb.h:
- Toshiba 2.5" HDD MK..65GSX: "... H" (USB?) variant
- Toshiba 2.5" HDD MQ01UBD... (USB 3.0)
- USB: Toshiba Stor.E Slim USB 3.0 (0x0480:0x0100)
- USB: Toshiba Stor.E Basics (0x0480:0xa009)
- USB: Toshiba Stor.E (0x0939:0x0b15)
- USB: Seagate FreeAgent GoFlex (0x0bc2:0x5020)
- USB: WD My Passport Ultra (0x1058:0x0741)
- USB: WD Elements (0x1058:0x1048)
- USB: Initio (0x13fd:0x1640) (ticket #295)
- USB: LucidPORT (0x1759:0x5100)
2013-12-08 Christian Franke <franke@computer.org>
drivedb.h:
- Apacer SDM4: SFDDA01C firmware (ticket #304).
- Crucial/Micron RealSSD m4/C400/P400: M4 SSD1 (ticket #306).
- Seagate Barracuda 7200.14: Check part number to avoid bogus
firmware bug warning (ticket #298).
2013-11-23 Christian Franke <franke@computer.org>
configure.ac, utility.cpp: Remove __DATE__, __TIME__
and SMARTMONTOOLS_CONFIGURE_DATE.
This obsoletes OpenSUSE nobuild-date.patch.
Reproducible builds are now supported.
2013-11-15 Alex Samorukov <samm@os2.kiev.ua>
os_freebsd.cpp: Fix crash on FreeBSD 9.2 caused by wrong
SCSI status check condition.
os_freebsd.cpp: Print debug info on errors only if requested.
2013-11-07 Matt Kraai <...>
smartctl.cpp: Add missing stdlib.h.
This fixes build on QNX 6.3.2 (ticket #300).
2013-11-07 Roger Röhrig <...>
drivedb.h: Intel DC S3500 Series SSDs: Add -F xerrorlba.
2013-11-07 Roger Röhrig <...>
atacmds.cpp: Fix Extended Comprehensive Error Log timestamp
byte order on big endian machines.
2013-09-12 Christoph Egger <christoph@debian.org>
dev_areca.h: Fix build on kFreeBSD (Debian bug 717567).
This obsoletes Debian kfreebsd.patch.
2013-08-17 Christian Franke <franke@computer.org>
examplescripts: Add scripts from Debian and Fedora packages.
2013-08-17 Christian Franke <franke@computer.org>
Add spaces between string literals and macro identifiers.
This avoids the interpretation as user-defined literals if
C++11 is enabled (g++ -std=gnu++11).
2013-08-15 Dan Lukes <dan+smartmontools.changelog@obluda.cz>
drivedb.h: Intel DC S3500 Series SSDs
2013-08-12 Christian Franke <franke@computer.org>
drivedb.h: Intel 320 Series SSDs: Add attribute 183 and 199.
2013-08-10 Christian Franke <franke@computer.org>
autogen.sh: automake 1.10.3, 1.12.6, and 1.13.4 work.
The new automake 1.14 is left out for now due to the
'subdir-objects' warning and the new 'compile' script.
Add options '--force' and '--warnings=CATEGORY'.
2013-07-26 Christian Franke <franke@computer.org> 2013-07-26 Christian Franke <franke@computer.org>

10
INSTALL
View File

@ -1,7 +1,7 @@
Smartmontools installation instructions Smartmontools installation instructions
======================================= =======================================
$Id: INSTALL 3817 2013-06-09 16:59:50Z chrfranke $ $Id: INSTALL 3935 2014-07-05 16:28:06Z chrfranke $
Please also see the smartmontools home page: Please also see the smartmontools home page:
http://smartmontools.sourceforge.net/ http://smartmontools.sourceforge.net/
@ -578,8 +578,8 @@ variable.
Source and binary packages for Windows are available at Source and binary packages for Windows are available at
http://sourceforge.net/projects/smartmontools/files/ http://sourceforge.net/projects/smartmontools/files/
Refer to http://sourceforge.net/apps/trac/smartmontools/wiki/Download Refer to http://www.smartmontools.org/wiki/Download for any additional
for any additional download and installation instructions. download and installation instructions.
The following files are installed if ./configure has no options: The following files are installed if ./configure has no options:
@ -661,6 +661,7 @@ OPTIONS DEFAULT AFFECTS
Directory for rc.d/init.d/smartd init script Directory for rc.d/init.d/smartd init script
--with-initscriptdir auto Location of init scripts --with-initscriptdir auto Location of init scripts
--with-systemdsystemunitdir auto Location of systemd service files --with-systemdsystemunitdir auto Location of systemd service files
--with-systemdenvfile ${sysconfdir}/sysconfig/smartmontools Path of environment file for system service
--with-docdir ${prefix}/share/doc/smartmontools Location of the documentation --with-docdir ${prefix}/share/doc/smartmontools Location of the documentation
--with-exampledir ${docdir}/examplescripts Location of example scripts --with-exampledir ${docdir}/examplescripts Location of example scripts
--enable-sample --disable-sample Adds the string '.sample' to the names of the smartd.conf file and the smartd RC file --enable-sample --disable-sample Adds the string '.sample' to the names of the smartd.conf file and the smartd RC file
@ -672,10 +673,13 @@ OPTIONS DEFAULT AFFECTS
available, option --capabilities is added to smartd. available, option --capabilities is added to smartd.
--disable-drivedb --enable-drivedb Disables default drive database file '${drivedbdir}/drivedb.h' --disable-drivedb --enable-drivedb Disables default drive database file '${drivedbdir}/drivedb.h'
--with-drivedbdir ${prefix}/share/smartmontools Directory for 'drivedb.h' (implies --enable-drivedb) --with-drivedbdir ${prefix}/share/smartmontools Directory for 'drivedb.h' (implies --enable-drivedb)
--with-smartdscriptdir ${sysconfdir} Directory for 'smartd_warning.sh' script
--with-smartdplugindir ${sysconfdir}/smartd_warning.d Directory for 'smartd_warning.sh' plugin scripts
--enable-savestates --disable-savestates Enables default smartd state files '${savestates}MODEL-SERIAL.ata.state' --enable-savestates --disable-savestates Enables default smartd state files '${savestates}MODEL-SERIAL.ata.state'
--with-savestates ${prefix}/var/lib/smartmontools/smartd. Prefix for smartd state files (implies --enable-savestates) --with-savestates ${prefix}/var/lib/smartmontools/smartd. Prefix for smartd state files (implies --enable-savestates)
--enable-attributelog --disable-attributelog Enables default smartd attribute log files --enable-attributelog --disable-attributelog Enables default smartd attribute log files
--with-attributelog ${prefix}/var/lib/smartmontools/attrlog. Prefix for smartd attribute log files (implies --enable-attributelog) --with-attributelog ${prefix}/var/lib/smartmontools/attrlog. Prefix for smartd attribute log files (implies --enable-attributelog)
--with-working-snprintf MinGW:guessed,others:yes Function snprintf() handles output truncation as specified by C99
Please note that in previous versions of smartmontools (<= 5.39) the Please note that in previous versions of smartmontools (<= 5.39) the
default for --with-docdir was default for --with-docdir was

View File

@ -1,6 +1,6 @@
## Process this file with automake to produce Makefile.in ## Process this file with automake to produce Makefile.in
# #
# $Id: Makefile.am 3759 2013-01-26 21:11:02Z chrfranke $ # $Id: Makefile.am 3957 2014-07-18 18:39:06Z chrfranke $
# #
@SET_MAKE@ @SET_MAKE@
@ -13,7 +13,11 @@ SUFFIXES = .cpp .c .s .o
# BUILD_INFO can be provided by package maintainers (see INSTALL file) # BUILD_INFO can be provided by package maintainers (see INSTALL file)
BUILD_INFO= "(local build)" BUILD_INFO= "(local build)"
AM_CPPFLAGS = -DBUILD_INFO='$(BUILD_INFO)' -DSMARTMONTOOLS_SYSCONFDIR='"$(sysconfdir)"' AM_CPPFLAGS = \
-DBUILD_INFO='$(BUILD_INFO)' \
-DSMARTMONTOOLS_SYSCONFDIR='"$(sysconfdir)"' \
-DSMARTMONTOOLS_SMARTDSCRIPTDIR='"$(smartdscriptdir)"'
if ENABLE_DRIVEDB if ENABLE_DRIVEDB
AM_CPPFLAGS += -DSMARTMONTOOLS_DRIVEDBDIR='"$(drivedbdir)"' AM_CPPFLAGS += -DSMARTMONTOOLS_DRIVEDBDIR='"$(drivedbdir)"'
endif endif
@ -96,6 +100,7 @@ EXTRA_smartctl_SOURCES = \
os_win32.cpp \ os_win32.cpp \
os_generic.cpp \ os_generic.cpp \
os_generic.h \ os_generic.h \
aacraid.h \
cciss.cpp \ cciss.cpp \
cciss.h \ cciss.h \
cissio_freebsd.h \ cissio_freebsd.h \
@ -155,6 +160,7 @@ EXTRA_smartd_SOURCES = \
os_win32.cpp \ os_win32.cpp \
os_generic.cpp \ os_generic.cpp \
os_generic.h \ os_generic.h \
aacraid.h \
cciss.cpp \ cciss.cpp \
cciss.h \ cciss.h \
cissio_freebsd.h \ cissio_freebsd.h \
@ -242,6 +248,11 @@ if OS_SOLARIS
extra_MANS = smartd.conf.4 \ extra_MANS = smartd.conf.4 \
smartctl.1m \ smartctl.1m \
smartd.1m smartd.1m
if ENABLE_DRIVEDB
extra_MANS += update-smart-drivedb.1m
endif
all-local: $(extra_MANS)
install-man: $(extra_MANS) install-man: $(extra_MANS)
@$(NORMAL_INSTALL) @$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(mandir)/man4 $(mkinstalldirs) $(DESTDIR)$(mandir)/man4
@ -268,27 +279,17 @@ uninstall-man:
echo " rm -f $(DESTDIR)$(mandir)/man$$ext/$$inst"; \ echo " rm -f $(DESTDIR)$(mandir)/man$$ext/$$inst"; \
rm -f $(DESTDIR)$(mandir)/man$$ext/$$inst; \ rm -f $(DESTDIR)$(mandir)/man$$ext/$$inst; \
done done
%.1m: %.8
awk '/^.TH/ {$$3="1m"} {print}' < $< | \
sed -e 's/smartd\.conf\(.*\)(5)/smartd.conf\1(4)/g' \
-e 's/syslog\.conf\(.*\)(5)/syslog.conf\1(4)/g' \
-e 's/smartctl\(.*\)(8)/smartctl\1(1m)/g' \
-e 's/syslogd\(.*\)(8)/syslogd\1(1m)/g' \
-e 's|/var/log/messages|/var/adm/messages|g' \
-e 's/smartd\(.*\)(8)/smartd\1(1m)/g' > $@
%.4: %.5
awk '/^.TH/ {$$3="4"} {print}' < $< | \
sed -e 's/smartd\.conf\(.*\)(5)/smartd.conf\1(4)/g' \
-e 's/syslog\.conf\(.*\)(5)/syslog.conf\1(4)/g' \
-e 's/smartctl\(.*\)(8)/smartdctl\1(1m)/g' \
-e 's/syslogd\(.*\)(8)/syslogd\1(1m)/g' \
-e 's|/var/log/messages|/var/adm/messages|g' \
-e 's/smartd\(.*\)(8)/smartd\1(1m)/g' > $@
else else
# For systems that adopts traditional manner # For systems that adopts traditional manner
man_MANS = smartd.conf.5 \ man_MANS = smartd.conf.5 \
smartctl.8 \ smartctl.8 \
smartd.8 smartd.8
if ENABLE_DRIVEDB
man_MANS += update-smart-drivedb.8
endif
endif endif
docsdir=$(docdir) docsdir=$(docdir)
@ -311,7 +312,9 @@ examples_SCRIPTS = \
examplescripts/Example1 \ examplescripts/Example1 \
examplescripts/Example2 \ examplescripts/Example2 \
examplescripts/Example3 \ examplescripts/Example3 \
examplescripts/Example4 examplescripts/Example4 \
examplescripts/Example5 \
examplescripts/Example6
sysconf_DATA = smartd.conf sysconf_DATA = smartd.conf
@ -345,9 +348,7 @@ uninstall-sysconfDATA:
echo " rm -f $$f"; \ echo " rm -f $$f"; \
rm -f "$$f" rm -f "$$f"
# automake does not allow 'sysconf_SCRIPTS' smartdscript_SCRIPTS = smartd_warning.sh
sysscriptdir = $(sysconfdir)
sysscript_SCRIPTS = smartd_warning.sh
EXTRA_DIST = \ EXTRA_DIST = \
autogen.sh \ autogen.sh \
@ -360,6 +361,7 @@ EXTRA_DIST = \
smartd.service.in \ smartd.service.in \
smartd_warning.sh.in \ smartd_warning.sh.in \
update-smart-drivedb.in \ update-smart-drivedb.in \
update-smart-drivedb.8.in \
m4/pkg.m4 \ m4/pkg.m4 \
os_darwin/SMART.in \ os_darwin/SMART.in \
os_darwin/StartupParameters.plist \ os_darwin/StartupParameters.plist \
@ -398,12 +400,15 @@ CLEANFILES = \
smartd_warning.sh \ smartd_warning.sh \
svnversion.h \ svnversion.h \
update-smart-drivedb \ update-smart-drivedb \
update-smart-drivedb.8 \
update-smart-drivedb.1m \
SMART SMART
# 'make maintainer-clean' also removes files generated by './autogen.sh' # 'make maintainer-clean' also removes files generated by './autogen.sh'
MAINTAINERCLEANFILES = \ MAINTAINERCLEANFILES = \
$(srcdir)/Makefile.in \ $(srcdir)/Makefile.in \
$(srcdir)/aclocal.m4 \ $(srcdir)/aclocal.m4 \
$(srcdir)/compile \
$(srcdir)/configure \ $(srcdir)/configure \
$(srcdir)/config.guess \ $(srcdir)/config.guess \
$(srcdir)/config.h.in \ $(srcdir)/config.h.in \
@ -420,8 +425,9 @@ utility.o: svnversion.h
if IS_SVN_BUILD if IS_SVN_BUILD
# Get version info from SVN # Get version info from SVN
svnversion.h: ChangeLog Makefile $(svn_deps) svnversion.h: ChangeLog Makefile $(svn_deps)
echo '/* svnversion.h. Generated by Makefile from svn info. */' > $@ @echo ' svn info | $$(VERSION_FROM_SVN_INFO) > $@'
(cd $(srcdir) \ @echo '/* svnversion.h. Generated by Makefile from svn info. */' > $@
@(cd $(srcdir) \
&& svnversion 2>/dev/null | sed -n 's,^\([0-9].*\),REV "\1",p' \ && svnversion 2>/dev/null | sed -n 's,^\([0-9].*\),REV "\1",p' \
&& TZ= LC_ALL=C svn info 2>/dev/null \ && TZ= LC_ALL=C svn info 2>/dev/null \
| sed -n 'h;s,^.* Date: *\([^ ]*\) .*$$,DATE "\1",p;g;s,^.* Date: *[^ ]* *\([^ ]*\) .*$$,TIME "\1",p') \ | sed -n 'h;s,^.* Date: *\([^ ]*\) .*$$,DATE "\1",p;g;s,^.* Date: *[^ ]* *\([^ ]*\) .*$$,TIME "\1",p') \
@ -430,8 +436,9 @@ else
# SVN not available, guess version info from Id strings # SVN not available, guess version info from Id strings
svnversion.h: ChangeLog Makefile svnversion.h: ChangeLog Makefile
echo '/* svnversion.h. Generated by Makefile from Id strings. */' > $@ @echo ' cat ChangeLog $$(SOURCES) | $$(VERSION_FROM_SVN_IDS) > $@'
(cd $(srcdir) && cat ChangeLog Makefile.am configure.ac smart*.in *.cpp *.h *.s) \ @echo '/* svnversion.h. Generated by Makefile from Id strings. */' > $@
@(cd $(srcdir) && cat ChangeLog Makefile.am configure.ac smart*.in *.cpp *.h *.s) \
| sed -n 's,^.*\$$[I][d]: [^ ]* \([0-9][0-9]* [0-9][-0-9]* [0-9][:0-9]*\)[^:0-9][^$$]*\$$.*$$,\1,p' \ | sed -n 's,^.*\$$[I][d]: [^ ]* \([0-9][0-9]* [0-9][-0-9]* [0-9][:0-9]*\)[^:0-9][^$$]*\$$.*$$,\1,p' \
| sort -n -r \ | sort -n -r \
| sed -n 'h;s,^\([^ ]*\) .*$$,REV "\1",p;g;s,^[^ ]* \([^ ]*\) .*$$,DATE "\1",p;g;s,^[^ ]* [^ ]* \([^ ]*\)$$,TIME "\1",p;q' \ | sed -n 'h;s,^\([^ ]*\) .*$$,REV "\1",p;g;s,^[^ ]* \([^ ]*\) .*$$,DATE "\1",p;g;s,^[^ ]* [^ ]* \([^ ]*\)$$,TIME "\1",p;q' \
@ -443,16 +450,6 @@ if ENABLE_DRIVEDB
drivedb_DATA = drivedb.h drivedb_DATA = drivedb.h
endif endif
if ENABLE_SAVESTATES
# Create $(savestatesdir) only
savestates_DATA =
endif
if ENABLE_ATTRIBUTELOG
# Create $(attributelogdir) only
attributelog_DATA =
endif
update-smart-drivedb: update-smart-drivedb.in config.status update-smart-drivedb: update-smart-drivedb.in config.status
$(SHELL) ./config.status --file=$@ $(SHELL) ./config.status --file=$@
chmod +x $@ chmod +x $@
@ -530,10 +527,30 @@ systemdsystemunit_DATA = smartd.service
endif endif
smartd.service: smartd.service.in Makefile smartd.service: smartd.service.in Makefile
sed -e 's|/usr/local/sbin/smartd|$(sbindir)/smartd|g' \ cat $(srcdir)/smartd.service.in | \
-e 's|/usr/local/etc/sysconfig/smartmontools|$(sysconfdir)/sysconfig/smartmontools|g' \ sed 's|/usr/local/sbin/smartd|$(sbindir)/smartd|' | \
$(srcdir)/smartd.service.in > $@ if test -n '$(systemdenvfile)'; then \
sed 's|/usr/local/etc/sysconfig/smartmontools|$(systemdenvfile)|'; \
else \
sed -e '/^EnvironmentFile=/d' -e 's| *\$$smartd[_a-z]* *||g'; \
fi > $@
# Create empty directories if configured.
# Default install rules no longer create empty directories since automake 1.11.
# Uses $(mkinstalldirs) instead of $(MKDIR_P) to preserve support for automake 1.7 - 1.9.
installdirs-local:
@for d in '$(smartdplugindir)' '$(savestatesdir)' '$(attributelogdir)'; do \
test -n "$$d" || continue; \
echo "$(mkinstalldirs) $(DESTDIR)$$d"; \
$(mkinstalldirs) "$(DESTDIR)$$d" || exit 1; \
done
install-data-local: installdirs-local
#
# Build man pages
#
if ENABLE_CAPABILITIES if ENABLE_CAPABILITIES
MAN_CAPABILITIES = cat MAN_CAPABILITIES = cat
else else
@ -569,8 +586,17 @@ MAN_FILTER = \
-e 's|/usr/local/share/doc/smartmontools/|$(docsdir)/|g' \ -e 's|/usr/local/share/doc/smartmontools/|$(docsdir)/|g' \
-e 's|!exampledir!|$(exampledir)/|g' \ -e 's|!exampledir!|$(exampledir)/|g' \
-e 's|/usr/local/etc/smartd\.conf|$(sysconfdir)/smartd.conf|g' \ -e 's|/usr/local/etc/smartd\.conf|$(sysconfdir)/smartd.conf|g' \
-e 's|/usr/local/etc/smartd_warning\.|$(sysconfdir)/smartd_warning.|g' \ -e 's|/usr/local/etc/smart_drivedb\.h|$(sysconfdir)/smart_drivedb.h|g' \
-e 's|/usr/local/etc/smart_drivedb\.h|$(sysconfdir)/smart_drivedb.h|g' | \ -e 's|/usr/local/etc/smartd_warning\.sh|$(smartdscriptdir)/smartd_warning.sh|g' \
-e 's|\\fBmail\\fP|\\fB$(os_mailer)\\fP|g' \
-e 's|\\'\''mail\\'\''|\\'\''$(os_mailer)\\'\''|g' \
-e 's|/usr/bin/mail|/usr/bin/$(os_mailer)|g' \
-e 's|RELEASE_6_0_DRIVEDB|@DRIVEDB_BRANCH@|g' | \
if test -n '$(smartdplugindir)'; then \
sed 's|/usr/local/etc/smartd_warning\.d|$(smartdplugindir)|g' ; \
else \
sed '/^\.\\" %IF ENABLE_SMARTDPLUGINDIR/,/^\.\\" %ENDIF ENABLE_SMARTDPLUGINDIR/ s,^,.\\"\# ,' ; \
fi | \
$(MAN_ATTRIBUTELOG) | \ $(MAN_ATTRIBUTELOG) | \
$(MAN_CAPABILITIES) | \ $(MAN_CAPABILITIES) | \
$(MAN_DRIVEDB) | \ $(MAN_DRIVEDB) | \
@ -589,13 +615,45 @@ MAN_FILTER = \
# Implicit rule 'smart%: smart%.in ...' does not work with BSD make # Implicit rule 'smart%: smart%.in ...' does not work with BSD make
smartctl.8: smartctl.8.in Makefile svnversion.h smartctl.8: smartctl.8.in Makefile svnversion.h
cat $(srcdir)/smartctl.8.in | $(MAN_FILTER) > $@ @echo ' cat $(srcdir)/smartctl.8.in | $$(MAN_FILTER) > $@'
@cat $(srcdir)/smartctl.8.in | $(MAN_FILTER) > $@
smartd.8: smartd.8.in Makefile svnversion.h smartd.8: smartd.8.in Makefile svnversion.h
cat $(srcdir)/smartd.8.in | $(MAN_FILTER) > $@ @echo ' cat $(srcdir)/smartd.8.in | $$(MAN_FILTER) > $@'
@cat $(srcdir)/smartd.8.in | $(MAN_FILTER) > $@
smartd.conf.5: smartd.conf.5.in Makefile svnversion.h smartd.conf.5: smartd.conf.5.in Makefile svnversion.h
cat $(srcdir)/smartd.conf.5.in | $(MAN_FILTER) > $@ @echo ' cat $(srcdir)/smartd.conf.5.in | $$(MAN_FILTER) > $@'
@cat $(srcdir)/smartd.conf.5.in | $(MAN_FILTER) > $@
update-smart-drivedb.8: update-smart-drivedb.8.in Makefile svnversion.h
@echo ' cat $(srcdir)/update-smart-drivedb.8.in | $$(MAN_FILTER) > $@'
@cat $(srcdir)/update-smart-drivedb.8.in | $(MAN_FILTER) > $@
# Build Solaris specific man pages
SOLARIS_MAN_FILTER = \
sed -e '/^\.TH/s, \([58]\) , !!\1!! ,' \
-e '/^\.BR/s, (\([578]\)), (!!\1!!),' \
-e 's,\\fP(\([578]\)),\\fP(!!\1!!),g' \
-e 's,!!5!!,4,g' -e 's,!!7!!,5,g' -e 's,!!8!!,1m,g' \
-e 's,/var/log/messages,/var/adm/messages,g'
smartctl.1m: smartctl.8
@echo ' cat smartctl.8 | $$(SOLARIS_MAN_FILTER) > $@'
@cat smartctl.8 | $(SOLARIS_MAN_FILTER) > $@
smartd.1m: smartd.8
@echo ' cat smartd.8 | $$(SOLARIS_MAN_FILTER) > $@'
@cat smartd.8 | $(SOLARIS_MAN_FILTER) > $@
smartd.conf.4: smartd.conf.5
@echo ' cat smartd.conf.5 | $$(SOLARIS_MAN_FILTER) > $@'
@cat smartd.conf.5 | $(SOLARIS_MAN_FILTER) > $@
update-smart-drivedb.1m: update-smart-drivedb.8
@echo ' cat update-smart-drivedb.8 | $$(SOLARIS_MAN_FILTER) > $@'
@cat update-smart-drivedb.8 | $(SOLARIS_MAN_FILTER) > $@
# Commands to convert man pages into .html and .txt # Commands to convert man pages into .html and .txt
# TODO: configure # TODO: configure
@ -657,12 +715,13 @@ smartctl_res.o: smartctl_res.rc
smartd_res.o: smartd_res.rc syslogevt.rc smartd_res.o: smartd_res.rc syslogevt.rc
$(WINDRES) -I. $< $@ $(WINDRES) -I. $< $@
# Convert version for VERSIONINFO resource: 6.1 r3754 -> 6.1.0.3754 # Convert version for VERSIONINFO resource: 6.1 r3754 -> 6.1.0.3754, set Copyright year
WIN_RC_FILTER = \ WIN_RC_FILTER = \
( ver=`echo '$(PACKAGE_VERSION).0' | sed -n 's,^\([0-9]*\.[0-9]*\.[0-9]*\).*$$,\1,p'`; \ ( ver=`echo '$(PACKAGE_VERSION).0' | sed -n 's,^\([0-9]*\.[0-9]*\.[0-9]*\).*$$,\1,p'`; \
rev=`sed -n 's,^.*REV[^"]*"\([0-9]*\).*$$,\1,p' svnversion.h`; \ rev=`sed -n 's,^.*REV[^"]*"\([0-9]*\).*$$,\1,p' svnversion.h`; \
txtver="$${ver:-0.0.0}.$${rev:-0}"; binver=`echo "$$txtver" | sed 's|\.|,|g'`; \ txtver="$${ver:-0.0.0}.$${rev:-0}"; binver=`echo "$$txtver" | sed 's|\.|,|g'`; \
sed -e "s|@BINARY_VERSION@|$$binver|g" -e "s|@TEXT_VERSION@|$$txtver|g"; ) yy=`sed -n 's,^.*DATE[^"]*"20\([0-9][0-9]\).*$$,\1,p' svnversion.h`; yy="$${yy:-XX}"; \
sed -e "s|@BINARY_VERSION@|$$binver|g" -e "s|@TEXT_VERSION@|$$txtver|g" -e "s|@YY@|$$yy|g"; )
smartctl_res.rc: os_win32/smartctl_res.rc.in Makefile svnversion.h smartctl_res.rc: os_win32/smartctl_res.rc.in Makefile svnversion.h
cat $< | $(WIN_RC_FILTER) > $@ cat $< | $(WIN_RC_FILTER) > $@

28
NEWS
View File

@ -1,10 +1,34 @@
smartmontools NEWS smartmontools NEWS
------------------ ------------------
$Id: NEWS 3841 2013-07-26 17:38:57Z chrfranke $ $Id: NEWS 3979 2014-08-15 11:09:41Z samm2 $
The most up-to-date version of this file is: The most up-to-date version of this file is:
http://sourceforge.net/p/smartmontools/code/HEAD/tree/trunk/smartmontools/NEWS http://sourceforge.net/p/smartmontools/code/HEAD/tree/trunk/smartmontools/NEWS
- darwin: '-S' command implemented, '-l devstat' should work now
Date 2014-07-26
Summary: smartmontools release 6.3
-----------------------------------------------------------
- smartctl: Fixed bogus error messages from '-g/-s wcreorder'.
- smartctl prints ATA form factor.
- SCSI: Improved support of modern disks (SAS SSDs).
- SCSI: Fixed sense data noise from old disks.
- update-smart-drivedb man page.
- configure option '--with-smartdscriptdir'.
- configure option '--with-smartdplugindir'.
- configure option '--with-systemdenvfile'.
- configure option '--with-working-snprintf'.
- Removed build time stamps to support reproducible builds.
- Compile fixes for C++11.
- HDD, SSD and USB additions to drive database.
- Linux: Support for controllers behind AACRAID driver.
- Linux: Fixed DEVICESCAN max path count.
- FreeBSD: Fixed possible crash caused by wrong SCSI error handling.
- FreeBSD: Compile fix for kFreeBSD.
- Windows: Reworked CSMI port scanning.
- QNX: Compile fix.
Date 2013-07-26 Date 2013-07-26
Summary: smartmontools release 6.2 Summary: smartmontools release 6.2
----------------------------------------------------------- -----------------------------------------------------------
@ -209,7 +233,7 @@ Summary: smartmontools release 5.39 (UNSTABLE/EXPERIMENTAL)
- Sourcecode repository moved from CVS to SVN - Sourcecode repository moved from CVS to SVN
- Support for USB devices with Cypress, JMicron and Sunplus USB bridges - Support for USB devices with Cypress, JMicron and Sunplus USB bridges
- USB device type autodetection for some devices on Linux, Windows and FreeBSD - USB device type autodetection for some devices on Linux, Windows and FreeBSD
(http://sourceforge.net/apps/trac/smartmontools/wiki/Supported_USB-Devices) (http://www.smartmontools.org/wiki/Supported_USB-Devices)
- Support for Areca controllers on Linux - Support for Areca controllers on Linux
- Support for MegaRAID controllers on Linux - Support for MegaRAID controllers on Linux
- Support for HighPoint RocketRAID controllers on FreeBSD - Support for HighPoint RocketRAID controllers on FreeBSD

22
README
View File

@ -3,7 +3,7 @@ smartmontools - S.M.A.R.T. utility toolset for Darwin/Mac
OSX, FreeBSD, Linux, NetBSD, OpenBSD, Solaris, and Windows. OSX, FreeBSD, Linux, NetBSD, OpenBSD, Solaris, and Windows.
========================================================== ==========================================================
$Id: README 3817 2013-06-09 16:59:50Z chrfranke $ $Id: README 3949 2014-07-13 17:23:40Z chrfranke $
== HOME == == HOME ==
The home for smartmontools is located at: The home for smartmontools is located at:
@ -20,6 +20,7 @@ You will find a mailing list for support and other questions at:
== COPYING == == COPYING ==
Copyright (C) 2002-9 Bruce Allen <smartmontools-support@lists.sourceforge.net> Copyright (C) 2002-9 Bruce Allen <smartmontools-support@lists.sourceforge.net>
Copyright (C) 2004-14 Christian Franke <smartmontools-support@lists.sourceforge.net>
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free under the terms of the GNU General Public License as published by the Free
@ -27,8 +28,7 @@ Software Foundation; either version 2, or (at your option) any later
version. version.
You should have received a copy of the GNU General Public License (for You should have received a copy of the GNU General Public License (for
example COPYING); if not, write to the Free Software Foundation, Inc., example COPYING). If not, see <http://www.gnu.org/licenses/>.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
== CREDITS == == CREDITS ==
@ -41,16 +41,9 @@ California, Santa Cruz. http://ssrc.soe.ucsc.edu/
== OVERVIEW == == OVERVIEW ==
smartmontools contains utilities that control and monitor storage smartmontools contains utilities that control and monitor storage
devices using the Self-Monitoring, Analysis and Reporting Technology devices using the Self-Monitoring, Analysis and Reporting Technology
(S.M.A.R.T.) system build into ATA and SCSI Hard Drives. This is used (SMART) system build into ATA/SATA and SCSI/SAS hard drives and
to check the reliability of the hard drive and to predict drive solid-state drives. This is used to check the reliability of the
failures. smartmontools Version 5.x is designed to comply to the drive and to predict drive failures.
ATA/ATAPI-5 specification (Revision 1). Future releases of
smartmontools (Versions 6.x and 7.x) will comply with the ATA/ATAPI-6
and ATA/ATAPI-7 specifications.
This package is meant to be an up-to-date replacement for the
ucsc-smartsuite and smartsuite packages, and is derived from that
code.
== CONTENTS == == CONTENTS ==
@ -89,9 +82,6 @@ http://sourceforge.net/p/smartmontools/code/HEAD/tree/tags/
Refer to the "INSTALL" file for detailed installation instructions. Refer to the "INSTALL" file for detailed installation instructions.
See the "WARNINGS" file for reports of hardware where these utilities
might cause serious problems such as lockups.
== GETTING STARTED == == GETTING STARTED ==
To examine SMART data from a disk, try: To examine SMART data from a disk, try:

4
TODO
View File

@ -1,4 +1,4 @@
$Id: TODO 3175 2010-10-02 14:34:09Z chrfranke $ $Id: TODO 3904 2014-06-15 14:21:15Z chrfranke $
This file is no longer maintained, please use the ticket reports: This file is no longer maintained, please use the ticket reports:
http://sourceforge.net/apps/trac/smartmontools/report http://www.smartmontools.org/report

124
WARNINGS
View File

@ -1,122 +1,4 @@
$Id: WARNINGS 3817 2013-06-09 16:59:50Z chrfranke $ $Id: WARNINGS 3904 2014-06-15 14:21:15Z chrfranke $
The most recent version of this file can be found here: This file is no longer maintained, please see:
http://sourceforge.net/p/smartmontools/code/HEAD/tree/trunk/smartmontools/WARNINGS http://www.smartmontools.org/wiki/Warnings
The following are reports of serious problems (eg system lockup) which
were due to smartmontools. There are DARWIN, LINUX, FREEBSD, SOLARIS
and WINDOWS sections below.
LINUX
-----
You may also wish to search the linux-kernel mailing list for problem
reports concerning smartmontools. Here is the URL:
http://groups.google.com/groups?as_q=smartmontools&safe=images&ie=UTF-8&oe=UTF-8&as_ugroup=linux.kernel&lr=&num=100&hl=en
SYSTEM: Any system with USB ports and USB storage devices
PROBLEM: Using smartd/smartctl on USB "SCSI" storage devices can cause kernel hang
REPORTER: see link below
LINK: https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=107615
NOTE: USB storage devices are handled as SCSI devices by the kernel. But many of these
devices do not comply with SCSI specs, and can cause the kernel to hang.
Avoid using smartd/smartctl on these devices (they don't do SMART anyway).
In particular, the use of smartd DEVICESCAN in /etc/smartd.conf can cause
these devices (typically represented by /dev/sda or /dev/sdb) to hang, and
the kernel to lock up.
FIXED: This problem should be fixed in smartmontools-5.25 and greater.
SYSTEM: Intel 875WP1-E motherboard with SATA drives on motherboard's SATA ports
PROBLEM: smartd makes NTP time drift
REPORTER: nohez@cmie.com
LINK: http://groups.google.de/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&safe=off&selm=Pine.LNX.4.33.0310111545530.1047-100000%40venus.cmie.ernet.in.lucky.linux.kernel
NOTE: When using SATA disks, linux kernel k_smp-2.4.21-108 (SMP because
of hyper-threading) and xntp-4.1.1-177, the server time went
out of sync with system time. Problem goes away when SATA
disks removed.
SYSTEM: Dell servers using AACRAID (SCSI)
PROBLEM: Locked up, needed to be rebooted
REPORTER: drew@eastvan.bc.ca
LINK: http://sourceforge.net/mailarchive/forum.php?thread_id=1311313&forum_id=12495
SYSTEM: Box with Promise 20265 IDE-controller (pdc202xx-driver) and > 2.4.18 kernel with ide-taskfile support
PROBLEM: Smartctl locks system solid when used on /dev/hd[ef].
REPORTER: Georg Acher <acher@in.tum.de>
LINK: http://sourceforge.net/mailarchive/forum.php?thread_id=1457979&forum_id=12495
NOTE: Lockup doesn't happen with 2.4.18 kernel, and doesn't affect /dev/hd[a-d]
This appears to be a problem with the pdc202xx-driver and has been reported
to the pdcx maintainers. If you enable the Promise-BIOS (ATA100-BIOS) then
everything will work fine. But if you disable it, then the machine will hang.
SYSTEM: Box with Promise 20262 IDE-controller
PROBLEM: Smartctl locks system solid
REPORTER: Ben Low <ben@bdlow.net>
LINK: http://sourceforge.net/mailarchive/message.php?msg_id=5074201
NOTE: Similar to previous report: Promise Ultra66 2-port card (20262) which, with
linux 2.4.20, suffers from the lockups reported above. But it was
impossible to enable the Promiste BIOS. A kernel patch is referenced
to fix the problem.
SYSTEM: Promise 20265 IDE-controller
PROBLEM: Smartctl locks system solid when used on CDROM/DVD device
REPORTER: see link below
LINK: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=208964
NOTE: Problem seems to affect kernel 2.4.21 only.
SYSTEM: Promise IDE-controllers and perhaps others also
PROBLEM: System freezes under heavy load, perhaps when running SMART commands
REPORTER: Mario 'BitKoenig' Holbe Mario.Holbe@RZ.TU-Ilmenau.DE
LINK: http://groups.google.de/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=1wUXW-2FA-9%40gated-at.bofh.it
NOTE: Before freezing, SYSLOG shows the following message(s)
kernel: hdf: dma timer expiry: dma status == 0xXX
where XX is two hexidecimal digits. This may be a kernel bug
or an underlying hardware problem. It's not clear if
smartmontools plays a role in provoking this problem. FINAL
NOTE: Problem was COMPLETELY resolved by replacing the power
supply. See URL above, entry on May 29, 2004 by Holbe. Other
things to try are exchanging cables, and cleaning PCI slots.
FREEBSD
-------
[No problem reports yet.]
SOLARIS
-------
[No problem reports yet.]
CYGWIN and WINDOWS
------------------
[No problem reports yet.]
DARWIN
------
SYSTEM: Any system before Tiger
PROBLEM: Can't switch off SMART, can't switch off auto-save, can't run
short tests.
REPORTER: Geoff Keating <geoffk@geoffk.org>
NOTE: There's a bug in the system library: when you ask it to
do any of these things, it does the inverse (switches on,
runs extended tests). Radar 3727283.
SYSTEM: All known systems
PROBLEM: When drive is asleep, SMART commands fail
REPORTER: Geoff Keating <geoffk@geoffk.org>
NOTE: You can prevent the drive from sleeping by saying
pmset -a disksleep 0
or by unchecking the 'Put the hard disk(s) to sleep when possible'
checkbox in the Energy Saver preferences. Radar 4094403.

105
aacraid.h Normal file
View File

@ -0,0 +1,105 @@
/* aacraid.h
* Copyright (C) 2014 Raghava Aditya <Raghava.Aditya@pmcs.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
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* You should have received a copy of the GNU General Public License
* (for example COPYING); If not, see <http://www.gnu.org/licenses/>.
*
*/
// Check windows
#if _WIN32 || _WIN64
#if _WIN64
#define ENVIRONMENT64
#else
#define ENVIRONMENT32
#endif
#endif
// Check GCC
#if __GNUC__
#if __x86_64__ || __ppc64__
#define ENVIRONMENT64
#else
#define ENVIRONMENT32
#endif
#endif
#define METHOD_BUFFERED 0
#define METHOD_NEITHER 3
#define CTL_CODE(function, method) ((4<< 16) | ((function) << 2) | (method) )
#define FSACTL_SEND_RAW_SRB CTL_CODE(2067, METHOD_BUFFERED)
#define SRB_FUNCTION_EXECUTE_SCSI 0X00
#define SRB_DataIn 0x0040
#define SRB_DataOut 0x0080
#define SRB_NoDataXfer 0x0000
typedef struct {
uint32_t lo32;
uint32_t hi32;
} address64;
typedef struct {
address64 addr64;
uint32_t length; /* Length. */
} user_sgentry64;
typedef struct {
uint32_t addr32;
uint32_t length;
} user_sgentry32;
typedef struct {
uint32_t count;
user_sgentry64 sg64[1];
} user_sgmap64;
typedef struct {
uint32_t count;
user_sgentry32 sg32[1];
} user_sgmap32;
typedef struct {
uint32_t function; //SRB_FUNCTION_EXECUTE_SCSI 0x00
uint32_t channel; //bus
uint32_t id; //use the ID number this is wrong
uint32_t lun; //Logical unit number
uint32_t timeout;
uint32_t flags; //Interesting stuff I must say
uint32_t count; // Data xfer size
uint32_t retry_limit; // We shall see
uint32_t cdb_size; // Length of CDB
uint8_t cdb[16]; // The actual cdb command
user_sgmap64 sg64; // pDatabuffer and address of Databuffer
} user_aac_srb64;
typedef struct {
uint32_t function; //SRB_FUNCTION_EXECUTE_SCSI 0x00
uint32_t channel; //bus
uint32_t id; //use the ID number this is wrong
uint32_t lun; //Logical unit number
uint32_t timeout;
uint32_t flags; //Interesting stuff I must say
uint32_t count; // Data xfer size
uint32_t retry_limit; // We shall see
uint32_t cdb_size; // Length of CDB
uint8_t cdb[16]; // The actual cdb command
user_sgmap32 sg32; // pDatabuffer and address of Databuffer
} user_aac_srb32;
typedef struct {
uint32_t status;
uint32_t srb_status;
uint32_t scsi_status;
uint32_t data_xfer_length;
uint32_t sense_data_size;
uint8_t sense_data[30];
} user_aac_reply;

View File

@ -4,7 +4,7 @@
* Home page of code is: http://smartmontools.sourceforge.net * Home page of code is: http://smartmontools.sourceforge.net
* *
* Copyright (C) 2002-11 Bruce Allen <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2002-11 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2008-13 Christian Franke <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2008-14 Christian Franke <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org> * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
* Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org> * Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org>
* *
@ -35,7 +35,7 @@
#include "utility.h" #include "utility.h"
#include "dev_ata_cmd_set.h" // for parsed_ata_device #include "dev_ata_cmd_set.h" // for parsed_ata_device
const char * atacmds_cpp_cvsid = "$Id: atacmds.cpp 3825 2013-07-06 21:38:25Z samm2 $" const char * atacmds_cpp_cvsid = "$Id: atacmds.cpp 3971 2014-07-23 18:57:55Z chrfranke $"
ATACMDS_H_CVSID; ATACMDS_H_CVSID;
// Print ATA debug messages? // Print ATA debug messages?
@ -134,7 +134,7 @@ const format_name_entry format_names[] = {
const unsigned num_format_names = sizeof(format_names)/sizeof(format_names[0]); const unsigned num_format_names = sizeof(format_names)/sizeof(format_names[0]);
// Table to map old to new '-v' option arguments // Table to map old to new '-v' option arguments
const char * map_old_vendor_opts[][2] = { const char * const map_old_vendor_opts[][2] = {
{ "9,halfminutes" , "9,halfmin2hour,Power_On_Half_Minutes"}, { "9,halfminutes" , "9,halfmin2hour,Power_On_Half_Minutes"},
{ "9,minutes" , "9,min2hour,Power_On_Minutes"}, { "9,minutes" , "9,min2hour,Power_On_Minutes"},
{ "9,seconds" , "9,sec2hour,Power_On_Seconds"}, { "9,seconds" , "9,sec2hour,Power_On_Seconds"},
@ -172,7 +172,7 @@ bool parse_attribute_def(const char * opt, ata_vendor_attr_defs & defs,
int id = 0, n1 = -1, n2 = -1; int id = 0, n1 = -1, n2 = -1;
char fmtname[32+1], attrname[32+1]; char fmtname[32+1], attrname[32+1];
if (opt[0] == 'N') { if (opt[0] == 'N') {
// "N,format" // "N,format[,name]"
if (!( sscanf(opt, "N,%32[^,]%n,%32[^,]%n", fmtname, &n1, attrname, &n2) >= 1 if (!( sscanf(opt, "N,%32[^,]%n,%32[^,]%n", fmtname, &n1, attrname, &n2) >= 1
&& (n1 == len || n2 == len))) && (n1 == len || n2 == len)))
return false; return false;
@ -196,6 +196,7 @@ bool parse_attribute_def(const char * opt, ata_vendor_attr_defs & defs,
// Split "format[:byteorder]" // Split "format[:byteorder]"
char byteorder[8+1] = ""; char byteorder[8+1] = "";
if (strchr(fmtname, ':')) { if (strchr(fmtname, ':')) {
n1 = n2 = -1;
if (!( sscanf(fmtname, "%*[^:]%n:%8[012345rvwz]%n", &n1, byteorder, &n2) >= 1 if (!( sscanf(fmtname, "%*[^:]%n:%8[012345rvwz]%n", &n1, byteorder, &n2) >= 1
&& n2 == (int)strlen(fmtname))) && n2 == (int)strlen(fmtname)))
return false; return false;
@ -598,8 +599,7 @@ int smartcommandhandler(ata_device * device, smart_command_set command, int sele
"probable SAT/USB truncation\n"); "probable SAT/USB truncation\n");
} }
else if (!out.out_regs.is_set()) { else if (!out.out_regs.is_set()) {
pout("SMART STATUS RETURN: incomplete response, ATA output registers missing\n"); device->set_err(ENOSYS, "Incomplete response, ATA output registers missing");
device->set_err(ENOSYS);
retval = -1; retval = -1;
} }
else { else {
@ -608,7 +608,7 @@ int smartcommandhandler(ata_device * device, smart_command_set command, int sele
pout("Please get assistance from %s\n", PACKAGE_HOMEPAGE); pout("Please get assistance from %s\n", PACKAGE_HOMEPAGE);
pout("Register values returned from SMART Status command are:\n"); pout("Register values returned from SMART Status command are:\n");
print_regs(" ", out.out_regs); print_regs(" ", out.out_regs);
device->set_err(EIO); device->set_err(ENOSYS, "Invalid ATA output register values");
retval = -1; retval = -1;
} }
break; break;
@ -1274,9 +1274,9 @@ int ataWriteSelectiveSelfTestLog(ata_device * device, ata_selective_selftest_arg
uint64_t spans = (num_sectors + oldsize-1) / oldsize; uint64_t spans = (num_sectors + oldsize-1) / oldsize;
uint64_t newsize = (num_sectors + spans-1) / spans; uint64_t newsize = (num_sectors + spans-1) / spans;
uint64_t newstart = num_sectors - newsize, newend = num_sectors - 1; uint64_t newstart = num_sectors - newsize, newend = num_sectors - 1;
pout("Span %d changed from %"PRIu64"-%"PRIu64" (%"PRIu64" sectors)\n", pout("Span %d changed from %" PRIu64 "-%" PRIu64 " (%" PRIu64 " sectors)\n",
i, start, end, oldsize); i, start, end, oldsize);
pout(" to %"PRIu64"-%"PRIu64" (%"PRIu64" sectors) (%"PRIu64" spans)\n", pout(" to %" PRIu64 "-%" PRIu64 " (%" PRIu64 " sectors) (%" PRIu64 " spans)\n",
newstart, newend, newsize, spans); newstart, newend, newsize, spans);
start = newstart; end = newend; start = newstart; end = newend;
} }
@ -1293,7 +1293,7 @@ int ataWriteSelectiveSelfTestLog(ata_device * device, ata_selective_selftest_arg
end = num_sectors - 1; end = num_sectors - 1;
} }
if (!(start <= end && end < num_sectors)) { if (!(start <= end && end < num_sectors)) {
pout("Invalid selective self-test span %d: %"PRIu64"-%"PRIu64" (%"PRIu64" sectors)\n", pout("Invalid selective self-test span %d: %" PRIu64 "-%" PRIu64 " (%" PRIu64 " sectors)\n",
i, start, end, num_sectors); i, start, end, num_sectors);
return -1; return -1;
} }
@ -1476,11 +1476,12 @@ bool ataReadExtErrorLog(ata_device * device, ata_smart_exterrlog * log,
if (isbigendian()) { if (isbigendian()) {
swapx(&log->device_error_count); swapx(&log->device_error_count);
swapx(&log->error_log_index); swapx(&log->error_log_index);
for (unsigned i = 0; i < nsectors; i++) { for (unsigned i = 0; i < nsectors; i++) {
for (unsigned j = 0; j < 4; j++) for (unsigned j = 0; j < 4; j++) {
swapx(&log->error_logs[i].commands[j].timestamp); for (unsigned k = 0; k < 5; k++)
swapx(&log->error_logs[i].error.timestamp); swapx(&log[i].error_logs[j].commands[k].timestamp);
swapx(&log[i].error_logs[j].error.timestamp);
}
} }
} }
@ -1648,7 +1649,7 @@ int ataSmartTest(ata_device * device, int testtype, bool force,
int i; int i;
pout("SPAN STARTING_LBA ENDING_LBA\n"); pout("SPAN STARTING_LBA ENDING_LBA\n");
for (i = 0; i < selargs_io.num_spans; i++) for (i = 0; i < selargs_io.num_spans; i++)
pout(" %d %20"PRId64" %20"PRId64"\n", i, pout(" %d %20" PRId64 " %20" PRId64 "\n", i,
selargs_io.span[i].start, selargs_io.span[i].start,
selargs_io.span[i].end); selargs_io.span[i].end);
} }
@ -1869,7 +1870,8 @@ static ata_attr_raw_format get_default_raw_format(unsigned char id)
case 196: // Reallocated event count case 196: // Reallocated event count
return RAWFMT_RAW16_OPT_RAW16; return RAWFMT_RAW16_OPT_RAW16;
case 9: // Power on hours case 9: // Power on hours
case 240: // Head flying hours
return RAWFMT_RAW24_OPT_RAW8; return RAWFMT_RAW24_OPT_RAW8;
case 190: // Temperature case 190: // Temperature
@ -1926,6 +1928,33 @@ uint64_t ata_get_attr_raw_value(const ata_smart_attribute & attr,
return rawvalue; return rawvalue;
} }
// Helper functions for RAWFMT_TEMPMINMAX
static inline int check_temp_word(unsigned word)
{
if (word <= 0x7f)
return 0x11; // >= 0, signed byte or word
if (word <= 0xff)
return 0x01; // < 0, signed byte
if (0xff80 <= word)
return 0x10; // < 0, signed word
return 0x00;
}
static bool check_temp_range(int t, unsigned char ut1, unsigned char ut2,
int & lo, int & hi)
{
int t1 = (signed char)ut1, t2 = (signed char)ut2;
if (t1 > t2) {
int tx = t1; t1 = t2; t2 = tx;
}
if ( -60 <= t1 && t1 <= t && t <= t2 && t2 <= 120
&& !(t1 == -1 && t2 <= 0) ) {
lo = t1; hi = t2;
return true;
}
return false;
}
// Format attribute raw value. // Format attribute raw value.
std::string ata_format_attr_raw_value(const ata_smart_attribute & attr, std::string ata_format_attr_raw_value(const ata_smart_attribute & attr,
@ -1967,19 +1996,19 @@ std::string ata_format_attr_raw_value(const ata_smart_attribute & attr,
case RAWFMT_RAW48: case RAWFMT_RAW48:
case RAWFMT_RAW56: case RAWFMT_RAW56:
case RAWFMT_RAW64: case RAWFMT_RAW64:
s = strprintf("%"PRIu64, rawvalue); s = strprintf("%" PRIu64, rawvalue);
break; break;
case RAWFMT_HEX48: case RAWFMT_HEX48:
s = strprintf("0x%012"PRIx64, rawvalue); s = strprintf("0x%012" PRIx64, rawvalue);
break; break;
case RAWFMT_HEX56: case RAWFMT_HEX56:
s = strprintf("0x%014"PRIx64, rawvalue); s = strprintf("0x%014" PRIx64, rawvalue);
break; break;
case RAWFMT_HEX64: case RAWFMT_HEX64:
s = strprintf("0x%016"PRIx64, rawvalue); s = strprintf("0x%016" PRIx64, rawvalue);
break; break;
case RAWFMT_RAW16_OPT_RAW16: case RAWFMT_RAW16_OPT_RAW16:
@ -2016,7 +2045,7 @@ std::string ata_format_attr_raw_value(const ata_smart_attribute & attr,
int64_t temp = word[0]+(word[1]<<16); int64_t temp = word[0]+(word[1]<<16);
int64_t tmp1 = temp/60; int64_t tmp1 = temp/60;
int64_t tmp2 = temp%60; int64_t tmp2 = temp%60;
s = strprintf("%"PRIu64"h+%02"PRIu64"m", tmp1, tmp2); s = strprintf("%" PRIu64 "h+%02" PRIu64 "m", tmp1, tmp2);
if (word[2]) if (word[2])
s += strprintf(" (%u)", word[2]); s += strprintf(" (%u)", word[2]);
} }
@ -2028,7 +2057,7 @@ std::string ata_format_attr_raw_value(const ata_smart_attribute & attr,
int64_t hours = rawvalue/3600; int64_t hours = rawvalue/3600;
int64_t minutes = (rawvalue-3600*hours)/60; int64_t minutes = (rawvalue-3600*hours)/60;
int64_t seconds = rawvalue%60; int64_t seconds = rawvalue%60;
s = strprintf("%"PRIu64"h+%02"PRIu64"m+%02"PRIu64"s", hours, minutes, seconds); s = strprintf("%" PRIu64 "h+%02" PRIu64 "m+%02" PRIu64 "s", hours, minutes, seconds);
} }
break; break;
@ -2037,7 +2066,7 @@ std::string ata_format_attr_raw_value(const ata_smart_attribute & attr,
// 30-second counter // 30-second counter
int64_t hours = rawvalue/120; int64_t hours = rawvalue/120;
int64_t minutes = (rawvalue-120*hours)/2; int64_t minutes = (rawvalue-120*hours)/2;
s += strprintf("%"PRIu64"h+%02"PRIu64"m", hours, minutes); s += strprintf("%" PRIu64 "h+%02" PRIu64 "m", hours, minutes);
} }
break; break;
@ -2056,34 +2085,63 @@ std::string ata_format_attr_raw_value(const ata_smart_attribute & attr,
// Temperature // Temperature
{ {
// Search for possible min/max values // Search for possible min/max values
// 00 HH 00 LL 00 TT (Hitachi/IBM) // [5][4][3][2][1][0] raw[]
// 00 00 HH LL 00 TT (Maxtor, Samsung) // [ 2 ] [ 1 ] [ 0 ] word[]
// xx HH xx LL xx TT (Hitachi/HGST)
// xx LL xx HH xx TT (Kingston SSDs)
// 00 00 HH LL xx TT (Maxtor, Samsung, Seagate, Toshiba)
// 00 00 00 HH LL TT (WDC) // 00 00 00 HH LL TT (WDC)
unsigned char lo = 0, hi = 0; // CC CC HH LL xx TT (WDC, CCCC=over temperature count)
int cnt = 0; // (xx = 00/ff, possibly sign extension of lower byte)
for (int i = 1; i < 6; i++) {
if (raw[i])
switch (cnt++) {
case 0:
lo = raw[i];
break;
case 1:
if (raw[i] < lo) {
hi = lo; lo = raw[i];
}
else
hi = raw[i];
break;
}
}
unsigned char t = raw[0]; int t = (signed char)raw[0];
if (cnt == 0) int lo = 0, hi = 0;
s = strprintf("%d", t);
else if (cnt == 2 && 0 < lo && lo <= t && t <= hi && hi < 128) int tformat;
s = strprintf("%d (Min/Max %d/%d)", t, lo, hi); int ctw0 = check_temp_word(word[0]);
if (!word[2]) {
if (!word[1] && ctw0)
// 00 00 00 00 xx TT
tformat = 0;
else if (ctw0 && check_temp_range(t, raw[2], raw[3], lo, hi))
// 00 00 HL LH xx TT
tformat = 1;
else if (!raw[3] && check_temp_range(t, raw[1], raw[2], lo, hi))
// 00 00 00 HL LH TT
tformat = 2;
else
tformat = -1;
}
else if (ctw0) {
if ( (ctw0 & check_temp_word(word[1]) & check_temp_word(word[2])) != 0x00
&& check_temp_range(t, raw[2], raw[4], lo, hi) )
// xx HL xx LH xx TT
tformat = 3;
else if ( word[2] < 0x7fff
&& check_temp_range(t, raw[2], raw[3], lo, hi)
&& hi >= 40 )
// CC CC HL LH xx TT
tformat = 4;
else
tformat = -2;
}
else else
s = strprintf("%d (%d %d %d %d %d)", t, raw[5], raw[4], raw[3], raw[2], raw[1]); tformat = -3;
switch (tformat) {
case 0:
s = strprintf("%d", t);
break;
case 1: case 2: case 3:
s = strprintf("%d (Min/Max %d/%d)", t, lo, hi);
break;
case 4:
s = strprintf("%d (Min/Max %d/%d #%d)", t, lo, hi, word[2]);
break;
default:
s = strprintf("%d (%d %d %d %d %d)", raw[0], raw[5], raw[4], raw[3], raw[2], raw[1]);
break;
}
} }
break; break;
@ -2380,13 +2438,11 @@ int ataReadSCTStatus(ata_device * device, ata_sct_status_response * sts)
return 0; return 0;
} }
// Read SCT Temperature History Table and Status // Read SCT Temperature History Table
int ataReadSCTTempHist(ata_device * device, ata_sct_temperature_history_table * tmh, int ataReadSCTTempHist(ata_device * device, ata_sct_temperature_history_table * tmh,
ata_sct_status_response * sts) ata_sct_status_response * sts)
{ {
// Check initial status // Initial SCT status must be provided by caller
if (ataReadSCTStatus(device, sts))
return -1;
// Do nothing if other SCT command is executing // Do nothing if other SCT command is executing
if (sts->ext_status_code == 0xffff) { if (sts->ext_status_code == 0xffff) {
@ -2491,7 +2547,7 @@ int ataGetSetSCTWriteCacheReordering(ata_device * device, bool enable, bool pers
ata_cmd_out out; ata_cmd_out out;
if (!device->ata_pass_through(in, out)) { if (!device->ata_pass_through(in, out)) {
pout("Write SCT (%cet) XXX Error Recovery Control Command failed: %s\n", pout("Write SCT (%cet) Feature Control Command failed: %s\n",
(!set ? 'G' : 'S'), device->get_errmsg()); (!set ? 'G' : 'S'), device->get_errmsg());
return -1; return -1;
} }
@ -2729,7 +2785,7 @@ int ataPrintSmartSelfTestEntry(unsigned testnum, unsigned char test_type,
char msglba[32]; char msglba[32];
if (retval < 0 && failing_lba < 0xffffffffffffULL) if (retval < 0 && failing_lba < 0xffffffffffffULL)
snprintf(msglba, sizeof(msglba), "%"PRIu64, failing_lba); snprintf(msglba, sizeof(msglba), "%" PRIu64, failing_lba);
else { else {
msglba[0] = '-'; msglba[1] = 0; msglba[0] = '-'; msglba[1] = 0;
} }
@ -2753,7 +2809,7 @@ int ataPrintSmartSelfTestlog(const ata_smart_selftestlog * data, bool allentries
pout("Warning: ATA Specification requires self-test log structure revision number = 1\n"); pout("Warning: ATA Specification requires self-test log structure revision number = 1\n");
if (data->mostrecenttest==0){ if (data->mostrecenttest==0){
if (allentries) if (allentries)
pout("No self-tests have been logged. [To run self-tests, use: smartctl -t]\n\n"); pout("No self-tests have been logged. [To run self-tests, use: smartctl -t]\n");
return 0; return 0;
} }

View File

@ -18,7 +18,7 @@
#include "config.h" #include "config.h"
#include "ataidentify.h" #include "ataidentify.h"
const char * ataidentify_cpp_cvsid = "$Id: ataidentify.cpp 3785 2013-03-07 21:58:05Z chrfranke $" const char * ataidentify_cpp_cvsid = "$Id: ataidentify.cpp 3851 2013-08-17 20:10:11Z chrfranke $"
ATAIDENTIFY_H_CVSID; ATAIDENTIFY_H_CVSID;
#include "int64.h" #include "int64.h"
@ -683,9 +683,9 @@ void ata_print_identify_data(const void * id, bool all_words, int bit_level)
if (word + 1 == word2 && strstr(desc, "(DWord)")) if (word + 1 == word2 && strstr(desc, "(DWord)"))
pout(" (%u)\n", ((unsigned)get_word(id, word2) << 16) | w); pout(" (%u)\n", ((unsigned)get_word(id, word2) << 16) | w);
else if (word + 3 == word2 && strstr(desc, "(QWord)")) else if (word + 3 == word2 && strstr(desc, "(QWord)"))
pout(" (%"PRIu64")\n", ((uint64_t)get_word(id, word + 3) << 48) pout(" (%" PRIu64 ")\n", ((uint64_t)get_word(id, word + 3) << 48)
| ((uint64_t)get_word(id, word + 2) << 32) | ((uint64_t)get_word(id, word + 2) << 32)
| ((unsigned)get_word(id, word + 1) << 16) | (unsigned)w); | ((unsigned)get_word(id, word + 1) << 16) | (unsigned)w);
else else
pout("\n"); pout("\n");
} }

View File

@ -4,7 +4,7 @@
* Home page of code is: http://smartmontools.sourceforge.net * Home page of code is: http://smartmontools.sourceforge.net
* *
* Copyright (C) 2002-11 Bruce Allen <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2002-11 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2008-13 Christian Franke <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2008-14 Christian Franke <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org> * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -40,7 +40,7 @@
#include "utility.h" #include "utility.h"
#include "knowndrives.h" #include "knowndrives.h"
const char * ataprint_cpp_cvsid = "$Id: ataprint.cpp 3831 2013-07-20 14:25:56Z chrfranke $" const char * ataprint_cpp_cvsid = "$Id: ataprint.cpp 3982 2014-08-16 21:07:19Z samm2 $"
ATAPRINT_H_CVSID; ATAPRINT_H_CVSID;
@ -380,7 +380,7 @@ static std::string format_st_er_desc(
lba48 |= lba48_regs->lba_mid_register; lba48 |= lba48_regs->lba_mid_register;
lba48 <<= 8; lba48 <<= 8;
lba48 |= lba48_regs->lba_low_register; lba48 |= lba48_regs->lba_low_register;
str += strprintf(" at LBA = 0x%08"PRIx64" = %"PRIu64, lba48, lba48); str += strprintf(" at LBA = 0x%08" PRIx64 " = %" PRIu64, lba48, lba48);
} }
} }
@ -565,7 +565,7 @@ static void print_drive_info(const ata_identify_device * drive,
unsigned oui = 0; uint64_t unique_id = 0; unsigned oui = 0; uint64_t unique_id = 0;
int naa = ata_get_wwn(drive, oui, unique_id); int naa = ata_get_wwn(drive, oui, unique_id);
if (naa >= 0) if (naa >= 0)
pout("LU WWN Device Id: %x %06x %09"PRIx64"\n", naa, oui, unique_id); pout("LU WWN Device Id: %x %06x %09" PRIx64 "\n", naa, oui, unique_id);
// Additional Product Identifier (OEM Id) string in words 170-173 // Additional Product Identifier (OEM Id) string in words 170-173
// (e08130r1, added in ACS-2 Revision 1, December 17, 2008) // (e08130r1, added in ACS-2 Revision 1, December 17, 2008)
@ -607,6 +607,24 @@ static void print_drive_info(const ata_identify_device * drive,
pout("Rotation Rate: Unknown (0x%04x)\n", -rpm); pout("Rotation Rate: Unknown (0x%04x)\n", -rpm);
} }
// Print form factor if reported
unsigned short word168 = drive->words088_255[168-88];
if (word168) {
const char * inches;
switch (word168) {
case 0x1: inches = "5.25"; break;
case 0x2: inches = "3.5"; break;
case 0x3: inches = "2.5"; break;
case 0x4: inches = "1.8"; break;
case 0x5: inches = "< 1.8"; break;
default : inches = 0;
}
if (inches)
pout("Form Factor: %s inches\n", inches);
else
pout("Form Factor: Unknown (0x%04x)\n", word168);
}
// See if drive is recognized // See if drive is recognized
pout("Device is: %s\n", !dbentry ? pout("Device is: %s\n", !dbentry ?
"Not in smartctl database [for details use: -P showall]": "Not in smartctl database [for details use: -P showall]":
@ -1124,7 +1142,7 @@ static const char * GetLogName(unsigned logaddr)
case 0x09: return "Selective self-test log"; case 0x09: return "Selective self-test log";
case 0x0a: return "Device Statistics Notification"; // ACS-3 case 0x0a: return "Device Statistics Notification"; // ACS-3
case 0x0b: return "Reserved for CFA"; // ACS-3 case 0x0b: return "Reserved for CFA"; // ACS-3
case 0x0c: return "Pending Defects log"; // ACS-4
case 0x0d: return "LPS Mis-alignment log"; // ACS-2 case 0x0d: return "LPS Mis-alignment log"; // ACS-2
case 0x10: return "NCQ Command Error log"; case 0x10: return "NCQ Command Error log";
@ -1133,7 +1151,8 @@ static const char * GetLogName(unsigned logaddr)
case 0x13: return "SATA NCQ Send and Receive log"; // ACS-3 case 0x13: return "SATA NCQ Send and Receive log"; // ACS-3
case 0x14: case 0x14:
case 0x15: case 0x15:
case 0x16: return "Reserved for Serial ATA"; case 0x16:
case 0x17: return "Reserved for Serial ATA";
case 0x19: return "LBA Status log"; // ACS-3 case 0x19: return "LBA Status log"; // ACS-3
@ -1162,7 +1181,7 @@ static const char * GetLogName(unsigned logaddr)
static const char * get_log_rw(unsigned logaddr) static const char * get_log_rw(unsigned logaddr)
{ {
if ( ( logaddr <= 0x08) if ( ( logaddr <= 0x08)
|| (0x0d == logaddr) || (0x0c <= logaddr && logaddr <= 0x0d)
|| (0x10 <= logaddr && logaddr <= 0x13) || (0x10 <= logaddr && logaddr <= 0x13)
|| (0x19 == logaddr) || (0x19 == logaddr)
|| (0x20 <= logaddr && logaddr <= 0x25) || (0x20 <= logaddr && logaddr <= 0x25)
@ -1421,6 +1440,12 @@ static void print_device_statistics_page(const unsigned char * data, int page,
if (!(flags & 0x80)) if (!(flags & 0x80))
continue; continue;
// Stop if unknown entries contain garbage data due to buggy firmware
if (!info && (data[offset+5] || data[offset+6])) {
pout("%3d 0x%03x - - [Trailing garbage ignored]\n", page, offset);
break;
}
// Get value size, default to max if unknown // Get value size, default to max if unknown
int size = (info ? info[i].size : 7); int size = (info ? info[i].size : 7);
@ -1437,7 +1462,7 @@ static void print_device_statistics_page(const unsigned char * data, int page,
for (int j = 0; j < size; j++) for (int j = 0; j < size; j++)
val |= (int64_t)data[offset+j] << (j*8); val |= (int64_t)data[offset+j] << (j*8);
} }
snprintf(valstr, sizeof(valstr), "%"PRId64, val); snprintf(valstr, sizeof(valstr), "%" PRId64, val);
} }
else { else {
// Value not known (yet) // Value not known (yet)
@ -1457,11 +1482,18 @@ static void print_device_statistics_page(const unsigned char * data, int page,
} }
static bool print_device_statistics(ata_device * device, unsigned nsectors, static bool print_device_statistics(ata_device * device, unsigned nsectors,
const std::vector<int> & single_pages, bool all_pages, bool ssd_page) const std::vector<int> & single_pages, bool all_pages, bool ssd_page,
bool use_gplog)
{ {
// Read list of supported pages from page 0 // Read list of supported pages from page 0
unsigned char page_0[512] = {0, }; unsigned char page_0[512] = {0, };
if (!ataReadLogExt(device, 0x04, 0, 0, page_0, 1)) { int rc;
if (use_gplog)
rc = ataReadLogExt(device, 0x04, 0, 0, page_0, 1);
else
rc = ataReadSmartLog(device, 0x04, page_0, 1);
if (!rc) {
pout("Read Device Statistics page 0 failed\n\n"); pout("Read Device Statistics page 0 failed\n\n");
return false; return false;
} }
@ -1500,7 +1532,8 @@ static bool print_device_statistics(ata_device * device, unsigned nsectors,
// Print list of supported pages if requested // Print list of supported pages if requested
if (print_page_0) { if (print_page_0) {
pout("Device Statistics (GP Log 0x04) supported pages\n"); pout("Device Statistics (%s Log 0x04) supported pages\n",
use_gplog ? "GP" : "SMART");
pout("Page Description\n"); pout("Page Description\n");
for (i = 0; i < nentries; i++) { for (i = 0; i < nentries; i++) {
int page = page_0[8+1+i]; int page = page_0[8+1+i];
@ -1512,18 +1545,35 @@ static bool print_device_statistics(ata_device * device, unsigned nsectors,
// Read & print pages // Read & print pages
if (!pages.empty()) { if (!pages.empty()) {
pout("Device Statistics (GP Log 0x04)\n"); pout("Device Statistics (%s Log 0x04)\n",
use_gplog ? "GP" : "SMART");
pout("Page Offset Size Value Description\n"); pout("Page Offset Size Value Description\n");
bool need_trailer = false; bool need_trailer = false;
int max_page = 0;
if (!use_gplog)
for (i = 0; i < pages.size(); i++) {
int page = pages[i];
if (max_page < page && page < 0xff)
max_page = page;
}
raw_buffer pages_buf((max_page+1) * 512);
if (!use_gplog && !ataReadSmartLog(device, 0x04, pages_buf.data(), max_page+1)) {
pout("Read Device Statistics pages 0-%d failed\n\n", max_page);
return false;
}
for (i = 0; i < pages.size(); i++) { for (i = 0; i < pages.size(); i++) {
int page = pages[i]; int page = pages[i];
unsigned char page_n[512] = {0, }; if (use_gplog && !ataReadLogExt(device, 0x04, 0, page, pages_buf.data(), 1)) {
if (!ataReadLogExt(device, 0x04, 0, page, page_n, 1)) {
pout("Read Device Statistics page %d failed\n\n", page); pout("Read Device Statistics page %d failed\n\n", page);
return false; return false;
} }
print_device_statistics_page(page_n, page, need_trailer);
int offset = (use_gplog ? 0 : page * 512);
print_device_statistics_page(pages_buf.data() + offset, page, need_trailer);
} }
if (need_trailer) if (need_trailer)
@ -1595,7 +1645,7 @@ static void PrintSataPhyEventCounters(const unsigned char * data, bool reset)
} }
// Counters stop at max value, add '+' in this case // Counters stop at max value, add '+' in this case
pout("0x%04x %u %12"PRIu64"%c %s\n", id, size, val, pout("0x%04x %u %12" PRIu64 "%c %s\n", id, size, val,
(val == max_val ? '+' : ' '), name); (val == max_val ? '+' : ' '), name);
} }
if (reset) if (reset)
@ -2034,9 +2084,9 @@ static void ataPrintSelectiveSelfTestLog(const ata_selective_self_test_log * log
// we need at least 7 characters wide fields to accomodate the // we need at least 7 characters wide fields to accomodate the
// labels // labels
if ((field1=snprintf(tmp,64, "%"PRIu64, maxl))<7) if ((field1=snprintf(tmp,64, "%" PRIu64, maxl))<7)
field1=7; field1=7;
if ((field2=snprintf(tmp,64, "%"PRIu64, maxr))<7) if ((field2=snprintf(tmp,64, "%" PRIu64, maxr))<7)
field2=7; field2=7;
// now print the five test spans // now print the five test spans
@ -2048,19 +2098,19 @@ static void ataPrintSelectiveSelfTestLog(const ata_selective_self_test_log * log
if ((i+1)==(int)log->currentspan) if ((i+1)==(int)log->currentspan)
// this span is currently under test // this span is currently under test
pout(" %d %*"PRIu64" %*"PRIu64" %s [%01d0%% left] (%"PRIu64"-%"PRIu64")\n", pout(" %d %*" PRIu64 " %*" PRIu64 " %s [%01d0%% left] (%" PRIu64 "-%" PRIu64 ")\n",
i+1, field1, start, field2, end, msg, i+1, field1, start, field2, end, msg,
(int)(sv->self_test_exec_status & 0xf), current, currentend); (int)(sv->self_test_exec_status & 0xf), current, currentend);
else else
// this span is not currently under test // this span is not currently under test
pout(" %d %*"PRIu64" %*"PRIu64" Not_testing\n", pout(" %d %*" PRIu64 " %*" PRIu64 " Not_testing\n",
i+1, field1, start, field2, end); i+1, field1, start, field2, end);
} }
// if we are currently read-scanning, print LBAs and the status of // if we are currently read-scanning, print LBAs and the status of
// the read scan // the read scan
if (log->currentspan>5) if (log->currentspan>5)
pout("%5d %*"PRIu64" %*"PRIu64" Read_scanning %s\n", pout("%5d %*" PRIu64 " %*" PRIu64 " Read_scanning %s\n",
(int)log->currentspan, field1, current, field2, currentend, (int)log->currentspan, field1, current, field2, currentend,
OfflineDataCollectionStatus(sv->offline_data_collection_status)); OfflineDataCollectionStatus(sv->offline_data_collection_status));
@ -2431,7 +2481,12 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
); );
// SMART and GP log directories needed ? // SMART and GP log directories needed ?
bool need_smart_logdir = options.smart_logdir; bool need_smart_logdir = (
options.smart_logdir
|| options.devstat_all_pages // devstat fallback to smartlog if needed
|| options.devstat_ssd_page
|| !options.devstat_pages.empty()
);
bool need_gp_logdir = ( bool need_gp_logdir = (
options.gp_logdir options.gp_logdir
@ -2618,35 +2673,22 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
if (options.get_security) if (options.get_security)
print_ata_security_status("ATA Security is: ", drive.words088_255[128-88]); print_ata_security_status("ATA Security is: ", drive.words088_255[128-88]);
// Check if SCT commands available // Print write cache reordering status
bool sct_ok = false; if (options.sct_wcache_reorder_get) {
if (need_sct_support) { if (isSCTFeatureControlCapable(&drive)) {
if (!isSCTCapable(&drive)) { int wcache_reorder = ataGetSetSCTWriteCacheReordering(device,
failuretest(OPTIONAL_CMD, returnval|=FAILSMART); false /*enable*/, false /*persistent*/, false /*set*/);
if (-1 <= wcache_reorder && wcache_reorder <= 2)
pout("Wt Cache Reorder: %s\n",
(wcache_reorder == -1 ? "Unknown (SCT Feature Control command failed)" :
wcache_reorder == 0 ? "Unknown" : // not defined in standard but returned on some drives if not set
wcache_reorder == 1 ? "Enabled" : "Disabled"));
else
pout("Wt Cache Reorder: Unknown (0x%02x)\n", wcache_reorder);
} }
else else
sct_ok = true; pout("Wt Cache Reorder: Unavailable\n");
}
// Print write cache reordering status
if (sct_ok && options.sct_wcache_reorder_get) {
int wcache_reorder=ataGetSetSCTWriteCacheReordering(device,
false /* enable */, false /* persistent */, false /*set*/);
pout("Wt Cache Reorder: ");
switch(wcache_reorder) {
case 0: /* not defined in standard but returned on some drives if not set */
pout("Unknown"); break;
case 1:
pout("Enabled"); break;
case 2:
pout("Disabled"); break;
default: /* error? */
pout("N/A"); break;
}
pout("\n");
}
if (!sct_ok && options.sct_wcache_reorder_get) {
pout("Wt Cache Reorder: Unavailable\n");
} }
// Print remaining drive info // Print remaining drive info
@ -2733,15 +2775,15 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
} }
// Enable/Disable write cache reordering // Enable/Disable write cache reordering
if (sct_ok && options.sct_wcache_reorder_set) { if (options.sct_wcache_reorder_set) {
bool enable = (options.sct_wcache_reorder_set > 0); bool enable = (options.sct_wcache_reorder_set > 0);
if (!isSCTFeatureControlCapable(&drive))
int wcache_reorder=ataGetSetSCTWriteCacheReordering(device, pout("Write cache reordering %sable failed: SCT Feature Control command not supported\n",
enable, false /* persistent */, true /*set*/); (enable ? "en" : "dis"));
else if (ataGetSetSCTWriteCacheReordering(device,
if (wcache_reorder < 0) { enable, false /*persistent*/, true /*set*/) < 0) {
pout("Write cache reordering %sable failed: %s\n", (enable ? "en" : "dis"), device->get_errmsg()); pout("Write cache reordering %sable failed: %s\n", (enable ? "en" : "dis"), device->get_errmsg());
returnval |= FAILSMART; returnval |= FAILSMART;
} }
else else
pout("Write cache reordering %sabled\n", (enable ? "en" : "dis")); pout("Write cache reordering %sabled\n", (enable ? "en" : "dis"));
@ -2941,7 +2983,11 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
// The ATA SMART RETURN STATUS command provides the result in the ATA output // 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 // registers. Buggy ATA/SATA drivers and SAT Layers often do not properly
// return the registers values. // return the registers values.
pout("SMART Status %s: %s\n",
(device->is_syscall_unsup() ? "not supported" : "command failed"),
device->get_errmsg());
failuretest(OPTIONAL_CMD, returnval|=FAILSMART); failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
if (!(smart_val_ok && smart_thres_ok)) { if (!(smart_val_ok && smart_thres_ok)) {
print_on(); print_on();
pout("SMART overall-health self-assessment test result: UNKNOWN!\n" pout("SMART overall-health self-assessment test result: UNKNOWN!\n"
@ -2951,6 +2997,7 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
print_on(); print_on();
pout("SMART overall-health self-assessment test result: FAILED!\n" pout("SMART overall-health self-assessment test result: FAILED!\n"
"Drive failure expected in less than 24 hours. SAVE ALL DATA.\n"); "Drive failure expected in less than 24 hours. SAVE ALL DATA.\n");
pout("Warning: This result is based on an Attribute check.\n");
print_off(); print_off();
returnval|=FAILATTR; returnval|=FAILATTR;
returnval|=FAILSTATUS; returnval|=FAILSTATUS;
@ -3217,6 +3264,8 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
} }
} }
// Check if SCT commands available
bool sct_ok = isSCTCapable(&drive);
if(!sct_ok && (options.sct_temp_sts || options.sct_temp_hist || options.sct_temp_int if(!sct_ok && (options.sct_temp_sts || options.sct_temp_hist || options.sct_temp_int
|| options.sct_erc_get || options.sct_erc_set )) || options.sct_erc_get || options.sct_erc_set ))
pout("SCT Commands not supported\n\n"); pout("SCT Commands not supported\n\n");
@ -3224,35 +3273,41 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
// Print SCT status and temperature history table // Print SCT status and temperature history table
if (sct_ok && (options.sct_temp_sts || options.sct_temp_hist || options.sct_temp_int)) { if (sct_ok && (options.sct_temp_sts || options.sct_temp_hist || options.sct_temp_int)) {
for (;;) { for (;;) {
if (options.sct_temp_sts || options.sct_temp_hist) { bool sct_temp_hist_ok = isSCTDataTableCapable(&drive);
ata_sct_status_response sts; ata_sct_status_response sts;
ata_sct_temperature_history_table tmh;
if (!options.sct_temp_hist) { if (options.sct_temp_sts || (options.sct_temp_hist && sct_temp_hist_ok)) {
// Read SCT status only // Read SCT status
if (ataReadSCTStatus(device, &sts)) { if (ataReadSCTStatus(device, &sts)) {
failuretest(OPTIONAL_CMD, returnval|=FAILSMART); pout("\n");
break; failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
} break;
} }
else { if (options.sct_temp_sts) {
if (!isSCTDataTableCapable(&drive)) {
pout("SCT Data Table command not supported\n\n");
failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
break;
}
// Read SCT status and temperature history
if (ataReadSCTTempHist(device, &tmh, &sts)) {
pout("Read SCT Temperature History failed\n\n");
failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
break;
}
}
if (options.sct_temp_sts)
ataPrintSCTStatus(&sts); ataPrintSCTStatus(&sts);
if (options.sct_temp_hist) pout("\n");
ataPrintSCTTempHist(&tmh); }
}
if (!sct_temp_hist_ok && (options.sct_temp_hist || options.sct_temp_int)) {
pout("SCT Data Table command not supported\n\n");
failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
break;
}
if (options.sct_temp_hist) {
// Read SCT temperature history,
// requires initial SCT status from above
ata_sct_temperature_history_table tmh;
if (ataReadSCTTempHist(device, &tmh, &sts)) {
pout("Read SCT Temperature History failed\n\n");
failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
break;
}
ataPrintSCTTempHist(&tmh);
pout("\n"); pout("\n");
} }
if (options.sct_temp_int) { if (options.sct_temp_int) {
// Set new temperature logging interval // Set new temperature logging interval
if (!isSCTFeatureControlCapable(&drive)) { if (!isSCTFeatureControlCapable(&drive)) {
@ -3319,11 +3374,18 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
// Print Device Statistics // Print Device Statistics
if (options.devstat_all_pages || options.devstat_ssd_page || !options.devstat_pages.empty()) { if (options.devstat_all_pages || options.devstat_ssd_page || !options.devstat_pages.empty()) {
unsigned nsectors = GetNumLogSectors(gplogdir, 0x04, true); bool use_gplog = true;
unsigned nsectors = 0;
if (gplogdir)
nsectors = GetNumLogSectors(gplogdir, 0x04, false);
else if (smartlogdir){ // for systems without ATA_READ_LOG_EXT
nsectors = GetNumLogSectors(smartlogdir, 0x04, false);
use_gplog = false;
}
if (!nsectors) if (!nsectors)
pout("Device Statistics (GP Log 0x04) not supported\n\n"); pout("Device Statistics (GP/SMART Log 0x04) not supported\n\n");
else if (!print_device_statistics(device, nsectors, options.devstat_pages, else if (!print_device_statistics(device, nsectors, options.devstat_pages,
options.devstat_all_pages, options.devstat_ssd_page)) options.devstat_all_pages, options.devstat_ssd_page, use_gplog))
failuretest(OPTIONAL_CMD, returnval|=FAILSMART); failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
} }

View File

@ -1,11 +1,17 @@
#!/bin/sh #!/bin/sh
# $Id: autogen.sh 3829 2013-07-08 15:13:16Z samm2 $ # $Id: autogen.sh 3917 2014-06-20 19:57:41Z chrfranke $
# #
# Generate ./configure from config.in and Makefile.in from Makefile.am. # Generate ./configure from config.in and Makefile.in from Makefile.am.
# This also adds files like missing,depcomp,install-sh to the source # This also adds files like missing,depcomp,install-sh to the source
# directory. To update these files at a later date use: # directory. To update these files at a later date use:
# autoreconf -f -i -v # autoreconf -f -i -v
force=; warnings=
while [ $# -gt 0 ]; do case $1 in
--force) force=$1; shift ;;
--warnings=?*) warnings="${warnings} $1"; shift ;;
*) echo "Usage: $0 [--force] [--warnings=CATEGORY ...]"; exit 1 ;;
esac; done
# Cygwin? # Cygwin?
test -x /usr/bin/uname && /usr/bin/uname | grep -i CYGWIN >/dev/null && test -x /usr/bin/uname && /usr/bin/uname | grep -i CYGWIN >/dev/null &&
@ -32,19 +38,21 @@ typep()
return 1 return 1
} }
test -x "$AUTOMAKE" || AUTOMAKE=`typep automake-1.12` || test -x "$AUTOMAKE" ||
AUTOMAKE=`typep automake-1.14` ||
AUTOMAKE=`typep automake-1.13` || AUTOMAKE=`typep automake-1.12` ||
AUTOMAKE=`typep automake-1.11` || AUTOMAKE=`typep automake-1.10` || AUTOMAKE=`typep automake-1.11` || AUTOMAKE=`typep automake-1.10` ||
AUTOMAKE=`typep automake-1.9` || AUTOMAKE=`typep automake-1.8` || AUTOMAKE=`typep automake-1.9` || AUTOMAKE=`typep automake-1.8` ||
AUTOMAKE=`typep automake-1.7` || AUTOMAKE=`typep automake17` || AUTOMAKE=`typep automake-1.7` || AUTOMAKE=`typep automake17` ||
{ {
echo echo
echo "You must have at least GNU Automake 1.7 (up to 1.11) installed" echo "You must have at least GNU Automake 1.7 (up to 1.14) installed"
echo "in order to bootstrap smartmontools from SVN. Download the" echo "in order to bootstrap smartmontools from SVN. Download the"
echo "appropriate package for your distribution, or the source tarball" echo "appropriate package for your distribution, or the source tarball"
echo "from ftp://ftp.gnu.org/gnu/automake/ ." echo "from ftp://ftp.gnu.org/gnu/automake/ ."
echo echo
echo "Also note that support for new Automake series (anything newer" echo "Also note that support for new Automake series (anything newer"
echo "than 1.11) is only added after extensive tests. If you live in" echo "than 1.14) is only added after extensive tests. If you live in"
echo "the bleeding edge, you should know what you're doing, mainly how" echo "the bleeding edge, you should know what you're doing, mainly how"
echo "to test it before the developers. Be patient." echo "to test it before the developers. Be patient."
exit 1; exit 1;
@ -70,6 +78,7 @@ case "$AUTOMAKE" in
esac esac
# Warn if Automake version was not tested or does not support filesystem # Warn if Automake version was not tested or does not support filesystem
amwarnings=$warnings
case "$ver" in case "$ver" in
1.[78]|1.[78].*) 1.[78]|1.[78].*)
# Check for case sensitive filesystem # Check for case sensitive filesystem
@ -84,10 +93,16 @@ case "$ver" in
rm -f casetest.tmp rm -f casetest.tmp
;; ;;
1.9.[1-6]|1.10|1.10.[12]|1.11|1.11.[1-6]|1.12.[2-5]) 1.9.[1-6]|1.10|1.10.[123]|1.11|1.11.[1-6]|1.12.[2-6]|1.13.[34])
# OK # OK
;; ;;
1.14|1.14.1)
# TODO: Enable 'subdir-objects' in configure.ac
# For now, suppress 'subdir-objects' forward-incompatibility warning
test -n "$warnings" || amwarnings="--warnings=no-unsupported"
;;
*) *)
echo "Note: GNU Automake version ${ver} was not tested by the developers." echo "Note: GNU Automake version ${ver} was not tested by the developers."
echo "Please report success/failure to the smartmontools-support mailing list." echo "Please report success/failure to the smartmontools-support mailing list."
@ -96,6 +111,7 @@ esac
# Install pkg-config macros # Install pkg-config macros
# (Don't use 'aclocal -I m4 --install' to keep support for automake < 1.10) # (Don't use 'aclocal -I m4 --install' to keep support for automake < 1.10)
test -d m4 || mkdir m4 || exit 1 test -d m4 || mkdir m4 || exit 1
test -z "$force" || rm -f m4/pkg.m4
test -f m4/pkg.m4 || acdir=`${ACLOCAL} --print-ac-dir` && test -f m4/pkg.m4 || acdir=`${ACLOCAL} --print-ac-dir` &&
test -n "$acdir" && test -f "$acdir/pkg.m4" && test -n "$acdir" && test -f "$acdir/pkg.m4" &&
{ {
@ -107,7 +123,9 @@ test -f m4/pkg.m4 ||
set -e # stops on error status set -e # stops on error status
${ACLOCAL} -I m4 test -z "$warnings" || set -x
autoheader
${AUTOMAKE} --add-missing --copy ${ACLOCAL} -I m4 $force $warnings
autoconf autoheader $force $warnings
${AUTOMAKE} --add-missing --copy ${force:+--force-missing} $amwarnings
autoconf $force $warnings

View File

@ -5,7 +5,7 @@
#include "config.h" #include "config.h"
#if defined(linux) #if defined(linux) || defined(__linux__)
# include <sys/ioctl.h> # include <sys/ioctl.h>
# ifdef HAVE_LINUX_COMPILER_H # ifdef HAVE_LINUX_COMPILER_H
# include <linux/compiler.h> # include <linux/compiler.h>
@ -38,7 +38,7 @@
#include "scsicmds.h" #include "scsicmds.h"
#include "utility.h" #include "utility.h"
const char * cciss_cpp_cvsid = "$Id: cciss.cpp 3578 2012-07-20 17:26:32Z chrfranke $" const char * cciss_cpp_cvsid = "$Id: cciss.cpp 3945 2014-07-13 15:29:05Z chrfranke $"
CCISS_H_CVSID; CCISS_H_CVSID;
typedef struct _ReportLUNdata_struct typedef struct _ReportLUNdata_struct

View File

@ -1,30 +1,28 @@
# #
# $Id: configure.ac 3841 2013-07-26 17:38:57Z chrfranke $ # $Id: configure.ac 3977 2014-07-26 11:03:24Z chrfranke $
# #
dnl Process this file with autoconf to produce a configure script. dnl Process this file with autoconf to produce a configure script.
AC_PREREQ(2.50) AC_PREREQ(2.50)
AC_INIT(smartmontools, 6.2, smartmontools-support@lists.sourceforge.net) AC_INIT(smartmontools, 6.4, smartmontools-support@lists.sourceforge.net)
AC_CONFIG_SRCDIR(smartctl.cpp) AC_CONFIG_SRCDIR(smartctl.cpp)
smartmontools_configure_date=`date -u +'%Y-%m-%d %T %Z'` smartmontools_cvs_tag=`echo '$Id: configure.ac 3977 2014-07-26 11:03:24Z chrfranke $'`
smartmontools_cvs_tag=`echo '$Id: configure.ac 3841 2013-07-26 17:38:57Z chrfranke $'` smartmontools_release_date=2014-07-26
smartmontools_release_date=2013-07-26 smartmontools_release_time="09:49:11 UTC"
smartmontools_release_time="17:38:20 UTC"
AC_DEFINE_UNQUOTED(SMARTMONTOOLS_CONFIGURE_ARGS, "$ac_configure_args", [smartmontools Configure Arguments]) AC_DEFINE_UNQUOTED(SMARTMONTOOLS_CONFIGURE_ARGS, "$ac_configure_args", [smartmontools Configure Arguments])
AC_DEFINE_UNQUOTED(SMARTMONTOOLS_CONFIGURE_DATE, "$smartmontools_configure_date", [smartmontools Configure Date])
AC_DEFINE_UNQUOTED(SMARTMONTOOLS_RELEASE_DATE, "$smartmontools_release_date", [smartmontools Release Date]) AC_DEFINE_UNQUOTED(SMARTMONTOOLS_RELEASE_DATE, "$smartmontools_release_date", [smartmontools Release Date])
AC_DEFINE_UNQUOTED(SMARTMONTOOLS_RELEASE_TIME, "$smartmontools_release_time", [smartmontools Release Time]) AC_DEFINE_UNQUOTED(SMARTMONTOOLS_RELEASE_TIME, "$smartmontools_release_time", [smartmontools Release Time])
AC_DEFINE_UNQUOTED(CONFIG_H_CVSID, "$smartmontools_cvs_tag", [smartmontools CVS Tag]) AC_DEFINE_UNQUOTED(CONFIG_H_CVSID, "$smartmontools_cvs_tag", [smartmontools CVS Tag])
AC_DEFINE_UNQUOTED(PACKAGE_HOMEPAGE, "http://smartmontools.sourceforge.net/", [smartmontools Home Page]) AC_DEFINE_UNQUOTED(PACKAGE_HOMEPAGE, "http://smartmontools.sourceforge.net/", [smartmontools Home Page])
AM_CONFIG_HEADER(config.h) AC_CONFIG_HEADER([config.h])
AM_INIT_AUTOMAKE([foreign]) AM_INIT_AUTOMAKE([foreign])
AM_MAINTAINER_MODE AM_MAINTAINER_MODE
AC_LANG_CPLUSPLUS AC_LANG([C++])
dnl Checks for programs. dnl Checks for programs.
AC_PROG_CXX AC_PROG_CXX
AM_PROG_AS AM_PROG_AS
@ -43,15 +41,10 @@ AC_ARG_VAR(MAKENSIS, [NSIS compiler command])
AC_CANONICAL_HOST AC_CANONICAL_HOST
case "${host}" in case "${host}" in
*-*-mingw*) *-*-mingw*)
# Cygwin gcc 4.x does no longer support '-mno-cygwin' to select MinGW gcc.
if test "${build}" = "${host}" && test -x /usr/bin/uname && \
/usr/bin/uname | grep -i '^CYGWIN' >/dev/null; then
AC_MSG_ERROR([Build with MinGW on Cygwin requires cross-compilation, see INSTALL file.])
fi
AC_CHECK_TOOL(WINDMC, [windmc]) AC_CHECK_TOOL(WINDMC, [windmc])
AC_CHECK_TOOL(WINDRES, [windres]) AC_CHECK_TOOL(WINDRES, [windres])
AC_MSG_CHECKING([checking for makensis]) AC_MSG_CHECKING([for makensis])
if test -z "$MAKENSIS"; then if test -z "$MAKENSIS"; then
if test -n "$PROGRAMFILES" && "$PROGRAMFILES/NSIS/makensis" -VERSION >/dev/null 2>&1; then if test -n "$PROGRAMFILES" && "$PROGRAMFILES/NSIS/makensis" -VERSION >/dev/null 2>&1; then
MAKENSIS="$PROGRAMFILES/NSIS/makensis" MAKENSIS="$PROGRAMFILES/NSIS/makensis"
@ -138,19 +131,6 @@ AC_CHECK_FUNCS([clock_gettime ftime gettimeofday])
# Check byte ordering (defines WORDS_BIGENDIAN) # Check byte ordering (defines WORDS_BIGENDIAN)
AC_C_BIGENDIAN AC_C_BIGENDIAN
# Check whether snprintf appends null char and returns expected length on overflow
AC_MSG_CHECKING([for working snprintf])
AC_RUN_IFELSE([AC_LANG_PROGRAM([[#include <stdio.h>]], [[ char buf[]="ABCDEFGHI";
int i=snprintf(buf,8,"12345678"); return !(!buf[7] && i==8); ]])],
[libc_have_working_snprintf=yes],
[libc_have_working_snprintf=no],
[libc_have_working_snprintf=unknown])
AC_SUBST(libc_have_working_snprintf)
if test "$libc_have_working_snprintf" = "yes"; then
AC_DEFINE(HAVE_WORKING_SNPRINTF, 1, [Define to 1 if the `snprintf' function is sane])
fi
AC_MSG_RESULT([$libc_have_working_snprintf])
# check for __attribute__((packed)) # check for __attribute__((packed))
# (sizeof() check is required to avoid false positives if other # (sizeof() check is required to avoid false positives if other
# __attribute__((x)) are supported) # __attribute__((x)) are supported)
@ -169,16 +149,23 @@ AC_SUBST(CPPFLAGS)
AC_SUBST(LDFLAGS) AC_SUBST(LDFLAGS)
AC_SUBST(ASFLAGS) AC_SUBST(ASFLAGS)
AC_ARG_WITH(systemdenvfile,
[AS_HELP_STRING([--with-systemdenvfile=@<:@FILE|no@:>@],
[Path of systemd EnvironmentFile (implies --with-systemdsystemunitdir=yes) [SYSCONFDIR/sysconfig/smartmontools]])],
[systemdenvfile=; test "$withval" != "no" && systemdenvfile="$withval"; systemd_default=yes],
[systemdenvfile='${sysconfdir}/sysconfig/smartmontools'; systemd_default=auto])
AC_SUBST(systemdenvfile)
AC_ARG_WITH(systemdsystemunitdir, AC_ARG_WITH(systemdsystemunitdir,
[AS_HELP_STRING([--with-systemdsystemunitdir@<:@=DIR|auto|yes|no@:>@], [Location of systemd service files [auto]])], [AS_HELP_STRING([--with-systemdsystemunitdir@<:@=DIR|auto|yes|no@:>@], [Location of systemd service files [auto]])],
[], [with_systemdsystemunitdir=auto]) [], [with_systemdsystemunitdir=$systemd_default])
systemdsystemunitdir= systemdsystemunitdir=
case "$with_systemdsystemunitdir" in case "$with_systemdsystemunitdir" in
auto|yes) auto|yes)
if test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG"; then
AC_MSG_CHECKING([for systemdsystemunitdir]) AC_MSG_CHECKING([for systemdsystemunitdir])
systemdsystemunitdir=`$PKG_CONFIG --variable=systemdsystemunitdir systemd` systemdsystemunitdir=`$PKG_CONFIG --variable=systemdsystemunitdir systemd 2>/dev/null`
AC_MSG_RESULT([${systemdsystemunitdir:-no}]) AC_MSG_RESULT([${systemdsystemunitdir:-no}])
fi fi
case "$with_systemdsystemunitdir:$sysconfdir:$systemdsystemunitdir" in case "$with_systemdsystemunitdir:$sysconfdir:$systemdsystemunitdir" in
@ -193,7 +180,7 @@ AC_SUBST(systemdsystemunitdir)
AM_CONDITIONAL(INSTALL_SYSTEMDUNIT, [test -n "$systemdsystemunitdir"]) AM_CONDITIONAL(INSTALL_SYSTEMDUNIT, [test -n "$systemdsystemunitdir"])
AC_ARG_WITH(initscriptdir, AC_ARG_WITH(initscriptdir,
[AC_HELP_STRING([--with-initscriptdir@<:@=DIR|auto|yes|no@:>@], [Location of init scripts [auto]])], [AS_HELP_STRING([--with-initscriptdir@<:@=DIR|auto|yes|no@:>@], [Location of init scripts [auto]])],
[], [with_initscriptdir=auto]) [], [with_initscriptdir=auto])
initddir= initddir=
@ -228,7 +215,7 @@ esac
AC_SUBST(initdfile) AC_SUBST(initdfile)
AC_ARG_WITH(docdir, AC_ARG_WITH(docdir,
[AC_HELP_STRING([--with-docdir=DIR],[Location of documentation [DATADIR/doc/smartmontools]])], [AS_HELP_STRING([--with-docdir=DIR], [Location of documentation [DATADIR/doc/smartmontools]])],
[docdir="$withval"], [docdir="$withval"],
[ if test -z "$docdir"; then [ if test -z "$docdir"; then
# autoconf 2.5x without '--docdir' support # autoconf 2.5x without '--docdir' support
@ -238,25 +225,38 @@ AC_ARG_WITH(docdir,
AC_SUBST(docdir) AC_SUBST(docdir)
AC_ARG_WITH(exampledir, AC_ARG_WITH(exampledir,
[AC_HELP_STRING([--with-exampledir=DIR],[Location of example scripts [DOCDIR/examplescripts]])], [AS_HELP_STRING([--with-exampledir=DIR], [Location of example scripts [DOCDIR/examplescripts]])],
[exampledir="$withval"], [exampledir='${docdir}/examplescripts']) [exampledir="$withval"], [exampledir='${docdir}/examplescripts'])
AC_SUBST(exampledir) AC_SUBST(exampledir)
AC_ARG_ENABLE(drivedb, AC_ARG_ENABLE(drivedb,
[AC_HELP_STRING([--disable-drivedb],[Disables drive database file])], [AS_HELP_STRING([--disable-drivedb], [Disables drive database file])],
[], [enable_drivedb=yes]) [], [enable_drivedb=yes])
AC_ARG_WITH(drivedbdir, AC_ARG_WITH(drivedbdir,
[AC_HELP_STRING([--with-drivedbdir=DIR],[Location of drive database file (implies --enable-drivedb) [DATADIR/smartmontools]])], [AS_HELP_STRING([--with-drivedbdir=DIR], [Location of drive database file [DATADIR/smartmontools]])],
[drivedbdir="$withval"; enable_drivedb=yes], [drivedbdir="$withval"; enable_drivedb=yes],
[drivedbdir=; test "$enable_drivedb" = "yes" && drivedbdir='${datadir}/${PACKAGE}']) [drivedbdir=; test "$enable_drivedb" = "yes" && drivedbdir='${datadir}/${PACKAGE}'])
AC_SUBST(drivedbdir) AC_SUBST(drivedbdir)
AM_CONDITIONAL(ENABLE_DRIVEDB, [test "$enable_drivedb" = "yes"]) AM_CONDITIONAL(ENABLE_DRIVEDB, [test "$enable_drivedb" = "yes"])
AC_ARG_ENABLE(savestates, [AC_HELP_STRING([--enable-savestates],[Enables default smartd state files])]) AC_ARG_WITH(smartdscriptdir,
[AS_HELP_STRING([--with-smartdscriptdir=DIR], [Location of smartd_warning.sh script [SYSCONFDIR]])],
[smartdscriptdir="$withval"], [smartdscriptdir='${sysconfdir}'])
AC_SUBST(smartdscriptdir)
AC_ARG_WITH(smartdplugindir,
[AS_HELP_STRING([--with-smartdplugindir=@<:@DIR|no@:>@],
[Location of smartd_warning.sh plugin scripts [SMARTDSCRIPTDIR/smartd_warning.d]])],
[smartdplugindir=; test "$withval" != "no" && smartdplugindir="$withval"],
[smartdplugindir='${smartdscriptdir}/smartd_warning.d'])
AC_SUBST(smartdplugindir)
AC_ARG_ENABLE(savestates, [AS_HELP_STRING([--enable-savestates], [Enables default smartd state files])])
AC_ARG_WITH(savestates, AC_ARG_WITH(savestates,
[AC_HELP_STRING([--with-savestates=PREFIX],[Prefix for default smartd state files (implies --enable-savestates) [LOCALSTATEDIR/lib/smartmontools/smartd.]])], [AS_HELP_STRING([--with-savestates=PREFIX],
[Prefix for default smartd state files (implies --enable-savestates) [LOCALSTATEDIR/lib/smartmontools/smartd.]])],
[savestates="$withval"; enable_savestates="yes"], [savestates="$withval"; enable_savestates="yes"],
[savestates=; test "$enable_savestates" = "yes" && savestates='${localstatedir}/lib/${PACKAGE}/smartd.']) [savestates=; test "$enable_savestates" = "yes" && savestates='${localstatedir}/lib/${PACKAGE}/smartd.'])
savestatesdir="${savestates%/*}" savestatesdir="${savestates%/*}"
@ -264,10 +264,11 @@ AC_SUBST(savestates)
AC_SUBST(savestatesdir) AC_SUBST(savestatesdir)
AM_CONDITIONAL(ENABLE_SAVESTATES, [test "$enable_savestates" = "yes"]) AM_CONDITIONAL(ENABLE_SAVESTATES, [test "$enable_savestates" = "yes"])
AC_ARG_ENABLE(attributelog, [AC_HELP_STRING([--enable-attributelog],[Enables default smartd attribute log files])]) AC_ARG_ENABLE(attributelog, [AS_HELP_STRING([--enable-attributelog], [Enables default smartd attribute log files])])
AC_ARG_WITH(attributelog, AC_ARG_WITH(attributelog,
[AC_HELP_STRING([--with-attributelog=PREFIX],[Prefix for default smartd attribute log files (implies --enable-attributelog) [LOCALSTATEDIR/lib/smartmontools/attrlog.]])], [AS_HELP_STRING([--with-attributelog=PREFIX],
[Prefix for default smartd attribute log files (implies --enable-attributelog) [LOCALSTATEDIR/lib/smartmontools/attrlog.]])],
[attributelog="$withval"; enable_attributelog="yes"], [attributelog="$withval"; enable_attributelog="yes"],
[attributelog=; test "$enable_attributelog" = "yes" && attributelog='${localstatedir}/lib/${PACKAGE}/attrlog.']) [attributelog=; test "$enable_attributelog" = "yes" && attributelog='${localstatedir}/lib/${PACKAGE}/attrlog.'])
attributelogdir="${attributelog%/*}" attributelogdir="${attributelog%/*}"
@ -276,13 +277,13 @@ AC_SUBST(attributelogdir)
AM_CONDITIONAL(ENABLE_ATTRIBUTELOG, [test "$enable_attributelog" = "yes"]) AM_CONDITIONAL(ENABLE_ATTRIBUTELOG, [test "$enable_attributelog" = "yes"])
AC_ARG_ENABLE(sample, AC_ARG_ENABLE(sample,
[AC_HELP_STRING([--enable-sample],[Enables appending .sample to the installed smartd rc script and configuration file])], [AS_HELP_STRING([--enable-sample], [Enables appending .sample to the installed smartd rc script and configuration file])],
[smartd_suffix=; test "$enableval" = "yes" && smartd_suffix=".sample"], [smartd_suffix=; test "$enableval" = "yes" && smartd_suffix=".sample"],
[smartd_suffix=;]) [smartd_suffix=;])
AC_SUBST(smartd_suffix) AC_SUBST(smartd_suffix)
AC_ARG_WITH(os-deps, AC_ARG_WITH(os-deps,
[AC_HELP_STRING([--with-os-deps='os_module.o ...'],[Specify OS dependent module(s) [guessed]])], [AS_HELP_STRING([--with-os-deps='os_module.o ...'], [Specify OS dependent module(s) [guessed]])],
[ for x in $with_os_deps; do [ for x in $with_os_deps; do
case $x in case $x in
*.o) ;; *.o) ;;
@ -292,7 +293,7 @@ AC_ARG_WITH(os-deps,
],[]) ],[])
AC_ARG_WITH(selinux, AC_ARG_WITH(selinux,
[AC_HELP_STRING([--with-selinux@<:@=yes|no@:>@],[Enables SELinux support [no]])], [AS_HELP_STRING([--with-selinux@<:@=yes|no@:>@], [Enables SELinux support [no]])],
[ if test "$withval" = "yes"; then [ if test "$withval" = "yes"; then
AC_CHECK_HEADERS([selinux/selinux.h], [], [AC_MSG_ERROR([Missing SELinux header files])]) AC_CHECK_HEADERS([selinux/selinux.h], [], [AC_MSG_ERROR([Missing SELinux header files])])
AC_CHECK_LIB(selinux, matchpathcon, [], [AC_MSG_ERROR([Missing or incorrect SELinux library files])]) AC_CHECK_LIB(selinux, matchpathcon, [], [AC_MSG_ERROR([Missing or incorrect SELinux library files])])
@ -304,7 +305,7 @@ if test "$with_selinux" = "yes"; then
fi fi
AC_ARG_WITH(libcap-ng, AC_ARG_WITH(libcap-ng,
[AC_HELP_STRING([--with-libcap-ng@<:@=auto|yes|no@:>@],[Add Libcap-ng support to smartd [auto]])], [AS_HELP_STRING([--with-libcap-ng@<:@=auto|yes|no@:>@], [Add Libcap-ng support to smartd [auto]])],
[], [with_libcap_ng=auto]) [], [with_libcap_ng=auto])
use_libcap_ng=no use_libcap_ng=no
@ -325,6 +326,40 @@ AC_SUBST(CAPNG_LDADD)
AM_CONDITIONAL(ENABLE_CAPABILITIES, [test "$use_libcap_ng" = "yes"]) AM_CONDITIONAL(ENABLE_CAPABILITIES, [test "$use_libcap_ng" = "yes"])
AC_MSG_RESULT([$use_libcap_ng]) AC_MSG_RESULT([$use_libcap_ng])
# Assume broken snprintf only on Windows with MSVCRT (MinGW without ANSI stdio support)
libc_have_working_snprintf=yes
case "$host" in
*-*-mingw*)
case " $CPPFLAGS $CXXFLAGS" in
*\ -[[DU]]__USE_MINGW_ANSI_STDIO*)
;;
*)
# Older MinGW do not properly define PRI?64 if __USE_MINGW_ANSI_STDIO is set
# Newer MinGW set __USE_MINGW_ANSI_STDIO in first C++ include which may be too late
AC_MSG_CHECKING([whether __USE_MINGW_ANSI_STDIO is defined by C++ includes])
AC_PREPROC_IFELSE([AC_LANG_SOURCE([[
#undef __USE_MINGW_ANSI_STDIO
#include <iostream>
#ifndef __USE_MINGW_ANSI_STDIO
#error false
#endif]])],
[CXXFLAGS="-D__USE_MINGW_ANSI_STDIO $CXXFLAGS"],
[libc_have_working_snprintf=no])
AC_MSG_RESULT([$libc_have_working_snprintf])
;;
esac ;;
esac
AC_ARG_WITH(working-snprintf,
[AS_HELP_STRING([--with-working-snprintf@<:@=yes|no@:>@],
[Function snprintf() handles output truncation as specified by C99 [MinGW:guessed,others:yes]])],
[libc_have_working_snprintf=$withval])
if test "$libc_have_working_snprintf" = "yes"; then
AC_DEFINE(HAVE_WORKING_SNPRINTF, 1, [Define to 1 if the `snprintf' function is sane])
fi
if test "$prefix" = "NONE"; then if test "$prefix" = "NONE"; then
dnl no prefix and no mandir, so use ${prefix}/share/man as default dnl no prefix and no mandir, so use ${prefix}/share/man as default
if test "$mandir" = '${prefix}/man'; then if test "$mandir" = '${prefix}/man'; then
@ -388,6 +423,7 @@ case "${host}" in
;; ;;
*-*-cygwin*) *-*-cygwin*)
os_deps='os_win32.o dev_areca.o' os_deps='os_win32.o dev_areca.o'
os_mailer='email'
os_hostname="'hostname' 'echo "'"${HOSTNAME?unset}"'"'" os_hostname="'hostname' 'echo "'"${HOSTNAME?unset}"'"'"
os_dnsdomainname="'dnsdomainname' 'hostname -d' 'echo "'"${USERDNSDOMAIN?unset}"'"'" os_dnsdomainname="'dnsdomainname' 'hostname -d' 'echo "'"${USERDNSDOMAIN?unset}"'"'"
os_nisdomainname= os_nisdomainname=
@ -548,7 +584,12 @@ case "$host_os" in
fi fi
echo "local drive database: `eval eval eval echo $sysconfdir`/smart_drivedb.h" >&AS_MESSAGE_FD 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 config file: `eval eval eval echo $sysconfdir`/smartd.conf${smartd_suffix}" >&AS_MESSAGE_FD
echo "smartd warning script: `eval eval eval echo $sysconfdir`/smartd_warning.sh" >&AS_MESSAGE_FD echo "smartd warning script: `eval eval eval echo $smartdscriptdir`/smartd_warning.sh" >&AS_MESSAGE_FD
if test -n "$smartdplugindir"; then
echo "smartd plugin path: `eval eval eval echo $smartdplugindir`" >&AS_MESSAGE_FD
else
echo "smartd plugin path: [[disabled]]" >&AS_MESSAGE_FD
fi
if test -n "$initddir"; then if test -n "$initddir"; then
echo "smartd initd script: `eval eval eval echo $initddir`/smartd${smartd_suffix}" >&AS_MESSAGE_FD echo "smartd initd script: `eval eval eval echo $initddir`/smartd${smartd_suffix}" >&AS_MESSAGE_FD
elif test -z "$systemdsystemunitdir"; then elif test -z "$systemdsystemunitdir"; then
@ -556,6 +597,11 @@ case "$host_os" in
fi fi
if test -n "$systemdsystemunitdir"; then if test -n "$systemdsystemunitdir"; then
echo "smartd systemd file: `eval eval eval echo $systemdsystemunitdir`/smartd.service" >&AS_MESSAGE_FD echo "smartd systemd file: `eval eval eval echo $systemdsystemunitdir`/smartd.service" >&AS_MESSAGE_FD
if test -n "$systemdenvfile"; then
echo "smartd environ file: `eval eval eval echo $systemdenvfile`" >&AS_MESSAGE_FD
else
echo "smartd environ file: [[disabled]]" >&AS_MESSAGE_FD
fi
fi fi
if test -n "$savestates"; then if test -n "$savestates"; then
echo "smartd save files: `eval eval eval echo $savestates`MODEL-SERIAL.TYPE.state" >&AS_MESSAGE_FD echo "smartd save files: `eval eval eval echo $savestates`MODEL-SERIAL.TYPE.state" >&AS_MESSAGE_FD

View File

@ -21,7 +21,7 @@
#include "dev_interface.h" #include "dev_interface.h"
#include "dev_areca.h" #include "dev_areca.h"
const char * dev_areca_cpp_cvsid = "$Id: dev_areca.cpp 3835 2013-07-20 18:37:19Z chrfranke $" const char * dev_areca_cpp_cvsid = "$Id: dev_areca.cpp 3872 2014-02-03 21:07:51Z chrfranke $"
DEV_ARECA_H_CVSID; DEV_ARECA_H_CVSID;
#include "atacmds.h" #include "atacmds.h"
@ -114,7 +114,10 @@ generic_areca_device::~generic_areca_device() throw()
// 1 if the command succeeded and disk SMART status is "FAILING" // 1 if the command succeeded and disk SMART status is "FAILING"
int generic_areca_device::arcmsr_command_handler(unsigned long arcmsr_cmd, unsigned char *data, int data_len) int generic_areca_device::arcmsr_command_handler(unsigned long arcmsr_cmd, unsigned char *data, int data_len)
{ {
unsigned int cmds[] = if (arcmsr_cmd >= ARCMSR_CMD_TOTAL)
return -1;
static const unsigned int cmds[ARCMSR_CMD_TOTAL] =
{ {
ARCMSR_IOCTL_READ_RQBUFFER, ARCMSR_IOCTL_READ_RQBUFFER,
ARCMSR_IOCTL_WRITE_WQBUFFER, ARCMSR_IOCTL_WRITE_WQBUFFER,
@ -145,11 +148,6 @@ int generic_areca_device::arcmsr_command_handler(unsigned long arcmsr_cmd, unsig
sBuf.srbioctl.Timeout = 10000; sBuf.srbioctl.Timeout = 10000;
sBuf.srbioctl.ControlCode = cmds[arcmsr_cmd]; sBuf.srbioctl.ControlCode = cmds[arcmsr_cmd];
if(arcmsr_cmd >= ARCMSR_CMD_TOTAL)
{
return -1;
}
switch ( arcmsr_cmd ) switch ( arcmsr_cmd )
{ {
// command for writing data to driver // command for writing data to driver

View File

@ -18,7 +18,7 @@
#ifndef DEV_ARECA_H #ifndef DEV_ARECA_H
#define DEV_ARECA_H #define DEV_ARECA_H
#define DEV_ARECA_H_CVSID "$Id: dev_areca.h 3763 2013-01-31 22:25:25Z chrfranke $" #define DEV_ARECA_H_CVSID "$Id: dev_areca.h 3854 2013-09-12 05:36:20Z chrfranke $"
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
/// Areca RAID support /// Areca RAID support
@ -58,7 +58,7 @@ ARCMSR_CMD_TOTAL
#define ARCMSR_IOCTL_CLEAR_RQBUFFER (ARECA_SATA_RAID | FUNCTION_CLEAR_RQBUFFER) #define ARCMSR_IOCTL_CLEAR_RQBUFFER (ARECA_SATA_RAID | FUNCTION_CLEAR_RQBUFFER)
#define ARCMSR_IOCTL_CLEAR_WQBUFFER (ARECA_SATA_RAID | FUNCTION_CLEAR_WQBUFFER) #define ARCMSR_IOCTL_CLEAR_WQBUFFER (ARECA_SATA_RAID | FUNCTION_CLEAR_WQBUFFER)
#define ARCMSR_IOCTL_RETURN_CODE_3F (ARECA_SATA_RAID | FUNCTION_RETURN_CODE_3F) #define ARCMSR_IOCTL_RETURN_CODE_3F (ARECA_SATA_RAID | FUNCTION_RETURN_CODE_3F)
#elif defined(__FreeBSD__) #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
#include <sys/ioctl.h> // _IOWR #include <sys/ioctl.h> // _IOWR
/*FunctionCode*/ /*FunctionCode*/

573
drivedb.h
View File

@ -4,7 +4,7 @@
* Home page of code is: http://smartmontools.sourceforge.net * Home page of code is: http://smartmontools.sourceforge.net
* *
* Copyright (C) 2003-11 Philip Williams, Bruce Allen * Copyright (C) 2003-11 Philip Williams, Bruce Allen
* Copyright (C) 2008-13 Christian Franke <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2008-14 Christian Franke <smartmontools-support@lists.sourceforge.net>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -75,7 +75,7 @@
/* /*
const drive_settings builtin_knowndrives[] = { const drive_settings builtin_knowndrives[] = {
*/ */
{ "$Id: drivedb.h 3840 2013-07-25 21:29:08Z chrfranke $", { "$Id: drivedb.h 3990 2014-09-29 17:59:37Z samm2 $",
"-", "-", "-", "-",
"This is a dummy entry to hold the SVN-Id of drivedb.h", "This is a dummy entry to hold the SVN-Id of drivedb.h",
"" ""
@ -144,7 +144,7 @@ const drive_settings builtin_knowndrives[] = {
"-v 232,raw48,Available_Reservd_Space " "-v 232,raw48,Available_Reservd_Space "
"-v 233,raw48,Media_Wearout_Indicator " // SSD only "-v 233,raw48,Media_Wearout_Indicator " // SSD only
// 234-239 Unknown_Attribute // 234-239 Unknown_Attribute
"-v 240,raw48,Head_Flying_Hours " // HDD only "-v 240,raw24(raw8),Head_Flying_Hours " // HDD only, smartmontools <= r3966: raw48
"-v 241,raw48,Total_LBAs_Written " "-v 241,raw48,Total_LBAs_Written "
"-v 242,raw48,Total_LBAs_Read " "-v 242,raw48,Total_LBAs_Read "
// 243-249 Unknown_Attribute // 243-249 Unknown_Attribute
@ -153,28 +153,42 @@ const drive_settings builtin_knowndrives[] = {
"-v 254,raw48,Free_Fall_Sensor " // HDD only "-v 254,raw48,Free_Fall_Sensor " // HDD only
*/ */
}, },
{ "Apple SSD SM128", // Samsung? { "Apacer SSD",
"APPLE SSD SM128", "(2|4|8|16|32)GB SATA Flash Drive", // tested with APSDM002G15AN-CT/SFDDA01C and SFI2101D, APSDM004G13AN-AT/SFDE001A
"", "", "" "SF(DDA01C|I2101D|DE001A)", "", // spec found at http://wfcache.advantech.com/www/certified-peripherals/documents/96fmcff-04g-cs-ap_Datasheet.pdf
},
{ "Apacer SDM4",
"2GB SATA Flash Drive", // tested with APSDM002G15AN-CT/SFI2101D
"SFI2101D", "",
"-v 160,raw48,Initial_Bad_Block_Count " "-v 160,raw48,Initial_Bad_Block_Count "
"-v 161,raw48,Bad_Block_Count " "-v 161,raw48,Bad_Block_Count "
"-v 162,raw48,Spare_Block_Count " "-v 162,raw48,Spare_Block_Count "
"-v 163,raw48,Max_Erase_Count " "-v 163,raw48,Max_Erase_Count "
"-v 164,raw48,Min_Erase_Count " // could be wrong "-v 164,raw48,Average_Erase_Count "
"-v 165,raw48,Average_Erase_Count " // could be wrong "-v 165,raw48,Average_Erase_Count " // could be wrong
"-v 166,raw48,Later_Bad_Block_Count "
"-v 167,raw48,SSD_Protect_Mode "
"-v 168,raw48,SATA_PHY_Err_Ct "
}, },
{ "Asus-Phison SSD", { "Apple SD/SM/TS...E/F SSDs", // SanDisk/Samsung/Toshiba?
"ASUS-PHISON SSD", "APPLE SSD (S[DM]|TS)0?(128|256|512|768)[EF]", // tested with APPLE SSD SD256E/1021AP, SD0128F/A223321
"", "", "" // APPLE SSD SM768E/CXM90A1Q, SM0512F/UXM2JA1Q, TS0256F/109L0704
"", "",
//"-v 1,raw48,Raw_Read_Error_Rate "
//"-v 5,raw16(raw16),Reallocated_Sector_Ct "
//"-v 9,raw24(raw8),Power_On_Hours "
//"-v 12,raw48,Power_Cycle_Count "
//"-v 169,raw48,Unknown_Attribute "
"-v 173,raw48,Wear_Leveling_Count " // ]
"-v 174,raw48,Host_Reads_MiB " // ] guessed (ticket #342), S[DM]*F only
"-v 175,raw48,Host_Writes_MiB " // ]
//"-v 192,raw48,Power-Off_Retract_Count "
//"-v 194,tempminmax,Temperature_Celsius "
//"-v 197,raw48,Current_Pending_Sector "
//"-v 199,raw48,UDMA_CRC_Error_Count "
//"-v 240,raw48,Unknown_SSD_Attribute "
}, },
{ "Crucial/Micron RealSSD C300/M500", // Marvell 88SS91xx { "Crucial/Micron RealSSD C300/M500", // Marvell 88SS91xx
"C300-CTFDDA[AC](064|128|256)MAG|" // Marvell 88SS9174 BJP2, tested with C300-CTFDDAC128MAG/0002, "C300-CTFDDA[AC](064|128|256)MAG|" // Marvell 88SS9174 BJP2, tested with C300-CTFDDAC128MAG/0002,
// C300-CTFDDAC064MAG/0006 // C300-CTFDDAC064MAG/0006
"Crucial_CT(120|240|480)M500SSD3", // Marvell 88SS9187 BLD2, tested with Crucial_CT120M500SSD3/MU02 "Crucial_CT(120|240|480)M500SSD[13]", // Marvell 88SS9187 BLD2, tested with Crucial_CT120M500SSD3/MU02,
// Crucial_CT120M500SSD1/MU02, Crucial_CT240M500SSD1/MU03, Crucial_CT480M500SSD1/MU03
"", "", "", "",
//"-v 1,raw48,Raw_Read_Error_Rate " //"-v 1,raw48,Raw_Read_Error_Rate "
//"-v 5,raw16(raw16),Reallocated_Sector_Ct " //"-v 5,raw16(raw16),Reallocated_Sector_Ct "
@ -197,12 +211,16 @@ const drive_settings builtin_knowndrives[] = {
//"-v 197,raw48,Current_Pending_Sector " //"-v 197,raw48,Current_Pending_Sector "
//"-v 198,raw48,Offline_Uncorrectable " //"-v 198,raw48,Offline_Uncorrectable "
//"-v 199,raw48,UDMA_CRC_Error_Count " //"-v 199,raw48,UDMA_CRC_Error_Count "
"-v 202,raw48,Perc_Rated_Life_Used " "-v 202,raw48,Percent_Lifetime_Used "
"-v 206,raw48,Write_Error_Rate" "-v 206,raw48,Write_Error_Rate "
"-v 210,raw48,Success_RAIN_Recov_Cnt "
"-v 246,raw48,Total_Host_Sector_Write "
"-v 247,raw48,Host_Program_Page_Count "
"-v 248,raw48,Bckgnd_Program_Page_Cnt"
}, },
{ "Crucial/Micron RealSSD m4/C400/P400", // Marvell 9176, fixed firmware { "Crucial/Micron RealSSD m4/C400/P400", // Marvell 9176, fixed firmware
"C400-MTFDDA[ACK](064|128|256|512)MAM|" "C400-MTFDDA[ACK](064|128|256|512)MAM|"
"M4-CT(064|128|256|512)M4SSD[23]|" // tested with M4-CT512M4SSD2/0309 "M4-CT(064|128|256|512)M4SSD[123]|" // tested with M4-CT512M4SSD2/0309
"MTFDDAK(064|128|256|512|050|100|200|400)MA[RN]-1[JKS]1AA.*", // tested with "MTFDDAK(064|128|256|512|050|100|200|400)MA[RN]-1[JKS]1AA.*", // tested with
// MTFDDAK256MAR-1K1AA/MA52 // MTFDDAK256MAR-1K1AA/MA52
"030[9-Z]|03[1-Z].|0[4-Z]..|[1-Z]....*", // >= "0309" "030[9-Z]|03[1-Z].|0[4-Z]..|[1-Z]....*", // >= "0309"
@ -233,7 +251,7 @@ const drive_settings builtin_knowndrives[] = {
}, },
{ "Crucial/Micron RealSSD m4/C400", // Marvell 9176, buggy or unknown firmware { "Crucial/Micron RealSSD m4/C400", // Marvell 9176, buggy or unknown firmware
"C400-MTFDDA[ACK](064|128|256|512)MAM|" // tested with C400-MTFDDAC256MAM/0002 "C400-MTFDDA[ACK](064|128|256|512)MAM|" // tested with C400-MTFDDAC256MAM/0002
"M4-CT(064|128|256|512)M4SSD[23]", // tested with M4-CT064M4SSD2/0002, "M4-CT(064|128|256|512)M4SSD[123]", // tested with M4-CT064M4SSD2/0002,
// M4-CT064M4SSD2/0009, M4-CT256M4SSD3/000F // M4-CT064M4SSD2/0009, M4-CT256M4SSD3/000F
"", "",
"This drive may hang after 5184 hours of power-on time:\n" "This drive may hang after 5184 hours of power-on time:\n"
@ -252,22 +270,83 @@ const drive_settings builtin_knowndrives[] = {
"-v 202,raw48,Perc_Rated_Life_Used " "-v 202,raw48,Perc_Rated_Life_Used "
"-v 206,raw48,Write_Error_Rate" "-v 206,raw48,Write_Error_Rate"
}, },
{ "Crucial/Micron MX100/M500/M510/M550 Client SSDs",
"Crucial_CT(128|256|512)MX100SSD1|"// tested with Crucial_CT256MX100SSD1/MU01
"Micron_M500_MTFDDA[KTV](120|240|480|960)MAV|"// tested with Micron_M500_MTFDDAK960MAV/MU05
"(Micron_)?M510[_-]MTFDDA[KTV](128|256)MAZ|" // tested with M510-MTFDDAK256MAZ/MU01
"(Micron_)?M550[_-]MTFDDA[KTV](064|128|256|512|1T0)MAY", // tested with M550-MTFDDAK256MAY/MU01
"", "",
//"-v 1,raw48,Raw_Read_Error_Rate "
"-v 5,raw48,Reallocate_NAND_Blk_Cnt "
//"-v 9,raw24(raw8),Power_On_Hours "
//"-v 12,raw48,Power_Cycle_Count "
"-v 171,raw48,Program_Fail_Count "
"-v 172,raw48,Erase_Fail_Count "
"-v 173,raw48,Ave_Block-Erase_Count "
"-v 174,raw48,Unexpect_Power_Loss_Ct "
"-v 180,raw48,Unused_Reserve_NAND_Blk "
"-v 183,raw48,SATA_Interfac_Downshift "
"-v 184,raw48,Error_Correction_Count "
//"-v 187,raw48,Reported_Uncorrect "
//"-v 194,tempminmax,Temperature_Celsius "
//"-v 196,raw16(raw16),Reallocated_Event_Count "
//"-v 197,raw48,Current_Pending_Sector "
//"-v 198,raw48,Offline_Uncorrectable "
//"-v 199,raw48,UDMA_CRC_Error_Count "
"-v 202,raw48,Percent_Lifetime_Used "
"-v 206,raw48,Write_Error_Rate "
"-v 210,raw48,Success_RAIN_Recov_Cnt "
"-v 246,raw48,Total_Host_Sector_Write "
"-v 247,raw48,Host_Program_Page_Count "
"-v 248,raw48,Bckgnd_Program_Page_Cnt"
},
{ "Micron M500DC Enterprise SSDs",
"Micron_M500DC_(EE|MT)FDDA[AK](120|240|480|800)MBB", // tested with
// Micron_M500DC_EEFDDAA120MBB/129, Micron_M500DC_MTFDDAK800MBB/0129
"", "",
//"-v 1,raw48,Raw_Read_Error_Rate "
"-v 5,raw48,Reallocated_Block_Count "
//"-v 9,raw24(raw8),Power_On_Hours "
//"-v 12,raw48,Power_Cycle_Count "
"-v 170,raw48,Reserved_Block_Count "
"-v 171,raw48,Program_Fail_Count "
"-v 172,raw48,Erase_Fail_Count "
"-v 173,raw48,Ave_Block-Erase_Count "
"-v 174,raw48,Unexpect_Power_Loss_Ct "
"-v 184,raw48,Error_Correction_Count "
//"-v 187,raw48,Reported_Uncorrect "
"-v 188,raw48,Command_Timeouts "
//"-v 194,tempminmax,Temperature_Celsius "
"-v 195,raw48,Cumulativ_Corrected_ECC "
//"-v 197,raw48,Current_Pending_Sector "
//"-v 198,raw48,Offline_Uncorrectable "
//"-v 199,raw48,UDMA_CRC_Error_Count "
"-v 202,raw48,Percent_Lifetime_Remain "
"-v 206,raw48,Write_Error_Rate "
"-v 247,raw48,Host_Program_Page_Count "
"-v 248,raw48,Bckgnd_Program_Page_Cnt"
},
{ "SandForce Driven SSDs", { "SandForce Driven SSDs",
"SandForce 1st Ed\\.|" // Demo Drive, tested with firmware 320A13F0 "SandForce 1st Ed\\.|" // Demo Drive, tested with firmware 320A13F0
"ADATA SSD S(396|510|599) .?..GB|" // tested with ADATA SSD S510 60GB/320ABBF0, "ADATA SSD S(396|510|599) .?..GB|" // tested with ADATA SSD S510 60GB/320ABBF0,
// ADATA SSD S599 256GB/3.1.0, 64GB/3.4.6 // ADATA SSD S599 256GB/3.1.0, 64GB/3.4.6
"ADATA SP900|" // Premier Pro, SF-2281, tested with ADATA SP900/5.0.6 "ADATA SP[389]00|" // tested with ADATA SP300/5.0.2d, SP800/5.0.6c,
// ADATA SP900/5.0.6 (Premier Pro, SF-2281)
"ADATA SSD SP900 (64|128|256)GB-DL2|" // tested with ADATA SSD SP900 256GB-DL2/5.0.6
"ADATA XM11 (128|256)GB|" // tested with ADATA XM11 128GB/5.0.1
"Corsair CSSD-F(40|60|80|115|120|160|240)GBP?2.*|" // Corsair Force, tested with "Corsair CSSD-F(40|60|80|115|120|160|240)GBP?2.*|" // Corsair Force, tested with
// Corsair CSSD-F40GB2/1.1, Corsair CSSD-F115GB2-A/2.1a // Corsair CSSD-F40GB2/1.1, Corsair CSSD-F115GB2-A/2.1a
"Corsair Force (3 SSD|GS|GT)|" // SF-2281, tested with "Corsair Force ((3 |LS )?SSD|GS|GT)|" // SF-2281, tested with
// Corsair Force 3 SSD/1.3.2, GT/1.3.3, GS/5.03 // Corsair Force SSD/5.05, 3 SSD/1.3.2, GT/1.3.3, GS/5.03, LS SSD/S8FM06.5
"FM-25S2S-(60|120|240)GBP2|" // G.SKILL Phoenix Pro, SF-1200, tested with "FM-25S2S-(60|120|240)GBP2|" // G.SKILL Phoenix Pro, SF-1200, tested with
// FM-25S2S-240GBP2/4.2 // FM-25S2S-240GBP2/4.2
"FTM(06|12|24|48)CT25H|" // Supertalent TeraDrive CT, tested with "FTM(06|12|24|48)CT25H|" // Supertalent TeraDrive CT, tested with
// FTM24CT25H/STTMP2P1 // FTM24CT25H/STTMP2P1
"KINGSTON SE50S3(100|240|480)G|" // tested with SE50S3100G/KE1ABBF0
"KINGSTON SH10[03]S3(90|120|240|480)G|" // HyperX (3K), SF-2281, tested with "KINGSTON SH10[03]S3(90|120|240|480)G|" // HyperX (3K), SF-2281, tested with
// SH100S3240G/320ABBF0, SH103S3120G/505ABBF0 // SH100S3240G/320ABBF0, SH103S3120G/505ABBF0
"KINGSTON SKC300S37A(60|120|240|480)G|" // SF-2281, tested with SKC300S37A120G/KC4ABBF0 "KINGSTON SKC(300S37A|380S3)(60|120|240|480)G|" // SF-2281, tested with SKC300S37A120G/KC4ABBF0,
// SKC380S3120G/507ABBF0
"KINGSTON SVP200S3(7A)?(60|90|120|240|480)G|" // V+ 200, SF-2281, tested with "KINGSTON SVP200S3(7A)?(60|90|120|240|480)G|" // V+ 200, SF-2281, tested with
// SVP200S37A480G/502ABBF0, SVP200S390G/332ABBF0 // SVP200S37A480G/502ABBF0, SVP200S390G/332ABBF0
"KINGSTON SMS200S3(30|60|120)G|" // mSATA, SF-2241, tested with SMS200S3120G/KC3ABBF0 "KINGSTON SMS200S3(30|60|120)G|" // mSATA, SF-2241, tested with SMS200S3120G/KC3ABBF0
@ -294,22 +373,26 @@ const drive_settings builtin_knowndrives[] = {
"(APOC|DENC|DENEVA|FTNC|GFGC|MANG|MMOC|NIMC|TMSC).*|" // other OCZ SF-1200, "(APOC|DENC|DENEVA|FTNC|GFGC|MANG|MMOC|NIMC|TMSC).*|" // other OCZ SF-1200,
// tested with DENCSTE251M11-0120/1.33, DENEVA PCI-E/1.33 // tested with DENCSTE251M11-0120/1.33, DENEVA PCI-E/1.33
"(DENR|DRSAK|EC188|NIMR|PSIR|TRSAK).*|" // other OCZ SF-1500 "(DENR|DRSAK|EC188|NIMR|PSIR|TRSAK).*|" // other OCZ SF-1500
"OWC Mercury Electra [36]G SSD|" // tested with "OWC Aura Pro 6G SSD|" // tested with OWC Aura Pro 6G SSD/507ABBF0
// OWC Mercury Electra 6G SSD/502ABBF0 "OWC Mercury Electra (Pro )?[36]G SSD|" // tested with
"OWC Mercury Extreme Pro (RE )?SSD|" // tested with // OWC Mercury Electra 6G SSD/502ABBF0, OWC Mercury Electra Pro 3G SSD/541ABBF0
// OWC Mercury Extreme Pro SSD/360A13F0 "OWC Mercury E(xtreme|XTREME) Pro (6G |RE )?SSD|" // tested with
"OWC Mercury EXTREME Pro 6G SSD|" // tested with // OWC Mercury Extreme Pro SSD/360A13F0, OWC Mercury EXTREME Pro 6G SSD/507ABBF0
// OWC Mercury EXTREME Pro 6G SSD/507ABBF0
"Patriot Pyro|" // tested with Patriot Pyro/332ABBF0 "Patriot Pyro|" // tested with Patriot Pyro/332ABBF0
"SanDisk SDSSDX(60|120|240|480)GG25|" // SanDisk Extreme, SF-2281, tested with "SanDisk SDSSDX(60|120|240|480)GG25|" // SanDisk Extreme, SF-2281, tested with
// SDSSDX240GG25/R201 // SDSSDX240GG25/R201
"SuperSSpeed S301 [0-9]*GB|" // SF-2281, tested with SuperSSpeed S301 128GB/503 "SuperSSpeed S301 [0-9]*GB|" // SF-2281, tested with SuperSSpeed S301 128GB/503
"SG9XCS2D(0?50|100|200|400)GESLT|" // Smart Storage Systems XceedIOPS2, tested with
// SG9XCS2D200GESLT/SA03L370
"SSD9SC(120|240|480)GED[EA]|" // PNY Prevail Elite, tested with SSD9SC120GEDA/334ABBF0
"(TX32|TX31C1|VN0.?..GCNMK).*|" // Smart Storage Systems XceedSTOR "(TX32|TX31C1|VN0.?..GCNMK).*|" // Smart Storage Systems XceedSTOR
"(TX22D1|TX21B1).*|" // Smart Storage Systems XceedIOPS2 "(TX22D1|TX21B1).*|" // Smart Storage Systems XceedIOPS2
"TX52D1.*|" // Smart Storage Systems Xcel-200 "TX52D1.*|" // Smart Storage Systems Xcel-200
"TS(64|128|256|512)GSSD320|" // Transcend SSD320, SF-2281, tested with TS128GSSD320 "TS(64|128|256|512)GSSD[37]20|" // Transcend SSD320/720, SF-2281, tested with
"UGB(88P|99S)GC...H[BF].", // Unigen, tested with // TS128GSSD320, TS256GSSD720/5.2.0
"UGB(88P|99S)GC...H[BF].|" // Unigen, tested with
// UGB88PGC100HF2/MP Rev2, UGB99SGC100HB3/RC Rev3 // UGB88PGC100HF2/MP Rev2, UGB99SGC100HB3/RC Rev3
"VisionTek GoDrive (60|120|240|480)GB", // tested with VisionTek GoDrive 480GB/506ABBF0
"", "", "", "",
"-v 1,raw24/raw32,Raw_Read_Error_Rate " "-v 1,raw24/raw32,Raw_Read_Error_Rate "
"-v 5,raw48,Retired_Block_Count " "-v 5,raw48,Retired_Block_Count "
@ -347,8 +430,8 @@ const drive_settings builtin_knowndrives[] = {
"Corsair CSSD-V(32|60|64|128|256)GB2|" // Corsair Nova, tested with Corsair CSSD-V32GB2/2.2 "Corsair CSSD-V(32|60|64|128|256)GB2|" // Corsair Nova, tested with Corsair CSSD-V32GB2/2.2
"CRUCIAL_CT(64|128|256)M225|" // tested with CRUCIAL_CT64M225/1571 "CRUCIAL_CT(64|128|256)M225|" // tested with CRUCIAL_CT64M225/1571
"G.SKILL FALCON (64|128|256)GB SSD|" // tested with G.SKILL FALCON 128GB SSD/2030 "G.SKILL FALCON (64|128|256)GB SSD|" // tested with G.SKILL FALCON 128GB SSD/2030
"OCZ[ -](AGILITY|ONYX|VERTEX( 1199|-TURBO)?)|" // tested with "OCZ[ -](AGILITY|ONYX|VERTEX( 1199|-TURBO| v1\\.10)?)|" // tested with
// OCZ-ONYX/1.6, OCZ-VERTEX 1199/00.P97, OCZ-VERTEX/1.30, OCZ VERTEX-TURBO/1.5 // OCZ-ONYX/1.6, OCZ-VERTEX 1199/00.P97, OCZ-VERTEX/1.30, OCZ VERTEX-TURBO/1.5, OCZ-VERTEX v1.10/1370
"Patriot[ -]Torqx.*|" "Patriot[ -]Torqx.*|"
"RENICE Z2|" // tested with RENICE Z2/2030 "RENICE Z2|" // tested with RENICE Z2/2030
"STT_FT[MD](28|32|56|64)GX25H|" // Super Talent Ultradrive GX, tested with STT_FTM64GX25H/1916 "STT_FT[MD](28|32|56|64)GX25H|" // Super Talent Ultradrive GX, tested with STT_FTM64GX25H/1916
@ -397,7 +480,8 @@ const drive_settings builtin_knowndrives[] = {
//"-v 233,raw48,Media_Wearout_Indicator" //"-v 233,raw48,Media_Wearout_Indicator"
}, },
{ "Indilinx Barefoot 3 based SSDs", { "Indilinx Barefoot 3 based SSDs",
"OCZ-VECTOR", // tested with OCZ-VECTOR/1.03 "OCZ-VECTOR|" // tested with OCZ-VECTOR/1.03
"OCZ-VERTEX450", // tested with OCZ-VERTEX450/1.0 (Barefoot 3 M10)
"", "", "" "", "", ""
"-v 5,raw48,Runtime_Bad_Block " "-v 5,raw48,Runtime_Bad_Block "
//"-v 9,raw24(raw8),Power_On_Hours " //"-v 9,raw24(raw8),Power_On_Hours "
@ -413,8 +497,44 @@ const drive_settings builtin_knowndrives[] = {
"-v 208,raw48,Average_Erase_Count " "-v 208,raw48,Average_Erase_Count "
"-v 210,raw48,SATA_CRC_Error_Count " "-v 210,raw48,SATA_CRC_Error_Count "
"-v 233,raw48,Remaining_Lifetime_Perc " "-v 233,raw48,Remaining_Lifetime_Perc "
"-v 241,raw48,Host_Writes_GiB " // M10
"-v 242,raw48,Host_Reads_GiB " // M10
"-v 249,raw48,Total_NAND_Prog_Ct_GiB" "-v 249,raw48,Total_NAND_Prog_Ct_GiB"
}, },
{ "OCZ Intrepid 3000 SSDs", // tested with OCZ INTREPID 3600/1.4.3.6, 3800/1.4.3.0
"OCZ INTREPID 3[68]00",
"", "", ""
"-v 5,raw48,Runtime_Bad_Block "
//"-v 9,raw24(raw8),Power_On_Hours "
//"-v 12,raw48,Power_Cycle_Count "
"-v 100,raw48,Total_Blocks_Erased "
"-v 171,raw48,Avail_OP_Block_Count "
"-v 174,raw48,Pwr_Cycle_Ct_Unplanned "
"-v 184,raw48,Factory_Bad_Block_Count "
"-v 187,raw48,Total_Unc_NAND_Reads "
"-v 190,tempminmax,Temperature_Celsius "
"-v 195,raw48,Total_Prog_Failures "
"-v 196,raw48,Total_Erase_Failures "
"-v 197,raw48,Total_Unc_Read_Failures "
"-v 198,raw48,Host_Reads_GiB "
"-v 199,raw48,Host_Writes_GiB "
"-v 202,raw48,Total_Read_Bits_Corr_Ct "
"-v 205,raw48,Max_Rated_PE_Count "
"-v 206,raw48,Min_Erase_Count "
"-v 207,raw48,Max_Erase_Count "
"-v 208,raw48,Average_Erase_Count "
"-v 210,raw48,SATA_CRC_Error_Count "
"-v 211,raw48,SATA_UNC_Count "
"-v 212,raw48,NAND_Reads_with_Retry "
"-v 213,raw48,Simple_Rd_Rtry_Attempts "
"-v 214,raw48,Adaptv_Rd_Rtry_Attempts "
"-v 221,raw48,Int_Data_Path_Prot_Unc "
"-v 222,raw48,RAID_Recovery_Count "
"-v 230,raw48,SuperCap_Charge_Status " // 0=not charged, 1=fully charged, 2=unknown
"-v 233,raw48,Remaining_Lifetime_Perc "
"-v 249,raw48,Total_NAND_Prog_Ct_GiB "
"-v 251,raw48,Total_NAND_Read_Ct_GiB"
},
{ "InnoDisk InnoLite SATADOM D150QV-L SSDs", // tested with InnoLite SATADOM D150QV-L/120319 { "InnoDisk InnoLite SATADOM D150QV-L SSDs", // tested with InnoLite SATADOM D150QV-L/120319
"InnoLite SATADOM D150QV-L", "InnoLite SATADOM D150QV-L",
"", "", "", "",
@ -528,8 +648,9 @@ const drive_settings builtin_knowndrives[] = {
"-v 242,raw48,Host_Reads_32MiB" "-v 242,raw48,Host_Reads_32MiB"
}, },
{ "Intel 320 Series SSDs", // tested with INTEL SSDSA2CT040G3/4PC10362, { "Intel 320 Series SSDs", // tested with INTEL SSDSA2CT040G3/4PC10362,
// INTEL SSDSA2CW160G3/4PC10362, INTEL SSDSA2BT040G3/4PC10362, INTEL SSDSA2BW120G3A/4PC10362 // INTEL SSDSA2CW160G3/4PC10362, INTEL SSDSA2BT040G3/4PC10362, INTEL SSDSA2BW120G3A/4PC10362,
"INTEL SSDSA[12][BC][WT](040|080|120|160|300|600)G3A?", // INTEL SSDSA2BW300G3D/4PC10362, INTEL SSDSA2BW160G3L/4PC1LE04
"INTEL SSDSA[12][BC][WT](040|080|120|160|300|600)G3[ADL]?",
"", "", "", "",
"-F nologdir " "-F nologdir "
//"-v 3,raw16(avg16),Spin_Up_Time " //"-v 3,raw16(avg16),Spin_Up_Time "
@ -540,8 +661,10 @@ const drive_settings builtin_knowndrives[] = {
"-v 170,raw48,Reserve_Block_Count " "-v 170,raw48,Reserve_Block_Count "
"-v 171,raw48,Program_Fail_Count " "-v 171,raw48,Program_Fail_Count "
"-v 172,raw48,Erase_Fail_Count " "-v 172,raw48,Erase_Fail_Count "
"-v 183,raw48,SATA_Downshift_Count " // FW >= 4Px10362
//"-v 184,raw48,End-to-End_Error " //"-v 184,raw48,End-to-End_Error "
//"-v 187,raw48,Reported_Uncorrect " //"-v 187,raw48,Reported_Uncorrect "
"-v 199,raw48,CRC_Error_Count " // FW >= 4Px10362
"-v 192,raw48,Unsafe_Shutdown_Count " "-v 192,raw48,Unsafe_Shutdown_Count "
"-v 225,raw48,Host_Writes_32MiB " "-v 225,raw48,Host_Writes_32MiB "
"-v 226,raw48,Workld_Media_Wear_Indic " // Timed Workload Media Wear Indicator (percent*1024) "-v 226,raw48,Workld_Media_Wear_Indic " // Timed Workload Media Wear Indicator (percent*1024)
@ -615,6 +738,58 @@ const drive_settings builtin_knowndrives[] = {
"-v 242,raw48,Host_Reads_32MiB " "-v 242,raw48,Host_Reads_32MiB "
"-v 249,raw48,NAND_Writes_1GiB" "-v 249,raw48,NAND_Writes_1GiB"
}, },
{ "Intel 525 Series SSDs", // mSATA, tested with SSDMCEAC120B3/LLLi
"INTEL SSDMCEAC(030|060|090|120|180|240)B3",
"", "",
//"-v 5,raw16(raw16),Reallocated_Sector_Ct "
"-v 9,msec24hour32,Power_On_Hours_and_Msec "
//"-v 12,raw48,Power_Cycle_Count "
"-v 170,raw48,Available_Reservd_Space "
"-v 171,raw48,Program_Fail_Count "
"-v 172,raw48,Erase_Fail_Count "
"-v 174,raw48,Unexpect_Power_Loss_Ct "
"-v 183,raw48,SATA_Downshift_Count "
//"-v 184,raw48,End-to-End_Error "
"-v 187,raw48,Uncorrectable_Error_Cnt "
//"-v 190,tempminmax,Airflow_Temperature_Cel "
//"-v 192,raw48,Power-Off_Retract_Count "
//"-v 199,raw48,UDMA_CRC_Error_Count "
"-v 225,raw48,Host_Writes_32MiB "
"-v 226,raw48,Workld_Media_Wear_Indic "
"-v 227,raw48,Workld_Host_Reads_Perc "
"-v 228,raw48,Workload_Minutes "
//"-v 232,raw48,Available_Reservd_Space "
//"-v 233,raw48,Media_Wearout_Indicator "
"-v 241,raw48,Host_Writes_32MiB "
"-v 242,raw48,Host_Reads_32MiB "
"-v 249,raw48,NAND_Writes_1GiB"
},
{ "Intel 530 Series SSDs", // tested with INTEL SSDSC2BW180A4/DC12, SSDSC2BW240A4/DC12
"INTEL SSDSC2BW(080|120|180|240|360|480)A4",
"", "",
//"-v 5,raw16(raw16),Reallocated_Sector_Ct "
"-v 9,msec24hour32,Power_On_Hours_and_Msec "
//"-v 12,raw48,Power_Cycle_Count "
"-v 170,raw48,Available_Reservd_Space "
"-v 171,raw48,Program_Fail_Count "
"-v 172,raw48,Erase_Fail_Count "
"-v 174,raw48,Unexpect_Power_Loss_Ct "
"-v 183,raw48,SATA_Downshift_Count "
//"-v 184,raw48,End-to-End_Error "
"-v 187,raw48,Uncorrectable_Error_Cnt "
//"-v 190,tempminmax,Airflow_Temperature_Cel "
//"-v 192,raw48,Power-Off_Retract_Count "
//"-v 199,raw48,UDMA_CRC_Error_Count "
"-v 225,raw48,Host_Writes_32MiB "
"-v 226,raw48,Workld_Media_Wear_Indic "
"-v 227,raw48,Workld_Host_Reads_Perc "
"-v 228,raw48,Workload_Minutes "
//"-v 232,raw48,Available_Reservd_Space "
//"-v 233,raw48,Media_Wearout_Indicator "
"-v 241,raw48,Host_Writes_32MiB "
"-v 242,raw48,Host_Reads_32MiB "
"-v 249,raw48,NAND_Writes_1GiB"
},
{ "Intel 330/335 Series SSDs", // tested with INTEL SSDSC2CT180A3/300i, SSDSC2CT240A3/300i, { "Intel 330/335 Series SSDs", // tested with INTEL SSDSC2CT180A3/300i, SSDSC2CT240A3/300i,
// INTEL SSDSC2CT240A4/335t // INTEL SSDSC2CT240A4/335t
"INTEL SSDSC2CT(060|120|180|240)A[34]", // A4 = 335 Series "INTEL SSDSC2CT(060|120|180|240)A[34]", // A4 = 335 Series
@ -632,8 +807,9 @@ const drive_settings builtin_knowndrives[] = {
"-v 242,raw48,Host_Reads_32MiB " "-v 242,raw48,Host_Reads_32MiB "
"-v 249,raw48,NAND_Writes_1GiB" "-v 249,raw48,NAND_Writes_1GiB"
}, },
{ "Intel DC S3700 Series SSDs", // tested with INTEL SSDSC2BA200G3/5DV10250 { "Intel 730 and DC S3500/S3700 Series SSDs", // tested with INTEL SSDSC2BP480G4, SSDSC2BB120G4/D2010355,
"INTEL SSDSC(1N|2B)A(100|200|400|800)G3", // INTEL SSDSC2BB800G4T, SSDSC2BA200G3/5DV10250
"INTEL SSDSC(1N|2B)[ABP](080|100|120|160|200|240|300|400|480|600|800)G[34]T?", // A=S3700, B=S3500, P=730
"", "", "", "",
//"-v 3,raw16(avg16),Spin_Up_Time " //"-v 3,raw16(avg16),Spin_Up_Time "
//"-v 4,raw48,Start_Stop_Count " //"-v 4,raw48,Start_Stop_Count "
@ -644,7 +820,7 @@ const drive_settings builtin_knowndrives[] = {
"-v 171,raw48,Program_Fail_Count " "-v 171,raw48,Program_Fail_Count "
"-v 172,raw48,Erase_Fail_Count " "-v 172,raw48,Erase_Fail_Count "
"-v 174,raw48,Unsafe_Shutdown_Count " "-v 174,raw48,Unsafe_Shutdown_Count "
"-v 175,raw48,Power_Loss_Cap_Test " "-v 175,raw16(raw16),Power_Loss_Cap_Test "
"-v 183,raw48,SATA_Downshift_Count " "-v 183,raw48,SATA_Downshift_Count "
//"-v 184,raw48,End-to-End_Error " //"-v 184,raw48,End-to-End_Error "
//"-v 187,raw48,Reported_Uncorrect " //"-v 187,raw48,Reported_Uncorrect "
@ -659,9 +835,10 @@ const drive_settings builtin_knowndrives[] = {
"-v 228,raw48,Workload_Minutes " // 226,227,228 can be reset by 'smartctl -t vendor,0x40' "-v 228,raw48,Workload_Minutes " // 226,227,228 can be reset by 'smartctl -t vendor,0x40'
//"-v 232,raw48,Available_Reservd_Space " //"-v 232,raw48,Available_Reservd_Space "
//"-v 233,raw48,Media_Wearout_Indicator " //"-v 233,raw48,Media_Wearout_Indicator "
"-v 234,raw48,Thermal_Throttle " "-v 234,raw24/raw32:04321,Thermal_Throttle "
"-v 241,raw48,Host_Writes_32MiB " "-v 241,raw48,Host_Writes_32MiB "
"-v 242,raw48,Host_Reads_32MiB" "-v 242,raw48,Host_Reads_32MiB "
"-F xerrorlba" // tested with SSDSC2BB600G4/D2010355
}, },
{ "Kingston branded X25-V SSDs", // fixed firmware { "Kingston branded X25-V SSDs", // fixed firmware
"KINGSTON SSDNow 40GB", "KINGSTON SSDNow 40GB",
@ -688,8 +865,9 @@ const drive_settings builtin_knowndrives[] = {
}, },
{ "JMicron based SSDs", // JMicron JMF60x { "JMicron based SSDs", // JMicron JMF60x
"Kingston SSDNow V Series [0-9]*GB|" // tested with Kingston SSDNow V Series 64GB/B090522a "Kingston SSDNow V Series [0-9]*GB|" // tested with Kingston SSDNow V Series 64GB/B090522a
"TS(2|4|8|16|32|64|128|192)GSSD25S?-(M|S)", // Transcend IDE and SATA, tested with TS32GSSD25-M/V090331 "TS(2|4|8|16|32|64|128|192)GSSD(18|25)[MS]?-[MS]", // Transcend IDE and SATA, tested with
"[BV].*", // other Transcend SSD versions will be catched by subsequent entry // TS32GSSD25-M/V090331, TS32GSSD18M-M/v090331
"[BVv].*", // other Transcend SSD versions will be catched by subsequent entry
"", "",
//"-v 9,raw24(raw8),Power_On_Hours " // raw value always 0? //"-v 9,raw24(raw8),Power_On_Hours " // raw value always 0?
//"-v 12,raw48,Power_Cycle_Count " //"-v 12,raw48,Power_Cycle_Count "
@ -700,9 +878,10 @@ const drive_settings builtin_knowndrives[] = {
"-v 234,raw24/raw24:w01234,Avg/Max_Erase_Count " "-v 234,raw24/raw24:w01234,Avg/Max_Erase_Count "
"-v 235,raw24/raw24:w01z23,Good/Sys_Block_Count" "-v 235,raw24/raw24:w01z23,Good/Sys_Block_Count"
}, },
{ "JMicron based SSDs", // JMicron JMF61x { "JMicron based SSDs", // JMicron JMF61x, JMF661
"ADATA S596 Turbo|" // tested with ADATA S596 Turbo 256GB SATA SSD (JMicron JMF616) "ADATA S596 Turbo|" // tested with ADATA S596 Turbo 256GB SATA SSD (JMicron JMF616)
"APPLE SSD TS.*|" // Toshiba?, tested with APPLE SSD TS064C/CJAA0201 "ADATA SP600|" // tested with ADATA SP600/2.4 (JMicron JMF661)
"APPLE SSD TS(064|128|256|512)C|" // Toshiba?, tested with APPLE SSD TS064C/CJAA0201
"KINGSTON SNV425S2(64|128)GB|" // SSDNow V Series (2. Generation, JMF618), "KINGSTON SNV425S2(64|128)GB|" // SSDNow V Series (2. Generation, JMF618),
// tested with KINGSTON SNV425S264GB/C091126a // tested with KINGSTON SNV425S264GB/C091126a
"KINGSTON SSDNOW 30GB|" // tested with KINGSTON SSDNOW 30GB/AJXA0202 "KINGSTON SSDNOW 30GB|" // tested with KINGSTON SSDNOW 30GB/AJXA0202
@ -729,17 +908,18 @@ const drive_settings builtin_knowndrives[] = {
"-v 168,raw48,SATA_Phy_Error_Count " "-v 168,raw48,SATA_Phy_Error_Count "
//"-v 169,raw48,Unknown_Attribute " //"-v 169,raw48,Unknown_Attribute "
"-v 170,raw16,Bad_Block_Count " "-v 170,raw16,Bad_Block_Count "
"-v 173,raw16,Erase_Count " "-v 173,raw16,Erase_Count " // JMF661: different?
"-v 175,raw48,Bad_Cluster_Table_Count " "-v 175,raw48,Bad_Cluster_Table_Count "
"-v 192,raw48,Unexpect_Power_Loss_Ct " "-v 192,raw48,Unexpect_Power_Loss_Ct "
//"-v 194,tempminmax,Temperature_Celsius " //"-v 194,tempminmax,Temperature_Celsius "
//"-v 197,raw48,Current_Pending_Sector " //"-v 197,raw48,Current_Pending_Sector "
"-v 240,raw48,Unknown_Attribute" "-v 240,raw48,Unknown_Attribute"
}, },
{ "Plextor M3 (Pro) Series SSDs", // Marvell 9174, tested with PLEXTOR PX-128M3/1.01, { "Plextor M3/M5 (Pro) Series SSDs", // Marvell 88SS9174 (M3, M5S), 88SS9187 (M5Pro), tested with
// PLEXTOR PX-128M3P/1.04, PLEXTOR PX-256M3/1.05 // PLEXTOR PX-128M3/1.01, PX-128M3P/1.04, PX-256M3/1.05, PX-128M5S/1.02, PX-256M5S/1.03,
// PX-128M5M/1.05, PX-128M5S/1.05, PX-128M5Pro/1.05, PX-512M5Pro/1.06
// (1.04/5 Firmware self-test log lifetime unit is bogus, possibly 1/256 hours) // (1.04/5 Firmware self-test log lifetime unit is bogus, possibly 1/256 hours)
"PLEXTOR PX-(64|128|256|512)M3P?", "PLEXTOR PX-(64|128|256|512)M(3P?|5[MS]|5Pro)",
"", "", "", "",
//"-v 1,raw48,Raw_Read_Error_Rate " //"-v 1,raw48,Raw_Read_Error_Rate "
//"-v 5,raw16(raw16),Reallocated_Sector_Ct " //"-v 5,raw16(raw16),Reallocated_Sector_Ct "
@ -755,7 +935,8 @@ const drive_settings builtin_knowndrives[] = {
//"-v 198,raw48,Offline_Uncorrectable " //"-v 198,raw48,Offline_Uncorrectable "
//"-v 199,raw48,UDMA_CRC_Error_Count " //"-v 199,raw48,UDMA_CRC_Error_Count "
//"-v 232,raw48,Available_Reservd_Space " //"-v 232,raw48,Available_Reservd_Space "
"" "-v 241,raw48,Host_Writes_32MiB "
"-v 242,raw48,Host_Reads_32MiB"
}, },
{ "Samsung based SSDs", { "Samsung based SSDs",
"SAMSUNG SSD PM800 .*GB|" // SAMSUNG PM800 SSDs, tested with SAMSUNG SSD PM800 TH 64GB/VBM25D1Q "SAMSUNG SSD PM800 .*GB|" // SAMSUNG PM800 SSDs, tested with SAMSUNG SSD PM800 TH 64GB/VBM25D1Q
@ -764,6 +945,8 @@ const drive_settings builtin_knowndrives[] = {
"SAMSUNG SSD 830 Series|" // tested with SAMSUNG SSD 830 Series 64GB/CXM03B1Q "SAMSUNG SSD 830 Series|" // tested with SAMSUNG SSD 830 Series 64GB/CXM03B1Q
"Samsung SSD 840 (PRO )?Series|" // tested with Samsung SSD 840 PRO Series 128GB/DXM04B0Q, "Samsung SSD 840 (PRO )?Series|" // tested with Samsung SSD 840 PRO Series 128GB/DXM04B0Q,
// Samsung SSD 840 Series/DXT06B0Q // Samsung SSD 840 Series/DXT06B0Q
"Samsung SSD 840 EVO ([0-9]*G|1T)B( mSATA)?|" // tested with Samsung SSD 840 EVO (120|250|500)GB/EXT0AB0Q,
// Samsung SSD 840 EVO (120|250)GB/EXT0BB6Q, 1TB/EXT0BB0Q, 120GB mSATA/EXT41B6Q
"SAMSUNG MZ7WD((120|240)HAFV|480HAGM|960HAGP)-00003", // SM843T Series, tested with "SAMSUNG MZ7WD((120|240)HAFV|480HAGM|960HAGP)-00003", // SM843T Series, tested with
// SAMSUNG MZ7WD120HAFV-00003/DXM85W3Q // SAMSUNG MZ7WD120HAFV-00003/DXM85W3Q
"", "", "", "",
@ -791,6 +974,55 @@ const drive_settings builtin_knowndrives[] = {
"-v 235,raw48,POR_Recovery_Count " // 830/840 Series "-v 235,raw48,POR_Recovery_Count " // 830/840 Series
//"-v 241,raw48,Total_LBAs_Written" //"-v 241,raw48,Total_LBAs_Written"
}, },
{ "Marvell based SanDisk SSDs",
"SanDisk SD5SG2[0-9]*G1052E|" // X100 (88SS9174), tested with SanDisk SD5SG2256G1052E/10.04.01
"SanDisk SD6SB[12]M[0-9]*G(1022I)?|" // X110/X210 (88SS9175), tested with SanDisk SD6SB1M064G1022I/X231600,
// SanDisk SD6SB1M256G1022I/X231600, SanDisk SD6SB2M512G1022I/X210400
"SanDisk SDSSDHP[0-9]*G|" // Ultra Plus (88SS9175), tested with SanDisk SDSSDHP128G/X23[01]6RL
"SanDisk SDSSDXP[0-9]*G", // Extreme II (88SS9187), tested with SanDisk SDSSDXP480G/R1311
"", "",
//"-v 5,raw16(raw16),Reallocated_Sector_Ct "
//"-v 9,raw24(raw8),Power_On_Hours "
//"-v 12,raw48,Power_Cycle_Count "
"-v 166,raw48,Min_W/E_Cycle "
"-v 167,raw48,Min_Bad_Block/Die "
"-v 168,raw48,Maximum_Erase_Cycle "
"-v 169,raw48,Total_Bad_Block "
"-v 171,raw48,Program_Fail_Count "
"-v 172,raw48,Erase_Fail_Count "
"-v 173,raw48,Avg_Write_Erase_Ct "
"-v 174,raw48,Unexpect_Power_Loss_Ct "
//"-v 187,raw48,Reported_Uncorrect "
//"-v 194,tempminmax,Temperature_Celsius "
"-v 212,raw48,SATA_PHY_Error "
"-v 230,raw48,Perc_Write_Erase_Count "
"-v 232,raw48,Perc_Avail_Resrvd_Space "
"-v 233,raw48,Total_NAND_Writes_GiB "
"-v 241,raw48,Total_Writes_GiB "
"-v 242,raw48,Total_Reads_GiB "
//"-v 243,raw48,Unknown_Attribute "
},
{ "SanDisk based SSDs",
"SanDisk iSSD P4 [0-9]*GB|" // tested with SanDisk iSSD P4 16GB/SSD 9.14
"SanDisk SDSSDP[0-9]*G|" // tested with SanDisk SDSSDP064G/1.0.0, SDSSDP128G/2.0.0
"SanDisk SSD i100 [0-9]*GB|" // tested with SanDisk SSD i100 8GB/11.56.04, 24GB/11.56.04
"SanDisk SSD U100 ([0-9]*GB|SMG2)|" // tested with SanDisk SSD U100 8GB/10.56.00, 256GB/10.01.02, SMG2/10.56.04
"SanDisk SD7[SU]B3Q(064|128|256|512)G.*", // tested with SD7SB3Q064G1122/SD7UB3Q256G1122/SD7SB3Q128G
"", "",
//"-v 5,raw16(raw16),Reallocated_Sector_Ct "
//"-v 9,raw24(raw8),Power_On_Hours "
//"-v 12,raw48,Power_Cycle_Count "
"-v 171,raw48,Program_Fail_Count "
"-v 172,raw48,Erase_Fail_Count "
"-v 173,raw48,Avg_Write_Erase_Ct "
"-v 174,raw48,Unexpect_Power_Loss_Ct "
//"-v 187,raw48,Reported_Uncorrect "
"-v 230,raw48,Perc_Write_Erase_Count "
"-v 232,raw48,Perc_Avail_Resrvd_Space "
"-v 234,raw48,Perc_Write_Erase_Ct_BC "
//"-v 241,raw48,Total_LBAs_Written "
//"-v 242,raw48,Total_LBAs_Read "
},
{ "Smart Storage Systems Xcel-10 SSDs", // based on http://www.smartm.com/files/salesLiterature/storage/xcel10.pdf { "Smart Storage Systems Xcel-10 SSDs", // based on http://www.smartm.com/files/salesLiterature/storage/xcel10.pdf
"SMART A25FD-(32|64|128)GI32N", // tested with SMART A25FD-128GI32N/B9F23D4K "SMART A25FD-(32|64|128)GI32N", // tested with SMART A25FD-128GI32N/B9F23D4K
"", "",
@ -1139,6 +1371,10 @@ const drive_settings builtin_knowndrives[] = {
"SAMSUNG HE(502H|754J|103S)J", "SAMSUNG HE(502H|754J|103S)J",
"", "", "" "", "", ""
}, },
{ "Seagate Samsung Spinpoint F4", // tested with ST250DM001 HD256GJ/1AR10001
"ST(250|320)DM001 HD(256G|322G|323H)J",
"", "", ""
},
{ "SAMSUNG SpinPoint F4 EG (AF)",// tested with HD204UI/1AQ10001(buggy|fixed) { "SAMSUNG SpinPoint F4 EG (AF)",// tested with HD204UI/1AQ10001(buggy|fixed)
"SAMSUNG HD(155|204)UI", "SAMSUNG HD(155|204)UI",
"", // 1AQ10001 "", // 1AQ10001
@ -1148,7 +1384,7 @@ const drive_settings builtin_knowndrives[] = {
"Buggy and fixed firmware report same version number!\n" "Buggy and fixed firmware report same version number!\n"
"See the following web pages for details:\n" "See the following web pages for details:\n"
"http://knowledge.seagate.com/articles/en_US/FAQ/223571en\n" "http://knowledge.seagate.com/articles/en_US/FAQ/223571en\n"
"http://sourceforge.net/apps/trac/smartmontools/wiki/SamsungF4EGBadBlocks", "http://www.smartmontools.org/wiki/SamsungF4EGBadBlocks",
"" ""
}, },
{ "SAMSUNG SpinPoint S250", // tested with HD200HJ/KF100-06 { "SAMSUNG SpinPoint S250", // tested with HD200HJ/KF100-06
@ -1887,8 +2123,8 @@ const drive_settings builtin_knowndrives[] = {
"", "", "" "", "", ""
}, },
{ "Toshiba 2.5\" HDD MK..65GSX", // tested with TOSHIBA MK5065GSX/GJ003A, MK3265GSXN/GH012H, { "Toshiba 2.5\" HDD MK..65GSX", // tested with TOSHIBA MK5065GSX/GJ003A, MK3265GSXN/GH012H,
// MK5065GSXF/GP006B // MK5065GSXF/GP006B, MK2565GSX H/GJ003A
"TOSHIBA MK(16|25|32|50|64)65GSX[FN]?", "TOSHIBA MK(16|25|32|50|64)65GSX[FN]?( H)?", // "... H" = USB ?
"", "", "" "", "", ""
}, },
{ "Toshiba 2.5\" HDD MK..76GSX", // tested with TOSHIBA MK3276GSX/GS002D { "Toshiba 2.5\" HDD MK..76GSX", // tested with TOSHIBA MK3276GSX/GS002D
@ -1901,10 +2137,18 @@ const drive_settings builtin_knowndrives[] = {
"TOSHIBA MQ01ABD(025|032|050|064|075|100)", "TOSHIBA MQ01ABD(025|032|050|064|075|100)",
"", "", "" "", "", ""
}, },
{ "Toshiba 2.5\" HDD MQ01UBD... (USB 3.0)", // tested with TOSHIBA MQ01ABD100/AX001U
"TOSHIBA MQ01UBD(050|075|100)",
"", "", ""
},
{ "Toshiba 3.5\" HDD MK.002TSKB", // tested with TOSHIBA MK1002TSKB/MT1A { "Toshiba 3.5\" HDD MK.002TSKB", // tested with TOSHIBA MK1002TSKB/MT1A
"TOSHIBA MK(10|20)02TSKB", "TOSHIBA MK(10|20)02TSKB",
"", "", "" "", "", ""
}, },
{ "Toshiba 3.5\" MG03ACAxxx(Y) Enterprise HDD", // tested with TOSHIBA MG03ACA100/FL1A
"TOSHIBA MG03ACA[1234]00Y?",
"", "", ""
},
{ "Toshiba 3.5\" HDD DT01ACA...", // tested with TOSHIBA DT01ACA100/MS2OA750, { "Toshiba 3.5\" HDD DT01ACA...", // tested with TOSHIBA DT01ACA100/MS2OA750,
// TOSHIBA DT01ACA200/MX4OABB0, TOSHIBA DT01ACA300/MX6OABB0 // TOSHIBA DT01ACA200/MX4OABB0, TOSHIBA DT01ACA300/MX6OABB0
"TOSHIBA DT01ACA(025|032|050|075|100|150|200|300)", "TOSHIBA DT01ACA(025|032|050|075|100|150|200|300)",
@ -2037,6 +2281,10 @@ const drive_settings builtin_knowndrives[] = {
"ST(160|250|320)LT0(07|09|11|14)-.*", "ST(160|250|320)LT0(07|09|11|14)-.*",
"", "", "" "", "", ""
}, },
{ "Seagate Laptop Thin HDD", // tested with ST500LT012-9WS142/0001SDM1
"ST(250|320|500)LT0(12|15|25)-.*",
"", "", ""
},
{ "Seagate Laptop SSHD", // tested with ST500LM000-1EJ162/SM11 { "Seagate Laptop SSHD", // tested with ST500LM000-1EJ162/SM11
"ST(500|1000)LM0(00|14)-.*", "ST(500|1000)LM0(00|14)-.*",
"", "", "" "", "", ""
@ -2183,14 +2431,14 @@ const drive_settings builtin_knowndrives[] = {
}, },
{ "Seagate Barracuda 7200.14 (AF)", // new firmware, tested with { "Seagate Barracuda 7200.14 (AF)", // new firmware, tested with
// ST3000DM001-9YN166/CC4H, ST3000DM001-9YN166/CC9E // ST3000DM001-9YN166/CC4H, ST3000DM001-9YN166/CC9E
"ST(1000|1500|2000|2500|3000)DM00[1-3]-.*", "ST(1000|1500|2000|2500|3000)DM00[1-3]-9YN16.",
"CC(4[H-Z]|[5-9A-Z]..*)", // >= "CC4H" "CC(4[H-Z]|[5-9A-Z]..*)", // >= "CC4H"
"", "",
"-v 188,raw16 -v 240,msec24hour32" // tested with ST3000DM001-9YN166/CC4H "-v 188,raw16 -v 240,msec24hour32" // tested with ST3000DM001-9YN166/CC4H
}, },
{ "Seagate Barracuda 7200.14 (AF)", // old firmware, tested with { "Seagate Barracuda 7200.14 (AF)", // old firmware, tested with
// ST1000DM003-9YN162/CC46 // ST1000DM003-9YN162/CC46
"ST(1000|1500|2000|2500|3000)DM00[1-3]-.*", "ST(1000|1500|2000|2500|3000)DM00[1-3]-9YN16.",
"CC4[679CG]", "CC4[679CG]",
"A firmware update for this drive is available,\n" "A firmware update for this drive is available,\n"
"see the following Seagate web pages:\n" "see the following Seagate web pages:\n"
@ -2199,7 +2447,7 @@ const drive_settings builtin_knowndrives[] = {
"-v 188,raw16 -v 240,msec24hour32" "-v 188,raw16 -v 240,msec24hour32"
}, },
{ "Seagate Barracuda 7200.14 (AF)", // unknown firmware { "Seagate Barracuda 7200.14 (AF)", // unknown firmware
"ST(1000|1500|2000|2500|3000)DM00[1-3]-.*", "ST(1000|1500|2000|2500|3000)DM00[1-3]-9YN16.",
"", "",
"A firmware update for this drive may be available,\n" "A firmware update for this drive may be available,\n"
"see the following Seagate web pages:\n" "see the following Seagate web pages:\n"
@ -2207,6 +2455,13 @@ const drive_settings builtin_knowndrives[] = {
"http://knowledge.seagate.com/articles/en_US/FAQ/223651en", "http://knowledge.seagate.com/articles/en_US/FAQ/223651en",
"-v 188,raw16 -v 240,msec24hour32" "-v 188,raw16 -v 240,msec24hour32"
}, },
{ "Seagate Barracuda 7200.14 (AF)", // different part number, tested with
// ST1000DM003-1CH162/CC47, ST1000DM003-1CH162/CC49, ST2000DM001-1CH164/CC24,
// ST1000DM000-9TS15E/CC92
"ST(1000|1500|2000|2500|3000)DM00[0-3]-.*",
"", "",
"-v 188,raw16 -v 240,msec24hour32"
},
{ "Seagate Barracuda 7200.14 (AF)", // < 1TB, tested with ST250DM000-1BC141 { "Seagate Barracuda 7200.14 (AF)", // < 1TB, tested with ST250DM000-1BC141
"ST(250|320|500|750)DM00[0-3]-.*", "ST(250|320|500|750)DM00[0-3]-.*",
"", "", "", "",
@ -2217,6 +2472,11 @@ const drive_settings builtin_knowndrives[] = {
"", "", "", "",
"-v 188,raw16 -v 240,msec24hour32" "-v 188,raw16 -v 240,msec24hour32"
}, },
{ "Seagate Desktop SSHD", // tested with ST2000DX001-1CM164/CC43
"ST(1000|2000|4000)DX001-.*",
"", "",
"-v 188,raw16 -v 240,msec24hour32"
},
{ "Seagate Barracuda LP", // new firmware { "Seagate Barracuda LP", // new firmware
"ST3(500412|1000520|1500541|2000542)AS", "ST3(500412|1000520|1500541|2000542)AS",
"CC3[5-9A-Z]", "CC3[5-9A-Z]",
@ -2234,7 +2494,7 @@ const drive_settings builtin_knowndrives[] = {
}, },
{ "Seagate Barracuda Green (AF)", // new firmware { "Seagate Barracuda Green (AF)", // new firmware
"ST((10|15|20)00DL00[123])-.*", "ST((10|15|20)00DL00[123])-.*",
"CC3[2-9A-Z]", "CC(3[2-9A-Z]|[4-9A-Z]..*)", // >= "CC32"
"", "" "", ""
}, },
{ "Seagate Barracuda Green (AF)", // unknown firmware { "Seagate Barracuda Green (AF)", // unknown firmware
@ -2295,6 +2555,18 @@ const drive_settings builtin_knowndrives[] = {
"ST[1234]000NM00[35]3-.*", "ST[1234]000NM00[35]3-.*",
"", "", "" "", "", ""
}, },
{ "Seagate Constellation CS", // tested with ST3000NC000/CE02, ST3000NC002-1DY166/CN02
"ST(1000|2000|3000)NC00[0-3](-.*)?",
"", "", ""
},
{ "Seagate Constellation.2 (SATA)", // 2.5", tested with ST91000640NS/SN02
"ST9(25061|50062|100064)[012]NS", // *SS = SAS
"", "", ""
},
{ "Seagate NAS HDD", // tested with ST2000VN000-1H3164/SC42, ST3000VN000-1H4167/SC43
"ST[234]000VN000-.*",
"", "", ""
},
{ "Seagate Pipeline HD 5900.1", { "Seagate Pipeline HD 5900.1",
"ST3(160310|320[34]10|500(321|422))CS", "ST3(160310|320[34]10|500(321|422))CS",
"", "", "" "", "", ""
@ -2303,6 +2575,10 @@ const drive_settings builtin_knowndrives[] = {
"ST3(160316|250[34]12|320(311|413)|500(312|414)|1000(322|424))CS", "ST3(160316|250[34]12|320(311|413)|500(312|414)|1000(322|424))CS",
"", "", "" "", "", ""
}, },
{ "Seagate Video 3.5 HDD", // tested with ST4000VM000-1F3168/SC23, SC25
"ST(10|15|20|30|40)00VM00[023]-.*",
"", "", ""
},
{ "Seagate Medalist 17240, 13030, 10231, 8420, and 4310", { "Seagate Medalist 17240, 13030, 10231, 8420, and 4310",
"ST3(17240|13030|10231|8420|4310)A", "ST3(17240|13030|10231|8420|4310)A",
"", "", "" "", "", ""
@ -2473,8 +2749,13 @@ const drive_settings builtin_knowndrives[] = {
"WDC WD2002FYPS-.*", "WDC WD2002FYPS-.*",
"", "", "" "", "", ""
}, },
{ "Western Digital RE4 (SATA 6Gb/s)", // tested with WDC WD2000FYYZ-01UL1B0/01.01K01 { "Western Digital RE4 (SATA 6Gb/s)", // tested with WDC WD2000FYYZ-01UL1B0/01.01K01,
"WDC WD(20|30|40)00FYYZ-.*", // WD2000FYYX/00.0D1K2
"WDC WD(20|30|40)00FYYZ-.*|WD2000FYYX",
"", "", ""
},
{ "Western Digital Se", // tested with WDC WD2000F9YZ-09N20L0/01.01A01
"WDC WD(1002|2000|3000|4000)F9YZ-.*",
"", "", "" "", "", ""
}, },
{ "Western Digital Caviar Green", { "Western Digital Caviar Green",
@ -2489,21 +2770,18 @@ const drive_settings builtin_knowndrives[] = {
}, },
{ "Western Digital Caviar Green (AF, SATA 6Gb/s)", // tested with { "Western Digital Caviar Green (AF, SATA 6Gb/s)", // tested with
// WDC WD10EZRX-00A8LB0/01.01A01, WDC WD20EZRX-00DC0B0/80.00A80, // WDC WD10EZRX-00A8LB0/01.01A01, WDC WD20EZRX-00DC0B0/80.00A80,
// WDC WD30EZRX-00MMMB0/80.00A80 // WDC WD30EZRX-00MMMB0/80.00A80, WDC WD40EZRX-00SPEB0/80.00A80
"WDC WD(7500AA|(10|15|20)EA|(10|20|25|30)EZ)RX-.*", "WDC WD(7500AA|(10|15|20)EA|(10|20|25|30|40)EZ)RX-.*",
"", "", "" "", "", ""
}, },
{ "Western Digital Caviar Black", { "Western Digital Caviar Black",
"WDC WD((500|640|750)1AAL|1001FA[EL]|2001FAS)S-.*", "WDC WD((500|640|750)1AAL|1001FA[EL]|2001FAS)S-.*",
"", "", "" "", "", ""
}, },
{ "Western Digital Caviar Black", // SATA 6 Gb/s variants, tested with { "Western Digital Black", // tested with
// WDC WD4001FAEX-00MJRA0/01.01L01 // WDC WD5003AZEX-00RKKA0/80.00A80, WDC WD1003FZEX-00MK2A0/01.01A01,
"WDC WD(5002AAL|(64|75)02AAE|((10|15|20)02|4001)FAE)X-.*", // WDC WD3001FAEX-00MJRA0/01.01L01, WDC WD4001FAEX-00MJRA0/01.01L01
"", "", "" "WDC WD(5002AAL|5003AZE|(64|75)02AAE|((10|15|20)0[23]|[34]001)F[AZ]E)X-.*",
},
{ "Western Digital Caviar Black (AF)", // tested with WDC WD5003AZEX-00RKKA0/80.00A80
"WDC WD(5003AZE)X-.*",
"", "", "" "", "", ""
}, },
{ "Western Digital AV ATA", // tested with WDC WD3200AVJB-63J5A0/01.03E01 { "Western Digital AV ATA", // tested with WDC WD3200AVJB-63J5A0/01.03E01
@ -2571,15 +2849,24 @@ const drive_settings builtin_knowndrives[] = {
"WDC WD(50|75)00BPKT-.*", "WDC WD(50|75)00BPKT-.*",
"", "", "" "", "", ""
}, },
{ "Western Digital Red (AF)", // tested with WDC WD10EFRX-68JCSN0/01.01A01 { "Western Digital Red (AF)", // tested with WDC WD10EFRX-68JCSN0/01.01A01,
"WDC WD(10|20|30)EFRX-.*", // WDC WD10JFCX-68N6GN0/01.01A01, WDC WD40EFRX-68WT0N0/80.00A80
"WDC WD(10|20|30|40)[EJ]F[CR]X-.*",
"", "", "" "", "", ""
}, },
{ "Western Digital My Passport (USB)", // tested with WDC WD5000BMVW-11AMCS0/01.01A01 { "Western Digital Blue Mobile", // tested with WDC WD5000LPVX-08V0TT2/03.01A03
"WDC WD((25|32|50|75)00[BLM]|10[JS])P[CV][TX]-.*",
"", "", ""
},
{ "Western Digital Green Mobile", // tested with WDC WD20NPVX-00EA4T0/01.01A01
"WDC WD(15|20)NPV[TX]-.*",
"", "", ""
},
{ "Western Digital Elements / My Passport (USB)", // tested with WDC WD5000BMVW-11AMCS0/01.01A01
"WDC WD(25|32|40|50)00BMV[UVW]-.*", // *W-* = USB 3.0 "WDC WD(25|32|40|50)00BMV[UVW]-.*", // *W-* = USB 3.0
"", "", "" "", "", ""
}, },
{ "Western Digital My Passport (USB, AF)", // tested with { "Western Digital Elements / My Passport (USB, AF)", // tested with
// WDC WD5000KMVV-11TK7S1/01.01A01, WDC WD10TMVW-11ZSMS5/01.01A01, // WDC WD5000KMVV-11TK7S1/01.01A01, WDC WD10TMVW-11ZSMS5/01.01A01,
// WDC WD10JMVW-11S5XS1/01.01A01, WDC WD20NMVW-11W68S0/01.01A01 // WDC WD10JMVW-11S5XS1/01.01A01, WDC WD20NMVW-11W68S0/01.01A01
"WDC WD(5000[LK]|7500K|10[JT]|20N)MV[VW]-.*", // *W-* = USB 3.0 "WDC WD(5000[LK]|7500K|10[JT]|20N)MV[VW]-.*", // *W-* = USB 3.0
@ -2672,6 +2959,12 @@ const drive_settings builtin_knowndrives[] = {
"", "",
"-d sat" "-d sat"
}, },
{ "USB: Buffalo MiniStationHD-PCFU3; ",
"0x0411:0x0240",
"",
"",
"-d sat"
},
// LG Electronics // LG Electronics
{ "USB: LG Mini HXD5; JMicron", { "USB: LG Mini HXD5; JMicron",
"0x043e:0x70f1", "0x043e:0x70f1",
@ -2687,6 +2980,12 @@ const drive_settings builtin_knowndrives[] = {
"-d sat" "-d sat"
}, },
// Toshiba // Toshiba
{ "USB: Toshiba Stor.E Slim USB 3.0; ", // 1TB, MQ01UBD100
"0x0480:0x0100",
"", // 0x0000
"",
"-d sat"
},
{ "USB: Toshiba Canvio 500GB; SunPlus", { "USB: Toshiba Canvio 500GB; SunPlus",
"0x0480:0xa004", "0x0480:0xa004",
"", "",
@ -2705,6 +3004,18 @@ const drive_settings builtin_knowndrives[] = {
"", "",
"-d sat" "-d sat"
}, },
{ "USB: Toshiba Stor.E Basics; ", // 1TB
"0x0480:0xa009",
"",
"",
"-d sat"
},
{ "USB: Toshiba Stor.E Plus", // 2TB
"0x0480:0xa00a",
"",
"",
"-d sat"
},
{ "USB: Toshiba Canvio Desktop; ", // 2TB { "USB: Toshiba Canvio Desktop; ", // 2TB
"0x0480:0xd010", "0x0480:0xd010",
"", "",
@ -2788,8 +3099,14 @@ const drive_settings builtin_knowndrives[] = {
"", "",
"-d sat" "-d sat"
}, },
{ "USB: Samsung M3 Portable USB 3.0; ", // 1TB { "USB: Samsung D3 Station; ", // 3TB
"0x04e8:0x61b6", "0x04e8:0x6124",
"", // 0x200
"",
"-d sat"
},
{ "USB: Samsung M3 Portable USB 3.0; ",
"0x04e8:0x61b[456]", // 4=2TB, 5=1.5TB, 6=1TB
"", // 0x0e00 "", // 0x0e00
"", "",
"-d sat" "-d sat"
@ -2850,6 +3167,12 @@ const drive_settings builtin_knowndrives[] = {
"", "",
"-d usbjmicron" "-d usbjmicron"
}, },
{ "USB: Iomega; JMicron",
"0x059b:0x047a",
"", // 0x0100
"",
"-d sat" // works also with "-d usbjmicron"
},
// LaCie // LaCie
{ "USB: LaCie hard disk (FA Porsche design);", { "USB: LaCie hard disk (FA Porsche design);",
"0x059f:0x0651", "0x059f:0x0651",
@ -3041,7 +3364,7 @@ const drive_settings builtin_knowndrives[] = {
}, },
// Lumberg, Inc. // Lumberg, Inc.
{ "USB: Toshiba Stor.E; Sunplus", { "USB: Toshiba Stor.E; Sunplus",
"0x0939:0x0b16", "0x0939:0x0b1[56]",
"", "",
"", "",
"-d usbsunplus" "-d usbsunplus"
@ -3066,7 +3389,7 @@ const drive_settings builtin_knowndrives[] = {
"-d sat" "-d sat"
}, },
{ "USB: Seagate Expansion Portable; ", { "USB: Seagate Expansion Portable; ",
"0x0bc2:0x2300", "0x0bc2:0x23(00|12)",
"", "",
"", "",
"-d sat" "-d sat"
@ -3090,13 +3413,13 @@ const drive_settings builtin_knowndrives[] = {
"-d sat,12" "-d sat,12"
}, },
{ "USB: Seagate Expansion External; ", // 2TB, 3TB { "USB: Seagate Expansion External; ", // 2TB, 3TB
"0x0bc2:0x33(00|20|32)", "0x0bc2:0x33(00|12|20|32)",
"", "",
"", "",
"-d sat" "-d sat"
}, },
{ "USB: Seagate FreeAgent GoFlex USB 2.0; ", { "USB: Seagate FreeAgent GoFlex USB 2.0; ",
"0x0bc2:0x5021", "0x0bc2:0x502[01]",
"", "",
"", "",
"-d sat" "-d sat"
@ -3143,6 +3466,12 @@ const drive_settings builtin_knowndrives[] = {
"", "",
"-d sat" "-d sat"
}, },
{ "USB: Seagate Backup Plus Slim USB 3.0; ", // (ticket #443)
"0x0bc2:0xab24",
"", // 0x0100
"",
"-d sat"
},
// Dura Micro // Dura Micro
{ "USB: Dura Micro; Cypress", { "USB: Dura Micro; Cypress",
"0x0c0b:0xb001", "0x0c0b:0xb001",
@ -3227,44 +3556,14 @@ const drive_settings builtin_knowndrives[] = {
"", "",
"-d usbcypress" "-d usbcypress"
}, },
{ "USB: WD My Passport Portable; ", { "USB: WD My Passport; ",
"0x1058:0x0702", "0x1058:0x07(0[245a]|30)",
"", // 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 Passport 0730; ",
"0x1058:0x0730",
"", // 0x1008
"",
"-d sat"
},
{ "USB: WD My Passport Essential SE USB 3.0; ",
"0x1058:0x074[02]",
"", "",
"", "",
"-d sat" "-d sat"
}, },
{ "USB: WD My Passport USB 3.0; ", { "USB: WD My Passport USB 3.0; ",
"0x1058:0x07[4a]8", "0x1058:0x0(74[0128a]|7a8|820)",
"", "",
"", "",
"-d sat" "-d sat"
@ -3294,7 +3593,7 @@ const drive_settings builtin_knowndrives[] = {
"-d sat" "-d sat"
}, },
{ "USB: WD Elements; ", { "USB: WD Elements; ",
"0x1058:0x10(10|a2)", "0x1058:0x10(10|48|a2)",
"", // 0x0105 "", // 0x0105
"", "",
"-d sat" "-d sat"
@ -3317,6 +3616,12 @@ const drive_settings builtin_knowndrives[] = {
"", "",
"-d sat" "-d sat"
}, },
{ "USB: WD Elements; ",
"0x1058:0x10[ab]8", // a=1TB, b=2TB
"", // a=0x1042, b=0x1007
"",
"-d sat"
},
{ "USB: WD My Book Essential; ", { "USB: WD My Book Essential; ",
"0x1058:0x1100", "0x1058:0x1100",
"", // 0x0165 "", // 0x0165
@ -3360,7 +3665,13 @@ const drive_settings builtin_knowndrives[] = {
"", "",
"-d sat" "-d sat"
}, },
// A-DATA // ADATA
{ "USB: ADATA; ",
"0x125f:0xa[13]1a", // 1=Classic CH11 1TB, 3=DashDrive HV620 2TB
"", // 0x0100
"",
"-d sat"
},
{ "USB: A-DATA SH93; Cypress", { "USB: A-DATA SH93; Cypress",
"0x125f:0xa93a", "0x125f:0xa93a",
"", // 0x0150 "", // 0x0150
@ -3410,6 +3721,12 @@ const drive_settings builtin_knowndrives[] = {
"", "",
"-d sat" "-d sat"
}, },
{ "USB: ; Initio",
"0x13fd:0x1640",
"", // 0x0864
"",
"-d sat,12" // some SMART commands fail, see ticket #295
},
{ "USB: Intenso Memory Station 2,5\"; Initio", { "USB: Intenso Memory Station 2,5\"; Initio",
"0x13fd:0x1840", "0x13fd:0x1840",
"", "",
@ -3430,12 +3747,19 @@ const drive_settings builtin_knowndrives[] = {
"-d usbcypress" "-d usbcypress"
}, },
// JMicron // JMicron
{ "USB: ; JMicron USB 3.0", { "USB: ; JMicron JMS539", // USB2/3->SATA (old firmware)
"0x152d:0x0539", "0x152d:0x0539",
"", // 0x0100 "0x0100", // 1.00
"", "",
"-d usbjmicron" "-d usbjmicron"
}, },
{ "USB: ; JMicron JMS539", // USB2/3->SATA (new firmware)
"0x152d:0x0539",
"0x0205|" // 2.05, ticket #338
"0x2812", // 28.12, Mediasonic ProBox H82-SU3S2 (port multiplier)
"",
"-d sat"
},
{ "USB: ; JMicron ", // USB->SATA->4xSATA (port multiplier) { "USB: ; JMicron ", // USB->SATA->4xSATA (port multiplier)
"0x152d:0x0551", "0x152d:0x0551",
"", // 0x0100 "", // 0x0100
@ -3511,6 +3835,12 @@ const drive_settings builtin_knowndrives[] = {
"", "",
"-d sat" "-d sat"
}, },
{ "USB: ; ASMedia AS2105", // Icy Box IB-AC603A-U3
"0x174c:0x5136",
"", // 0x0001
"",
"-d sat"
},
// LucidPort // LucidPort
{ "USB: ; LucidPORT USB300", // RaidSonic ICY BOX IB-110StU3-B, Sharkoon SATA QuickPort H3 { "USB: ; LucidPORT USB300", // RaidSonic ICY BOX IB-110StU3-B, Sharkoon SATA QuickPort H3
"0x1759:0x500[02]", // 0x5000: USB 2.0, 0x5002: USB 3.0 "0x1759:0x500[02]", // 0x5000: USB 2.0, 0x5002: USB 3.0
@ -3518,6 +3848,12 @@ const drive_settings builtin_knowndrives[] = {
"", "",
"-d sat" "-d sat"
}, },
{ "USB: ; LucidPort", // Fuj:tech SATA-USB3 dock
"0x1759:0x5100",
"", // 0x2580
"",
"-d sat"
},
// Verbatim // Verbatim
{ "USB: Verbatim Portable Hard Drive; Sunplus", { "USB: Verbatim Portable Hard Drive; Sunplus",
"0x18a5:0x0214", "0x18a5:0x0214",
@ -3569,6 +3905,13 @@ const drive_settings builtin_knowndrives[] = {
"", "",
"-d usbsunplus" "-d usbsunplus"
}, },
// TrekStor
{ "USB: TrekStor DataStation; ", // DataStation maxi light (USB 3.0)
"0x1e68:0x0050",
"", // 0x0100
"",
"-d sat"
},
// Innostor // Innostor
{ "USB: ; Innostor IS888", // Sharkoon SATA QuickDeck Pro USB 3.0 { "USB: ; Innostor IS888", // Sharkoon SATA QuickDeck Pro USB 3.0
"0x1f75:0x0888", "0x1f75:0x0888",

View File

@ -1,4 +1,4 @@
#!/bin/bash #! /bin/sh
# #
# This is a script from the smartmontools examplescripts/ directory. # This is a script from the smartmontools examplescripts/ directory.
# It can be used as an argument to the -M exec Directive in # It can be used as an argument to the -M exec Directive in
@ -8,7 +8,7 @@
# Please see man 8 smartd or man 5 smartd.conf for further # Please see man 8 smartd or man 5 smartd.conf for further
# information. # information.
# #
# $Id: Example1,v 1.7 2004/08/29 02:33:17 ballen4705 Exp $ # $Id: Example1 3958 2014-07-18 19:13:32Z chrfranke $
# Save standard input into a temp file # Save standard input into a temp file
cat > /root/tempfile cat > /root/tempfile
@ -36,9 +36,9 @@ echo "$SMARTD_TFIRSTEPOCH" >> /root/tempfile
# Run smartctl -a and save output in temp file # Run smartctl -a and save output in temp file
/usr/sbin/smartctl -a -d $SMARTD_DEVICETYPE $SMARTD_DEVICE >> /root/tempfile /usr/sbin/smartctl -a -d $SMARTD_DEVICETYPE $SMARTD_DEVICE >> /root/tempfile
# Email the contents of the temp file. Solaris and other OSes # Email the contents of the temp file. Solaris and
# may need to use /bin/mailx not /bin/mail. # other OSes may need to use /usr/bin/mailx below.
/bin/mail -s "SMART errors detected on host: `hostname`" $SMARTD_ADDRESS < /root/tempfile /usr/bin/mail -s "SMART errors detected on host: `hostname`" $SMARTD_ADDRESS < /root/tempfile
# And exit # And exit
exit 0 exit 0

View File

@ -1,4 +1,4 @@
#! /bin/bash #! /bin/sh
# #
# This is a script from the smartmontools examplescripts/ directory. # This is a script from the smartmontools examplescripts/ directory.
# It can be used as an argument to the -M exec Directive in # It can be used as an argument to the -M exec Directive in
@ -8,7 +8,7 @@
# Please see man 8 smartd or man 5 smartd.conf for further # Please see man 8 smartd or man 5 smartd.conf for further
# information. # information.
# #
# $Id: Example2,v 1.4 2004/01/07 16:49:56 ballen4705 Exp $ # $Id: Example2 3958 2014-07-18 19:13:32Z chrfranke $
# Save the email message (STDIN) to a file: # Save the email message (STDIN) to a file:
cat > /root/msg cat > /root/msg
@ -16,7 +16,7 @@ cat > /root/msg
# Append the output of smartctl -a to the message: # Append the output of smartctl -a to the message:
/usr/sbin/smartctl -a -d $SMARTD_DEVICETYPE $SMARTD_DEVICE >> /root/msg /usr/sbin/smartctl -a -d $SMARTD_DEVICETYPE $SMARTD_DEVICE >> /root/msg
# Now email the message to the user at address ADD. Solaris and # Now email the message to the user. Solaris and
# other OSes may need to use /bin/mailx below. # other OSes may need to use /usr/bin/mailx below.
/bin/mail -s "$SMARTD_SUBJECT" $SMARTD_ADDRESS < /root/msg /usr/bin/mail -s "$SMARTD_SUBJECT" $SMARTD_ADDRESS < /root/msg

View File

@ -1,4 +1,4 @@
#! /bin/bash #! /bin/sh
# #
# This is a script from the smartmontools examplescripts/ directory. # This is a script from the smartmontools examplescripts/ directory.
# It can be used as an argument to the -M exec Directive in # It can be used as an argument to the -M exec Directive in
@ -8,7 +8,7 @@
# Please see man 8 smartd or man 5 smartd.conf for further # Please see man 8 smartd or man 5 smartd.conf for further
# information. # information.
# #
# $Id: Example3 3187 2010-10-16 13:34:18Z chrfranke $ # $Id: Example3 3958 2014-07-18 19:13:32Z chrfranke $
# Warn all users of a problem # Warn all users of a problem
wall <<EOF wall <<EOF

View File

@ -1,5 +1,8 @@
#! /bin/sh #! /bin/sh
# Send message if /usr/lib/powersave/powersave-notify exists or exit silently
[ -x /usr/lib/powersave/powersave-notify ] || exit 0
/usr/lib/powersave/powersave-notify "<b>Your hard disk drive is failing!</b> /usr/lib/powersave/powersave-notify "<b>Your hard disk drive is failing!</b>
S.M.A.R.T. message: S.M.A.R.T. message:
$SMARTD_MESSAGE" $SMARTD_MESSAGE"

10
examplescripts/Example5 Executable file
View File

@ -0,0 +1,10 @@
#!/bin/bash -e
tmp=$(tempfile)
cat >$tmp
run-parts --report --lsbsysinit --arg=$tmp --arg="$1" \
--arg="$2" --arg="$3" -- /etc/smartmontools/run.d
rm -f $tmp

15
examplescripts/Example6 Executable file
View File

@ -0,0 +1,15 @@
#! /bin/sh
# Send mail
echo "$SMARTD_MESSAGE" | mail -s "$SMARTD_FAILTYPE" "$SMARTD_ADDRESS"
# Notify desktop user
MESSAGE="WARNING: Your hard drive is failing"
# direct write to terminals, do not use 'wall', because we don't want its ugly header
for t in $(who | awk '{ print $2; }' | grep -e '^tty' -e '^pts/')
do
echo "$MESSAGE
$SMARTD_MESSAGE" >/dev/$t 2>/dev/null ||:
done

View File

@ -1,8 +1,9 @@
# Home page: http://smartmontools.sourceforge.net # Home page: http://smartmontools.sourceforge.net
# #
# $Id: README 3728 2012-12-13 17:57:50Z chrfranke $ # $Id: README 3958 2014-07-18 19:13:32Z chrfranke $
# #
# Copyright (C) 2003-8 Bruce Allen <smartmontools-support@lists.sourceforge.net> # Copyright (C) 2003-8 Bruce Allen <smartmontools-support@lists.sourceforge.net>
# Copyright (C) 2009-14 Christian Franke <smartmontools-support@lists.sourceforge.net>
# #
# This program is free software; you can redistribute it and/or modify it # This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free # under the terms of the GNU General Public License as published by the Free
@ -10,15 +11,14 @@
# version. # version.
# #
# You should have received a copy of the GNU General Public License (for # You should have received a copy of the GNU General Public License (for
# example COPYING); if not, write to the Free Software Foundation, Inc., 51 # example COPYING). If not, see <http://www.gnu.org/licenses/>.
# Franklin Street, Fifth Floor, Boston, 02110-1301 USA.
# #
# This code was originally developed as a Senior Thesis by Michael Cornwell # This code was originally developed as a Senior Thesis by Michael Cornwell
# at the Concurrent Systems Laboratory (now part of the Storage Systems # at the Concurrent Systems Laboratory (now part of the Storage Systems
# Research Center), Jack Baskin School of Engineering, University of # Research Center), Jack Baskin School of Engineering, University of
# California, Santa Cruz. http://ssrc.soe.ucsc.edu/ # California, Santa Cruz. http://ssrc.soe.ucsc.edu/
This directory contains executable bash scripts, that are intended for This directory contains executable shell scripts, that are intended for
use with the use with the
-m address -M exec /path/to/an/executable -m address -M exec /path/to/an/executable
Directive in /etc/smartd.conf. Directive in /etc/smartd.conf.
@ -35,16 +35,24 @@ and include a brief description to use below.
The files contained in this directory are: The files contained in this directory are:
Example1: appends values of $SMARTD_* environment variables and the output Example1: Appends values of $SMARTD_* environment variables and the output
of smartctl -a to the normal email message, and sends that of smartctl -a to the normal email message, and sends that
to the email address listed as the argument to the -m to the email address listed as the argument to the -m
Directive. Directive.
Example2: Appends output of smartctl -a to the normal email message Example2: Appends output of smartctl -a to the normal email message
and sends that to the email address listed as the argument and sends that to the email address listed as the argument
to the -m Directive. to the -m Directive.
Example3: Uses wall(1) to send a warning message to all users, then powers Example3: Uses wall(1) to send a warning message to all users, then powers
down the machine. down the machine.
Example4: Uses powersave-notify to issue a desktop neutral warning. Example4: Uses powersave-notify to issue a desktop neutral warning.
(/etc/smartmontools/run.d/10powersave-notify from Debian package)
Example5: Uses run-parts(8) to run scripts from /etc/smartmontools/run.d/.
(/usr/share/smartmontools/smartd-runner from Debian package)
Example6: Sends a warning mail and then notifies the users by direct write
to terminals.
(/usr/libexec/smartmontools/smartdnotify from Fedora package)

View File

@ -1,18 +1,19 @@
/* /*
* os_darwin.c * os_darwin.cpp
* *
* Home page of code is: http://smartmontools.sourceforge.net * Home page of code is: http://smartmontools.sourceforge.net
* *
* Copyright (C) 2004-8 Geoffrey Keating <geoffk@geoffk.org> * Copyright (C) 2004-8 Geoffrey Keating <geoffk@geoffk.org>
* Copyright (C) 2014 Alex Samorukov <samm@os2.kiev.ua>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option) * the Free Software Foundation; either version 2, or (at your option)
* any later version. * any later version.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* (for example COPYING); if not, write to the Free Software Foundation, * along with smartmontools. If not, see <http://www.gnu.org/licenses/>.
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
*/ */
#include <stdbool.h> #include <stdbool.h>
@ -40,17 +41,16 @@
#include "atacmds.h" #include "atacmds.h"
#include "scsicmds.h" #include "scsicmds.h"
#include "utility.h" #include "utility.h"
#include "os_darwin.h" #include "os_darwin.h"
#include "dev_interface.h"
// Needed by '-V' option (CVS versioning) of smartd/smartctl // Needed by '-V' option (CVS versioning) of smartd/smartctl
const char *os_XXXX_c_cvsid="$Id: os_darwin.cpp 3805 2013-03-29 19:54:18Z chrfranke $" \ const char *os_darwin_cpp_cvsid="$Id: os_darwin.cpp 3982 2014-08-16 21:07:19Z samm2 $" \
ATACMDS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_DARWIN_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID; ATACMDS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_DARWIN_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
// Print examples for smartctl. // examples for smartctl
void print_smartctl_examples(){ static const char smartctl_examples[] =
printf("=================================================== SMARTCTL EXAMPLES =====\n\n"); "=================================================== SMARTCTL EXAMPLES =====\n\n"
printf(
" smartctl -a disk0 (Prints all SMART information)\n\n" " smartctl -a disk0 (Prints all SMART information)\n\n"
" smartctl -t long /dev/disk0 (Executes extended disk self-test)\n\n" " smartctl -t long /dev/disk0 (Executes extended disk self-test)\n\n"
#ifdef HAVE_GETOPT_LONG #ifdef HAVE_GETOPT_LONG
@ -66,15 +66,64 @@ void print_smartctl_examples(){
" (You can use IOService: ...)\n\n" " (You can use IOService: ...)\n\n"
" smartctl -c IODeviceTree:/pci@f4000000/ata-6@D/@0:0\n" " smartctl -c IODeviceTree:/pci@f4000000/ata-6@D/@0:0\n"
" (... Or IODeviceTree:)\n" " (... Or IODeviceTree:)\n"
); ;
return;
// Information that we keep about each device.
static struct {
io_object_t ioob;
IOCFPlugInInterface **plugin;
IOATASMARTInterface **smartIf;
} devices[20];
const char * dev_darwin_cpp_cvsid = "$Id: os_darwin.cpp 3982 2014-08-16 21:07:19Z samm2 $"
DEV_INTERFACE_H_CVSID;
/////////////////////////////////////////////////////////////////////////////
namespace os { // No need to publish anything, name provided for Doxygen
/////////////////////////////////////////////////////////////////////////////
/// Implement shared open/close routines with old functions.
class darwin_smart_device
: virtual public /*implements*/ smart_device
{
public:
explicit darwin_smart_device(const char * mode)
: smart_device(never_called),
m_fd(-1), m_mode(mode) { }
virtual ~darwin_smart_device() throw();
virtual bool is_open() const;
virtual bool open();
virtual bool close();
protected:
/// Return filedesc for derived classes.
int get_fd() const
{ return m_fd; }
private:
int m_fd; ///< filedesc, -1 if not open.
const char * m_mode; ///< Mode string for deviceopen().
};
darwin_smart_device::~darwin_smart_device() throw()
{
if (m_fd >= 0)
darwin_smart_device::close();
} }
// tries to guess device type given the name (a path). See utility.h bool darwin_smart_device::is_open() const
// for return values. {
int guess_device_type (const char * /* dev_name */) { return (m_fd >= 0);
// Only ATA is supported right now, so that's what it'd better be.
return CONTROLLER_ATA;
} }
// Determine whether 'dev' is a SMART-capable device. // Determine whether 'dev' is a SMART-capable device.
@ -96,115 +145,39 @@ static bool is_smart_capable (io_object_t dev) {
// If it's an kIOATABlockStorageDeviceClass then we're successful // If it's an kIOATABlockStorageDeviceClass then we're successful
// only if its ATA features indicate it supports SMART. // only if its ATA features indicate it supports SMART.
if (IOObjectConformsTo (dev, kIOATABlockStorageDeviceClass) if (IOObjectConformsTo (dev, kIOATABlockStorageDeviceClass)
&& (diskChars = (CFDictionaryRef)IORegistryEntryCreateCFProperty && (diskChars = (CFDictionaryRef)IORegistryEntryCreateCFProperty
(dev, CFSTR (kIOPropertyDeviceCharacteristicsKey), (dev, CFSTR (kIOPropertyDeviceCharacteristicsKey),
kCFAllocatorDefault, kNilOptions)) != NULL) kCFAllocatorDefault, kNilOptions)) != NULL)
{ {
CFNumberRef diskFeatures = NULL; CFNumberRef diskFeatures = NULL;
UInt32 ataFeatures = 0; UInt32 ataFeatures = 0;
if (CFDictionaryGetValueIfPresent (diskChars, CFSTR ("ATA Features"), if (CFDictionaryGetValueIfPresent (diskChars, CFSTR ("ATA Features"),
(const void **)&diskFeatures)) (const void **)&diskFeatures))
CFNumberGetValue (diskFeatures, kCFNumberLongType, CFNumberGetValue (diskFeatures, kCFNumberLongType,
&ataFeatures); &ataFeatures);
CFRelease (diskChars); CFRelease (diskChars);
if (diskFeatures) if (diskFeatures)
CFRelease (diskFeatures); CFRelease (diskFeatures);
return (ataFeatures & kIOATAFeatureSMART) != 0; return (ataFeatures & kIOATAFeatureSMART) != 0;
} }
return false; return false;
} }
bool darwin_smart_device::open()
// makes a list of ATA or SCSI devices for the DEVICESCAN directive of {
// smartd. Returns number N of devices, or -1 if out of // Acceptable device names are:
// memory. Allocates N+1 arrays: one of N pointers (devlist); the // /dev/disk*
// other N arrays each contain null-terminated character strings. In // /dev/rdisk*
// the case N==0, no arrays are allocated because the array of 0 // disk*
// pointers has zero length, equivalent to calling malloc(0). // IOService:*
int make_device_names (char*** devlist, const char* name) { // IODeviceTree:*
IOReturn err;
io_iterator_t i;
io_object_t device = MACH_PORT_NULL;
int result;
int index;
// We treat all devices as ATA so long as they support SMARTLib.
if (strcmp (name, "ATA") != 0)
return 0;
err = IOServiceGetMatchingServices
(kIOMasterPortDefault, IOServiceMatching (kIOBlockStorageDeviceClass), &i);
if (err != kIOReturnSuccess)
return -1;
// Count the devices.
result = 0;
while ((device = IOIteratorNext (i)) != MACH_PORT_NULL) {
if (is_smart_capable (device))
result++;
IOObjectRelease (device);
}
// Create an array of service names.
IOIteratorReset (i);
*devlist = (char**)Calloc (result, sizeof (char *));
if (! *devlist)
goto error;
index = 0;
while ((device = IOIteratorNext (i)) != MACH_PORT_NULL) {
if (is_smart_capable (device))
{
io_string_t devName;
IORegistryEntryGetPath(device, kIOServicePlane, devName);
(*devlist)[index] = CustomStrDup (devName, true, __LINE__, __FILE__);
if (! (*devlist)[index])
goto error;
index++;
}
IOObjectRelease (device);
}
IOObjectRelease (i);
return result;
error:
if (device != MACH_PORT_NULL)
IOObjectRelease (device);
IOObjectRelease (i);
if (*devlist)
{
for (index = 0; index < result; index++)
if ((*devlist)[index])
FreeNonZero ((*devlist)[index], 0, __LINE__, __FILE__);
FreeNonZero (*devlist, result * sizeof (char *), __LINE__, __FILE__);
}
return -1;
}
// Information that we keep about each device.
static struct {
io_object_t ioob;
IOCFPlugInInterface **plugin;
IOATASMARTInterface **smartIf;
} devices[20];
// Like open(). Return non-negative integer handle, only used by the
// functions below. type=="ATA" or "SCSI". The return value is
// an index into the devices[] array. If the device can't be opened,
// sets errno and returns -1.
// Acceptable device names are:
// /dev/disk*
// /dev/rdisk*
// disk*
// IOService:*
// IODeviceTree:*
int deviceopen(const char *pathname, char *type){
size_t devnum; size_t devnum;
const char *devname; const char *devname;
io_object_t disk; io_object_t disk;
const char *pathname = get_dev_name();
char *type = const_cast<char*>(m_mode);
if (strcmp (type, "ATA") != 0) if (strcmp (type, "ATA") != 0)
{ {
@ -258,11 +231,11 @@ int deviceopen(const char *pathname, char *type){
// Find this device's parent and try again. // Find this device's parent and try again.
err = IORegistryEntryGetParentEntry (disk, kIOServicePlane, &disk); err = IORegistryEntryGetParentEntry (disk, kIOServicePlane, &disk);
if (err != kIOReturnSuccess || ! disk) if (err != kIOReturnSuccess || ! disk)
{ {
errno = ENODEV; errno = ENODEV;
IOObjectRelease (prevdisk); IOObjectRelease (prevdisk);
return -1; return -1;
} }
} }
devices[devnum].ioob = disk; devices[devnum].ioob = disk;
@ -275,151 +248,332 @@ int deviceopen(const char *pathname, char *type){
// Create an interface to the ATA SMART library. // Create an interface to the ATA SMART library.
if (IOCreatePlugInInterfaceForService (disk, if (IOCreatePlugInInterfaceForService (disk,
kIOATASMARTUserClientTypeID, kIOATASMARTUserClientTypeID,
kIOCFPlugInInterfaceID, kIOCFPlugInInterfaceID,
&devices[devnum].plugin, &devices[devnum].plugin,
&dummy) == kIOReturnSuccess) &dummy) == kIOReturnSuccess)
(*devices[devnum].plugin)->QueryInterface (*devices[devnum].plugin)->QueryInterface
(devices[devnum].plugin, (devices[devnum].plugin,
CFUUIDGetUUIDBytes ( kIOATASMARTInterfaceID), CFUUIDGetUUIDBytes ( kIOATASMARTInterfaceID),
(void **)&devices[devnum].smartIf); (void **)&devices[devnum].smartIf);
} }
return devnum;
m_fd = devnum;
if (m_fd < 0) {
set_err((errno==ENOENT || errno==ENOTDIR) ? ENODEV : errno);
return false;
}
return true;
} }
// Like close(). Acts only on integer handles returned by bool darwin_smart_device::close()
// deviceopen() above. {
int deviceclose(int fd){ int fd = m_fd; m_fd = -1;
if (devices[fd].smartIf) if (devices[fd].smartIf)
(*devices[fd].smartIf)->Release (devices[fd].smartIf); (*devices[fd].smartIf)->Release (devices[fd].smartIf);
if (devices[fd].plugin) if (devices[fd].plugin)
IODestroyPlugInInterface (devices[fd].plugin); IODestroyPlugInInterface (devices[fd].plugin);
IOObjectRelease (devices[fd].ioob); IOObjectRelease (devices[fd].ioob);
devices[fd].ioob = MACH_PORT_NULL; devices[fd].ioob = MACH_PORT_NULL;
return 0; return true;
} }
// Interface to ATA devices. See os_linux.cpp for the cannonical example. // makes a list of ATA or SCSI devices for the DEVICESCAN directive of
// DETAILED DESCRIPTION OF ARGUMENTS // smartd. Returns number N of devices, or -1 if out of
// device: is the integer handle provided by deviceopen() // memory. Allocates N+1 arrays: one of N pointers (devlist); the
// command: defines the different operations, see atacmds.h // other N arrays each contain null-terminated character strings. In
// select: additional input data IF NEEDED (which log, which type of // the case N==0, no arrays are allocated because the array of 0
// self-test). // pointers has zero length, equivalent to calling malloc(0).
// data: location to write output data, IF NEEDED (1 or 512 bytes). static int make_device_names (char*** devlist, const char* name) {
// Note: not all commands use all arguments. IOReturn err;
// RETURN VALUES (for all commands BUT command==STATUS_CHECK) io_iterator_t i;
// -1 if the command failed io_object_t device = MACH_PORT_NULL;
// 0 if the command succeeded, int result;
// RETURN VALUES if command==STATUS_CHECK int index;
// -1 if the command failed OR the disk SMART status can't be determined
// 0 if the command succeeded and disk SMART status is "OK"
// 1 if the command succeeded and disk SMART status is "FAILING"
// Things that aren't available in the Darwin interfaces: // We treat all devices as ATA so long as they support SMARTLib.
// - Tests other than short and extended (in particular, can't run if (strcmp (name, "ATA") != 0)
// an immediate offline test) return 0;
// - Captive-mode tests, aborting tests
// - ability to switch automatic offline testing on or off
// Note that some versions of Darwin, at least 7H63 and earlier, err = IOServiceGetMatchingServices
// have a buggy library that treats the boolean value in (kIOMasterPortDefault, IOServiceMatching (kIOBlockStorageDeviceClass), &i);
// SMARTEnableDisableOperations, SMARTEnableDisableAutosave, and if (err != kIOReturnSuccess)
// SMARTExecuteOffLineImmediate as always being true. return -1;
int
ata_command_interface(int fd, smart_command_set command, // Count the devices.
int select, char *data) result = 0;
while ((device = IOIteratorNext (i)) != MACH_PORT_NULL) {
if (is_smart_capable (device))
result++;
IOObjectRelease (device);
}
// Create an array of service names.
IOIteratorReset (i);
*devlist = (char**)calloc (result, sizeof (char *));
if (! *devlist)
goto error;
index = 0;
while ((device = IOIteratorNext (i)) != MACH_PORT_NULL) {
if (is_smart_capable (device))
{
io_string_t devName;
IORegistryEntryGetPath(device, kIOServicePlane, devName);
(*devlist)[index] = strdup (devName);
if (! (*devlist)[index])
goto error;
index++;
}
IOObjectRelease (device);
}
IOObjectRelease (i);
return result;
error:
if (device != MACH_PORT_NULL)
IOObjectRelease (device);
IOObjectRelease (i);
if (*devlist)
{
for (index = 0; index < result; index++)
if ((*devlist)[index])
free ((*devlist)[index]);
free (*devlist);
}
return -1;
}
/////////////////////////////////////////////////////////////////////////////
/// Implement standard ATA support
class darwin_ata_device
: public /*implements*/ ata_device,
public /*extends*/ darwin_smart_device
{ {
public:
darwin_ata_device(smart_interface * intf, const char * dev_name, const char * req_type);
virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out);
protected:
// virtual int ata_command_interface(smart_command_set command, int select, char * data);
};
darwin_ata_device::darwin_ata_device(smart_interface * intf, const char * dev_name, const char * req_type)
: smart_device(intf, dev_name, "ata", req_type),
darwin_smart_device("ATA")
{
}
bool darwin_ata_device::ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out)
{
if (!ata_cmd_is_ok(in,
true, // data_out_support
true, // multi_sector_support
false) // not supported by API
)
return false;
int select = 0;
char * data = (char *)in.buffer;
int fd = get_fd();
IOATASMARTInterface **ifp = devices[fd].smartIf; IOATASMARTInterface **ifp = devices[fd].smartIf;
IOATASMARTInterface *smartIf; IOATASMARTInterface *smartIf;
IOReturn err; IOReturn err;
int timeoutCount = 5; int timeoutCount = 5;
int rc = 0;
if (! ifp) if (! ifp)
return -1; return -1;
smartIf = *ifp; smartIf = *ifp;
clear_err(); errno = 0;
do { do {
switch (command) switch (in.in_regs.command) {
case ATA_IDENTIFY_DEVICE:
{ {
case STATUS: UInt32 dummy;
return 0; err = smartIf->GetATAIdentifyData (ifp, data, 512, &dummy);
case STATUS_CHECK: if (err != kIOReturnSuccess && err != kIOReturnTimeout
{ && err != kIOReturnNotResponding)
Boolean is_failing; printf ("identify failed: %#x\n", (unsigned) rc);
err = smartIf->SMARTReturnStatus (ifp, &is_failing); if (err == kIOReturnSuccess && isbigendian())
if (err == kIOReturnSuccess && is_failing) {
return 1; int i;
break; /* The system has already byte-swapped, undo it. */
} for (i = 0; i < 256; i+=2)
case ENABLE: swap2 (data + i);
case DISABLE: }
err = smartIf->SMARTEnableDisableOperations (ifp, command == ENABLE);
break;
case AUTOSAVE:
err = smartIf->SMARTEnableDisableAutosave (ifp, select != 0);
break;
case IMMEDIATE_OFFLINE:
if (select != SHORT_SELF_TEST && select != EXTEND_SELF_TEST)
{
errno = EINVAL;
return -1;
}
err = smartIf->SMARTExecuteOffLineImmediate (ifp,
select == EXTEND_SELF_TEST);
break;
case READ_VALUES:
err = smartIf->SMARTReadData (ifp, (ATASMARTData *)data);
break;
case READ_THRESHOLDS:
err = smartIf->SMARTReadDataThresholds (ifp,
(ATASMARTDataThresholds *)data);
break;
case READ_LOG:
err = smartIf->SMARTReadLogAtAddress (ifp, select, data, 512);
break;
case WRITE_LOG:
err = smartIf->SMARTWriteLogAtAddress (ifp, select, data, 512);
break;
case IDENTIFY:
{
UInt32 dummy;
err = smartIf->GetATAIdentifyData (ifp, data, 512, &dummy);
if (err != kIOReturnSuccess && err != kIOReturnTimeout
&& err != kIOReturnNotResponding)
printf ("identify failed: %#x\n", (unsigned) err);
if (err == kIOReturnSuccess && isbigendian())
{
int i;
/* The system has already byte-swapped, undo it. */
for (i = 0; i < 256; i+=2)
swap2 (data + i);
}
}
break;
case CHECK_POWER_MODE:
// The information is right there in the device registry, but how
// to get to it portably?
default:
errno = ENOTSUP;
return -1;
} }
/* This bit is a bit strange. Apparently, when the drive is spun break;
down, the intended behaviour of these calls is that they fail, case ATA_IDENTIFY_PACKET_DEVICE:
return kIOReturnTimeout and then power the drive up. So if case ATA_CHECK_POWER_MODE:
you get a timeout, you have to try again to get the actual errno = ENOTSUP;
command run, but the drive is already powering up so you can't err = -1;
use this for CHECK_POWER_MODE. */ break;
if (err == kIOReturnTimeout || err == kIOReturnNotResponding) case ATA_SMART_CMD:
sleep (1); switch (in.in_regs.features) {
case ATA_SMART_READ_VALUES:
err = smartIf->SMARTReadData (ifp, (ATASMARTData *)data);
break;
case ATA_SMART_READ_THRESHOLDS:
err = smartIf->SMARTReadDataThresholds (ifp,
(ATASMARTDataThresholds *)data);
break;
case ATA_SMART_READ_LOG_SECTOR:
err = smartIf->SMARTReadLogAtAddress (ifp, in.in_regs.lba_low, data, 512 * in.in_regs.sector_count);
break;
case ATA_SMART_WRITE_LOG_SECTOR:
err = smartIf->SMARTWriteLogAtAddress (ifp, in.in_regs.lba_low, data, 512 * in.in_regs.sector_count);
break;
case ATA_SMART_ENABLE:
case ATA_SMART_DISABLE:
err = smartIf->SMARTEnableDisableOperations (ifp, in.in_regs.features == ATA_SMART_ENABLE);
break;
case ATA_SMART_STATUS:
if (in.out_needed.lba_high) // statuscheck
{
Boolean is_failing;
err = smartIf->SMARTReturnStatus (ifp, &is_failing);
if (err == kIOReturnSuccess && is_failing) {
err = -1; // thresholds exceeded condition
out.out_regs.lba_high = 0x2c; out.out_regs.lba_mid = 0xf4;
}
else
out.out_regs.lba_high = 0xc2; out.out_regs.lba_mid = 0x4f;
break;
}
else err = 0;
break;
case ATA_SMART_AUTOSAVE:
err = smartIf->SMARTEnableDisableAutosave (ifp,
(in.in_regs.sector_count == 241 ? true : false));
break;
case ATA_SMART_IMMEDIATE_OFFLINE:
select = in.in_regs.lba_low;
if (select != SHORT_SELF_TEST && select != EXTEND_SELF_TEST)
{
errno = EINVAL;
err = -1;
}
err = smartIf->SMARTExecuteOffLineImmediate (ifp,
select == EXTEND_SELF_TEST);
break;
case ATA_SMART_AUTO_OFFLINE:
return set_err(ENOSYS, "SMART command not supported");
default:
return set_err(ENOSYS, "Unknown SMART command");
}
break;
default:
return set_err(ENOSYS, "Non-SMART commands not implemented");
}
} while ((err == kIOReturnTimeout || err == kIOReturnNotResponding) } while ((err == kIOReturnTimeout || err == kIOReturnNotResponding)
&& timeoutCount-- > 0); && timeoutCount-- > 0);
if (err == kIOReturnExclusiveAccess) if (err == kIOReturnExclusiveAccess)
errno = EBUSY; errno = EBUSY;
return err == kIOReturnSuccess ? 0 : -1; rc = err == kIOReturnSuccess ? 0 : -1;
if (rc < 0) {
if (!get_errno())
set_err(errno);
return false;
}
return true;
} }
// Interface to SCSI devices. See os_linux.c /////////////////////////////////////////////////////////////////////////////
int do_scsi_cmnd_io(int /* fd */, struct scsi_cmnd_io * /* iop */, int /* report */) { /// Implement platform interface
return -ENOSYS;
class darwin_smart_interface
: public /*implements*/ smart_interface
{
public:
virtual std::string get_app_examples(const char * appname);
virtual bool scan_smart_devices(smart_device_list & devlist, const char * type,
const char * pattern = 0);
protected:
virtual ata_device * get_ata_device(const char * name, const char * type);
virtual scsi_device * get_scsi_device(const char * name, const char * type);
virtual smart_device * autodetect_smart_device(const char * name);
};
//////////////////////////////////////////////////////////////////////
std::string darwin_smart_interface::get_app_examples(const char * appname)
{
if (!strcmp(appname, "smartctl"))
return smartctl_examples;
return ""; // ... so don't print again.
}
ata_device * darwin_smart_interface::get_ata_device(const char * name, const char * type)
{
return new darwin_ata_device(this, name, type);
}
scsi_device * darwin_smart_interface::get_scsi_device(const char *, const char *)
{
return 0; // scsi devices are not supported [yet]
}
smart_device * darwin_smart_interface::autodetect_smart_device(const char * name)
{
return new darwin_ata_device(this, name, "");
}
static void free_devnames(char * * devnames, int numdevs)
{
for (int i = 0; i < numdevs; i++)
free(devnames[i]);
free(devnames);
}
bool darwin_smart_interface::scan_smart_devices(smart_device_list & devlist,
const char * type, const char * pattern /*= 0*/)
{
if (pattern) {
set_err(EINVAL, "DEVICESCAN with pattern not implemented yet");
return false;
}
// Make namelists
char * * atanames = 0; int numata = 0;
if (!type || !strcmp(type, "ata")) {
numata = make_device_names(&atanames, "ATA");
if (numata < 0) {
set_err(ENOMEM);
return false;
}
}
// Add to devlist
int i;
if (!type)
type="";
for (i = 0; i < numata; i++) {
ata_device * atadev = get_ata_device(atanames[i], type);
if (atadev)
devlist.push_back(atadev);
}
free_devnames(atanames, numata);
return true;
}
} // namespace
/////////////////////////////////////////////////////////////////////////////
/// Initialize platform interface and register with smi()
void smart_interface::init()
{
static os::darwin_smart_interface the_interface;
smart_interface::set(&the_interface);
} }

View File

@ -75,7 +75,7 @@
#define PATHINQ_SETTINGS_SIZE 128 #define PATHINQ_SETTINGS_SIZE 128
#endif #endif
const char *os_XXXX_c_cvsid="$Id: os_freebsd.cpp 3824 2013-07-05 10:40:38Z samm2 $" \ const char *os_XXXX_c_cvsid="$Id: os_freebsd.cpp 3902 2014-05-23 19:14:15Z samm2 $" \
ATACMDS_H_CVSID CCISS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_FREEBSD_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID; ATACMDS_H_CVSID CCISS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_FREEBSD_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
#define NO_RETURN 0 #define NO_RETURN 0
@ -135,9 +135,9 @@ class freebsd_smart_device
: virtual public /*implements*/ smart_device : virtual public /*implements*/ smart_device
{ {
public: public:
explicit freebsd_smart_device(const char * mode) explicit freebsd_smart_device()
: smart_device(never_called), : smart_device(never_called),
m_fd(-1), m_mode(mode) { } m_fd(-1) { }
virtual ~freebsd_smart_device() throw(); virtual ~freebsd_smart_device() throw();
@ -157,7 +157,6 @@ protected:
private: private:
int m_fd; ///< filedesc, -1 if not open. int m_fd; ///< filedesc, -1 if not open.
const char * m_mode; ///< Mode string for deviceopen().
}; };
#ifdef __GLIBC__ #ifdef __GLIBC__
@ -249,7 +248,7 @@ protected:
freebsd_ata_device::freebsd_ata_device(smart_interface * intf, const char * dev_name, const char * req_type) freebsd_ata_device::freebsd_ata_device(smart_interface * intf, const char * dev_name, const char * req_type)
: smart_device(intf, dev_name, "ata", req_type), : smart_device(intf, dev_name, "ata", req_type),
freebsd_smart_device("ATA") freebsd_smart_device()
{ {
} }
@ -445,7 +444,8 @@ int freebsd_atacam_device::do_cmd( struct ata_ioc_request* request, bool is_48bi
} }
if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
cam_error_print(m_camdev, &ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr); if(scsi_debugmode > 0)
cam_error_print(m_camdev, &ccb, CAM_ESF_ALL, CAM_EPF_ALL, stderr);
set_err(EIO); set_err(EIO);
return -1; return -1;
} }
@ -489,10 +489,7 @@ private:
freebsd_escalade_device::freebsd_escalade_device(smart_interface * intf, const char * dev_name, freebsd_escalade_device::freebsd_escalade_device(smart_interface * intf, const char * dev_name,
int escalade_type, int disknum) int escalade_type, int disknum)
: smart_device(intf, dev_name, "3ware", "3ware"), : smart_device(intf, dev_name, "3ware", "3ware"),
freebsd_smart_device( freebsd_smart_device(),
escalade_type==CONTROLLER_3WARE_9000_CHAR ? "ATA_3WARE_9000" :
escalade_type==CONTROLLER_3WARE_678K_CHAR ? "ATA_3WARE_678K" :
/* CONTROLLER_3WARE_678K */ "ATA" ),
m_escalade_type(escalade_type), m_disknum(disknum) m_escalade_type(escalade_type), m_disknum(disknum)
{ {
set_info().info_name = strprintf("%s [3ware_disk_%02d]", dev_name, disknum); set_info().info_name = strprintf("%s [3ware_disk_%02d]", dev_name, disknum);
@ -704,7 +701,7 @@ private:
freebsd_highpoint_device::freebsd_highpoint_device(smart_interface * intf, const char * dev_name, freebsd_highpoint_device::freebsd_highpoint_device(smart_interface * intf, const char * dev_name,
unsigned char controller, unsigned char channel, unsigned char port) unsigned char controller, unsigned char channel, unsigned char port)
: smart_device(intf, dev_name, "hpt", "hpt"), : smart_device(intf, dev_name, "hpt", "hpt"),
freebsd_smart_device("ATA") freebsd_smart_device()
{ {
m_hpt_data[0] = controller; m_hpt_data[1] = channel; m_hpt_data[2] = port; m_hpt_data[0] = controller; m_hpt_data[1] = channel; m_hpt_data[2] = port;
set_info().info_name = strprintf("%s [hpt_disk_%u/%u/%u]", dev_name, m_hpt_data[0], m_hpt_data[1], m_hpt_data[2]); set_info().info_name = strprintf("%s [hpt_disk_%u/%u/%u]", dev_name, m_hpt_data[0], m_hpt_data[1], m_hpt_data[2]);
@ -897,7 +894,6 @@ public:
virtual bool close(); virtual bool close();
private: private:
int m_fd;
struct cam_device *m_camdev; struct cam_device *m_camdev;
}; };
@ -921,17 +917,16 @@ bool freebsd_scsi_device::close(){
freebsd_scsi_device::freebsd_scsi_device(smart_interface * intf, freebsd_scsi_device::freebsd_scsi_device(smart_interface * intf,
const char * dev_name, const char * req_type) const char * dev_name, const char * req_type)
: smart_device(intf, dev_name, "scsi", req_type), : smart_device(intf, dev_name, "scsi", req_type),
freebsd_smart_device("SCSI") freebsd_smart_device()
{ {
} }
bool freebsd_scsi_device::scsi_pass_through(scsi_cmnd_io * iop) bool freebsd_scsi_device::scsi_pass_through(scsi_cmnd_io * iop)
{ {
int report=scsi_debugmode;
union ccb *ccb; union ccb *ccb;
if (report > 0) { if (scsi_debugmode) {
unsigned int k; unsigned int k;
const unsigned char * ucp = iop->cmnd; const unsigned char * ucp = iop->cmnd;
const char * np; const char * np;
@ -940,7 +935,7 @@ bool freebsd_scsi_device::scsi_pass_through(scsi_cmnd_io * iop)
pout(" [%s: ", np ? np : "<unknown opcode>"); pout(" [%s: ", np ? np : "<unknown opcode>");
for (k = 0; k < iop->cmnd_len; ++k) for (k = 0; k < iop->cmnd_len; ++k)
pout("%02x ", ucp[k]); pout("%02x ", ucp[k]);
if ((report > 1) && if ((scsi_debugmode > 1) &&
(DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) { (DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
int trunc = (iop->dxfer_len > 256) ? 1 : 0; int trunc = (iop->dxfer_len > 256) ? 1 : 0;
@ -949,18 +944,21 @@ bool freebsd_scsi_device::scsi_pass_through(scsi_cmnd_io * iop)
dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1); dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
} }
else else
pout("]"); pout("]\n");
} }
if(m_camdev==NULL) { if(m_camdev==NULL) {
warnx("error: camdev=0!"); if (scsi_debugmode)
return -ENOTTY; pout(" error: camdev=0!\n");
return set_err(ENOTTY);
} }
if (!(ccb = cam_getccb(m_camdev))) { if (!(ccb = cam_getccb(m_camdev))) {
warnx("error allocating ccb"); if (scsi_debugmode)
return -ENOMEM; pout(" error allocating ccb\n");
return set_err(ENOMEM);
} }
// mfi SAT layer is known to be buggy // mfi SAT layer is known to be buggy
if(!strcmp("mfi",m_camdev->sim_name)) { if(!strcmp("mfi",m_camdev->sim_name)) {
if (iop->cmnd[0] == SAT_ATA_PASSTHROUGH_12 || iop->cmnd[0] == SAT_ATA_PASSTHROUGH_16) { if (iop->cmnd[0] == SAT_ATA_PASSTHROUGH_12 || iop->cmnd[0] == SAT_ATA_PASSTHROUGH_16) {
@ -984,8 +982,8 @@ bool freebsd_scsi_device::scsi_pass_through(scsi_cmnd_io * iop)
sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr)); sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
cam_fill_csio(&ccb->csio, cam_fill_csio(&ccb->csio,
/*retrires*/ 1, /* retries */ 1,
/*cbfcnp*/ NULL, /* cbfcnp */ NULL,
/* flags */ (iop->dxfer_dir == DXFER_NONE ? CAM_DIR_NONE :(iop->dxfer_dir == DXFER_FROM_DEVICE ? CAM_DIR_IN : CAM_DIR_OUT)), /* flags */ (iop->dxfer_dir == DXFER_NONE ? CAM_DIR_NONE :(iop->dxfer_dir == DXFER_FROM_DEVICE ? CAM_DIR_IN : CAM_DIR_OUT)),
/* tagaction */ MSG_SIMPLE_Q_TAG, /* tagaction */ MSG_SIMPLE_Q_TAG,
/* dataptr */ iop->dxferp, /* dataptr */ iop->dxferp,
@ -996,44 +994,81 @@ bool freebsd_scsi_device::scsi_pass_through(scsi_cmnd_io * iop)
memcpy(ccb->csio.cdb_io.cdb_bytes,iop->cmnd,iop->cmnd_len); memcpy(ccb->csio.cdb_io.cdb_bytes,iop->cmnd,iop->cmnd_len);
if (cam_send_ccb(m_camdev,ccb) < 0) { if (cam_send_ccb(m_camdev,ccb) < 0) {
warn("error sending SCSI ccb"); if (scsi_debugmode) {
cam_error_print(m_camdev,ccb,CAM_ESF_ALL,CAM_EPF_ALL,stderr); pout(" error sending SCSI ccb\n");
cam_error_print(m_camdev,ccb,CAM_ESF_ALL,CAM_EPF_ALL,stderr);
}
cam_freeccb(ccb); cam_freeccb(ccb);
return -EIO; return set_err(EIO);
}
if (scsi_debugmode) {
pout(" CAM status=0x%x, SCSI status=0x%x, resid=0x%x\n",
ccb->ccb_h.status, ccb->csio.scsi_status, ccb->csio.resid);
if ((scsi_debugmode > 1) && (DXFER_FROM_DEVICE == iop->dxfer_dir)) {
int trunc, len;
len = iop->dxfer_len - ccb->csio.resid;
trunc = (len > 256) ? 1 : 0;
if (len > 0) {
pout(" Incoming data, len=%d%s:\n", len,
(trunc ? " [only first 256 bytes shown]" : ""));
dStrHex(iop->dxferp, (trunc ? 256 : len), 1);
}
else
pout(" Incoming data trimmed to nothing by resid\n");
}
} }
if (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_SCSI_STATUS_ERROR)) { if (((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) && ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_SCSI_STATUS_ERROR)) {
cam_error_print(m_camdev,ccb,CAM_ESF_ALL,CAM_EPF_ALL,stderr); if (scsi_debugmode)
cam_error_print(m_camdev,ccb,CAM_ESF_ALL,CAM_EPF_ALL,stderr);
cam_freeccb(ccb); cam_freeccb(ccb);
return -EIO; return set_err(EIO);
}
if (iop->sensep) {
iop->resp_sense_len = ccb->csio.sense_len - ccb->csio.sense_resid;
memcpy(iop->sensep,&(ccb->csio.sense_data),iop->resp_sense_len);
} }
iop->resid = ccb->csio.resid;
iop->scsi_status = ccb->csio.scsi_status; iop->scsi_status = ccb->csio.scsi_status;
if (iop->sensep && (ccb->ccb_h.status & CAM_AUTOSNS_VALID) != 0) {
if (scsi_debugmode)
pout(" sense_len=0x%x, sense_resid=0x%x\n",
ccb->csio.sense_len, ccb->csio.sense_resid);
iop->resp_sense_len = ccb->csio.sense_len - ccb->csio.sense_resid;
/* Some SCSI controller device drivers miscalculate the sense_resid
field so cap resp_sense_len on max_sense_len. */
if (iop->resp_sense_len > iop->max_sense_len)
iop->resp_sense_len = iop->max_sense_len;
if (iop->resp_sense_len > 0) {
memcpy(iop->sensep, &(ccb->csio.sense_data), iop->resp_sense_len);
if (scsi_debugmode) {
if (scsi_debugmode > 1) {
pout(" >>> Sense buffer, len=%zu:\n", iop->resp_sense_len);
dStrHex(iop->sensep, iop->resp_sense_len, 1);
}
if ((iop->sensep[0] & 0x7f) > 0x71)
pout(" status=0x%x: [desc] sense_key=0x%x asc=0x%x ascq=0x%x\n",
iop->scsi_status, iop->sensep[1] & 0xf,
iop->sensep[2], iop->sensep[3]);
else
pout(" status=0x%x: sense_key=0x%x asc=0x%x ascq=0x%x\n",
iop->scsi_status, iop->sensep[2] & 0xf,
iop->sensep[12], iop->sensep[13]);
}
}
else if (scsi_debugmode)
pout(" status=0x%x\n", iop->scsi_status);
}
else if (scsi_debugmode)
pout(" status=0x%x\n", iop->scsi_status);
cam_freeccb(ccb); cam_freeccb(ccb);
if (report > 0) {
int trunc;
pout(" status=0\n");
trunc = (iop->dxfer_len > 256) ? 1 : 0;
pout(" Incoming data, len=%d%s:\n", (int)iop->dxfer_len,
(trunc ? " [only first 256 bytes shown]" : ""));
dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
}
// mfip replacing PDT of the device so response does not make a sense // mfip replacing PDT of the device so response does not make a sense
// this sets PDT to 00h - direct-access block device // this sets PDT to 00h - direct-access block device
if((!strcmp("mfi", m_camdev->sim_name) || !strcmp("mpt", m_camdev->sim_name)) if((!strcmp("mfi", m_camdev->sim_name) || !strcmp("mpt", m_camdev->sim_name))
&& iop->cmnd[0] == INQUIRY) { && iop->cmnd[0] == INQUIRY) {
if (report > 0) { if (scsi_debugmode) {
pout("device on %s controller, patching PDT\n", m_camdev->sim_name); pout(" device on %s controller, patching PDT\n", m_camdev->sim_name);
} }
iop->dxferp[0] = iop->dxferp[0] & 0xe0; iop->dxferp[0] = iop->dxferp[0] & 0xe0;
} }
@ -1077,7 +1112,7 @@ public:
// Areca RAID Controller(SATA Disk) // Areca RAID Controller(SATA Disk)
freebsd_areca_ata_device::freebsd_areca_ata_device(smart_interface * intf, const char * dev_name, int disknum, int encnum) freebsd_areca_ata_device::freebsd_areca_ata_device(smart_interface * intf, const char * dev_name, int disknum, int encnum)
: smart_device(intf, dev_name, "areca", "areca"), : smart_device(intf, dev_name, "areca", "areca"),
freebsd_smart_device("ATA") freebsd_smart_device()
{ {
set_disknum(disknum); set_disknum(disknum);
set_encnum(encnum); set_encnum(encnum);
@ -1146,7 +1181,7 @@ bool freebsd_areca_ata_device::arcmsr_unlock()
// Areca RAID Controller(SAS Device) // Areca RAID Controller(SAS Device)
freebsd_areca_scsi_device::freebsd_areca_scsi_device(smart_interface * intf, const char * dev_name, int disknum, int encnum) freebsd_areca_scsi_device::freebsd_areca_scsi_device(smart_interface * intf, const char * dev_name, int disknum, int encnum)
: smart_device(intf, dev_name, "areca", "areca"), : smart_device(intf, dev_name, "areca", "areca"),
freebsd_smart_device("SCSI") freebsd_smart_device()
{ {
set_disknum(disknum); set_disknum(disknum);
set_encnum(encnum); set_encnum(encnum);
@ -1220,7 +1255,7 @@ bool freebsd_cciss_device::open()
freebsd_cciss_device::freebsd_cciss_device(smart_interface * intf, freebsd_cciss_device::freebsd_cciss_device(smart_interface * intf,
const char * dev_name, unsigned char disknum) const char * dev_name, unsigned char disknum)
: smart_device(intf, dev_name, "cciss", "cciss"), : smart_device(intf, dev_name, "cciss", "cciss"),
freebsd_smart_device("SCSI"), freebsd_smart_device(),
m_disknum(disknum) m_disknum(disknum)
{ {
set_info().info_name = strprintf("%s [cciss_disk_%02d]", dev_name, disknum); set_info().info_name = strprintf("%s [cciss_disk_%02d]", dev_name, disknum);

View File

@ -5,16 +5,23 @@
* *
* Copyright (C) 2003-11 Bruce Allen <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2003-11 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2003-11 Doug Gilbert <dgilbert@interlog.com> * Copyright (C) 2003-11 Doug Gilbert <dgilbert@interlog.com>
* Copyright (C) 2008-12 Hank Wu <hank@areca.com.tw> * Copyright (C) 2008-14 Christian Franke <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2008 Oliver Bock <brevilo@users.sourceforge.net>
* Copyright (C) 2008-12 Christian Franke <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2008 Jordan Hargrave <jordan_hargrave@dell.com>
* *
* Parts of this file are derived from code that was * Original AACRaid code:
* Copyright (C) 2014 Raghava Aditya <raghava.aditya@pmcs.com>
*
* Original Areca code:
* Copyright (C) 2008-12 Hank Wu <hank@areca.com.tw>
* Copyright (C) 2008 Oliver Bock <brevilo@users.sourceforge.net>
*
* Original MegaRAID code:
* Copyright (C) 2008 Jordan Hargrave <jordan_hargrave@dell.com>
*
* 3ware code was derived from code that was:
* *
* Written By: Adam Radford <linux@3ware.com> * Written By: Adam Radford <linux@3ware.com>
* Modifications By: Joel Jacobson <linux@3ware.com> * Modifications By: Joel Jacobson <linux@3ware.com>
* Arnaldo Carvalho de Melo <acme@conectiva.com.br> * Arnaldo Carvalho de Melo <acme@conectiva.com.br>
* Brad Strand <linux@3ware.com> * Brad Strand <linux@3ware.com>
* *
* Copyright (C) 1999-2003 3ware Inc. * Copyright (C) 1999-2003 3ware Inc.
@ -80,6 +87,7 @@
#include "utility.h" #include "utility.h"
#include "cciss.h" #include "cciss.h"
#include "megaraid.h" #include "megaraid.h"
#include "aacraid.h"
#include "dev_interface.h" #include "dev_interface.h"
#include "dev_ata_cmd_set.h" #include "dev_ata_cmd_set.h"
@ -91,7 +99,7 @@
#define ARGUSED(x) ((void)(x)) #define ARGUSED(x) ((void)(x))
const char * os_linux_cpp_cvsid = "$Id: os_linux.cpp 3824 2013-07-05 10:40:38Z samm2 $" const char * os_linux_cpp_cvsid = "$Id: os_linux.cpp 3900 2014-05-01 17:08:59Z chrfranke $"
OS_LINUX_H_CVSID; OS_LINUX_H_CVSID;
extern unsigned char failuretest_permissive; extern unsigned char failuretest_permissive;
@ -859,6 +867,217 @@ bool linux_scsi_device::scsi_pass_through(scsi_cmnd_io * iop)
return true; return true;
} }
/////////////////////////////////////////////////////////////////////////////
/// PMC AacRAID support
class linux_aacraid_device
:public scsi_device,
public /*extends */ linux_smart_device
{
public:
linux_aacraid_device(smart_interface *intf, const char *dev_name,
unsigned int host, unsigned int channel, unsigned int device);
virtual ~linux_aacraid_device() throw();
virtual bool open();
virtual bool scsi_pass_through(scsi_cmnd_io *iop);
private:
//Device Host number
int aHost;
//Channel(Lun) of the device
int aLun;
//Id of the device
int aId;
};
linux_aacraid_device::linux_aacraid_device(smart_interface *intf,
const char *dev_name, unsigned int host, unsigned int channel, unsigned int device)
: smart_device(intf,dev_name,"aacraid","aacraid"),
linux_smart_device(O_RDWR|O_NONBLOCK),
aHost(host), aLun(channel), aId(device)
{
set_info().info_name = strprintf("%s [aacraid_disk_%02d_%02d_%d]",dev_name,aHost,aLun,aId);
set_info().dev_type = strprintf("aacraid,%d,%d,%d",aHost,aLun,aId);
}
linux_aacraid_device::~linux_aacraid_device() throw()
{
}
bool linux_aacraid_device::open()
{
//Create the character device name based on the host number
//Required for get stats from disks connected to different controllers
char dev_name[128];
snprintf(dev_name, sizeof(dev_name), "/dev/aac%d", aHost);
//Initial open of dev name to check if it exsists
int afd = ::open(dev_name,O_RDWR);
if(afd < 0 && errno == ENOENT) {
FILE *fp = fopen("/proc/devices","r");
if(NULL == fp)
return set_err(errno,"cannot open /proc/devices:%s",
strerror(errno));
char line[256];
int mjr = -1;
while(fgets(line,sizeof(line),fp) !=NULL) {
int nc = -1;
if(sscanf(line,"%d aac%n",&mjr,&nc) == 1
&& nc > 0 && '\n' == line[nc])
break;
mjr = -1;
}
//work with /proc/devices is done
fclose(fp);
if (mjr < 0)
return set_err(ENOENT, "aac entry not found in /proc/devices");
//Create misc device file in /dev/ used for communication with driver
if(mknod(dev_name,S_IFCHR,makedev(mjr,aHost)))
return set_err(errno,"cannot create %s:%s",dev_name,strerror(errno));
afd = ::open(dev_name,O_RDWR);
}
if(afd < 0)
return set_err(errno,"cannot open %s:%s",dev_name,strerror(errno));
set_fd(afd);
return true;
}
bool linux_aacraid_device::scsi_pass_through(scsi_cmnd_io *iop)
{
int report = scsi_debugmode;
if (report > 0) {
int k, j;
const unsigned char * ucp = iop->cmnd;
const char * np;
char buff[256];
const int sz = (int)sizeof(buff);
np = scsi_get_opcode_name(ucp[0]);
j = snprintf(buff, sz, " [%s: ", np ? np : "<unknown opcode>");
for (k = 0; k < (int)iop->cmnd_len; ++k)
j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "%02x ", ucp[k]);
if ((report > 1) &&
(DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
int trunc = (iop->dxfer_len > 256) ? 1 : 0;
j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n Outgoing "
"data, len=%d%s:\n", (int)iop->dxfer_len,
(trunc ? " [only first 256 bytes shown]" : ""));
dStrHex((const char *)iop->dxferp,
(trunc ? 256 : iop->dxfer_len) , 1);
}
else
j += snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n");
pout("%s", buff);
}
//return test commands
if (iop->cmnd[0] == 0x00)
return true;
user_aac_reply *pReply;
#ifdef ENVIRONMENT64
// Create user 64 bit request
user_aac_srb64 *pSrb;
uint8_t aBuff[sizeof(user_aac_srb64) + sizeof(user_aac_reply)] = {0,};
pSrb = (user_aac_srb64*)aBuff;
pReply = (user_aac_reply*)(aBuff+sizeof(user_aac_srb64));
#elif defined(ENVIRONMENT32)
//Create user 32 bit request
user_aac_srb32 *pSrb;
uint8_t aBuff[sizeof(user_aac_srb32) + sizeof(user_aac_reply)] = {0,};
pSrb = (user_aac_srb32*)aBuff;
pReply = (user_aac_reply*)(aBuff+sizeof(user_aac_srb32));
#endif
pSrb->function = SRB_FUNCTION_EXECUTE_SCSI;
//channel is 0 always
pSrb->channel = 0;
pSrb->id = aId;
pSrb->lun = aLun;
pSrb->timeout = 0;
pSrb->retry_limit = 0;
pSrb->cdb_size = iop->cmnd_len;
switch(iop->dxfer_dir) {
case DXFER_NONE:
pSrb->flags = SRB_NoDataXfer;
break;
case DXFER_FROM_DEVICE:
pSrb->flags = SRB_DataIn;
break;
case DXFER_TO_DEVICE:
pSrb->flags = SRB_DataOut;
break;
default:
pout("aacraid: bad dxfer_dir\n");
return set_err(EINVAL, "aacraid: bad dxfer_dir\n");
}
if(iop->dxfer_len > 0) {
#ifdef ENVIRONMENT64
pSrb->sg64.count = 1;
pSrb->sg64.sg64[0].addr64.lo32 = ((intptr_t)iop->dxferp) &
0x00000000ffffffff;
pSrb->sg64.sg64[0].addr64.hi32 = ((intptr_t)iop->dxferp) >> 32;
pSrb->sg64.sg64[0].length = (uint32_t)iop->dxfer_len;
pSrb->count = sizeof(user_aac_srb64) +
(sizeof(user_sgentry64)*(pSrb->sg64.count-1));
#elif defined(ENVIRONMENT32)
pSrb->sg32.count = 1;
pSrb->sg32.sg32[0].addr32 = (intptr_t)iop->dxferp;
pSrb->sg32.sg32[0].length = (uint32_t)iop->dxfer_len;
pSrb->count = sizeof(user_aac_srb32) +
(sizeof(user_sgentry32)*(pSrb->sg32.count-1));
#endif
}
memcpy(pSrb->cdb,iop->cmnd,iop->cmnd_len);
int rc = 0;
errno = 0;
rc = ioctl(get_fd(),FSACTL_SEND_RAW_SRB,pSrb);
if(rc!= 0 || pReply->srb_status != 0x01) {
if(pReply->srb_status == 0x08) {
return set_err(EIO, "aacraid: Device %d %d does not exist\n" ,aLun,aId );
}
return set_err((errno ? errno : EIO), "aacraid result: %d.%d = %d/%d",
aLun, aId, errno,
pReply->srb_status);
}
return true;
}
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
/// LSI MegaRAID support /// LSI MegaRAID support
@ -2488,7 +2707,7 @@ bool linux_smart_interface::get_dev_list(smart_device_list & devlist,
} }
// did we find too many paths? // did we find too many paths?
const int max_pathc = 32; const int max_pathc = 1024;
int n = (int)globbuf.gl_pathc; int n = (int)globbuf.gl_pathc;
if (n > max_pathc) { if (n > max_pathc) {
pout("glob(3) found %d > MAX=%d devices matching pattern %s: ignoring %d paths\n", pout("glob(3) found %d > MAX=%d devices matching pattern %s: ignoring %d paths\n",
@ -2939,12 +3158,23 @@ smart_device * linux_smart_interface::get_custom_smart_device(const char * name,
if (sscanf(type, "megaraid,%d", &disknum) == 1) { if (sscanf(type, "megaraid,%d", &disknum) == 1) {
return new linux_megaraid_device(this, name, 0, disknum); return new linux_megaraid_device(this, name, 0, disknum);
} }
//aacraid?
unsigned int device;
unsigned int host;
if(sscanf(type, "aacraid,%d,%d,%d", &host, &channel, &device)==3) {
//return new linux_aacraid_device(this,name,channel,device);
return get_sat_device("sat,auto",
new linux_aacraid_device(this, name, host, channel, device));
}
return 0; return 0;
} }
std::string linux_smart_interface::get_valid_custom_dev_types_str() std::string linux_smart_interface::get_valid_custom_dev_types_str()
{ {
return "marvell, areca,N/E, 3ware,N, hpt,L/M/N, megaraid,N" return "marvell, areca,N/E, 3ware,N, hpt,L/M/N, megaraid,N, aacraid,H,L,ID"
#ifdef HAVE_LINUX_CCISS_IOCTL_H #ifdef HAVE_LINUX_CCISS_IOCTL_H
", cciss,N" ", cciss,N"
#endif #endif

View File

@ -3,7 +3,7 @@
* *
* Home page of code is: http://smartmontools.sourceforge.net * Home page of code is: http://smartmontools.sourceforge.net
* *
* Copyright (C) 2004-13 Christian Franke <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2004-14 Christian Franke <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2012 Hank Wu <hank@areca.com.tw> * Copyright (C) 2012 Hank Wu <hank@areca.com.tw>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -95,7 +95,7 @@
#define SELECT_WIN_32_64(x32, x64) (x64) #define SELECT_WIN_32_64(x32, x64) (x64)
#endif #endif
const char * os_win32_cpp_cvsid = "$Id: os_win32.cpp 3830 2013-07-18 20:59:53Z chrfranke $"; const char * os_win32_cpp_cvsid = "$Id: os_win32.cpp 3923 2014-06-25 17:10:46Z chrfranke $";
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// Windows I/O-controls, some declarations are missing in the include files // Windows I/O-controls, some declarations are missing in the include files
@ -400,19 +400,19 @@ class csmi_device
: virtual public /*extends*/ smart_device : virtual public /*extends*/ smart_device
{ {
public: public:
/// Get phy info /// Get bitmask of used ports
bool get_phy_info(CSMI_SAS_PHY_INFO & phy_info); unsigned get_ports_used();
/// Check physical drive existence
bool check_phy(const CSMI_SAS_PHY_INFO & phy_info, unsigned phy_no);
protected: protected:
csmi_device() csmi_device()
: smart_device(never_called) : smart_device(never_called)
{ memset(&m_phy_ent, 0, sizeof(m_phy_ent)); } { memset(&m_phy_ent, 0, sizeof(m_phy_ent)); }
/// Get phy info
bool get_phy_info(CSMI_SAS_PHY_INFO & phy_info);
/// Select physical drive /// Select physical drive
bool select_phy(unsigned phy_no); bool select_port(int port);
/// Get info for selected physical drive /// Get info for selected physical drive
const CSMI_SAS_PHY_ENTITY & get_phy_ent() const const CSMI_SAS_PHY_ENTITY & get_phy_ent() const
@ -465,7 +465,7 @@ protected:
private: private:
HANDLE m_fh; ///< Controller device handle HANDLE m_fh; ///< Controller device handle
unsigned m_phy_no; ///< Physical drive number int m_port; ///< Port number
}; };
@ -1013,12 +1013,13 @@ bool win_smart_interface::scan_smart_devices(smart_device_list & devlist,
win_csmi_device test_dev(this, name, ""); win_csmi_device test_dev(this, name, "");
if (!test_dev.open_scsi()) if (!test_dev.open_scsi())
continue; continue;
CSMI_SAS_PHY_INFO phy_info;
if (!test_dev.get_phy_info(phy_info)) unsigned ports_used = test_dev.get_ports_used();
if (!ports_used)
continue; continue;
for (int pi = 0; pi < phy_info.bNumberOfPhys; pi++) { for (int pi = 0; pi < 32; pi++) {
if (!test_dev.check_phy(phy_info, pi)) if (!(ports_used & (1 << pi)))
continue; continue;
snprintf(name, sizeof(name)-1, "/dev/csmi%d,%d", i, pi); snprintf(name, sizeof(name)-1, "/dev/csmi%d,%d", i, pi);
devlist.push_back( new win_csmi_device(this, name, "ata") ); devlist.push_back( new win_csmi_device(this, name, "ata") );
@ -2888,14 +2889,19 @@ bool csmi_device::get_phy_info(CSMI_SAS_PHY_INFO & phy_info)
return false; return false;
phy_info = phy_info_buf.Information; phy_info = phy_info_buf.Information;
if (phy_info.bNumberOfPhys > sizeof(phy_info.Phy)/sizeof(phy_info.Phy[0]))
const int max_number_of_phys = sizeof(phy_info.Phy) / sizeof(phy_info.Phy[0]);
if (phy_info.bNumberOfPhys > max_number_of_phys)
return set_err(EIO, "CSMI_SAS_PHY_INFO: Bogus NumberOfPhys=%d", phy_info.bNumberOfPhys); return set_err(EIO, "CSMI_SAS_PHY_INFO: Bogus NumberOfPhys=%d", phy_info.bNumberOfPhys);
if (scsi_debugmode > 1) { if (scsi_debugmode > 1) {
pout("CSMI_SAS_PHY_INFO: NumberOfPhys=%d\n", phy_info.bNumberOfPhys); pout("CSMI_SAS_PHY_INFO: NumberOfPhys=%d\n", phy_info.bNumberOfPhys);
for (int i = 0; i < phy_info.bNumberOfPhys; i++) { for (int i = 0; i < max_number_of_phys; i++) {
const CSMI_SAS_PHY_ENTITY & pe = phy_info.Phy[i]; const CSMI_SAS_PHY_ENTITY & pe = phy_info.Phy[i];
const CSMI_SAS_IDENTIFY & id = pe.Identify, & at = pe.Attached; const CSMI_SAS_IDENTIFY & id = pe.Identify, & at = pe.Attached;
if (id.bDeviceType == CSMI_SAS_NO_DEVICE_ATTACHED)
continue;
pout("Phy[%d] Port: 0x%02x\n", i, pe.bPortIdentifier); pout("Phy[%d] Port: 0x%02x\n", i, pe.bPortIdentifier);
pout(" Type: 0x%02x, 0x%02x\n", id.bDeviceType, at.bDeviceType); pout(" Type: 0x%02x, 0x%02x\n", id.bDeviceType, at.bDeviceType);
pout(" InitProto: 0x%02x, 0x%02x\n", id.bInitiatorPortProtocol, at.bInitiatorPortProtocol); pout(" InitProto: 0x%02x, 0x%02x\n", id.bInitiatorPortProtocol, at.bInitiatorPortProtocol);
@ -2913,40 +2919,92 @@ bool csmi_device::get_phy_info(CSMI_SAS_PHY_INFO & phy_info)
return true; return true;
} }
bool csmi_device::check_phy(const CSMI_SAS_PHY_INFO & phy_info, unsigned phy_no) unsigned csmi_device::get_ports_used()
{ {
// Check Phy presence CSMI_SAS_PHY_INFO phy_info;
if (phy_no >= phy_info.bNumberOfPhys) if (!get_phy_info(phy_info))
return set_err(ENOENT, "Port %u does not exist (#ports: %d)", phy_no, return 0;
phy_info.bNumberOfPhys);
const CSMI_SAS_PHY_ENTITY & phy_ent = phy_info.Phy[phy_no]; unsigned ports_used = 0;
for (unsigned i = 0; i < sizeof(phy_info.Phy) / sizeof(phy_info.Phy[0]); i++) {
const CSMI_SAS_PHY_ENTITY & pe = phy_info.Phy[i];
if (pe.Identify.bDeviceType == CSMI_SAS_NO_DEVICE_ATTACHED)
continue;
if (pe.Attached.bDeviceType == CSMI_SAS_NO_DEVICE_ATTACHED)
continue;
switch (pe.Attached.bTargetPortProtocol) {
case CSMI_SAS_PROTOCOL_SATA:
case CSMI_SAS_PROTOCOL_STP:
break;
default:
continue;
}
if (pe.bPortIdentifier == 0xff)
// Older (<= 9.*) Intel RST driver
ports_used |= (1 << i);
else
ports_used |= (1 << pe.bPortIdentifier);
}
return ports_used;
}
bool csmi_device::select_port(int port)
{
CSMI_SAS_PHY_INFO phy_info;
if (!get_phy_info(phy_info))
return false;
// Find port
int max_port = -1, port_index = -1;
for (unsigned i = 0; i < sizeof(phy_info.Phy) / sizeof(phy_info.Phy[0]); i++) {
const CSMI_SAS_PHY_ENTITY & pe = phy_info.Phy[i];
if (pe.Identify.bDeviceType == CSMI_SAS_NO_DEVICE_ATTACHED)
continue;
if (pe.bPortIdentifier == 0xff) {
// Older (<= 9.*) Intel RST driver
max_port = phy_info.bNumberOfPhys - 1;
if (i >= phy_info.bNumberOfPhys)
break;
if ((int)i != port)
continue;
}
else {
if (pe.bPortIdentifier > max_port)
max_port = pe.bPortIdentifier;
if (pe.bPortIdentifier != port)
continue;
}
port_index = i;
break;
}
if (port_index < 0) {
if (port <= max_port)
return set_err(ENOENT, "Port %d is disabled", port);
else
return set_err(ENOENT, "Port %d does not exist (#ports: %d)", port,
max_port + 1);
}
const CSMI_SAS_PHY_ENTITY & phy_ent = phy_info.Phy[port_index];
if (phy_ent.Attached.bDeviceType == CSMI_SAS_NO_DEVICE_ATTACHED) if (phy_ent.Attached.bDeviceType == CSMI_SAS_NO_DEVICE_ATTACHED)
return set_err(ENOENT, "No device on port %u", phy_no); return set_err(ENOENT, "No device on port %d", port);
switch (phy_ent.Attached.bTargetPortProtocol) { switch (phy_ent.Attached.bTargetPortProtocol) {
case CSMI_SAS_PROTOCOL_SATA: case CSMI_SAS_PROTOCOL_SATA:
case CSMI_SAS_PROTOCOL_STP: case CSMI_SAS_PROTOCOL_STP:
break; break;
default: default:
return set_err(ENOENT, "No SATA device on port %u (protocol: %u)", return set_err(ENOENT, "No SATA device on port %d (protocol: %d)",
phy_no, phy_ent.Attached.bTargetPortProtocol); port, phy_ent.Attached.bTargetPortProtocol);
} }
return true; m_phy_ent = phy_ent;
}
bool csmi_device::select_phy(unsigned phy_no)
{
CSMI_SAS_PHY_INFO phy_info;
if (!get_phy_info(phy_info))
return false;
if (!check_phy(phy_info, phy_no))
return false;
m_phy_ent = phy_info.Phy[phy_no];
return true; return true;
} }
@ -3055,7 +3113,7 @@ bool csmi_ata_device::ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out)
win_csmi_device::win_csmi_device(smart_interface * intf, const char * dev_name, win_csmi_device::win_csmi_device(smart_interface * intf, const char * dev_name,
const char * req_type) const char * req_type)
: smart_device(intf, dev_name, "ata", req_type), : smart_device(intf, dev_name, "ata", req_type),
m_fh(INVALID_HANDLE_VALUE), m_phy_no(0) m_fh(INVALID_HANDLE_VALUE), m_port(-1)
{ {
} }
@ -3083,10 +3141,10 @@ bool win_csmi_device::close()
bool win_csmi_device::open_scsi() bool win_csmi_device::open_scsi()
{ {
// Parse name // Parse name
unsigned contr_no = ~0, phy_no = ~0; int nc = -1; unsigned contr_no = ~0, port = ~0; int nc = -1;
const char * name = skipdev(get_dev_name()); const char * name = skipdev(get_dev_name());
if (!( sscanf(name, "csmi%u,%u%n", &contr_no, &phy_no, &nc) >= 0 if (!( sscanf(name, "csmi%u,%u%n", &contr_no, &port, &nc) >= 0
&& nc == (int)strlen(name) && contr_no <= 9 && phy_no < 32) ) && nc == (int)strlen(name) && contr_no <= 9 && port < 32) )
return set_err(EINVAL); return set_err(EINVAL);
// Open controller handle // Open controller handle
@ -3112,7 +3170,7 @@ bool win_csmi_device::open_scsi()
pout(" %s: successfully opened\n", devpath); pout(" %s: successfully opened\n", devpath);
m_fh = h; m_fh = h;
m_phy_no = phy_no; m_port = port;
return true; return true;
} }
@ -3123,7 +3181,7 @@ bool win_csmi_device::open()
return false; return false;
// Get Phy info for this drive // Get Phy info for this drive
if (!select_phy(m_phy_no)) { if (!select_port(m_port)) {
close(); close();
return false; return false;
} }
@ -3427,14 +3485,14 @@ bool win_scsi_device::scsi_pass_through(struct scsi_cmnd_io * iop)
} else } else
iop->resp_sense_len = 0; iop->resp_sense_len = 0;
if ((iop->dxfer_len > 0) && (sb.spt.DataTransferLength > 0)) if (iop->dxfer_len > sb.spt.DataTransferLength)
iop->resid = iop->dxfer_len - sb.spt.DataTransferLength; iop->resid = iop->dxfer_len - sb.spt.DataTransferLength;
else else
iop->resid = 0; iop->resid = 0;
if ((iop->dxfer_dir == DXFER_FROM_DEVICE) && (report > 1)) { if ((iop->dxfer_dir == DXFER_FROM_DEVICE) && (report > 1)) {
int trunc = (iop->dxfer_len > 256) ? 1 : 0; int trunc = (iop->dxfer_len > 256) ? 1 : 0;
pout(" Incoming data, len=%d%s:\n", (int)iop->dxfer_len, pout(" Incoming data, len=%d, resid=%d%s:\n", (int)iop->dxfer_len, iop->resid,
(trunc ? " [only first 256 bytes shown]" : "")); (trunc ? " [only first 256 bytes shown]" : ""));
dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1); dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
} }
@ -3553,14 +3611,14 @@ static long scsi_pass_through_direct(HANDLE fd, UCHAR targetid, struct scsi_cmnd
} else } else
iop->resp_sense_len = 0; iop->resp_sense_len = 0;
if ((iop->dxfer_len > 0) && (sb.spt.DataTransferLength > 0)) if (iop->dxfer_len > sb.spt.DataTransferLength)
iop->resid = iop->dxfer_len - sb.spt.DataTransferLength; iop->resid = iop->dxfer_len - sb.spt.DataTransferLength;
else else
iop->resid = 0; iop->resid = 0;
if ((iop->dxfer_dir == DXFER_FROM_DEVICE) && (report > 1)) { if ((iop->dxfer_dir == DXFER_FROM_DEVICE) && (report > 1)) {
int trunc = (iop->dxfer_len > 256) ? 1 : 0; int trunc = (iop->dxfer_len > 256) ? 1 : 0;
pout(" Incoming data, len=%d%s:\n", (int)iop->dxfer_len, pout(" Incoming data, len=%d, resid=%d%s:\n", (int)iop->dxfer_len, iop->resid,
(trunc ? " [only first 256 bytes shown]" : "")); (trunc ? " [only first 256 bytes shown]" : ""));
dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1); dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
} }

View File

@ -3,7 +3,7 @@
* *
* Home page of code is: http://smartmontools.sourceforge.net * Home page of code is: http://smartmontools.sourceforge.net
* *
* Copyright (C) 2004-13 Christian Franke <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2004-14 Christian Franke <smartmontools-support@lists.sourceforge.net>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -20,7 +20,7 @@
#include "daemon_win32.h" #include "daemon_win32.h"
const char * daemon_win32_cpp_cvsid = "$Id: daemon_win32.cpp 3834 2013-07-20 16:17:13Z chrfranke $" const char * daemon_win32_cpp_cvsid = "$Id: daemon_win32.cpp 3959 2014-07-18 19:22:18Z chrfranke $"
DAEMON_WIN32_H_CVSID; DAEMON_WIN32_H_CVSID;
#include <stdio.h> #include <stdio.h>
@ -34,11 +34,6 @@ const char * daemon_win32_cpp_cvsid = "$Id: daemon_win32.cpp 3834 2013-07-20 16:
#include <crtdbg.h> #include <crtdbg.h>
#endif #endif
#ifndef SERVICE_CONFIG_DELAYED_AUTO_START_INFO
// Missing in older MinGW headers
#define SERVICE_CONFIG_DELAYED_AUTO_START_INFO 3
#endif
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
@ -1011,8 +1006,13 @@ static int svcadm_main(const char * ident, const daemon_winsvc_options * svc_opt
if ( GetVersionExA(&ver) if ( GetVersionExA(&ver)
&& ver.dwPlatformId == VER_PLATFORM_WIN32_NT && ver.dwPlatformId == VER_PLATFORM_WIN32_NT
&& ver.dwMajorVersion >= 6 /* Vista */ ) { && ver.dwMajorVersion >= 6 /* Vista */ ) {
SERVICE_DELAYED_AUTO_START_INFO sdasi = { TRUE }; // SERVICE_{,CONFIG_}DELAYED_AUTO_START_INFO are missing in older MinGW headers
ChangeServiceConfig2A(hs, SERVICE_CONFIG_DELAYED_AUTO_START_INFO, &sdasi); struct /* SERVICE_DELAYED_AUTO_START_INFO */ {
BOOL fDelayedAutostart;
} sdasi = { TRUE };
// typedef char ASSERT_sizeof_sdasi[sizeof(sdasi) == sizeof(SERVICE_DELAYED_AUTO_START_INFO) ? 1 : -1];
// typedef char ASSERT_const_scdasi[SERVICE_CONFIG_DELAYED_AUTO_START_INFO == 3 ? 1 : -1];
ChangeServiceConfig2A(hs, 3 /* SERVICE_CONFIG_DELAYED_AUTO_START_INFO */, &sdasi);
} }
} }
else { else {

View File

@ -3,7 +3,7 @@
; ;
; Home page of code is: http://smartmontools.sourceforge.net ; Home page of code is: http://smartmontools.sourceforge.net
; ;
; Copyright (C) 2006-13 Christian Franke <smartmontools-support@lists.sourceforge.net> ; Copyright (C) 2006-14 Christian Franke <smartmontools-support@lists.sourceforge.net>
; ;
; This program is free software; you can redistribute it and/or modify ; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by ; it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
; You should have received a copy of the GNU General Public License ; You should have received a copy of the GNU General Public License
; (for example COPYING); If not, see <http://www.gnu.org/licenses/>. ; (for example COPYING); If not, see <http://www.gnu.org/licenses/>.
; ;
; $Id: installer.nsi 3759 2013-01-26 21:11:02Z chrfranke $ ; $Id: installer.nsi 3912 2014-06-18 19:03:30Z chrfranke $
; ;
@ -208,20 +208,23 @@ Section "Uninstaller" UNINST_SECTION
CreateDirectory "$INSTDIR" CreateDirectory "$INSTDIR"
; Save installation location ; Keep old Install_Dir registry entry for GSmartControl
WriteRegStr HKLM "Software\smartmontools" "Install_Dir" "$INSTDIR" ReadRegStr $0 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\GSmartControl" "InstallLocation"
ReadRegStr $1 HKLM "Software\smartmontools" "Install_Dir"
StrCmp "$0$1" "" +2 0
WriteRegStr HKLM "Software\smartmontools" "Install_Dir" "$INSTDIR"
; Write uninstall keys and program ; Write uninstall keys and program
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "DisplayName" "smartmontools" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "DisplayName" "smartmontools"
!ifdef VERSTR !ifdef VERSTR
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "DisplayVersion" "${VERSTR}" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "DisplayVersion" "${VERSTR}"
!endif !endif
;WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "Publisher" "smartmontools" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "InstallLocation" "$INSTDIR"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "UninstallString" '"$INSTDIR\uninst-smartmontools.exe"' WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "UninstallString" '"$INSTDIR\uninst-smartmontools.exe"'
;WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "URLInfoAbout" "http://smartmontools.sourceforge.net/" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "Publisher" "smartmontools.org"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "HelpLink" "http://smartmontools.sourceforge.net/" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "URLInfoAbout" "http://www.smartmontools.org/"
;WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "URLUpdateInfo" "http://sourceforge.net/project/showfiles.php?group_id=64297" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "HelpLink" "http://sourceforge.net/projects/smartmontools/support"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "URLUpdateInfo" "http://smartmontools-win32.dyndns.org/" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "URLUpdateInfo" "http://smartmontools.no-ip.org/"
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "NoModify" 1 WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "NoModify" 1
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "NoRepair" 1 WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "NoRepair" 1
WriteUninstaller "uninst-smartmontools.exe" WriteUninstaller "uninst-smartmontools.exe"
@ -313,11 +316,11 @@ Section "Start Menu Shortcuts" MENU_SECTION
CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\ChangeLog.lnk" "$INSTDIR\doc\ChangeLog.txt" CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\ChangeLog.lnk" "$INSTDIR\doc\ChangeLog.txt"
CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\COPYING.lnk" "$INSTDIR\doc\COPYING.txt" CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\COPYING.lnk" "$INSTDIR\doc\COPYING.txt"
CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\NEWS.lnk" "$INSTDIR\doc\NEWS.txt" CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\NEWS.lnk" "$INSTDIR\doc\NEWS.txt"
CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\Windows version download page.lnk" "http://smartmontools-win32.dyndns.org/smartmontools/" CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\Windows version download page.lnk" "http://smartmontools.no-ip.org/"
nodoc: nodoc:
; Homepage ; Homepage
CreateShortCut "$SMPROGRAMS\smartmontools\smartmontools Home Page.lnk" "http://smartmontools.sourceforge.net/" CreateShortCut "$SMPROGRAMS\smartmontools\smartmontools Home Page.lnk" "http://www.smartmontools.org/"
; drivedb.h update ; drivedb.h update
IfFileExists "$INSTDIR\bin\update-smart-drivedb.exe" 0 noupdb IfFileExists "$INSTDIR\bin\update-smart-drivedb.exe" 0 noupdb
@ -500,6 +503,8 @@ Function .onInit
; Set default install directories ; Set default install directories
StrCmp $INSTDIR "" 0 endinst ; /D=PATH option specified ? StrCmp $INSTDIR "" 0 endinst ; /D=PATH option specified ?
ReadRegStr $INSTDIR HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "InstallLocation"
StrCmp $INSTDIR "" 0 endinst ; Already installed ?
ReadRegStr $INSTDIR HKLM "Software\smartmontools" "Install_Dir" ReadRegStr $INSTDIR HKLM "Software\smartmontools" "Install_Dir"
StrCmp $INSTDIR "" 0 endinst ; Already installed ? StrCmp $INSTDIR "" 0 endinst ; Already installed ?
StrCpy $INSTDIR "$PROGRAMFILES\smartmontools" StrCpy $INSTDIR "$PROGRAMFILES\smartmontools"

View File

@ -1,7 +1,7 @@
// //
// os_win32/smartctl_res.rc.in // os_win32/smartctl_res.rc.in
// //
// $Id: smartctl_res.rc.in 3755 2013-01-26 15:13:08Z chrfranke $ // $Id: smartctl_res.rc.in 3878 2014-03-03 18:45:21Z chrfranke $
// //
1 VERSIONINFO 1 VERSIONINFO
@ -21,7 +21,7 @@ BEGIN
VALUE "FileDescription", "Control and Monitor Utility for SMART Disks" VALUE "FileDescription", "Control and Monitor Utility for SMART Disks"
VALUE "FileVersion", "@TEXT_VERSION@" VALUE "FileVersion", "@TEXT_VERSION@"
VALUE "InternalName", "smartctl" VALUE "InternalName", "smartctl"
VALUE "LegalCopyright", "(C) 2002-13, Bruce Allen, Christian Franke, www.smartmontools.org" VALUE "LegalCopyright", "(C) 2002-@YY@, Bruce Allen, Christian Franke, www.smartmontools.org"
VALUE "OriginalFilename", "smartctl.exe" VALUE "OriginalFilename", "smartctl.exe"
VALUE "ProductName", "smartmontools" VALUE "ProductName", "smartmontools"
VALUE "ProductVersion", "@TEXT_VERSION@" VALUE "ProductVersion", "@TEXT_VERSION@"

View File

@ -1,7 +1,7 @@
// //
// os_win32/smartd_res.rc.in // os_win32/smartd_res.rc.in
// //
// $Id: smartd_res.rc.in 3756 2013-01-26 16:16:35Z chrfranke $ // $Id: smartd_res.rc.in 3878 2014-03-03 18:45:21Z chrfranke $
// //
1 VERSIONINFO 1 VERSIONINFO
@ -21,7 +21,7 @@ BEGIN
VALUE "FileDescription", "SMART Disk Monitoring Daemon" VALUE "FileDescription", "SMART Disk Monitoring Daemon"
VALUE "FileVersion", "@TEXT_VERSION@" VALUE "FileVersion", "@TEXT_VERSION@"
VALUE "InternalName", "smartd" VALUE "InternalName", "smartd"
VALUE "LegalCopyright", "(C) 2002-13, Bruce Allen, Christian Franke, www.smartmontools.org" VALUE "LegalCopyright", "(C) 2002-@YY@, Bruce Allen, Christian Franke, www.smartmontools.org"
VALUE "OriginalFilename", "smartd.exe" VALUE "OriginalFilename", "smartd.exe"
VALUE "ProductName", "smartmontools" VALUE "ProductName", "smartmontools"
VALUE "ProductVersion", "@TEXT_VERSION@" VALUE "ProductVersion", "@TEXT_VERSION@"

View File

@ -62,7 +62,7 @@
#include "dev_ata_cmd_set.h" // ata_device_with_command_set #include "dev_ata_cmd_set.h" // ata_device_with_command_set
#include "dev_tunnelled.h" // tunnelled_device<> #include "dev_tunnelled.h" // tunnelled_device<>
const char * scsiata_cpp_cvsid = "$Id: scsiata.cpp 3741 2013-01-02 17:06:54Z chrfranke $"; const char * scsiata_cpp_cvsid = "$Id: scsiata.cpp 3922 2014-06-23 19:17:18Z chrfranke $";
/* This is a slightly stretched SCSI sense "descriptor" format header. /* This is a slightly stretched SCSI sense "descriptor" format header.
The addition is to allow the 0x70 and 0x71 response codes. The idea The addition is to allow the 0x70 and 0x71 response codes. The idea
@ -980,7 +980,7 @@ bool usbjmicron_device::ata_pass_through(const ata_cmd_in & in, ata_cmd_out & ou
memset(&io_hdr, 0, sizeof(io_hdr)); memset(&io_hdr, 0, sizeof(io_hdr));
bool rwbit = true; bool rwbit = true;
unsigned char smart_status = 0; unsigned char smart_status = 0xff;
bool is_smart_status = ( in.in_regs.command == ATA_SMART_CMD bool is_smart_status = ( in.in_regs.command == ATA_SMART_CMD
&& in.in_regs.features == ATA_SMART_STATUS); && in.in_regs.features == ATA_SMART_STATUS);
@ -1038,15 +1038,22 @@ bool usbjmicron_device::ata_pass_through(const ata_cmd_in & in, ata_cmd_out & ou
if (in.out_needed.is_set()) { if (in.out_needed.is_set()) {
if (is_smart_status) { if (is_smart_status) {
if (io_hdr.resid == 1)
// Some (Prolific) USB bridges do not transfer a status byte
return set_err(ENOSYS, "Incomplete response, status byte missing [JMicron]");
switch (smart_status) { switch (smart_status) {
case 0x01: case 0xc2: case 0xc2:
out.out_regs.lba_high = 0xc2; out.out_regs.lba_high = 0xc2;
out.out_regs.lba_mid = 0x4f; out.out_regs.lba_mid = 0x4f;
break; break;
case 0x00: case 0x2c: case 0x2c:
out.out_regs.lba_high = 0x2c; out.out_regs.lba_high = 0x2c;
out.out_regs.lba_mid = 0xf4; out.out_regs.lba_mid = 0xf4;
break; break;
default:
// Some (JM20336) USB bridges always return 0x01, regardless of SMART Status
return set_err(ENOSYS, "Invalid status byte (0x%02x) [JMicron]", smart_status);
} }
} }

View File

@ -49,7 +49,7 @@
#include "dev_interface.h" #include "dev_interface.h"
#include "utility.h" #include "utility.h"
const char *scsicmds_c_cvsid="$Id: scsicmds.cpp 3820 2013-06-17 08:45:10Z samm2 $" const char *scsicmds_c_cvsid="$Id: scsicmds.cpp 3915 2014-06-19 18:24:57Z dpgilbert $"
SCSICMDS_H_CVSID; SCSICMDS_H_CVSID;
// Print SCSI debug messages? // Print SCSI debug messages?
@ -60,7 +60,7 @@ supported_vpd_pages * supported_vpd_pages_p = NULL;
supported_vpd_pages::supported_vpd_pages(scsi_device * device) : num_valid(0) supported_vpd_pages::supported_vpd_pages(scsi_device * device) : num_valid(0)
{ {
unsigned char b[0x1fc]; /* size chosen for old INQUIRY command */ unsigned char b[0xfc]; /* pre SPC-3 INQUIRY max response size */
int n; int n;
memset(b, 0, sizeof(b)); memset(b, 0, sizeof(b));
@ -1441,12 +1441,13 @@ scsiSetExceptionControlAndWarning(scsi_device * device, int enabled,
if (offset < 0) if (offset < 0)
return -EINVAL; return -EINVAL;
memcpy(rout, iecp->raw_curr, SCSI_IECMP_RAW_LEN); memcpy(rout, iecp->raw_curr, SCSI_IECMP_RAW_LEN);
/* mask out DPOFUA device specific (disk) parameter bit */
if (10 == iecp->modese_len) { if (10 == iecp->modese_len) {
resp_len = (rout[0] << 8) + rout[1] + 2; resp_len = (rout[0] << 8) + rout[1] + 2;
rout[3] &= 0xef; /* for disks mask out DPOFUA bit */ rout[3] &= 0xef;
} else { } else {
resp_len = rout[0] + 1; resp_len = rout[0] + 1;
rout[2] &= 0xef; /* for disks mask out DPOFUA bit */ rout[2] &= 0xef;
} }
sp = (rout[offset] & 0x80) ? 1 : 0; /* PS bit becomes 'SELECT's SP bit */ sp = (rout[offset] & 0x80) ? 1 : 0; /* PS bit becomes 'SELECT's SP bit */
if (enabled) { if (enabled) {
@ -2479,7 +2480,8 @@ scsiFetchControlGLTSD(scsi_device * device, int modese_len, int current)
* RIGID_DISK_DRIVE_GEOMETRY_PAGE mode page. */ * RIGID_DISK_DRIVE_GEOMETRY_PAGE mode page. */
int int
scsiGetRPM(scsi_device * device, int modese_len, int * form_factorp) scsiGetRPM(scsi_device * device, int modese_len, int * form_factorp,
int * haw_zbcp)
{ {
int err, offset, speed; int err, offset, speed;
UINT8 buff[64]; UINT8 buff[64];
@ -2492,10 +2494,14 @@ scsiGetRPM(scsi_device * device, int modese_len, int * form_factorp)
speed = (buff[4] << 8) + buff[5]; speed = (buff[4] << 8) + buff[5];
if (form_factorp) if (form_factorp)
*form_factorp = buff[7] & 0xf; *form_factorp = buff[7] & 0xf;
if (haw_zbcp)
*haw_zbcp = !!(0x10 & buff[8]);
return speed; return speed;
} }
if (form_factorp) if (form_factorp)
*form_factorp = 0; *form_factorp = 0;
if (haw_zbcp)
*haw_zbcp = 0;
if (modese_len <= 6) { if (modese_len <= 6) {
if ((err = scsiModeSense(device, RIGID_DISK_DRIVE_GEOMETRY_PAGE, 0, pc, if ((err = scsiModeSense(device, RIGID_DISK_DRIVE_GEOMETRY_PAGE, 0, pc,
buff, sizeof(buff)))) { buff, sizeof(buff)))) {
@ -2599,12 +2605,13 @@ scsiGetSetCache(scsi_device * device, int modese_len, short int * wcep,
buff[offset + 2] &= 0xfe; // clear bit buff[offset + 2] &= 0xfe; // clear bit
} }
/* mask out DPOFUA device specific (disk) parameter bit */
if (10 == modese_len) { if (10 == modese_len) {
resp_len = (buff[0] << 8) + buff[1] + 2; resp_len = (buff[0] << 8) + buff[1] + 2;
buff[3] &= 0xef; /* for disks mask out DPOFUA bit */ buff[3] &= 0xef;
} else { } else {
resp_len = buff[0] + 1; resp_len = buff[0] + 1;
buff[2] &= 0xef; /* for disks mask out DPOFUA bit */ buff[2] &= 0xef;
} }
sp = 0; /* Do not change saved values */ sp = 0; /* Do not change saved values */
if (10 == modese_len) if (10 == modese_len)
@ -2667,14 +2674,15 @@ scsiSetControlGLTSD(scsi_device * device, int enabled, int modese_len)
if (err) if (err)
return err; return err;
if (0 == (ch_buff[offset + 2] & 2)) if (0 == (ch_buff[offset + 2] & 2))
return SIMPLE_ERR_BAD_PARAM; /* GLTSD bit not chageable */ return SIMPLE_ERR_BAD_PARAM; /* GLTSD bit not changeable */
/* mask out DPOFUA device specific (disk) parameter bit */
if (10 == modese_len) { if (10 == modese_len) {
resp_len = (buff[0] << 8) + buff[1] + 2; resp_len = (buff[0] << 8) + buff[1] + 2;
buff[3] &= 0xef; /* for disks mask out DPOFUA bit */ buff[3] &= 0xef;
} else { } else {
resp_len = buff[0] + 1; resp_len = buff[0] + 1;
buff[2] &= 0xef; /* for disks mask out DPOFUA bit */ buff[2] &= 0xef;
} }
sp = (buff[offset] & 0x80) ? 1 : 0; /* PS bit becomes 'SELECT's SP bit */ sp = (buff[offset] & 0x80) ? 1 : 0; /* PS bit becomes 'SELECT's SP bit */
if (enabled) if (enabled)

View File

@ -32,7 +32,7 @@
#ifndef SCSICMDS_H_ #ifndef SCSICMDS_H_
#define SCSICMDS_H_ #define SCSICMDS_H_
#define SCSICMDS_H_CVSID "$Id: scsicmds.h 3783 2013-03-02 01:51:12Z dpgilbert $\n" #define SCSICMDS_H_CVSID "$Id: scsicmds.h 3896 2014-04-28 04:31:25Z dpgilbert $\n"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -420,7 +420,8 @@ int scsiSelfTestInProgress(scsi_device * device, int * inProgress);
int scsiFetchControlGLTSD(scsi_device * device, int modese_len, int current); int scsiFetchControlGLTSD(scsi_device * device, int modese_len, int current);
int scsiSetControlGLTSD(scsi_device * device, int enabled, int modese_len); int scsiSetControlGLTSD(scsi_device * device, int enabled, int modese_len);
int scsiFetchTransportProtocol(scsi_device * device, int modese_len); int scsiFetchTransportProtocol(scsi_device * device, int modese_len);
int scsiGetRPM(scsi_device * device, int modese_len, int * form_factorp); int scsiGetRPM(scsi_device * device, int modese_len, int * form_factorp,
int * haw_zbcp);
int scsiGetSetCache(scsi_device * device, int modese_len, short int * wce, int scsiGetSetCache(scsi_device * device, int modese_len, short int * wce,
short int * rcd); short int * rcd);
uint64_t scsiGetSize(scsi_device * device, unsigned int * lb_sizep, uint64_t scsiGetSize(scsi_device * device, unsigned int * lb_sizep,

View File

@ -42,7 +42,7 @@
#define GBUF_SIZE 65535 #define GBUF_SIZE 65535
const char * scsiprint_c_cvsid = "$Id: scsiprint.cpp 3807 2013-04-18 17:11:12Z chrfranke $" const char * scsiprint_c_cvsid = "$Id: scsiprint.cpp 3898 2014-04-30 17:44:13Z dpgilbert $"
SCSIPRINT_H_CVSID; SCSIPRINT_H_CVSID;
@ -470,7 +470,7 @@ scsiPrintSeagateCacheLPage(scsi_device * device)
ull <<= 8; ull <<= 8;
ull |= xp[j]; ull |= xp[j];
} }
pout(" = %"PRIu64"\n", ull); pout(" = %" PRIu64 "\n", ull);
num -= pl; num -= pl;
ucp += pl; ucp += pl;
} }
@ -565,7 +565,7 @@ scsiPrintSeagateFactoryLPage(scsi_device * device)
if (0 == pc) if (0 == pc)
pout(" = %.2f\n", ull / 60.0 ); pout(" = %.2f\n", ull / 60.0 );
else else
pout(" = %"PRIu64"\n", ull); pout(" = %" PRIu64 "\n", ull);
} }
num -= pl; num -= pl;
ucp += pl; ucp += pl;
@ -616,11 +616,11 @@ scsiPrintErrorCounterLog(scsi_device * device)
if (! found[k]) if (! found[k])
continue; continue;
ecp = &errCounterArr[k]; ecp = &errCounterArr[k];
pout("%s%8"PRIu64" %8"PRIu64" %8"PRIu64" %8"PRIu64" %8"PRIu64, pout("%s%8" PRIu64 " %8" PRIu64 " %8" PRIu64 " %8" PRIu64 " %8" PRIu64,
pageNames[k], ecp->counter[0], ecp->counter[1], pageNames[k], ecp->counter[0], ecp->counter[1],
ecp->counter[2], ecp->counter[3], ecp->counter[4]); ecp->counter[2], ecp->counter[3], ecp->counter[4]);
processed_gb = ecp->counter[5] / 1000000000.0; processed_gb = ecp->counter[5] / 1000000000.0;
pout(" %12.3f %8"PRIu64"\n", processed_gb, ecp->counter[6]); pout(" %12.3f %8" PRIu64 "\n", processed_gb, ecp->counter[6]);
} }
} }
else else
@ -629,12 +629,12 @@ scsiPrintErrorCounterLog(scsi_device * device)
NON_MEDIUM_ERROR_LPAGE, 0, gBuf, LOG_RESP_LEN, 0))) { NON_MEDIUM_ERROR_LPAGE, 0, gBuf, LOG_RESP_LEN, 0))) {
scsiDecodeNonMediumErrPage(gBuf, &nme); scsiDecodeNonMediumErrPage(gBuf, &nme);
if (nme.gotPC0) if (nme.gotPC0)
pout("\nNon-medium error count: %8"PRIu64"\n", nme.counterPC0); pout("\nNon-medium error count: %8" PRIu64 "\n", nme.counterPC0);
if (nme.gotTFE_H) if (nme.gotTFE_H)
pout("Track following error count [Hitachi]: %8"PRIu64"\n", pout("Track following error count [Hitachi]: %8" PRIu64 "\n",
nme.counterTFE_H); nme.counterTFE_H);
if (nme.gotPE_H) if (nme.gotPE_H)
pout("Positioning error count [Hitachi]: %8"PRIu64"\n", pout("Positioning error count [Hitachi]: %8" PRIu64 "\n",
nme.counterPE_H); nme.counterPE_H);
} }
if (gLastNErrorLPage && (0 == scsiLogSense(device, if (gLastNErrorLPage && (0 == scsiLogSense(device,
@ -843,8 +843,8 @@ scsiPrintSelfTest(scsi_device * device)
char buff[32]; char buff[32];
// was hex but change to decimal to conform with ATA // was hex but change to decimal to conform with ATA
snprintf(buff, sizeof(buff), "%"PRIu64, ull); snprintf(buff, sizeof(buff), "%" PRIu64, ull);
// snprintf(buff, sizeof(buff), "0x%"PRIx64, ull); // snprintf(buff, sizeof(buff), "0x%" PRIx64, ull);
pout("%18s", buff); pout("%18s", buff);
} else } else
pout(" -"); pout(" -");
@ -863,7 +863,7 @@ scsiPrintSelfTest(scsi_device * device)
else else
if ((0 == scsiFetchExtendedSelfTestTime(device, &durationSec, if ((0 == scsiFetchExtendedSelfTestTime(device, &durationSec,
modese_len)) && (durationSec > 0)) { modese_len)) && (durationSec > 0)) {
pout("Long (extended) Self Test duration: %d seconds " pout("\nLong (extended) Self Test duration: %d seconds "
"[%.1f minutes]\n", durationSec, durationSec / 60.0); "[%.1f minutes]\n", durationSec, durationSec / 60.0);
} }
pout("\n"); pout("\n");
@ -1048,11 +1048,12 @@ scsiPrintSSMedia(scsi_device * device)
case 1: case 1:
if (pl < 8) { if (pl < 8) {
print_on(); print_on();
pout("Percentage used endurance indicator too short (pl=%d)\n", pl); pout("SS Media Percentage used endurance indicator parameter "
"too short (pl=%d)\n", pl);
print_off(); print_off();
return FAILSMART; return FAILSMART;
} }
pout("SS Media used endurance indicator: %d%%\n", ucp[7]); pout("Percentage used endurance indicator: %d%%\n", ucp[7]);
default: /* ignore other parameter codes */ default: /* ignore other parameter codes */
break; break;
} }
@ -1221,7 +1222,7 @@ show_sas_port_param(unsigned char * ucp, int param_len)
t = ((0x70 & vcp[4]) >> 4); t = ((0x70 & vcp[4]) >> 4);
switch (t) { switch (t) {
case 0: snprintf(s, sz, "no device attached"); break; case 0: snprintf(s, sz, "no device attached"); break;
case 1: snprintf(s, sz, "end device"); break; case 1: snprintf(s, sz, "SAS or SATA device"); break;
case 2: snprintf(s, sz, "expander device"); break; case 2: snprintf(s, sz, "expander device"); break;
case 3: snprintf(s, sz, "expander device (fanout)"); break; case 3: snprintf(s, sz, "expander device (fanout)"); break;
default: snprintf(s, sz, "reserved [%d]", t); break; default: snprintf(s, sz, "reserved [%d]", t); break;
@ -1279,6 +1280,7 @@ show_sas_port_param(unsigned char * ucp, int param_len)
case 8: snprintf(s, sz, "phy enabled; 1.5 Gbps"); break; case 8: snprintf(s, sz, "phy enabled; 1.5 Gbps"); break;
case 9: snprintf(s, sz, "phy enabled; 3 Gbps"); break; case 9: snprintf(s, sz, "phy enabled; 3 Gbps"); break;
case 0xa: snprintf(s, sz, "phy enabled; 6 Gbps"); break; case 0xa: snprintf(s, sz, "phy enabled; 6 Gbps"); break;
case 0xb: snprintf(s, sz, "phy enabled; 12 Gbps"); break;
default: snprintf(s, sz, "reserved [%d]", t); break; default: snprintf(s, sz, "reserved [%d]", t); break;
} }
pout(" negotiated logical link rate: %s\n", s); pout(" negotiated logical link rate: %s\n", s);
@ -1347,12 +1349,8 @@ show_protocol_specific_page(unsigned char * resp, int len)
} }
// See Serial Attached SCSI (SAS-2) (e.g. revision 16) the Protocol Specific // See Serial Attached SCSI (SPL-3) (e.g. revision 6g) the Protocol Specific
// log pageSerial Attached SCSI (SAS-2) (e.g. revision 16) the Protocol // log page [0x18]. Returns 0 if ok else FAIL* bitmask.
// Specific log page.
// Returns 0 if ok else FAIL* bitmask. Note that if any of the most recent
// 20 self tests fail (result code 3 to 7 inclusive) then FAILLOG and/or
// FAILSMART is returned.
static int static int
scsiPrintSasPhy(scsi_device * device, int reset) scsiPrintSasPhy(scsi_device * device, int reset)
{ {
@ -1410,6 +1408,22 @@ static const char * peripheral_dt_arr[] = {
"enclosure", "enclosure",
"simplified disk", "simplified disk",
"optical card reader" "optical card reader"
"reserved [0x10]"
"object based storage"
"automation/driver interface"
"security manager device"
"host managed zoned block device"
"reserved [0x15]"
"reserved [0x16]"
"reserved [0x17]"
"reserved [0x18]"
"reserved [0x19]"
"reserved [0x1a]"
"reserved [0x1b]"
"reserved [0x1c]"
"reserved [0x1d]"
"well known logical unit"
"unknown or no device type"
}; };
static const char * transport_proto_arr[] = { static const char * transport_proto_arr[] = {
@ -1419,11 +1433,11 @@ static const char * transport_proto_arr[] = {
"IEEE 1394 (SBP-2)", "IEEE 1394 (SBP-2)",
"RDMA (SRP)", "RDMA (SRP)",
"iSCSI", "iSCSI",
"SAS", "SAS (SPL-3)",
"ADT", "ADT",
"0x8", "ATA (ACS-2)",
"0x9", "UAS",
"0xa", "SOP",
"0xb", "0xb",
"0xc", "0xc",
"0xd", "0xd",
@ -1437,12 +1451,13 @@ scsiGetDriveInfo(scsi_device * device, UINT8 * peripheral_type, bool all)
{ {
char timedatetz[DATEANDEPOCHLEN]; char timedatetz[DATEANDEPOCHLEN];
struct scsi_iec_mode_page iec; struct scsi_iec_mode_page iec;
int err, iec_err, len, req_len, avail_len, n; int err, iec_err, len, req_len, avail_len, n, scsi_version;
int is_tape = 0; int is_tape = 0;
int peri_dt = 0; int peri_dt = 0;
int returnval = 0; int returnval = 0;
int transport = -1; int transport = -1;
int form_factor = 0; int form_factor = 0;
int haw_zbc = 0;
int protect = 0; int protect = 0;
memset(gBuf, 0, 96); memset(gBuf, 0, 96);
@ -1474,6 +1489,9 @@ scsiGetDriveInfo(scsi_device * device, UINT8 * peripheral_type, bool all)
print_off(); print_off();
return 1; return 1;
} }
// Upper bits of version bytes were used in older standards
// Only interested in SPC-4 (0x6) and SPC-5 (assumed to be 0x7)
scsi_version = gBuf[2] & 0x7;
if (all && (0 != strncmp((char *)&gBuf[8], "ATA", 3))) { if (all && (0 != strncmp((char *)&gBuf[8], "ATA", 3))) {
char vendor[8+1], product[16+1], revision[4+1]; char vendor[8+1], product[16+1], revision[4+1];
@ -1486,6 +1504,10 @@ scsiGetDriveInfo(scsi_device * device, UINT8 * peripheral_type, bool all)
pout("Product: %.16s\n", product); pout("Product: %.16s\n", product);
if (gBuf[32] >= ' ') if (gBuf[32] >= ' ')
pout("Revision: %.4s\n", revision); pout("Revision: %.4s\n", revision);
if (scsi_version == 0x6)
pout("Compliance: SPC-4\n");
else if (scsi_version == 0x7)
pout("Compliance: SPC-5\n");
} }
if (!*device->get_req_type()/*no type requested*/ && if (!*device->get_req_type()/*no type requested*/ &&
@ -1527,7 +1549,8 @@ scsiGetDriveInfo(scsi_device * device, UINT8 * peripheral_type, bool all)
(lb_size * (1 << lb_per_pb_exp))); (lb_size * (1 << lb_per_pb_exp)));
pout("Physical block size: %s bytes\n", lb_str); pout("Physical block size: %s bytes\n", lb_str);
n = ((rc16_12[2] & 0x3f) << 8) + rc16_12[3]; n = ((rc16_12[2] & 0x3f) << 8) + rc16_12[3];
pout("Lowest aligned LBA: %d\n", n); if (n > 0) // not common so cut the clutter
pout("Lowest aligned LBA: %d\n", n);
} }
if (rc16_12[0] & 0x1) { /* PROT_EN set */ if (rc16_12[0] & 0x1) { /* PROT_EN set */
int p_type = ((rc16_12[0] >> 1) & 0x7); int p_type = ((rc16_12[0] >> 1) & 0x7);
@ -1566,8 +1589,8 @@ scsiGetDriveInfo(scsi_device * device, UINT8 * peripheral_type, bool all)
lbprz = !! (lb_prov_resp[5] & 0x4); lbprz = !! (lb_prov_resp[5] & 0x4);
switch (prov_type) { switch (prov_type) {
case 0: case 0:
pout("Logical block provisioning type unreported, " pout("LB provisioning type: unreported, LBPME=%d, LBPRZ=%d\n",
"LBPME=%d, LBPRZ=%d\n", lbpme, lbprz); lbpme, lbprz);
break; break;
case 1: case 1:
pout("LU is resource provisioned, LBPRZ=%d\n", lbprz); pout("LU is resource provisioned, LBPRZ=%d\n", lbprz);
@ -1583,10 +1606,14 @@ scsiGetDriveInfo(scsi_device * device, UINT8 * peripheral_type, bool all)
} else if (1 == lbpme) } else if (1 == lbpme)
pout("Logical block provisioning enabled, LBPRZ=%d\n", lbprz); pout("Logical block provisioning enabled, LBPRZ=%d\n", lbprz);
int rpm = scsiGetRPM(device, modese_len, &form_factor); int rpm = scsiGetRPM(device, modese_len, &form_factor, &haw_zbc);
if (rpm > 0) { if (rpm >= 0) {
if (1 == rpm) if (0 == rpm)
; // Not reported
else if (1 == rpm)
pout("Rotation Rate: Solid State Device\n"); pout("Rotation Rate: Solid State Device\n");
else if ((rpm <= 0x400) || (0xffff == rpm))
; // Reserved
else else
pout("Rotation Rate: %d rpm\n", rpm); pout("Rotation Rate: %d rpm\n", rpm);
} }
@ -1613,6 +1640,8 @@ scsiGetDriveInfo(scsi_device * device, UINT8 * peripheral_type, bool all)
if (cp) if (cp)
pout("Form Factor: %s inches\n", cp); pout("Form Factor: %s inches\n", cp);
} }
if (haw_zbc > 0)
pout("Host aware zoned block capable\n");
} }
/* Do this here to try and detect badly conforming devices (some USB /* Do this here to try and detect badly conforming devices (some USB
@ -2107,7 +2136,7 @@ scsiPrintMain(scsi_device * device, const scsi_print_options & options)
pout("Self Test returned without error\n"); pout("Self Test returned without error\n");
any_output = true; any_output = true;
} }
if (options.sasphy) { if (options.sasphy && gProtocolSpecificLPage) {
if (scsiPrintSasPhy(device, options.sasphy_reset)) if (scsiPrintSasPhy(device, options.sasphy_reset))
return returnval | FAILSMART; return returnval | FAILSMART;
any_output = true; any_output = true;

View File

@ -1,8 +1,8 @@
.ig .ig
Copyright (C) 2002-10 Bruce Allen <smartmontools-support@lists.sourceforge.net> Copyright (C) 2002-10 Bruce Allen <smartmontools-support@lists.sourceforge.net>
Copyright (C) 2004-13 Christian Franke <smartmontools-support@lists.sourceforge.net> Copyright (C) 2004-14 Christian Franke <smartmontools-support@lists.sourceforge.net>
$Id: smartctl.8.in 3832 2013-07-20 14:49:31Z chrfranke $ $Id: smartctl.8.in 3965 2014-07-20 14:46:41Z chrfranke $
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -25,11 +25,6 @@ California, Santa Cruz. http://ssrc.soe.ucsc.edu/
.SH SYNOPSIS .SH SYNOPSIS
.B smartctl [options] device .B smartctl [options] device
.\" %IF NOT OS Windows
.SH FULL PATH
.B /usr/local/sbin/smartctl
.\" %ENDIF NOT OS Windows
.SH PACKAGE VERSION .SH PACKAGE VERSION
CURRENT_SVN_VERSION CURRENT_SVN_DATE CURRENT_SVN_REV CURRENT_SVN_VERSION CURRENT_SVN_DATE CURRENT_SVN_REV
@ -47,7 +42,7 @@ and predict drive failures, and to carry out different types of drive
self-tests. self-tests.
\fBsmartctl\fP also supports some features not related to SMART. \fBsmartctl\fP also supports some features not related to SMART.
This version of \fBsmartctl\fP is compatible with This version of \fBsmartctl\fP is compatible with
ACS-2, ATA8-ACS, ATA/ATAPI-7 and earlier standards ACS-3, ACS-2, ATA8-ACS, ATA/ATAPI-7 and earlier standards
(see \fBREFERENCES\fP below). (see \fBREFERENCES\fP below).
\fBsmartctl\fP also provides support for polling TapeAlert messages \fBsmartctl\fP also provides support for polling TapeAlert messages
@ -164,9 +159,7 @@ values in base 10 (decimal), but some values are displayed in base 16
displayed with a leading \fB"0x"\fP, for example: "0xff". This man displayed with a leading \fB"0x"\fP, for example: "0xff". This man
page follows the same convention. page follows the same convention.
.PP
.SH OPTIONS .SH OPTIONS
.PP
The options are grouped below into several categories. \fBsmartctl\fP The options are grouped below into several categories. \fBsmartctl\fP
will execute the corresponding commands in the order: INFORMATION, will execute the corresponding commands in the order: INFORMATION,
ENABLE/DISABLE, DISPLAY DATA, RUN/ABORT TESTS. ENABLE/DISABLE, DISPLAY DATA, RUN/ABORT TESTS.
@ -195,8 +188,7 @@ drive model family may also be printed. If \'\-n\' (see below) is
specified, the power mode of the drive is printed. specified, the power mode of the drive is printed.
.TP .TP
.B \-\-identify[=[w][nvb]] .B \-\-identify[=[w][nvb]]
[ATA only] [NEW EXPERIMENTAL SMARTCTL FEATURE] Prints an annotated [ATA only] Prints an annotated table of the IDENTIFY DEVICE data.
table of the IDENTIFY DEVICE data.
By default, only valid words (words not equal to 0x0000 or 0xffff) By default, only valid words (words not equal to 0x0000 or 0xffff)
and nonzero bits and bit fields are printed. and nonzero bits and bit fields are printed.
This can be changed by the optional argument which consists of one or This can be changed by the optional argument which consists of one or
@ -375,11 +367,28 @@ It is possible to set RAID device name as /dev/bus/N, where N is a SCSI bus
number. number.
The following entry in /proc/devices must exist: The following entry in /proc/devices must exist:
.fi .br
For PERC2/3/4 controllers: \fBmegadevN\fP For PERC2/3/4 controllers: \fBmegadevN\fP
.fi .br
For PERC5/6 controllers: \fBmegaraid_sas_ioctlN\fP For PERC5/6 controllers: \fBmegaraid_sas_ioctlN\fP
.I aacraid,H,L,ID
\- [Linux only] [NEW EXPERIMENTAL SMARTCTL FEATURE]
the device consists of one or more SCSI/SAS disks connected to an AacRaid controller.
The non-negative integers H,L,ID (Host number, Lun, ID) denote which disk
on the controller is monitored.
Use syntax such as:
.nf
\fBsmartctl \-a \-d aacraid,0,0,66 /dev/sda\fP
.fi
.nf
\fBsmartctl \-a \-d aacraid,0,0,66 /dev/sdb\fP
.fi
The L and ID numbers of a disk can be found in /proc/scsi/scsi
The following entry in /proc/devices must exist: \fBaac\fP.
Character device nodes /dev/aacH (H=Host number) are created if required.
.\" %ENDIF OS Linux .\" %ENDIF OS Linux
.\" %IF OS FreeBSD Linux .\" %IF OS FreeBSD Linux
.I 3ware,N .I 3ware,N
@ -736,11 +745,7 @@ Note that the SMART automatic offline test command is listed as
"Obsolete" in every version of the ATA and ATA/ATAPI Specifications. "Obsolete" in every version of the ATA and ATA/ATAPI Specifications.
It was originally part of the SFF-8035i Revision 2.0 specification, It was originally part of the SFF-8035i Revision 2.0 specification,
but was never part of any ATA specification. However it is but was never part of any ATA specification. However it is
implemented and used by many vendors. [Good documentation can be found implemented and used by many vendors.
in IBM\'s Official Published Disk Specifications. For example the IBM
Travelstar 40GNX Hard Disk Drive Specifications (Revision 1.1, 22
April 2002, Publication # 1541, Document S07N-7715-02) page 164. You
can also read the SFF-8035i Specification -- see REFERENCES below.]
You can tell if automatic offline testing is supported by seeing if You can tell if automatic offline testing is supported by seeing if
this command enables and disables it, as indicated by the \'Auto this command enables and disables it, as indicated by the \'Auto
Offline Data Collection\' part of the SMART capabilities report Offline Data Collection\' part of the SMART capabilities report
@ -1098,13 +1103,12 @@ specification. Some commands are not defined in any version of the
ATA specification but are in common use nonetheless; these are marked ATA specification but are in common use nonetheless; these are marked
\fB[NS]\fP, meaning non-standard. \fB[NS]\fP, meaning non-standard.
The ATA Specification (ATA-5 Revision 1c, Section 8.41.6.8.2) says: The ATA Specification (ATA ACS-2 Revision 7, Section A.7.1) says:
\fB"Error log structures shall include UNC errors, IDNF errors for \fB"Error log data structures shall include, but are not limited to,
which the address requested was valid, servo errors, write fault Uncorrectable errors, ID Not Found errors for which the LBA requested was
errors, etc. Error log data structures shall not include errors valid, servo errors, and write fault errors. Error log data structures
attributed to the receipt of faulty commands such as command codes not shall not include errors attributed to the receipt of faulty commands."\fP
implemented by the device or requests with invalid parameters or The definitions of these terms are:
invalid addresses."\fP The definitions of these terms are:
.br .br
\fBUNC\fP (\fBUNC\fPorrectable): data is uncorrectable. This refers \fBUNC\fP (\fBUNC\fPorrectable): data is uncorrectable. This refers
to data which has been read from the disk, but for which the Error to data which has been read from the disk, but for which the Error
@ -1142,8 +1146,7 @@ log (see \'\-l error\' above), it provides sufficient space to log
the contents of the 48-bit LBA register set introduced with ATA-6. the contents of the 48-bit LBA register set introduced with ATA-6.
It also supports logs with more than one sector. Each sector holds It also supports logs with more than one sector. Each sector holds
up to 4 log entries. The actual number of log sectors is vendor up to 4 log entries. The actual number of log sectors is vendor
specific, typical values for HDD are 2 (Samsung), 5 (Seagate) or specific.
6 (WD).
Only the 8 most recent error log entries are printed by default. Only the 8 most recent error log entries are printed by default.
This number can be changed by the optional parameter NUM. This number can be changed by the optional parameter NUM.
@ -1197,7 +1200,7 @@ test terminology).
Log address 0x07). Unlike the SMART self-test log (see \'\-l selftest\' Log address 0x07). Unlike the SMART self-test log (see \'\-l selftest\'
above), it supports 48-bit LBA and logs with more than one sector. above), it supports 48-bit LBA and logs with more than one sector.
Each sector holds up to 19 log entries. The actual number of log sectors Each sector holds up to 19 log entries. The actual number of log sectors
is vendor specific, typical values are 1 (Seagate) or 2 (Samsung). is vendor specific.
Only the 25 most recent log entries are printed by default. This number Only the 25 most recent log entries are printed by default. This number
can be changed by the optional parameter NUM. can be changed by the optional parameter NUM.
@ -1270,7 +1273,7 @@ is vendor specific, typical values are 1, 2, or 5 minutes.
.I scterc[,READTIME,WRITETIME] .I scterc[,READTIME,WRITETIME]
\- [ATA only] prints values and descriptions of the SCT Error Recovery \- [ATA only] prints values and descriptions of the SCT Error Recovery
Control settings. These are equivalent to TLER (as used by Western Control settings. These are equivalent to TLER (as used by Western
Digital), CCTL (as used by Samsung and Hitachi) and ERC (as used by Digital), CCTL (as used by Samsung and Hitachi/HGST) and ERC (as used by
Seagate). READTIME and WRITETIME arguments (deciseconds) set the Seagate). READTIME and WRITETIME arguments (deciseconds) set the
specified values. Values of 0 disable the feature, other values less specified values. Values of 0 disable the feature, other values less
than 65 are probably not supported. For RAID configurations, this is than 65 are probably not supported. For RAID configurations, this is
@ -1281,9 +1284,7 @@ typically set to 70,70 deciseconds.
log pages (General Purpose Log address 0x04). If no PAGE number is specified, log pages (General Purpose Log address 0x04). If no PAGE number is specified,
entries from all supported pages are printed. If PAGE 0 is specified, entries from all supported pages are printed. If PAGE 0 is specified,
the list of supported pages is printed. Device Statistics was the list of supported pages is printed. Device Statistics was
introduced in ACS-2 and is only supported by some recent devices introduced in ACS-2 and is only supported by some recent devices.
(e.g. Hitachi 7K3000, Intel 320, 330, 520 and 710 Series SSDs, Crucial/Micron
m4 SSDs).
.I sataphy[,reset] .I sataphy[,reset]
\- [SATA only] prints values and descriptions of the SATA Phy Event \- [SATA only] prints values and descriptions of the SATA Phy Event
@ -1525,10 +1526,6 @@ is not reset if uncorrectable sectors are reallocated
.I 220,temp .I 220,temp
\- same as: \- same as:
.I 220,tempminmax,Temperature_Celsius. .I 220,tempminmax,Temperature_Celsius.
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 .TP
.B \-F TYPE, \-\-firmwarebug=TYPE .B \-F TYPE, \-\-firmwarebug=TYPE
[ATA only] Modifies the behavior of \fBsmartctl\fP to compensate for some [ATA only] Modifies the behavior of \fBsmartctl\fP to compensate for some
@ -1538,7 +1535,7 @@ multiple times. The valid arguments are:
.I none .I none
\- Assume that the device firmware obeys the ATA specifications. This \- Assume that the device firmware obeys the ATA specifications. This
is the default, unless the device has presets for \'\-F\' in the is the default, unless the device has presets for \'\-F\' in the
drive database. Using this option on the command line will over-ride any drive database. Using this option on the command line will override any
preset values. preset values.
.I nologdir .I nologdir
@ -1573,7 +1570,7 @@ execution status (see options \'\-c\' or \'\-a\' above) accordingly.
.I xerrorlba .I xerrorlba
\- Fixes LBA byte ordering in Extended Comprehensive SMART error log. \- Fixes LBA byte ordering in Extended Comprehensive SMART error log.
Some disk use little endian byte ordering instead of ATA register Some disks use little endian byte ordering instead of ATA register
ordering to specifiy the LBA addresses in the log entries. ordering to specifiy the LBA addresses in the log entries.
.I swapid .I swapid
@ -1585,15 +1582,6 @@ firmware version) returned by some buggy device drivers.
that are available for this drive. By default, if the drive is recognized that are available for this drive. By default, if the drive is recognized
in the \fBsmartmontools\fP database, then the presets are used. in the \fBsmartmontools\fP database, then the presets are used.
\fBsmartctl\fP can automatically set appropriate options for known
drives. For example, the Maxtor 4D080H4 uses Attribute 9 to stores
power-on time in minutes whereas most drives use that Attribute to
store the power-on time in hours. The command-line option \'\-v
9,minutes\' ensures that \fBsmartctl\fP correctly interprets Attribute
9 in this case, but that option is preset for the Maxtor 4D080H4 and
so need not be specified by the user on the \fBsmartctl\fP command
line.
The argument The argument
.I show .I show
will show any preset options for your drive and the argument will show any preset options for your drive and the argument
@ -1926,7 +1914,7 @@ T13/1699-D Revision 6a (ATA8-ACS). Note that the subcommands
\fBWARNING: Only run subcommands documented by the vendor of the \fBWARNING: Only run subcommands documented by the vendor of the
device.\fP device.\fP
Example for Intel (X18/X25-M G2, 320, 520 and 710 Series) SSDs only: Example for some Intel SSDs only:
The subcommand 0x40 (\'\-t vendor,0x40\') clears the timed workload The subcommand 0x40 (\'\-t vendor,0x40\') clears the timed workload
related SMART attributes (226, 227, 228). Note that the raw values of related SMART attributes (226, 227, 228). Note that the raw values of
these attributes are held at 65535 (0xffff) until the workload timer these attributes are held at 65535 (0xffff) until the workload timer
@ -1951,7 +1939,7 @@ mounted partitions!\fP
Aborts non-captive SMART Self Tests. Note that this Aborts non-captive SMART Self Tests. Note that this
command will abort the Offline Immediate Test routine only if your command will abort the Offline Immediate Test routine only if your
disk has the "Abort Offline collection upon new command" capability. disk has the "Abort Offline collection upon new command" capability.
.PP
.SH ATA, SCSI command sets and SAT .SH ATA, SCSI command sets and SAT
In the past there has been a clear distinction between storage devices In the past there has been a clear distinction between storage devices
that used the ATA and SCSI command sets. This distinction was often that used the ATA and SCSI command sets. This distinction was often
@ -1995,7 +1983,7 @@ disks from a distant OS is a challenge for smartmontools. Another
approach is running a tool like smartmontools inside the RAID 1 box (e.g. approach is running a tool like smartmontools inside the RAID 1 box (e.g.
a Network Attached Storage (NAS) box) and fetching the logs via a a Network Attached Storage (NAS) box) and fetching the logs via a
browser. browser.
.PP
.SH EXAMPLES .SH EXAMPLES
.nf .nf
.B smartctl \-a /dev/hda .B smartctl \-a /dev/hda
@ -2124,7 +2112,7 @@ device is restored.
.fi .fi
Examine all SMART data for the first SCSI disk connected to a cciss Examine all SMART data for the first SCSI disk connected to a cciss
RAID controller card. RAID controller card.
.PP
.SH RETURN VALUES .SH RETURN VALUES
The return values of \fBsmartctl\fP are defined by a bitmask. If all The return values of \fBsmartctl\fP are defined by a bitmask. If all
is well with the disk, the return value (exit status) of is well with the disk, the return value (exit status) of
@ -2165,8 +2153,8 @@ The device self-test log contains records of errors.
self-test are ignored. self-test are ignored.
.PP .PP
To test within the shell for whether or not the different bits are To test within the shell for whether or not the different bits are
turned on or off, you can use the following type of construction (this turned on or off, you can use the following type of construction
is bash syntax): (which should work with any POSIX compatible shell):
.nf .nf
.B smartstat=$(($? & 8)) .B smartstat=$(($? & 8))
.fi .fi
@ -2175,23 +2163,37 @@ This looks at only at bit 3 of the exit status
(since 8=2^3). The shell variable (since 8=2^3). The shell variable
$smartstat will be nonzero if SMART status check returned "disk $smartstat will be nonzero if SMART status check returned "disk
failing" and zero otherwise. failing" and zero otherwise.
.PP
This bash script prints all status bits: This shell script prints all status bits:
.nf .nf
status=$? val=$?; mask=1
for ((i=0; i<8; i++)); do for i in 0 1 2 3 4 5 6 7; do
echo "Bit $i: $((status & 2**i && 1))" echo "Bit $i: $(((val & mask) && 1))"
mask=$((mask << 1))
done done
.fi .fi
.PP .\" %IF NOT OS Windows
.SH FILES
.TP
.B /usr/local/sbin/smartctl
full path of this executable.
.\" %IF ENABLE_DRIVEDB
.TP
.B /usr/local/share/smartmontools/drivedb.h
drive database (see \'\-B\' option).
.\" %ENDIF ENABLE_DRIVEDB
.TP
.B /usr/local/etc/smart_drivedb.h
optional local drive database (see \'\-B\' option).
.\" %ENDIF NOT OS Windows
.SH NOTES .SH NOTES
The TapeAlert log page flags are cleared for the initiator when the The TapeAlert log page flags are cleared for the initiator when the
page is read. This means that each alert condition is reported only page is read. This means that each alert condition is reported only
once by \fBsmartctl\fP for each initiator for each activation of the once by \fBsmartctl\fP for each initiator for each activation of the
condition. condition.
.PP
.SH AUTHORS .SH AUTHORS
\fBBruce Allen\fP \fBBruce Allen\fP
.br .br
@ -2202,49 +2204,53 @@ since 2009)
.br .br
\fBsmartmontools\-support@lists.sourceforge.net\fP \fBsmartmontools\-support@lists.sourceforge.net\fP
.PP
.SH CONTRIBUTORS
The following have made large contributions to smartmontools: The following have made large contributions to smartmontools:
.nf .br
\fBCasper Dik\fP (Solaris SCSI interface) \fBCasper Dik\fP (Solaris SCSI interface)
.br
\fBDouglas Gilbert\fP (SCSI subsystem) \fBDouglas Gilbert\fP (SCSI subsystem)
.br
\fBGuido Guenther\fP (Autoconf/Automake packaging) \fBGuido Guenther\fP (Autoconf/Automake packaging)
.br
\fBGeoffrey Keating\fP (Darwin ATA interface) \fBGeoffrey Keating\fP (Darwin ATA interface)
.br
\fBEduard Martinescu\fP (FreeBSD interface) \fBEduard Martinescu\fP (FreeBSD interface)
.br
\fBFr\['e]d\['e]ric L. W. Meunier\fP (Web site and Mailing list) \fBFr\['e]d\['e]ric L. W. Meunier\fP (Web site and Mailing list)
.br
\fBGabriele Pohl\fP (Web site and Wiki, conversion from CVS to SVN) \fBGabriele Pohl\fP (Web site and Wiki, conversion from CVS to SVN)
.br
\fBKeiji Sawada\fP (Solaris ATA interface) \fBKeiji Sawada\fP (Solaris ATA interface)
.br
\fBManfred Schwarb\fP (Drive database) \fBManfred Schwarb\fP (Drive database)
.br
\fBSergey Svishchev\fP (NetBSD interface) \fBSergey Svishchev\fP (NetBSD interface)
.br
\fBDavid Snyder and Sergey Svishchev\fP (OpenBSD interface) \fBDavid Snyder and Sergey Svishchev\fP (OpenBSD interface)
.br
\fBPhil Williams\fP (User interface and drive database) \fBPhil Williams\fP (User interface and drive database)
.br
\fBYuri Dario\fP (OS/2, eComStation interface) \fBYuri Dario\fP (OS/2, eComStation interface)
.br
\fBShengfeng Zhou\fP (Linux/FreeBSD HighPoint RocketRAID interface) \fBShengfeng Zhou\fP (Linux/FreeBSD HighPoint RocketRAID interface)
.fi .br
Many other individuals have made smaller contributions and corrections. Many other individuals have made smaller contributions and corrections.
.PP The first smartmontools code was derived from the smartsuite package,
.SH CREDITS written by Michael Cornwell, and from the previous UCSC smartsuite package.
.fi This code was originally developed as a
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
Senior Thesis by Michael Cornwell at the Concurrent Systems Laboratory Senior Thesis by Michael Cornwell at the Concurrent Systems Laboratory
(now part of the Storage Systems Research Center), Jack Baskin School (now part of the Storage Systems Research Center), Jack Baskin School
of Engineering, University of California, Santa of Engineering, University of California, Santa
Cruz. \fBhttp://ssrc.soe.ucsc.edu/\fP . Cruz. \fBhttp://ssrc.soe.ucsc.edu/\fP .
.SH
HOME PAGE FOR SMARTMONTOOLS:
.fi
Please see the following web site for updates, further documentation, bug
reports and patches: \fBhttp://smartmontools.sourceforge.net/\fP
.SH .SH SEE ALSO
SEE ALSO: \fBsmartd\fP(8), \fBupdate-smart-drivedb\fP(8).
\fBsmartd\fP(8), \fBbadblocks\fP(8), \fBide\-smart\fP(8).
.SH .SH REFERENCES
REFERENCES FOR SMART Please see the following web site for more info:
.fi \fBhttp://smartmontools.sourceforge.net/\fP
An introductory article about smartmontools is \fIMonitoring Hard An introductory article about smartmontools is \fIMonitoring Hard
Disks with SMART\fP, by Bruce Allen, Linux Journal, January 2004, Disks with SMART\fP, by Bruce Allen, Linux Journal, January 2004,
pages 74-77. This is \fBhttp://www.linuxjournal.com/article/6983\fP pages 74-77. This is \fBhttp://www.linuxjournal.com/article/6983\fP
@ -2256,15 +2262,12 @@ volume of the \'AT Attachment with Packet Interface-7\' (ATA/ATAPI-7)
specification Revision 4b. This documents the SMART functionality which the specification Revision 4b. This documents the SMART functionality which the
\fBsmartmontools\fP utilities provide access to. \fBsmartmontools\fP utilities provide access to.
.fi
The functioning of SMART was originally defined by the SFF-8035i The functioning of SMART was originally defined by the SFF-8035i
revision 2 and the SFF-8055i revision 1.4 specifications. These are revision 2 and the SFF-8055i revision 1.4 specifications. These are
publications of the Small Form Factors (SFF) Committee. publications of the Small Form Factors (SFF) Committee.
Links to these and other documents may be found on the Links page of the Links to these and other documents may be found on the Links page of the
\fBsmartmontools\fP Wiki at \fBsmartmontools\fP Wiki at \fBhttp://www.smartmontools.org/wiki/Links\fP .
\fBhttp://sourceforge.net/apps/trac/smartmontools/wiki/Links\fP .
.SH .SH SVN ID OF THIS PAGE
SVN ID OF THIS PAGE: $Id: smartctl.8.in 3965 2014-07-20 14:46:41Z chrfranke $
$Id: smartctl.8.in 3832 2013-07-20 14:49:31Z chrfranke $

View File

@ -4,7 +4,7 @@
* Home page of code is: http://smartmontools.sourceforge.net * Home page of code is: http://smartmontools.sourceforge.net
* *
* Copyright (C) 2002-11 Bruce Allen <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2002-11 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2008-12 Christian Franke <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2008-14 Christian Franke <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2000 Michael Cornwell <cornwell@acm.org> * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -26,6 +26,7 @@
#include <stdio.h> #include <stdio.h>
#include <sys/types.h> #include <sys/types.h>
#include <string.h> #include <string.h>
#include <stdlib.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdexcept> #include <stdexcept>
#include <getopt.h> #include <getopt.h>
@ -50,7 +51,7 @@
#include "smartctl.h" #include "smartctl.h"
#include "utility.h" #include "utility.h"
const char * smartctl_cpp_cvsid = "$Id: smartctl.cpp 3826 2013-07-06 21:57:29Z samm2 $" const char * smartctl_cpp_cvsid = "$Id: smartctl.cpp 3936 2014-07-05 17:16:23Z chrfranke $"
CONFIG_H_CVSID SMARTCTL_H_CVSID; CONFIG_H_CVSID SMARTCTL_H_CVSID;
// Globals to control printing // Globals to control printing
@ -724,7 +725,7 @@ static const char * parse_options(int argc, char** argv,
} else { } else {
if (ataopts.smart_selective_args.num_spans >= 5 || start > stop) { if (ataopts.smart_selective_args.num_spans >= 5 || start > stop) {
if (start > stop) { if (start > stop) {
snprintf(extraerror, sizeof(extraerror), "ERROR: Start LBA (%"PRIu64") > ending LBA (%"PRId64") in argument \"%s\"\n", snprintf(extraerror, sizeof(extraerror), "ERROR: Start LBA (%" PRIu64 ") > ending LBA (%" PRId64 ") in argument \"%s\"\n",
start, stop, optarg); start, stop, optarg);
} else { } else {
snprintf(extraerror, sizeof(extraerror),"ERROR: No more than five selective self-test spans may be" snprintf(extraerror, sizeof(extraerror),"ERROR: No more than five selective self-test spans may be"
@ -1212,8 +1213,8 @@ void scan_devices(const char * type, bool with_open, char ** argv)
// Main program without exception handling // Main program without exception handling
static int main_worker(int argc, char **argv) static int main_worker(int argc, char **argv)
{ {
// Throw if CPU endianess does not match compile time test. // Throw if runtime environment does not match compile time test.
check_endianness(); check_config();
// Initialize interface // Initialize interface
smart_interface::init(); smart_interface::init();

View File

@ -1,8 +1,8 @@
.ig .ig
Copyright (C) 2002-10 Bruce Allen <smartmontools-support@lists.sourceforge.net> Copyright (C) 2002-10 Bruce Allen <smartmontools-support@lists.sourceforge.net>
Copyright (C) 2004-13 Christian Franke <smartmontools-support@lists.sourceforge.net> Copyright (C) 2004-14 Christian Franke <smartmontools-support@lists.sourceforge.net>
$Id: smartd.8.in 3799 2013-03-15 17:47:25Z chrfranke $ $Id: smartd.8.in 3965 2014-07-20 14:46:41Z chrfranke $
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -25,11 +25,6 @@ California, Santa Cruz. http://ssrc.soe.ucsc.edu/
.SH SYNOPSIS .SH SYNOPSIS
.B smartd [options] .B smartd [options]
.\" %IF NOT OS Windows
.SH FULL PATH
.B /usr/local/sbin/smartd
.\" %ENDIF NOT OS Windows
.SH PACKAGE VERSION .SH PACKAGE VERSION
CURRENT_SVN_VERSION CURRENT_SVN_DATE CURRENT_SVN_REV CURRENT_SVN_VERSION CURRENT_SVN_DATE CURRENT_SVN_REV
@ -46,7 +41,7 @@ The purpose of SMART is to monitor the reliability of the hard drive
and predict drive failures, and to carry out different types of drive and predict drive failures, and to carry out different types of drive
self-tests. self-tests.
This version of \fBsmartd\fP is compatible with This version of \fBsmartd\fP is compatible with
ACS-2, ATA8-ACS, ATA/ATAPI-7 and earlier standards ACS-3, ACS-2, ATA8-ACS, ATA/ATAPI-7 and earlier standards
(see \fBREFERENCES\fP below). (see \fBREFERENCES\fP below).
\fBsmartd\fP will attempt to enable SMART monitoring on ATA devices \fBsmartd\fP will attempt to enable SMART monitoring on ATA devices
@ -76,9 +71,9 @@ file \fB/usr/local/etc/smartd.conf\fP (Windows: \fBEXEDIR/smartd.conf\fP).
If the configuration file is subsequently modified, \fBsmartd\fP If the configuration file is subsequently modified, \fBsmartd\fP
can be told to re-read the configuration file by sending it a can be told to re-read the configuration file by sending it a
\fBHUP\fP signal, for example with the command: \fBHUP\fP signal, for example with the command:
.fi .br
\fBkillall -HUP smartd\fP. \fBkillall -HUP smartd\fP.
.fi .br
.\" %IF OS Windows .\" %IF OS Windows
(Windows: See NOTES below.) (Windows: See NOTES below.)
.\" %ENDIF OS Windows .\" %ENDIF OS Windows
@ -150,9 +145,7 @@ Disks behind Areca RAID controllers are not included.
for \fIall\fP possible SMART errors (corresponding to the \fB\'\-a\'\fP for \fIall\fP possible SMART errors (corresponding to the \fB\'\-a\'\fP
Directive in the configuration file; see the \fBsmartd.conf\fP(5) man page). Directive in the configuration file; see the \fBsmartd.conf\fP(5) man page).
.SH .SH OPTIONS
OPTIONS
.TP .TP
.B \-A PREFIX, \-\-attributelog=PREFIX .B \-A PREFIX, \-\-attributelog=PREFIX
Writes \fBsmartd\fP attribute information (normalized and raw Writes \fBsmartd\fP attribute information (normalized and raw
@ -199,7 +192,7 @@ to perform quick and simple checks without a configuration file.
.\" %IF ENABLE_CAPABILITIES .\" %IF ENABLE_CAPABILITIES
.TP .TP
.B \-C, \-\-capabilities .B \-C, \-\-capabilities
Use \fBcapabilities(7)\fP. Use \fBcapabilities\fP(7).
Warning: Mail notification does not work when used. Warning: Mail notification does not work when used.
.\" %ENDIF ENABLE_CAPABILITIES .\" %ENDIF ENABLE_CAPABILITIES
@ -207,7 +200,7 @@ Warning: Mail notification does not work when used.
.B \-d, \-\-debug .B \-d, \-\-debug
Runs \fBsmartd\fP in "debug" mode. In this mode, it displays status Runs \fBsmartd\fP in "debug" mode. In this mode, it displays status
information to STDOUT rather than logging it to SYSLOG and does not information to STDOUT rather than logging it to SYSLOG and does not
\fBfork(2)\fP into the background and detach from the controlling \fBfork\fP(2) into the background and detach from the controlling
terminal. In this mode, \fBsmartd\fP also prints more verbose terminal. In this mode, \fBsmartd\fP also prints more verbose
information about what it is doing than when operating in "daemon" information about what it is doing than when operating in "daemon"
mode. In this mode, the \fBINT\fP signal (normally generated from a mode. In this mode, the \fBINT\fP signal (normally generated from a
@ -224,8 +217,8 @@ debug mode is enabled.
.B \-D, \-\-showdirectives .B \-D, \-\-showdirectives
Prints a list (to STDOUT) of all the possible Directives which may Prints a list (to STDOUT) of all the possible Directives which may
appear in the configuration file /usr/local/etc/smartd.conf, and then exits. appear in the configuration file /usr/local/etc/smartd.conf, and then exits.
These Directives are also described later in this man page. They may These Directives are described in the \fBsmartd.conf\fP(5) man page.
appear in the configuration file following the device name. They may appear in the configuration file following the device name.
.TP .TP
.B \-h, \-\-help, \-\-usage .B \-h, \-\-help, \-\-usage
Prints usage message to STDOUT and exits. Prints usage message to STDOUT and exits.
@ -248,7 +241,7 @@ also use:
.B killall -USR1 smartd .B killall -USR1 smartd
.fi .fi
for the same purpose. for the same purpose.
.fi .br
.\" %IF OS Windows .\" %IF OS Windows
(Windows: See NOTES below.) (Windows: See NOTES below.)
.\" %ENDIF OS Windows .\" %ENDIF OS Windows
@ -261,35 +254,14 @@ then by default messages from \fBsmartd\fP are logged to the facility
\fIdaemon\fP. \fIdaemon\fP.
If you would like to have \fBsmartd\fP messages logged somewhere other If you would like to have \fBsmartd\fP messages logged somewhere other
than the default location, this can typically be accomplished with than the default location, include (for example) \'\-l local3\' in its
(for example) the following steps: start up argument list.
.RS 7 Tell the syslog daemon to log all messages from facility \fBlocal3\fP
.IP \fB[1]\fP 4 to (for example) \'/var/log/smartd.log\'.
Modify the script that starts \fBsmartd\fP to include the \fBsmartd\fP
command-line argument \'\-l local3\'. This tells \fBsmartd\fP to log its
messages to facility \fBlocal3\fP.
.IP \fB[2]\fP 4
Modify the \fBsyslogd\fP configuration file (typically
\fB/etc/syslog.conf\fP) by adding a line of the form:
.nf
\fBlocal3.* /var/log/smartd.log\fP
.fi
This tells \fBsyslogd\fP to log all the messages from facility \fBlocal3\fP to
the designated file: /var/log/smartd.log.
.IP \fB[3]\fP 4
Tell \fBsyslogd\fP to re-read its configuration file, typically by
sending the \fBsyslogd\fP process a \fBSIGHUP\fP hang-up signal.
.IP \fB[4]\fP 4
Start (or restart) the \fBsmartd\fP daemon.
.RE
.\" The following two lines are a workaround for a man2html bug. Please leave them.
.\" They define a non-existent option; useful because man2html can't correctly reset the margins.
.TP
.B \&
For more detailed information, please refer to the man pages for For more detailed information, please refer to the man pages for
\fBsyslog.conf\fP, \fBsyslogd\fP, and \fBsyslog\fP. You may also want the local syslog daemon, typically \fBsyslogd\fP(8), \fBsyslog-ng\fP(8)
to modify the log rotation configuration files; see the man pages for or \fBrsyslogd\fP(8).
\fBlogrotate\fP and examine your system\'s /etc/logrotate.conf file.
.\" %IF OS Cygwin .\" %IF OS Cygwin
Cygwin: If no \fBsyslogd\fP is running, the \'\-l\' option has no effect. Cygwin: If no \fBsyslogd\fP is running, the \'\-l\' option has no effect.
@ -473,30 +445,25 @@ information for your copy of \fBsmartd\fP to STDOUT and then exits.
Please include this information if you are reporting bugs or problems. Please include this information if you are reporting bugs or problems.
.SH EXAMPLES .SH EXAMPLES
.B smartd
.B .br
smartd
.fi
Runs the daemon in forked mode. This is the normal way to run Runs the daemon in forked mode. This is the normal way to run
\fBsmartd\fP. \fBsmartd\fP.
Entries are logged to SYSLOG. Entries are logged to SYSLOG.
.B .B smartd -d -i 30
smartd -d -i 30 .br
.fi
Run in foreground (debug) mode, checking the disk status Run in foreground (debug) mode, checking the disk status
every 30 seconds. every 30 seconds.
.B .B smartd -q onecheck
smartd -q onecheck .br
.fi
Registers devices, and checks the status of the devices exactly Registers devices, and checks the status of the devices exactly
once. The exit status (the bash once. The exit status (the shell
.B $? .B $?
variable) will be zero if all went well, and nonzero if no devices variable) will be zero if all went well, and nonzero if no devices
were detected or some other problem was encountered. were detected or some other problem was encountered.
.fi
Note that \fBsmartmontools\fP provides a start-up script in Note that \fBsmartmontools\fP provides a start-up script in
\fB/usr/local/etc/rc.d/init.d/smartd\fP which is responsible for starting and \fB/usr/local/etc/rc.d/init.d/smartd\fP which is responsible for starting and
stopping the daemon via the normal init interface. Using this script, stopping the daemon via the normal init interface. Using this script,
@ -508,8 +475,10 @@ and stop it by using the command:
.nf .nf
.B /usr/local/etc/rc.d/init.d/smartd stop .B /usr/local/etc/rc.d/init.d/smartd stop
.fi .fi
.SH CONFIGURATION .SH CONFIGURATION
The syntax of the smartd.conf(5) file is discussed separately. The syntax of the \fBsmartd.conf\fP(5) file is discussed separately.
.SH NOTES .SH NOTES
\fBsmartd\fP \fBsmartd\fP
will make log entries at loglevel will make log entries at loglevel
@ -642,21 +611,19 @@ checks disks immediately (like \fBSIGUSR1\fP).
.\" %ENDIF OS Windows .\" %ENDIF OS Windows
.SH LOG TIMESTAMP TIMEZONE .SH LOG TIMESTAMP TIMEZONE
When \fBsmartd\fP makes log entries, these are time-stamped. The time When \fBsmartd\fP makes log entries, these are time-stamped. The time
stamps are in the computer's local time zone, which is generally set stamps are in the computer's local time zone, which is generally set
using either the environment variable \'\fBTZ\fP\' or using a using either the environment variable \'\fBTZ\fP\' or using a
time-zone file such as \fB/etc/localtime\fP. You may wish to change time-zone file such as \fB/etc/localtime\fP. You may wish to change
the timezone while \fBsmartd\fP is running (for example, if you carry the timezone while \fBsmartd\fP is running (for example, if you carry
a laptop to a new time-zone and don't reboot it). Due to a bug in the a laptop to a new time-zone and don't reboot it). Due to a bug in the
\fBtzset(3)\fP function of many unix standard C libraries, the \fBtzset\fP(3) function of many unix standard C libraries, the
time-zone stamps of \fBsmartd\fP might not change. For some systems, time-zone stamps of \fBsmartd\fP might not change. For some systems,
\fBsmartd\fP will work around this problem \fIif\fP the time-zone is \fBsmartd\fP will work around this problem \fIif\fP the time-zone is
set using \fB/etc/localtime\fP. The work-around \fIfails\fP if the set using \fB/etc/localtime\fP. The work-around \fIfails\fP if the
time-zone is set using the \'\fBTZ\fP\' variable (or a file that it time-zone is set using the \'\fBTZ\fP\' variable (or a file that it
points to). points to).
.SH RETURN VALUES .SH RETURN VALUES
The return value (exit status) of The return value (exit status) of
\fBsmartd\fP \fBsmartd\fP
@ -722,7 +689,34 @@ status is then 128 plus the signal number. For example if
\fBsmartd\fP \fBsmartd\fP
is killed by SIGKILL (signal 9) then the exit status is 137. is killed by SIGKILL (signal 9) then the exit status is 137.
.PP .\" %IF NOT OS Windows
.SH FILES
.TP
.B /usr/local/sbin/smartd
full path of this executable.
.TP
.B /usr/local/etc/smartd.conf
configuration file (see \fBsmartd.conf\fP(5) man page).
.TP
.B /usr/local/etc/smartd_warning.sh
script run on warnings (see \'\-M exec\' directive on
\fBsmartd.conf\fP(5) man page).
.\" %IF ENABLE_SMARTDPLUGINDIR
.TP
.B /usr/local/etc/smartd_warning.d/
plugin directory for smartd warning script (see \'\-m\' directive on
\fBsmartd.conf\fP(5) man page).
.\" %ENDIF ENABLE_SMARTDPLUGINDIR
.\" %IF ENABLE_DRIVEDB
.TP
.B /usr/local/share/smartmontools/drivedb.h
drive database (see \'\-B\' option).
.\" %ENDIF ENABLE_DRIVEDB
.TP
.B /usr/local/etc/smart_drivedb.h
optional local drive database (see \'\-B\' option).
.\" %ENDIF NOT OS Windows
.SH AUTHORS .SH AUTHORS
\fBBruce Allen\fP \fBBruce Allen\fP
.br .br
@ -733,50 +727,51 @@ since 2009)
.br .br
\fBsmartmontools\-support@lists.sourceforge.net\fP \fBsmartmontools\-support@lists.sourceforge.net\fP
.PP
.SH CONTRIBUTORS
The following have made large contributions to smartmontools: The following have made large contributions to smartmontools:
.nf .br
\fBCasper Dik\fP (Solaris SCSI interface) \fBCasper Dik\fP (Solaris SCSI interface)
.br
\fBDouglas Gilbert\fP (SCSI subsystem) \fBDouglas Gilbert\fP (SCSI subsystem)
.br
\fBGuido Guenther\fP (Autoconf/Automake packaging) \fBGuido Guenther\fP (Autoconf/Automake packaging)
.br
\fBGeoffrey Keating\fP (Darwin ATA interface) \fBGeoffrey Keating\fP (Darwin ATA interface)
.br
\fBEduard Martinescu\fP (FreeBSD interface) \fBEduard Martinescu\fP (FreeBSD interface)
.br
\fBFr\['e]d\['e]ric L. W. Meunier\fP (Web site and Mailing list) \fBFr\['e]d\['e]ric L. W. Meunier\fP (Web site and Mailing list)
.br
\fBGabriele Pohl\fP (Web site and Wiki, conversion from CVS to SVN) \fBGabriele Pohl\fP (Web site and Wiki, conversion from CVS to SVN)
.br
\fBKeiji Sawada\fP (Solaris ATA interface) \fBKeiji Sawada\fP (Solaris ATA interface)
.br
\fBManfred Schwarb\fP (Drive database) \fBManfred Schwarb\fP (Drive database)
.br
\fBSergey Svishchev\fP (NetBSD interface) \fBSergey Svishchev\fP (NetBSD interface)
.br
\fBDavid Snyder and Sergey Svishchev\fP (OpenBSD interface) \fBDavid Snyder and Sergey Svishchev\fP (OpenBSD interface)
.br
\fBPhil Williams\fP (User interface and drive database) \fBPhil Williams\fP (User interface and drive database)
.br
\fBShengfeng Zhou\fP (Linux/FreeBSD HighPoint RocketRAID interface) \fBShengfeng Zhou\fP (Linux/FreeBSD HighPoint RocketRAID interface)
.fi .br
Many other individuals have made smaller contributions and corrections. Many other individuals have made smaller contributions and corrections.
.PP The first smartmontools code was derived from the smartsuite package,
.SH CREDITS written by Michael Cornwell, and from the previous UCSC smartsuite package.
.fi This code was originally developed as a
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
Senior Thesis by Michael Cornwell at the Concurrent Systems Laboratory Senior Thesis by Michael Cornwell at the Concurrent Systems Laboratory
(now part of the Storage Systems Research Center), Jack Baskin School (now part of the Storage Systems Research Center), Jack Baskin School
of Engineering, University of California, Santa of Engineering, University of California, Santa
Cruz. \fBhttp://ssrc.soe.ucsc.edu/\fP . Cruz. \fBhttp://ssrc.soe.ucsc.edu/\fP .
.SH
HOME PAGE FOR SMARTMONTOOLS:
.fi
Please see the following web site for updates, further documentation, bug
reports and patches: \fBhttp://smartmontools.sourceforge.net/\fP
.SH .SH SEE ALSO
SEE ALSO: \fBsmartd.conf\fP(5), \fBsmartctl\fP(8), \fBupdate-smart-drivedb\fP(8).
\fBsmartd.conf\fP(5), \fBsmartctl\fP(8), \fBsyslogd\fP(8),
\fBsyslog.conf\fP(5), \fBbadblocks\fP(8), \fBide\-smart\fP(8), \fBregex\fP(7). .SH REFERENCES
Please see the following web site for more info:
\fBhttp://smartmontools.sourceforge.net/\fP
.SH
REFERENCES FOR SMART
.fi
An introductory article about smartmontools is \fIMonitoring Hard An introductory article about smartmontools is \fIMonitoring Hard
Disks with SMART\fP, by Bruce Allen, Linux Journal, January 2004, Disks with SMART\fP, by Bruce Allen, Linux Journal, January 2004,
pages 74-77. This is \fBhttp://www.linuxjournal.com/article/6983\fP pages 74-77. This is \fBhttp://www.linuxjournal.com/article/6983\fP
@ -788,15 +783,12 @@ volume of the \'AT Attachment with Packet Interface-7\' (ATA/ATAPI-7)
specification Revision 4b. This documents the SMART functionality which the specification Revision 4b. This documents the SMART functionality which the
\fBsmartmontools\fP utilities provide access to. \fBsmartmontools\fP utilities provide access to.
.fi
The functioning of SMART was originally defined by the SFF-8035i The functioning of SMART was originally defined by the SFF-8035i
revision 2 and the SFF-8055i revision 1.4 specifications. These are revision 2 and the SFF-8055i revision 1.4 specifications. These are
publications of the Small Form Factors (SFF) Committee. publications of the Small Form Factors (SFF) Committee.
Links to these and other documents may be found on the Links page of the Links to these and other documents may be found on the Links page of the
\fBsmartmontools\fP Wiki at \fBsmartmontools\fP Wiki at \fBhttp://www.smartmontools.org/wiki/Links\fP .
\fBhttp://sourceforge.net/apps/trac/smartmontools/wiki/Links\fP .
.SH .SH SVN ID OF THIS PAGE
SVN ID OF THIS PAGE: $Id: smartd.8.in 3965 2014-07-20 14:46:41Z chrfranke $
$Id: smartd.8.in 3799 2013-03-15 17:47:25Z chrfranke $

View File

@ -1,8 +1,8 @@
.ig .ig
Copyright (C) 2002-10 Bruce Allen <smartmontools-support@lists.sourceforge.net> Copyright (C) 2002-10 Bruce Allen <smartmontools-support@lists.sourceforge.net>
Copyright (C) 2004-13 Christian Franke <smartmontools-support@lists.sourceforge.net> Copyright (C) 2004-14 Christian Franke <smartmontools-support@lists.sourceforge.net>
$Id: smartd.conf.5.in 3833 2013-07-20 15:00:04Z chrfranke $ $Id: smartd.conf.5.in 3965 2014-07-20 14:46:41Z chrfranke $
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -22,11 +22,6 @@ California, Santa Cruz. http://ssrc.soe.ucsc.edu/
.SH NAME .SH NAME
\fBsmartd.conf\fP \- SMART Disk Monitoring Daemon Configuration File\fP \fBsmartd.conf\fP \- SMART Disk Monitoring Daemon Configuration File\fP
.\" %IF NOT OS Windows
.SH FULL PATH
.B /usr/local/etc/smartd.conf
.\" %ENDIF NOT OS Windows
.SH PACKAGE VERSION .SH PACKAGE VERSION
CURRENT_SVN_VERSION CURRENT_SVN_DATE CURRENT_SVN_REV CURRENT_SVN_VERSION CURRENT_SVN_DATE CURRENT_SVN_REV
@ -84,8 +79,8 @@ non-whitespace or non-comment item on a line.
Note: a line whose first character is a hash sign \'#\' is treated as Note: a line whose first character is a hash sign \'#\' is treated as
a white-space blank line, \fBnot\fP as a non-existent line, and will a white-space blank line, \fBnot\fP as a non-existent line, and will
\fBend\fP a continuation line. \fBend\fP a continuation line.
.PP 0 .PP
.fi
Here is an example configuration file. It\'s for illustrative purposes Here is an example configuration file. It\'s for illustrative purposes
only; please don\'t copy it onto your system without reading to the end only; please don\'t copy it onto your system without reading to the end
of the of the
@ -104,7 +99,6 @@ Section below!
.B # device, four SATA disks connected to an Areca .B # device, four SATA disks connected to an Areca
.B # RAID controller, and one SATA disk. .B # RAID controller, and one SATA disk.
.B # .B #
.nf
.B # First ATA disk on two different interfaces. On .B # First ATA disk on two different interfaces. On
.B # the second disk, start a long self-test every .B # the second disk, start a long self-test every
.B # Sunday between 3 and 4 am. .B # Sunday between 3 and 4 am.
@ -112,19 +106,16 @@ Section below!
.B \ \ /dev/hda -a -m admin@example.com,root@localhost .B \ \ /dev/hda -a -m admin@example.com,root@localhost
.B \ \ /dev/hdc -a -I 194 -I 5 -i 12 -s L/../../7/03 .B \ \ /dev/hdc -a -I 194 -I 5 -i 12 -s L/../../7/03
.B # .B #
.nf
.B # SCSI disks. Send a TEST warning email to admin on .B # SCSI disks. Send a TEST warning email to admin on
.B # startup. .B # startup.
.B # .B #
.B \ \ /dev/sda .B \ \ /dev/sda
.B \ \ /dev/sdb -m admin@example.com -M test .B \ \ /dev/sdb -m admin@example.com -M test
.B # .B #
.nf
.B # Strange device. It\'s SCSI. Start a scheduled .B # Strange device. It\'s SCSI. Start a scheduled
.B # long self test between 5 and 6 am Monday/Thursday .B # long self test between 5 and 6 am Monday/Thursday
.B \ \ /dev/weird -d scsi -s L/../../(1|4)/05 .B \ \ /dev/weird -d scsi -s L/../../(1|4)/05
.B # .B #
.nf
.B # An ATA disk may appear as a SCSI device to the .B # An ATA disk may appear as a SCSI device to the
.B # OS. If a SCSI to ATA Translation (SAT) layer .B # OS. If a SCSI to ATA Translation (SAT) layer
.B # is between the OS and the device then this can be .B # is between the OS and the device then this can be
@ -133,7 +124,6 @@ Section below!
.B # environments. .B # environments.
.B \ \ /dev/sda -a -d sat .B \ \ /dev/sda -a -d sat
.B # .B #
.nf
.\" %IF OS Linux .\" %IF OS Linux
.B # Three disks connected to a MegaRAID controller .B # Three disks connected to a MegaRAID controller
.B # Start short self-tests daily between 1-2, 2-3, and .B # Start short self-tests daily between 1-2, 2-3, and
@ -142,10 +132,15 @@ Section below!
.B \ \ /dev/sda -d megaraid,1 -a -s S/../.././02 .B \ \ /dev/sda -d megaraid,1 -a -s S/../.././02
.B \ \ /dev/sda -d megaraid,2 -a -s S/../.././03 .B \ \ /dev/sda -d megaraid,2 -a -s S/../.././03
.B \ \ /dev/bus/0 -d megaraid,2 -a -s S/../.././03 .B \ \ /dev/bus/0 -d megaraid,2 -a -s S/../.././03
.B .B #
.B # Three disks connected to an AacRaid controller
.B # Start short self-tests daily between 1-2, 2-3, and
.B # 3-4 am.
.B \ \ /dev/sda -d aacraid,0,0,66 -a -s S/../.././01
.B \ \ /dev/sda -d aacraid,0,0,67 -a -s S/../.././02
.B \ \ /dev/sda -d aacraid,0,0,68 -a -s S/../.././03
.B # .B #
.\" %ENDIF OS Linux .\" %ENDIF OS Linux
.nf
.B # Four ATA disks on a 3ware 6/7/8000 controller. .B # Four ATA disks on a 3ware 6/7/8000 controller.
.B # Start short self-tests daily between midnight and 1am, .B # Start short self-tests daily between midnight and 1am,
.B # 1-2, 2-3, and 3-4 am. Starting with the Linux 2.6 .B # 1-2, 2-3, and 3-4 am. Starting with the Linux 2.6
@ -157,14 +152,12 @@ Section below!
.B \ \ /dev/sdd -d 3ware,2 -a -s S/../.././02 .B \ \ /dev/sdd -d 3ware,2 -a -s S/../.././02
.B \ \ /dev/sdd -d 3ware,3 -a -s S/../.././03 .B \ \ /dev/sdd -d 3ware,3 -a -s S/../.././03
.B # .B #
.nf
.B # Two ATA disks on a 3ware 9000 controller. .B # Two ATA disks on a 3ware 9000 controller.
.B # Start long self-tests Sundays between midnight and .B # Start long self-tests Sundays between midnight and
.B # 1am and 2-3 am .B # 1am and 2-3 am
.B \ \ /dev/twa0 -d 3ware,0 -a -s L/../../7/00 .B \ \ /dev/twa0 -d 3ware,0 -a -s L/../../7/00
.B \ \ /dev/twa0 -d 3ware,1 -a -s L/../../7/02 .B \ \ /dev/twa0 -d 3ware,1 -a -s L/../../7/02
.B # .B #
.nf
.B # Two SATA (not SAS) disks on a 3ware 9750 controller. .B # Two SATA (not SAS) disks on a 3ware 9750 controller.
.B # Start long self-tests Sundays between midnight and .B # Start long self-tests Sundays between midnight and
.B # 1am and 2-3 am .B # 1am and 2-3 am
@ -177,7 +170,6 @@ Section below!
.B \ \ /dev/tws0 -d 3ware,1 -a -s L/../../7/02 .B \ \ /dev/tws0 -d 3ware,1 -a -s L/../../7/02
.\" %ENDIF OS FreeBSD .\" %ENDIF OS FreeBSD
.B # .B #
.nf
.B # Three SATA disks on a HighPoint RocketRAID controller. .B # Three SATA disks on a HighPoint RocketRAID controller.
.B # Start short self-tests daily between 1-2, 2-3, and .B # Start short self-tests daily between 1-2, 2-3, and
.B # 3-4 am. .B # 3-4 am.
@ -194,7 +186,6 @@ Section below!
.B /dev/hptrr -d hpt,1/3 -a -s S/../.././03 .B /dev/hptrr -d hpt,1/3 -a -s S/../.././03
.\" %ENDIF OS FreeBSD .\" %ENDIF OS FreeBSD
.B # .B #
.nf
.B # Two SATA disks connected to a HighPoint RocketRAID .B # Two SATA disks connected to a HighPoint RocketRAID
.B # via a pmport device. Start long self-tests Sundays .B # via a pmport device. Start long self-tests Sundays
.B # between midnight and 1am and 2-3 am. .B # between midnight and 1am and 2-3 am.
@ -209,7 +200,6 @@ Section below!
.B \ \ /dev/hptrr -d hpt,1/4/2 -a -s L/../../7/02 .B \ \ /dev/hptrr -d hpt,1/4/2 -a -s L/../../7/02
.B # .B #
.\" %ENDIF OS FreeBSD .\" %ENDIF OS FreeBSD
.nf
.B # Three SATA disks connected to an Areca .B # Three SATA disks connected to an Areca
.B # RAID controller. Start long self-tests Sundays .B # RAID controller. Start long self-tests Sundays
.B # between midnight and 3 am. .B # between midnight and 3 am.
@ -224,7 +214,6 @@ Section below!
.B \ \ /dev/arcmsr0 -d areca,3 -a -s L/../../7/02 .B \ \ /dev/arcmsr0 -d areca,3 -a -s L/../../7/02
.\" %ENDIF OS FreeBSD .\" %ENDIF OS FreeBSD
.B # .B #
.nf
.B # The following line enables monitoring of the .B # The following line enables monitoring of the
.B # ATA Error Log and the Self-Test Error Log. .B # ATA Error Log and the Self-Test Error Log.
.B # It also tracks changes in both Prefailure .B # It also tracks changes in both Prefailure
@ -241,10 +230,7 @@ Section below!
.B ################################################ .B ################################################
.fi .fi
.PP
.SH CONFIGURATION FILE DIRECTIVES .SH CONFIGURATION FILE DIRECTIVES
.PP
If a non-comment entry in the configuration file is the text string If a non-comment entry in the configuration file is the text string
.B DEVICESCAN .B DEVICESCAN
in capital letters, then in capital letters, then
@ -256,14 +242,13 @@ may optionally be followed by Directives that will apply to all
devices that are found in the scan. Please see below for additional devices that are found in the scan. Please see below for additional
details. details.
[NEW EXPERIMENTAL SMARTD FEATURE] If an entry in the configuration file If an entry in the configuration file starts with
starts with
.B DEFAULT .B DEFAULT
instead of a device name, then all directives in this entry are set instead of a device name, then all directives in this entry are set
as defaults for the next device entries. as defaults for the next device entries.
.PP
This configuration: This configuration:
.PP
.nf .nf
\ \ DEFAULT -a -R5! -W 2,40,45 -I 194 -s L/../../7/00 -m admin@example.com \ \ DEFAULT -a -R5! -W 2,40,45 -I 194 -s L/../../7/00 -m admin@example.com
\ \ /dev/sda \ \ /dev/sda
@ -273,9 +258,9 @@ This configuration:
\ \ /dev/sdd \ \ /dev/sdd
\ \ /dev/sde -d removable \ \ /dev/sde -d removable
.fi .fi
.PP
has the same effect as: has the same effect as:
.PP
.nf .nf
\ \ /dev/sda -a -R5! -W 2,40,45 -I 194 -s L/../../7/00 -m admin@example.com \ \ /dev/sda -a -R5! -W 2,40,45 -I 194 -s L/../../7/00 -m admin@example.com
\ \ /dev/sdb -a -R5! -W 2,40,45 -I 194 -s L/../../7/00 -m admin@example.com \ \ /dev/sdb -a -R5! -W 2,40,45 -I 194 -s L/../../7/00 -m admin@example.com
@ -284,7 +269,7 @@ has the same effect as:
\ \ /dev/sde -d removable -H -m admin@example.com \ \ /dev/sde -d removable -H -m admin@example.com
.fi .fi
.sp 2
The following are the Directives that may appear following the device The following are the Directives that may appear following the device
name or name or
.B DEVICESCAN .B DEVICESCAN
@ -412,6 +397,14 @@ It is possible to set RAID device name as /dev/bus/N, where N is a SCSI bus
number. number.
Please see the \fBsmartctl\fP(8) man page for further details. Please see the \fBsmartctl\fP(8) man page for further details.
.I aacraid,H,L,ID
\- [Linux only] [NEW EXPERIMENTAL SMARTD FEATURE]
the device consists of one or more SCSI/SAS disks connected to an AacRaid controller.
The non-negative integers H,L,ID (Host number, Lun, ID) denote which disk
on the controller is monitored.
In log files and email messages this disk will be identified as aacraid_disk_HH_LL_ID.
Please see the \fBsmartctl\fP(8) man page for further details.
.\" %ENDIF OS Linux .\" %ENDIF OS Linux
.\" %IF OS FreeBSD Linux .\" %IF OS FreeBSD Linux
.I 3ware,N .I 3ware,N
@ -667,7 +660,6 @@ Values of 0 disable the feature, other values less than 65 are probably
not supported. For RAID configurations, this is typically set to not supported. For RAID configurations, this is typically set to
70,70 deciseconds. 70,70 deciseconds.
[Please see the \fBsmartctl \-l scterc\fP command-line option.] [Please see the \fBsmartctl \-l scterc\fP command-line option.]
.TP .TP
.B \-e NAME[,VALUE] .B \-e NAME[,VALUE]
Sets non-SMART device settings when \fBsmartd\fP starts up and has no Sets non-SMART device settings when \fBsmartd\fP starts up and has no
@ -693,7 +685,6 @@ IDLE mode.
.I wcache,[on|off] .I wcache,[on|off]
\- [ATA only] Sets the volatile write cache feature. \- [ATA only] Sets the volatile write cache feature.
.TP .TP
.B \-s REGEXP .B \-s REGEXP
Run Self-Tests or Offline Immediate Tests, at scheduled times. A Run Self-Tests or Offline Immediate Tests, at scheduled times. A
@ -720,7 +711,6 @@ Some disks (e.g. WD) do not preserve the selective self test log accross
power cycles. If state persistence (\'\-s\' option) is enabled, the last power cycles. If state persistence (\'\-s\' option) is enabled, the last
test span is preserved by smartd and used if (and only if) the selective test span is preserved by smartd and used if (and only if) the selective
self test log is empty. self test log is empty.
.IP \fBMM\fP 4 .IP \fBMM\fP 4
is the month of the year, expressed with two decimal digits. The is the month of the year, expressed with two decimal digits. The
range is from 01 (January) to 12 (December) inclusive. Do \fBnot\fP range is from 01 (January) to 12 (December) inclusive. Do \fBnot\fP
@ -819,8 +809,8 @@ during disk standby time, the longest of these tests is run when the
disk is active again. disk is active again.
Unix users: please beware that the rules for extended regular Unix users: please beware that the rules for extended regular
expressions [regex(7)] are \fBnot\fP the same as the rules for expressions [\fBregex\fP(7)] are \fBnot\fP the same as the rules for
file-name pattern matching by the shell [glob(7)]. \fBsmartd\fP will file-name pattern matching by the shell [\fBglob\fP(7)]. \fBsmartd\fP will
issue harmless informational warning messages if it detects characters issue harmless informational warning messages if it detects characters
in \fBREGEXP\fP that appear to indicate that you have made this in \fBREGEXP\fP that appear to indicate that you have made this
mistake. mistake.
@ -848,25 +838,14 @@ Directive described below to send one test email message on
\fBsmartd\fP \fBsmartd\fP
startup. startup.
By default, email is sent using the system By default, email is sent using the system \fBmail\fP(1) command.
.B mail In order that \fBsmartd\fP find this command (normally /usr/bin/mail) the
command. In order that executable must be in the path of the shell or environment from which
\fBsmartd\fP
find the mail command (normally /bin/mail) an executable named
.B \'mail\'
must be in the path of the shell or environment from which
\fBsmartd\fP \fBsmartd\fP
was started. If you wish to specify an explicit path to the mail was started. If you wish to specify an explicit path to the mail
executable (for example /usr/local/bin/mail) or a custom script to executable (for example /usr/local/bin/mail) or a custom script to
run, please use the \'\-M exec\' Directive below. run, please use the \'\-M exec\' Directive below.
.\" %IF OS Solaris
Note that by default under Solaris, in the previous paragraph,
\'\fBmailx\fP\' and \'\fB/bin/mailx\fP\' are used, since Solaris
\'/bin/mail\' does not accept a \'\-s\' (Subject) command-line
argument.
.\" %ENDIF OS Solaris
.\" %IF OS Windows .\" %IF OS Windows
On Windows, the \'\fBBlat\fP\' mailer On Windows, the \'\fBBlat\fP\' mailer
(\fBhttp://blat.sourceforge.net/\fP) is used by default. (\fBhttp://blat.sourceforge.net/\fP) is used by default.
@ -886,6 +865,7 @@ sending mail, this should help you to understand and fix them. If
you have mail problems, we recommend running \fBsmartd\fP in debug you have mail problems, we recommend running \fBsmartd\fP in debug
mode with the \'-d\' flag, using the \'-M test\' Directive described mode with the \'-d\' flag, using the \'-M test\' Directive described
below. below.
.\" %IF ENABLE_SMARTDPLUGINDIR
.\" %IF NOT OS Windows .\" %IF NOT OS Windows
[NEW EXPERIMENTAL SMARTD FEATURE] [NEW EXPERIMENTAL SMARTD FEATURE]
@ -898,6 +878,7 @@ are run instead.
This is handled by the script /usr/local/etc/smartd_warning.sh This is handled by the script /usr/local/etc/smartd_warning.sh
(see also \'\-M exec\' below). (see also \'\-M exec\' below).
.\" %ENDIF NOT OS Windows .\" %ENDIF NOT OS Windows
.\" %ENDIF ENABLE_SMARTDPLUGINDIR
.\" %IF OS Windows .\" %IF OS Windows
[Windows only] [NEW EXPERIMENTAL SMARTD FEATURE] [Windows only] [NEW EXPERIMENTAL SMARTD FEATURE]
@ -995,7 +976,7 @@ exported by \fBsmartd\fP are:
.RS 7 .RS 7
.IP \fBSMARTD_MAILER\fP 4 .IP \fBSMARTD_MAILER\fP 4
is set to the argument of \-M exec, if present or else to \'mail\' is set to the argument of \-M exec, if present or else to \'mail\'
(examples: /bin/mail, mail). (examples: /usr/local/bin/mail, mail).
.IP \fBSMARTD_DEVICE\fP 4 .IP \fBSMARTD_DEVICE\fP 4
is set to the device path (examples: /dev/hda, /dev/sdb). is set to the device path (examples: /dev/hda, /dev/sdb).
.IP \fBSMARTD_DEVICETYPE\fP 4 .IP \fBSMARTD_DEVICETYPE\fP 4
@ -1009,7 +990,7 @@ RocketRAID controller, the form is \'/dev/sdd [hpt_1/1/1]\' under Linux
or \'/dev/hptrr [hpt_1/1/1]\' under FreeBSD. For Areca controllers, the or \'/dev/hptrr [hpt_1/1/1]\' under FreeBSD. For Areca controllers, the
form is \'/dev/sg2 [areca_disk_09]\' on Linux or \'/dev/arcmsr0 [areca_disk_09]\' on FreeBSD. In these cases the device string form is \'/dev/sg2 [areca_disk_09]\' on Linux or \'/dev/arcmsr0 [areca_disk_09]\' on FreeBSD. In these cases the device string
contains a space and is NOT quoted. So to use $SMARTD_DEVICESTRING in a contains a space and is NOT quoted. So to use $SMARTD_DEVICESTRING in a
bash script you should probably enclose it in double quotes. shell script you should probably enclose it in double quotes.
.IP \fBSMARTD_DEVICEINFO\fP 4 .IP \fBSMARTD_DEVICEINFO\fP 4
is set to device identify information. It includes most of the info printed is set to device identify information. It includes most of the info printed
by \fBsmartctl \-i\fP but uses a brief single line format. by \fBsmartctl \-i\fP but uses a brief single line format.
@ -1018,46 +999,33 @@ The string contains space characters and is NOT quoted.
.IP \fBSMARTD_FAILTYPE\fP 4 .IP \fBSMARTD_FAILTYPE\fP 4
gives the reason for the warning or message email. The possible values that gives the reason for the warning or message email. The possible values that
it takes and their meanings are: it takes and their meanings are:
.nf .br
.fi
\fIEmailTest\fP: this is an email test message. \fIEmailTest\fP: this is an email test message.
.nf .br
.fi
\fIHealth\fP: the SMART health status indicates imminent failure. \fIHealth\fP: the SMART health status indicates imminent failure.
.nf .br
.fi
\fIUsage\fP: a usage Attribute has failed. \fIUsage\fP: a usage Attribute has failed.
.nf .br
.fi
\fISelfTest\fP: the number of self-test failures has increased. \fISelfTest\fP: the number of self-test failures has increased.
.nf .br
.fi
\fIErrorCount\fP: the number of errors in the ATA error log has increased. \fIErrorCount\fP: the number of errors in the ATA error log has increased.
.nf .br
.fi
\fICurrentPendingSector\fP: one of more disk sectors could not be \fICurrentPendingSector\fP: one of more disk sectors could not be
read and are marked to be reallocated (replaced with spare sectors). read and are marked to be reallocated (replaced with spare sectors).
.nf .br
.fi
\fIOfflineUncorrectableSector\fP: during off-line testing, or self-testing, \fIOfflineUncorrectableSector\fP: during off-line testing, or self-testing,
one or more disk sectors could not be read. one or more disk sectors could not be read.
.nf .br
.fi
\fITemperature\fP: Temperature reached critical limit (see \-W directive). \fITemperature\fP: Temperature reached critical limit (see \-W directive).
.nf .br
.fi
\fIFailedHealthCheck\fP: the SMART health status command failed. \fIFailedHealthCheck\fP: the SMART health status command failed.
.nf .br
.fi
\fIFailedReadSmartData\fP: the command to read SMART Attribute data failed. \fIFailedReadSmartData\fP: the command to read SMART Attribute data failed.
.nf .br
.fi
\fIFailedReadSmartErrorLog\fP: the command to read the SMART error log failed. \fIFailedReadSmartErrorLog\fP: the command to read the SMART error log failed.
.nf .br
.fi
\fIFailedReadSmartSelfTestLog\fP: the command to read the SMART self-test log failed. \fIFailedReadSmartSelfTestLog\fP: the command to read the SMART self-test log failed.
.nf .br
.fi
\fIFailedOpenDevice\fP: the open() command to the device failed. \fIFailedOpenDevice\fP: the open() command to the device failed.
.IP \fBSMARTD_ADDRESS\fP 4 .IP \fBSMARTD_ADDRESS\fP 4
is determined by the address argument ADD of the \'\-m\' Directive. is determined by the address argument ADD of the \'\-m\' Directive.
@ -1066,7 +1034,7 @@ Otherwise, it is set to the comma-separated-list of email addresses
given by the argument ADD, with the commas replaced by spaces given by the argument ADD, with the commas replaced by spaces
(example:admin@example.com root). If more than one email address is (example:admin@example.com root). If more than one email address is
given, then this string will contain space characters and is NOT given, then this string will contain space characters and is NOT
quoted, so to use it in a bash script you may want to enclose it in quoted, so to use it in a shell script you may want to enclose it in
double quotes. double quotes.
.\" %IF OS Windows .\" %IF OS Windows
.IP \fBSMARTD_ADDRCSV\fP 4 .IP \fBSMARTD_ADDRCSV\fP 4
@ -1077,14 +1045,14 @@ SMARTD_ADDRESS.
is set to the one sentence summary warning email message string from is set to the one sentence summary warning email message string from
\fBsmartd\fP. \fBsmartd\fP.
This message string contains space characters and is NOT quoted. So to This message string contains space characters and is NOT quoted. So to
use $SMARTD_MESSAGE in a bash script you should probably enclose it in use $SMARTD_MESSAGE in a shell script you should probably enclose it in
double quotes. double quotes.
.\" %IF NOT OS Windows .\" %IF NOT OS Windows
.IP \fBSMARTD_FULLMESSAGE\fP 4 .IP \fBSMARTD_FULLMESSAGE\fP 4
is set to the contents of the entire email warning message string from is set to the contents of the entire email warning message string from
\fBsmartd\fP. \fBsmartd\fP.
This message string contains space and return characters and is NOT quoted. So to This message string contains space and return characters and is NOT quoted. So to
use $SMARTD_FULLMESSAGE in a bash script you should probably enclose it in use $SMARTD_FULLMESSAGE in a shell script you should probably enclose it in
double quotes. double quotes.
.\" %ENDIF NOT OS Windows .\" %ENDIF NOT OS Windows
.\" %IF OS Windows .\" %IF OS Windows
@ -1098,8 +1066,7 @@ the mailer or command exits.
is a text string giving the time and date at which the first problem is a text string giving the time and date at which the first problem
of this type was reported. This text string contains space characters of this type was reported. This text string contains space characters
and no newlines, and is NOT quoted. For example: and no newlines, and is NOT quoted. For example:
.nf .br
.fi
Sun Feb 9 14:58:19 2003 CST Sun Feb 9 14:58:19 2003 CST
.IP \fBSMARTD_TFIRSTEPOCH\fP 4 .IP \fBSMARTD_TFIRSTEPOCH\fP 4
is an integer, which is the unix epoch (number of seconds since Jan 1, is an integer, which is the unix epoch (number of seconds since Jan 1,
@ -1128,9 +1095,9 @@ command-line arguments:
.fi .fi
that would normally be provided to \'mail\'. Examples include: that would normally be provided to \'mail\'. Examples include:
.nf .nf
.B -m user@home -M exec /bin/mail .B -m user@home -M exec /usr/bin/mail
.B -m admin@work -M exec /usr/local/bin/mailto .B -m admin@work -M exec /usr/local/bin/mailto
.B -m root -M exec /Example_1/bash/script/below .B -m root -M exec /Example_1/shell/script/below
.fi .fi
.\" %IF OS Windows .\" %IF OS Windows
@ -1149,7 +1116,7 @@ STDIN and
.B no .B no
command-line arguments, for example: command-line arguments, for example:
.nf .nf
.B -m <nomailer> -M exec /Example_2/bash/script/below .B -m <nomailer> -M exec /Example_2/shell/script/below
.fi .fi
If the executable produces any STDERR/STDOUT output, then \fBsmartd\fP If the executable produces any STDERR/STDOUT output, then \fBsmartd\fP
assumes that something is going wrong, and a snippet of that output assumes that something is going wrong, and a snippet of that output
@ -1186,7 +1153,6 @@ SMARTD_SUBJECT and SMARTD_FULLMESSAGE
.\"! SMARTD_SUBJECT, SMARTD_FULLMSGFILE and SMARTD_ADDRCSV .\"! SMARTD_SUBJECT, SMARTD_FULLMSGFILE and SMARTD_ADDRCSV
.\" %ENDIF OS Windows .\" %ENDIF OS Windows
are set by the script before running the executable. are set by the script before running the executable.
.TP .TP
.B \-f .B \-f
[ATA only] Check for \'failure\' of any Usage Attributes. If these [ATA only] Check for \'failure\' of any Usage Attributes. If these
@ -1382,7 +1348,7 @@ multiple times. The valid arguments are:
.I none .I none
\- Assume that the device firmware obeys the ATA specifications. This \- Assume that the device firmware obeys the ATA specifications. This
is the default, unless the device has presets for \'\-F\' in the is the default, unless the device has presets for \'\-F\' in the
drive database. Using this directive will over-ride any preset values. drive database. Using this directive will override any preset values.
.I nologdir .I nologdir
\- Suppresses read attempts of SMART or GP Log Directory. \- Suppresses read attempts of SMART or GP Log Directory.
@ -1430,7 +1396,7 @@ if no other \'-C\' directive is specified.
.I 198,increasing .I 198,increasing
\- Raw Attribute number 198 (Offline Uncorrectable Sector Count) is not \- Raw Attribute number 198 (Offline Uncorrectable Sector Count) is not
reset if uncorrectable sector are reallocated. This sets \'-U 198+\' reset if uncorrectable sectors are reallocated. This sets \'-U 198+\'
if no other \'-U\' directive is specified. if no other \'-U\' directive is specified.
.TP .TP
.B \-P TYPE .B \-P TYPE
@ -1555,7 +1521,7 @@ to the output of the smartd email warning message and sends it to ADDRESS.
.nf .nf
\fB \fB
#! /bin/bash #! /bin/sh
# Save the email message (STDIN) to a file: # Save the email message (STDIN) to a file:
cat > /root/msg cat > /root/msg
@ -1564,7 +1530,7 @@ cat > /root/msg
/usr/local/sbin/smartctl -a -d $SMART_DEVICETYPE $SMARTD_DEVICE >> /root/msg /usr/local/sbin/smartctl -a -d $SMART_DEVICETYPE $SMARTD_DEVICE >> /root/msg
# Now email the message to the user at address ADD: # Now email the message to the user at address ADD:
/bin/mail -s "$SMARTD_SUBJECT" $SMARTD_ADDRESS < /root/msg /usr/bin/mail -s "$SMARTD_SUBJECT" $SMARTD_ADDRESS < /root/msg
\fP \fP
.fi .fi
@ -1574,16 +1540,18 @@ then powers down the machine.
.nf .nf
\fB \fB
#! /bin/bash #! /bin/sh
# Warn all users of a problem # Warn all users of a problem
wall \'Problem detected with disk: \' "$SMARTD_DEVICESTRING" wall <<EOF
wall \'Warning message from smartd is: \' "$SMARTD_MESSAGE" Problem detected with disk: $SMARTD_DEVICESTRING
wall \'Shutting down machine in 30 seconds... \' Warning message from smartd is: $SMARTD_MESSAGE
Shutting down machine in 30 seconds...
EOF
# Wait half a minute # Wait half a minute
sleep 30 sleep 30
# Power down the machine # Power down the machine
/sbin/shutdown -hf now /sbin/shutdown -hf now
\fP \fP
@ -1602,58 +1570,16 @@ this is interpreted as indicating that there was an internal error
within the script, and a snippet of STDOUT/STDERR is logged to SYSLOG. within the script, and a snippet of STDOUT/STDERR is logged to SYSLOG.
The remainder is flushed. The remainder is flushed.
.PP .\" %IF NOT OS Windows
.SH AUTHORS .SH FILES
\fBBruce Allen\fP .TP
.br .B /usr/local/etc/smartd.conf
University of Wisconsin \- Milwaukee Physics Department full path of this file.
.br
\fBChristian Franke\fP (Windows interface, C++ redesign, most enhancements
since 2009)
.br
\fBsmartmontools\-support@lists.sourceforge.net\fP
.PP .\" %ENDIF NOT OS Windows
.SH CONTRIBUTORS .SH SEE ALSO
The following have made large contributions to smartmontools: \fBsmartd\fP(8), \fBsmartctl\fP(8),
.nf \fBmail\fP(1), \fBregex\fP(7).
\fBCasper Dik\fP (Solaris SCSI interface)
\fBDouglas Gilbert\fP (SCSI subsystem)
\fBGuido Guenther\fP (Autoconf/Automake packaging)
\fBGeoffrey Keating\fP (Darwin ATA interface)
\fBEduard Martinescu\fP (FreeBSD interface)
\fBFr\['e]d\['e]ric L. W. Meunier\fP (Web site and Mailing list)
\fBGabriele Pohl\fP (Web site and Wiki, conversion from CVS to SVN)
\fBKeiji Sawada\fP (Solaris ATA interface)
\fBManfred Schwarb\fP (Drive database)
\fBSergey Svishchev\fP (NetBSD interface)
\fBDavid Snyder and Sergey Svishchev\fP (OpenBSD interface)
\fBPhil Williams\fP (User interface and drive database)
\fBShengfeng Zhou\fP (Linux/FreeBSD HighPoint RocketRAID interface)
.fi
Many other individuals have made smaller contributions and corrections.
.PP .SH SVN ID OF THIS PAGE
.SH CREDITS $Id: smartd.conf.5.in 3965 2014-07-20 14:46:41Z chrfranke $
.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
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
Cruz. \fBhttp://ssrc.soe.ucsc.edu/\fP .
.SH
HOME PAGE FOR SMARTMONTOOLS:
.fi
Please see the following web site for updates, further documentation, bug
reports and patches: \fBhttp://smartmontools.sourceforge.net/\fP
.SH
SEE ALSO:
\fBsmartd\fP(8), \fBsmartctl\fP(8), \fBsyslogd\fP(8),
\fBsyslog.conf\fP(5), \fBbadblocks\fP(8), \fBide\-smart\fP(8), \fBregex\fP(7).
.SH
SVN ID OF THIS PAGE:
$Id: smartd.conf.5.in 3833 2013-07-20 15:00:04Z chrfranke $

View File

@ -4,7 +4,7 @@
* Copyright (C) 2002-11 Bruce Allen <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2002-11 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2000 Michael Cornwell <cornwell@acm.org> * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
* Copyright (C) 2008 Oliver Bock <brevilo@users.sourceforge.net> * Copyright (C) 2008 Oliver Bock <brevilo@users.sourceforge.net>
* Copyright (C) 2008-13 Christian Franke <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2008-14 Christian Franke <smartmontools-support@lists.sourceforge.net>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -106,7 +106,7 @@ typedef int pid_t;
extern "C" int getdomainname(char *, int); // no declaration in header files! extern "C" int getdomainname(char *, int); // no declaration in header files!
#endif #endif
const char * smartd_cpp_cvsid = "$Id: smartd.cpp 3802 2013-03-24 18:36:21Z chrfranke $" const char * smartd_cpp_cvsid = "$Id: smartd.cpp 3948 2014-07-13 16:53:30Z chrfranke $"
CONFIG_H_CVSID; CONFIG_H_CVSID;
// smartd exit codes // smartd exit codes
@ -676,13 +676,13 @@ static bool read_dev_state(const char * path, persistent_dev_state & state)
static void write_dev_state_line(FILE * f, const char * name, uint64_t val) static void write_dev_state_line(FILE * f, const char * name, uint64_t val)
{ {
if (val) if (val)
fprintf(f, "%s = %"PRIu64"\n", name, val); fprintf(f, "%s = %" PRIu64 "\n", name, val);
} }
static void write_dev_state_line(FILE * f, const char * name1, int id, const char * name2, uint64_t val) static void write_dev_state_line(FILE * f, const char * name1, int id, const char * name2, uint64_t val)
{ {
if (val) if (val)
fprintf(f, "%s.%d.%s = %"PRIu64"\n", name1, id, name2, val); fprintf(f, "%s.%d.%s = %" PRIu64 "\n", name1, id, name2, val);
} }
// Write a state file // Write a state file
@ -757,7 +757,7 @@ static bool write_dev_attrlog(const char * path, const dev_state & state)
const persistent_dev_state::ata_attribute & pa = state.ata_attributes[i]; const persistent_dev_state::ata_attribute & pa = state.ata_attributes[i];
if (!pa.id) if (!pa.id)
continue; continue;
fprintf(f, "\t%d;%d;%"PRIu64";", pa.id, pa.val, pa.raw); fprintf(f, "\t%d;%d;%" PRIu64 ";", pa.id, pa.val, pa.raw);
} }
// SCSI ONLY // SCSI ONLY
const struct scsiErrorCounter * ecp; const struct scsiErrorCounter * ecp;
@ -765,13 +765,13 @@ static bool write_dev_attrlog(const char * path, const dev_state & state)
for (int k = 0; k < 3; ++k) { for (int k = 0; k < 3; ++k) {
if ( !state.scsi_error_counters[k].found ) continue; if ( !state.scsi_error_counters[k].found ) continue;
ecp = &state.scsi_error_counters[k].errCounter; ecp = &state.scsi_error_counters[k].errCounter;
fprintf(f, "\t%s-corr-by-ecc-fast;%"PRIu64";" fprintf(f, "\t%s-corr-by-ecc-fast;%" PRIu64 ";"
"\t%s-corr-by-ecc-delayed;%"PRIu64";" "\t%s-corr-by-ecc-delayed;%" PRIu64 ";"
"\t%s-corr-by-retry;%"PRIu64";" "\t%s-corr-by-retry;%" PRIu64 ";"
"\t%s-total-err-corrected;%"PRIu64";" "\t%s-total-err-corrected;%" PRIu64 ";"
"\t%s-corr-algorithm-invocations;%"PRIu64";" "\t%s-corr-algorithm-invocations;%" PRIu64 ";"
"\t%s-gb-processed;%.3f;" "\t%s-gb-processed;%.3f;"
"\t%s-total-unc-errors;%"PRIu64";", "\t%s-total-unc-errors;%" PRIu64 ";",
pageNames[k], ecp->counter[0], pageNames[k], ecp->counter[0],
pageNames[k], ecp->counter[1], pageNames[k], ecp->counter[1],
pageNames[k], ecp->counter[2], pageNames[k], ecp->counter[2],
@ -781,7 +781,7 @@ static bool write_dev_attrlog(const char * path, const dev_state & state)
pageNames[k], ecp->counter[6]); pageNames[k], ecp->counter[6]);
} }
if(state.scsi_nonmedium_error.found && state.scsi_nonmedium_error.nme.gotPC0) { if(state.scsi_nonmedium_error.found && state.scsi_nonmedium_error.nme.gotPC0) {
fprintf(f, "\tnon-medium-errors;%"PRIu64";", state.scsi_nonmedium_error.nme.counterPC0); fprintf(f, "\tnon-medium-errors;%" PRIu64 ";", state.scsi_nonmedium_error.nme.counterPC0);
} }
// write SCSI current temperature if it is monitored // write SCSI current temperature if it is monitored
if(state.TempPageSupported && state.temperature) if(state.TempPageSupported && state.temperature)
@ -1491,7 +1491,7 @@ static void Usage()
PrintOut(LOG_INFO," -A PREFIX, --attributelog=PREFIX\n"); PrintOut(LOG_INFO," -A PREFIX, --attributelog=PREFIX\n");
PrintOut(LOG_INFO," Log ATA attribute information to {PREFIX}MODEL-SERIAL.ata.csv\n"); PrintOut(LOG_INFO," Log ATA attribute information to {PREFIX}MODEL-SERIAL.ata.csv\n");
#ifdef SMARTMONTOOLS_ATTRIBUTELOG #ifdef SMARTMONTOOLS_ATTRIBUTELOG
PrintOut(LOG_INFO," [default is "SMARTMONTOOLS_ATTRIBUTELOG"MODEL-SERIAL.ata.csv]\n"); PrintOut(LOG_INFO," [default is " SMARTMONTOOLS_ATTRIBUTELOG "MODEL-SERIAL.ata.csv]\n");
#endif #endif
PrintOut(LOG_INFO,"\n"); PrintOut(LOG_INFO,"\n");
PrintOut(LOG_INFO," -B [+]FILE, --drivedb=[+]FILE\n"); PrintOut(LOG_INFO," -B [+]FILE, --drivedb=[+]FILE\n");
@ -1537,13 +1537,13 @@ static void Usage()
PrintOut(LOG_INFO," -s PREFIX, --savestates=PREFIX\n"); PrintOut(LOG_INFO," -s PREFIX, --savestates=PREFIX\n");
PrintOut(LOG_INFO," Save disk states to {PREFIX}MODEL-SERIAL.TYPE.state\n"); PrintOut(LOG_INFO," Save disk states to {PREFIX}MODEL-SERIAL.TYPE.state\n");
#ifdef SMARTMONTOOLS_SAVESTATES #ifdef SMARTMONTOOLS_SAVESTATES
PrintOut(LOG_INFO," [default is "SMARTMONTOOLS_SAVESTATES"MODEL-SERIAL.TYPE.state]\n"); PrintOut(LOG_INFO," [default is " SMARTMONTOOLS_SAVESTATES "MODEL-SERIAL.TYPE.state]\n");
#endif #endif
PrintOut(LOG_INFO,"\n"); PrintOut(LOG_INFO,"\n");
PrintOut(LOG_INFO," -w NAME, --warnexec=NAME\n"); PrintOut(LOG_INFO," -w NAME, --warnexec=NAME\n");
PrintOut(LOG_INFO," Run executable NAME on warnings\n"); PrintOut(LOG_INFO," Run executable NAME on warnings\n");
#ifndef _WIN32 #ifndef _WIN32
PrintOut(LOG_INFO," [default is "SMARTMONTOOLS_SYSCONFDIR"/smartd_warning.sh]\n\n"); PrintOut(LOG_INFO," [default is " SMARTMONTOOLS_SMARTDSCRIPTDIR "/smartd_warning.sh]\n\n");
#else #else
PrintOut(LOG_INFO," [default is %s/smartd_warning.cmd]\n\n", get_exe_dir().c_str()); PrintOut(LOG_INFO," [default is %s/smartd_warning.cmd]\n\n", get_exe_dir().c_str());
#endif #endif
@ -1698,7 +1698,7 @@ static bool check_pending_id(const dev_config & cfg, const dev_state & state,
uint64_t rawval = ata_get_attr_raw_value(state.smartval.vendor_attributes[i], uint64_t rawval = ata_get_attr_raw_value(state.smartval.vendor_attributes[i],
cfg.attribute_defs); cfg.attribute_defs);
if (rawval >= (state.num_sectors ? state.num_sectors : 0xffffffffULL)) { if (rawval >= (state.num_sectors ? state.num_sectors : 0xffffffffULL)) {
PrintOut(LOG_INFO, "Device: %s, ignoring %s count - bogus Attribute %d value %"PRIu64" (0x%"PRIx64")\n", PrintOut(LOG_INFO, "Device: %s, ignoring %s count - bogus Attribute %d value %" PRIu64 " (0x%" PRIx64 ")\n",
cfg.name.c_str(), msg, id, rawval, rawval); cfg.name.c_str(), msg, id, rawval, rawval);
return false; return false;
} }
@ -1781,7 +1781,7 @@ static int ATADeviceScan(dev_config & cfg, dev_state & state, ata_device * atade
unsigned oui = 0; uint64_t unique_id = 0; unsigned oui = 0; uint64_t unique_id = 0;
int naa = ata_get_wwn(&drive, oui, unique_id); int naa = ata_get_wwn(&drive, oui, unique_id);
if (naa >= 0) if (naa >= 0)
snprintf(wwn, sizeof(wwn), "WWN:%x-%06x-%09"PRIx64", ", naa, oui, unique_id); snprintf(wwn, sizeof(wwn), "WWN:%x-%06x-%09" PRIx64 ", ", naa, oui, unique_id);
// Format device id string for warning emails // Format device id string for warning emails
char cap[32]; char cap[32];
@ -2749,7 +2749,7 @@ static int DoATASelfTest(const dev_config & cfg, dev_state & state, ata_device *
return 1; return 1;
} }
uint64_t start = selargs.span[0].start, end = selargs.span[0].end; uint64_t start = selargs.span[0].start, end = selargs.span[0].end;
PrintOut(LOG_INFO, "Device: %s, %s test span at LBA %"PRIu64" - %"PRIu64" (%"PRIu64" sectors, %u%% - %u%% of disk).\n", PrintOut(LOG_INFO, "Device: %s, %s test span at LBA %" PRIu64 " - %" PRIu64 " (%" PRIu64 " sectors, %u%% - %u%% of disk).\n",
name, (selargs.span[0].mode == SEL_NEXT ? "next" : "redo"), name, (selargs.span[0].mode == SEL_NEXT ? "next" : "redo"),
start, end, end - start + 1, start, end, end - start + 1,
(unsigned)((100 * start + state.num_sectors/2) / state.num_sectors), (unsigned)((100 * start + state.num_sectors/2) / state.num_sectors),
@ -2800,9 +2800,9 @@ static void check_pending(const dev_config & cfg, dev_state & state,
return; return;
// Format message. // Format message.
std::string s = strprintf("Device: %s, %"PRId64" %s", cfg.name.c_str(), rawval, msg); std::string s = strprintf("Device: %s, %" PRId64 " %s", cfg.name.c_str(), rawval, msg);
if (prev_rawval > 0 && rawval != prev_rawval) if (prev_rawval > 0 && rawval != prev_rawval)
s += strprintf(" (changed %+"PRId64")", rawval - prev_rawval); s += strprintf(" (changed %+" PRId64 ")", rawval - prev_rawval);
PrintOut(LOG_CRIT, "%s\n", s.c_str()); PrintOut(LOG_CRIT, "%s\n", s.c_str());
MailWarning(cfg, state, mailtype, "%s", s.c_str()); MailWarning(cfg, state, mailtype, "%s", s.c_str());
@ -4254,10 +4254,10 @@ static int ParseConfigFile(dev_config_vector & conf_entries)
// No configuration file found -- use fake one // No configuration file found -- use fake one
int entry = 0; int entry = 0;
if (!f) { if (!f) {
char fakeconfig[] = SCANDIRECTIVE" -a"; // TODO: Remove this hack, build cfg_entry. char fakeconfig[] = SCANDIRECTIVE " -a"; // TODO: Remove this hack, build cfg_entry.
if (ParseConfigLine(conf_entries, default_conf, 0, fakeconfig) != -1) if (ParseConfigLine(conf_entries, default_conf, 0, fakeconfig) != -1)
throw std::logic_error("Internal error parsing "SCANDIRECTIVE); throw std::logic_error("Internal error parsing " SCANDIRECTIVE);
return 0; return 0;
} }
@ -4395,8 +4395,8 @@ static void ParseOpts(int argc, char **argv)
{ {
// Init default path names // Init default path names
#ifndef _WIN32 #ifndef _WIN32
configfile = SMARTMONTOOLS_SYSCONFDIR"/smartd.conf"; configfile = SMARTMONTOOLS_SYSCONFDIR "/smartd.conf";
warning_script = SMARTMONTOOLS_SYSCONFDIR"/smartd_warning.sh"; warning_script = SMARTMONTOOLS_SMARTDSCRIPTDIR "/smartd_warning.sh";
#else #else
std::string exedir = get_exe_dir(); std::string exedir = get_exe_dir();
static std::string configfile_str = exedir + "/smartd.conf"; static std::string configfile_str = exedir + "/smartd.conf";
@ -5028,7 +5028,7 @@ static int main_worker(int argc, char **argv)
PrintOut(LOG_INFO, PrintOut(LOG_INFO,
caughtsigHUP==1? caughtsigHUP==1?
"Signal HUP - rereading configuration file %s\n": "Signal HUP - rereading configuration file %s\n":
"\a\nSignal INT - rereading configuration file %s ("SIGQUIT_KEYNAME" quits)\n\n", "\a\nSignal INT - rereading configuration file %s (" SIGQUIT_KEYNAME " quits)\n\n",
configfile); configfile);
} }
@ -5178,9 +5178,9 @@ int main(int argc, char **argv){
"smartd", "SmartD Service", // servicename, displayname "smartd", "SmartD Service", // servicename, displayname
// description // description
"Controls and monitors storage devices using the Self-Monitoring, " "Controls and monitors storage devices using the Self-Monitoring, "
"Analysis and Reporting Technology System (S.M.A.R.T.) " "Analysis and Reporting Technology System (SMART) built into "
"built into ATA and SCSI Hard Drives. " "ATA/SATA and SCSI/SAS hard drives and solid-state drives. "
PACKAGE_HOMEPAGE "www.smartmontools.org"
}; };
// daemon_main() handles daemon and service specific commands // daemon_main() handles daemon and service specific commands
// and starts smartd_main() direct, from a new process, // and starts smartd_main() direct, from a new process,

View File

@ -1,5 +1,6 @@
[Unit] [Unit]
Description=Self Monitoring and Reporting Technology (SMART) Daemon Description=Self Monitoring and Reporting Technology (SMART) Daemon
Documentation=man:smartd(8) man:smartd.conf(5)
After=syslog.target After=syslog.target
[Service] [Service]

View File

@ -2,7 +2,7 @@
# #
# smartd warning script # smartd warning script
# #
# Copyright (C) 2012-13 Christian Franke <smartmontools-support@lists.sourceforge.net> # Copyright (C) 2012-14 Christian Franke <smartmontools-support@lists.sourceforge.net>
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
@ -12,7 +12,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# (for example COPYING); If not, see <http://www.gnu.org/licenses/>. # (for example COPYING); If not, see <http://www.gnu.org/licenses/>.
# #
# $Id: smartd_warning.sh.in 3809 2013-04-18 19:41:40Z chrfranke $ # $Id: smartd_warning.sh.in 3932 2014-06-29 19:02:38Z chrfranke $
# #
set -e set -e
@ -22,12 +22,13 @@ PACKAGE="@PACKAGE@"
VERSION="@VERSION@" VERSION="@VERSION@"
prefix="@prefix@" prefix="@prefix@"
sysconfdir="@sysconfdir@" sysconfdir="@sysconfdir@"
smartdscriptdir="@smartdscriptdir@"
# Default mailer # Default mailer
os_mailer="@os_mailer@" os_mailer="@os_mailer@"
# Plugin directory # Plugin directory (disabled if empty)
plugindir="$sysconfdir/smartd_warning.d" plugindir="@smartdplugindir@"
# Parse options # Parse options
dryrun= dryrun=
@ -127,7 +128,8 @@ export SMARTD_FULLMESSAGE="$fullmessage
" "
# Run plugin scripts if requested # Run plugin scripts if requested
case " $SMARTD_ADDRESS" in if test -n "$plugindir"; then
case " $SMARTD_ADDRESS" in
*\ @*) *\ @*)
if [ -n "$dryrun" ]; then if [ -n "$dryrun" ]; then
echo "export SMARTD_SUBJECT='$SMARTD_SUBJECT'" echo "export SMARTD_SUBJECT='$SMARTD_SUBJECT'"
@ -177,7 +179,8 @@ case " $SMARTD_ADDRESS" in
# Send email to remaining addresses # Send email to remaining addresses
test -n "$SMARTD_ADDRESS" || exit 0 test -n "$SMARTD_ADDRESS" || exit 0
;; ;;
esac esac
fi
# Send mail or run command # Send mail or run command
if [ -n "$SMARTD_ADDRESS" ]; then if [ -n "$SMARTD_ADDRESS" ]; then

104
update-smart-drivedb.8.in Normal file
View File

@ -0,0 +1,104 @@
.ig
Copyright (C) 2013 Hannes von Haugwitz <hannes@vonhaugwitz.com>
Copyright (C) 2014 Christian Franke <smartmontools-support@lists.sourceforge.net>
$Id: update-smart-drivedb.8.in 3961 2014-07-19 16:44:10Z 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 Software Foundation; either version 2, or (at your option)
any later version.
You should have received a copy of the GNU General Public License
(for example COPYING); If not, see <http://www.gnu.org/licenses/>.
..
.TH UPDATE-SMART-DRIVEDB 8 CURRENT_SVN_DATE CURRENT_SVN_VERSION CURRENT_SVN_DATE
.SH NAME
update-smart-drivedb \- update smartmontools drive database
.SH "SYNOPSIS"
.B update-smart-drivedb
.RB [ -v ]
.RI [ DESTFILE ]
.SH PACKAGE VERSION
CURRENT_SVN_VERSION CURRENT_SVN_DATE CURRENT_SVN_REV
.SH "DESCRIPTION"
.B update-smart-drivedb
updates
.B /usr/local/share/smartmontools/drivedb.h
or
.I DESTFILE
from smartmontools SVN repository.
It tries to download first from the current branch and then from
trunk. The tools used for downloading are either
.BR curl (1),
.BR wget "(1) or"
.BR lynx (1).
.\" %IF OS FreeBSD
On FreeBSD,
.BR fetch (1)
is used as a fallback.
.\" %ENDIF OS FreeBSD
.\" %IF OS OpenBSD
On OpenBSD,
.BR ftp (1)
is used as a fallback.
.\" %ENDIF OS OpenBSD
The old file is kept if the downloaded file is identical (ignoring
the differences in Id string) otherwise it is moved to
.BR drivedb.h.old .
.SH "OPTIONS"
.TP
\-v
verbose output
.SH "EXAMPLES"
.nf
# update-smart-drivedb
/usr/local/share/smartmontools/drivedb.h updated from branches/RELEASE_6_0_DRIVEDB
.fi
.SH "EXIT STATUS"
The exit status is 0 if the database has been successfully
updated. If an error occurs the exit status is 1.
.SH FILES
.TP
.B /usr/local/sbin/update-smart-drivedb
full path of this script.
.TP
.B /usr/local/sbin/smartctl
used to check syntax of new drive database.
.TP
.B /usr/local/share/smartmontools/drivedb.h
current drive database.
.TP
.B /usr/local/share/smartmontools/drivedb.h.old
previous drive database.
.TP
.B /usr/local/share/smartmontools/drivedb.h.error
new drive database rejected due to syntax errors.
.TP
.B /usr/local/share/smartmontools/drivedb.h.lastcheck
empty file created if downloaded file was identical.
.SH "SEE ALSO"
.BR smartctl (8),
.BR smartd (8).
.SH AUTHORS
\fBChristian Franke\fP
.br
\fBsmartmontools\-support@lists.sourceforge.net\fP
.br
This manual page was originally written by
.BR "Hannes von Haugwitz <hannes@vonhaugwitz.com>" .
.SH SVN ID OF THIS PAGE
$Id: update-smart-drivedb.8.in 3961 2014-07-19 16:44:10Z chrfranke $

View File

@ -4,7 +4,7 @@
* Home page of code is: http://smartmontools.sourceforge.net * Home page of code is: http://smartmontools.sourceforge.net
* *
* Copyright (C) 2002-12 Bruce Allen <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2002-12 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2008-13 Christian Franke <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2008-14 Christian Franke <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2000 Michael Cornwell <cornwell@acm.org> * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -52,7 +52,7 @@
#include "atacmds.h" #include "atacmds.h"
#include "dev_interface.h" #include "dev_interface.h"
const char * utility_cpp_cvsid = "$Id: utility.cpp 3838 2013-07-21 16:32:27Z chrfranke $" const char * utility_cpp_cvsid = "$Id: utility.cpp 3937 2014-07-05 17:51:21Z chrfranke $"
UTILITY_H_CVSID INT64_H_CVSID; UTILITY_H_CVSID INT64_H_CVSID;
const char * packet_types[] = { const char * packet_types[] = {
@ -83,14 +83,14 @@ const char * packet_types[] = {
std::string format_version_info(const char * prog_name, bool full /*= false*/) std::string format_version_info(const char * prog_name, bool full /*= false*/)
{ {
std::string info = strprintf( std::string info = strprintf(
"%s "PACKAGE_VERSION" " "%s " PACKAGE_VERSION " "
#ifdef SMARTMONTOOLS_SVN_REV #ifdef SMARTMONTOOLS_SVN_REV
SMARTMONTOOLS_SVN_DATE" r"SMARTMONTOOLS_SVN_REV SMARTMONTOOLS_SVN_DATE " r" SMARTMONTOOLS_SVN_REV
#else #else
"(build date "__DATE__")" // checkout without expansion of Id keywords "(build date " __DATE__ ")" // checkout without expansion of Id keywords
#endif #endif
" [%s] "BUILD_INFO"\n" " [%s] " BUILD_INFO "\n"
"Copyright (C) 2002-13, Bruce Allen, Christian Franke, www.smartmontools.org\n", "Copyright (C) 2002-14, Bruce Allen, Christian Franke, www.smartmontools.org\n",
prog_name, smi()->get_os_version_str().c_str() prog_name, smi()->get_os_version_str().c_str()
); );
if (!full) if (!full)
@ -106,21 +106,21 @@ std::string format_version_info(const char * prog_name, bool full /*= false*/)
"\n", "\n",
prog_name prog_name
); );
info += strprintf( info +=
"smartmontools release "PACKAGE_VERSION "smartmontools release " PACKAGE_VERSION
" dated "SMARTMONTOOLS_RELEASE_DATE" at "SMARTMONTOOLS_RELEASE_TIME"\n" " dated " SMARTMONTOOLS_RELEASE_DATE " at " SMARTMONTOOLS_RELEASE_TIME "\n"
#ifdef SMARTMONTOOLS_SVN_REV #ifdef SMARTMONTOOLS_SVN_REV
"smartmontools SVN rev "SMARTMONTOOLS_SVN_REV "smartmontools SVN rev " SMARTMONTOOLS_SVN_REV
" dated "SMARTMONTOOLS_SVN_DATE" at "SMARTMONTOOLS_SVN_TIME"\n" " dated " SMARTMONTOOLS_SVN_DATE " at " SMARTMONTOOLS_SVN_TIME "\n"
#else #else
"smartmontools SVN rev is unknown\n" "smartmontools SVN rev is unknown\n"
#endif #endif
"smartmontools build host: "SMARTMONTOOLS_BUILD_HOST"\n" "smartmontools build host: " SMARTMONTOOLS_BUILD_HOST "\n"
"smartmontools build configured: "SMARTMONTOOLS_CONFIGURE_DATE "\n" #if defined(__GNUC__) && defined(__VERSION__) // works also with CLang
"%s compile dated "__DATE__" at "__TIME__"\n" "smartmontools build with: GCC " __VERSION__ "\n"
"smartmontools configure arguments: ", #endif
prog_name "smartmontools configure arguments: "
); ;
info += (sizeof(SMARTMONTOOLS_CONFIGURE_ARGS) > 1 ? info += (sizeof(SMARTMONTOOLS_CONFIGURE_ARGS) > 1 ?
SMARTMONTOOLS_CONFIGURE_ARGS : "[no arguments given]"); SMARTMONTOOLS_CONFIGURE_ARGS : "[no arguments given]");
info += '\n'; info += '\n';
@ -265,7 +265,7 @@ const char *packetdevicetype(int type){
} }
// Runtime check of byte ordering, throws if different from isbigendian(). // Runtime check of byte ordering, throws if different from isbigendian().
void check_endianness() static void check_endianness()
{ {
union { union {
// Force compile error if int type is not 32bit. // Force compile error if int type is not 32bit.
@ -735,7 +735,7 @@ const char * format_with_thousands_sep(char * str, int strsize, uint64_t val,
} }
char num[64]; char num[64];
snprintf(num, sizeof(num), "%"PRIu64, val); snprintf(num, sizeof(num), "%" PRIu64, val);
int numlen = strlen(num); int numlen = strlen(num);
int i = 0, j = 0; int i = 0, j = 0;
@ -783,12 +783,12 @@ const char * format_capacity(char * str, int strsize, uint64_t val,
if (i == 0) if (i == 0)
snprintf(str, strsize, "%u B", (unsigned)n); snprintf(str, strsize, "%u B", (unsigned)n);
else if (n >= 100) // "123 xB" else if (n >= 100) // "123 xB"
snprintf(str, strsize, "%"PRIu64" %cB", n, prefixes[i]); snprintf(str, strsize, "%" PRIu64 " %cB", n, prefixes[i]);
else if (n >= 10) // "12.3 xB" else if (n >= 10) // "12.3 xB"
snprintf(str, strsize, "%"PRIu64"%s%u %cB", n, decimal_point, snprintf(str, strsize, "%" PRIu64 "%s%u %cB", n, decimal_point,
(unsigned)(((val % d) * 10) / d), prefixes[i]); (unsigned)(((val % d) * 10) / d), prefixes[i]);
else // "1.23 xB" else // "1.23 xB"
snprintf(str, strsize, "%"PRIu64"%s%02u %cB", n, decimal_point, snprintf(str, strsize, "%" PRIu64 "%s%02u %cB", n, decimal_point,
(unsigned)(((val % d) * 100) / d), prefixes[i]); (unsigned)(((val % d) * 100) / d), prefixes[i]);
return str; return str;
@ -814,8 +814,8 @@ std::string strprintf(const char * fmt, ...)
#ifndef HAVE_WORKING_SNPRINTF #ifndef HAVE_WORKING_SNPRINTF
// Some versions of (v)snprintf() don't append null char on overflow (MSVCRT.DLL), // Some versions of (v)snprintf() don't append null char (MSVCRT.DLL),
// and/or return -1 on overflow (old Linux). // and/or return -1 on output truncation (glibc <= 2.0.6).
// Below are sane replacements substituted by #define in utility.h. // Below are sane replacements substituted by #define in utility.h.
#undef vsnprintf #undef vsnprintf
@ -844,5 +844,25 @@ int safe_snprintf(char *buf, int size, const char *fmt, ...)
return i; return i;
} }
#endif #else // HAVE_WORKING_SNPRINTF
static void check_snprintf()
{
char buf[] = "ABCDEFGHI";
int n1 = snprintf(buf, 8, "123456789");
int n2 = snprintf(buf, 0, "X");
if (!(!strcmp(buf, "1234567") && n1 == 9 && n2 == 1))
throw std::logic_error("Function snprintf() does not conform to C99,\n"
"please contact " PACKAGE_BUGREPORT);
}
#endif // HAVE_WORKING_SNPRINTF
// Runtime check of ./configure result, throws on error.
void check_config()
{
check_endianness();
#ifdef HAVE_WORKING_SNPRINTF
check_snprintf();
#endif
}

View File

@ -4,7 +4,7 @@
* Home page of code is: http://smartmontools.sourceforge.net * Home page of code is: http://smartmontools.sourceforge.net
* *
* Copyright (C) 2002-11 Bruce Allen <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2002-11 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2008-12 Christian Franke <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2008-14 Christian Franke <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2000 Michael Cornwell <cornwell@acm.org> * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -25,7 +25,7 @@
#ifndef UTILITY_H_ #ifndef UTILITY_H_
#define UTILITY_H_ #define UTILITY_H_
#define UTILITY_H_CVSID "$Id: utility.h 3719 2012-12-03 21:19:33Z chrfranke $" #define UTILITY_H_CVSID "$Id: utility.h 3936 2014-07-05 17:16:23Z chrfranke $"
#include <time.h> #include <time.h>
#include <sys/types.h> // for regex.h (according to POSIX) #include <sys/types.h> // for regex.h (according to POSIX)
@ -155,8 +155,8 @@ inline bool isbigendian()
#endif #endif
} }
// Runtime check of byte ordering, throws if different from isbigendian(). // Runtime check of ./configure result, throws on error.
void check_endianness(); void check_config();
// This value follows the peripheral device type value as defined in // This value follows the peripheral device type value as defined in
// SCSI Primary Commands, ANSI INCITS 301:1997. It is also used in // SCSI Primary Commands, ANSI INCITS 301:1997. It is also used in