-$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>
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:
http://smartmontools.sourceforge.net/
Source and binary packages for Windows are available at
http://sourceforge.net/projects/smartmontools/files/
-Refer to http://sourceforge.net/apps/trac/smartmontools/wiki/Download
-for any additional download and installation instructions.
+Refer to http://www.smartmontools.org/wiki/Download for any additional
+download and installation instructions.
The following files are installed if ./configure has no options:
Directory for rc.d/init.d/smartd init script
--with-initscriptdir auto Location of init scripts
--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-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
available, option --capabilities is added to smartd.
--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-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'
--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
--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
default for --with-docdir was
## 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@
# BUILD_INFO can be provided by package maintainers (see INSTALL file)
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
AM_CPPFLAGS += -DSMARTMONTOOLS_DRIVEDBDIR='"$(drivedbdir)"'
endif
os_win32.cpp \
os_generic.cpp \
os_generic.h \
+ aacraid.h \
cciss.cpp \
cciss.h \
cissio_freebsd.h \
os_win32.cpp \
os_generic.cpp \
os_generic.h \
+ aacraid.h \
cciss.cpp \
cciss.h \
cissio_freebsd.h \
extra_MANS = smartd.conf.4 \
smartctl.1m \
smartd.1m
+if ENABLE_DRIVEDB
+extra_MANS += update-smart-drivedb.1m
+endif
+
+all-local: $(extra_MANS)
install-man: $(extra_MANS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(mandir)/man4
echo " rm -f $(DESTDIR)$(mandir)/man$$ext/$$inst"; \
rm -f $(DESTDIR)$(mandir)/man$$ext/$$inst; \
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
# For systems that adopts traditional manner
+
man_MANS = smartd.conf.5 \
smartctl.8 \
smartd.8
+
+if ENABLE_DRIVEDB
+man_MANS += update-smart-drivedb.8
+endif
+
endif
docsdir=$(docdir)
examplescripts/Example1 \
examplescripts/Example2 \
examplescripts/Example3 \
- examplescripts/Example4
+ examplescripts/Example4 \
+ examplescripts/Example5 \
+ examplescripts/Example6
sysconf_DATA = smartd.conf
echo " rm -f $$f"; \
rm -f "$$f"
-# automake does not allow 'sysconf_SCRIPTS'
-sysscriptdir = $(sysconfdir)
-sysscript_SCRIPTS = smartd_warning.sh
+smartdscript_SCRIPTS = smartd_warning.sh
EXTRA_DIST = \
autogen.sh \
smartd.service.in \
smartd_warning.sh.in \
update-smart-drivedb.in \
+ update-smart-drivedb.8.in \
m4/pkg.m4 \
os_darwin/SMART.in \
os_darwin/StartupParameters.plist \
smartd_warning.sh \
svnversion.h \
update-smart-drivedb \
+ update-smart-drivedb.8 \
+ update-smart-drivedb.1m \
SMART
# 'make maintainer-clean' also removes files generated by './autogen.sh'
MAINTAINERCLEANFILES = \
$(srcdir)/Makefile.in \
$(srcdir)/aclocal.m4 \
+ $(srcdir)/compile \
$(srcdir)/configure \
$(srcdir)/config.guess \
$(srcdir)/config.h.in \
if IS_SVN_BUILD
# Get version info from SVN
svnversion.h: ChangeLog Makefile $(svn_deps)
- echo '/* svnversion.h. Generated by Makefile from svn info. */' > $@
- (cd $(srcdir) \
+ @echo ' svn info | $$(VERSION_FROM_SVN_INFO) > $@'
+ @echo '/* svnversion.h. Generated by Makefile from svn info. */' > $@
+ @(cd $(srcdir) \
&& svnversion 2>/dev/null | sed -n 's,^\([0-9].*\),REV "\1",p' \
&& TZ= LC_ALL=C svn info 2>/dev/null \
| sed -n 'h;s,^.* Date: *\([^ ]*\) .*$$,DATE "\1",p;g;s,^.* Date: *[^ ]* *\([^ ]*\) .*$$,TIME "\1",p') \
# SVN not available, guess version info from Id strings
svnversion.h: ChangeLog Makefile
- echo '/* svnversion.h. Generated by Makefile from Id strings. */' > $@
- (cd $(srcdir) && cat ChangeLog Makefile.am configure.ac smart*.in *.cpp *.h *.s) \
+ @echo ' cat ChangeLog $$(SOURCES) | $$(VERSION_FROM_SVN_IDS) > $@'
+ @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' \
| sort -n -r \
| sed -n 'h;s,^\([^ ]*\) .*$$,REV "\1",p;g;s,^[^ ]* \([^ ]*\) .*$$,DATE "\1",p;g;s,^[^ ]* [^ ]* \([^ ]*\)$$,TIME "\1",p;q' \
drivedb_DATA = drivedb.h
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
$(SHELL) ./config.status --file=$@
chmod +x $@
endif
smartd.service: smartd.service.in Makefile
- sed -e 's|/usr/local/sbin/smartd|$(sbindir)/smartd|g' \
- -e 's|/usr/local/etc/sysconfig/smartmontools|$(sysconfdir)/sysconfig/smartmontools|g' \
- $(srcdir)/smartd.service.in > $@
+ cat $(srcdir)/smartd.service.in | \
+ sed 's|/usr/local/sbin/smartd|$(sbindir)/smartd|' | \
+ 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
MAN_CAPABILITIES = cat
else
-e 's|/usr/local/share/doc/smartmontools/|$(docsdir)/|g' \
-e 's|!exampledir!|$(exampledir)/|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_CAPABILITIES) | \
$(MAN_DRIVEDB) | \
# Implicit rule 'smart%: smart%.in ...' does not work with BSD make
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
- 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
- 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
# TODO: configure
smartd_res.o: smartd_res.rc syslogevt.rc
$(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 = \
( 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`; \
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
cat $< | $(WIN_RC_FILTER) > $@
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:
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
Summary: smartmontools release 6.2
-----------------------------------------------------------
- Sourcecode repository moved from CVS to SVN
- Support for USB devices with Cypress, JMicron and Sunplus USB bridges
- 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 MegaRAID controllers on Linux
- Support for HighPoint RocketRAID controllers on FreeBSD
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 ==
The home for smartmontools is located at:
== COPYING ==
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
under the terms of the GNU General Public License as published by the Free
version.
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 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+example COPYING). If not, see <http://www.gnu.org/licenses/>.
== CREDITS ==
== OVERVIEW ==
smartmontools contains utilities that control and monitor storage
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
-to check the reliability of the hard drive and to predict drive
-failures. smartmontools Version 5.x is designed to comply to the
-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.
+(SMART) system build into ATA/SATA and SCSI/SAS hard drives and
+solid-state drives. This is used to check the reliability of the
+drive and to predict drive failures.
== CONTENTS ==
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 ==
To examine SMART data from a disk, try:
-$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:
-http://sourceforge.net/apps/trac/smartmontools/report
+http://www.smartmontools.org/report
-$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:
-http://sourceforge.net/p/smartmontools/code/HEAD/tree/trunk/smartmontools/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.
+This file is no longer maintained, please see:
+http://www.smartmontools.org/wiki/Warnings
--- /dev/null
+/* 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;
* Home page of code is: http://smartmontools.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) 2000 Andre Hedrick <andre@linux-ide.org>
*
#include "utility.h"
#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;
// Print ATA debug messages?
const unsigned num_format_names = sizeof(format_names)/sizeof(format_names[0]);
// 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,minutes" , "9,min2hour,Power_On_Minutes"},
{ "9,seconds" , "9,sec2hour,Power_On_Seconds"},
int id = 0, n1 = -1, n2 = -1;
char fmtname[32+1], attrname[32+1];
if (opt[0] == 'N') {
- // "N,format"
+ // "N,format[,name]"
if (!( sscanf(opt, "N,%32[^,]%n,%32[^,]%n", fmtname, &n1, attrname, &n2) >= 1
&& (n1 == len || n2 == len)))
return false;
// Split "format[:byteorder]"
char byteorder[8+1] = "";
if (strchr(fmtname, ':')) {
+ n1 = n2 = -1;
if (!( sscanf(fmtname, "%*[^:]%n:%8[012345rvwz]%n", &n1, byteorder, &n2) >= 1
&& n2 == (int)strlen(fmtname)))
return false;
"probable SAT/USB truncation\n");
}
else if (!out.out_regs.is_set()) {
- pout("SMART STATUS RETURN: incomplete response, ATA output registers missing\n");
- device->set_err(ENOSYS);
+ device->set_err(ENOSYS, "Incomplete response, ATA output registers missing");
retval = -1;
}
else {
pout("Please get assistance from %s\n", PACKAGE_HOMEPAGE);
pout("Register values returned from SMART Status command are:\n");
print_regs(" ", out.out_regs);
- device->set_err(EIO);
+ device->set_err(ENOSYS, "Invalid ATA output register values");
retval = -1;
}
break;
uint64_t spans = (num_sectors + oldsize-1) / oldsize;
uint64_t newsize = (num_sectors + spans-1) / spans;
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);
- pout(" to %"PRIu64"-%"PRIu64" (%"PRIu64" sectors) (%"PRIu64" spans)\n",
+ pout(" to %" PRIu64 "-%" PRIu64 " (%" PRIu64 " sectors) (%" PRIu64 " spans)\n",
newstart, newend, newsize, spans);
start = newstart; end = newend;
}
end = num_sectors - 1;
}
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);
return -1;
}
if (isbigendian()) {
swapx(&log->device_error_count);
swapx(&log->error_log_index);
-
for (unsigned i = 0; i < nsectors; i++) {
- for (unsigned j = 0; j < 4; j++)
- swapx(&log->error_logs[i].commands[j].timestamp);
- swapx(&log->error_logs[i].error.timestamp);
+ for (unsigned j = 0; j < 4; j++) {
+ for (unsigned k = 0; k < 5; k++)
+ swapx(&log[i].error_logs[j].commands[k].timestamp);
+ swapx(&log[i].error_logs[j].error.timestamp);
+ }
}
}
int i;
pout("SPAN STARTING_LBA ENDING_LBA\n");
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].end);
}
case 196: // Reallocated event count
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;
case 190: // Temperature
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.
std::string ata_format_attr_raw_value(const ata_smart_attribute & attr,
case RAWFMT_RAW48:
case RAWFMT_RAW56:
case RAWFMT_RAW64:
- s = strprintf("%"PRIu64, rawvalue);
+ s = strprintf("%" PRIu64, rawvalue);
break;
case RAWFMT_HEX48:
- s = strprintf("0x%012"PRIx64, rawvalue);
+ s = strprintf("0x%012" PRIx64, rawvalue);
break;
case RAWFMT_HEX56:
- s = strprintf("0x%014"PRIx64, rawvalue);
+ s = strprintf("0x%014" PRIx64, rawvalue);
break;
case RAWFMT_HEX64:
- s = strprintf("0x%016"PRIx64, rawvalue);
+ s = strprintf("0x%016" PRIx64, rawvalue);
break;
case RAWFMT_RAW16_OPT_RAW16:
int64_t temp = word[0]+(word[1]<<16);
int64_t tmp1 = 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])
s += strprintf(" (%u)", word[2]);
}
int64_t hours = rawvalue/3600;
int64_t minutes = (rawvalue-3600*hours)/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;
// 30-second counter
int64_t hours = rawvalue/120;
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;
// Temperature
{
// Search for possible min/max values
- // 00 HH 00 LL 00 TT (Hitachi/IBM)
- // 00 00 HH LL 00 TT (Maxtor, Samsung)
+ // [5][4][3][2][1][0] raw[]
+ // [ 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)
- unsigned char lo = 0, hi = 0;
- int cnt = 0;
- 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;
- }
+ // CC CC HH LL xx TT (WDC, CCCC=over temperature count)
+ // (xx = 00/ff, possibly sign extension of lower byte)
+
+ int t = (signed char)raw[0];
+ int lo = 0, hi = 0;
+
+ int tformat;
+ 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;
}
-
- unsigned char t = raw[0];
- if (cnt == 0)
- s = strprintf("%d", t);
- else if (cnt == 2 && 0 < lo && lo <= t && t <= hi && hi < 128)
- s = strprintf("%d (Min/Max %d/%d)", t, lo, hi);
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;
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,
ata_sct_status_response * sts)
{
- // Check initial status
- if (ataReadSCTStatus(device, sts))
- return -1;
+ // Initial SCT status must be provided by caller
// Do nothing if other SCT command is executing
if (sts->ext_status_code == 0xffff) {
ata_cmd_out 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());
return -1;
}
char msglba[32];
if (retval < 0 && failing_lba < 0xffffffffffffULL)
- snprintf(msglba, sizeof(msglba), "%"PRIu64, failing_lba);
+ snprintf(msglba, sizeof(msglba), "%" PRIu64, failing_lba);
else {
msglba[0] = '-'; msglba[1] = 0;
}
pout("Warning: ATA Specification requires self-test log structure revision number = 1\n");
if (data->mostrecenttest==0){
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;
}
#include "config.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;
#include "int64.h"
if (word + 1 == word2 && strstr(desc, "(DWord)"))
pout(" (%u)\n", ((unsigned)get_word(id, word2) << 16) | w);
else if (word + 3 == word2 && strstr(desc, "(QWord)"))
- pout(" (%"PRIu64")\n", ((uint64_t)get_word(id, word + 3) << 48)
- | ((uint64_t)get_word(id, word + 2) << 32)
- | ((unsigned)get_word(id, word + 1) << 16) | (unsigned)w);
+ pout(" (%" PRIu64 ")\n", ((uint64_t)get_word(id, word + 3) << 48)
+ | ((uint64_t)get_word(id, word + 2) << 32)
+ | ((unsigned)get_word(id, word + 1) << 16) | (unsigned)w);
else
pout("\n");
}
* Home page of code is: http://smartmontools.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>
*
* This program is free software; you can redistribute it and/or modify
#include "utility.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;
lba48 |= lba48_regs->lba_mid_register;
lba48 <<= 8;
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);
}
}
unsigned oui = 0; uint64_t unique_id = 0;
int naa = ata_get_wwn(drive, oui, unique_id);
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
// (e08130r1, added in ACS-2 Revision 1, December 17, 2008)
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
pout("Device is: %s\n", !dbentry ?
"Not in smartctl database [for details use: -P showall]":
case 0x09: return "Selective self-test log";
case 0x0a: return "Device Statistics Notification"; // 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 0x10: return "NCQ Command Error log";
case 0x13: return "SATA NCQ Send and Receive log"; // ACS-3
case 0x14:
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
static const char * get_log_rw(unsigned logaddr)
{
if ( ( logaddr <= 0x08)
- || (0x0d == logaddr)
+ || (0x0c <= logaddr && logaddr <= 0x0d)
|| (0x10 <= logaddr && logaddr <= 0x13)
|| (0x19 == logaddr)
|| (0x20 <= logaddr && logaddr <= 0x25)
if (!(flags & 0x80))
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
int size = (info ? info[i].size : 7);
for (int j = 0; j < size; j++)
val |= (int64_t)data[offset+j] << (j*8);
}
- snprintf(valstr, sizeof(valstr), "%"PRId64, val);
+ snprintf(valstr, sizeof(valstr), "%" PRId64, val);
}
else {
// Value not known (yet)
}
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
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");
return false;
}
// Print list of supported pages if requested
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");
for (i = 0; i < nentries; i++) {
int page = page_0[8+1+i];
// Read & print pages
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");
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++) {
int page = pages[i];
- unsigned char page_n[512] = {0, };
- if (!ataReadLogExt(device, 0x04, 0, page, page_n, 1)) {
+ if (use_gplog && !ataReadLogExt(device, 0x04, 0, page, pages_buf.data(), 1)) {
pout("Read Device Statistics page %d failed\n\n", page);
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)
}
// 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);
}
if (reset)
// we need at least 7 characters wide fields to accomodate the
// labels
- if ((field1=snprintf(tmp,64, "%"PRIu64, maxl))<7)
+ if ((field1=snprintf(tmp,64, "%" PRIu64, maxl))<7)
field1=7;
- if ((field2=snprintf(tmp,64, "%"PRIu64, maxr))<7)
+ if ((field2=snprintf(tmp,64, "%" PRIu64, maxr))<7)
field2=7;
// now print the five test spans
if ((i+1)==(int)log->currentspan)
// 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,
(int)(sv->self_test_exec_status & 0xf), current, currentend);
else
// 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);
}
// if we are currently read-scanning, print LBAs and the status of
// the read scan
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,
OfflineDataCollectionStatus(sv->offline_data_collection_status));
);
// 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 = (
options.gp_logdir
if (options.get_security)
print_ata_security_status("ATA Security is: ", drive.words088_255[128-88]);
- // Check if SCT commands available
- bool sct_ok = false;
- if (need_sct_support) {
- if (!isSCTCapable(&drive)) {
- failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
+ // Print write cache reordering status
+ if (options.sct_wcache_reorder_get) {
+ if (isSCTFeatureControlCapable(&drive)) {
+ int wcache_reorder = ataGetSetSCTWriteCacheReordering(device,
+ 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
- sct_ok = true;
- }
-
- // 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");
+ pout("Wt Cache Reorder: Unavailable\n");
}
// Print remaining drive info
}
// 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);
-
- int wcache_reorder=ataGetSetSCTWriteCacheReordering(device,
- enable, false /* persistent */, true /*set*/);
-
- if (wcache_reorder < 0) {
- pout("Write cache reordering %sable failed: %s\n", (enable ? "en" : "dis"), device->get_errmsg());
- returnval |= FAILSMART;
+ if (!isSCTFeatureControlCapable(&drive))
+ pout("Write cache reordering %sable failed: SCT Feature Control command not supported\n",
+ (enable ? "en" : "dis"));
+ else if (ataGetSetSCTWriteCacheReordering(device,
+ enable, false /*persistent*/, true /*set*/) < 0) {
+ pout("Write cache reordering %sable failed: %s\n", (enable ? "en" : "dis"), device->get_errmsg());
+ returnval |= FAILSMART;
}
else
pout("Write cache reordering %sabled\n", (enable ? "en" : "dis"));
// The ATA SMART RETURN STATUS command provides the result in the ATA output
// registers. Buggy ATA/SATA drivers and SAT Layers often do not properly
// return the registers values.
+ pout("SMART Status %s: %s\n",
+ (device->is_syscall_unsup() ? "not supported" : "command failed"),
+ device->get_errmsg());
failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
+
if (!(smart_val_ok && smart_thres_ok)) {
print_on();
pout("SMART overall-health self-assessment test result: UNKNOWN!\n"
print_on();
pout("SMART overall-health self-assessment test result: FAILED!\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();
returnval|=FAILATTR;
returnval|=FAILSTATUS;
}
}
+ // 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
|| options.sct_erc_get || options.sct_erc_set ))
pout("SCT Commands not supported\n\n");
// Print SCT status and temperature history table
if (sct_ok && (options.sct_temp_sts || options.sct_temp_hist || options.sct_temp_int)) {
for (;;) {
- if (options.sct_temp_sts || options.sct_temp_hist) {
- ata_sct_status_response sts;
- ata_sct_temperature_history_table tmh;
- if (!options.sct_temp_hist) {
- // Read SCT status only
- if (ataReadSCTStatus(device, &sts)) {
- failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
- break;
- }
- }
- else {
- 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;
- }
+ bool sct_temp_hist_ok = isSCTDataTableCapable(&drive);
+ ata_sct_status_response sts;
+
+ if (options.sct_temp_sts || (options.sct_temp_hist && sct_temp_hist_ok)) {
+ // Read SCT status
+ if (ataReadSCTStatus(device, &sts)) {
+ pout("\n");
+ failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
+ break;
}
- if (options.sct_temp_sts)
+ if (options.sct_temp_sts) {
ataPrintSCTStatus(&sts);
- if (options.sct_temp_hist)
- ataPrintSCTTempHist(&tmh);
+ pout("\n");
+ }
+ }
+
+ 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");
}
+
if (options.sct_temp_int) {
// Set new temperature logging interval
if (!isSCTFeatureControlCapable(&drive)) {
// Print Device Statistics
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)
- 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,
- options.devstat_all_pages, options.devstat_ssd_page))
+ options.devstat_all_pages, options.devstat_ssd_page, use_gplog))
failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
}
#!/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.
# This also adds files like missing,depcomp,install-sh to the source
# directory. To update these files at a later date use:
# 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?
test -x /usr/bin/uname && /usr/bin/uname | grep -i CYGWIN >/dev/null &&
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.9` || AUTOMAKE=`typep automake-1.8` ||
AUTOMAKE=`typep automake-1.7` || AUTOMAKE=`typep automake17` ||
{
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 "appropriate package for your distribution, or the source tarball"
echo "from ftp://ftp.gnu.org/gnu/automake/ ."
echo
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 "to test it before the developers. Be patient."
exit 1;
esac
# Warn if Automake version was not tested or does not support filesystem
+amwarnings=$warnings
case "$ver" in
1.[78]|1.[78].*)
# Check for case sensitive filesystem
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
;;
+ 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 "Please report success/failure to the smartmontools-support mailing list."
# Install pkg-config macros
# (Don't use 'aclocal -I m4 --install' to keep support for automake < 1.10)
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 -n "$acdir" && test -f "$acdir/pkg.m4" &&
{
set -e # stops on error status
-${ACLOCAL} -I m4
-autoheader
-${AUTOMAKE} --add-missing --copy
-autoconf
+test -z "$warnings" || set -x
+
+${ACLOCAL} -I m4 $force $warnings
+autoheader $force $warnings
+${AUTOMAKE} --add-missing --copy ${force:+--force-missing} $amwarnings
+autoconf $force $warnings
#include "config.h"
-#if defined(linux)
+#if defined(linux) || defined(__linux__)
# include <sys/ioctl.h>
# ifdef HAVE_LINUX_COMPILER_H
# include <linux/compiler.h>
#include "scsicmds.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;
typedef struct _ReportLUNdata_struct
#
-# $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.
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)
-smartmontools_configure_date=`date -u +'%Y-%m-%d %T %Z'`
-smartmontools_cvs_tag=`echo '$Id: configure.ac 3841 2013-07-26 17:38:57Z chrfranke $'`
-smartmontools_release_date=2013-07-26
-smartmontools_release_time="17:38:20 UTC"
+smartmontools_cvs_tag=`echo '$Id: configure.ac 3977 2014-07-26 11:03:24Z chrfranke $'`
+smartmontools_release_date=2014-07-26
+smartmontools_release_time="09:49:11 UTC"
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_TIME, "$smartmontools_release_time", [smartmontools Release Time])
AC_DEFINE_UNQUOTED(CONFIG_H_CVSID, "$smartmontools_cvs_tag", [smartmontools CVS Tag])
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_MAINTAINER_MODE
-AC_LANG_CPLUSPLUS
+AC_LANG([C++])
dnl Checks for programs.
AC_PROG_CXX
AM_PROG_AS
AC_CANONICAL_HOST
case "${host}" in
*-*-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(WINDRES, [windres])
- AC_MSG_CHECKING([checking for makensis])
+ AC_MSG_CHECKING([for makensis])
if test -z "$MAKENSIS"; then
if test -n "$PROGRAMFILES" && "$PROGRAMFILES/NSIS/makensis" -VERSION >/dev/null 2>&1; then
MAKENSIS="$PROGRAMFILES/NSIS/makensis"
# Check byte ordering (defines WORDS_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))
# (sizeof() check is required to avoid false positives if other
# __attribute__((x)) are supported)
AC_SUBST(LDFLAGS)
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,
[AS_HELP_STRING([--with-systemdsystemunitdir@<:@=DIR|auto|yes|no@:>@], [Location of systemd service files [auto]])],
- [], [with_systemdsystemunitdir=auto])
+ [], [with_systemdsystemunitdir=$systemd_default])
systemdsystemunitdir=
case "$with_systemdsystemunitdir" in
auto|yes)
if test -n "$PKG_CONFIG"; then
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}])
fi
case "$with_systemdsystemunitdir:$sysconfdir:$systemdsystemunitdir" in
AM_CONDITIONAL(INSTALL_SYSTEMDUNIT, [test -n "$systemdsystemunitdir"])
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])
initddir=
AC_SUBST(initdfile)
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"],
[ if test -z "$docdir"; then
# autoconf 2.5x without '--docdir' support
AC_SUBST(docdir)
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'])
AC_SUBST(exampledir)
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])
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=; test "$enable_drivedb" = "yes" && drivedbdir='${datadir}/${PACKAGE}'])
AC_SUBST(drivedbdir)
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_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=; test "$enable_savestates" = "yes" && savestates='${localstatedir}/lib/${PACKAGE}/smartd.'])
savestatesdir="${savestates%/*}"
AC_SUBST(savestatesdir)
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_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=; test "$enable_attributelog" = "yes" && attributelog='${localstatedir}/lib/${PACKAGE}/attrlog.'])
attributelogdir="${attributelog%/*}"
AM_CONDITIONAL(ENABLE_ATTRIBUTELOG, [test "$enable_attributelog" = "yes"])
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=;])
AC_SUBST(smartd_suffix)
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
case $x in
*.o) ;;
],[])
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
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])])
fi
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])
use_libcap_ng=no
AM_CONDITIONAL(ENABLE_CAPABILITIES, [test "$use_libcap_ng" = "yes"])
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
dnl no prefix and no mandir, so use ${prefix}/share/man as default
if test "$mandir" = '${prefix}/man'; then
;;
*-*-cygwin*)
os_deps='os_win32.o dev_areca.o'
+ os_mailer='email'
os_hostname="'hostname' 'echo "'"${HOSTNAME?unset}"'"'"
os_dnsdomainname="'dnsdomainname' 'hostname -d' 'echo "'"${USERDNSDOMAIN?unset}"'"'"
os_nisdomainname=
fi
echo "local drive database: `eval eval eval echo $sysconfdir`/smart_drivedb.h" >&AS_MESSAGE_FD
echo "smartd config file: `eval eval eval echo $sysconfdir`/smartd.conf${smartd_suffix}" >&AS_MESSAGE_FD
- echo "smartd 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
echo "smartd initd script: `eval eval eval echo $initddir`/smartd${smartd_suffix}" >&AS_MESSAGE_FD
elif test -z "$systemdsystemunitdir"; then
fi
if test -n "$systemdsystemunitdir"; then
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
if test -n "$savestates"; then
echo "smartd save files: `eval eval eval echo $savestates`MODEL-SERIAL.TYPE.state" >&AS_MESSAGE_FD
#include "dev_interface.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;
#include "atacmds.h"
// 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)
{
- 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_WRITE_WQBUFFER,
sBuf.srbioctl.Timeout = 10000;
sBuf.srbioctl.ControlCode = cmds[arcmsr_cmd];
- if(arcmsr_cmd >= ARCMSR_CMD_TOTAL)
- {
- return -1;
- }
-
switch ( arcmsr_cmd )
{
// command for writing data to driver
#ifndef 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
#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_RETURN_CODE_3F (ARECA_SATA_RAID | FUNCTION_RETURN_CODE_3F)
-#elif defined(__FreeBSD__)
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
#include <sys/ioctl.h> // _IOWR
/*FunctionCode*/
* Home page of code is: http://smartmontools.sourceforge.net
*
* 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
* it under the terms of the GNU General Public License as published by
/*
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",
""
"-v 232,raw48,Available_Reservd_Space "
"-v 233,raw48,Media_Wearout_Indicator " // SSD only
// 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 242,raw48,Total_LBAs_Read "
// 243-249 Unknown_Attribute
"-v 254,raw48,Free_Fall_Sensor " // HDD only
*/
},
- { "Apple SSD SM128", // Samsung?
- "APPLE SSD SM128",
- "", "", ""
- },
- { "Apacer SDM4",
- "2GB SATA Flash Drive", // tested with APSDM002G15AN-CT/SFI2101D
- "SFI2101D", "",
+ { "Apacer SSD",
+ "(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
"-v 160,raw48,Initial_Bad_Block_Count "
"-v 161,raw48,Bad_Block_Count "
"-v 162,raw48,Spare_Block_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 166,raw48,Later_Bad_Block_Count "
+ "-v 167,raw48,SSD_Protect_Mode "
+ "-v 168,raw48,SATA_PHY_Err_Ct "
},
- { "Asus-Phison SSD",
- "ASUS-PHISON SSD",
- "", "", ""
+ { "Apple SD/SM/TS...E/F SSDs", // SanDisk/Samsung/Toshiba?
+ "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
"C300-CTFDDA[AC](064|128|256)MAG|" // Marvell 88SS9174 BJP2, tested with C300-CTFDDAC128MAG/0002,
// 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 5,raw16(raw16),Reallocated_Sector_Ct "
//"-v 197,raw48,Current_Pending_Sector "
//"-v 198,raw48,Offline_Uncorrectable "
//"-v 199,raw48,UDMA_CRC_Error_Count "
- "-v 202,raw48,Perc_Rated_Life_Used "
- "-v 206,raw48,Write_Error_Rate"
+ "-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"
},
{ "Crucial/Micron RealSSD m4/C400/P400", // Marvell 9176, fixed firmware
"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
// MTFDDAK256MAR-1K1AA/MA52
"030[9-Z]|03[1-Z].|0[4-Z]..|[1-Z]....*", // >= "0309"
},
{ "Crucial/Micron RealSSD m4/C400", // Marvell 9176, buggy or unknown firmware
"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
"",
"This drive may hang after 5184 hours of power-on time:\n"
"-v 202,raw48,Perc_Rated_Life_Used "
"-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 1st Ed\\.|" // Demo Drive, tested with firmware 320A13F0
"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 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-F40GB2/1.1, Corsair CSSD-F115GB2-A/2.1a
- "Corsair Force (3 SSD|GS|GT)|" // SF-2281, tested with
- // Corsair Force 3 SSD/1.3.2, GT/1.3.3, GS/5.03
+ "Corsair Force ((3 |LS )?SSD|GS|GT)|" // SF-2281, tested with
+ // 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-240GBP2/4.2
"FTM(06|12|24|48)CT25H|" // Supertalent TeraDrive CT, tested with
// 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
// 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
// SVP200S37A480G/502ABBF0, SVP200S390G/332ABBF0
"KINGSTON SMS200S3(30|60|120)G|" // mSATA, SF-2241, tested with SMS200S3120G/KC3ABBF0
"(APOC|DENC|DENEVA|FTNC|GFGC|MANG|MMOC|NIMC|TMSC).*|" // other OCZ SF-1200,
// tested with DENCSTE251M11-0120/1.33, DENEVA PCI-E/1.33
"(DENR|DRSAK|EC188|NIMR|PSIR|TRSAK).*|" // other OCZ SF-1500
- "OWC Mercury Electra [36]G SSD|" // tested with
- // OWC Mercury Electra 6G SSD/502ABBF0
- "OWC Mercury Extreme Pro (RE )?SSD|" // tested with
- // OWC Mercury Extreme Pro SSD/360A13F0
- "OWC Mercury EXTREME Pro 6G SSD|" // tested with
- // OWC Mercury EXTREME Pro 6G SSD/507ABBF0
+ "OWC Aura Pro 6G SSD|" // tested with OWC Aura Pro 6G SSD/507ABBF0
+ "OWC Mercury Electra (Pro )?[36]G SSD|" // tested with
+ // OWC Mercury Electra 6G SSD/502ABBF0, OWC Mercury Electra Pro 3G SSD/541ABBF0
+ "OWC Mercury E(xtreme|XTREME) Pro (6G |RE )?SSD|" // tested with
+ // OWC Mercury Extreme Pro SSD/360A13F0, OWC Mercury EXTREME Pro 6G SSD/507ABBF0
"Patriot Pyro|" // tested with Patriot Pyro/332ABBF0
"SanDisk SDSSDX(60|120|240|480)GG25|" // SanDisk Extreme, SF-2281, tested with
// SDSSDX240GG25/R201
"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
"(TX22D1|TX21B1).*|" // Smart Storage Systems XceedIOPS2
"TX52D1.*|" // Smart Storage Systems Xcel-200
- "TS(64|128|256|512)GSSD320|" // Transcend SSD320, SF-2281, tested with TS128GSSD320
- "UGB(88P|99S)GC...H[BF].", // Unigen, tested with
+ "TS(64|128|256|512)GSSD[37]20|" // Transcend SSD320/720, SF-2281, tested with
+ // TS128GSSD320, TS256GSSD720/5.2.0
+ "UGB(88P|99S)GC...H[BF].|" // Unigen, tested with
// 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 5,raw48,Retired_Block_Count "
"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
"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-ONYX/1.6, OCZ-VERTEX 1199/00.P97, OCZ-VERTEX/1.30, OCZ VERTEX-TURBO/1.5
+ "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-VERTEX v1.10/1370
"Patriot[ -]Torqx.*|"
"RENICE Z2|" // tested with RENICE Z2/2030
"STT_FT[MD](28|32|56|64)GX25H|" // Super Talent Ultradrive GX, tested with STT_FTM64GX25H/1916
//"-v 233,raw48,Media_Wearout_Indicator"
},
{ "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 9,raw24(raw8),Power_On_Hours "
"-v 208,raw48,Average_Erase_Count "
"-v 210,raw48,SATA_CRC_Error_Count "
"-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"
},
+ { "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
"InnoLite SATADOM D150QV-L",
"", "",
"-v 242,raw48,Host_Reads_32MiB"
},
{ "Intel 320 Series SSDs", // tested with INTEL SSDSA2CT040G3/4PC10362,
- // INTEL SSDSA2CW160G3/4PC10362, INTEL SSDSA2BT040G3/4PC10362, INTEL SSDSA2BW120G3A/4PC10362
- "INTEL SSDSA[12][BC][WT](040|080|120|160|300|600)G3A?",
+ // INTEL SSDSA2CW160G3/4PC10362, INTEL SSDSA2BT040G3/4PC10362, INTEL SSDSA2BW120G3A/4PC10362,
+ // INTEL SSDSA2BW300G3D/4PC10362, INTEL SSDSA2BW160G3L/4PC1LE04
+ "INTEL SSDSA[12][BC][WT](040|080|120|160|300|600)G3[ADL]?",
"", "",
"-F nologdir "
//"-v 3,raw16(avg16),Spin_Up_Time "
"-v 170,raw48,Reserve_Block_Count "
"-v 171,raw48,Program_Fail_Count "
"-v 172,raw48,Erase_Fail_Count "
+ "-v 183,raw48,SATA_Downshift_Count " // FW >= 4Px10362
//"-v 184,raw48,End-to-End_Error "
//"-v 187,raw48,Reported_Uncorrect "
+ "-v 199,raw48,CRC_Error_Count " // FW >= 4Px10362
"-v 192,raw48,Unsafe_Shutdown_Count "
"-v 225,raw48,Host_Writes_32MiB "
"-v 226,raw48,Workld_Media_Wear_Indic " // Timed Workload Media Wear Indicator (percent*1024)
"-v 242,raw48,Host_Reads_32MiB "
"-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 SSDSC2CT240A4/335t
"INTEL SSDSC2CT(060|120|180|240)A[34]", // A4 = 335 Series
"-v 242,raw48,Host_Reads_32MiB "
"-v 249,raw48,NAND_Writes_1GiB"
},
- { "Intel DC S3700 Series SSDs", // tested with INTEL SSDSC2BA200G3/5DV10250
- "INTEL SSDSC(1N|2B)A(100|200|400|800)G3",
+ { "Intel 730 and DC S3500/S3700 Series SSDs", // tested with INTEL SSDSC2BP480G4, SSDSC2BB120G4/D2010355,
+ // 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 4,raw48,Start_Stop_Count "
"-v 171,raw48,Program_Fail_Count "
"-v 172,raw48,Erase_Fail_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 184,raw48,End-to-End_Error "
//"-v 187,raw48,Reported_Uncorrect "
"-v 228,raw48,Workload_Minutes " // 226,227,228 can be reset by 'smartctl -t vendor,0x40'
//"-v 232,raw48,Available_Reservd_Space "
//"-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 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 SSDNow 40GB",
},
{ "JMicron based SSDs", // JMicron JMF60x
"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
- "[BV].*", // other Transcend SSD versions will be catched by subsequent entry
+ "TS(2|4|8|16|32|64|128|192)GSSD(18|25)[MS]?-[MS]", // Transcend IDE and SATA, tested with
+ // 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 12,raw48,Power_Cycle_Count "
"-v 234,raw24/raw24:w01234,Avg/Max_Erase_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)
- "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),
// tested with KINGSTON SNV425S264GB/C091126a
"KINGSTON SSDNOW 30GB|" // tested with KINGSTON SSDNOW 30GB/AJXA0202
"-v 168,raw48,SATA_Phy_Error_Count "
//"-v 169,raw48,Unknown_Attribute "
"-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 192,raw48,Unexpect_Power_Loss_Ct "
//"-v 194,tempminmax,Temperature_Celsius "
//"-v 197,raw48,Current_Pending_Sector "
"-v 240,raw48,Unknown_Attribute"
},
- { "Plextor M3 (Pro) Series SSDs", // Marvell 9174, tested with PLEXTOR PX-128M3/1.01,
- // PLEXTOR PX-128M3P/1.04, PLEXTOR PX-256M3/1.05
+ { "Plextor M3/M5 (Pro) Series SSDs", // Marvell 88SS9174 (M3, M5S), 88SS9187 (M5Pro), tested with
+ // 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)
- "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 5,raw16(raw16),Reallocated_Sector_Ct "
//"-v 198,raw48,Offline_Uncorrectable "
//"-v 199,raw48,UDMA_CRC_Error_Count "
//"-v 232,raw48,Available_Reservd_Space "
- ""
+ "-v 241,raw48,Host_Writes_32MiB "
+ "-v 242,raw48,Host_Reads_32MiB"
},
{ "Samsung based SSDs",
"SAMSUNG SSD PM800 .*GB|" // SAMSUNG PM800 SSDs, tested with SAMSUNG SSD PM800 TH 64GB/VBM25D1Q
"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 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 MZ7WD120HAFV-00003/DXM85W3Q
"", "",
"-v 235,raw48,POR_Recovery_Count " // 830/840 Series
//"-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 A25FD-(32|64|128)GI32N", // tested with SMART A25FD-128GI32N/B9F23D4K
"",
"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 HD(155|204)UI",
"", // 1AQ10001
"Buggy and fixed firmware report same version number!\n"
"See the following web pages for details:\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
"", "", ""
},
{ "Toshiba 2.5\" HDD MK..65GSX", // tested with TOSHIBA MK5065GSX/GJ003A, MK3265GSXN/GH012H,
- // MK5065GSXF/GP006B
- "TOSHIBA MK(16|25|32|50|64)65GSX[FN]?",
+ // MK5065GSXF/GP006B, MK2565GSX H/GJ003A
+ "TOSHIBA MK(16|25|32|50|64)65GSX[FN]?( H)?", // "... H" = USB ?
"", "", ""
},
{ "Toshiba 2.5\" HDD MK..76GSX", // tested with TOSHIBA MK3276GSX/GS002D
"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 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 DT01ACA200/MX4OABB0, TOSHIBA DT01ACA300/MX6OABB0
"TOSHIBA DT01ACA(025|032|050|075|100|150|200|300)",
"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
"ST(500|1000)LM0(00|14)-.*",
"", "", ""
},
{ "Seagate Barracuda 7200.14 (AF)", // new firmware, tested with
// 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"
"",
"-v 188,raw16 -v 240,msec24hour32" // tested with ST3000DM001-9YN166/CC4H
},
{ "Seagate Barracuda 7200.14 (AF)", // old firmware, tested with
// ST1000DM003-9YN162/CC46
- "ST(1000|1500|2000|2500|3000)DM00[1-3]-.*",
+ "ST(1000|1500|2000|2500|3000)DM00[1-3]-9YN16.",
"CC4[679CG]",
"A firmware update for this drive is available,\n"
"see the following Seagate web pages:\n"
"-v 188,raw16 -v 240,msec24hour32"
},
{ "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"
"see the following Seagate web pages:\n"
"http://knowledge.seagate.com/articles/en_US/FAQ/223651en",
"-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
"ST(250|320|500|750)DM00[0-3]-.*",
"", "",
"", "",
"-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
"ST3(500412|1000520|1500541|2000542)AS",
"CC3[5-9A-Z]",
},
{ "Seagate Barracuda Green (AF)", // new firmware
"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
"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",
"ST3(160310|320[34]10|500(321|422))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",
"ST3(17240|13030|10231|8420|4310)A",
"", "", ""
"WDC WD2002FYPS-.*",
"", "", ""
},
- { "Western Digital RE4 (SATA 6Gb/s)", // tested with WDC WD2000FYYZ-01UL1B0/01.01K01
- "WDC WD(20|30|40)00FYYZ-.*",
+ { "Western Digital RE4 (SATA 6Gb/s)", // tested with WDC WD2000FYYZ-01UL1B0/01.01K01,
+ // 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 (AF, SATA 6Gb/s)", // tested with
// WDC WD10EZRX-00A8LB0/01.01A01, WDC WD20EZRX-00DC0B0/80.00A80,
- // WDC WD30EZRX-00MMMB0/80.00A80
- "WDC WD(7500AA|(10|15|20)EA|(10|20|25|30)EZ)RX-.*",
+ // WDC WD30EZRX-00MMMB0/80.00A80, WDC WD40EZRX-00SPEB0/80.00A80
+ "WDC WD(7500AA|(10|15|20)EA|(10|20|25|30|40)EZ)RX-.*",
"", "", ""
},
{ "Western Digital Caviar Black",
"WDC WD((500|640|750)1AAL|1001FA[EL]|2001FAS)S-.*",
"", "", ""
},
- { "Western Digital Caviar Black", // SATA 6 Gb/s variants, tested with
- // WDC WD4001FAEX-00MJRA0/01.01L01
- "WDC WD(5002AAL|(64|75)02AAE|((10|15|20)02|4001)FAE)X-.*",
- "", "", ""
- },
- { "Western Digital Caviar Black (AF)", // tested with WDC WD5003AZEX-00RKKA0/80.00A80
- "WDC WD(5003AZE)X-.*",
+ { "Western Digital Black", // tested with
+ // WDC WD5003AZEX-00RKKA0/80.00A80, WDC WD1003FZEX-00MK2A0/01.01A01,
+ // 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 AV ATA", // tested with WDC WD3200AVJB-63J5A0/01.03E01
"WDC WD(50|75)00BPKT-.*",
"", "", ""
},
- { "Western Digital Red (AF)", // tested with WDC WD10EFRX-68JCSN0/01.01A01
- "WDC WD(10|20|30)EFRX-.*",
+ { "Western Digital Red (AF)", // tested with WDC WD10EFRX-68JCSN0/01.01A01,
+ // WDC WD10JFCX-68N6GN0/01.01A01, WDC WD40EFRX-68WT0N0/80.00A80
+ "WDC WD(10|20|30|40)[EJ]F[CR]X-.*",
+ "", "", ""
+ },
+ { "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 My Passport (USB)", // tested with WDC WD5000BMVW-11AMCS0/01.01A01
+ { "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
"", "", ""
},
- { "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 WD10JMVW-11S5XS1/01.01A01, WDC WD20NMVW-11W68S0/01.01A01
"WDC WD(5000[LK]|7500K|10[JT]|20N)MV[VW]-.*", // *W-* = USB 3.0
"",
"-d sat"
},
+ { "USB: Buffalo MiniStationHD-PCFU3; ",
+ "0x0411:0x0240",
+ "",
+ "",
+ "-d sat"
+ },
// LG Electronics
{ "USB: LG Mini HXD5; JMicron",
"0x043e:0x70f1",
"-d sat"
},
// Toshiba
+ { "USB: Toshiba Stor.E Slim USB 3.0; ", // 1TB, MQ01UBD100
+ "0x0480:0x0100",
+ "", // 0x0000
+ "",
+ "-d sat"
+ },
{ "USB: Toshiba Canvio 500GB; SunPlus",
"0x0480:0xa004",
"",
"",
"-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
"0x0480:0xd010",
"",
"",
"-d sat"
},
- { "USB: Samsung M3 Portable USB 3.0; ", // 1TB
- "0x04e8:0x61b6",
+ { "USB: Samsung D3 Station; ", // 3TB
+ "0x04e8:0x6124",
+ "", // 0x200
+ "",
+ "-d sat"
+ },
+ { "USB: Samsung M3 Portable USB 3.0; ",
+ "0x04e8:0x61b[456]", // 4=2TB, 5=1.5TB, 6=1TB
"", // 0x0e00
"",
"-d sat"
"",
"-d usbjmicron"
},
+ { "USB: Iomega; JMicron",
+ "0x059b:0x047a",
+ "", // 0x0100
+ "",
+ "-d sat" // works also with "-d usbjmicron"
+ },
// LaCie
{ "USB: LaCie hard disk (FA Porsche design);",
"0x059f:0x0651",
},
// Lumberg, Inc.
{ "USB: Toshiba Stor.E; Sunplus",
- "0x0939:0x0b16",
+ "0x0939:0x0b1[56]",
"",
"",
"-d usbsunplus"
"-d sat"
},
{ "USB: Seagate Expansion Portable; ",
- "0x0bc2:0x2300",
+ "0x0bc2:0x23(00|12)",
"",
"",
"-d sat"
"-d sat,12"
},
{ "USB: Seagate Expansion External; ", // 2TB, 3TB
- "0x0bc2:0x33(00|20|32)",
+ "0x0bc2:0x33(00|12|20|32)",
"",
"",
"-d sat"
},
{ "USB: Seagate FreeAgent GoFlex USB 2.0; ",
- "0x0bc2:0x5021",
+ "0x0bc2:0x502[01]",
"",
"",
"-d sat"
"",
"-d sat"
},
+ { "USB: Seagate Backup Plus Slim USB 3.0; ", // (ticket #443)
+ "0x0bc2:0xab24",
+ "", // 0x0100
+ "",
+ "-d sat"
+ },
// Dura Micro
{ "USB: Dura Micro; Cypress",
"0x0c0b:0xb001",
"",
"-d usbcypress"
},
- { "USB: WD My Passport Portable; ",
- "0x1058:0x0702",
- "", // 0x0102
- "",
- "-d sat"
- },
- { "USB: WD My Passport Essential; ",
- "0x1058:0x0704",
- "", // 0x0175
- "",
- "-d sat"
- },
- { "USB: WD My Passport Elite; ",
- "0x1058:0x0705",
- "", // 0x0175
- "",
- "-d sat"
- },
- { "USB: WD My Passport 070A; ",
- "0x1058:0x070a",
- "", // 0x1028
- "",
- "-d sat"
- },
- { "USB: WD My Passport 0730; ",
- "0x1058:0x0730",
- "", // 0x1008
- "",
- "-d sat"
- },
- { "USB: WD My Passport Essential SE USB 3.0; ",
- "0x1058:0x074[02]",
+ { "USB: WD My Passport; ",
+ "0x1058:0x07(0[245a]|30)",
"",
"",
"-d sat"
},
{ "USB: WD My Passport USB 3.0; ",
- "0x1058:0x07[4a]8",
+ "0x1058:0x0(74[0128a]|7a8|820)",
"",
"",
"-d sat"
"-d sat"
},
{ "USB: WD Elements; ",
- "0x1058:0x10(10|a2)",
+ "0x1058:0x10(10|48|a2)",
"", // 0x0105
"",
"-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; ",
"0x1058:0x1100",
"", // 0x0165
"",
"-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",
"0x125f:0xa93a",
"", // 0x0150
"",
"-d sat"
},
+ { "USB: ; Initio",
+ "0x13fd:0x1640",
+ "", // 0x0864
+ "",
+ "-d sat,12" // some SMART commands fail, see ticket #295
+ },
{ "USB: Intenso Memory Station 2,5\"; Initio",
"0x13fd:0x1840",
"",
"-d usbcypress"
},
// JMicron
- { "USB: ; JMicron USB 3.0",
+ { "USB: ; JMicron JMS539", // USB2/3->SATA (old firmware)
"0x152d:0x0539",
- "", // 0x0100
+ "0x0100", // 1.00
"",
"-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)
"0x152d:0x0551",
"", // 0x0100
"",
"-d sat"
},
+ { "USB: ; ASMedia AS2105", // Icy Box IB-AC603A-U3
+ "0x174c:0x5136",
+ "", // 0x0001
+ "",
+ "-d sat"
+ },
// LucidPort
{ "USB: ; LucidPORT USB300", // RaidSonic ICY BOX IB-110StU3-B, Sharkoon SATA QuickPort H3
"0x1759:0x500[02]", // 0x5000: USB 2.0, 0x5002: USB 3.0
"",
"-d sat"
},
+ { "USB: ; LucidPort", // Fuj:tech SATA-USB3 dock
+ "0x1759:0x5100",
+ "", // 0x2580
+ "",
+ "-d sat"
+ },
// Verbatim
{ "USB: Verbatim Portable Hard Drive; Sunplus",
"0x18a5:0x0214",
"",
"-d usbsunplus"
},
+ // TrekStor
+ { "USB: TrekStor DataStation; ", // DataStation maxi light (USB 3.0)
+ "0x1e68:0x0050",
+ "", // 0x0100
+ "",
+ "-d sat"
+ },
// Innostor
{ "USB: ; Innostor IS888", // Sharkoon SATA QuickDeck Pro USB 3.0
"0x1f75:0x0888",
-#!/bin/bash
+#! /bin/sh
#
# This is a script from the smartmontools examplescripts/ directory.
# It can be used as an argument to the -M exec Directive in
# Please see man 8 smartd or man 5 smartd.conf for further
# 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
cat > /root/tempfile
# Run smartctl -a and save output in temp file
/usr/sbin/smartctl -a -d $SMARTD_DEVICETYPE $SMARTD_DEVICE >> /root/tempfile
-# Email the contents of the temp file. Solaris and other OSes
-# may need to use /bin/mailx not /bin/mail.
-/bin/mail -s "SMART errors detected on host: `hostname`" $SMARTD_ADDRESS < /root/tempfile
+# Email the contents of the temp file. Solaris and
+# other OSes may need to use /usr/bin/mailx below.
+/usr/bin/mail -s "SMART errors detected on host: `hostname`" $SMARTD_ADDRESS < /root/tempfile
# And exit
exit 0
-#! /bin/bash
+#! /bin/sh
#
# This is a script from the smartmontools examplescripts/ directory.
# It can be used as an argument to the -M exec Directive in
# Please see man 8 smartd or man 5 smartd.conf for further
# 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:
cat > /root/msg
# Append the output of smartctl -a to the message:
/usr/sbin/smartctl -a -d $SMARTD_DEVICETYPE $SMARTD_DEVICE >> /root/msg
-# Now email the message to the user at address ADD. Solaris and
-# other OSes may need to use /bin/mailx below.
-/bin/mail -s "$SMARTD_SUBJECT" $SMARTD_ADDRESS < /root/msg
+# Now email the message to the user. Solaris and
+# other OSes may need to use /usr/bin/mailx below.
+/usr/bin/mail -s "$SMARTD_SUBJECT" $SMARTD_ADDRESS < /root/msg
-#! /bin/bash
+#! /bin/sh
#
# This is a script from the smartmontools examplescripts/ directory.
# It can be used as an argument to the -M exec Directive in
# Please see man 8 smartd or man 5 smartd.conf for further
# 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
wall <<EOF
#! /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>
S.M.A.R.T. message:
$SMARTD_MESSAGE"
--- /dev/null
+#!/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
+
--- /dev/null
+#! /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
+
# 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) 2009-14 Christian Franke <smartmontools-support@lists.sourceforge.net>
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# version.
#
# 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
-# Franklin Street, Fifth Floor, Boston, 02110-1301 USA.
+# example COPYING). If not, see <http://www.gnu.org/licenses/>.
#
# 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. 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
-m address -M exec /path/to/an/executable
Directive in /etc/smartd.conf.
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
to the email address listed as the argument to the -m
Directive.
Example2: Appends output of smartctl -a to the normal email message
- and sends that to the email address listed as the argument
- to the -m Directive.
+ and sends that to the email address listed as the argument
+ to the -m Directive.
Example3: Uses wall(1) to send a warning message to all users, then powers
down the machine.
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)
/*
- * os_darwin.c
+ * os_darwin.cpp
*
* Home page of code is: http://smartmontools.sourceforge.net
*
* 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
* 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, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * You should have received a copy of the GNU General Public License
+ * along with smartmontools. If not, see <http://www.gnu.org/licenses/>.
+ *
*/
#include <stdbool.h>
#include "atacmds.h"
#include "scsicmds.h"
#include "utility.h"
-
#include "os_darwin.h"
+#include "dev_interface.h"
// 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;
-// Print examples for smartctl.
-void print_smartctl_examples(){
- printf("=================================================== SMARTCTL EXAMPLES =====\n\n");
- printf(
+// examples for smartctl
+static const char smartctl_examples[] =
+ "=================================================== SMARTCTL EXAMPLES =====\n\n"
" smartctl -a disk0 (Prints all SMART information)\n\n"
" smartctl -t long /dev/disk0 (Executes extended disk self-test)\n\n"
#ifdef HAVE_GETOPT_LONG
" (You can use IOService: ...)\n\n"
" smartctl -c IODeviceTree:/pci@f4000000/ata-6@D/@0:0\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
-// for return values.
-int guess_device_type (const char * /* dev_name */) {
- // Only ATA is supported right now, so that's what it'd better be.
- return CONTROLLER_ATA;
+bool darwin_smart_device::is_open() const
+{
+ return (m_fd >= 0);
}
// Determine whether 'dev' is a SMART-capable device.
// If it's an kIOATABlockStorageDeviceClass then we're successful
// only if its ATA features indicate it supports SMART.
if (IOObjectConformsTo (dev, kIOATABlockStorageDeviceClass)
- && (diskChars = (CFDictionaryRef)IORegistryEntryCreateCFProperty
- (dev, CFSTR (kIOPropertyDeviceCharacteristicsKey),
- kCFAllocatorDefault, kNilOptions)) != NULL)
+ && (diskChars = (CFDictionaryRef)IORegistryEntryCreateCFProperty
+ (dev, CFSTR (kIOPropertyDeviceCharacteristicsKey),
+ kCFAllocatorDefault, kNilOptions)) != NULL)
{
CFNumberRef diskFeatures = NULL;
UInt32 ataFeatures = 0;
if (CFDictionaryGetValueIfPresent (diskChars, CFSTR ("ATA Features"),
- (const void **)&diskFeatures))
- CFNumberGetValue (diskFeatures, kCFNumberLongType,
- &ataFeatures);
+ (const void **)&diskFeatures))
+ CFNumberGetValue (diskFeatures, kCFNumberLongType,
+ &ataFeatures);
CFRelease (diskChars);
if (diskFeatures)
- CFRelease (diskFeatures);
+ CFRelease (diskFeatures);
return (ataFeatures & kIOATAFeatureSMART) != 0;
}
return false;
}
-
-// makes a list of ATA or SCSI devices for the DEVICESCAN directive of
-// smartd. Returns number N of devices, or -1 if out of
-// memory. Allocates N+1 arrays: one of N pointers (devlist); the
-// other N arrays each contain null-terminated character strings. In
-// the case N==0, no arrays are allocated because the array of 0
-// pointers has zero length, equivalent to calling malloc(0).
-int make_device_names (char*** devlist, const char* name) {
- 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){
+bool darwin_smart_device::open()
+{
+ // Acceptable device names are:
+ // /dev/disk*
+ // /dev/rdisk*
+ // disk*
+ // IOService:*
+ // IODeviceTree:*
size_t devnum;
const char *devname;
io_object_t disk;
+ const char *pathname = get_dev_name();
+ char *type = const_cast<char*>(m_mode);
if (strcmp (type, "ATA") != 0)
{
// Find this device's parent and try again.
err = IORegistryEntryGetParentEntry (disk, kIOServicePlane, &disk);
if (err != kIOReturnSuccess || ! disk)
- {
- errno = ENODEV;
- IOObjectRelease (prevdisk);
- return -1;
- }
+ {
+ errno = ENODEV;
+ IOObjectRelease (prevdisk);
+ return -1;
+ }
}
devices[devnum].ioob = disk;
// Create an interface to the ATA SMART library.
if (IOCreatePlugInInterfaceForService (disk,
- kIOATASMARTUserClientTypeID,
- kIOCFPlugInInterfaceID,
- &devices[devnum].plugin,
- &dummy) == kIOReturnSuccess)
- (*devices[devnum].plugin)->QueryInterface
- (devices[devnum].plugin,
- CFUUIDGetUUIDBytes ( kIOATASMARTInterfaceID),
- (void **)&devices[devnum].smartIf);
+ kIOATASMARTUserClientTypeID,
+ kIOCFPlugInInterfaceID,
+ &devices[devnum].plugin,
+ &dummy) == kIOReturnSuccess)
+ (*devices[devnum].plugin)->QueryInterface
+ (devices[devnum].plugin,
+ CFUUIDGetUUIDBytes ( kIOATASMARTInterfaceID),
+ (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
-// deviceopen() above.
-int deviceclose(int fd){
+bool darwin_smart_device::close()
+{
+ int fd = m_fd; m_fd = -1;
if (devices[fd].smartIf)
(*devices[fd].smartIf)->Release (devices[fd].smartIf);
if (devices[fd].plugin)
IODestroyPlugInInterface (devices[fd].plugin);
IOObjectRelease (devices[fd].ioob);
devices[fd].ioob = MACH_PORT_NULL;
- return 0;
+ return true;
+}
+
+// makes a list of ATA or SCSI devices for the DEVICESCAN directive of
+// smartd. Returns number N of devices, or -1 if out of
+// memory. Allocates N+1 arrays: one of N pointers (devlist); the
+// other N arrays each contain null-terminated character strings. In
+// the case N==0, no arrays are allocated because the array of 0
+// pointers has zero length, equivalent to calling malloc(0).
+static int make_device_names (char*** devlist, const char* name) {
+ 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] = 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")
+{
}
-// Interface to ATA devices. See os_linux.cpp for the cannonical example.
-// DETAILED DESCRIPTION OF ARGUMENTS
-// device: is the integer handle provided by deviceopen()
-// command: defines the different operations, see atacmds.h
-// select: additional input data IF NEEDED (which log, which type of
-// self-test).
-// data: location to write output data, IF NEEDED (1 or 512 bytes).
-// Note: not all commands use all arguments.
-// RETURN VALUES (for all commands BUT command==STATUS_CHECK)
-// -1 if the command failed
-// 0 if the command succeeded,
-// RETURN VALUES if command==STATUS_CHECK
-// -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:
-// - Tests other than short and extended (in particular, can't run
-// an immediate offline test)
-// - 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,
-// have a buggy library that treats the boolean value in
-// SMARTEnableDisableOperations, SMARTEnableDisableAutosave, and
-// SMARTExecuteOffLineImmediate as always being true.
-int
-ata_command_interface(int fd, smart_command_set command,
- int select, char *data)
+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 *smartIf;
IOReturn err;
int timeoutCount = 5;
+ int rc = 0;
if (! ifp)
return -1;
smartIf = *ifp;
-
+ clear_err(); errno = 0;
do {
- switch (command)
+ switch (in.in_regs.command) {
+ case ATA_IDENTIFY_DEVICE:
{
- case STATUS:
- return 0;
- case STATUS_CHECK:
- {
- Boolean is_failing;
- err = smartIf->SMARTReturnStatus (ifp, &is_failing);
- if (err == kIOReturnSuccess && is_failing)
- return 1;
- break;
- }
- case ENABLE:
- 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?
+ UInt32 dummy;
+ err = smartIf->GetATAIdentifyData (ifp, data, 512, &dummy);
+ if (err != kIOReturnSuccess && err != kIOReturnTimeout
+ && err != kIOReturnNotResponding)
+ printf ("identify failed: %#x\n", (unsigned) rc);
+ 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 ATA_IDENTIFY_PACKET_DEVICE:
+ case ATA_CHECK_POWER_MODE:
+ errno = ENOTSUP;
+ err = -1;
+ break;
+ case ATA_SMART_CMD:
+ 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:
- errno = ENOTSUP;
- return -1;
+ return set_err(ENOSYS, "Unknown SMART command");
}
- /* This bit is a bit strange. Apparently, when the drive is spun
- down, the intended behaviour of these calls is that they fail,
- return kIOReturnTimeout and then power the drive up. So if
- you get a timeout, you have to try again to get the actual
- command run, but the drive is already powering up so you can't
- use this for CHECK_POWER_MODE. */
- if (err == kIOReturnTimeout || err == kIOReturnNotResponding)
- sleep (1);
+ break;
+ default:
+ return set_err(ENOSYS, "Non-SMART commands not implemented");
+ }
} while ((err == kIOReturnTimeout || err == kIOReturnNotResponding)
- && timeoutCount-- > 0);
+ && timeoutCount-- > 0);
if (err == kIOReturnExclusiveAccess)
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;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+/// Implement platform interface
+
+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.
}
-// Interface to SCSI devices. See os_linux.c
-int do_scsi_cmnd_io(int /* fd */, struct scsi_cmnd_io * /* iop */, int /* report */) {
- return -ENOSYS;
+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);
}
#define PATHINQ_SETTINGS_SIZE 128
#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;
#define NO_RETURN 0
: virtual public /*implements*/ smart_device
{
public:
- explicit freebsd_smart_device(const char * mode)
+ explicit freebsd_smart_device()
: smart_device(never_called),
- m_fd(-1), m_mode(mode) { }
+ m_fd(-1) { }
virtual ~freebsd_smart_device() throw();
private:
int m_fd; ///< filedesc, -1 if not open.
- const char * m_mode; ///< Mode string for deviceopen().
};
#ifdef __GLIBC__
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),
- freebsd_smart_device("ATA")
+ freebsd_smart_device()
{
}
}
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);
return -1;
}
freebsd_escalade_device::freebsd_escalade_device(smart_interface * intf, const char * dev_name,
int escalade_type, int disknum)
: smart_device(intf, dev_name, "3ware", "3ware"),
- 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" ),
+ freebsd_smart_device(),
m_escalade_type(escalade_type), m_disknum(disknum)
{
set_info().info_name = strprintf("%s [3ware_disk_%02d]", dev_name, disknum);
freebsd_highpoint_device::freebsd_highpoint_device(smart_interface * intf, const char * dev_name,
unsigned char controller, unsigned char channel, unsigned char port)
: 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;
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]);
virtual bool close();
private:
- int m_fd;
struct cam_device *m_camdev;
};
freebsd_scsi_device::freebsd_scsi_device(smart_interface * intf,
const char * dev_name, const char * 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)
{
- int report=scsi_debugmode;
union ccb *ccb;
- if (report > 0) {
+ if (scsi_debugmode) {
unsigned int k;
const unsigned char * ucp = iop->cmnd;
const char * np;
pout(" [%s: ", np ? np : "<unknown opcode>");
for (k = 0; k < iop->cmnd_len; ++k)
pout("%02x ", ucp[k]);
- if ((report > 1) &&
+ if ((scsi_debugmode > 1) &&
(DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
int trunc = (iop->dxfer_len > 256) ? 1 : 0;
dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
}
else
- pout("]");
+ pout("]\n");
}
if(m_camdev==NULL) {
- warnx("error: camdev=0!");
- return -ENOTTY;
+ if (scsi_debugmode)
+ pout(" error: camdev=0!\n");
+ return set_err(ENOTTY);
}
if (!(ccb = cam_getccb(m_camdev))) {
- warnx("error allocating ccb");
- return -ENOMEM;
+ if (scsi_debugmode)
+ pout(" error allocating ccb\n");
+ return set_err(ENOMEM);
}
+
// mfi SAT layer is known to be buggy
if(!strcmp("mfi",m_camdev->sim_name)) {
if (iop->cmnd[0] == SAT_ATA_PASSTHROUGH_12 || iop->cmnd[0] == SAT_ATA_PASSTHROUGH_16) {
sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
cam_fill_csio(&ccb->csio,
- /*retrires*/ 1,
- /*cbfcnp*/ NULL,
+ /* retries */ 1,
+ /* cbfcnp */ NULL,
/* 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,
/* dataptr */ iop->dxferp,
memcpy(ccb->csio.cdb_io.cdb_bytes,iop->cmnd,iop->cmnd_len);
if (cam_send_ccb(m_camdev,ccb) < 0) {
- warn("error sending SCSI ccb");
- cam_error_print(m_camdev,ccb,CAM_ESF_ALL,CAM_EPF_ALL,stderr);
+ if (scsi_debugmode) {
+ pout(" error sending SCSI ccb\n");
+ cam_error_print(m_camdev,ccb,CAM_ESF_ALL,CAM_EPF_ALL,stderr);
+ }
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)) {
- 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);
- return -EIO;
+ return set_err(EIO);
}
- if (iop->sensep) {
+ iop->resid = ccb->csio.resid;
+ 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;
- memcpy(iop->sensep,&(ccb->csio.sense_data),iop->resp_sense_len);
+ /* 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);
}
-
- iop->scsi_status = ccb->csio.scsi_status;
+ else if (scsi_debugmode)
+ pout(" status=0x%x\n", iop->scsi_status);
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
// this sets PDT to 00h - direct-access block device
if((!strcmp("mfi", m_camdev->sim_name) || !strcmp("mpt", m_camdev->sim_name))
&& iop->cmnd[0] == INQUIRY) {
- if (report > 0) {
- pout("device on %s controller, patching PDT\n", m_camdev->sim_name);
+ if (scsi_debugmode) {
+ pout(" device on %s controller, patching PDT\n", m_camdev->sim_name);
}
iop->dxferp[0] = iop->dxferp[0] & 0xe0;
}
// Areca RAID Controller(SATA Disk)
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"),
- freebsd_smart_device("ATA")
+ freebsd_smart_device()
{
set_disknum(disknum);
set_encnum(encnum);
// Areca RAID Controller(SAS Device)
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"),
- freebsd_smart_device("SCSI")
+ freebsd_smart_device()
{
set_disknum(disknum);
set_encnum(encnum);
freebsd_cciss_device::freebsd_cciss_device(smart_interface * intf,
const char * dev_name, unsigned char disknum)
: smart_device(intf, dev_name, "cciss", "cciss"),
- freebsd_smart_device("SCSI"),
+ freebsd_smart_device(),
m_disknum(disknum)
{
set_info().info_name = strprintf("%s [cciss_disk_%02d]", dev_name, disknum);
*
* Copyright (C) 2003-11 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2003-11 Doug Gilbert <dgilbert@interlog.com>
- * Copyright (C) 2008-12 Hank Wu <hank@areca.com.tw>
- * 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>
+ * Copyright (C) 2008-14 Christian Franke <smartmontools-support@lists.sourceforge.net>
*
- * 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>
* 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>
*
* Copyright (C) 1999-2003 3ware Inc.
#include "utility.h"
#include "cciss.h"
#include "megaraid.h"
+#include "aacraid.h"
#include "dev_interface.h"
#include "dev_ata_cmd_set.h"
#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;
extern unsigned char failuretest_permissive;
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
}
// did we find too many paths?
- const int max_pathc = 32;
+ const int max_pathc = 1024;
int n = (int)globbuf.gl_pathc;
if (n > max_pathc) {
pout("glob(3) found %d > MAX=%d devices matching pattern %s: ignoring %d paths\n",
if (sscanf(type, "megaraid,%d", &disknum) == 1) {
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;
}
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
", cciss,N"
#endif
*
* 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>
*
* This program is free software; you can redistribute it and/or modify
#define SELECT_WIN_32_64(x32, x64) (x64)
#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
: virtual public /*extends*/ smart_device
{
public:
- /// Get phy info
- bool get_phy_info(CSMI_SAS_PHY_INFO & phy_info);
-
- /// Check physical drive existence
- bool check_phy(const CSMI_SAS_PHY_INFO & phy_info, unsigned phy_no);
+ /// Get bitmask of used ports
+ unsigned get_ports_used();
protected:
csmi_device()
: smart_device(never_called)
{ 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
- bool select_phy(unsigned phy_no);
+ bool select_port(int port);
/// Get info for selected physical drive
const CSMI_SAS_PHY_ENTITY & get_phy_ent() const
private:
HANDLE m_fh; ///< Controller device handle
- unsigned m_phy_no; ///< Physical drive number
+ int m_port; ///< Port number
};
win_csmi_device test_dev(this, name, "");
if (!test_dev.open_scsi())
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;
- for (int pi = 0; pi < phy_info.bNumberOfPhys; pi++) {
- if (!test_dev.check_phy(phy_info, pi))
+ for (int pi = 0; pi < 32; pi++) {
+ if (!(ports_used & (1 << pi)))
continue;
snprintf(name, sizeof(name)-1, "/dev/csmi%d,%d", i, pi);
devlist.push_back( new win_csmi_device(this, name, "ata") );
return false;
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);
if (scsi_debugmode > 1) {
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_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(" Type: 0x%02x, 0x%02x\n", id.bDeviceType, at.bDeviceType);
pout(" InitProto: 0x%02x, 0x%02x\n", id.bInitiatorPortProtocol, at.bInitiatorPortProtocol);
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
- if (phy_no >= phy_info.bNumberOfPhys)
- return set_err(ENOENT, "Port %u does not exist (#ports: %d)", phy_no,
- phy_info.bNumberOfPhys);
+ CSMI_SAS_PHY_INFO phy_info;
+ if (!get_phy_info(phy_info))
+ return 0;
- const CSMI_SAS_PHY_ENTITY & phy_ent = phy_info.Phy[phy_no];
- if (phy_ent.Attached.bDeviceType == CSMI_SAS_NO_DEVICE_ATTACHED)
- return set_err(ENOENT, "No device on port %u", 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;
+ }
- switch (phy_ent.Attached.bTargetPortProtocol) {
- case CSMI_SAS_PROTOCOL_SATA:
- case CSMI_SAS_PROTOCOL_STP:
- break;
- default:
- return set_err(ENOENT, "No SATA device on port %u (protocol: %u)",
- phy_no, phy_ent.Attached.bTargetPortProtocol);
+ if (pe.bPortIdentifier == 0xff)
+ // Older (<= 9.*) Intel RST driver
+ ports_used |= (1 << i);
+ else
+ ports_used |= (1 << pe.bPortIdentifier);
}
- return true;
+ return ports_used;
}
-bool csmi_device::select_phy(unsigned phy_no)
+
+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 (!check_phy(phy_info, phy_no))
- return false;
+ 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;
+ }
- m_phy_ent = phy_info.Phy[phy_no];
+ 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)
+ return set_err(ENOENT, "No device on port %d", port);
+
+ switch (phy_ent.Attached.bTargetPortProtocol) {
+ case CSMI_SAS_PROTOCOL_SATA:
+ case CSMI_SAS_PROTOCOL_STP:
+ break;
+ default:
+ return set_err(ENOENT, "No SATA device on port %d (protocol: %d)",
+ port, phy_ent.Attached.bTargetPortProtocol);
+ }
+
+ m_phy_ent = phy_ent;
return true;
}
win_csmi_device::win_csmi_device(smart_interface * intf, const char * dev_name,
const char * 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)
{
}
bool win_csmi_device::open_scsi()
{
// 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());
- if (!( sscanf(name, "csmi%u,%u%n", &contr_no, &phy_no, &nc) >= 0
- && nc == (int)strlen(name) && contr_no <= 9 && phy_no < 32) )
+ if (!( sscanf(name, "csmi%u,%u%n", &contr_no, &port, &nc) >= 0
+ && nc == (int)strlen(name) && contr_no <= 9 && port < 32) )
return set_err(EINVAL);
// Open controller handle
pout(" %s: successfully opened\n", devpath);
m_fh = h;
- m_phy_no = phy_no;
+ m_port = port;
return true;
}
return false;
// Get Phy info for this drive
- if (!select_phy(m_phy_no)) {
+ if (!select_port(m_port)) {
close();
return false;
}
} else
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;
else
iop->resid = 0;
if ((iop->dxfer_dir == DXFER_FROM_DEVICE) && (report > 1)) {
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]" : ""));
dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
}
} else
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;
else
iop->resid = 0;
if ((iop->dxfer_dir == DXFER_FROM_DEVICE) && (report > 1)) {
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]" : ""));
dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
}
*
* 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
* it under the terms of the GNU General Public License as published by
#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;
#include <stdio.h>
#include <crtdbg.h>
#endif
-#ifndef SERVICE_CONFIG_DELAYED_AUTO_START_INFO
-// Missing in older MinGW headers
-#define SERVICE_CONFIG_DELAYED_AUTO_START_INFO 3
-#endif
-
/////////////////////////////////////////////////////////////////////////////
if ( GetVersionExA(&ver)
&& ver.dwPlatformId == VER_PLATFORM_WIN32_NT
&& ver.dwMajorVersion >= 6 /* Vista */ ) {
- SERVICE_DELAYED_AUTO_START_INFO sdasi = { TRUE };
- ChangeServiceConfig2A(hs, SERVICE_CONFIG_DELAYED_AUTO_START_INFO, &sdasi);
+ // SERVICE_{,CONFIG_}DELAYED_AUTO_START_INFO are missing in older MinGW headers
+ 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 {
;
; 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
; it under the terms of the GNU General Public License as published by
; You should have received a copy of the GNU General Public License
; (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 $
;
CreateDirectory "$INSTDIR"
- ; Save installation location
- WriteRegStr HKLM "Software\smartmontools" "Install_Dir" "$INSTDIR"
+ ; Keep old Install_Dir registry entry for GSmartControl
+ 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
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "DisplayName" "smartmontools"
!ifdef VERSTR
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "DisplayVersion" "${VERSTR}"
!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" "URLInfoAbout" "http://smartmontools.sourceforge.net/"
- WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "HelpLink" "http://smartmontools.sourceforge.net/"
- ;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" "URLUpdateInfo" "http://smartmontools-win32.dyndns.org/"
+ WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "Publisher" "smartmontools.org"
+ WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "URLInfoAbout" "http://www.smartmontools.org/"
+ 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.no-ip.org/"
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "NoModify" 1
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "NoRepair" 1
WriteUninstaller "uninst-smartmontools.exe"
CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\ChangeLog.lnk" "$INSTDIR\doc\ChangeLog.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\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:
; 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
IfFileExists "$INSTDIR\bin\update-smart-drivedb.exe" 0 noupdb
; Set default install directories
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"
StrCmp $INSTDIR "" 0 endinst ; Already installed ?
StrCpy $INSTDIR "$PROGRAMFILES\smartmontools"
//
// 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
VALUE "FileDescription", "Control and Monitor Utility for SMART Disks"
VALUE "FileVersion", "@TEXT_VERSION@"
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 "ProductName", "smartmontools"
VALUE "ProductVersion", "@TEXT_VERSION@"
//
// 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
VALUE "FileDescription", "SMART Disk Monitoring Daemon"
VALUE "FileVersion", "@TEXT_VERSION@"
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 "ProductName", "smartmontools"
VALUE "ProductVersion", "@TEXT_VERSION@"
#include "dev_ata_cmd_set.h" // ata_device_with_command_set
#include "dev_tunnelled.h" // tunnelled_device<>
-const char * scsiata_cpp_cvsid = "$Id: scsiata.cpp 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.
The addition is to allow the 0x70 and 0x71 response codes. The idea
memset(&io_hdr, 0, sizeof(io_hdr));
bool rwbit = true;
- unsigned char smart_status = 0;
+ unsigned char smart_status = 0xff;
bool is_smart_status = ( in.in_regs.command == ATA_SMART_CMD
&& in.in_regs.features == ATA_SMART_STATUS);
if (in.out_needed.is_set()) {
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) {
- case 0x01: case 0xc2:
+ case 0xc2:
out.out_regs.lba_high = 0xc2;
out.out_regs.lba_mid = 0x4f;
break;
- case 0x00: case 0x2c:
+ case 0x2c:
out.out_regs.lba_high = 0x2c;
out.out_regs.lba_mid = 0xf4;
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);
}
}
#include "dev_interface.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;
// Print SCSI debug messages?
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;
memset(b, 0, sizeof(b));
if (offset < 0)
return -EINVAL;
memcpy(rout, iecp->raw_curr, SCSI_IECMP_RAW_LEN);
+ /* mask out DPOFUA device specific (disk) parameter bit */
if (10 == iecp->modese_len) {
resp_len = (rout[0] << 8) + rout[1] + 2;
- rout[3] &= 0xef; /* for disks mask out DPOFUA bit */
+ rout[3] &= 0xef;
} else {
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 */
if (enabled) {
* RIGID_DISK_DRIVE_GEOMETRY_PAGE mode page. */
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;
UINT8 buff[64];
speed = (buff[4] << 8) + buff[5];
if (form_factorp)
*form_factorp = buff[7] & 0xf;
+ if (haw_zbcp)
+ *haw_zbcp = !!(0x10 & buff[8]);
return speed;
}
if (form_factorp)
*form_factorp = 0;
+ if (haw_zbcp)
+ *haw_zbcp = 0;
if (modese_len <= 6) {
if ((err = scsiModeSense(device, RIGID_DISK_DRIVE_GEOMETRY_PAGE, 0, pc,
buff, sizeof(buff)))) {
buff[offset + 2] &= 0xfe; // clear bit
}
+ /* mask out DPOFUA device specific (disk) parameter bit */
if (10 == modese_len) {
resp_len = (buff[0] << 8) + buff[1] + 2;
- buff[3] &= 0xef; /* for disks mask out DPOFUA bit */
+ buff[3] &= 0xef;
} else {
resp_len = buff[0] + 1;
- buff[2] &= 0xef; /* for disks mask out DPOFUA bit */
+ buff[2] &= 0xef;
}
sp = 0; /* Do not change saved values */
if (10 == modese_len)
if (err)
return err;
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) {
resp_len = (buff[0] << 8) + buff[1] + 2;
- buff[3] &= 0xef; /* for disks mask out DPOFUA bit */
+ buff[3] &= 0xef;
} else {
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 */
if (enabled)
#ifndef 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 <stdlib.h>
int scsiFetchControlGLTSD(scsi_device * device, int modese_len, int current);
int scsiSetControlGLTSD(scsi_device * device, int enabled, 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,
short int * rcd);
uint64_t scsiGetSize(scsi_device * device, unsigned int * lb_sizep,
#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;
ull <<= 8;
ull |= xp[j];
}
- pout(" = %"PRIu64"\n", ull);
+ pout(" = %" PRIu64 "\n", ull);
num -= pl;
ucp += pl;
}
if (0 == pc)
pout(" = %.2f\n", ull / 60.0 );
else
- pout(" = %"PRIu64"\n", ull);
+ pout(" = %" PRIu64 "\n", ull);
}
num -= pl;
ucp += pl;
if (! found[k])
continue;
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],
ecp->counter[2], ecp->counter[3], ecp->counter[4]);
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
NON_MEDIUM_ERROR_LPAGE, 0, gBuf, LOG_RESP_LEN, 0))) {
scsiDecodeNonMediumErrPage(gBuf, &nme);
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)
- pout("Track following error count [Hitachi]: %8"PRIu64"\n",
+ pout("Track following error count [Hitachi]: %8" PRIu64 "\n",
nme.counterTFE_H);
if (nme.gotPE_H)
- pout("Positioning error count [Hitachi]: %8"PRIu64"\n",
+ pout("Positioning error count [Hitachi]: %8" PRIu64 "\n",
nme.counterPE_H);
}
if (gLastNErrorLPage && (0 == scsiLogSense(device,
char buff[32];
// was hex but change to decimal to conform with ATA
- snprintf(buff, sizeof(buff), "%"PRIu64, ull);
- // snprintf(buff, sizeof(buff), "0x%"PRIx64, ull);
+ snprintf(buff, sizeof(buff), "%" PRIu64, ull);
+ // snprintf(buff, sizeof(buff), "0x%" PRIx64, ull);
pout("%18s", buff);
} else
pout(" -");
else
if ((0 == scsiFetchExtendedSelfTestTime(device, &durationSec,
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);
}
pout("\n");
case 1:
if (pl < 8) {
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();
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 */
break;
}
t = ((0x70 & vcp[4]) >> 4);
switch (t) {
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 3: snprintf(s, sz, "expander device (fanout)"); break;
default: snprintf(s, sz, "reserved [%d]", t); break;
case 8: snprintf(s, sz, "phy enabled; 1.5 Gbps"); break;
case 9: snprintf(s, sz, "phy enabled; 3 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;
}
pout(" negotiated logical link rate: %s\n", s);
}
-// See Serial Attached SCSI (SAS-2) (e.g. revision 16) the Protocol Specific
-// log pageSerial Attached SCSI (SAS-2) (e.g. revision 16) the Protocol
-// 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.
+// See Serial Attached SCSI (SPL-3) (e.g. revision 6g) the Protocol Specific
+// log page [0x18]. Returns 0 if ok else FAIL* bitmask.
static int
scsiPrintSasPhy(scsi_device * device, int reset)
{
"enclosure",
"simplified disk",
"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[] = {
"IEEE 1394 (SBP-2)",
"RDMA (SRP)",
"iSCSI",
- "SAS",
+ "SAS (SPL-3)",
"ADT",
- "0x8",
- "0x9",
- "0xa",
+ "ATA (ACS-2)",
+ "UAS",
+ "SOP",
"0xb",
"0xc",
"0xd",
{
char timedatetz[DATEANDEPOCHLEN];
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 peri_dt = 0;
int returnval = 0;
int transport = -1;
int form_factor = 0;
+ int haw_zbc = 0;
int protect = 0;
memset(gBuf, 0, 96);
print_off();
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))) {
char vendor[8+1], product[16+1], revision[4+1];
pout("Product: %.16s\n", product);
if (gBuf[32] >= ' ')
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*/ &&
(lb_size * (1 << lb_per_pb_exp)));
pout("Physical block size: %s bytes\n", lb_str);
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 */
int p_type = ((rc16_12[0] >> 1) & 0x7);
lbprz = !! (lb_prov_resp[5] & 0x4);
switch (prov_type) {
case 0:
- pout("Logical block provisioning type unreported, "
- "LBPME=%d, LBPRZ=%d\n", lbpme, lbprz);
+ pout("LB provisioning type: unreported, LBPME=%d, LBPRZ=%d\n",
+ lbpme, lbprz);
break;
case 1:
pout("LU is resource provisioned, LBPRZ=%d\n", lbprz);
} else if (1 == lbpme)
pout("Logical block provisioning enabled, LBPRZ=%d\n", lbprz);
- int rpm = scsiGetRPM(device, modese_len, &form_factor);
- if (rpm > 0) {
- if (1 == rpm)
+ int rpm = scsiGetRPM(device, modese_len, &form_factor, &haw_zbc);
+ if (rpm >= 0) {
+ if (0 == rpm)
+ ; // Not reported
+ else if (1 == rpm)
pout("Rotation Rate: Solid State Device\n");
+ else if ((rpm <= 0x400) || (0xffff == rpm))
+ ; // Reserved
else
pout("Rotation Rate: %d rpm\n", rpm);
}
if (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
pout("Self Test returned without error\n");
any_output = true;
}
- if (options.sasphy) {
+ if (options.sasphy && gProtocolSpecificLPage) {
if (scsiPrintSasPhy(device, options.sasphy_reset))
return returnval | FAILSMART;
any_output = true;
.ig
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
it under the terms of the GNU General Public License as published by
.SH SYNOPSIS
.B smartctl [options] device
-.\" %IF NOT OS Windows
-.SH FULL PATH
-.B /usr/local/sbin/smartctl
-
-.\" %ENDIF NOT OS Windows
.SH PACKAGE VERSION
CURRENT_SVN_VERSION CURRENT_SVN_DATE CURRENT_SVN_REV
self-tests.
\fBsmartctl\fP also supports some features not related to SMART.
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).
\fBsmartctl\fP also provides support for polling TapeAlert messages
displayed with a leading \fB"0x"\fP, for example: "0xff". This man
page follows the same convention.
-.PP
.SH OPTIONS
-.PP
The options are grouped below into several categories. \fBsmartctl\fP
will execute the corresponding commands in the order: INFORMATION,
ENABLE/DISABLE, DISPLAY DATA, RUN/ABORT TESTS.
specified, the power mode of the drive is printed.
.TP
.B \-\-identify[=[w][nvb]]
-[ATA only] [NEW EXPERIMENTAL SMARTCTL FEATURE] Prints an annotated
-table of the IDENTIFY DEVICE data.
+[ATA only] Prints an annotated table of the IDENTIFY DEVICE data.
By default, only valid words (words not equal to 0x0000 or 0xffff)
and nonzero bits and bit fields are printed.
This can be changed by the optional argument which consists of one or
number.
The following entry in /proc/devices must exist:
-.fi
+.br
For PERC2/3/4 controllers: \fBmegadevN\fP
-.fi
+.br
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
.\" %IF OS FreeBSD Linux
.I 3ware,N
"Obsolete" in every version of the ATA and ATA/ATAPI Specifications.
It was originally part of the SFF-8035i Revision 2.0 specification,
but was never part of any ATA specification. However it is
-implemented and used by many vendors. [Good documentation can be found
-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.]
+implemented and used by many vendors.
You can tell if automatic offline testing is supported by seeing if
this command enables and disables it, as indicated by the \'Auto
Offline Data Collection\' part of the SMART capabilities report
ATA specification but are in common use nonetheless; these are marked
\fB[NS]\fP, meaning non-standard.
-The ATA Specification (ATA-5 Revision 1c, Section 8.41.6.8.2) says:
-\fB"Error log structures shall include UNC errors, IDNF errors for
-which the address requested was valid, servo errors, write fault
-errors, etc. Error log data structures shall not include errors
-attributed to the receipt of faulty commands such as command codes not
-implemented by the device or requests with invalid parameters or
-invalid addresses."\fP The definitions of these terms are:
+The ATA Specification (ATA ACS-2 Revision 7, Section A.7.1) says:
+\fB"Error log data structures shall include, but are not limited to,
+Uncorrectable errors, ID Not Found errors for which the LBA requested was
+valid, servo errors, and write fault errors. Error log data structures
+shall not include errors attributed to the receipt of faulty commands."\fP
+The definitions of these terms are:
.br
\fBUNC\fP (\fBUNC\fPorrectable): data is uncorrectable. This refers
to data which has been read from the disk, but for which the Error
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
up to 4 log entries. The actual number of log sectors is vendor
-specific, typical values for HDD are 2 (Samsung), 5 (Seagate) or
-6 (WD).
+specific.
Only the 8 most recent error log entries are printed by default.
This number can be changed by the optional parameter NUM.
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.
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
can be changed by the optional parameter NUM.
.I scterc[,READTIME,WRITETIME]
\- [ATA only] prints values and descriptions of the SCT Error Recovery
Control settings. These are equivalent to TLER (as used by Western
-Digital), CCTL (as used by Samsung and Hitachi) and ERC (as used by
+Digital), CCTL (as used by Samsung and Hitachi/HGST) and ERC (as used by
Seagate). READTIME and WRITETIME arguments (deciseconds) set the
specified values. Values of 0 disable the feature, other values less
than 65 are probably not supported. For RAID configurations, this is
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,
the list of supported pages is printed. Device Statistics was
-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).
+introduced in ACS-2 and is only supported by some recent devices.
.I sataphy[,reset]
\- [SATA only] prints values and descriptions of the SATA Phy Event
.I 220,temp
\- same as:
.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
.B \-F TYPE, \-\-firmwarebug=TYPE
[ATA only] Modifies the behavior of \fBsmartctl\fP to compensate for some
.I none
\- Assume that the device firmware obeys the ATA specifications. This
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.
.I nologdir
.I xerrorlba
\- 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.
.I swapid
that are available for this drive. By default, if the drive is recognized
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
.I show
will show any preset options for your drive and the argument
\fBWARNING: Only run subcommands documented by the vendor of the
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
related SMART attributes (226, 227, 228). Note that the raw values of
these attributes are held at 65535 (0xffff) until the workload timer
Aborts non-captive SMART Self Tests. Note that this
command will abort the Offline Immediate Test routine only if your
disk has the "Abort Offline collection upon new command" capability.
-.PP
+
.SH ATA, SCSI command sets and SAT
In the past there has been a clear distinction between storage devices
that used the ATA and SCSI command sets. This distinction was often
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
browser.
-.PP
+
.SH EXAMPLES
.nf
.B smartctl \-a /dev/hda
.fi
Examine all SMART data for the first SCSI disk connected to a cciss
RAID controller card.
-.PP
+
.SH RETURN VALUES
The return values of \fBsmartctl\fP are defined by a bitmask. If all
is well with the disk, the return value (exit status) of
self-test are ignored.
.PP
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
-is bash syntax):
+turned on or off, you can use the following type of construction
+(which should work with any POSIX compatible shell):
.nf
.B smartstat=$(($? & 8))
.fi
(since 8=2^3). The shell variable
$smartstat will be nonzero if SMART status check returned "disk
failing" and zero otherwise.
-
-This bash script prints all status bits:
+.PP
+This shell script prints all status bits:
.nf
-status=$?
-for ((i=0; i<8; i++)); do
- echo "Bit $i: $((status & 2**i && 1))"
+val=$?; mask=1
+for i in 0 1 2 3 4 5 6 7; do
+ echo "Bit $i: $(((val & mask) && 1))"
+ mask=$((mask << 1))
done
.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
The TapeAlert log page flags are cleared for the initiator when the
page is read. This means that each alert condition is reported only
once by \fBsmartctl\fP for each initiator for each activation of the
condition.
-.PP
.SH AUTHORS
\fBBruce Allen\fP
.br
.br
\fBsmartmontools\-support@lists.sourceforge.net\fP
-.PP
-.SH CONTRIBUTORS
The following have made large contributions to smartmontools:
-.nf
+.br
\fBCasper Dik\fP (Solaris SCSI interface)
+.br
\fBDouglas Gilbert\fP (SCSI subsystem)
+.br
\fBGuido Guenther\fP (Autoconf/Automake packaging)
+.br
\fBGeoffrey Keating\fP (Darwin ATA interface)
+.br
\fBEduard Martinescu\fP (FreeBSD interface)
+.br
\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)
+.br
\fBKeiji Sawada\fP (Solaris ATA interface)
+.br
\fBManfred Schwarb\fP (Drive database)
+.br
\fBSergey Svishchev\fP (NetBSD interface)
+.br
\fBDavid Snyder and Sergey Svishchev\fP (OpenBSD interface)
+.br
\fBPhil Williams\fP (User interface and drive database)
+.br
\fBYuri Dario\fP (OS/2, eComStation interface)
+.br
\fBShengfeng Zhou\fP (Linux/FreeBSD HighPoint RocketRAID interface)
-.fi
+.br
Many other individuals have made smaller contributions and corrections.
-.PP
-.SH CREDITS
-.fi
-This code was derived from the smartsuite package, written by Michael
-Cornwell, and from the previous UCSC smartsuite package. It extends
-these to cover ATA-5 disks. This code was originally developed as a
+The first smartmontools code was derived from the smartsuite package,
+written by Michael Cornwell, and from the previous UCSC smartsuite package.
+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), \fBbadblocks\fP(8), \fBide\-smart\fP(8).
-.SH
-REFERENCES FOR SMART
-.fi
+.SH SEE ALSO
+\fBsmartd\fP(8), \fBupdate-smart-drivedb\fP(8).
+
+.SH REFERENCES
+Please see the following web site for more info:
+\fBhttp://smartmontools.sourceforge.net/\fP
+
An introductory article about smartmontools is \fIMonitoring Hard
Disks with SMART\fP, by Bruce Allen, Linux Journal, January 2004,
pages 74-77. This is \fBhttp://www.linuxjournal.com/article/6983\fP
specification Revision 4b. This documents the SMART functionality which the
\fBsmartmontools\fP utilities provide access to.
-.fi
The functioning of SMART was originally defined by the SFF-8035i
revision 2 and the SFF-8055i revision 1.4 specifications. These are
publications of the Small Form Factors (SFF) Committee.
Links to these and other documents may be found on the Links page of the
-\fBsmartmontools\fP Wiki at
-\fBhttp://sourceforge.net/apps/trac/smartmontools/wiki/Links\fP .
+\fBsmartmontools\fP Wiki at \fBhttp://www.smartmontools.org/wiki/Links\fP .
-.SH
-SVN ID OF THIS PAGE:
-$Id: smartctl.8.in 3832 2013-07-20 14:49:31Z chrfranke $
+.SH SVN ID OF THIS PAGE
+$Id: smartctl.8.in 3965 2014-07-20 14:46:41Z chrfranke $
* Home page of code is: http://smartmontools.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>
*
* This program is free software; you can redistribute it and/or modify
#include <stdio.h>
#include <sys/types.h>
#include <string.h>
+#include <stdlib.h>
#include <stdarg.h>
#include <stdexcept>
#include <getopt.h>
#include "smartctl.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;
// Globals to control printing
} else {
if (ataopts.smart_selective_args.num_spans >= 5 || 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);
} else {
snprintf(extraerror, sizeof(extraerror),"ERROR: No more than five selective self-test spans may be"
// Main program without exception handling
static int main_worker(int argc, char **argv)
{
- // Throw if CPU endianess does not match compile time test.
- check_endianness();
+ // Throw if runtime environment does not match compile time test.
+ check_config();
// Initialize interface
smart_interface::init();
.ig
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
it under the terms of the GNU General Public License as published by
.SH SYNOPSIS
.B smartd [options]
-.\" %IF NOT OS Windows
-.SH FULL PATH
-.B /usr/local/sbin/smartd
-
-.\" %ENDIF NOT OS Windows
.SH PACKAGE VERSION
CURRENT_SVN_VERSION CURRENT_SVN_DATE CURRENT_SVN_REV
and predict drive failures, and to carry out different types of drive
self-tests.
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).
\fBsmartd\fP will attempt to enable SMART monitoring on ATA devices
If the configuration file is subsequently modified, \fBsmartd\fP
can be told to re-read the configuration file by sending it a
\fBHUP\fP signal, for example with the command:
-.fi
+.br
\fBkillall -HUP smartd\fP.
-.fi
+.br
.\" %IF OS Windows
(Windows: See NOTES below.)
.\" %ENDIF OS Windows
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).
-.SH
-OPTIONS
-
+.SH OPTIONS
.TP
.B \-A PREFIX, \-\-attributelog=PREFIX
Writes \fBsmartd\fP attribute information (normalized and raw
.\" %IF ENABLE_CAPABILITIES
.TP
.B \-C, \-\-capabilities
-Use \fBcapabilities(7)\fP.
+Use \fBcapabilities\fP(7).
Warning: Mail notification does not work when used.
.\" %ENDIF ENABLE_CAPABILITIES
.B \-d, \-\-debug
Runs \fBsmartd\fP in "debug" mode. In this mode, it displays status
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
information about what it is doing than when operating in "daemon"
mode. In this mode, the \fBINT\fP signal (normally generated from a
.B \-D, \-\-showdirectives
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.
-These Directives are also described later in this man page. They may
-appear in the configuration file following the device name.
+These Directives are described in the \fBsmartd.conf\fP(5) man page.
+They may appear in the configuration file following the device name.
.TP
.B \-h, \-\-help, \-\-usage
Prints usage message to STDOUT and exits.
.B killall -USR1 smartd
.fi
for the same purpose.
-.fi
+.br
.\" %IF OS Windows
(Windows: See NOTES below.)
.\" %ENDIF OS Windows
\fIdaemon\fP.
If you would like to have \fBsmartd\fP messages logged somewhere other
-than the default location, this can typically be accomplished with
-(for example) the following steps:
-.RS 7
-.IP \fB[1]\fP 4
-Modify the script that starts \fBsmartd\fP to include the \fBsmartd\fP
-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 \&
+than the default location, include (for example) \'\-l local3\' in its
+start up argument list.
+Tell the syslog daemon to log all messages from facility \fBlocal3\fP
+to (for example) \'/var/log/smartd.log\'.
+
For more detailed information, please refer to the man pages for
-\fBsyslog.conf\fP, \fBsyslogd\fP, and \fBsyslog\fP. You may also want
-to modify the log rotation configuration files; see the man pages for
-\fBlogrotate\fP and examine your system\'s /etc/logrotate.conf file.
+the local syslog daemon, typically \fBsyslogd\fP(8), \fBsyslog-ng\fP(8)
+or \fBrsyslogd\fP(8).
.\" %IF OS Cygwin
Cygwin: If no \fBsyslogd\fP is running, the \'\-l\' option has no effect.
Please include this information if you are reporting bugs or problems.
.SH EXAMPLES
-
-.B
-smartd
-.fi
+.B smartd
+.br
Runs the daemon in forked mode. This is the normal way to run
\fBsmartd\fP.
Entries are logged to SYSLOG.
-.B
-smartd -d -i 30
-.fi
+.B smartd -d -i 30
+.br
Run in foreground (debug) mode, checking the disk status
every 30 seconds.
-.B
-smartd -q onecheck
-.fi
+.B smartd -q onecheck
+.br
Registers devices, and checks the status of the devices exactly
-once. The exit status (the bash
+once. The exit status (the shell
.B $?
variable) will be zero if all went well, and nonzero if no devices
were detected or some other problem was encountered.
-.fi
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
stopping the daemon via the normal init interface. Using this script,
.nf
.B /usr/local/etc/rc.d/init.d/smartd stop
.fi
+
.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
\fBsmartd\fP
will make log entries at loglevel
.\" %ENDIF OS Windows
.SH LOG TIMESTAMP TIMEZONE
-
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
using either the environment variable \'\fBTZ\fP\' or using a
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
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,
\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
time-zone is set using the \'\fBTZ\fP\' variable (or a file that it
points to).
-
.SH RETURN VALUES
The return value (exit status) of
\fBsmartd\fP
\fBsmartd\fP
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
\fBBruce Allen\fP
.br
.br
\fBsmartmontools\-support@lists.sourceforge.net\fP
-.PP
-.SH CONTRIBUTORS
The following have made large contributions to smartmontools:
-.nf
+.br
\fBCasper Dik\fP (Solaris SCSI interface)
+.br
\fBDouglas Gilbert\fP (SCSI subsystem)
+.br
\fBGuido Guenther\fP (Autoconf/Automake packaging)
+.br
\fBGeoffrey Keating\fP (Darwin ATA interface)
+.br
\fBEduard Martinescu\fP (FreeBSD interface)
+.br
\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)
+.br
\fBKeiji Sawada\fP (Solaris ATA interface)
+.br
\fBManfred Schwarb\fP (Drive database)
+.br
\fBSergey Svishchev\fP (NetBSD interface)
+.br
\fBDavid Snyder and Sergey Svishchev\fP (OpenBSD interface)
+.br
\fBPhil Williams\fP (User interface and drive database)
+.br
\fBShengfeng Zhou\fP (Linux/FreeBSD HighPoint RocketRAID interface)
-.fi
+.br
Many other individuals have made smaller contributions and corrections.
-.PP
-.SH CREDITS
-.fi
-This code was derived from the smartsuite package, written by Michael
-Cornwell, and from the previous UCSC smartsuite package. It extends
-these to cover ATA-5 disks. This code was originally developed as a
+The first smartmontools code was derived from the smartsuite package,
+written by Michael Cornwell, and from the previous UCSC smartsuite package.
+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.conf\fP(5), \fBsmartctl\fP(8), \fBsyslogd\fP(8),
-\fBsyslog.conf\fP(5), \fBbadblocks\fP(8), \fBide\-smart\fP(8), \fBregex\fP(7).
+.SH SEE ALSO
+\fBsmartd.conf\fP(5), \fBsmartctl\fP(8), \fBupdate-smart-drivedb\fP(8).
+
+.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
Disks with SMART\fP, by Bruce Allen, Linux Journal, January 2004,
pages 74-77. This is \fBhttp://www.linuxjournal.com/article/6983\fP
specification Revision 4b. This documents the SMART functionality which the
\fBsmartmontools\fP utilities provide access to.
-.fi
The functioning of SMART was originally defined by the SFF-8035i
revision 2 and the SFF-8055i revision 1.4 specifications. These are
publications of the Small Form Factors (SFF) Committee.
Links to these and other documents may be found on the Links page of the
-\fBsmartmontools\fP Wiki at
-\fBhttp://sourceforge.net/apps/trac/smartmontools/wiki/Links\fP .
+\fBsmartmontools\fP Wiki at \fBhttp://www.smartmontools.org/wiki/Links\fP .
-.SH
-SVN ID OF THIS PAGE:
-$Id: smartd.8.in 3799 2013-03-15 17:47:25Z chrfranke $
+.SH SVN ID OF THIS PAGE
+$Id: smartd.8.in 3965 2014-07-20 14:46:41Z chrfranke $
.ig
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
it under the terms of the GNU General Public License as published by
.SH NAME
\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
CURRENT_SVN_VERSION CURRENT_SVN_DATE CURRENT_SVN_REV
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
\fBend\fP a continuation line.
-.PP 0
-.fi
+.PP
+
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
of the
.B # device, four SATA disks connected to an Areca
.B # RAID controller, and one SATA disk.
.B #
-.nf
.B # First ATA disk on two different interfaces. On
.B # the second disk, start a long self-test every
.B # Sunday between 3 and 4 am.
.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 #
-.nf
.B # SCSI disks. Send a TEST warning email to admin on
.B # startup.
.B #
.B \ \ /dev/sda
.B \ \ /dev/sdb -m admin@example.com -M test
.B #
-.nf
.B # Strange device. It\'s SCSI. Start a scheduled
.B # long self test between 5 and 6 am Monday/Thursday
.B \ \ /dev/weird -d scsi -s L/../../(1|4)/05
.B #
-.nf
.B # An ATA disk may appear as a SCSI device to the
.B # OS. If a SCSI to ATA Translation (SAT) layer
.B # is between the OS and the device then this can be
.B # environments.
.B \ \ /dev/sda -a -d sat
.B #
-.nf
.\" %IF OS Linux
.B # Three disks connected to a MegaRAID controller
.B # Start short self-tests daily between 1-2, 2-3, and
.B \ \ /dev/sda -d megaraid,1 -a -s S/../.././02
.B \ \ /dev/sda -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 #
.\" %ENDIF OS Linux
-.nf
.B # Four ATA disks on a 3ware 6/7/8000 controller.
.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 \ \ /dev/sdd -d 3ware,2 -a -s S/../.././02
.B \ \ /dev/sdd -d 3ware,3 -a -s S/../.././03
.B #
-.nf
.B # Two ATA disks on a 3ware 9000 controller.
.B # Start long self-tests Sundays between midnight and
.B # 1am and 2-3 am
.B \ \ /dev/twa0 -d 3ware,0 -a -s L/../../7/00
.B \ \ /dev/twa0 -d 3ware,1 -a -s L/../../7/02
.B #
-.nf
.B # Two SATA (not SAS) disks on a 3ware 9750 controller.
.B # Start long self-tests Sundays between midnight and
.B # 1am and 2-3 am
.B \ \ /dev/tws0 -d 3ware,1 -a -s L/../../7/02
.\" %ENDIF OS FreeBSD
.B #
-.nf
.B # Three SATA disks on a HighPoint RocketRAID controller.
.B # Start short self-tests daily between 1-2, 2-3, and
.B # 3-4 am.
.B /dev/hptrr -d hpt,1/3 -a -s S/../.././03
.\" %ENDIF OS FreeBSD
.B #
-.nf
.B # Two SATA disks connected to a HighPoint RocketRAID
.B # via a pmport device. Start long self-tests Sundays
.B # between midnight and 1am and 2-3 am.
.B \ \ /dev/hptrr -d hpt,1/4/2 -a -s L/../../7/02
.B #
.\" %ENDIF OS FreeBSD
-.nf
.B # Three SATA disks connected to an Areca
.B # RAID controller. Start long self-tests Sundays
.B # between midnight and 3 am.
.B \ \ /dev/arcmsr0 -d areca,3 -a -s L/../../7/02
.\" %ENDIF OS FreeBSD
.B #
-.nf
.B # The following line enables monitoring of the
.B # ATA Error Log and the Self-Test Error Log.
.B # It also tracks changes in both Prefailure
.B ################################################
.fi
-.PP
.SH CONFIGURATION FILE DIRECTIVES
-.PP
-
If a non-comment entry in the configuration file is the text string
.B DEVICESCAN
in capital letters, then
devices that are found in the scan. Please see below for additional
details.
-[NEW EXPERIMENTAL SMARTD FEATURE] If an entry in the configuration file
-starts with
+If an entry in the configuration file starts with
.B DEFAULT
instead of a device name, then all directives in this entry are set
as defaults for the next device entries.
-
+.PP
This configuration:
-
+.PP
.nf
\ \ DEFAULT -a -R5! -W 2,40,45 -I 194 -s L/../../7/00 -m admin@example.com
\ \ /dev/sda
\ \ /dev/sdd
\ \ /dev/sde -d removable
.fi
-
+.PP
has the same effect as:
-
+.PP
.nf
\ \ /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/sde -d removable -H -m admin@example.com
.fi
-.sp 2
+
The following are the Directives that may appear following the device
name or
.B DEVICESCAN
number.
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
.\" %IF OS FreeBSD Linux
.I 3ware,N
not supported. For RAID configurations, this is typically set to
70,70 deciseconds.
[Please see the \fBsmartctl \-l scterc\fP command-line option.]
-
.TP
.B \-e NAME[,VALUE]
Sets non-SMART device settings when \fBsmartd\fP starts up and has no
.I wcache,[on|off]
\- [ATA only] Sets the volatile write cache feature.
-
.TP
.B \-s REGEXP
Run Self-Tests or Offline Immediate Tests, at scheduled times. A
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
self test log is empty.
-
.IP \fBMM\fP 4
is the month of the year, expressed with two decimal digits. The
range is from 01 (January) to 12 (December) inclusive. Do \fBnot\fP
disk is active again.
Unix users: please beware that the rules for extended regular
-expressions [regex(7)] are \fBnot\fP the same as the rules for
-file-name pattern matching by the shell [glob(7)]. \fBsmartd\fP will
+expressions [\fBregex\fP(7)] are \fBnot\fP the same as the rules for
+file-name pattern matching by the shell [\fBglob\fP(7)]. \fBsmartd\fP will
issue harmless informational warning messages if it detects characters
in \fBREGEXP\fP that appear to indicate that you have made this
mistake.
\fBsmartd\fP
startup.
-By default, email is sent using the system
-.B mail
-command. In order that
-\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
+By default, email is sent using the system \fBmail\fP(1) command.
+In order that \fBsmartd\fP find this command (normally /usr/bin/mail) the
+executable must be in the path of the shell or environment from which
\fBsmartd\fP
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
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
On Windows, the \'\fBBlat\fP\' mailer
(\fBhttp://blat.sourceforge.net/\fP) is used by default.
you have mail problems, we recommend running \fBsmartd\fP in debug
mode with the \'-d\' flag, using the \'-M test\' Directive described
below.
+.\" %IF ENABLE_SMARTDPLUGINDIR
.\" %IF NOT OS Windows
[NEW EXPERIMENTAL SMARTD FEATURE]
This is handled by the script /usr/local/etc/smartd_warning.sh
(see also \'\-M exec\' below).
.\" %ENDIF NOT OS Windows
+.\" %ENDIF ENABLE_SMARTDPLUGINDIR
.\" %IF OS Windows
[Windows only] [NEW EXPERIMENTAL SMARTD FEATURE]
.RS 7
.IP \fBSMARTD_MAILER\fP 4
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
is set to the device path (examples: /dev/hda, /dev/sdb).
.IP \fBSMARTD_DEVICETYPE\fP 4
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
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
is set to device identify information. It includes most of the info printed
by \fBsmartctl \-i\fP but uses a brief single line format.
.IP \fBSMARTD_FAILTYPE\fP 4
gives the reason for the warning or message email. The possible values that
it takes and their meanings are:
-.nf
-.fi
+.br
\fIEmailTest\fP: this is an email test message.
-.nf
-.fi
+.br
\fIHealth\fP: the SMART health status indicates imminent failure.
-.nf
-.fi
+.br
\fIUsage\fP: a usage Attribute has failed.
-.nf
-.fi
+.br
\fISelfTest\fP: the number of self-test failures has increased.
-.nf
-.fi
+.br
\fIErrorCount\fP: the number of errors in the ATA error log has increased.
-.nf
-.fi
+.br
\fICurrentPendingSector\fP: one of more disk sectors could not be
read and are marked to be reallocated (replaced with spare sectors).
-.nf
-.fi
+.br
\fIOfflineUncorrectableSector\fP: during off-line testing, or self-testing,
one or more disk sectors could not be read.
-.nf
-.fi
+.br
\fITemperature\fP: Temperature reached critical limit (see \-W directive).
-.nf
-.fi
+.br
\fIFailedHealthCheck\fP: the SMART health status command failed.
-.nf
-.fi
+.br
\fIFailedReadSmartData\fP: the command to read SMART Attribute data failed.
-.nf
-.fi
+.br
\fIFailedReadSmartErrorLog\fP: the command to read the SMART error log failed.
-.nf
-.fi
+.br
\fIFailedReadSmartSelfTestLog\fP: the command to read the SMART self-test log failed.
-.nf
-.fi
+.br
\fIFailedOpenDevice\fP: the open() command to the device failed.
.IP \fBSMARTD_ADDRESS\fP 4
is determined by the address argument ADD of the \'\-m\' Directive.
given by the argument ADD, with the commas replaced by spaces
(example:admin@example.com root). If more than one email address is
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.
.\" %IF OS Windows
.IP \fBSMARTD_ADDRCSV\fP 4
is set to the one sentence summary warning email message string from
\fBsmartd\fP.
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.
.\" %IF NOT OS Windows
.IP \fBSMARTD_FULLMESSAGE\fP 4
is set to the contents of the entire email warning message string from
\fBsmartd\fP.
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.
.\" %ENDIF NOT OS Windows
.\" %IF OS Windows
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
and no newlines, and is NOT quoted. For example:
-.nf
-.fi
+.br
Sun Feb 9 14:58:19 2003 CST
.IP \fBSMARTD_TFIRSTEPOCH\fP 4
is an integer, which is the unix epoch (number of seconds since Jan 1,
.fi
that would normally be provided to \'mail\'. Examples include:
.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 root -M exec /Example_1/bash/script/below
+.B -m root -M exec /Example_1/shell/script/below
.fi
.\" %IF OS Windows
.B no
command-line arguments, for example:
.nf
-.B -m <nomailer> -M exec /Example_2/bash/script/below
+.B -m <nomailer> -M exec /Example_2/shell/script/below
.fi
If the executable produces any STDERR/STDOUT output, then \fBsmartd\fP
assumes that something is going wrong, and a snippet of that output
.\"! SMARTD_SUBJECT, SMARTD_FULLMSGFILE and SMARTD_ADDRCSV
.\" %ENDIF OS Windows
are set by the script before running the executable.
-
.TP
.B \-f
[ATA only] Check for \'failure\' of any Usage Attributes. If these
.I none
\- Assume that the device firmware obeys the ATA specifications. This
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
\- Suppresses read attempts of SMART or GP Log Directory.
.I 198,increasing
\- 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.
.TP
.B \-P TYPE
.nf
\fB
-#! /bin/bash
+#! /bin/sh
# Save the email message (STDIN) to a file:
cat > /root/msg
/usr/local/sbin/smartctl -a -d $SMART_DEVICETYPE $SMARTD_DEVICE >> /root/msg
# 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
.fi
.nf
\fB
-#! /bin/bash
+#! /bin/sh
# Warn all users of a problem
-wall \'Problem detected with disk: \' "$SMARTD_DEVICESTRING"
-wall \'Warning message from smartd is: \' "$SMARTD_MESSAGE"
-wall \'Shutting down machine in 30 seconds... \'
-
+wall <<EOF
+Problem detected with disk: $SMARTD_DEVICESTRING
+Warning message from smartd is: $SMARTD_MESSAGE
+Shutting down machine in 30 seconds...
+EOF
+
# Wait half a minute
sleep 30
-
+
# Power down the machine
/sbin/shutdown -hf now
\fP
within the script, and a snippet of STDOUT/STDERR is logged to SYSLOG.
The remainder is flushed.
-.PP
-.SH AUTHORS
-\fBBruce Allen\fP
-.br
-University of Wisconsin \- Milwaukee Physics Department
-.br
-\fBChristian Franke\fP (Windows interface, C++ redesign, most enhancements
-since 2009)
-.br
-\fBsmartmontools\-support@lists.sourceforge.net\fP
-
-.PP
-.SH CONTRIBUTORS
-The following have made large contributions to smartmontools:
-.nf
-\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 CREDITS
-.fi
-This code was derived from the smartsuite package, written by Michael
-Cornwell, and from the previous UCSC smartsuite package. It extends
-these to cover ATA-5 disks. This code was originally developed as a
-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
+.\" %IF NOT OS Windows
+.SH FILES
+.TP
+.B /usr/local/etc/smartd.conf
+full path of this file.
-.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).
+.\" %ENDIF NOT OS Windows
+.SH SEE ALSO
+\fBsmartd\fP(8), \fBsmartctl\fP(8),
+\fBmail\fP(1), \fBregex\fP(7).
-.SH
-SVN ID OF THIS PAGE:
-$Id: smartd.conf.5.in 3833 2013-07-20 15:00:04Z chrfranke $
+.SH SVN ID OF THIS PAGE
+$Id: smartd.conf.5.in 3965 2014-07-20 14:46:41Z chrfranke $
* Copyright (C) 2002-11 Bruce Allen <smartmontools-support@lists.sourceforge.net>
* Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
* 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
* it under the terms of the GNU General Public License as published by
extern "C" int getdomainname(char *, int); // no declaration in header files!
#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;
// smartd exit codes
static void write_dev_state_line(FILE * f, const char * name, uint64_t 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)
{
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
const persistent_dev_state::ata_attribute & pa = state.ata_attributes[i];
if (!pa.id)
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
const struct scsiErrorCounter * ecp;
for (int k = 0; k < 3; ++k) {
if ( !state.scsi_error_counters[k].found ) continue;
ecp = &state.scsi_error_counters[k].errCounter;
- fprintf(f, "\t%s-corr-by-ecc-fast;%"PRIu64";"
- "\t%s-corr-by-ecc-delayed;%"PRIu64";"
- "\t%s-corr-by-retry;%"PRIu64";"
- "\t%s-total-err-corrected;%"PRIu64";"
- "\t%s-corr-algorithm-invocations;%"PRIu64";"
+ fprintf(f, "\t%s-corr-by-ecc-fast;%" PRIu64 ";"
+ "\t%s-corr-by-ecc-delayed;%" PRIu64 ";"
+ "\t%s-corr-by-retry;%" PRIu64 ";"
+ "\t%s-total-err-corrected;%" PRIu64 ";"
+ "\t%s-corr-algorithm-invocations;%" PRIu64 ";"
"\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[1],
pageNames[k], ecp->counter[2],
pageNames[k], ecp->counter[6]);
}
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
if(state.TempPageSupported && state.temperature)
PrintOut(LOG_INFO," -A PREFIX, --attributelog=PREFIX\n");
PrintOut(LOG_INFO," Log ATA attribute information to {PREFIX}MODEL-SERIAL.ata.csv\n");
#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
PrintOut(LOG_INFO,"\n");
PrintOut(LOG_INFO," -B [+]FILE, --drivedb=[+]FILE\n");
PrintOut(LOG_INFO," -s PREFIX, --savestates=PREFIX\n");
PrintOut(LOG_INFO," Save disk states to {PREFIX}MODEL-SERIAL.TYPE.state\n");
#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
PrintOut(LOG_INFO,"\n");
PrintOut(LOG_INFO," -w NAME, --warnexec=NAME\n");
PrintOut(LOG_INFO," Run executable NAME on warnings\n");
#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
PrintOut(LOG_INFO," [default is %s/smartd_warning.cmd]\n\n", get_exe_dir().c_str());
#endif
uint64_t rawval = ata_get_attr_raw_value(state.smartval.vendor_attributes[i],
cfg.attribute_defs);
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);
return false;
}
unsigned oui = 0; uint64_t unique_id = 0;
int naa = ata_get_wwn(&drive, oui, unique_id);
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
char cap[32];
return 1;
}
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"),
start, end, end - start + 1,
(unsigned)((100 * start + state.num_sectors/2) / state.num_sectors),
return;
// 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)
- s += strprintf(" (changed %+"PRId64")", rawval - prev_rawval);
+ s += strprintf(" (changed %+" PRId64 ")", rawval - prev_rawval);
PrintOut(LOG_CRIT, "%s\n", s.c_str());
MailWarning(cfg, state, mailtype, "%s", s.c_str());
// No configuration file found -- use fake one
int entry = 0;
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)
- throw std::logic_error("Internal error parsing "SCANDIRECTIVE);
+ throw std::logic_error("Internal error parsing " SCANDIRECTIVE);
return 0;
}
{
// Init default path names
#ifndef _WIN32
- configfile = SMARTMONTOOLS_SYSCONFDIR"/smartd.conf";
- warning_script = SMARTMONTOOLS_SYSCONFDIR"/smartd_warning.sh";
+ configfile = SMARTMONTOOLS_SYSCONFDIR "/smartd.conf";
+ warning_script = SMARTMONTOOLS_SMARTDSCRIPTDIR "/smartd_warning.sh";
#else
std::string exedir = get_exe_dir();
static std::string configfile_str = exedir + "/smartd.conf";
PrintOut(LOG_INFO,
caughtsigHUP==1?
"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);
}
"smartd", "SmartD Service", // servicename, displayname
// description
"Controls and monitors storage devices using the Self-Monitoring, "
- "Analysis and Reporting Technology System (S.M.A.R.T.) "
- "built into ATA and SCSI Hard Drives. "
- PACKAGE_HOMEPAGE
+ "Analysis and Reporting Technology System (SMART) built into "
+ "ATA/SATA and SCSI/SAS hard drives and solid-state drives. "
+ "www.smartmontools.org"
};
// daemon_main() handles daemon and service specific commands
// and starts smartd_main() direct, from a new process,
[Unit]
Description=Self Monitoring and Reporting Technology (SMART) Daemon
+Documentation=man:smartd(8) man:smartd.conf(5)
After=syslog.target
[Service]
#
# 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
# it under the terms of the GNU General Public License as published by
# You should have received a copy of the GNU General Public License
# (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
VERSION="@VERSION@"
prefix="@prefix@"
sysconfdir="@sysconfdir@"
+smartdscriptdir="@smartdscriptdir@"
# Default mailer
os_mailer="@os_mailer@"
-# Plugin directory
-plugindir="$sysconfdir/smartd_warning.d"
+# Plugin directory (disabled if empty)
+plugindir="@smartdplugindir@"
# Parse options
dryrun=
"
# Run plugin scripts if requested
-case " $SMARTD_ADDRESS" in
+if test -n "$plugindir"; then
+ case " $SMARTD_ADDRESS" in
*\ @*)
if [ -n "$dryrun" ]; then
echo "export SMARTD_SUBJECT='$SMARTD_SUBJECT'"
# Send email to remaining addresses
test -n "$SMARTD_ADDRESS" || exit 0
;;
-esac
+ esac
+fi
# Send mail or run command
if [ -n "$SMARTD_ADDRESS" ]; then
--- /dev/null
+.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 $
* Home page of code is: http://smartmontools.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>
*
* This program is free software; you can redistribute it and/or modify
#include "atacmds.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;
const char * packet_types[] = {
std::string format_version_info(const char * prog_name, bool full /*= false*/)
{
std::string info = strprintf(
- "%s "PACKAGE_VERSION" "
+ "%s " PACKAGE_VERSION " "
#ifdef SMARTMONTOOLS_SVN_REV
- SMARTMONTOOLS_SVN_DATE" r"SMARTMONTOOLS_SVN_REV
+ SMARTMONTOOLS_SVN_DATE " r" SMARTMONTOOLS_SVN_REV
#else
- "(build date "__DATE__")" // checkout without expansion of Id keywords
+ "(build date " __DATE__ ")" // checkout without expansion of Id keywords
#endif
- " [%s] "BUILD_INFO"\n"
- "Copyright (C) 2002-13, Bruce Allen, Christian Franke, www.smartmontools.org\n",
+ " [%s] " BUILD_INFO "\n"
+ "Copyright (C) 2002-14, Bruce Allen, Christian Franke, www.smartmontools.org\n",
prog_name, smi()->get_os_version_str().c_str()
);
if (!full)
"\n",
prog_name
);
- info += strprintf(
- "smartmontools release "PACKAGE_VERSION
- " dated "SMARTMONTOOLS_RELEASE_DATE" at "SMARTMONTOOLS_RELEASE_TIME"\n"
+ info +=
+ "smartmontools release " PACKAGE_VERSION
+ " dated " SMARTMONTOOLS_RELEASE_DATE " at " SMARTMONTOOLS_RELEASE_TIME "\n"
#ifdef SMARTMONTOOLS_SVN_REV
- "smartmontools SVN rev "SMARTMONTOOLS_SVN_REV
- " dated "SMARTMONTOOLS_SVN_DATE" at "SMARTMONTOOLS_SVN_TIME"\n"
+ "smartmontools SVN rev " SMARTMONTOOLS_SVN_REV
+ " dated " SMARTMONTOOLS_SVN_DATE " at " SMARTMONTOOLS_SVN_TIME "\n"
#else
"smartmontools SVN rev is unknown\n"
#endif
- "smartmontools build host: "SMARTMONTOOLS_BUILD_HOST"\n"
- "smartmontools build configured: "SMARTMONTOOLS_CONFIGURE_DATE "\n"
- "%s compile dated "__DATE__" at "__TIME__"\n"
- "smartmontools configure arguments: ",
- prog_name
- );
+ "smartmontools build host: " SMARTMONTOOLS_BUILD_HOST "\n"
+#if defined(__GNUC__) && defined(__VERSION__) // works also with CLang
+ "smartmontools build with: GCC " __VERSION__ "\n"
+#endif
+ "smartmontools configure arguments: "
+ ;
info += (sizeof(SMARTMONTOOLS_CONFIGURE_ARGS) > 1 ?
SMARTMONTOOLS_CONFIGURE_ARGS : "[no arguments given]");
info += '\n';
}
// Runtime check of byte ordering, throws if different from isbigendian().
-void check_endianness()
+static void check_endianness()
{
union {
// Force compile error if int type is not 32bit.
}
char num[64];
- snprintf(num, sizeof(num), "%"PRIu64, val);
+ snprintf(num, sizeof(num), "%" PRIu64, val);
int numlen = strlen(num);
int i = 0, j = 0;
if (i == 0)
snprintf(str, strsize, "%u B", (unsigned)n);
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"
- 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]);
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]);
return str;
#ifndef HAVE_WORKING_SNPRINTF
-// Some versions of (v)snprintf() don't append null char on overflow (MSVCRT.DLL),
-// and/or return -1 on overflow (old Linux).
+// Some versions of (v)snprintf() don't append null char (MSVCRT.DLL),
+// and/or return -1 on output truncation (glibc <= 2.0.6).
// Below are sane replacements substituted by #define in utility.h.
#undef vsnprintf
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
+}
* Home page of code is: http://smartmontools.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>
*
* This program is free software; you can redistribute it and/or modify
#ifndef 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 <sys/types.h> // for regex.h (according to POSIX)
#endif
}
-// Runtime check of byte ordering, throws if different from isbigendian().
-void check_endianness();
+// Runtime check of ./configure result, throws on error.
+void check_config();
// This value follows the peripheral device type value as defined in
// SCSI Primary Commands, ANSI INCITS 301:1997. It is also used in