New upstream version 6.6

This commit is contained in:
Jonathan Dowland 2018-08-09 09:01:20 +01:00
parent 3d21a6f6d3
commit f9e10201ba
100 changed files with 25617 additions and 5487 deletions

51
.editorconfig Normal file
View File

@ -0,0 +1,51 @@
# smartmontools indent style settings for EditorConfig
# http://editorconfig.org/
# $Id: .editorconfig 4385 2017-01-28 15:31:50Z chrfranke $
# top-most file
root = true
[*]
indent_style = space
indent_size = 2
tab_width = 8
[/ChangeLog]
indent_style = tab
indent_size = 8
[Makefile*]
# Rule recipes require tab characters (spaces are used elsewhere)
indent_style = tab
indent_size = 8
# TODO: Fix files with other indent styles
[/scsiata.cpp]
# indent_size = 2 and 4
[/scsicmds.*]
indent_size = 4
[/scsiprint.cpp]
indent_size = 4
[/os_win32/syslog_win32.cpp]
indent_style = tab
indent_size = 4
tab_width = 4
# Keep indent style of imported files as is
[/*_nvme_ioctl.h]
indent_style = tab
indent_size = 8
[/csmisas.h]
indent_size = 3
[/getopt/getopt.*]
indent_style = tab
indent_size = 2
[/regex/reg*.*]
indent_style = tab
indent_size = 2

View File

@ -1,13 +1,15 @@
$Id: AUTHORS 4285 2016-04-10 13:17:11Z chrfranke $ $Id: AUTHORS 4403 2017-03-09 20:31:15Z chrfranke $
Developers / Maintainers / Contributors: Developers / Maintainers / Contributors:
Raghava Aditya <...> Raghava Aditya <...>
Bruce Allen <...> Bruce Allen <...>
Casey Biemiller <cbiemiller@intelliprop.com>
Erik Inge Bolsø <...> Erik Inge Bolsø <...>
Stanislav Brabec <sbrabec@suse.cz> Stanislav Brabec <sbrabec@suse.cz>
Peter Cassidy <pcassidy@mac.com> Peter Cassidy <pcassidy@mac.com>
Praveen Chidambaram <bunchofmails@gmail.com> Praveen Chidambaram <bunchofmails@gmail.com>
Jonghwan Choi <jhbird.choi@gmail.com>
Yuri Dario <mc6530@mclink.it> Yuri Dario <mc6530@mclink.it>
Casper Dik <...> Casper Dik <...>
Christian Franke <franke@computer.org> Christian Franke <franke@computer.org>
@ -19,11 +21,13 @@ Jordan Hargrave <jordan_hargrave@dell.com>
Joerg Hering <...> Joerg Hering <...>
Geoff Keating <geoffk@geoffk.org> Geoff Keating <geoffk@geoffk.org>
Dr. David Kirkby <...> Dr. David Kirkby <...>
Song Liu <songliubraving@fb.com>
Dan Lukes <dan+smartmontools.changelog@obluda.cz> Dan Lukes <dan+smartmontools.changelog@obluda.cz>
Kai Mäkisara <kai.makisara@kolumbus.fi> Kai Mäkisara <kai.makisara@kolumbus.fi>
Nidhi Malhotra <nidhi.malhotra@pmcs.com> Nidhi Malhotra <nidhi.malhotra@pmcs.com>
Eduard Martinescu <martines@rochester.rr.com> Eduard Martinescu <martines@rochester.rr.com>
Frédéric L. W. Meunier <...> Frédéric L. W. Meunier <...>
Kimihiro Nonaka <...>
Alex Samorukov <samm@os2.kiev.ua> Alex Samorukov <samm@os2.kiev.ua>
Keiji Sawada <card_captor@users.sourceforge.net> Keiji Sawada <card_captor@users.sourceforge.net>
Manfred Schwarb <manfred99@gmx.ch> Manfred Schwarb <manfred99@gmx.ch>

699
ChangeLog
View File

@ -1,4 +1,701 @@
$Id: ChangeLog 4324 2016-05-31 20:45:50Z chrfranke $ $Id: ChangeLog 4594 2017-11-05 15:21:35Z chrfranke $
2017-11-05 Christian Franke <franke@computer.org>
smartmontools 6.6
2017-11-04 Christian Franke <franke@computer.org>
drivedb.h:
- Apple SD/SM/TS...E/F/G SSDs: Rename, add 1TB
- Innodisk 3IE3/3ME3/3ME4 SSDs: Rename, add 3ME4
- Intel 730 and DC S35x0/3610/3700 Series SSDs: 150GB, *G7
(ticket #750)
- USB: Toshiba Canvio (0x0480:0xa202, 0xa207)
- USB: Seagate Expansion Desktop (0x0bc2:0x3330)
- USB: Maxtor D3 Station 3TB (0x0bc2:0x6123)
- USB: Seagate Backup Plus 4TB (0x0bc2:0xab1e)
- USB: JMicron (0x152d:0x0579)
- USB: Hitachi Touro Mobile (0x4971:0x1023)
- USB: JMicron JMS566 (0xa152:0xb566)
- USB: LogiLink PCCloneEX Lite (0xabcd:0x6104)
smartd.conf.5.in: Fix conditionals of platform specific samples.
smartctl.8.in, smartd.conf.5.in: Shorten or remove info about
very old 3ware controllers.
smartctl.8.in: Add '-g' to '-x' documentation.
Avoid a very long line.
smartctl.cpp: Improve help text formatting.
2017-11-03 Christian Franke <franke@computer.org>
update-smart-drivedb.8.in: Update mailing list link.
update-smart-drivedb.in: Update mailing list comment.
utility.cpp: Silence g++ 7.1 -Wformat-truncation warning.
atacmds.cpp, dev_areca.cpp, os_linux.cpp: Add comments to silence
g++ 7.1 -Wimplicit-fallthrough=[1-4] warnings.
os_linux.cpp: Fix indentation (g++ 6.3: -Wmisleading-indentation).
nvmeprint.cpp: Print IEEE EUI-64 of namespace.
2017-10-29 Christian Franke <franke@computer.org>
smartctl.8.in: Add notes about SMART commands obsoleted in ACS-4.
Remove some outdated info.
smartctl.8.in, smartd.8.in, smartd.conf.5.in: Enable NVMe sections
for Darwin.
os_win32/installer.nsi: Update links.
Remove outdated uninstall commands.
INSTALL: Update ./configure description and OS info.
ataidentify.cpp, ataprint.cpp: Minor ACS-4 additions.
ataprint.cpp, ataprint.h, smartctl.cpp: Add option '-l defects'
to print ATA ACS-4 Pending Defects log (ticket #909).
smartctl.8.in: Document '-l defects'.
2017-10-25 Christian Franke <franke@computer.org>
drivedb.h:
- Samsung based SSDs: PM871b (tickets #895, #903)
- Seagate Enterprise Capacity 3.5 HDD: 4TB (fix for #913)
- Western Digital Red Pro: 6TB (ticket #785)
os_win32/smartd_warning.cmd: Add ability to run PowerShell scripts
with '-M exec'.
smartd.conf.5.in: Document new functionality. Fix typo.
2017-10-25 Alex Samorukov <samm@os2.kiev.ua>
drivedb.h:
- add SATA Voyager GTX (#893)
2017-10-24 Christian Franke <franke@computer.org>
do_release: Update code signing key id.
update-smart-drivedb.in: Add new mailing list address to database
signing key.
2017-10-24 Alex Samorukov <samm@os2.kiev.ua>
drivedb.h:
- add USB Voyager GTX (#893)
- add Phison based OEM SSD based on the firmware name (#853, #831)
- add Ultrastar 7K2 series (#892)
- add LITEON ZETA (LMH-*V2M-*) (#794)
2017-10-22 Christian Franke <franke@computer.org>
os_win32.cpp: Decode Windows 10 1709 build number.
configure.ac: Fail instead of warn if no compiler option to accept
C++11 found and '--with-cxx11-option' is not specified.
2017-10-19 Alex Samorukov <samm@os2.kiev.ua>
scsicmds.h: increase SCSI_TIMEOUT_DEFAULT to 1 minute to work on the
big JBOD arrays (#917)
2017-10-15 Christian Franke <franke@computer.org>
smartd.cpp: Use also device identify information to detect for
duplicate devices (ticket #313).
atacmds.cpp: Don't pass possibly unaligned pointers to swapx().
This silences '-Waddress-of-packed-member' warning from clang++ 4.0
(ticket #915).
2017-10-12 Alex Samorukov <samm@os2.kiev.ua>
os_linux.cpp: implemented support for the SG_IO V4 API. This should
fix kernel warnings and other issues on the /dev/bsg SCSI devices.
Based on the patch created by Circuitsoft (#782)
2017-10-11 Alex Samorukov <samm@os2.kiev.ua>
os_darwin.cpp: fix crash on --scan (regression from r4549)
2017-10-10 Christian Franke <franke@computer.org>
configure.ac, os_darwin.cpp: Align Darwin NVMe device scanning with
other platforms: Disable unless '--with-nvme-devicescan' or '-d nvme'
is specified. Print related configure warning.
2017-10-09 Alex Samorukov <samm@os2.kiev.ua>
drivedb.h:
- Extend Seagate Barracuda 7200.12 regexp (#910)
- Extend Seagate NAS HDD regexp (#778)
- Extend Seagate Surveillance regexp (#807)
- Extend Seagate Enterprise Capacity 3.5 HDD regexp (#864, #913)
- Fix Seagate Barracuda 2.5 5400 regexp to add new models and
avoid false matches (#796)
- Add Seagate IronWolf HDD series (#760)
- Fix attribute 183 for the Seagate Barracuda 2.5 5400 HDD (#816)
- Added Mushkin Triactor series (#905)
- Extend Samsung PM830 regexp (#897)
2017-10-08 Alex Samorukov <samm@os2.kiev.ua>
drivedb.h:
- Add TOSHIBA MQ03UBB... series (#901)
- extend TOSHIBA THNSF regexp (#790)
2017-10-08 Christian Franke <franke@computer.org>
configure.ac: Check for compiler option to accept C++11.
If none found, print warning and ask user to provide info.
Add '--with-cxx11-option' to suppress this warning.
This is intended to check whether C++11 could be used in some
future smartmontools release. The current build is not affected.
configure.ac, Makefile.am: Add Windows VERSIONINFO resource also to
runcmd*.exe and wtssendmsg.exe. Include application manifests if
needed. This also fixes manifests with older MinGW binutils which
do not support more than one resource objects.
os_win32/smart*_res.rc.in: Replace by os_win32/versioninfo.rc.in.
2017-10-06 Christian Franke <franke@computer.org>
Makefile.am: Add PDF man page formatting.
os_win32/installer.nsi: Add PDF man pages, remove TXT man pages.
drivedb.h:
- SMART Modular Technologies mSATA XL+ SSDs (patch from ticket #802)
- StorFly CFast SATA: Add missing space.
- Fix regexp from tickets #882, #885.
2017-10-05 Alex Samorukov <samm@os2.kiev.ua>
drivedb.h: add StorFly CFast SATA 6Gbps SSDs (#911)
2017-10-05 Christian Franke <franke@computer.org>
drivedb.h:
- Western Digital Red: WD80EFAX (tickets #857, #899)
- USB: Toshiba Canvio (0x0480:0xb207)
- USB: Apple/TOSHIBA MQ01UBB200 (0x05ac:0x8406)
- USB: Seagate Expansion Portable 2TB (0x0bc2:0x231a)
- USB: Maxtor M3 Portable 4TB (0x0bc2:0x61b7) (ticket #875)
- USB: WD Elements / My Passport (0x1058:0x259f) (ticket #833)
- USB: WD Elements / My Passport (0x1058:0x25e2)
- USB: WD Elements / My Passport (0x1058:0x25fa) (ticket #840)
- USB: WD My Book / Easystore (0x1058:0x1230) (ticket #835)
- USB: WD My Book / Easystore (0x1058:0x25fb) (tickets #857, #899)
- USB: JMicron JMS561U (0x152d:0x8561) (ticket #860)
- USB: Innostor IS888 (0x1f75:0x0888): -d sat works (ticket #827)
2017-10-04 Alex Samorukov <samm@os2.kiev.ua>
smartctl.8.in: update information about NVMe in Darwin and OS/2 support
smartd.cpp, utility.cpp: fix compiler warnings related to vprintf
2017-10-03 Christian Franke <franke@computer.org>
nvmeprint.cpp: Print new NVMe 1.3 feature flags.
2017-10-02 Christian Franke <franke@computer.org>
smartd.cpp: Add strict tests of /dev/null redirection and chdir("/").
configure.ac: Use '-fstack-protector' if '-strong' is not supported.
2017-10-01 Christian Franke <franke@computer.org>
configure.ac: Set default LDFLAGS for MinGW only if LDFLAGS is unset.
Add '-Wformat=2 -fstack-protector-strong' if supported and CXXFLAGS
is unset.
drivedb.h:
- Fix regexp from tickets #714, #721, #759, #789, #797, #798, #806,
#824, #825, #866, #872, #880.
- SK hynix SATA SSDs (based on patch from ticket #874)
2017-09-25 Alex Samorukov <samm@os2.kiev.ua>
NVME:
- extend controller and smart log page structures to match 1.3 specification.
- Print thermal temperature transition statistic
drivedb.h:
- Added support for more LaCie and Freecom devices (patch from #891)
2017-09-24 Alex Samorukov <samm@os2.kiev.ua>
drivedb.h:
- Added Toshiba MK..34GSX series (#886) and MK..32GSX series (#887)
- Added GOODRAM CX200 SSD (#838)
- Added Mushkin SSD family (#797)
- Added Samsung PM871 to the Samsung SSD family (#798)
- Added PNY CS1311 family (#890)
- Added 0x152d:0x0578 Jmicron USB->SATA
- Added Transcend MTS800 drives (#787)
- Added Transcend MSA 630 series (#759)
- Extended Hitachi Deskstar 7K3000 regexp (#858)
2017-09-23 Alex Samorukov <samm@os2.kiev.ua>
drivedb.h:
- Fix HGST HDS724040ALE640 (#885)
- Add Toshiba MQ03ABB300 (#884)
- Fixed Hitachi 7K1000 (#883)
- Added Seagate Barracuda 2.5 5400 series (#882)
- Added new Seagate Barracuda 3.5 7200 series (#880)
- Added Toshiba P300 series (#881)
- Added SK hynix SSD SC300 series (#699)
- Added Toshiba HG6 Series SSD (#721)
- Added Hynix SSD series
- Added AMD Radeon Solid State Drives (#762)
- Added USB Bridge 0x3538:0x0064 (#855)
- Added Seagate ST4000NM0085 to the Capacity family
- Added Sandisk SATA Cloudspeed Max and GEN2 ESS SSDs and Sandisk SATA CS1K
GEN1 ESS SSDs (#846)
- Added Seagate FireCuda drives (#825)
- Added Transcend MTS400 drives (#847)
- Added Transcend MTS420 drives (#869)
- Added Transcend SSD230 drives (#879)
- Added Transcend SSD220S drives (#821)
- Added Intel 540 Series SSDs (#803)
- Added Intel 3710 Series SSDs (#824)
- Added Micron 5100 ECO, PRO, and MAX Models (#861)
- Added Samsung EVO SSD series - make regexp match less strict (#806)
- Added Hitachi CinemaStar 5K1000 series (#758)
- Added WDC WD4004FZWX disk to the Digital Black family (#765)
- Added Samsung SSD 845DC EVO series (#866)
- Added SK hynix SL308 family (#808)
- Added WD Blue PC SSD family (#767)
- Corrected Crucial M4 drivedb entry to include 32Gb model (#844)
2017-09-20 Alex Samorukov <samm@os2.kiev.ua>
os_freebsd: use /dev/nvme/nvme.h on the recent versions
os_darwin:
- initial NVMe support for the darwin platform.
- NVMe device scan support
- Add device type autodetection
2017-08-08 Christian Franke <franke@computer.org>
ataprint.cpp: Fix ATA Security Level check.
configure.ac: Detect MinGW libstdc++ problems with high
'--image-base'.
Update smartmontools-support mailing list address.
Remove old mailing list address from all source files.
2017-05-03 Christian Franke <franke@computer.org>
smartctl.8.in, smartd.8.in, smartd.conf.5.in,
update-smart-drivedb.8.in:
Rework vertical space and '.nf...fi' (no-fill) sections
for better formatting with various tools (groff, mandoc,
man2html) and output formats (text, pdf, html).
Use default vertical space instead of an empty line
between paragraphs.
Use '.br' instead of '.nf...fi' where applicable.
Use CW font in remaining no-fill sections.
smartctl.8.in: Replace UTF-8 quotes.
2017-05-02 Christian Franke <franke@computer.org>
smartctl.8.in, smartd.8.in, smartd.conf.5.in,
update-smart-drivedb.8.in:
Various man/groff syntax fixes (ticket #656):
Split long lines.
Insert two spaces or newline between sentences.
Use ' for apostrophes.
Use groff extension \(aq (apostrophe quote, ASCII 0x27)
or ' for quotes.
Use \- (minus sign) for options and examples.
Use \(en (en-dash) for numeric ranges.
Protect . with \& if not at end of sentence.
2017-04-24 Alex Samorukov <samm@os2.kiev.ua>
os_freebsd.cpp: remove duplicated code which checks ATA SMART
status (#746)
2017-04-23 Alex Samorukov <samm@os2.kiev.ua>
os_os2.cpp:
- code cleanup
- add os2ahci driver initial support
- fix selftest command
- add device scan support
2017-04-19 Alex Samorukov <samm@os2.kiev.ua>
OS/2 - many fixes:
- autodetect and build os_os2.o on OS/2
- fix os_os2.cpp/os_os2.h compilation (thanks to franke@)
- get rid from the os_os/hdreg.h - use constants from the atacmd.h
- remove most of the dead code and unused functions
2017-04-17 Christian Franke <franke@computer.org>
os_win32.cpp: Decode Windows 10 1703 build number.
atacmds.h, ataprint.cpp: Use STANDBY instead of IDLE command if
'-s standby,[N|off]' and '-s standby,now' are both specified.
smartctl.8.in: Document new behaviour of '-s standby,*'.
2017-04-01 Christian Franke <franke@computer.org>
atacmds.cpp, atacmds.h, ataprint.cpp: Print minimum supported ERC
Time Limit from SCT Status.
ataidentify.cpp, ataprint.cpp: Add ACS-4 and SATA 3.3 major
versions, log pages, device statistic values and feature bits.
2017-03-27 Christian Franke <franke@computer.org>
scsiprint.cpp: Suppress "SAS address" if '-q noserial' is
specified (ticket #822).
scsicmds.cpp: Remove useless variable
(cppcheck 1.77: knownConditionTrueFalse).
smartd.cpp: Always suppress "failed to read Temperature" message
if SCSI device does not support temperature (ticket #817).
Fix initial check for SCSI temperature support.
Log SCSI temperature regardless of its origin.
2017-03-11 Christian Franke <franke@computer.org>
smartctl.8.in, smartd.8.in, smartd.conf.5.in,
update-smart-drivedb.8.in: Update EXPERIMENTAL notes.
Update links. Update or remove various outdated info.
smartctl.8.in: Fix documentation of the '-g all' option.
smartctl.cpp: Add '-g dsn' to '-x' output.
2017-03-11 Jonghwan Choi <jhbird.choi@gmail.com>
ataprint.cpp: Fix false positive DSN support detection.
2017-03-09 Jean Delvare <...>
smartctl.8.in: Fix documentation of the '-q' option.
2017-03-09 Christian Franke <franke@computer.org>
AUTHORS: Add Jonghwan Choi.
2017-03-09 Jonghwan Choi <jhbird.choi@gmail.com>
Add options to get/set ATA DSN (Device Statistics Notification)
feature (ticket #815):
atacmds.h: Add DSN feature subcommand code.
ataprint.cpp, ataprint.h, smartctl.cpp: Add '-g/s dsn' options.
smartd.cpp: Add '-e dsn' directive.
smartctl.8.in, smartd.conf.5.in: Document the new options.
2017-03-04 Christian Franke <franke@computer.org>
smartctl.cpp, smartd.cpp: Fix help text for '-B' option.
smartd.cpp: Unify indent style, replace tabs.
Move ATA/SCSI/NVMe device open to new common function.
Suppress warning emails and repeated log messages on open error if
'-d removable' is specified (Debian Bug 770872, Ubuntu Bug 1451572).
smartd.conf.5.in: Document new behaviour of '-d removable'.
2017-03-02 Christian Franke <franke@computer.org>
smartd.cpp: Move single device registration to new function.
Exit smartd on device open error unless '-q never' or '-d removable'
is specified (regression from r2602).
Prevent retry if registration failed and '-q never' is specified.
Add enum for '-q, --quit' option.
2017-02-27 Christian Franke <franke@computer.org>
drivedb.h:
- Crucial/Micron RealSSD C300/P300: Rename, add P300, remove M500
- Crucial/Micron RealSSD m4/C400/P400: P400e micro SATA
- Crucial/Micron MX1/2/300, M5/600, 1100 Client SSDs: Rename,
add MX300 (tickets #763, #791), M550 M.2 (ticket #810),
1100 (ticket #783)
2017-02-22 Christian Franke <franke@computer.org>
configure.ac: Set various default LDFLAGS for MinGW builds:
Link statically, indicate DEP and TS compatibility, enable ASLR.
Add '--with-mingw-aslr' option.
2017-02-20 Christian Franke <franke@computer.org>
os_win32.cpp: Decode Windows Server 2016 build number.
os_win32.cpp: Rework CSMI port mapping. This fixes access to
ports != 0 behind IRST driver 15.2 (ticket #804).
2017-01-30 Alex Samorukov <samm@os2.kiev.ua>
os_freebsd.cpp: unblock 48bit ATACAM commands for the legacy controllers
if FreeBSD version is >= 9.2-RELEASE, tested on FreeBSD 10.3
2017-01-28 Christian Franke <franke@computer.org>
ataidentify.cpp: Don't shift negative values
(g++ 6.3: -Wshift-negative-value, cppcheck 1.77: shiftNegativeLHS).
os_win32.cpp, scsiata.cpp, scsicmds.cpp, scsiprint.cpp: Fix 'if'
and 'else' clause indentations (g++ 6.3: -Wmisleading-indentation).
Add indent style configuration for EditorConfig
(http://editorconfig.org/):
.editorconfig: New file.
Makefile.am: Add new file to source tarball.
2017-01-21 Christian Franke <franke@computer.org>
drivedb.h:
- Marvell based SanDisk SSDs: X300 OEM (ticket #747),
X400 (ticket #715), Ultra II (ticket #744)
- USB: Renesas uPD720231A (0x045b:0x0229)
- USB: Maxtor D3 Station 5TB (0x0bc2:0x6126)
- USB: Seagate Backup Plus 8TB (0x0bc2:0xab38) (ticket #786)
- USB: WD Elements / My Passport (0x1058:0x107d) (ticket #772)
- USB: WD Elements / My Passport (0x1058:0x25a1) (ticket #773)
- USB: WD My Book 4TB (0x1058:0x25a3) (ticket #784)
- USB: WD Elements / My Passport: Merge entries
- USB: WD My Book: Merge entries
2017-01-14 Christian Franke <franke@computer.org>
scsiata.cpp: Remove redundant assignment
(cppcheck: redundantAssignment).
ataprint.cpp, ataprint.h, smartctl.cpp, smartctl.8.in:
Add STATUS parameter to '-n POWERMODE' option (ticket #697).
2017-01-13 Christian Franke <franke@computer.org>
configure.ac: Rework CXXFLAGS settings, use shell intrinsics.
os_win32.cpp: Fix harmless buffer overflow bug
(found by VC14 code analyser).
2017-01-12 Christian Franke <franke@computer.org>
drivedb.h:
- Innodisk 1ME3/3ME/3SE SSDs: Rename, add 1ME3 (ticket #713), 3SE
- Innodisk 3IE2/3ME2/3MG2/3SE2 SSDs: Rename, add 3ME2
- Samsung based SSDs: 750 EVO, PM810(470), 840, PM830, PM851,
CM871 (ticket #754), CM871a, PM871a (tickets #745, #775),
SM951 (ticket #704)
2017-01-11 Christian Franke <franke@computer.org>
smartctl.8.in: Make '-d intelliprop' visible on all platforms.
Add warning.
smartd.conf.5.in: Document '-d intelliprop'.
os_win32/vc14/smart*.vcxproj*: Add new files.
AUTHORS: Add Casey Biemiller
2017-01-11 Casey Biemiller <cbiemiller@intelliprop.com>
Add '-d intelliprop' device type for drives behind IntelliProp
RAID controllers (ticket #730):
atacmds.cpp, atacmds.h: Add function ataWriteLogExt().
dev_intelliprop.cpp, dev_intelliprop.h: New files.
dev_interface.cpp: Add '-d intelliprop,N[+TYPE]' option.
Makefile.am: Add new files.
smartctl.8.in, smartd.conf.5.in: Document it.
2017-01-09 Alex Samorukov <samm@os2.kiev.ua>
os_freebsd.cpp: fix panic on INVARIANTS enabled kernel, patch
provided (#780) by Oliver Pinter <oliver.pinter@hardenedbsd.org>
2017-01-01 Christian Franke <franke@computer.org>
Happy New Year! Update copyright year in version info.
2016-11-12 Christian Franke <franke@computer.org>
atacmds.h, freebsd_nvme_ioctl.h: Apply patch-atacmds.h 1.1
and patch-freebsd_nvme_ioctl.h 1.1 (2016-11-04) from
pkgsrc.se/sysutils/smartmontools:
Build fix for FreeBSD-11 and newer. Don't redefine now
existing things, ATA_SET_FEATURES and nvme_command.
2016-11-10 Christian Franke <franke@computer.org>
os_linux.cpp: Don't detect devices behind hpsa driver as regular
SCSI devices. Suggest to use '-d cciss,N' instead.
Based on patch provided by Stanislav Brabec.
2016-11-05 Christian Franke <franke@computer.org>
update-smart-drivedb.in: Fix 'mv' error on first update with new
script.
configure.ac, update-smart-drivedb.in: Add '--with-gnupg' option.
configure.ac: Add '--with-update-smart-drivedb=X.Y' option to
backport drive database update script and man page to older
version X.Y.
configure.ac: Remove checks for no longer supported options
--disable-drivedb, --enable-savestates and --enable-attributelog.
2016-11-04 Christian Franke <franke@computer.org>
Add authentication to update-smart-drivedb (ticket #751):
Create missing branches RELEASE_6_5_DRIVEDB and RELEASE_6_6_DRIVEDB.
Add signature files drivedb.h.raw.asc to each maintained branch.
update-smart-drivedb.in: Include new public key block ID DFD22559.
Download also drivedb.h.raw.asc.
Do no longer download from trunk if branch does not exist.
Create drivedb.h.raw. Verify signature.
Add options '--trunk', '--no-verify' and '--export-key'.
update-smart-drivedb.8.in: Document new behaviour and options.
2016-10-23 Christian Franke <franke@computer.org>
smartd.8.in: Document Windows PARAMCHANGE service control command.
smartctl.8.in, smartd.8.in, smartd.conf.5.in: Enable NVMe sections
for NetBSD.
configure.ac, os_netbsd.cpp: Add --with-nvme-devicescan for NetBSD.
drivedb.h:
- Toshiba 3.5" MG04ACA... Enterprise HDD (ticket #732)
- Toshiba X300 (ticket #716)
- Seagate Laptop HDD: Rename, add 3/4TB (ticket #738)
- Seagate Constellation ES: HP OEM
- Western Digital RE4: *ABYZ variant
- Western Digital Re: Add attribute 16 (ticket #742)
- Western Digital Black: Remove *BEK[TX] variants
- Western Digital Black Mobile: 1TB, *BEKT, *LPLX variants
- Western Digital Elements / My Passport (USB, AF): 4TB
- USB: Neodio Technologies (0x0aec:0x3050)
- USB: Dura Micro (0x0c0b:0xb136)
- USB: My Passport Ultra 4TB (0x1058:0x2599)
2016-10-17 Christian Franke <franke@computer.org>
configure.ac: Add --with-scriptpath option.
smartd_warning.sh.in, update-smart-drivedb.in: Set PATH variable.
2016-10-03 Christian Franke <franke@computer.org>
os_win32/vc14/*.vcxproj: Add platform x64.
os_win32.cpp: Use new enhanced version of IOCTL_STORAGE_QUERY_PROPERTY
to access NVMe info. This works with Windows 10 NVMe driver
(stornvme.sys) (ticket #691).
smartctl.8.in, smartd.8.in: Document device names.
2016-09-28 Christian Franke <franke@computer.org>
drivedb.h:
- USB: Buffalo MiniStation HD-PZU3 (0x0411:0x01f9) (ticket #739)
- USB: Iomega Prestige (0x059b:0x0571)
- USB: LaCie P9223 (0x059f:0x1070)
- USB: Seagate Expansion Desktop (0x0bc2:0x331a) (ticket #725)
- USB: Seagate Backup Plus (0x0bc2:0xab28) (ticket #738)
- USB: WD My Passport Ultra (0x1058:0x259d) (ticket #736)
- USB: ASMedia ASM1351 (0x174c:0x1351)
2016-09-25 Christian Franke <franke@computer.org>
AUTHORS: Add Kimihiro Nonaka.
2016-09-25 Kimihiro Nonaka <...>
os_netbsd.cpp: Migrate to new dev_interface (ticket #101).
Add NVMe support (ticket #728).
Implement netbsd_ata_device::ata_pass_through().
netbsd_nvme_ioctl.h: New file based on "sys/dev/ic/nvmeio.h" from
NetBSD kernel sources.
Makefile.am: Add new file.
2016-09-07 Christian Franke <franke@computer.org>
Makefile.am: clean-vc14 targets.
os_win32.cpp: Decode Windows 10 build number.
os_win32/smartd_warning.cmd: Use delayed variable expansion.
os_win32/smartd_mailer.ps1: Use domainname for default sender address.
os_win32/smartd_mailer.conf.sample.ps1: Update related comment.
os_win32/smartd_warning.cmd: Remove trailing '\r' from USERDNSDOMAIN.
2016-08-28 Christian Franke <franke@computer.org>
os_win32/installer.nsi: Fix quoting of EDITOR shortcuts.
Send warning mails via PowerShell script on Windows (ticket #731):
Makefile.am, os_win32/installer.nsi: Add new files.
os_win32/smartd_mailer.ps1: New PowerShell script using Send-MailMessage
cmdlet to send mail.
os_win32/smartd_mailer.conf.sample.ps1: New sample config file.
os_win32/smartd_warning.cmd: Call new script if configured.
Improve error handling. Add setlocal.
smartd.conf.5.in: Document it.
2016-08-17 Christian Franke <franke@computer.org>
AUTHORS: Add Song Liu.
smartctl.cpp: Reduce scope of 'persistent' flag
(cppcheck: variableScope).
2016-08-17 Song Liu <songliubraving@fb.com>
ataprint.cpp, ataprint.h, smartctl.cpp, smartctl.8.in:
Add persistent option ',p' to '-s wcreorder,on|off' (ticket #726).
atacmds.cpp, atacmds.h, ataprint.cpp, ataprint.h, smartctl.cpp,
smartctl.8.in: Add ability to control ATA drive write cache through
SCT Feature control. The new smartctl options are
'-s wcache-sct,ata|on|off[,p]' and '-g wcache-sct' (ticket #723).
2016-08-06 Christian Franke <franke@computer.org>
os_win32.cpp: Add Windows 10 build number to get_os_version_str().
Update MSVC10 (VS2010) for VC14 (VS2015):
os_win32/vc14/*: Move from os_win32/vc10/*.
os_win32/vc14/*.vcxproj: Update for VC14.
Remove '__func__' workaround (revert r4225).
Makefile.am: Rename and update config-vc14 target.
utility.cpp: Add workaround for missing 'tzname'.
drivedb.h:
- OCZ/Toshiba Trion SSDs: Rename, add TOSHIBA-TR150 (ticket #722)
- HGST Ultrastar 7K6000 (ticket #708)
- HGST Ultrastar He10
- Seagate Desktop HDD.15: 6TB, 8TB
- Seagate Enterprise Capacity 3.5 HDD: 8TB, 10TB (ticket #717),
attribute 240
- Seagate SV35: 4TB
- Western Digital Gold (ticket #711)
- USB: LaCie (0x059f:0x1075) (ticket #718)
- USB: Seagate Expansion External (0x0bc2:0x3322) (ticket #706)
- USB: Seagate FreeAgent GoFlex (0x0bc2:0x5030) (ticket #720)
- USB: Seagate Backup Plus Desktop (0x0bc2:0xab34) (ticket #700)
2016-05-31 Christian Franke <franke@computer.org> 2016-05-31 Christian Franke <franke@computer.org>

241
Doxyfile
View File

@ -1,241 +0,0 @@
# Doxyfile 1.5.5
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = smartmontools
PROJECT_NUMBER =
OUTPUT_DIRECTORY = doc
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ABBREVIATE_BRIEF =
ALWAYS_DETAILED_SEC = YES
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = YES
STRIP_FROM_PATH =
STRIP_FROM_INC_PATH =
SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = YES
QT_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = NO
DETAILS_AT_TOP = NO
INHERIT_DOCS = YES
SEPARATE_MEMBER_PAGES = NO
TAB_SIZE = 8
ALIASES =
OPTIMIZE_OUTPUT_FOR_C = NO
OPTIMIZE_OUTPUT_JAVA = NO
OPTIMIZE_FOR_FORTRAN = NO
OPTIMIZE_OUTPUT_VHDL = NO
BUILTIN_STL_SUPPORT = NO
CPP_CLI_SUPPORT = NO
SIP_SUPPORT = NO
DISTRIBUTE_GROUP_DOC = NO
SUBGROUPING = YES
TYPEDEF_HIDES_STRUCT = NO
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
EXTRACT_ALL = YES
EXTRACT_PRIVATE = YES
EXTRACT_STATIC = YES
EXTRACT_LOCAL_CLASSES = YES
EXTRACT_LOCAL_METHODS = NO
EXTRACT_ANON_NSPACES = YES
HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO
HIDE_FRIEND_COMPOUNDS = NO
HIDE_IN_BODY_DOCS = NO
INTERNAL_DOCS = NO
CASE_SENSE_NAMES = YES
HIDE_SCOPE_NAMES = NO
SHOW_INCLUDE_FILES = YES
INLINE_INFO = YES
SORT_MEMBER_DOCS = YES
SORT_BRIEF_DOCS = NO
SORT_GROUP_NAMES = NO
SORT_BY_SCOPE_NAME = NO
GENERATE_TODOLIST = YES
GENERATE_TESTLIST = YES
GENERATE_BUGLIST = YES
GENERATE_DEPRECATEDLIST= YES
ENABLED_SECTIONS =
MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = YES
SHOW_DIRECTORIES = NO
FILE_VERSION_FILTER =
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
QUIET = NO
WARNINGS = YES
WARN_IF_UNDOCUMENTED = NO
WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = NO
WARN_FORMAT = "$file:$line: $text"
WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT =
INPUT_ENCODING = UTF-8
FILE_PATTERNS = dev*.h \
dev*.cpp \
scsiata.cpp
RECURSIVE = NO
EXCLUDE =
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS =
EXCLUDE_SYMBOLS =
EXAMPLE_PATH =
EXAMPLE_PATTERNS =
EXAMPLE_RECURSIVE = NO
IMAGE_PATH =
INPUT_FILTER =
FILTER_PATTERNS =
FILTER_SOURCE_FILES = NO
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER = YES
INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = NO
REFERENCED_BY_RELATION = NO
REFERENCES_RELATION = NO
REFERENCES_LINK_SOURCE = YES
USE_HTAGS = NO
VERBATIM_HEADERS = YES
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = NO
COLS_IN_ALPHA_INDEX = 5
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
GENERATE_HTML = YES
HTML_OUTPUT = html
HTML_FILE_EXTENSION = .html
HTML_HEADER =
HTML_FOOTER =
HTML_STYLESHEET =
HTML_ALIGN_MEMBERS = YES
GENERATE_HTMLHELP = NO
GENERATE_DOCSET = NO
DOCSET_FEEDNAME = "Doxygen generated docs"
DOCSET_BUNDLE_ID = org.doxygen.Project
HTML_DYNAMIC_SECTIONS = NO
CHM_FILE =
HHC_LOCATION =
GENERATE_CHI = NO
BINARY_TOC = NO
TOC_EXPAND = NO
DISABLE_INDEX = NO
ENUM_VALUES_PER_LINE = 4
GENERATE_TREEVIEW = NO
TREEVIEW_WIDTH = 250
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_LATEX = YES
LATEX_OUTPUT = latex
LATEX_CMD_NAME = latex
MAKEINDEX_CMD_NAME = makeindex
COMPACT_LATEX = NO
PAPER_TYPE = a4wide
EXTRA_PACKAGES =
LATEX_HEADER =
PDF_HYPERLINKS = YES
USE_PDFLATEX = YES
LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
GENERATE_RTF = NO
RTF_OUTPUT = rtf
COMPACT_RTF = NO
RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
GENERATE_MAN = NO
MAN_OUTPUT = man
MAN_EXTENSION = .3
MAN_LINKS = NO
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
GENERATE_XML = NO
XML_OUTPUT = xml
XML_SCHEMA =
XML_DTD =
XML_PROGRAMLISTING = YES
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# configuration options related to the Perl module output
#---------------------------------------------------------------------------
GENERATE_PERLMOD = NO
PERLMOD_LATEX = NO
PERLMOD_PRETTY = YES
PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = NO
EXPAND_ONLY_PREDEF = NO
SEARCH_INCLUDES = YES
INCLUDE_PATH =
INCLUDE_FILE_PATTERNS =
PREDEFINED =
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration::additions related to external references
#---------------------------------------------------------------------------
TAGFILES =
GENERATE_TAGFILE =
ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = YES
MSCGEN_PATH =
HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = NO
CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES
GROUP_GRAPHS = YES
UML_LOOK = NO
TEMPLATE_RELATIONS = NO
INCLUDE_GRAPH = YES
INCLUDED_BY_GRAPH = YES
CALL_GRAPH = NO
CALLER_GRAPH = NO
GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES
DOT_IMAGE_FORMAT = png
DOT_PATH =
DOTFILE_DIRS =
DOT_GRAPH_MAX_NODES = 50
MAX_DOT_GRAPH_DEPTH = 0
DOT_TRANSPARENT = YES
DOT_MULTI_TARGETS = NO
GENERATE_LEGEND = YES
DOT_CLEANUP = YES
#---------------------------------------------------------------------------
# Configuration::additions related to the search engine
#---------------------------------------------------------------------------
SEARCHENGINE = NO

72
INSTALL
View File

@ -1,7 +1,7 @@
Smartmontools installation instructions Smartmontools installation instructions
======================================= =======================================
$Id: INSTALL 4120 2015-08-27 16:12:21Z samm2 $ $Id: INSTALL 4574 2017-10-29 15:41:13Z chrfranke $
Please also see the smartmontools home page: Please also see the smartmontools home page:
http://www.smartmontools.org/ http://www.smartmontools.org/
@ -54,8 +54,8 @@ Table of contents:
E) Cygwin E) Cygwin
The code was tested on Cygwin 1.7.15-1. It should also work on other The code was tested on Cygwin 2.9.0-3 x86 and x86_64. It should also
recent releases. work on other recent releases.
Both Cygwin and Windows versions of smartmontools share the same code Both Cygwin and Windows versions of smartmontools share the same code
to access the IDE/ATA or SCSI devices. The information in the "Windows" to access the IDE/ATA or SCSI devices. The information in the "Windows"
@ -64,7 +64,7 @@ Table of contents:
F) Windows F) Windows
The code was tested on Windows XP SP3, 2003, Vista, Windows 7, 8, 8.1 The code was tested on Windows XP SP3, 2003, Vista, Windows 7, 8, 8.1
and Windows 10 Release Preview. Support von Windows 9x/ME and NT4 was and Windows 10 up to 1709. Support von Windows 9x/ME and NT4 was
removed after smartmontools 5.43. removed after smartmontools 5.43.
ATA or SATA devices are supported if the device driver implements ATA or SATA devices are supported if the device driver implements
@ -72,16 +72,11 @@ Table of contents:
Only the latter provides full pass-through support which is needed Only the latter provides full pass-through support which is needed
for all smartmontools features. for all smartmontools features.
SATA devices behind a Intel RST driver are accessed through CSMI.
SCSI and USB devices are accessed through SPTI. Special driver support SCSI and USB devices are accessed through SPTI. Special driver support
is not required. is not required.
3ware 9000 RAID controllers are supported using features available
in the Windows driver release 9.4.0 (3wareDrv.sys 3.0.2.70) or later.
Older drivers provide SMART access to the first physical drive (port)
of each logical drive (unit). If driver support is not available
(7000/8000 series, 9000 on XP 64), smartctl can be used to parse SMART
data output from CLI or 3DM.
G) MacOS/Darwin G) MacOS/Darwin
The code was tested on MacOS 10.3.4. It should work from 10.3 The code was tested on MacOS 10.3.4. It should work from 10.3
@ -149,11 +144,9 @@ Table of contents:
and continue with step [3] below, skipping the "unpack the tarball" step. and continue with step [3] below, skipping the "unpack the tarball" step.
The autogen.sh command is ONLY required when installing from The autogen.sh command is ONLY required when installing from
SVN. You need GNU Autoconf (version 2.50 or greater), GNU Automake SVN. You need GNU Autoconf (version 2.60 or greater), GNU Automake
(version 1.7 or greater) and their dependencies installed in order (version 1.10 or greater) and their dependencies installed in order
to run it. You can get these here: to run it.
http://directory.fsf.org/project/autoconf/
http://directory.fsf.org/project/automake/
[3] Installing from the source tarball [3] Installing from the source tarball
====================================== ======================================
@ -184,14 +177,21 @@ Table of contents:
--with-initscriptdir=auto --with-initscriptdir=auto
--with-exampledir='${docdir}/examplescripts' --with-exampledir='${docdir}/examplescripts'
--with-drivedbdir='${datadir}/smartmontools' --with-drivedbdir='${datadir}/smartmontools'
--with-update-smart-drivedb
--with-gnupg
--with-smartdscriptdir='${sysconfdir}' --with-smartdscriptdir='${sysconfdir}'
--with-smartdplugindir='${smartdscriptdir}/smartd_warning.d' --with-smartdplugindir='${smartdscriptdir}/smartd_warning.d'
--with-scriptpath='/bin:/usr/bin'
--without-savestates --without-savestates
--without-attributelog --without-attributelog
--with-os-deps='os_linux.o dev_areca.o' (platform specific) --with-os-deps='os_linux.o dev_areca.o' (platform specific)
--without-selinux --without-selinux
--with-libcap-ng=auto --with-libcap-ng=auto
--with-working-snprintf --without-nvme-devicescan
--without-solaris-sparc-ata (Solaris SPARC only)
--with-working-snprintf (Windows: guessed)
--with-mingw-aslr=auto (Windows only)
--with-cxx11-option=auto
These will usually not overwrite existing "distribution" installations on These will usually not overwrite existing "distribution" installations on
Linux Systems since the FHS reserves this area for use by the system Linux Systems since the FHS reserves this area for use by the system
@ -200,10 +200,8 @@ Table of contents:
For different installation locations or distributions, simply add For different installation locations or distributions, simply add
arguments to ./configure as shown in [4] below. arguments to ./configure as shown in [4] below.
If you wish to alter the default C++ compiler flags, set an If you wish to alter the default C++ compiler flags, add
environment variable CXXFLAGS='your options' before doing CXXFLAGS='your options' to ./configure command.
./configure, or else do:
make CXXFLAGS='your options'
The first output line of smartctl and smartd provides information The first output line of smartctl and smartd provides information
about release number, last SVN checkin date and revison, platform, about release number, last SVN checkin date and revison, platform,
@ -215,7 +213,7 @@ Table of contents:
================================================ ================================================
Note: Please send corrections/additions to: Note: Please send corrections/additions to:
smartmontools-support@lists.sourceforge.net smartmontools-support@listi.jpberlin.de
Debian: Debian:
If you don't want to overwrite any distribution package, use: If you don't want to overwrite any distribution package, use:
@ -373,7 +371,7 @@ Same as Red Hat:
[10] Guidelines for Windows [10] Guidelines for Windows
=========================== ===========================
To compile the Windows release with MinGW gcc on MSYS, use: To compile statically linked Windows release with MinGW gcc on MSYS, use:
./configure ./configure
make make
@ -384,12 +382,10 @@ To compile the Windows release with MinGW gcc on MSYS, use:
Cross-compile statically linked 32-bit and 64-bit versions with MinGW-w64: Cross-compile statically linked 32-bit and 64-bit versions with MinGW-w64:
./configure --build=$(./config.guess) \ ./configure --build=$(./config.guess) \
--host=i686-w64-mingw32 \ --host=i686-w64-mingw32
LDFLAGS=-static
./configure --build=$(./config.guess) \ ./configure --build=$(./config.guess) \
--host=x86_64-w64-mingw32 \ --host=x86_64-w64-mingw32
LDFLAGS=-static
Tested on Cygwin, Debian and Fedora. Tested on Cygwin, Debian and Fedora.
@ -438,16 +434,16 @@ To both create and run the (interactive) installer, use:
The binary distribution includes all documentation files converted The binary distribution includes all documentation files converted
to DOS text file format and *.html and *.txt preformatted man pages. to DOS text file format and *.html and *.txt preformatted man pages.
To prepare os_win32 directory for MS Visual Studio C++ 2010 [Express], To prepare os_win32/vc14 directory for MS Visual Studio C++ 2015 builds,
use the following on MSYS or Cygwin: use the following on MSYS or Cygwin:
mkdir vctmp && cd vctmp mkdir vctmp && cd vctmp
../configure [... any MinGW option set from above ...] ../configure [... any MinGW option set from above ...]
make config-vc10 make config-vc14
The MSVC project files (os_win32/vc10/*) are included in SVN (but not The MSVC project files (os_win32/vc14/*) are included in SVN (but not
in source tarball). The target config-vc10 from a Makefile configured in source tarball). The target config-vc14 from a Makefile configured
for MinGW creates os_win32/vc10/{config.h,smart*.rc,svnversion.h}. for MinGW creates os_win32/vc14/{config.h,smart*.rc,svnversion.h}.
The configure skript must be run outside of the source directory to The configure skript must be run outside of the source directory to
avoid inclusion of the original config.h. avoid inclusion of the original config.h.
@ -457,7 +453,7 @@ use the following on MSYS or Cygwin:
To compile the OS/2 code, please run To compile the OS/2 code, please run
./os_os2/configure.os2 ./configure
make make
make install make install
@ -559,13 +555,14 @@ default then the default configuration file is installed as
The commands: The commands:
make htmlman make htmlman
make pdfman
make txtman make txtman
may be used to build .html and .txt preformatted man pages. may be used to build .html, .pdf and .txt preformatted man pages.
These are used by the dist-win32 make target to build the Windows These are used by the dist-win32 make target to build the Windows
distribution. distribution.
The commands also work on other operating system configurations The commands also work on other operating system configurations
if suitable versions of man2html, groff and grotty are installed. if suitable versions of man, man2html and groff are installed.
On systems without man2html, the following command should work On systems without man2html, the following command should work
if groff is available: if groff is available:
@ -594,8 +591,7 @@ a description of available configure options is printed
[with defaults in square brackets]. See also section [3] above. [with defaults in square brackets]. See also section [3] above.
The following old configure options are deprecated and will be removed The following old configure options are no longer supported:
in a future release of smartmontools:
Old option Replacement Old option Replacement
--with-docdir=DIR --docdir=DIR (autoconf >= 2.60) --with-docdir=DIR --docdir=DIR (autoconf >= 2.60)
@ -670,4 +666,4 @@ Case 2:
/usr/local/etc/rc.d/init.d/smartd /usr/local/etc/rc.d/init.d/smartd
Additional information about using configure can be found here: Additional information about using configure can be found here:
http://www.gnu.org/software/autoconf/manual/autoconf.html#Running-configure-Scripts https://www.gnu.org/software/autoconf/manual/autoconf.html#Running-configure-Scripts

View File

@ -1,6 +1,6 @@
## Process this file with automake to produce Makefile.in ## Process this file with automake to produce Makefile.in
# #
# $Id: Makefile.am 4299 2016-04-16 19:45:57Z chrfranke $ # $Id: Makefile.am 4519 2017-10-08 15:41:54Z chrfranke $
# #
@SET_MAKE@ @SET_MAKE@
@ -63,6 +63,8 @@ smartctl_SOURCES = \
ataprint.h \ ataprint.h \
dev_ata_cmd_set.cpp \ dev_ata_cmd_set.cpp \
dev_ata_cmd_set.h \ dev_ata_cmd_set.h \
dev_intelliprop.cpp \
dev_intelliprop.h \
dev_interface.cpp \ dev_interface.cpp \
dev_interface.h \ dev_interface.h \
dev_tunnelled.h \ dev_tunnelled.h \
@ -96,6 +98,8 @@ EXTRA_smartctl_SOURCES = \
os_netbsd.h \ os_netbsd.h \
os_openbsd.cpp \ os_openbsd.cpp \
os_openbsd.h \ os_openbsd.h \
os_os2.cpp \
os_os2.h \
os_qnxnto.cpp \ os_qnxnto.cpp \
os_qnxnto.h \ os_qnxnto.h \
os_solaris.cpp \ os_solaris.cpp \
@ -115,8 +119,8 @@ EXTRA_smartctl_SOURCES = \
if OS_WIN32_MINGW if OS_WIN32_MINGW
smartctl_LDADD += smartctl_res.o $(os_win32_manifest) smartctl_LDADD += smartctl_res.o
smartctl_DEPENDENCIES += smartctl_res.o $(os_win32_manifest) smartctl_DEPENDENCIES += smartctl_res.o
endif endif
@ -129,6 +133,8 @@ smartd_SOURCES = \
atacmds.h \ atacmds.h \
dev_ata_cmd_set.cpp \ dev_ata_cmd_set.cpp \
dev_ata_cmd_set.h \ dev_ata_cmd_set.h \
dev_intelliprop.cpp \
dev_intelliprop.h \
dev_interface.cpp \ dev_interface.cpp \
dev_interface.h \ dev_interface.h \
dev_tunnelled.h \ dev_tunnelled.h \
@ -158,6 +164,8 @@ EXTRA_smartd_SOURCES = \
os_netbsd.h \ os_netbsd.h \
os_openbsd.cpp \ os_openbsd.cpp \
os_openbsd.h \ os_openbsd.h \
os_os2.cpp \
os_os2.h \
os_qnxnto.cpp \ os_qnxnto.cpp \
os_qnxnto.h \ os_qnxnto.h \
os_solaris.cpp \ os_solaris.cpp \
@ -174,6 +182,7 @@ EXTRA_smartd_SOURCES = \
dev_legacy.cpp \ dev_legacy.cpp \
linux_nvme_ioctl.h \ linux_nvme_ioctl.h \
freebsd_nvme_ioctl.h \ freebsd_nvme_ioctl.h \
netbsd_nvme_ioctl.h \
megaraid.h megaraid.h
if OS_WIN32_MINGW if OS_WIN32_MINGW
@ -184,8 +193,8 @@ smartd_SOURCES += \
os_win32/syslog_win32.cpp \ os_win32/syslog_win32.cpp \
os_win32/syslog.h os_win32/syslog.h
smartd_LDADD += smartd_res.o $(os_win32_manifest) smartd_LDADD += smartd_res.o
smartd_DEPENDENCIES += smartd_res.o $(os_win32_manifest) smartd_DEPENDENCIES += smartd_res.o
endif endif
@ -360,6 +369,7 @@ uninstall-sysconfDATA:
smartdscript_SCRIPTS = smartd_warning.sh smartdscript_SCRIPTS = smartd_warning.sh
EXTRA_DIST = \ EXTRA_DIST = \
.editorconfig \
autogen.sh \ autogen.sh \
smartd.initd.in \ smartd.initd.in \
smartd.freebsd.initd.in \ smartd.freebsd.initd.in \
@ -380,32 +390,36 @@ EXTRA_DIST = \
os_win32/default.manifest \ os_win32/default.manifest \
os_win32/installer.nsi \ os_win32/installer.nsi \
os_win32/runcmd.c \ os_win32/runcmd.c \
os_win32/smartctl_res.rc.in \ os_win32/smartd_mailer.ps1 \
os_win32/smartd_res.rc.in \ os_win32/smartd_mailer.conf.sample.ps1 \
os_win32/smartd_warning.cmd \ os_win32/smartd_warning.cmd \
os_win32/syslogevt.mc \ os_win32/syslogevt.mc \
os_win32/update-smart-drivedb.nsi \ os_win32/update-smart-drivedb.nsi \
os_win32/wbemcli_small.h \ os_win32/wbemcli_small.h \
os_win32/versioninfo.rc.in \
os_win32/wtssendmsg.c \ os_win32/wtssendmsg.c \
$(docs_DATA) \ $(docs_DATA) \
$(examples_DATA) \ $(examples_DATA) \
$(examples_SCRIPTS) $(examples_SCRIPTS)
CLEANFILES = \ CLEANFILES = \
smartd.conf.5 \
smartd.conf.4 \
smartd.8 \ smartd.8 \
smartd.1m \ smartd.1m \
smartd.8.html \ smartd.8.html \
smartd.8.html.tmp \ smartd.8.html.tmp \
smartd.8.pdf \
smartd.8.txt \ smartd.8.txt \
smartctl.8 \ smartctl.8 \
smartctl.1m \ smartctl.1m \
smartctl.8.html \ smartctl.8.html \
smartctl.8.html.tmp \ smartctl.8.html.tmp \
smartctl.8.pdf \
smartctl.8.txt \ smartctl.8.txt \
smartd.conf.5 \
smartd.conf.4 \
smartd.conf.5.html \ smartd.conf.5.html \
smartd.conf.5.html.tmp \ smartd.conf.5.html.tmp \
smartd.conf.5.pdf \
smartd.conf.5.txt \ smartd.conf.5.txt \
smartd.initd \ smartd.initd \
smartd.freebsd.initd \ smartd.freebsd.initd \
@ -415,6 +429,10 @@ CLEANFILES = \
update-smart-drivedb \ update-smart-drivedb \
update-smart-drivedb.8 \ update-smart-drivedb.8 \
update-smart-drivedb.1m \ update-smart-drivedb.1m \
update-smart-drivedb.8.html \
update-smart-drivedb.8.html.tmp \
update-smart-drivedb.8.pdf \
update-smart-drivedb.8.txt \
SMART SMART
# 'make maintainer-clean' also removes files generated by './autogen.sh' # 'make maintainer-clean' also removes files generated by './autogen.sh'
@ -658,10 +676,12 @@ update-smart-drivedb.1m: update-smart-drivedb.8
@$(SOLARIS_MAN_FILTER) < update-smart-drivedb.8 > $@ @$(SOLARIS_MAN_FILTER) < update-smart-drivedb.8 > $@
# Commands to convert man pages into .html and .txt # Convert man pages into .html, .pdf and .txt
# TODO: configure # TODO: configure
MAN2HTML = man2html MAN2HTML = man2html
#MAN2HTML = groff -man -Thtml #MAN2HTML = groff -man -Thtml
MAN2PDF = man -Tpdf -l
#MAN2PDF = groff -man -Tpdf
MAN2TXT = groff -man -Tascii -P'-bcou' MAN2TXT = groff -man -Tascii -P'-bcou'
# Remove HTTP header and fix links in man2html output # Remove HTTP header and fix links in man2html output
@ -671,11 +691,11 @@ FIXHTML = sed -e '1s,^Content-type.*,,' \
-e 's,<A HREF="[^"]*/man2html?[^"]*">\([^<]*\)</A>,\1,g' \ -e 's,<A HREF="[^"]*/man2html?[^"]*">\([^<]*\)</A>,\1,g' \
-e 's,<A HREF="mailto:[^s][^m][^a][^"]*">\([^<]*\)</A>,\1,g' -e 's,<A HREF="mailto:[^s][^m][^a][^"]*">\([^<]*\)</A>,\1,g'
# Convert man pages into .html and .txt htmlman: smartctl.8.html smartd.8.html smartd.conf.5.html update-smart-drivedb.8.html
htmlman: smartctl.8.html smartd.8.html smartd.conf.5.html pdfman: smartctl.8.pdf smartd.8.pdf smartd.conf.5.pdf update-smart-drivedb.8.pdf
txtman: smartctl.8.txt smartd.8.txt smartd.conf.5.txt txtman: smartctl.8.txt smartd.8.txt smartd.conf.5.txt update-smart-drivedb.8.txt
%.5.html: %.5 %.5.html: %.5
$(MAN2HTML) $< > $@.tmp $(MAN2HTML) $< > $@.tmp
@ -687,6 +707,12 @@ txtman: smartctl.8.txt smartd.8.txt smartd.conf.5.txt
@echo ' $$(FIXHTML) < $@.tmp > $@' @echo ' $$(FIXHTML) < $@.tmp > $@'
@$(FIXHTML) < $@.tmp > $@ @$(FIXHTML) < $@.tmp > $@
%.5.pdf: %.5
$(MAN2PDF) $< > $@
%.8.pdf: %.8
$(MAN2PDF) $< > $@
%.5.txt: %.5 %.5.txt: %.5
$(MAN2TXT) $< > $@ $(MAN2TXT) $< > $@
@ -706,39 +732,65 @@ check:
if OS_WIN32_MINGW if OS_WIN32_MINGW
# Windows resources # Windows resources
smartctl_res.o: smartctl_res.rc smartctl_res.o: smartctl_res.rc $(os_win32_manifest)
$(WINDRES) $< $@ $(WINDRES) $< $@
smartd_res.o: smartd_res.rc syslogevt.rc smartd_res.o: smartd_res.rc syslogevt.rc $(os_win32_manifest)
$(WINDRES) -I. $< $@ $(WINDRES) $< $@
# Convert version for VERSIONINFO resource: 6.1 r3754 -> 6.1.0.3754, set Copyright year runcmda_res.o: runcmda_res.rc defadmin.manifest
$(WINDRES) $< $@
runcmdu_res.o: runcmdu_res.rc $(os_win32_manifest)
$(WINDRES) $< $@
wtssendmsg_res.o: wtssendmsg_res.rc $(os_win32_manifest)
$(WINDRES) $< $@
# Convert version for VERSIONINFO resource: 6.6 r4519 -> 6.6.0.4519,
# set description, name, version and year
WIN_RC_FILTER = { \ WIN_RC_FILTER = { \
ver=`echo '$(PACKAGE_VERSION).0' | sed -n 's,^\([0-9]*\.[0-9]*\.[0-9]*\).*$$,\1,p'` && \ ver=`echo '$(PACKAGE_VERSION).0' | sed -n 's,^\([0-9]*\.[0-9]*\.[0-9]*\).*$$,\1,p'` && \
rev=`sed -n 's,^.*REV[^"]*"\([0-9]*\).*$$,\1,p' svnversion.h` && \ rev=`sed -n 's,^.*REV[^"]*"\([0-9]*\).*$$,\1,p' svnversion.h` && \
txtver="$${ver:-0.0.0}.$${rev:-0}" && binver=`echo "$$txtver" | sed 's|\.|,|g'` && \ txtver="$${ver:-0.0.0}.$${rev:-0}" && binver=`echo "$$txtver" | sed 's|\.|,|g'` && \
yy=`sed -n 's,^.*DATE[^"]*"20\([0-9][0-9]\).*$$,\1,p' svnversion.h` && yy="$${yy:-XX}" && \ 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"; } sed -e "s|@DESC@|$$d|" -e "s|@NAME@|$$n|" -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 WIN_MAKE_RES = \
@echo ' $$(WIN_RC_FILTER) < $< > $@' echo "n=$$n d=\"$$d"'"; $$(WIN_RC_FILTER) < $< > $@'; \
@$(WIN_RC_FILTER) < $< > $@ $(WIN_RC_FILTER) < $< > $@
smartd_res.rc: os_win32/smartd_res.rc.in Makefile svnversion.h WIN_APP_MANIFEST = \
@echo ' $$(WIN_RC_FILTER) < $< > $@' if test -n '$(os_win32_manifest)'; then \
@$(WIN_RC_FILTER) < $< > $@ echo "echo '1 24 \"$(srcdir)/$(os_win32_manifest)\"' >> $@"; \
echo '1 24 "$(srcdir)/$(os_win32_manifest)"' >> $@; \
fi
smartctl_res.rc: os_win32/versioninfo.rc.in Makefile svnversion.h
@n=smartctl d="Control and Monitor Utility for SMART Disks"; $(WIN_MAKE_RES)
@$(WIN_APP_MANIFEST)
smartd_res.rc: os_win32/versioninfo.rc.in Makefile svnversion.h
@n=smartd d="SMART Disk Monitoring Daemon"; $(WIN_MAKE_RES)
echo '#include "./syslogevt.rc"' >> $@
@$(WIN_APP_MANIFEST)
runcmdu_res.rc: os_win32/versioninfo.rc.in Makefile svnversion.h
@n=runcmdu d="Run console command"; $(WIN_MAKE_RES)
@$(WIN_APP_MANIFEST)
runcmda_res.rc: os_win32/versioninfo.rc.in Makefile svnversion.h
@n=runcmda d="Run console command as admin"; $(WIN_MAKE_RES)
echo '1 24 "./defadmin.manifest"' >> $@
wtssendmsg_res.rc: os_win32/versioninfo.rc.in Makefile svnversion.h
@n=wtssendmsg d="Send console messages"; $(WIN_MAKE_RES)
@$(WIN_APP_MANIFEST)
syslogevt.rc: os_win32/syslogevt.mc syslogevt.rc: os_win32/syslogevt.mc
$(WINDMC) -b $< $(WINDMC) -b $<
# Application manifests
default.manifest.o: os_win32/default.manifest
echo '1 24 "$<"' | $(WINDRES) -J rc -o $@
defadmin.manifest.o: defadmin.manifest
echo '1 24 "$<"' | $(WINDRES) -J rc -o $@
defadmin.manifest: os_win32/default.manifest defadmin.manifest: os_win32/default.manifest
sed 's,"asInvoker","requireAdministrator",' $< > $@ sed 's,"asInvoker","requireAdministrator",' $< > $@
@ -761,6 +813,8 @@ EXEFILES_WIN32 = \
$(exedir_win32)/smartctl.exe \ $(exedir_win32)/smartctl.exe \
$(exedir_win32)/smartctl-nc.exe \ $(exedir_win32)/smartctl-nc.exe \
$(exedir_win32)/smartd.exe \ $(exedir_win32)/smartd.exe \
$(exedir_win32)/smartd_mailer.ps1 \
$(exedir_win32)/smartd_mailer.conf.sample.ps1 \
$(exedir_win32)/smartd_warning.cmd \ $(exedir_win32)/smartd_warning.cmd \
$(exedir_win32)/runcmda.exe \ $(exedir_win32)/runcmda.exe \
$(exedir_win32)/runcmdu.exe \ $(exedir_win32)/runcmdu.exe \
@ -786,11 +840,11 @@ FILES_WIN32 = \
$(docdir_win32)/checksums$(win_bits).txt \ $(docdir_win32)/checksums$(win_bits).txt \
$(docdir_win32)/smartd.conf \ $(docdir_win32)/smartd.conf \
$(docdir_win32)/smartctl.8.html \ $(docdir_win32)/smartctl.8.html \
$(docdir_win32)/smartctl.8.txt \ $(docdir_win32)/smartctl.8.pdf \
$(docdir_win32)/smartd.8.html \ $(docdir_win32)/smartd.8.html \
$(docdir_win32)/smartd.8.txt \ $(docdir_win32)/smartd.8.pdf \
$(docdir_win32)/smartd.conf.5.html \ $(docdir_win32)/smartd.conf.5.html \
$(docdir_win32)/smartd.conf.5.txt $(docdir_win32)/smartd.conf.5.pdf
if ENABLE_DRIVEDB if ENABLE_DRIVEDB
FILES_WIN32 += \ FILES_WIN32 += \
@ -801,13 +855,14 @@ CLEANFILES += \
$(FILES_WIN32) \ $(FILES_WIN32) \
defadmin.manifest \ defadmin.manifest \
distdir.mkdir \ distdir.mkdir \
runcmda.exe runcmdu.exe \ runcmda.exe runcmda_res.rc \
runcmdu.exe runcmdu_res.rc \
smartctl-nc.exe smartctl-nc.exe.tmp \ smartctl-nc.exe smartctl-nc.exe.tmp \
smartctl_res.rc smartd_res.rc \ smartctl_res.rc smartd_res.rc \
syslogevt.h \ syslogevt.h \
syslogevt.rc syslogevt_*.bin \ syslogevt.rc syslogevt_*.bin \
update-smart-drivedb.exe \ update-smart-drivedb.exe \
wtssendmsg.exe wtssendmsg.exe wtssendmsg_res.rc
# Note: Only use without options to be compatible with all variants # Note: Only use without options to be compatible with all variants
UNIX2DOS = unix2dos UNIX2DOS = unix2dos
@ -880,13 +935,16 @@ $(exedir_win32)/%.cmd: $(srcdir)/os_win32/%.cmd
$(UNIX2DOS) < $< > $@ $(UNIX2DOS) < $< > $@
touch -r $< $@ touch -r $< $@
$(exedir_win32)/%.ps1: $(srcdir)/os_win32/%.ps1
$(UNIX2DOS) < $< > $@
touch -r $< $@
$(docdir_win32)/%.html: %.html $(docdir_win32)/%.html: %.html
$(UNIX2DOS) < $< > $@ $(UNIX2DOS) < $< > $@
touch -r $< $@ touch -r $< $@
$(docdir_win32)/%.txt: %.txt $(docdir_win32)/%.pdf: %.pdf
$(UNIX2DOS) < $< > $@ cp -p $< $@
touch -r $< $@
$(docdir_win32)/%.txt: $(srcdir)/% $(docdir_win32)/%.txt: $(srcdir)/%
$(UNIX2DOS) < $< > $@ $(UNIX2DOS) < $< > $@
@ -920,37 +978,58 @@ smartctl-nc.exe: smartctl.exe
runcmd.o: os_win32/runcmd.c runcmd.o: os_win32/runcmd.c
$(CC) -c -Os $< $(CC) -c -Os $<
runcmdu.exe: runcmd.o $(os_win32_manifest) runcmdu.exe: runcmd.o runcmdu_res.o
$(CC) -o $@ $^ $(CC) -o $@ $^
runcmda.exe: runcmd.o defadmin.manifest.o runcmda.exe: runcmd.o runcmda_res.o
$(CC) -o $@ $^ $(CC) -o $@ $^
wtssendmsg.exe: os_win32/wtssendmsg.c $(os_win32_manifest) wtssendmsg.exe: os_win32/wtssendmsg.c wtssendmsg_res.o
$(CC) -Os -o $@ $< $(os_win32_manifest) -lwtsapi32 $(CC) -Os -o $@ $^ -lwtsapi32
# Build os_win32/vc10/{config.h,smart*.rc,svnversion.h} for MSVC10 from MinGW files # Build os_win32/vc14/{config.h,smart*.rc,svnversion.h} for MSVC14 from MinGW files
config-vc10: $(srcdir)/os_win32/vc10/config.h \ vcver = 14
$(srcdir)/os_win32/vc10/smartctl_res.rc \
$(srcdir)/os_win32/vc10/smartd_res.rc \
$(srcdir)/os_win32/vc10/svnversion.h
$(srcdir)/os_win32/vc10/config.h: config.h Makefile CONFIG_VC_FILES = \
sed -e '1i/* os_win32/vc10/config.h. Generated from config.h by Makefile. */' \ $(srcdir)/os_win32/vc$(vcver)/config.h \
-e 's,^#define HAVE_\(ATTR_PACKED\|GETTIMEOFDAY\|INTTYPES_H\|[DK_]*NTDDDISK_H\|STRINGS_H\|STRTOULL\|UNISTD_H\|WORKING_SNPRINTF\) 1$$,/* #undef HAVE_\1 */,' \ $(srcdir)/os_win32/vc$(vcver)/smartctl_res.rc \
-e 's,^\(#define SMARTMONTOOLS_BUILD_HOST "[^-]*\)[^"]*,\1-pc-w32vc10,' $< > $@ $(srcdir)/os_win32/vc$(vcver)/smartd_res.rc \
$(srcdir)/os_win32/vc$(vcver)/svnversion.h
$(srcdir)/os_win32/vc10/svnversion.h: svnversion.h config-vc$(vcver): $(CONFIG_VC_FILES)
$(srcdir)/os_win32/vc$(vcver)/config.h: config.h Makefile
sed -e '1i/* os_win32/vc$(vcver)/config.h. Generated from config.h by Makefile. */' \
-e 's,^#define HAVE_\(ATTR_PACKED\|GETTIMEOFDAY\|[DK_]*NTDDDISK_H\|STRINGS_H\|UNISTD_H\|WORKING_SNPRINTF\) 1$$,/* #undef HAVE_\1 */ /* VC$(vcver) */,' \
-e 's,^\(#define SMARTMONTOOLS_BUILD_HOST "[^-]*\)[^"]*,\1-pc-w32vc$(vcver),' $< > $@
$(srcdir)/os_win32/vc$(vcver)/svnversion.h: svnversion.h
cp $< $@ cp $< $@
$(srcdir)/os_win32/vc10/smartctl_res.rc: smartctl_res.rc $(srcdir)/os_win32/vc$(vcver)/smartctl_res.rc: smartctl_res.rc
cp $< $@ sed '/^1 24 /d' $< > $@
$(srcdir)/os_win32/vc10/smartd_res.rc: smartd_res.rc $(srcdir)/os_win32/vc$(vcver)/smartd_res.rc: smartd_res.rc
cp $< $@ sed '/^1 24 /d' $< > $@
clean-vc$(vcver):
rm -f $(srcdir)/os_win32/vc$(vcver)/smartmontools.VC.VC.opendb
rm -f $(srcdir)/os_win32/vc$(vcver)/smartmontools.VC.db
rm -f $(srcdir)/os_win32/vc$(vcver)/syslogevt.h
rm -rf $(srcdir)/os_win32/vc$(vcver)/Debug
rm -rf $(srcdir)/os_win32/vc$(vcver)/Release
rm -rf $(srcdir)/os_win32/vc$(vcver)/x64
distclean-vc$(vcver): clean-vc$(vcver)
rm -f $(CONFIG_VC_FILES)
maintainer-clean-vc$(vcver): distclean-vc$(vcver)
rm -rf $(srcdir)/os_win32/vc$(vcver)/.vs
endif endif
if OS_DARWIN if OS_DARWIN
# Definitions for OSX distribution # Definitions for OSX distribution
distdir_darwin = $(PACKAGE)-$(VERSION).darwin distdir_darwin = $(PACKAGE)-$(VERSION).darwin

2274
Makefile.in Normal file

File diff suppressed because it is too large Load Diff

63
NEWS
View File

@ -1,9 +1,68 @@
smartmontools NEWS smartmontools NEWS
------------------ ------------------
$Id: NEWS 4318 2016-05-07 11:18:20Z chrfranke $ $Id: NEWS 4594 2017-11-05 15:21:35Z chrfranke $
The most up-to-date version of this file is: The most up-to-date version of this file is:
http://sourceforge.net/p/smartmontools/code/HEAD/tree/trunk/smartmontools/NEWS https://sourceforge.net/p/smartmontools/code/HEAD/tree/trunk/smartmontools/NEWS
Date 2017-11-05
Summary: smartmontools release 6.6
-----------------------------------------------------------
- smartctl '-i' and '--identify': ATA ACS-4 and SATA 3.3 enhancements.
- smartctl: Control ATA write cache through SCT Feature Control
with '-s wcache-sct,ata|on|off[,p]' and '-g wcache-sct'.
- smartctl: Print ATA Pending Defects log with '-l defects'.
- smartctl '-s wcreorder,on|off': New persistent flag ',p'.
- smartctl '-s standby': Prevent temporary drive spinup.
- smartctl '-n POWERMODE': New parameter to set exit status.
- smartctl '-g security': ATA Security Level check fixed.
- smartctl '-l scttemp*': Print minimum supported ERC Time Limit.
- smartctl '-q noserial': Now also suppresses "SAS address" output.
- smartctl '-i': Print IEEE EUI-64 of NVMe namespace.
- smartctl '-c': Print NVMe 1.3 feature flags.
- smartctl '-A': Print NVMe 1.3 thermal temperature transition
statistic.
- smartctl '-g/s dsn': Get/set ATA DSN.
- smartd: Uses also device identify information to detect for duplicate
devices.
- smartd '-e dsn' directive: Set ATA DSN.
- smartd: Improved SCSI/SAS temperature logging.
- smartd: Silence emails and log messages on open errors of
'-d removable' devices.
- smartd: Exit on device open error unless '-q never' or '-d removable'
is specified (regression).
- update-smart-drivedb: Now authenticates downloaded file with GnuPG.
- update-smart-drivedb: New options '--trunk', '--no-verify' and
'--export-key'.
- Device type '-d intelliprop,N' for IntelliProp controllers.
- SCSI: Default timeout increased to 1 minute.
- configure: New options '--with-gnupg', '--with-scriptpath' and
'--with-update-smart-drivedb=X.Y'
- configure: Checks for C++11 support option and requires
'--with[out]-cxx11-option' if option unknown or no C++11 support.
- HDD, SSD and USB additions to drive database.
- New smartmontools-* mailing list addresses.
- Man page formatting reworked.
- Linux: Uses SG_IO V4 API if supported.
- Linux: Devices behind hpsa driver are no longer detected as regular
SCSI devices.
- Darwin: Initial NVMe support based on undocumented API.
- FreeBSD: Fix panic on INVARIANTS enabled kernel.
- FreeBSD: Improve ATA SMART STATUS check for legacy controllers.
- FreeBSD: Compile fix for FreeBSD-11 and newer.
- NetBSD: NVMe support.
- NetBSD: Full 28-bit ATA support.
- NetBSD: Compile fix.
- NetBSD: Use a raw disk device file.
- OpenBSD: Compile fix.
- OS/2: Support for the OS2AHCI driver, updating source code,
adding autoscan support, adding self-test support.
- Windows: Support for Windows 10 NVMe driver (stornvme.sys).
- Windows: Fix CSMI access for IRST driver 15.2.
- Windows smartd: Ability to run PowerShell scripts with '-M exec'.
- Windows smartd: New PowerShell script to send smartd warning emails
without external tools.
- Windows package: Now provides PDF man pages.
Date 2016-05-07 Date 2016-05-07
Summary: smartmontools release 6.5 Summary: smartmontools release 6.5

4
README
View File

@ -3,7 +3,7 @@ smartmontools - S.M.A.R.T. utility toolset for Darwin/Mac
OSX, FreeBSD, Linux, NetBSD, OpenBSD, Solaris, and Windows. OSX, FreeBSD, Linux, NetBSD, OpenBSD, Solaris, and Windows.
========================================================== ==========================================================
$Id: README 4120 2015-08-27 16:12:21Z samm2 $ $Id: README 4431 2017-08-08 19:38:15Z chrfranke $
== HOME == == HOME ==
The home for smartmontools is located at: The home for smartmontools is located at:
@ -15,7 +15,7 @@ patches and bug reports.
You will find a mailing list for support and other questions at: You will find a mailing list for support and other questions at:
http://lists.sourceforge.net/lists/listinfo/smartmontools-support https://listi.jpberlin.de/mailman/listinfo/smartmontools-support
== COPYING == == COPYING ==

1209
aclocal.m4 vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@
* Home page of code is: http://www.smartmontools.org * Home page of code is: http://www.smartmontools.org
* *
* Copyright (C) 2003-8 Philip Williams * Copyright (C) 2003-8 Philip Williams
* Copyright (C) 2012 Christian Franke <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2012 Christian Franke
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -20,7 +20,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
const char * atacmdnames_cpp_cvsid = "$Id: atacmdnames.cpp 4120 2015-08-27 16:12:21Z samm2 $" const char * atacmdnames_cpp_cvsid = "$Id: atacmdnames.cpp 4431 2017-08-08 19:38:15Z chrfranke $"
ATACMDNAMES_H_CVSID; ATACMDNAMES_H_CVSID;
const char cmd_reserved[] = "[RESERVED]"; const char cmd_reserved[] = "[RESERVED]";

View File

@ -5,7 +5,6 @@
* specification, which is available from http://www.t13.org/#FTP_site * specification, which is available from http://www.t13.org/#FTP_site
* *
* Home page of code is: http://www.smartmontools.org * Home page of code is: http://www.smartmontools.org
* Address of support mailing list: smartmontools-support@lists.sourceforge.net
* *
* Copyright (C) 2003-8 Philip Williams * Copyright (C) 2003-8 Philip Williams
* *
@ -23,7 +22,7 @@
#ifndef ATACMDNAMES_H_ #ifndef ATACMDNAMES_H_
#define ATACMDNAMES_H_ #define ATACMDNAMES_H_
#define ATACMDNAMES_H_CVSID "$Id: atacmdnames.h 4120 2015-08-27 16:12:21Z samm2 $\n" #define ATACMDNAMES_H_CVSID "$Id: atacmdnames.h 4431 2017-08-08 19:38:15Z chrfranke $\n"
/* Returns the name of the command (and possibly sub-command) with the given /* Returns the name of the command (and possibly sub-command) with the given
command code and feature register values. */ command code and feature register values. */

View File

@ -4,7 +4,7 @@
* Home page of code is: http://www.smartmontools.org * Home page of code is: http://www.smartmontools.org
* *
* Copyright (C) 2002-11 Bruce Allen * Copyright (C) 2002-11 Bruce Allen
* Copyright (C) 2008-15 Christian Franke * Copyright (C) 2008-17 Christian Franke
* Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org> * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
* Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org> * Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org>
* *
@ -36,7 +36,7 @@
#include "utility.h" #include "utility.h"
#include "dev_ata_cmd_set.h" // for parsed_ata_device #include "dev_ata_cmd_set.h" // for parsed_ata_device
const char * atacmds_cpp_cvsid = "$Id: atacmds.cpp 4301 2016-04-16 20:48:29Z chrfranke $" const char * atacmds_cpp_cvsid = "$Id: atacmds.cpp 4582 2017-11-03 20:54:56Z chrfranke $"
ATACMDS_H_CVSID; ATACMDS_H_CVSID;
// Print ATA debug messages? // Print ATA debug messages?
@ -339,6 +339,16 @@ void swap8(char *location){
return; return;
} }
// When using the overloaded swapx() function with member of packed ATA structs,
// it is required to pass a possibly unaligned pointer as argument.
// Clang++ 4.0 prints -Waddress-of-packed-member warning in this case.
// The SWAPV() macro below is a replacement which prevents the use of such pointers.
template <typename T>
static T get_swapx_val(T x)
{ swapx(&x); return x; }
#define SWAPV(x) ((x) = get_swapx_val(x))
// Invalidate serial number and WWN and adjust checksum in IDENTIFY data // Invalidate serial number and WWN and adjust checksum in IDENTIFY data
static void invalidate_serno(ata_identify_device * id) static void invalidate_serno(ata_identify_device * id)
{ {
@ -355,13 +365,13 @@ static void invalidate_serno(ata_identify_device * id)
#ifndef __NetBSD__ #ifndef __NetBSD__
bool must_swap = !!isbigendian(); bool must_swap = !!isbigendian();
if (must_swap) if (must_swap)
swapx(id->words088_255+255-88); SWAPV(id->words088_255[255-88]);
#endif #endif
if ((id->words088_255[255-88] & 0x00ff) == 0x00a5) if ((id->words088_255[255-88] & 0x00ff) == 0x00a5)
id->words088_255[255-88] += sum << 8; id->words088_255[255-88] += sum << 8;
#ifndef __NetBSD__ #ifndef __NetBSD__
if (must_swap) if (must_swap)
swapx(id->words088_255+255-88); SWAPV(id->words088_255[255-88]);
#endif #endif
} }
@ -538,6 +548,7 @@ int smartcommandhandler(ata_device * device, smart_command_set command, int sele
break; break;
case STATUS_CHECK: case STATUS_CHECK:
in.out_needed.lba_high = in.out_needed.lba_mid = true; // Status returned here in.out_needed.lba_high = in.out_needed.lba_mid = true; // Status returned here
/* FALLTHRU */
case STATUS: case STATUS:
in.in_regs.features = ATA_SMART_STATUS; in.in_regs.features = ATA_SMART_STATUS;
break; break;
@ -1001,7 +1012,7 @@ int ataReadSmartValues(ata_device * device, struct ata_smart_values *data){
swap2((char *)&(data->revnumber)); swap2((char *)&(data->revnumber));
swap2((char *)&(data->total_time_to_complete_off_line)); swap2((char *)&(data->total_time_to_complete_off_line));
swap2((char *)&(data->smart_capability)); swap2((char *)&(data->smart_capability));
swapx(&data->extend_test_completion_time_w); SWAPV(data->extend_test_completion_time_w);
for (i=0; i<NUMBER_ATA_SMART_ATTRIBUTES; i++){ for (i=0; i<NUMBER_ATA_SMART_ATTRIBUTES; i++){
struct ata_smart_attribute *x=data->vendor_attributes+i; struct ata_smart_attribute *x=data->vendor_attributes+i;
swap2((char *)&(x->flags)); swap2((char *)&(x->flags));
@ -1088,15 +1099,45 @@ bool ataReadExtSelfTestLog(ata_device * device, ata_smart_extselftestlog * log,
check_multi_sector_sum(log, nsectors, "SMART Extended Self-test Log Structure"); check_multi_sector_sum(log, nsectors, "SMART Extended Self-test Log Structure");
if (isbigendian()) { if (isbigendian()) {
swapx(&log->log_desc_index); SWAPV(log->log_desc_index);
for (unsigned i = 0; i < nsectors; i++) { for (unsigned i = 0; i < nsectors; i++) {
for (unsigned j = 0; j < 19; j++) for (unsigned j = 0; j < 19; j++)
swapx(&log->log_descs[i].timestamp); SWAPV(log->log_descs[i].timestamp);
} }
} }
return true; return true;
} }
// Write GP Log page(s)
bool ataWriteLogExt(ata_device * device, unsigned char logaddr,
unsigned page, void * data, unsigned nsectors)
{
ata_cmd_in in;
in.in_regs.command = ATA_WRITE_LOG_EXT;
in.set_data_out(data, nsectors);
in.in_regs.lba_low = logaddr;
in.in_regs.lba_mid_16 = page;
in.set_data_out(data, nsectors);
ata_cmd_out out;
if (!device->ata_pass_through(in, out)) { // TODO: Debug output
if (nsectors <= 1) {
pout("ATA_WRITE_LOG_EXT (addr=0x%02x, page=%u, n=%u) failed: %s\n",
logaddr, page, nsectors, device->get_errmsg());
return false;
}
// Recurse to retry with single sectors,
// multi-sector reads may not be supported by ioctl.
for (unsigned i = 0; i < nsectors; i++) {
if (!ataWriteLogExt(device, logaddr, page + i,
(char *)data + 512*i, 1))
return false;
}
}
return true;
}
// Read GP Log page(s) // Read GP Log page(s)
bool ataReadLogExt(ata_device * device, unsigned char logaddr, bool ataReadLogExt(ata_device * device, unsigned char logaddr,
@ -1165,7 +1206,7 @@ int ataReadLogDirectory(ata_device * device, ata_smart_log_directory * data, boo
// swap endian order if needed // swap endian order if needed
if (isbigendian()) if (isbigendian())
swapx(&data->logversion); SWAPV(data->logversion);
return 0; return 0;
} }
@ -1488,13 +1529,13 @@ bool ataReadExtErrorLog(ata_device * device, ata_smart_exterrlog * log,
check_multi_sector_sum(log, nsectors, "SMART Extended Comprehensive Error Log Structure"); check_multi_sector_sum(log, nsectors, "SMART Extended Comprehensive Error Log Structure");
if (isbigendian()) { if (isbigendian()) {
swapx(&log->device_error_count); SWAPV(log->device_error_count);
swapx(&log->error_log_index); SWAPV(log->error_log_index);
for (unsigned i = 0; i < nsectors; i++) { for (unsigned i = 0; i < nsectors; i++) {
for (unsigned j = 0; j < 4; j++) { for (unsigned j = 0; j < 4; j++) {
for (unsigned k = 0; k < 5; k++) for (unsigned k = 0; k < 5; k++)
swapx(&log[i].error_logs[j].commands[k].timestamp); SWAPV(log[i].error_logs[j].commands[k].timestamp);
swapx(&log[i].error_logs[j].error.timestamp); SWAPV(log[i].error_logs[j].error.timestamp);
} }
} }
} }
@ -2227,15 +2268,16 @@ int ataReadSCTStatus(ata_device * device, ata_sct_status_response * sts)
// swap endian order if needed // swap endian order if needed
if (isbigendian()){ if (isbigendian()){
swapx(&sts->format_version); SWAPV(sts->format_version);
swapx(&sts->sct_version); SWAPV(sts->sct_version);
swapx(&sts->sct_spec); SWAPV(sts->sct_spec);
swapx(&sts->ext_status_code); SWAPV(sts->ext_status_code);
swapx(&sts->action_code); SWAPV(sts->action_code);
swapx(&sts->function_code); SWAPV(sts->function_code);
swapx(&sts->over_limit_count); SWAPV(sts->over_limit_count);
swapx(&sts->under_limit_count); SWAPV(sts->under_limit_count);
swapx(&sts->smart_status); SWAPV(sts->smart_status);
SWAPV(sts->min_erc_time);
} }
// Check format version // Check format version
@ -2268,9 +2310,9 @@ int ataReadSCTTempHist(ata_device * device, ata_sct_temperature_history_table *
// swap endian order if needed // swap endian order if needed
if (isbigendian()) { if (isbigendian()) {
swapx(&cmd.action_code); SWAPV(cmd.action_code);
swapx(&cmd.function_code); SWAPV(cmd.function_code);
swapx(&cmd.table_id); SWAPV(cmd.table_id);
} }
// write command via SMART log page 0xe0 // write command via SMART log page 0xe0
@ -2298,17 +2340,19 @@ int ataReadSCTTempHist(ata_device * device, ata_sct_temperature_history_table *
// swap endian order if needed // swap endian order if needed
if (isbigendian()){ if (isbigendian()){
swapx(&tmh->format_version); SWAPV(tmh->format_version);
swapx(&tmh->sampling_period); SWAPV(tmh->sampling_period);
swapx(&tmh->interval); SWAPV(tmh->interval);
swapx(&tmh->cb_index); SWAPV(tmh->cb_index);
swapx(&tmh->cb_size); SWAPV(tmh->cb_size);
} }
return 0; return 0;
} }
// Get/Set Write Cache Reordering // Common function for Get/Set SCT Feature Control:
int ataGetSetSCTWriteCacheReordering(ata_device * device, bool enable, bool persistent, bool set) // Write Cache, Write Cache Reordering, etc.
static int ataGetSetSCTFeatureControl(ata_device * device, unsigned short feature_code,
unsigned short state, bool persistent, bool set)
{ {
// Check initial status // Check initial status
ata_sct_status_response sts; ata_sct_status_response sts;
@ -2327,17 +2371,17 @@ int ataGetSetSCTWriteCacheReordering(ata_device * device, bool enable, bool pers
// CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK) // CAUTION: DO NOT CHANGE THIS VALUE (SOME ACTION CODES MAY ERASE DISK)
cmd.action_code = 4; // Feature Control command cmd.action_code = 4; // Feature Control command
cmd.function_code = (set ? 1 : 2); // 1=Set, 2=Get cmd.function_code = (set ? 1 : 2); // 1=Set, 2=Get
cmd.feature_code = 2; // Enable/Disable Write Cache Reordering cmd.feature_code = feature_code;
cmd.state = (enable ? 1 : 2); // 1 enable, 2 disable cmd.state = state;
cmd.option_flags = (persistent ? 0x01 : 0x00); cmd.option_flags = (persistent ? 0x01 : 0x00);
// swap endian order if needed // swap endian order if needed
if (isbigendian()) { if (isbigendian()) {
swapx(&cmd.action_code); SWAPV(cmd.action_code);
swapx(&cmd.function_code); SWAPV(cmd.function_code);
swapx(&cmd.feature_code); SWAPV(cmd.feature_code);
swapx(&cmd.state); SWAPV(cmd.state);
swapx(&cmd.option_flags); SWAPV(cmd.option_flags);
} }
// write command via SMART log page 0xe0 // write command via SMART log page 0xe0
@ -2359,7 +2403,7 @@ int ataGetSetSCTWriteCacheReordering(ata_device * device, bool enable, bool pers
(!set ? 'G' : 'S'), device->get_errmsg()); (!set ? 'G' : 'S'), device->get_errmsg());
return -1; return -1;
} }
int state = out.out_regs.sector_count | (out.out_regs.lba_low << 8); state = out.out_regs.sector_count | (out.out_regs.lba_low << 8);
// re-read and check SCT status // re-read and check SCT status
if (ataReadSCTStatus(device, &sts)) if (ataReadSCTStatus(device, &sts))
@ -2373,6 +2417,19 @@ int ataGetSetSCTWriteCacheReordering(ata_device * device, bool enable, bool pers
return state; return state;
} }
// Get/Set Write Cache Reordering
int ataGetSetSCTWriteCacheReordering(ata_device * device, bool enable, bool persistent, bool set)
{
return ataGetSetSCTFeatureControl(device, 2 /* Enable/Disable Write Cache Reordering */,
(enable ? 1 : 2), persistent, set);
}
// Get/Set Write Cache (force enable, force disable,
int ataGetSetSCTWriteCache(ata_device * device, unsigned short state, bool persistent, bool set)
{
return ataGetSetSCTFeatureControl(device, 1 /* Enable/Disable Write Cache */,
state, persistent, set);
}
// Set SCT Temperature Logging Interval // Set SCT Temperature Logging Interval
int ataSetSCTTempInterval(ata_device * device, unsigned interval, bool persistent) int ataSetSCTTempInterval(ata_device * device, unsigned interval, bool persistent)
@ -2400,11 +2457,11 @@ int ataSetSCTTempInterval(ata_device * device, unsigned interval, bool persisten
// swap endian order if needed // swap endian order if needed
if (isbigendian()) { if (isbigendian()) {
swapx(&cmd.action_code); SWAPV(cmd.action_code);
swapx(&cmd.function_code); SWAPV(cmd.function_code);
swapx(&cmd.feature_code); SWAPV(cmd.feature_code);
swapx(&cmd.state); SWAPV(cmd.state);
swapx(&cmd.option_flags); SWAPV(cmd.option_flags);
} }
// write command via SMART log page 0xe0 // write command via SMART log page 0xe0
@ -2452,10 +2509,10 @@ static int ataGetSetSCTErrorRecoveryControltime(ata_device * device, unsigned ty
// swap endian order if needed // swap endian order if needed
if (isbigendian()) { if (isbigendian()) {
swapx(&cmd.action_code); SWAPV(cmd.action_code);
swapx(&cmd.function_code); SWAPV(cmd.function_code);
swapx(&cmd.selection_code); SWAPV(cmd.selection_code);
swapx(&cmd.time_limit); SWAPV(cmd.time_limit);
} }
// write command via SMART log page 0xe0 // write command via SMART log page 0xe0

View File

@ -4,7 +4,7 @@
* Home page of code is: http://www.smartmontools.org * Home page of code is: http://www.smartmontools.org
* *
* Copyright (C) 2002-11 Bruce Allen * Copyright (C) 2002-11 Bruce Allen
* Copyright (C) 2008-15 Christian Franke * Copyright (C) 2008-17 Christian Franke
* Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org> * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -25,7 +25,7 @@
#ifndef ATACMDS_H_ #ifndef ATACMDS_H_
#define ATACMDS_H_ #define ATACMDS_H_
#define ATACMDS_H_CVSID "$Id: atacmds.h 4162 2015-10-31 16:36:16Z chrfranke $" #define ATACMDS_H_CVSID "$Id: atacmds.h 4419 2017-04-17 13:20:31Z chrfranke $"
#include "dev_interface.h" // ata_device #include "dev_interface.h" // ata_device
@ -74,7 +74,10 @@ typedef enum {
#define ATA_IDLE 0xe3 #define ATA_IDLE 0xe3
#define ATA_SMART_CMD 0xb0 #define ATA_SMART_CMD 0xb0
#define ATA_SECURITY_FREEZE_LOCK 0xf5 #define ATA_SECURITY_FREEZE_LOCK 0xf5
#ifndef ATA_SET_FEATURES
#define ATA_SET_FEATURES 0xef #define ATA_SET_FEATURES 0xef
#endif
#define ATA_STANDBY 0xe2
#define ATA_STANDBY_IMMEDIATE 0xe0 #define ATA_STANDBY_IMMEDIATE 0xe0
// SET_FEATURES subcommands // SET_FEATURES subcommands
@ -86,9 +89,11 @@ typedef enum {
#define ATA_ENABLE_APM 0x05 #define ATA_ENABLE_APM 0x05
#define ATA_ENABLE_WRITE_CACHE 0x02 #define ATA_ENABLE_WRITE_CACHE 0x02
#define ATA_ENABLE_READ_LOOK_AHEAD 0xaa #define ATA_ENABLE_READ_LOOK_AHEAD 0xaa
#define ATA_ENABLE_DISABLE_DSN 0x63
// 48-bit commands // 48-bit commands
#define ATA_READ_LOG_EXT 0x2F #define ATA_READ_LOG_EXT 0x2F
#define ATA_WRITE_LOG_EXT 0x3F
// ATA Specification Feature Register Values (SMART Subcommands). // ATA Specification Feature Register Values (SMART Subcommands).
// Note that some are obsolete as of ATA-7. // Note that some are obsolete as of ATA-7.
@ -546,7 +551,8 @@ struct ata_sct_status_response
unsigned int over_limit_count; // 206-209: # intervals since last reset with temperature > Max Op Limit unsigned int over_limit_count; // 206-209: # intervals since last reset with temperature > Max Op Limit
unsigned int under_limit_count; // 210-213: # intervals since last reset with temperature < Min Op Limit unsigned int under_limit_count; // 210-213: # intervals since last reset with temperature < Min Op Limit
unsigned short smart_status; // 214-215: LBA(32:8) of SMART RETURN STATUS (0, 0x2cf4, 0xc24f) (ACS-4) unsigned short smart_status; // 214-215: LBA(32:8) of SMART RETURN STATUS (0, 0x2cf4, 0xc24f) (ACS-4)
unsigned char bytes216_479[479-216+1]; // 216-479: reserved unsigned short min_erc_time; // 216-217: Minimum supported value for ERC (ACS-4)
unsigned char bytes216_479[479-218+1]; // 218-479: reserved
unsigned char vendor_specific[32];// 480-511: vendor specific unsigned char vendor_specific[32];// 480-511: vendor specific
} ATTR_PACKED; } ATTR_PACKED;
#pragma pack() #pragma pack()
@ -779,6 +785,10 @@ int ataReadSelfTestLog(ata_device * device, ata_smart_selftestlog * data,
int ataReadSelectiveSelfTestLog(ata_device * device, struct ata_selective_self_test_log *data); int ataReadSelectiveSelfTestLog(ata_device * device, struct ata_selective_self_test_log *data);
int ataReadLogDirectory(ata_device * device, ata_smart_log_directory *, bool gpl); int ataReadLogDirectory(ata_device * device, ata_smart_log_directory *, bool gpl);
// Write GP Log page(s)
bool ataWriteLogExt(ata_device * device, unsigned char logaddr,
unsigned page, void * data, unsigned nsectors);
// Read GP Log page(s) // Read GP Log page(s)
bool ataReadLogExt(ata_device * device, unsigned char logaddr, bool ataReadLogExt(ata_device * device, unsigned char logaddr,
unsigned char features, unsigned page, unsigned char features, unsigned page,
@ -844,6 +854,12 @@ int ataSmartSupport(const ata_identify_device * drive);
// -1: error // -1: error
int ataGetSetSCTWriteCacheReordering(ata_device * device, bool enable, bool persistent, bool set); int ataGetSetSCTWriteCacheReordering(ata_device * device, bool enable, bool persistent, bool set);
// Return values:
// 1: Write cache controled by ATA Set Features command
// 2: Force enable write cache
// 3: Force disable write cache
int ataGetSetSCTWriteCache(ata_device * device, unsigned short state, bool persistent, bool set);
// Return values: // Return values:
// 1: SMART enabled // 1: SMART enabled
// 0: SMART disabled // 0: SMART disabled

View File

@ -3,7 +3,7 @@
* *
* Home page of code is: http://www.smartmontools.org * Home page of code is: http://www.smartmontools.org
* *
* Copyright (C) 2012-15 Christian Franke * Copyright (C) 2012-17 Christian Franke
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -18,7 +18,7 @@
#include "config.h" #include "config.h"
#include "ataidentify.h" #include "ataidentify.h"
const char * ataidentify_cpp_cvsid = "$Id: ataidentify.cpp 4120 2015-08-27 16:12:21Z samm2 $" const char * ataidentify_cpp_cvsid = "$Id: ataidentify.cpp 4573 2017-10-29 15:13:58Z chrfranke $"
ATAIDENTIFY_H_CVSID; ATAIDENTIFY_H_CVSID;
#include "int64.h" #include "int64.h"
@ -34,7 +34,7 @@ const char * ataidentify_cpp_cvsid = "$Id: ataidentify.cpp 4120 2015-08-27 16:12
// Tables 29 and 39 of T13/1699-D (ATA8-ACS) Revision 6a, September 6, 2008 // Tables 29 and 39 of T13/1699-D (ATA8-ACS) Revision 6a, September 6, 2008
// Tables 50 and 61 of T13/2015-D (ACS-2) Revision 7, June 22, 2011 // Tables 50 and 61 of T13/2015-D (ACS-2) Revision 7, June 22, 2011
// Tables 45 and 50 of T13/2161-D (ACS-3) Revision 5, October 28, 2013 // Tables 45 and 50 of T13/2161-D (ACS-3) Revision 5, October 28, 2013
// Table 44 of T13/BSR INCITS 529 (ACS-4) Revision 08, April 28, 2015 (ATAPI removed) // Table 55 of T13/BSR INCITS 529 (ACS-4) Revision 20, October 26, 2017 (ATAPI removed)
const char * const identify_descriptions[] = { const char * const identify_descriptions[] = {
" 0 General configuration", " 0 General configuration",
@ -121,8 +121,8 @@ const char * const identify_descriptions[] = {
". 11 Cmds during sanitize as specified by this standard", // ACS-3 ". 11 Cmds during sanitize as specified by this standard", // ACS-3
". 10 SANITIZE ANTIFREEZE LOCK EXT supported", // ACS-3 ". 10 SANITIZE ANTIFREEZE LOCK EXT supported", // ACS-3
". 9 Reserved", ". 9 Reserved",
". 8 Bits 7:0 are valid", ". 8 Bits 7:0 are valid [OBS-ACS-4]",
". 7:0 Current sectors per DRQ on READ/WRITE MULTIPLE", ". 7:0 Current number of sectors per DRQ [OBS-ACS-4]",
" 60-61 User addressable sectors for 28-bit commands (DWord)", " 60-61 User addressable sectors for 28-bit commands (DWord)",
" 62 Single Word DMA modes [OBS-3]", " 62 Single Word DMA modes [OBS-3]",
@ -190,7 +190,9 @@ const char * const identify_descriptions[] = {
". 0 Must be set to 0", ". 0 Must be set to 0",
" 77 Serial ATA additional capabilities", // ACS-3 " 77 Serial ATA additional capabilities", // ACS-3
". 15:7 Reserved for Serial ATA", ". 15:9 Reserved for Serial ATA",
". 8 Power Disable feature always enabled", // ACS-4
". 7 DevSleep to ReducedPwrState supported", // ACS-4
". 6 RECEIVE/SEND FPDMA QUEUED supported", ". 6 RECEIVE/SEND FPDMA QUEUED supported",
". 5 NCQ Queue Management supported", ". 5 NCQ Queue Management supported",
". 4 NCQ Streaming supported", ". 4 NCQ Streaming supported",
@ -198,7 +200,12 @@ const char * const identify_descriptions[] = {
". 0 Must be set to 0", ". 0 Must be set to 0",
" 78 Serial ATA features supported", " 78 Serial ATA features supported",
". 15:8 Reserved for Serial ATA", ". 15:13 Reserved for Serial ATA",
". 12 Power Disable feature supported", // ACS-4
". 11 Rebuild Assist feature set supported", // ACS-4
". 10 Reserved for Serial ATA",
". 9 Hybrid Information supported", // ACS-4
". 8 Device Sleep feature supported", // ACS-4
". 7 NCQ Autosense supported", // ACS-3 ". 7 NCQ Autosense supported", // ACS-3
". 6 Software Settings Preservation supported", ". 6 Software Settings Preservation supported",
". 5 Hardware Feature Control supported", // ACS-3 ". 5 Hardware Feature Control supported", // ACS-3
@ -209,7 +216,11 @@ const char * const identify_descriptions[] = {
". 0 Must be set to 0", ". 0 Must be set to 0",
" 79 Serial ATA features enabled", " 79 Serial ATA features enabled",
". 15:8 Reserved for Serial ATA", ". 15:12 Reserved for Serial ATA",
". 11 Rebuild Assist feature set enabled", // ACS-4
". 10 Power Disable feature enabled", // ACS-4
". 9 Hybrid Information enabled", // ACS-4
". 8 Device Sleep feature enabled", // ACS-4
". 7 Automatic Partial to Slumber transitions enabled", // ACS-3 ". 7 Automatic Partial to Slumber transitions enabled", // ACS-3
". 6 Software Settings Preservation enabled", ". 6 Software Settings Preservation enabled",
". 5 Hardware Feature Control enabled", // ACS-3 ". 5 Hardware Feature Control enabled", // ACS-3
@ -225,9 +236,9 @@ const char * const identify_descriptions[] = {
". 10 ACS-3 supported", ". 10 ACS-3 supported",
". 9 ACS-2 supported", ". 9 ACS-2 supported",
". 8 ATA8-ACS supported", ". 8 ATA8-ACS supported",
". 7 ATA/ATAPI-7 supported", ". 7 ATA/ATAPI-7 supported [OBS-ACS-4]",
". 6 ATA/ATAPI-6 supported", ". 6 ATA/ATAPI-6 supported [OBS-ACS-4]",
". 5 ATA/ATAPI-5 supported", ". 5 ATA/ATAPI-5 supported [OBS-ACS-4]",
". 4 ATA/ATAPI-4 supported [OBS-8]", ". 4 ATA/ATAPI-4 supported [OBS-8]",
". 3 ATA-3 supported [OBS-7]", ". 3 ATA-3 supported [OBS-7]",
". 2 ATA-2 supported [OBS-6]", ". 2 ATA-2 supported [OBS-6]",
@ -278,10 +289,10 @@ const char * const identify_descriptions[] = {
". 10 URG bit for WRITE STREAM (DMA) EXT supported [OBS-8]", ". 10 URG bit for WRITE STREAM (DMA) EXT supported [OBS-8]",
". 9 URG bit for READ STREAM (DMA) EXT supported [OBS-8]", ". 9 URG bit for READ STREAM (DMA) EXT supported [OBS-8]",
". 8 64-bit World Wide Name supported", ". 8 64-bit World Wide Name supported",
". 7 WRITE DMA QUEUED FUA EXT supported", ". 7 WRITE DMA QUEUED FUA EXT supported [OBS-ACS-2]",
". 6 WRITE DMA/MULTIPLE FUA EXT supported", ". 6 WRITE DMA/MULTIPLE FUA EXT supported",
". 5 GPL feature set supported", ". 5 GPL feature set supported",
". 4 Streaming feature set supported [OBS-ACS-3]", ". 4 Streaming feature set supported",
". 3 Media Card Pass Through Command supported [OBS-ACS-2]", ". 3 Media Card Pass Through Command supported [OBS-ACS-2]",
". 2 Media serial number supported [RES-ACS-3]", ". 2 Media serial number supported [RES-ACS-3]",
". 1 SMART self-test supported", ". 1 SMART self-test supported",
@ -406,7 +417,7 @@ const char * const identify_descriptions[] = {
". 3:0 2^X logical sectors per physical sector", ". 3:0 2^X logical sectors per physical sector",
"107 Inter-seek delay for ISO 7779 acoustic testing", "107 Inter-seek delay for ISO 7779 acoustic testing",
"108-111 64-bit World Wide Name", "108-111 World Wide Name",
"112-115 Reserved", // ATA-7: Reserved for world wide name extension to 128 bits "112-115 Reserved", // ATA-7: Reserved for world wide name extension to 128 bits
"116 Reserved for TLC [OBS-ACS-3]", "116 Reserved for TLC [OBS-ACS-3]",
"117-118 Logical sector size (DWord)", "117-118 Logical sector size (DWord)",
@ -471,7 +482,7 @@ const char * const identify_descriptions[] = {
"168 Form factor", "168 Form factor",
". 15:4 Reserved", ". 15:4 Reserved",
". 3:0 Nominal form factor: -, 5.25, 3.5, 2.5, 1.8, <1.8", ". 3:0 Nominal form factor: -, 5.25, 3.5, 2.5, 1.8, ...", // <1.8, ACS-4: mSATA, M.2, ...
"169 DATA SET MANAGEMENT command support", "169 DATA SET MANAGEMENT command support",
". 15:1 Reserved", ". 15:1 Reserved",
@ -527,10 +538,11 @@ const char * const identify_descriptions[] = {
"222 Transport major version number", "222 Transport major version number",
". 15:12 Transport: 0x0 = Parallel, 0x1 = Serial, 0xe = PCIe", // PCIe: ACS-4 ". 15:12 Transport: 0x0 = Parallel, 0x1 = Serial, 0xe = PCIe", // PCIe: ACS-4
". 11:8 Reserved | Reserved", ". 11:9 Reserved | Reserved",
". 7 Reserved | SATA 3.2", ". 8 Reserved | SATA 3.3", // ACS-4
". 6 Reserved | SATA 3.1", ". 7 Reserved | SATA 3.2", // ACS-4
". 5 Reserved | SATA 3.0", ". 6 Reserved | SATA 3.1", // ACS-3
". 5 Reserved | SATA 3.0", // ACS-2
". 4 Reserved | SATA 2.6", ". 4 Reserved | SATA 2.6",
". 3 Reserved | SATA 2.5", ". 3 Reserved | SATA 2.5",
". 2 Reserved | SATA II: Extensions", ". 2 Reserved | SATA II: Extensions",
@ -626,7 +638,7 @@ void ata_print_identify_data(const void * id, bool all_words, int bit_level)
if (bit >= 0) { if (bit >= 0) {
int b; int b;
if (bit2 >= 0) if (bit2 >= 0)
b = (w >> bit2) & ~(~0 << (bit-bit2+1)); b = (w >> bit2) & ~(~0U << (bit-bit2+1));
else else
b = (w >> bit) & 1; b = (w >> bit) & 1;

View File

@ -3,7 +3,7 @@
* *
* Home page of code is: http://www.smartmontools.org * Home page of code is: http://www.smartmontools.org
* *
* Copyright (C) 2012 Christian Franke <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2012 Christian Franke
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -18,7 +18,7 @@
#ifndef ATAIDENTIFY_H #ifndef ATAIDENTIFY_H
#define ATAIDENTIFY_H #define ATAIDENTIFY_H
#define ATAIDENTIFY_H_CVSID "$Id: ataidentify.h 4120 2015-08-27 16:12:21Z samm2 $" #define ATAIDENTIFY_H_CVSID "$Id: ataidentify.h 4431 2017-08-08 19:38:15Z chrfranke $"
void ata_print_identify_data(const void * id, bool all_words, int bit_level); void ata_print_identify_data(const void * id, bool all_words, int bit_level);

View File

@ -4,7 +4,7 @@
* Home page of code is: http://www.smartmontools.org * Home page of code is: http://www.smartmontools.org
* *
* Copyright (C) 2002-11 Bruce Allen * Copyright (C) 2002-11 Bruce Allen
* Copyright (C) 2008-16 Christian Franke * Copyright (C) 2008-17 Christian Franke
* Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org> * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -40,7 +40,7 @@
#include "utility.h" #include "utility.h"
#include "knowndrives.h" #include "knowndrives.h"
const char * ataprint_cpp_cvsid = "$Id: ataprint.cpp 4256 2016-03-27 16:51:32Z chrfranke $" const char * ataprint_cpp_cvsid = "$Id: ataprint.cpp 4573 2017-10-29 15:13:58Z chrfranke $"
ATAPRINT_H_CVSID; ATAPRINT_H_CVSID;
@ -440,7 +440,13 @@ static int find_msb(unsigned short word)
static const char * get_ata_major_version(const ata_identify_device * drive) static const char * get_ata_major_version(const ata_identify_device * drive)
{ {
// Table 13 of T13/1153D (ATA/ATAPI-4) revision 18, August 19, 1998
// Table 48 of T13/BSR INCITS 529 (ACS-4) Revision 16, February 21, 2017
switch (find_msb(drive->major_rev_num)) { switch (find_msb(drive->major_rev_num)) {
case 14: return "ACS >4 (14)";
case 13: return "ACS >4 (13)";
case 12: return "ACS >4 (12)";
case 11: return "ACS-4";
case 10: return "ACS-3"; case 10: return "ACS-3";
case 9: return "ACS-2"; case 9: return "ACS-2";
case 8: return "ATA8-ACS"; case 8: return "ATA8-ACS";
@ -540,11 +546,13 @@ static const char * get_pata_version(unsigned short word222, char (& buf)[32])
} }
} }
static const char * get_sata_version(unsigned short word222, char (& buf)[32]) static const char * get_sata_version(unsigned short word222)
{ {
switch (find_msb(word222 & 0x0fff)) { switch (find_msb(word222 & 0x0fff)) {
default: snprintf(buf, sizeof(buf), case 11: return "SATA >3.3 (11)";
"SATA >3.2 (0x%03x)", word222 & 0x0fff); return buf; case 10: return "SATA >3.3 (10)";
case 9: return "SATA >3.3 (9)";
case 8: return "SATA 3.3";
case 7: return "SATA 3.2"; case 7: return "SATA 3.2";
case 6: return "SATA 3.1"; case 6: return "SATA 3.1";
case 5: return "SATA 3.0"; case 5: return "SATA 3.0";
@ -553,7 +561,7 @@ static const char * get_sata_version(unsigned short word222, char (& buf)[32])
case 2: return "SATA II Ext"; case 2: return "SATA II Ext";
case 1: return "SATA 1.0a"; case 1: return "SATA 1.0a";
case 0: return "ATA8-AST"; case 0: return "ATA8-AST";
case -1: return "Unknown"; default: return "Unknown";
} }
} }
@ -697,16 +705,17 @@ static void print_drive_info(const ata_identify_device * drive,
pout("ATA Version is: %s\n", infofound(ataver.c_str())); pout("ATA Version is: %s\n", infofound(ataver.c_str()));
// Print Transport specific version // Print Transport specific version
// cppcheck-suppress variableScope
char buf[32] = "";
unsigned short word222 = drive->words088_255[222-88]; unsigned short word222 = drive->words088_255[222-88];
if (word222 != 0x0000 && word222 != 0xffff) switch (word222 >> 12) { if (word222 != 0x0000 && word222 != 0xffff) switch (word222 >> 12) {
case 0x0: // PATA case 0x0: // PATA
{
char buf[32] = "";
pout("Transport Type: Parallel, %s\n", get_pata_version(word222, buf)); pout("Transport Type: Parallel, %s\n", get_pata_version(word222, buf));
}
break; break;
case 0x1: // SATA case 0x1: // SATA
{ {
const char * sataver = get_sata_version(word222, buf); const char * sataver = get_sata_version(word222);
const char * maxspeed = get_sata_maxspeed(drive); const char * maxspeed = get_sata_maxspeed(drive);
const char * curspeed = get_sata_curspeed(drive); const char * curspeed = get_sata_curspeed(drive);
pout("SATA Version is: %s%s%s%s%s%s\n", sataver, pout("SATA Version is: %s%s%s%s%s%s\n", sataver,
@ -1183,8 +1192,10 @@ static unsigned GetNumLogSectors(const ata_smart_log_directory * logdir, unsigne
// Get name of log. // Get name of log.
static const char * GetLogName(unsigned logaddr) static const char * GetLogName(unsigned logaddr)
{ {
// Table 205 of T13/BSR INCITS 529 (ACS-4) Revision 08, April 28, 2015 // Table A.2 of T13/2015-D (ACS-2) Revision 7, June 22, 2011
// Table 112 of Serial ATA Revision 3.2, August 7, 2013 // Table 112 of Serial ATA Revision 3.2, August 7, 2013
// Table A.2 of T13/2161-D (ACS-3) Revision 5, October 28, 2013
// Table 204 of T13/BSR INCITS 529 (ACS-4) Revision 16, February 21, 2017
switch (logaddr) { switch (logaddr) {
case 0x00: return "Log Directory"; case 0x00: return "Log Directory";
case 0x01: return "Summary SMART error log"; case 0x01: return "Summary SMART error log";
@ -1200,15 +1211,15 @@ static const char * GetLogName(unsigned logaddr)
case 0x0b: return "Reserved for CFA"; // ACS-3 case 0x0b: return "Reserved for CFA"; // ACS-3
case 0x0c: return "Pending Defects log"; // ACS-4 case 0x0c: return "Pending Defects log"; // ACS-4
case 0x0d: return "LPS Mis-alignment log"; // ACS-2 case 0x0d: return "LPS Mis-alignment log"; // ACS-2
case 0x0e: return "Reserved for ZAC-2"; // ACS-4
case 0x0f: return "Sense Data for Successful NCQ Cmds log"; // ACS-4 case 0x0f: return "Sense Data for Successful NCQ Cmds log"; // ACS-4
case 0x10: return "SATA NCQ Queued Error log"; case 0x10: return "NCQ Command Error log";
case 0x11: return "SATA Phy Event Counters log"; case 0x11: return "SATA Phy Event Counters log";
//case 0x12: return "SATA NCQ Queue Management log"; // SATA 3.0/3.1 //case 0x12: return "SATA NCQ Queue Management log"; // SATA 3.0/3.1, ACS-3
case 0x12: return "SATA NCQ NON-DATA log"; // SATA 3.2 case 0x12: return "SATA NCQ Non-Data log"; // SATA 3.2, ACS-4
case 0x13: return "SATA NCQ Send and Receive log"; // SATA 3.1 case 0x13: return "SATA NCQ Send and Receive log"; // SATA 3.1, ACS-3
case 0x14: return "SATA Hybrid Information log"; // SATA 3.2 case 0x14: return "Hybrid Information log"; // SATA 3.2, ACS-4
case 0x15: return "SATA Rebuild Assist log"; // SATA 3.2 case 0x15: return "Rebuild Assist log"; // SATA 3.2, ACS-4
case 0x16: case 0x16:
case 0x17: return "Reserved for Serial ATA"; case 0x17: return "Reserved for Serial ATA";
@ -1221,6 +1232,7 @@ static const char * GetLogName(unsigned logaddr)
case 0x24: return "Current Device Internal Status Data log"; // ACS-3 case 0x24: return "Current Device Internal Status Data log"; // ACS-3
case 0x25: return "Saved Device Internal Status Data log"; // ACS-3 case 0x25: return "Saved Device Internal Status Data log"; // ACS-3
case 0x2f: return "Set Sector Configuration";; // ACS-4
case 0x30: return "IDENTIFY DEVICE data log"; // ACS-3 case 0x30: return "IDENTIFY DEVICE data log"; // ACS-3
case 0xe0: return "SCT Command/Status"; case 0xe0: return "SCT Command/Status";
@ -1371,7 +1383,7 @@ static void PrintLogPages(const char * type, const unsigned char * data,
// Device statistics (Log 0x04) // Device statistics (Log 0x04)
// Section A.5 of T13/2161-D (ACS-3) Revision 5, October 28, 2013 // Section A.5 of T13/2161-D (ACS-3) Revision 5, October 28, 2013
// Section 9.5 of T13/BSR INCITS 529 (ACS-4) Revision 08, April 28, 2015 // Section 9.5 of T13/BSR INCITS 529 (ACS-4) Revision 20, October 26, 2017
struct devstat_entry_info struct devstat_entry_info
{ {
@ -1396,6 +1408,8 @@ const devstat_entry_info devstat_info_0x01[] = {
{ 4, "Pending Error Count" }, // ACS-4 { 4, "Pending Error Count" }, // ACS-4
{ 2, "Workload Utilization" }, // ACS-4 { 2, "Workload Utilization" }, // ACS-4
{ 6, "Utilization Usage Rate" }, // ACS-4 (TODO: field provides 3 values) { 6, "Utilization Usage Rate" }, // ACS-4 (TODO: field provides 3 values)
{ 2, "Resource Availability" }, // ACS-4
{ 1, "Random Write Resources Used" }, // ACS-4
{ 0, 0 } { 0, 0 }
}; };
@ -1424,6 +1438,7 @@ const devstat_entry_info devstat_info_0x04[] = {
{ 4, "Number of Reported Uncorrectable Errors" }, { 4, "Number of Reported Uncorrectable Errors" },
//{ 4, "Number of Resets Between Command Acceptance and Command Completion" }, //{ 4, "Number of Resets Between Command Acceptance and Command Completion" },
{ 4, "Resets Between Cmd Acceptance and Completion" }, { 4, "Resets Between Cmd Acceptance and Completion" },
{ 4, "Physical Element Status Changed" }, // ACS-4
{ 0, 0 } { 0, 0 }
}; };
@ -1468,6 +1483,7 @@ const devstat_entry_info * devstat_infos[] = {
devstat_info_0x05, devstat_info_0x05,
devstat_info_0x06, devstat_info_0x06,
devstat_info_0x07 devstat_info_0x07
// TODO: 0x08 Zoned Device Statistics (T13/f16136r7, January 2017)
}; };
const int num_devstat_infos = sizeof(devstat_infos)/sizeof(devstat_infos[0]); const int num_devstat_infos = sizeof(devstat_infos)/sizeof(devstat_infos[0]);
@ -1659,6 +1675,79 @@ static bool print_device_statistics(ata_device * device, unsigned nsectors,
} }
///////////////////////////////////////////////////////////////////////
// Pending Defects log (Log 0x0c)
// Section 9.26 of T13/BSR INCITS 529 (ACS-4) Revision 20, October 26, 2017
// TODO: Move to utility.h:
static inline unsigned le32_to_uint(const unsigned char * val)
{
return ( (unsigned)val[0]
| ((unsigned)val[1] << 8)
| ((unsigned)val[2] << 16)
| ((unsigned)val[3] << 24));
}
static inline uint64_t le64_to_uint(const unsigned char * val)
{
return (le32_to_uint(val) | ((uint64_t)le32_to_uint(val + 4) << 32));
}
static bool print_pending_defects_log(ata_device * device, unsigned nsectors,
unsigned max_entries)
{
// Read #entries from page 0
unsigned char page_buf[512] = {0, };
if (!ataReadLogExt(device, 0x0c, 0, 0, page_buf, 1)) {
pout("Read Pending Defects log page 0x00 failed\n\n");
return false;
}
pout("Pending Defects log (GP Log 0x0c)\n");
unsigned nentries = le32_to_uint(page_buf);
if (!nentries) {
pout("No Defects Logged\n\n");
return true;
}
// Print entries
pout("Index LBA Hours\n");
for (unsigned i = 0, pi = 1, page = 0; i < nentries && i < max_entries; i++, pi++) {
// Read new page if required
if (pi >= 32) {
if (++page >= nsectors) {
pout("Pending Defects count %u exceeds log size (#pages=%u)\n\n",
nentries, nsectors);
return false;
}
if (!ataReadLogExt(device, 0x0c, 0, page, page_buf, 1)) {
pout("Read Pending Defects log page 0x%02x failed\n\n", page);
return false;
}
pi = 0;
}
const unsigned char * entry = page_buf + 16 * pi;
unsigned hours = le32_to_uint(entry);
char hourstr[32];
if (hours != 0xffffffffU)
snprintf(hourstr, sizeof(hourstr), "%u", hours);
else
hourstr[0] = '-', hourstr[1] = 0;
uint64_t lba = le64_to_uint(entry + 8);
pout("%5u %18" PRIu64 " %8s\n", i, lba, hourstr);
}
if (nentries > max_entries)
pout("... (%u entries not shown)\n", nentries - max_entries);
// TODO: Remove when no longer EXPERIMENTAL
pout("Please send sample output of above table to:\n" PACKAGE_BUGREPORT "\n");
pout("\n");
return true;
}
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
// Print log 0x11 // Print log 0x11
@ -2310,7 +2399,8 @@ static int ataPrintSCTStatus(const ata_sct_status_response * sts)
// T13/e06152r0-3 (Additional SCT Temperature Statistics), August - October 2006 // T13/e06152r0-3 (Additional SCT Temperature Statistics), August - October 2006
// Table 60 of T13/1699-D (ATA8-ACS) Revision 3f, December 2006 (format version 2) // Table 60 of T13/1699-D (ATA8-ACS) Revision 3f, December 2006 (format version 2)
// Table 80 of T13/1699-D (ATA8-ACS) Revision 6a, September 2008 (format version 3) // Table 80 of T13/1699-D (ATA8-ACS) Revision 6a, September 2008 (format version 3)
// Table 182 of T13/BSR INCITS 529 (ACS-4) Revision 02a, May 22, 2014 (smart_status field) // Table 185 of T13/BSR INCITS 529 (ACS-4) Revision 16, February 21, 2017
// (smart_status, min_erc_time)
pout("Current Temperature: %s Celsius\n", pout("Current Temperature: %s Celsius\n",
sct_ptemp(sts->hda_temp, buf1)); sct_ptemp(sts->hda_temp, buf1));
pout("Power Cycle Min/Max Temperature: %s/%s Celsius\n", pout("Power Cycle Min/Max Temperature: %s/%s Celsius\n",
@ -2328,6 +2418,10 @@ static int ataPrintSCTStatus(const ata_sct_status_response * sts)
(sts->smart_status == 0x2cf4 ? "FAILED" : (sts->smart_status == 0x2cf4 ? "FAILED" :
sts->smart_status == 0xc24f ? "PASSED" : "Reserved")); sts->smart_status == 0xc24f ? "PASSED" : "Reserved"));
if (sts->min_erc_time) // ACS-4
pout("Minimum supported ERC Time Limit: %d (%0.1f seconds)\n",
sts->min_erc_time, sts->min_erc_time/10.0);
if (nonempty(sts->vendor_specific, sizeof(sts->vendor_specific))) { if (nonempty(sts->vendor_specific, sizeof(sts->vendor_specific))) {
pout("Vendor specific:\n"); pout("Vendor specific:\n");
for (unsigned i = 0; i < sizeof(sts->vendor_specific); i++) for (unsigned i = 0; i < sizeof(sts->vendor_specific); i++)
@ -2468,7 +2562,7 @@ static void print_ata_security_status(const char * msg, unsigned short state)
} }
else { else {
s1 = "ENABLED, PW level "; s1 = "ENABLED, PW level ";
if (!(state & 0x0020)) if (!(state & 0x0100))
s2 = "HIGH"; s2 = "HIGH";
else else
s2 = "MAX"; s2 = "MAX";
@ -2568,8 +2662,8 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
} }
if (powername) { if (powername) {
if (options.powermode >= powerlimit) { if (options.powermode >= powerlimit) {
pout("Device is in %s mode, exit(%d)\n", powername, FAILPOWER); pout("Device is in %s mode, exit(%d)\n", powername, options.powerexit);
return FAILPOWER; return options.powerexit;
} }
powerchg = (powermode != 0xff); // SMART tests will spin up drives powerchg = (powermode != 0xff); // SMART tests will spin up drives
} }
@ -2619,6 +2713,7 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
|| options.devstat_all_pages || options.devstat_all_pages
|| options.devstat_ssd_page || options.devstat_ssd_page
|| !options.devstat_pages.empty() || !options.devstat_pages.empty()
|| options.pending_defects_log
); );
unsigned i; unsigned i;
@ -2638,6 +2733,8 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
|| options.sct_erc_set || options.sct_erc_set
|| options.sct_wcache_reorder_get || options.sct_wcache_reorder_get
|| options.sct_wcache_reorder_set || options.sct_wcache_reorder_set
|| options.sct_wcache_sct_get
|| options.sct_wcache_sct_set
); );
// Exit if no further options specified // Exit if no further options specified
@ -2793,6 +2890,20 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
!(drive.cfs_enable_1 & 0x0020) ? "Disabled" : "Enabled"); // word085 !(drive.cfs_enable_1 & 0x0020) ? "Disabled" : "Enabled"); // word085
} }
// Print DSN status
unsigned short word120 = drive.words088_255[120-88];
unsigned short word119 = drive.words088_255[119-88];
if (options.get_dsn) {
if (!(drive.word086 & 0x8000) // word086
|| ((word119 & 0xc200) != 0x4200) // word119
|| ((word120 & 0xc000) != 0x4000)) // word120
pout("DSN feature is: Unavailable\n");
else if (word120 & 0x200) // word120
pout("DSN feature is: Enabled\n");
else
pout("DSN feature is: Disabled\n");
}
// Check for ATA Security LOCK // Check for ATA Security LOCK
unsigned short word128 = drive.words088_255[128-88]; unsigned short word128 = drive.words088_255[128-88];
bool locked = ((word128 & 0x0007) == 0x0007); // LOCKED|ENABLED|SUPPORTED bool locked = ((word128 & 0x0007) == 0x0007); // LOCKED|ENABLED|SUPPORTED
@ -2821,6 +2932,31 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
} }
} }
const char * sct_write_cache_state_desc[4] = {
"Unknown", // 0: not defined in standard but returned on some drives if not set
"Controlled by ATA", // 1: controlled ATA Set Features command
"Force Enabled", // 2
"Force Disabled" // 3
};
// Print SCT feature control of write cache
if (options.sct_wcache_sct_get) {
if (!isSCTFeatureControlCapable(&drive))
pout("SCT Write Cache Control: Unavailable\n");
else if (locked)
pout("SCT Write Cache Control: Unknown (SCT not supported if ATA Security is LOCKED)\n");
else {
int state = ataGetSetSCTWriteCache(device, 1, false /*persistent*/, false /*set*/);
if (-1 <= state && state <= 3)
pout("SCT Write Cache Control: %s\n",
(state == -1 ? "Unknown (SCT Feature Control command failed)" :
sct_write_cache_state_desc[state]));
else
pout("SCT Write Cache Control: Unknown (0x%02x)\n", state);
}
}
// Print remaining drive info // Print remaining drive info
if (options.drive_info) { if (options.drive_info) {
// Print the (now possibly changed) power mode if available // Print the (now possibly changed) power mode if available
@ -2839,7 +2975,7 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
|| options.smart_auto_offl_disable || options.smart_auto_offl_enable || options.smart_auto_offl_disable || options.smart_auto_offl_enable
|| options.set_aam || options.set_apm || options.set_lookahead || options.set_aam || options.set_apm || options.set_lookahead
|| options.set_wcache || options.set_security_freeze || options.set_standby || options.set_wcache || options.set_security_freeze || options.set_standby
|| options.sct_wcache_reorder_set) || options.sct_wcache_reorder_set || options.sct_wcache_sct_set || options.set_dsn)
pout("=== START OF ENABLE/DISABLE COMMANDS SECTION ===\n"); pout("=== START OF ENABLE/DISABLE COMMANDS SECTION ===\n");
// Enable/Disable AAM // Enable/Disable AAM
@ -2904,6 +3040,17 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
pout("Write cache %sabled\n", (enable ? "en" : "dis")); pout("Write cache %sabled\n", (enable ? "en" : "dis"));
} }
// Enable/Disable DSN
if (options.set_dsn) {
bool enable = (options.set_dsn > 0);
if (!ata_set_features(device, ATA_ENABLE_DISABLE_DSN, (enable ? 0x1 : 0x2))) {
pout("DSN %sable failed: %s\n", (enable ? "en" : "dis"), device->get_errmsg());
returnval |= FAILSMART;
}
else
pout("DSN %sabled\n", (enable ? "en" : "dis"));
}
// Enable/Disable write cache reordering // Enable/Disable write cache reordering
if (options.sct_wcache_reorder_set) { if (options.sct_wcache_reorder_set) {
bool enable = (options.sct_wcache_reorder_set > 0); bool enable = (options.sct_wcache_reorder_set > 0);
@ -2914,12 +3061,30 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
pout("Write cache reordering %sable failed: SCT not supported if ATA Security is LOCKED\n", pout("Write cache reordering %sable failed: SCT not supported if ATA Security is LOCKED\n",
(enable ? "en" : "dis")); (enable ? "en" : "dis"));
else if (ataGetSetSCTWriteCacheReordering(device, else if (ataGetSetSCTWriteCacheReordering(device,
enable, false /*persistent*/, true /*set*/) < 0) { enable, options.sct_wcache_reorder_set_pers, true /*set*/) < 0) {
pout("Write cache reordering %sable failed: %s\n", (enable ? "en" : "dis"), device->get_errmsg()); pout("Write cache reordering %sable failed: %s\n", (enable ? "en" : "dis"), device->get_errmsg());
returnval |= FAILSMART; returnval |= FAILSMART;
} }
else else
pout("Write cache reordering %sabled\n", (enable ? "en" : "dis")); pout("Write cache reordering %sabled (%s)\n", (enable ? "en" : "dis"),
(options.sct_wcache_reorder_set_pers ? "persistent" : "volatile"));
}
// Enable/Disable write cache in SCT
if (options.sct_wcache_sct_set) {
if (!isSCTFeatureControlCapable(&drive))
pout("SCT Feature Control of write cache failed: SCT Feature Control command not supported\n");
else if (locked)
pout("SCT Feature Control of write cache failed: SCT not supported if ATA Security is LOCKED\n");
else if (ataGetSetSCTWriteCache(device,
options.sct_wcache_sct_set, options.sct_wcache_sct_set_pers, true /*set*/) < 0) {
pout("SCT Feature Control of write cache failed: %s\n", device->get_errmsg());
returnval |= FAILSMART;
}
else
pout("Write cache SCT Feature Control is set to: %s (%s)\n",
sct_write_cache_state_desc[options.sct_wcache_sct_set],
(options.sct_wcache_sct_set_pers ? "persistent" : "volatile"));
} }
// Freeze ATA security // Freeze ATA security
@ -2932,8 +3097,8 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
pout("ATA Security set to frozen mode\n"); pout("ATA Security set to frozen mode\n");
} }
// Set standby timer // Set standby timer unless immediate standby is also requested
if (options.set_standby) { if (options.set_standby && !options.set_standby_now) {
if (!ata_nodata_command(device, ATA_IDLE, options.set_standby-1)) { if (!ata_nodata_command(device, ATA_IDLE, options.set_standby-1)) {
pout("ATA IDLE command failed: %s\n", device->get_errmsg()); pout("ATA IDLE command failed: %s\n", device->get_errmsg());
returnval |= FAILSMART; returnval |= FAILSMART;
@ -3055,7 +3220,7 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
|| options.smart_auto_offl_disable || options.smart_auto_offl_enable || options.smart_auto_offl_disable || options.smart_auto_offl_enable
|| options.set_aam || options.set_apm || options.set_lookahead || options.set_aam || options.set_apm || options.set_lookahead
|| options.set_wcache || options.set_security_freeze || options.set_standby || options.set_wcache || options.set_security_freeze || options.set_standby
|| options.sct_wcache_reorder_set) || options.sct_wcache_reorder_set || options.set_dsn)
pout("\n"); pout("\n");
// START OF READ-ONLY OPTIONS APART FROM -V and -i // START OF READ-ONLY OPTIONS APART FROM -V and -i
@ -3534,6 +3699,17 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
failuretest(OPTIONAL_CMD, returnval|=FAILSMART); failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
} }
// Print Pending Defects log
if (options.pending_defects_log || options.pending_defects_info) {
unsigned nsectors = GetNumLogSectors(gplogdir, 0x0c, true);
if (!nsectors)
pout("Pending Defects log (GP Log 0x0c) not supported\n\n");
else if (!options.pending_defects_log) // TODO: Remove when no longer EXPERIMENTAL
pout("Pending Defects log (GP Log 0x0c) supported [please try: '-l defects']\n\n");
else if (!print_pending_defects_log(device, nsectors, options.pending_defects_log))
failuretest(OPTIONAL_CMD, returnval|=FAILSMART);
}
// Print SATA Phy Event Counters // Print SATA Phy Event Counters
if (options.sataphy) { if (options.sataphy) {
unsigned nsectors = GetNumLogSectors(gplogdir, 0x11, true); unsigned nsectors = GetNumLogSectors(gplogdir, 0x11, true);
@ -3556,9 +3732,20 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
} }
} }
// Set to standby (spindown) mode // Set to standby (spindown) mode and set standby timer if not done above
// (Above commands may spinup drive) // (Above commands may spinup drive)
if (options.set_standby_now) { if (options.set_standby_now) {
if (options.set_standby) {
if (!ata_nodata_command(device, ATA_STANDBY, options.set_standby-1)) {
pout("ATA STANDBY command failed: %s\n", device->get_errmsg());
returnval |= FAILSMART;
}
else {
print_standby_timer("Standby timer set to ", options.set_standby-1, drive);
pout("Device placed in STANDBY mode\n");
}
}
else {
if (!ata_nodata_command(device, ATA_STANDBY_IMMEDIATE)) { if (!ata_nodata_command(device, ATA_STANDBY_IMMEDIATE)) {
pout("ATA STANDBY IMMEDIATE command failed: %s\n", device->get_errmsg()); pout("ATA STANDBY IMMEDIATE command failed: %s\n", device->get_errmsg());
returnval |= FAILSMART; returnval |= FAILSMART;
@ -3566,6 +3753,7 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
else else
pout("Device placed in STANDBY mode\n"); pout("Device placed in STANDBY mode\n");
} }
}
// START OF THE TESTING SECTION OF THE CODE. IF NO TESTING, RETURN // START OF THE TESTING SECTION OF THE CODE. IF NO TESTING, RETURN
if (!smart_val_ok || options.smart_selftest_type == -1) if (!smart_val_ok || options.smart_selftest_type == -1)

View File

@ -3,8 +3,8 @@
* *
* Home page of code is: http://www.smartmontools.org * Home page of code is: http://www.smartmontools.org
* *
* Copyright (C) 2002-9 Bruce Allen <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2002-09 Bruce Allen
* Copyright (C) 2008-12 Christian Franke <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2008-17 Christian Franke
* Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org> * Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -25,7 +25,7 @@
#ifndef ATAPRINT_H_ #ifndef ATAPRINT_H_
#define ATAPRINT_H_ #define ATAPRINT_H_
#define ATAPRINT_H_CVSID "$Id: ataprint.h 4120 2015-08-27 16:12:21Z samm2 $\n" #define ATAPRINT_H_CVSID "$Id: ataprint.h 4572 2017-10-29 14:36:00Z chrfranke $\n"
#include <vector> #include <vector>
@ -64,6 +64,9 @@ struct ata_print_options
bool devstat_all_pages, devstat_ssd_page; bool devstat_all_pages, devstat_ssd_page;
std::vector<int> devstat_pages; std::vector<int> devstat_pages;
bool pending_defects_info;
unsigned pending_defects_log;
bool sct_temp_sts, sct_temp_hist; bool sct_temp_sts, sct_temp_hist;
bool sct_erc_get; bool sct_erc_get;
bool sct_erc_set; bool sct_erc_set;
@ -92,6 +95,7 @@ struct ata_print_options
bool ignore_presets; // Ignore presets from drive database bool ignore_presets; // Ignore presets from drive database
bool show_presets; // Show presets and exit bool show_presets; // Show presets and exit
unsigned char powermode; // Skip check, if disk in idle or standby mode unsigned char powermode; // Skip check, if disk in idle or standby mode
unsigned char powerexit; // exit() code for low power mode
bool get_set_used; // true if any get/set command is used bool get_set_used; // true if any get/set command is used
bool get_aam; // print Automatic Acoustic Management status bool get_aam; // print Automatic Acoustic Management status
@ -108,6 +112,12 @@ struct ata_print_options
int set_wcache; // disable(-1), enable(1) write cache int set_wcache; // disable(-1), enable(1) write cache
bool sct_wcache_reorder_get; // print write cache reordering status bool sct_wcache_reorder_get; // print write cache reordering status
int sct_wcache_reorder_set; // disable(-1), enable(1) write cache reordering int sct_wcache_reorder_set; // disable(-1), enable(1) write cache reordering
bool sct_wcache_reorder_set_pers;
bool sct_wcache_sct_get; // print SCT Feature Control of write cache status
int sct_wcache_sct_set; // determined by ata set features command(1), force enable(2), force disable(3)
bool sct_wcache_sct_set_pers; // persistent or volatile
bool get_dsn; // print DSN status
int set_dsn; // disable(02h), enable(01h) DSN
ata_print_options() ata_print_options()
: drive_info(false), : drive_info(false),
@ -123,6 +133,7 @@ struct ata_print_options
smart_ext_selftest_log(0), smart_ext_selftest_log(0),
retry_error_log(false), retry_selftest_log(false), retry_error_log(false), retry_selftest_log(false),
devstat_all_pages(false), devstat_ssd_page(false), devstat_all_pages(false), devstat_ssd_page(false),
pending_defects_info(false), pending_defects_log(0),
sct_temp_sts(false), sct_temp_hist(false), sct_temp_sts(false), sct_temp_hist(false),
sct_erc_get(false), sct_erc_get(false),
sct_erc_set(false), sct_erc_set(false),
@ -137,7 +148,7 @@ struct ata_print_options
fix_swapped_id(false), fix_swapped_id(false),
ignore_presets(false), ignore_presets(false),
show_presets(false), show_presets(false),
powermode(0), powermode(0), powerexit(0),
get_set_used(false), get_set_used(false),
get_aam(false), set_aam(0), get_aam(false), set_aam(0),
get_apm(false), set_apm(0), get_apm(false), set_apm(0),
@ -145,7 +156,11 @@ struct ata_print_options
set_standby(0), set_standby_now(false), set_standby(0), set_standby_now(false),
get_security(false), set_security_freeze(false), get_security(false), set_security_freeze(false),
get_wcache(false), set_wcache(0), get_wcache(false), set_wcache(0),
sct_wcache_reorder_get(false), sct_wcache_reorder_set(0) sct_wcache_reorder_get(false), sct_wcache_reorder_set(0),
sct_wcache_reorder_set_pers(false),
sct_wcache_sct_get(false), sct_wcache_sct_set(0),
sct_wcache_sct_set_pers(false),
get_dsn(false), set_dsn(0)
{ } { }
}; };

View File

@ -1,5 +1,5 @@
#!/bin/sh #!/bin/sh
# $Id: autogen.sh 4115 2015-07-15 20:52:26Z chrfranke $ # $Id: autogen.sh 4434 2017-09-14 18:05:12Z samm2 $
# #
# Generate ./configure from configure.ac and Makefile.in from Makefile.am. # Generate ./configure from configure.ac and Makefile.in from Makefile.am.
# This also adds files like missing,depcomp,install-sh to the source # This also adds files like missing,depcomp,install-sh to the source
@ -60,7 +60,7 @@ case "$ver" in
# OK # OK
;; ;;
1.14|1.14.1|1.15) 1.14|1.14.1|1.15|1.15.1)
# TODO: Enable 'subdir-objects' in configure.ac # TODO: Enable 'subdir-objects' in configure.ac
# For now, suppress 'subdir-objects' forward-incompatibility warning # For now, suppress 'subdir-objects' forward-incompatibility warning
test -n "$warnings" || amwarnings="--warnings=no-unsupported" test -n "$warnings" || amwarnings="--warnings=no-unsupported"

348
compile Executable file
View File

@ -0,0 +1,348 @@
#! /bin/sh
# Wrapper for compilers which do not understand '-c -o'.
scriptversion=2016-01-11.22; # UTC
# Copyright (C) 1999-2017 Free Software Foundation, Inc.
# Written by Tom Tromey <tromey@cygnus.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.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# This file is maintained in Automake, please report
# bugs to <bug-automake@gnu.org> or send patches to
# <automake-patches@gnu.org>.
nl='
'
# We need space, tab and new line, in precisely that order. Quoting is
# there to prevent tools from complaining about whitespace usage.
IFS=" "" $nl"
file_conv=
# func_file_conv build_file lazy
# Convert a $build file to $host form and store it in $file
# Currently only supports Windows hosts. If the determined conversion
# type is listed in (the comma separated) LAZY, no conversion will
# take place.
func_file_conv ()
{
file=$1
case $file in
/ | /[!/]*) # absolute file, and not a UNC file
if test -z "$file_conv"; then
# lazily determine how to convert abs files
case `uname -s` in
MINGW*)
file_conv=mingw
;;
CYGWIN*)
file_conv=cygwin
;;
*)
file_conv=wine
;;
esac
fi
case $file_conv/,$2, in
*,$file_conv,*)
;;
mingw/*)
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
;;
cygwin/*)
file=`cygpath -m "$file" || echo "$file"`
;;
wine/*)
file=`winepath -w "$file" || echo "$file"`
;;
esac
;;
esac
}
# func_cl_dashL linkdir
# Make cl look for libraries in LINKDIR
func_cl_dashL ()
{
func_file_conv "$1"
if test -z "$lib_path"; then
lib_path=$file
else
lib_path="$lib_path;$file"
fi
linker_opts="$linker_opts -LIBPATH:$file"
}
# func_cl_dashl library
# Do a library search-path lookup for cl
func_cl_dashl ()
{
lib=$1
found=no
save_IFS=$IFS
IFS=';'
for dir in $lib_path $LIB
do
IFS=$save_IFS
if $shared && test -f "$dir/$lib.dll.lib"; then
found=yes
lib=$dir/$lib.dll.lib
break
fi
if test -f "$dir/$lib.lib"; then
found=yes
lib=$dir/$lib.lib
break
fi
if test -f "$dir/lib$lib.a"; then
found=yes
lib=$dir/lib$lib.a
break
fi
done
IFS=$save_IFS
if test "$found" != yes; then
lib=$lib.lib
fi
}
# func_cl_wrapper cl arg...
# Adjust compile command to suit cl
func_cl_wrapper ()
{
# Assume a capable shell
lib_path=
shared=:
linker_opts=
for arg
do
if test -n "$eat"; then
eat=
else
case $1 in
-o)
# configure might choose to run compile as 'compile cc -o foo foo.c'.
eat=1
case $2 in
*.o | *.[oO][bB][jJ])
func_file_conv "$2"
set x "$@" -Fo"$file"
shift
;;
*)
func_file_conv "$2"
set x "$@" -Fe"$file"
shift
;;
esac
;;
-I)
eat=1
func_file_conv "$2" mingw
set x "$@" -I"$file"
shift
;;
-I*)
func_file_conv "${1#-I}" mingw
set x "$@" -I"$file"
shift
;;
-l)
eat=1
func_cl_dashl "$2"
set x "$@" "$lib"
shift
;;
-l*)
func_cl_dashl "${1#-l}"
set x "$@" "$lib"
shift
;;
-L)
eat=1
func_cl_dashL "$2"
;;
-L*)
func_cl_dashL "${1#-L}"
;;
-static)
shared=false
;;
-Wl,*)
arg=${1#-Wl,}
save_ifs="$IFS"; IFS=','
for flag in $arg; do
IFS="$save_ifs"
linker_opts="$linker_opts $flag"
done
IFS="$save_ifs"
;;
-Xlinker)
eat=1
linker_opts="$linker_opts $2"
;;
-*)
set x "$@" "$1"
shift
;;
*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
func_file_conv "$1"
set x "$@" -Tp"$file"
shift
;;
*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
func_file_conv "$1" mingw
set x "$@" "$file"
shift
;;
*)
set x "$@" "$1"
shift
;;
esac
fi
shift
done
if test -n "$linker_opts"; then
linker_opts="-link$linker_opts"
fi
exec "$@" $linker_opts
exit 1
}
eat=
case $1 in
'')
echo "$0: No command. Try '$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: compile [--help] [--version] PROGRAM [ARGS]
Wrapper for compilers which do not understand '-c -o'.
Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
arguments, and rename the output as expected.
If you are trying to build a whole package this is not the
right script to run: please start by reading the file 'INSTALL'.
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "compile $scriptversion"
exit $?
;;
cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \
icl | *[/\\]icl | icl.exe | *[/\\]icl.exe )
func_cl_wrapper "$@" # Doesn't return...
;;
esac
ofile=
cfile=
for arg
do
if test -n "$eat"; then
eat=
else
case $1 in
-o)
# configure might choose to run compile as 'compile cc -o foo foo.c'.
# So we strip '-o arg' only if arg is an object.
eat=1
case $2 in
*.o | *.obj)
ofile=$2
;;
*)
set x "$@" -o "$2"
shift
;;
esac
;;
*.c)
cfile=$1
set x "$@" "$1"
shift
;;
*)
set x "$@" "$1"
shift
;;
esac
fi
shift
done
if test -z "$ofile" || test -z "$cfile"; then
# If no '-o' option was seen then we might have been invoked from a
# pattern rule where we don't need one. That is ok -- this is a
# normal compilation that the losing compiler can handle. If no
# '.c' file was seen then we are probably linking. That is also
# ok.
exec "$@"
fi
# Name of file we expect compiler to create.
cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
# Create the lock directory.
# Note: use '[/\\:.-]' here to ensure that we don't use the same name
# that we are using for the .o file. Also, base the name on the expected
# object file name, since that is what matters with a parallel build.
lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
while true; do
if mkdir "$lockdir" >/dev/null 2>&1; then
break
fi
sleep 1
done
# FIXME: race condition here if user kills between mkdir and trap.
trap "rmdir '$lockdir'; exit 1" 1 2 15
# Run the compile.
"$@"
ret=$?
if test -f "$cofile"; then
test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
elif test -f "${cofile}bj"; then
test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
fi
rmdir "$lockdir"
exit $ret
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:

1466
config.guess vendored Executable file

File diff suppressed because it is too large Load Diff

190
config.h.in Normal file
View File

@ -0,0 +1,190 @@
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define if building universal (internal helper macro) */
#undef AC_APPLE_UNIVERSAL_BUILD
/* freebsd ciss header location */
#undef CISS_LOCATION
/* smartmontools CVS Tag */
#undef CONFIG_H_CVSID
/* Define to 1 if C++ compiler supports __attribute__((packed)) */
#undef HAVE_ATTR_PACKED
/* Define to 1 if you have the `clock_gettime' function. */
#undef HAVE_CLOCK_GETTIME
/* Define to 1 if you have the <ddk/ntdddisk.h> header file. */
#undef HAVE_DDK_NTDDDISK_H
/* Define to 1 if you have the <dev/ata/atavar.h> header file. */
#undef HAVE_DEV_ATA_ATAVAR_H
/* Define to 1 if you have the <dev/ciss/cissio.h> header file. */
#undef HAVE_DEV_CISS_CISSIO_H
/* Define to 1 if you have the `ftime' function. */
#undef HAVE_FTIME
/* Define to 1 if you have the `getopt_long' function. */
#undef HAVE_GETOPT_LONG
/* Define to 1 if you have the `gettimeofday' function. */
#undef HAVE_GETTIMEOFDAY
/* Define to 1 if the system has the type `int64_t'. */
#undef HAVE_INT64_T
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the `cap-ng' library (-lcap-ng). */
#undef HAVE_LIBCAP_NG
/* Define to 1 if you have the `selinux' library (-lselinux). */
#undef HAVE_LIBSELINUX
/* Define to 1 if you have the `usb' library (-lusb). */
#undef HAVE_LIBUSB
/* Define to 1 if you have the <linux/cciss_ioctl.h> header file. */
#undef HAVE_LINUX_CCISS_IOCTL_H
/* Define to 1 if you have the <linux/compiler.h> header file. */
#undef HAVE_LINUX_COMPILER_H
/* Define to 1 if you have the <locale.h> header file. */
#undef HAVE_LOCALE_H
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the <ntdddisk.h> header file. */
#undef HAVE_NTDDDISK_H
/* Define to 1 if you have the `regcomp' function. */
#undef HAVE_REGCOMP
/* Define to 1 if you have the <selinux/selinux.h> header file. */
#undef HAVE_SELINUX_SELINUX_H
/* Define to 1 if you have the `sigset' function. */
#undef HAVE_SIGSET
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the `strtoull' function. */
#undef HAVE_STRTOULL
/* Define to 1 if you have the <sys/inttypes.h> header file. */
#undef HAVE_SYS_INTTYPES_H
/* Define to 1 if you have the <sys/int_types.h> header file. */
#undef HAVE_SYS_INT_TYPES_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/tweio.h> header file. */
#undef HAVE_SYS_TWEIO_H
/* Define to 1 if you have the <sys/twereg.h> header file. */
#undef HAVE_SYS_TWEREG_H
/* Define to 1 if you have the <sys/tw_osl_ioctl.h> header file. */
#undef HAVE_SYS_TW_OSL_IOCTL_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if the system has the type `uint64_t'. */
#undef HAVE_UINT64_T
/* Define to 1 if you have the `uname' function. */
#undef HAVE_UNAME
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if you have the <wbemcli.h> header file. */
#undef HAVE_WBEMCLI_H
/* Define to 1 if the `snprintf' function is sane. */
#undef HAVE_WORKING_SNPRINTF
/* Define to 1 if os_*.cpp still uses the old interface */
#undef OLD_INTERFACE
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* smartmontools Home Page */
#undef PACKAGE_HOMEPAGE
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* smartmontools Build Host */
#undef SMARTMONTOOLS_BUILD_HOST
/* smartmontools Configure Arguments */
#undef SMARTMONTOOLS_CONFIGURE_ARGS
/* smartmontools Release Date */
#undef SMARTMONTOOLS_RELEASE_DATE
/* smartmontools Release Time */
#undef SMARTMONTOOLS_RELEASE_TIME
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Version number of package */
#undef VERSION
/* Define to 1 to include NVMe devices in smartd DEVICESCAN. */
#undef WITH_NVME_DEVICESCAN
/* Define to 1 if SELinux support is enabled */
#undef WITH_SELINUX
/* Define to 1 to enable legacy ATA support on Solaris SPARC. */
#undef WITH_SOLARIS_SPARC_ATA
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
# undef WORDS_BIGENDIAN
# endif
#endif

1831
config.sub vendored Executable file

File diff suppressed because it is too large Load Diff

8761
configure vendored Executable file

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +1,14 @@
# #
# $Id: configure.ac 4319 2016-05-07 12:14:20Z chrfranke $ # $Id: configure.ac 4594 2017-11-05 15:21:35Z chrfranke $
# #
dnl Process this file with autoconf to produce a configure script. dnl Process this file with autoconf to produce a configure script.
AC_PREREQ([2.60]) AC_PREREQ([2.60])
AC_INIT(smartmontools, 6.6, smartmontools-support@lists.sourceforge.net) AC_INIT(smartmontools, 6.6, smartmontools-support@listi.jpberlin.de)
AM_INIT_AUTOMAKE([1.10 foreign]) AM_INIT_AUTOMAKE([1.10 foreign])
smartmontools_cvs_tag=`echo '$Id: configure.ac 4319 2016-05-07 12:14:20Z chrfranke $'` smartmontools_cvs_tag=`echo '$Id: configure.ac 4594 2017-11-05 15:21:35Z chrfranke $'`
smartmontools_release_date=2016-05-07 smartmontools_release_date=2017-11-05
smartmontools_release_time="11:17:46 UTC" smartmontools_release_time="15:20:58 UTC"
AC_DEFINE_UNQUOTED(SMARTMONTOOLS_CONFIGURE_ARGS, "$ac_configure_args", [smartmontools Configure Arguments]) AC_DEFINE_UNQUOTED(SMARTMONTOOLS_CONFIGURE_ARGS, "$ac_configure_args", [smartmontools Configure Arguments])
AC_DEFINE_UNQUOTED(SMARTMONTOOLS_RELEASE_DATE, "$smartmontools_release_date", [smartmontools Release Date]) AC_DEFINE_UNQUOTED(SMARTMONTOOLS_RELEASE_DATE, "$smartmontools_release_date", [smartmontools Release Date])
@ -244,13 +244,36 @@ AC_ARG_WITH(drivedbdir,
AC_SUBST(drivedbdir) AC_SUBST(drivedbdir)
AM_CONDITIONAL(ENABLE_DRIVEDB, [test -n "$drivedbdir"]) AM_CONDITIONAL(ENABLE_DRIVEDB, [test -n "$drivedbdir"])
drivedb_version=$VERSION
AC_ARG_WITH(update-smart_drivedb, AC_ARG_WITH(update-smart_drivedb,
[AS_HELP_STRING([--with-update-smart-drivedb@<:@=yes|no@:>@], [Install update-smart-drivedb script [yes]])], [AS_HELP_STRING([--with-update-smart-drivedb@<:@=yes|no|X.Y@:>@],
[], [with_update_smart_drivedb=yes]) [Install update-smart-drivedb script (and backport it to branches/RELEASE_X_Y_DRIVEDB) [yes]])],
[ case "$withval" in
yes|no) ;;
5.4[[0-3]]|6.[[0-9]]) drivedb_version=$withval; with_update_smart_drivedb=yes ;;
*) AC_MSG_ERROR([Invalid drivedb branch version: $withval]) ;;
esac
],
[with_update_smart_drivedb=yes])
test -n "$drivedbdir" || with_update_smart_drivedb=no test -n "$drivedbdir" || with_update_smart_drivedb=no
AC_SUBST(with_update_smart_drivedb) AC_SUBST(with_update_smart_drivedb)
AM_CONDITIONAL(ENABLE_UPDATE_SMART_DRIVEDB, [test "$with_update_smart_drivedb" = "yes"]) AM_CONDITIONAL(ENABLE_UPDATE_SMART_DRIVEDB, [test "$with_update_smart_drivedb" = "yes"])
gnupg="gpg"
# Also check for '--with-gnupg[=yes]' because 'yes' is a valid command with infinite output
AC_ARG_WITH(gnupg,
[AS_HELP_STRING([--with-gnupg@<:@=FILE|yes|no@:>@], [GnuPG used to verify drivedb.h [gpg]])],
[case "$withval" in yes) ;; no) gnupg= ;; *) gnupg="$withval" ;; esac], [])
AC_SUBST(gnupg)
case "$with_update_smart_drivedb:$gnupg" in
no:?*)
AC_MSG_ERROR([
'--without-update-smart-drivedb' now requires '--without-gnupg'.
NEWS: update-smart-drivedb now verifies the downloaded drivedb.h file with GnuPG.])
;;
esac
AC_ARG_WITH(smartdscriptdir, AC_ARG_WITH(smartdscriptdir,
[AS_HELP_STRING([--with-smartdscriptdir=DIR], [Location of smartd_warning.sh script [SYSCONFDIR]])], [AS_HELP_STRING([--with-smartdscriptdir=DIR], [Location of smartd_warning.sh script [SYSCONFDIR]])],
[smartdscriptdir="$withval"], [smartdscriptdir='${sysconfdir}']) [smartdscriptdir="$withval"], [smartdscriptdir='${sysconfdir}'])
@ -263,6 +286,14 @@ AC_ARG_WITH(smartdplugindir,
[smartdplugindir='${smartdscriptdir}/smartd_warning.d']) [smartdplugindir='${smartdscriptdir}/smartd_warning.d'])
AC_SUBST(smartdplugindir) AC_SUBST(smartdplugindir)
AC_ARG_WITH(scriptpath,
[AS_HELP_STRING([--with-scriptpath=@<:@PATH|no@:>@],
[PATH variable set within scripts [/usr/bin:/bin]])],
[scriptpath=; test "$withval" != "no" && scriptpath="$withval"],
[scriptpath="/usr/bin:/bin"])
AC_SUBST(scriptpath)
AM_CONDITIONAL(ENABLE_SCRIPTPATH, [test -n "$scriptpath"])
savestates= savestates=
AC_ARG_WITH(savestates, AC_ARG_WITH(savestates,
[AS_HELP_STRING([--with-savestates@<:@=PREFIX|yes|no@:>@], [AS_HELP_STRING([--with-savestates@<:@=PREFIX|yes|no@:>@],
@ -392,11 +423,45 @@ if test "$libc_have_working_snprintf" = "yes"; then
AC_DEFINE(HAVE_WORKING_SNPRINTF, 1, [Define to 1 if the `snprintf' function is sane.]) dnl `vim syntax AC_DEFINE(HAVE_WORKING_SNPRINTF, 1, [Define to 1 if the `snprintf' function is sane.]) dnl `vim syntax
fi fi
AC_ARG_WITH(mingw-aslr,
[AS_HELP_STRING([--with-mingw-aslr@<:@=auto|yes|low|no@:>@], [Enable ASLR for MinGW executables [auto]])],
[], [with_mingw_aslr=auto])
case "$host:${LDFLAGS+set}" in
*-*-mingw*:) # MinGW defaults: link statically and indicate DEP and TS compatibility
LDFLAGS="-static -Wl,--nxcompat,--tsaware" ;;
esac
case "$host:$with_mingw_aslr" in
x86_64-*-mingw*:auto)
AC_MSG_CHECKING([whether $CXX supports --high-entropy-va])
save_LDFLAGS=$LDFLAGS
LDFLAGS="$LDFLAGS -pie -Wl,--dynamicbase,-emainCRTStartup,--high-entropy-va,--image-base,0x140000000"
# Link libstdc++ to detect MinGW 6.3.0 problems with high --image-base
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <string>
std::string s(42, '.');]])],
[with_mingw_aslr=yes], [with_mingw_aslr=no])
LDFLAGS=$save_LDFLAGS
AC_MSG_RESULT([$with_mingw_aslr])
test "$with_mingw_aslr" = "yes" || with_mingw_aslr=low
;;
esac
case "$host:$with_mingw_aslr" in
x86_64-*-mingw*:yes)
LDFLAGS="$LDFLAGS -pie -Wl,--dynamicbase,-emainCRTStartup,--high-entropy-va,--image-base,0x140000000" ;;
x86_64-*-mingw*:low)
LDFLAGS="$LDFLAGS -pie -Wl,--dynamicbase,-emainCRTStartup" ;;
*-*-mingw*:auto|*-*-mingw*:yes|*-*-mingw*:low)
LDFLAGS="$LDFLAGS -pie -Wl,--dynamicbase,-e_mainCRTStartup" ;;
esac
os_win32_manifest= os_win32_manifest=
case "$host" in case "$host" in
*-*-mingw*) *-*-mingw*)
# Newer MinGW may add a default manifest # Newer MinGW may add a default manifest
AC_MSG_CHECKING([whether $CC adds an application manifest]) AC_MSG_CHECKING([whether $CXX adds an application manifest])
cc_adds_manifest=no cc_adds_manifest=no
AC_LINK_IFELSE([AC_LANG_PROGRAM()], [ AC_LINK_IFELSE([AC_LANG_PROGRAM()], [
if "$WINDRES" -O rc conftest.exe 2>/dev/null | grep '^1.*RT_MANIFEST' >/dev/null 2>&1; then if "$WINDRES" -O rc conftest.exe 2>/dev/null | grep '^1.*RT_MANIFEST' >/dev/null 2>&1; then
@ -408,24 +473,62 @@ case "$host" in
fi], fi],
[AC_MSG_ERROR([test compile failed])]) [AC_MSG_ERROR([test compile failed])])
AC_MSG_RESULT([$cc_adds_manifest]) AC_MSG_RESULT([$cc_adds_manifest])
test "$cc_adds_manifest" = "yes" || os_win32_manifest='default.manifest.o' test "$cc_adds_manifest" = "yes" || os_win32_manifest='os_win32/default.manifest'
;; ;;
esac esac
# TODO: Remove after smartmontools 6.5 AC_ARG_WITH(cxx11-option,
AC_ARG_WITH(docdir, [AS_HELP_STRING([--with-cxx11-option@<:@=OPTION|auto|no@:>@],
[AS_HELP_STRING([--with-docdir=DIR], [(removed, use --docdir=DIR instead)])], [Compiler option to enable C++11 support for future versions of smartmontools, 'no' if unsupported [auto]])],
[AC_MSG_ERROR([--with-docdir is no longer supported, use --docdir instead])]) [], [with_cxx11_option=auto])
AC_ARG_ENABLE(drivedb,
[AS_HELP_STRING([--disable-drivedb], [(removed, use --without-drivedbdir instead)])]) check_cxx11_support()
AC_ARG_ENABLE(savestates, {
[AS_HELP_STRING([--enable-savestates], [(removed, use --with-savestates@<:@=yes@:>@ instead)])]) save_CXXFLAGS=$CXXFLAGS
AC_ARG_ENABLE(attributelog, CXXFLAGS=$1
[AS_HELP_STRING([--enable-attributelog], [(removed, use --with-attributelog@<:@=yes@:>@ instead)])]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
if test -n "${enable_drivedb+set}${enable_savestates+set}${enable_attributelog+set}"; then #if __cplusplus < 201103L
AC_MSG_ERROR([Options --disable-drivedb, --enable-savestates, --enable-attributelog are no longer supported. #error false
Use --without-drivedbdir, --with-savestates, --with-attributelog instead.]) #endif
fi // use some C++11 features (and return v * 42 :-)
auto cxx11(long v) noexcept -> decltype(v) {
typedef decltype(v) t; t r = v;
static const t a[] = { -7, -1, 1, 2, 3 };
static_assert(sizeof(r) == sizeof(a[0]), "fail");
auto f = [](t x, t y){ return x * y; };
for (const auto & e : a) r = f(r, e);
return r;
}]])],
[CXXFLAGS=$save_CXXFLAGS; return 0], [CXXFLAGS=$save_CXXFLAGS; return 1])
}
case "$with_cxx11_option" in
no) ;;
auto)
AC_MSG_CHECKING([for $CXX option to accept C++11])
with_cxx11_option=unknown
for option in "" "-std=gnu++11" "-std=gnu++0x" "-std=c++11" "-std=c++0x"; do
if check_cxx11_support "$option"; then with_cxx11_option=$option; break; fi
done
AC_MSG_RESULT([${with_cxx11_option:-none needed}])
test "$with_cxx11_option" != "unknown" || AC_MSG_ERROR([
This version of smartmontools does not use C++11 features, but future
versions possibly will.
This script was unable to determine a compiler option to enable C++11.
Use option '--with-cxx11-option=OPTION' to specify the compiler option
(it will be checked, but not used in the actual build).
Use option '--without-cxx11-option' to suppress this error message if the
compiler lacks C++11 support.
In both cases, please send info about compiler and platform to
$PACKAGE_BUGREPORT - Thanks!])
;;
*)
AC_MSG_CHECKING([whether $CXX $with_cxx11_option accepts C++11])
res=no; check_cxx11_support "$with_cxx11_option" && res=yes
AC_MSG_RESULT([$res])
test "$res" = "yes" || AC_MSG_ERROR([$CXX $with_cxx11_option does not accept C++11])
;;
esac
AC_SUBST(releaseversion,['${PACKAGE}-${VERSION}']) AC_SUBST(releaseversion,['${PACKAGE}-${VERSION}'])
@ -515,6 +618,9 @@ case "${host}" in
*-*-nto-qnx*) *-*-nto-qnx*)
os_deps='os_qnxnto.o' os_deps='os_qnxnto.o'
;; ;;
*-*-os2-*)
os_deps='os_os2.o'
;;
*) *)
os_deps='os_generic.o' os_deps='os_generic.o'
;; ;;
@ -546,10 +652,10 @@ AC_SUBST([os_man_filter])
AC_SUBST([os_win32_manifest]) AC_SUBST([os_win32_manifest])
# Create drivedb.h update branch name from version: 5.41[.X] -> RELEASE_5_41_DRIVEDB # Create drivedb.h update branch name from version: 5.41[.X] -> RELEASE_5_41_DRIVEDB
DRIVEDB_BRANCH=`echo $VERSION | sed 's,^\([[0-9]]*\.[[0-9]]*\)\..*$,\1,' \ DRIVEDB_BRANCH=`echo "$drivedb_version" | sed 's,^\([[0-9]]*\.[[0-9]]*\)\..*$,\1,' \
| sed -n 's,^\([[0-9]][[0-9]]*\)\.\([[0-9]][[0-9]]*\)$,RELEASE_\1_\2_DRIVEDB,p'` | sed -n 's,^\([[0-9]][[0-9]]*\)\.\([[0-9]][[0-9]]*\)$,RELEASE_\1_\2_DRIVEDB,p'`
if test -z "$DRIVEDB_BRANCH"; then if test -z "$DRIVEDB_BRANCH"; then
AC_MSG_ERROR([Unable to create DRIVEDB_BRANCH from VERSION=$VERSION]) AC_MSG_ERROR([Unable to create DRIVEDB_BRANCH for version: $drivedb_version])
fi fi
AC_SUBST([DRIVEDB_BRANCH]) AC_SUBST([DRIVEDB_BRANCH])
@ -561,36 +667,52 @@ AM_CONDITIONAL(OS_WIN32_MINGW, [test "$os_win32_mingw" = "yes"])
AM_CONDITIONAL(OS_WIN32_NSIS, [test -n "$MAKENSIS"]) AM_CONDITIONAL(OS_WIN32_NSIS, [test -n "$MAKENSIS"])
AM_CONDITIONAL(OS_WIN64, [test "$os_win64" = "yes"]) AM_CONDITIONAL(OS_WIN64, [test "$os_win64" = "yes"])
dnl Add -Wall and -W if using g++ and its not already specified.
if test "$GXX" = "yes"; then if test "$GXX" = "yes"; then
if test -z "`echo "$CXXFLAGS" | grep "\-Wall" 2> /dev/null`" ; then # Add -Wall and -W[extra] if its not already specified
CXXFLAGS="$CXXFLAGS -Wall" case " $CXXFLAGS " in
fi *\ -Wall\ *) ;;
# In the next line, do NOT delete the 2 spaces inside double quotes. *) CXXFLAGS="$CXXFLAGS -Wall" ;;
if test -z "`echo "$CXXFLAGS " | grep "\-W " 2> /dev/null`" ; then esac
CXXFLAGS="$CXXFLAGS -W" case " $CXXFLAGS " in
fi *\ -W\ *|*\ -Wextra\ *) ;;
*) CXXFLAGS="$CXXFLAGS -W" ;;
esac
# Add -Wformat=2 (GCC 3.0) -fstack-protector[-strong] (GCC 4.1[4.9]) if supported
# and CXXFLAGS was not set in configure cmdline (TODO: -Wformat-signedness)
case "${ac_test_CXXFLAGS+set}:$ac_test_CXXFLAGS" in
set:)
for option in "-Wformat=2" "-fstack-protector-strong" "-fstack-protector"; do
case " $CXXFLAGS:$option" in *\ -fstack-p*:-fstack-p*) continue ;; esac
AC_MSG_CHECKING([whether $CXX supports $option])
save_CXXFLAGS=$CXXFLAGS
CXXFLAGS="$CXXFLAGS $option"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], [res=yes], [res=no; CXXFLAGS=$save_CXXFLAGS])
AC_MSG_RESULT([$res])
done
;;
esac
else else
dnl We are NOT using gcc, so enable host-specific compiler flags # We are NOT using gcc, so enable host-specific compiler flags
case "${host}" in case "${host}" in
sparc*-*-solaris*) sparc*-*-solaris*)
dnl set CXXFLAGS for Solaris/SPARC C++ compiler # Tell the Solaris/SPARC C++ compiler about packed ATA structures
if test -z "`echo "$CXXFLAGS" | grep "\-xmemalign" 2> /dev/null`" ; then case " $CXXFLAGS" in
dnl we have to tell the compilers about packed ATA structures *\ -xmemalign*) ;;
CXXFLAGS="-xmemalign=1i $CXXFLAGS" *) CXXFLAGS="-xmemalign=1i $CXXFLAGS" ;;
fi esac ;;
esac esac
case "${host}" in case "${host}" in
*-*-solaris*) *-*-solaris*)
if test -z "`echo "$CXXFLAGS" | grep "\-xO" 2> /dev/null`" ; then # Turn on optimization if user has not explicitly set its value
dnl turn on optimization if user has not explicitly set its value case " $CXXFLAGS" in
CXXFLAGS="-xO2 $CXXFLAGS" *\ -xO*) ;;
fi *) CXXFLAGS="-xO2 $CXXFLAGS" ;;
if test -z "`echo "$CXXFLAGS" | grep "\-erroff" 2> /dev/null`" ; then esac
dnl suppress trivial warnings # Suppress trivial warnings
CXXFLAGS="-erroff=%none,wbadinitl,wbadasgl,badargtypel2w,badargtype2w $CXXFLAGS" case " $CXXFLAGS" in
fi *\ -erroff*) ;;
*) CXXFLAGS="-erroff=%none,wbadinitl,wbadasgl,badargtypel2w,badargtype2w $CXXFLAGS" ;;
esac ;;
esac esac
fi fi
@ -647,7 +769,15 @@ info=`
echo "drive database file: \`eval eval eval echo $drivedbdir\`/drivedb.h" echo "drive database file: \`eval eval eval echo $drivedbdir\`/drivedb.h"
if test "$with_update_smart_drivedb" = "yes"; then if test "$with_update_smart_drivedb" = "yes"; then
echo "database update script: \`eval eval eval echo $sbindir\`/update-smart-drivedb" echo "database update script: \`eval eval eval echo $sbindir\`/update-smart-drivedb"
if test "$drivedb_version" != "$VERSION"; then
echo "... backported to: branches/$DRIVEDB_BRANCH"
fi
echo "download tools: \`eval eval eval echo $os_dltools\`" echo "download tools: \`eval eval eval echo $os_dltools\`"
if test -n "$gnupg"; then
echo "GnuPG for verification: \`eval eval eval echo $gnupg\`"
else
echo "GnuPG for verification: [[disabled]]"
fi
else else
echo "database update script: [[disabled]]" echo "database update script: [[disabled]]"
fi fi
@ -662,6 +792,11 @@ info=`
else else
echo "smartd plugin path: [[disabled]]" echo "smartd plugin path: [[disabled]]"
fi fi
if test -n "$scriptpath"; then
echo "PATH within scripts: \`eval eval eval echo $scriptpath\`"
else
echo "PATH within scripts: [[inherited]]"
fi
if test -n "$initddir"; then if test -n "$initddir"; then
echo "smartd initd script: \`eval eval eval echo $initddir\`/${initdfile}" echo "smartd initd script: \`eval eval eval echo $initddir\`/${initdfile}"
elif test -z "$systemdsystemunitdir"; then elif test -z "$systemdsystemunitdir"; then
@ -690,7 +825,8 @@ info=`
linux*) echo "SELinux support: ${with_selinux-no}" ;; linux*) echo "SELinux support: ${with_selinux-no}" ;;
esac esac
case "$host_os" in case "$host_os" in
linux*|cygwin*) echo "NVMe DEVICESCAN: ${with_nvme_devicescan-no}" ;; linux*|darwin*|netbsd*|cygwin*)
echo "NVMe DEVICESCAN: ${with_nvme_devicescan-no}" ;;
esac esac
;; ;;
esac esac
@ -703,17 +839,18 @@ $info
# TODO: Remove when NVMe support is no longer EXPERIMENTAL # TODO: Remove when NVMe support is no longer EXPERIMENTAL
case "$host_os:${with_nvme_devicescan+set}" in case "$host_os:${with_nvme_devicescan+set}" in
linux*:|cygwin*:|mingw*:) linux*:|darwin*:|netbsd*:|cygwin*:|mingw*:)
AC_MSG_WARN([ AC_MSG_WARN([
This version of smartmontools provides NVMe support which is still This version of smartmontools provides NVMe support which is still
EXPERIMENTAL. NVMe devices are not yet included in smartd.conf EXPERIMENTAL. NVMe devices are not yet included in smartd.conf
'DEVICESCAN' and 'smartctl --scan' unless '-d nvme' is specified. 'DEVICESCAN' and 'smartctl --scan' unless '-d nvme' is specified.
Use option '--with-nvme-devicescan' to include NVMe devices. Use option '--with-nvme-devicescan' to include NVMe devices.
Use option '--without-nvme-devicescan' to suppress this warning.]) Use option '--without-nvme-devicescan' to suppress this warning.
])
;; ;;
esac esac
# TODO: Remove after smartmontools 6.5 # TODO: Remove after smartmontools 6.6
case "$host:${with_solaris_sparc_ata+set}" in case "$host:${with_solaris_sparc_ata+set}" in
sparc-*-solaris*:) sparc-*-solaris*:)
AC_MSG_WARN([ AC_MSG_WARN([
@ -721,6 +858,7 @@ Legacy ATA support is no longer enabled by default on Solaris SPARC.
The required source file 'os_solaris_ata.s' is no longer included in The required source file 'os_solaris_ata.s' is no longer included in
the source tarball but still available in the SVN repository. the source tarball but still available in the SVN repository.
Use option '--with-solaris-sparc-ata' to enable legacy ATA support. Use option '--with-solaris-sparc-ata' to enable legacy ATA support.
Use option '--without-solaris-sparc-ata' to suppress this warning.]) Use option '--without-solaris-sparc-ata' to suppress this warning.
])
;; ;;
esac esac

791
depcomp Executable file
View File

@ -0,0 +1,791 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2016-01-11.22; # UTC
# Copyright (C) 1999-2017 Free Software Foundation, Inc.
# 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.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
case $1 in
'')
echo "$0: No command. Try '$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
Run PROGRAMS ARGS to compile a file, generating dependencies
as side-effects.
Environment variables:
depmode Dependency tracking mode.
source Source file read by 'PROGRAMS ARGS'.
object Object file output by 'PROGRAMS ARGS'.
DEPDIR directory where to store dependencies.
depfile Dependency file to output.
tmpdepfile Temporary file to use when outputting dependencies.
libtool Whether libtool is used (yes/no).
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "depcomp $scriptversion"
exit $?
;;
esac
# Get the directory component of the given path, and save it in the
# global variables '$dir'. Note that this directory component will
# be either empty or ending with a '/' character. This is deliberate.
set_dir_from ()
{
case $1 in
*/*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;;
*) dir=;;
esac
}
# Get the suffix-stripped basename of the given path, and save it the
# global variable '$base'.
set_base_from ()
{
base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'`
}
# If no dependency file was actually created by the compiler invocation,
# we still have to create a dummy depfile, to avoid errors with the
# Makefile "include basename.Plo" scheme.
make_dummy_depfile ()
{
echo "#dummy" > "$depfile"
}
# Factor out some common post-processing of the generated depfile.
# Requires the auxiliary global variable '$tmpdepfile' to be set.
aix_post_process_depfile ()
{
# If the compiler actually managed to produce a dependency file,
# post-process it.
if test -f "$tmpdepfile"; then
# Each line is of the form 'foo.o: dependency.h'.
# Do two passes, one to just change these to
# $object: dependency.h
# and one to simply output
# dependency.h:
# which is needed to avoid the deleted-header problem.
{ sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile"
sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile"
} > "$depfile"
rm -f "$tmpdepfile"
else
make_dummy_depfile
fi
}
# A tabulation character.
tab=' '
# A newline character.
nl='
'
# Character ranges might be problematic outside the C locale.
# These definitions help.
upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ
lower=abcdefghijklmnopqrstuvwxyz
digits=0123456789
alpha=${upper}${lower}
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
echo "depcomp: Variables source, object and depmode must be set" 1>&2
exit 1
fi
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
depfile=${depfile-`echo "$object" |
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
rm -f "$tmpdepfile"
# Avoid interferences from the environment.
gccflag= dashmflag=
# Some modes work just like other modes, but use different flags. We
# parameterize here, but still list the modes in the big case below,
# to make depend.m4 easier to write. Note that we *cannot* use a case
# here, because this file can only contain one case statement.
if test "$depmode" = hp; then
# HP compiler uses -M and no extra arg.
gccflag=-M
depmode=gcc
fi
if test "$depmode" = dashXmstdout; then
# This is just like dashmstdout with a different argument.
dashmflag=-xM
depmode=dashmstdout
fi
cygpath_u="cygpath -u -f -"
if test "$depmode" = msvcmsys; then
# This is just like msvisualcpp but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u='sed s,\\\\,/,g'
depmode=msvisualcpp
fi
if test "$depmode" = msvc7msys; then
# This is just like msvc7 but w/o cygpath translation.
# Just convert the backslash-escaped backslashes to single forward
# slashes to satisfy depend.m4
cygpath_u='sed s,\\\\,/,g'
depmode=msvc7
fi
if test "$depmode" = xlc; then
# IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information.
gccflag=-qmakedep=gcc,-MF
depmode=gcc
fi
case "$depmode" in
gcc3)
## gcc 3 implements dependency tracking that does exactly what
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
## it if -MD -MP comes after the -MF stuff. Hmm.
## Unfortunately, FreeBSD c89 acceptance of flags depends upon
## the command line argument order; so add the flags where they
## appear in depend2.am. Note that the slowdown incurred here
## affects only configure: in makefiles, %FASTDEP% shortcuts this.
for arg
do
case $arg in
-c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
*) set fnord "$@" "$arg" ;;
esac
shift # fnord
shift # $arg
done
"$@"
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
mv "$tmpdepfile" "$depfile"
;;
gcc)
## Note that this doesn't just cater to obsosete pre-3.x GCC compilers.
## but also to in-use compilers like IMB xlc/xlC and the HP C compiler.
## (see the conditional assignment to $gccflag above).
## There are various ways to get dependency output from gcc. Here's
## why we pick this rather obscure method:
## - Don't want to use -MD because we'd like the dependencies to end
## up in a subdir. Having to rename by hand is ugly.
## (We might end up doing this anyway to support other compilers.)
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
## -MM, not -M (despite what the docs say). Also, it might not be
## supported by the other compilers which use the 'gcc' depmode.
## - Using -M directly means running the compiler twice (even worse
## than renaming).
if test -z "$gccflag"; then
gccflag=-MD,
fi
"$@" -Wp,"$gccflag$tmpdepfile"
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
# The second -e expression handles DOS-style file names with drive
# letters.
sed -e 's/^[^:]*: / /' \
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
## This next piece of magic avoids the "deleted header file" problem.
## The problem is that when a header file which appears in a .P file
## is deleted, the dependency causes make to die (because there is
## typically no way to rebuild the header). We avoid this by adding
## dummy dependencies for each header file. Too bad gcc doesn't do
## this for us directly.
## Some versions of gcc put a space before the ':'. On the theory
## that the space means something, we add a space to the output as
## well. hp depmode also adds that space, but also prefixes the VPATH
## to the object. Take care to not repeat it in the output.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
sgi)
if test "$libtool" = yes; then
"$@" "-Wp,-MDupdate,$tmpdepfile"
else
"$@" -MDupdate "$tmpdepfile"
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
echo "$object : \\" > "$depfile"
# Clip off the initial element (the dependent). Don't try to be
# clever and replace this with sed code, as IRIX sed won't handle
# lines with more than a fixed number of characters (4096 in
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
# the IRIX cc adds comments like '#:fec' to the end of the
# dependency line.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \
| tr "$nl" ' ' >> "$depfile"
echo >> "$depfile"
# The second pass generates a dummy entry for each header file.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
>> "$depfile"
else
make_dummy_depfile
fi
rm -f "$tmpdepfile"
;;
xlc)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
aix)
# The C for AIX Compiler uses -M and outputs the dependencies
# in a .u file. In older versions, this file always lives in the
# current directory. Also, the AIX compiler puts '$object:' at the
# start of each line; $object doesn't have directory information.
# Version 6 uses the directory in both cases.
set_dir_from "$object"
set_base_from "$object"
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.u
tmpdepfile2=$base.u
tmpdepfile3=$dir.libs/$base.u
"$@" -Wc,-M
else
tmpdepfile1=$dir$base.u
tmpdepfile2=$dir$base.u
tmpdepfile3=$dir$base.u
"$@" -M
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
do
test -f "$tmpdepfile" && break
done
aix_post_process_depfile
;;
tcc)
# tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26
# FIXME: That version still under development at the moment of writing.
# Make that this statement remains true also for stable, released
# versions.
# It will wrap lines (doesn't matter whether long or short) with a
# trailing '\', as in:
#
# foo.o : \
# foo.c \
# foo.h \
#
# It will put a trailing '\' even on the last line, and will use leading
# spaces rather than leading tabs (at least since its commit 0394caf7
# "Emit spaces for -MD").
"$@" -MD -MF "$tmpdepfile"
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each non-empty line is of the form 'foo.o : \' or ' dep.h \'.
# We have to change lines of the first kind to '$object: \'.
sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile"
# And for each line of the second kind, we have to emit a 'dep.h:'
# dummy dependency, to avoid the deleted-header problem.
sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile"
rm -f "$tmpdepfile"
;;
## The order of this option in the case statement is important, since the
## shell code in configure will try each of these formats in the order
## listed in this file. A plain '-MD' option would be understood by many
## compilers, so we must ensure this comes after the gcc and icc options.
pgcc)
# Portland's C compiler understands '-MD'.
# Will always output deps to 'file.d' where file is the root name of the
# source file under compilation, even if file resides in a subdirectory.
# The object file name does not affect the name of the '.d' file.
# pgcc 10.2 will output
# foo.o: sub/foo.c sub/foo.h
# and will wrap long lines using '\' :
# foo.o: sub/foo.c ... \
# sub/foo.h ... \
# ...
set_dir_from "$object"
# Use the source, not the object, to determine the base name, since
# that's sadly what pgcc will do too.
set_base_from "$source"
tmpdepfile=$base.d
# For projects that build the same source file twice into different object
# files, the pgcc approach of using the *source* file root name can cause
# problems in parallel builds. Use a locking strategy to avoid stomping on
# the same $tmpdepfile.
lockdir=$base.d-lock
trap "
echo '$0: caught signal, cleaning up...' >&2
rmdir '$lockdir'
exit 1
" 1 2 13 15
numtries=100
i=$numtries
while test $i -gt 0; do
# mkdir is a portable test-and-set.
if mkdir "$lockdir" 2>/dev/null; then
# This process acquired the lock.
"$@" -MD
stat=$?
# Release the lock.
rmdir "$lockdir"
break
else
# If the lock is being held by a different process, wait
# until the winning process is done or we timeout.
while test -d "$lockdir" && test $i -gt 0; do
sleep 1
i=`expr $i - 1`
done
fi
i=`expr $i - 1`
done
trap - 1 2 13 15
if test $i -le 0; then
echo "$0: failed to acquire lock after $numtries attempts" >&2
echo "$0: check lockdir '$lockdir'" >&2
exit 1
fi
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each line is of the form `foo.o: dependent.h',
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp2)
# The "hp" stanza above does not work with aCC (C++) and HP's ia64
# compilers, which have integrated preprocessors. The correct option
# to use with these is +Maked; it writes dependencies to a file named
# 'foo.d', which lands next to the object file, wherever that
# happens to be.
# Much of this is similar to the tru64 case; see comments there.
set_dir_from "$object"
set_base_from "$object"
if test "$libtool" = yes; then
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir.libs/$base.d
"$@" -Wc,+Maked
else
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir$base.d
"$@" +Maked
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile"
# Add 'dependent.h:' lines.
sed -ne '2,${
s/^ *//
s/ \\*$//
s/$/:/
p
}' "$tmpdepfile" >> "$depfile"
else
make_dummy_depfile
fi
rm -f "$tmpdepfile" "$tmpdepfile2"
;;
tru64)
# The Tru64 compiler uses -MD to generate dependencies as a side
# effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'.
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
# dependencies in 'foo.d' instead, so we check for that too.
# Subdirectories are respected.
set_dir_from "$object"
set_base_from "$object"
if test "$libtool" = yes; then
# Libtool generates 2 separate objects for the 2 libraries. These
# two compilations output dependencies in $dir.libs/$base.o.d and
# in $dir$base.o.d. We have to check for both files, because
# one of the two compilations can be disabled. We should prefer
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
# automatically cleaned when .libs/ is deleted, while ignoring
# the former would cause a distcleancheck panic.
tmpdepfile1=$dir$base.o.d # libtool 1.5
tmpdepfile2=$dir.libs/$base.o.d # Likewise.
tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504
"$@" -Wc,-MD
else
tmpdepfile1=$dir$base.d
tmpdepfile2=$dir$base.d
tmpdepfile3=$dir$base.d
"$@" -MD
fi
stat=$?
if test $stat -ne 0; then
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
do
test -f "$tmpdepfile" && break
done
# Same post-processing that is required for AIX mode.
aix_post_process_depfile
;;
msvc7)
if test "$libtool" = yes; then
showIncludes=-Wc,-showIncludes
else
showIncludes=-showIncludes
fi
"$@" $showIncludes > "$tmpdepfile"
stat=$?
grep -v '^Note: including file: ' "$tmpdepfile"
if test $stat -ne 0; then
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
# The first sed program below extracts the file names and escapes
# backslashes for cygpath. The second sed program outputs the file
# name when reading, but also accumulates all include files in the
# hold buffer in order to output them again at the end. This only
# works with sed implementations that can handle large buffers.
sed < "$tmpdepfile" -n '
/^Note: including file: *\(.*\)/ {
s//\1/
s/\\/\\\\/g
p
}' | $cygpath_u | sort -u | sed -n '
s/ /\\ /g
s/\(.*\)/'"$tab"'\1 \\/p
s/.\(.*\) \\/\1:/
H
$ {
s/.*/'"$tab"'/
G
p
}' >> "$depfile"
echo >> "$depfile" # make sure the fragment doesn't end with a backslash
rm -f "$tmpdepfile"
;;
msvc7msys)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
#nosideeffect)
# This comment above is used by automake to tell side-effect
# dependency tracking mechanisms from slower ones.
dashmstdout)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout, regardless of -o.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# Remove '-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
test -z "$dashmflag" && dashmflag=-M
# Require at least two characters before searching for ':'
# in the target name. This is to cope with DOS-style filenames:
# a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
"$@" $dashmflag |
sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this sed invocation
# correctly. Breaking it into two sed invocations is a workaround.
tr ' ' "$nl" < "$tmpdepfile" \
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
dashXmstdout)
# This case only exists to satisfy depend.m4. It is never actually
# run, as this mode is specially recognized in the preamble.
exit 1
;;
makedepend)
"$@" || exit $?
# Remove any Libtool call
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# X makedepend
shift
cleared=no eat=no
for arg
do
case $cleared in
no)
set ""; shift
cleared=yes ;;
esac
if test $eat = yes; then
eat=no
continue
fi
case "$arg" in
-D*|-I*)
set fnord "$@" "$arg"; shift ;;
# Strip any option that makedepend may not understand. Remove
# the object too, otherwise makedepend will parse it as a source file.
-arch)
eat=yes ;;
-*|$object)
;;
*)
set fnord "$@" "$arg"; shift ;;
esac
done
obj_suffix=`echo "$object" | sed 's/^.*\././'`
touch "$tmpdepfile"
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
rm -f "$depfile"
# makedepend may prepend the VPATH from the source file name to the object.
# No need to regex-escape $object, excess matching of '.' is harmless.
sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process the last invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed '1,2d' "$tmpdepfile" \
| tr ' ' "$nl" \
| sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \
| sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile" "$tmpdepfile".bak
;;
cpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
# Remove '-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
"$@" -E \
| sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
| sed '$ s: \\$::' > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
cat < "$tmpdepfile" >> "$depfile"
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvisualcpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test "X$1" != 'X--mode=compile'; do
shift
done
shift
fi
IFS=" "
for arg
do
case "$arg" in
-o)
shift
;;
$object)
shift
;;
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
set fnord "$@"
shift
shift
;;
*)
set fnord "$@" "$arg"
shift
shift
;;
esac
done
"$@" -E 2>/dev/null |
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile"
echo "$tab" >> "$depfile"
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvcmsys)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
none)
exec "$@"
;;
*)
echo "Unknown depmode $depmode" 1>&2
exit 1
;;
esac
exit 0
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:

View File

@ -21,7 +21,7 @@
#include "dev_interface.h" #include "dev_interface.h"
#include "dev_areca.h" #include "dev_areca.h"
const char * dev_areca_cpp_cvsid = "$Id: dev_areca.cpp 4209 2016-01-22 20:49:44Z chrfranke $" const char * dev_areca_cpp_cvsid = "$Id: dev_areca.cpp 4582 2017-11-03 20:54:56Z chrfranke $"
DEV_ARECA_H_CVSID; DEV_ARECA_H_CVSID;
#include "atacmds.h" #include "atacmds.h"
@ -157,6 +157,7 @@ int generic_areca_device::arcmsr_command_handler(unsigned long arcmsr_cmd, unsig
sBuf.srbioctl.Length = data_len; sBuf.srbioctl.Length = data_len;
memcpy((unsigned char *)sBuf.ioctldatabuffer, (unsigned char *)data, data_len); memcpy((unsigned char *)sBuf.ioctldatabuffer, (unsigned char *)data, data_len);
} }
/* FALLTHRU */
// commands for clearing related buffer of driver // commands for clearing related buffer of driver
case ARCMSR_CLEAR_RQBUFFER: case ARCMSR_CLEAR_RQBUFFER:
case ARCMSR_CLEAR_WQBUFFER: case ARCMSR_CLEAR_WQBUFFER:

View File

@ -3,7 +3,7 @@
* *
* Home page of code is: http://www.smartmontools.org * Home page of code is: http://www.smartmontools.org
* *
* Copyright (C) 2008 Christian Franke <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2008 Christian Franke
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -22,7 +22,7 @@
#include <errno.h> #include <errno.h>
const char * dev_ata_cmd_set_cpp_cvsid = "$Id: dev_ata_cmd_set.cpp 4122 2015-08-27 19:08:07Z chrfranke $" const char * dev_ata_cmd_set_cpp_cvsid = "$Id: dev_ata_cmd_set.cpp 4431 2017-08-08 19:38:15Z chrfranke $"
DEV_ATA_CMD_SET_H_CVSID; DEV_ATA_CMD_SET_H_CVSID;

View File

@ -3,7 +3,7 @@
* *
* Home page of code is: http://www.smartmontools.org * Home page of code is: http://www.smartmontools.org
* *
* Copyright (C) 2008 Christian Franke <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2008 Christian Franke
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -18,7 +18,7 @@
#ifndef DEV_ATA_CMD_SET_H #ifndef DEV_ATA_CMD_SET_H
#define DEV_ATA_CMD_SET_H #define DEV_ATA_CMD_SET_H
#define DEV_ATA_CMD_SET_H_CVSID "$Id: dev_ata_cmd_set.h 4122 2015-08-27 19:08:07Z chrfranke $" #define DEV_ATA_CMD_SET_H_CVSID "$Id: dev_ata_cmd_set.h 4431 2017-08-08 19:38:15Z chrfranke $"
#include "atacmds.h" // smart_command_set #include "atacmds.h" // smart_command_set
#include "dev_interface.h" #include "dev_interface.h"

304
dev_intelliprop.cpp Normal file
View File

@ -0,0 +1,304 @@
/*
* dev_intelliprop.cpp
*
* Home page of code is: http://www.smartmontools.org
*
* Copyright (C) 2016 Casey Biemiller <cbiemiller@intelliprop.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/>.
*
*/
#include "config.h"
#include "int64.h"
#include "atacmds.h" //ATTR_PACKED and ASSERT_SIZEOF_STRUCT
#include "dev_interface.h"
#include "dev_intelliprop.h"
#include "dev_tunnelled.h"
#include <errno.h>
const char * dev_intelliprop_cpp_cvsid = "$Id: dev_intelliprop.cpp 4370 2017-01-11 20:35:38Z chrfranke $"
DEV_INTELLIPROP_H_CVSID;
//Vendor Specific log addresses
#define LOG_C0 0xc0
// VS LOG MODE CONTROL BITS
enum {
IPROP_VS_LOG_MODE_CTL_AUTO_SUPPORTED = (0 << 0), // NOTE: Not supported
IPROP_VS_LOG_MODE_CTL_MANUAL_SUPPORTED = (1 << 1),
IPROP_VS_LOG_MODE_CTL_AUTO_ENABLED = (0 << 2), // NOTE: Not supported
IPROP_VS_LOG_MODE_CTL_MANUAL_ENABLED = (1 << 3),
};
// VS LOG PORT SETTING BITS
enum {
IPROP_VS_LOG_PORT_WRITE_ENABLE_MASK = 0xC000,
IPROP_VS_LOG_PORT_WRITE_ENABLE_VALID = 0x8000,
IPROP_VS_LOG_PORT_RX_DC_GAIN_MASK = 0x3000,
IPROP_VS_LOG_PORT_RX_DC_GAIN_SHIFT = 12,
IPROP_VS_LOG_PORT_RX_EQ_MASK = 0x0F00,
IPROP_VS_LOG_PORT_RX_EQ_SHIFT = 8,
IPROP_VS_LOG_PORT_TX_PREEMP_MASK = 0x00F8,
IPROP_VS_LOG_PORT_TX_PREEMP_SHIFT = 3,
IPROP_VS_LOG_PORT_TX_VOD_MASK = 0x0007,
IPROP_VS_LOG_PORT_TX_VOD_SHIFT = 0,
};
//This struct is used for the Vendor Specific log C0 on devices that support it.
#pragma pack(1)
struct iprop_internal_log
{
uint32_t drive_select; // Bytes - [ 3: 0] of Log C0
uint32_t obsolete; // Bytes - [ 7: 4] of Log C0
uint8_t mode_control; // Byte - [ 8] of Log C0
uint8_t log_passthrough; // Byte - [ 9] of Log C0
uint16_t tier_id; // Bytes - [ 11: 10] of Log C0
uint32_t hw_version; // Bytes - [ 15: 12] of Log C0
uint32_t fw_version; // Bytes - [ 19: 16] of Log C0
uint8_t variant[8]; // Bytes - [ 27: 20] of Log C0
uint8_t reserved[228]; // Bytes - [255: 28] of Log C0
uint16_t port_0_settings[3]; // Bytes - [263:256] of Log C0
uint16_t port_0_reserved;
uint16_t port_1_settings[3]; // Bytes - [271:264] of Log C0
uint16_t port_1_reserved;
uint16_t port_2_settings[3]; // Bytes - [279:272] of Log C0
uint16_t port_2_reserved;
uint16_t port_3_settings[3]; // Bytes - [287:280] of Log C0
uint16_t port_3_reserved;
uint16_t port_4_settings[3]; // Bytes - [295:288] of Log C0
uint16_t port_4_reserved;
uint8_t reserved2[214]; // Bytes - [509:296] of Log C0
uint16_t crc; // Bytes - [511:510] of Log C0
} ATTR_PACKED;
#pragma pack()
ASSERT_SIZEOF_STRUCT(iprop_internal_log, 512);
/**
* buffer is a pointer to a buffer of bytes, which should include data and
* also CRC if the function is being used to check CRC
* len is the number of bytes in the buffer (including CRC if it is present)
* check_crc is a boolean value, set true to check an existing CRC, false
* to calculate a new CRC
*/
static uint16_t iprop_crc16_1(uint8_t * buffer, uint32_t len, bool check_crc)
{
uint8_t crc[16];
uint16_t crc_final = 0;
uint8_t crc_msb;
uint8_t data_msb;
uint32_t total_len;
// Initialize CRC array
for (uint32_t ii = 0; ii < 16; ii++) {
crc[ii] = 0;
//crc[ii] = (crc_in >> ii) & 1;
}
// If calculating a new CRC, we need to pad the data with extra zeroes
total_len = check_crc ? len : len + 2;
// Loop for each byte, plus extra for the CRC itself
for (uint32_t ii = 0; ii < total_len; ii++) {
uint8_t data = (ii < len) ? buffer[ii] : 0;
// Loop for each bit
for (uint32_t jj = 0; jj < 8; jj++) {
crc_msb = crc[15];
data_msb = (data >> (8 - jj - 1)) & 1;
crc[15] = crc[14] ^ crc_msb;
crc[14] = crc[13];
crc[13] = crc[12];
crc[12] = crc[11];
crc[11] = crc[10] ^ crc_msb;
crc[10] = crc[9];
crc[9] = crc[8] ^ crc_msb;
crc[8] = crc[7] ^ crc_msb;
crc[7] = crc[6] ^ crc_msb;
crc[6] = crc[5];
crc[5] = crc[4] ^ crc_msb;
crc[4] = crc[3] ^ crc_msb;
crc[3] = crc[2];
crc[2] = crc[1] ^ crc_msb;
crc[1] = crc[0] ^ crc_msb;
crc[0] = data_msb ^ crc_msb;
}
}
// Convert CRC array to final value
for (uint32_t ii = 0; ii < 16; ii++) {
if (crc[ii] == 1) {
crc_final |= (1 << ii);
} else {
crc_final &= ~(1 << ii);
}
}
return crc_final;
}
static void iprop_dump_log_structure(struct iprop_internal_log const * const log)
{
pout("Dumping LOG Structure:\n");
pout(" drive_select: 0x%08x\n", log->drive_select);
pout(" obsolete: 0x%08x\n", log->obsolete);
pout(" mode_control: 0x%02x\n", log->mode_control);
pout(" log_passthrough: 0x%02x\n", log->log_passthrough);
pout(" tier_id: 0x%04x\n", log->tier_id);
pout(" hw_version: 0x%08x\n", log->hw_version);
pout(" fw_version: 0x%08x\n", log->fw_version);
pout(" variant: \"");
for (int ii = 0; ii < 8; ii++) {
pout("%c", (char)log->variant[ii]);
}
pout("\"\n");
pout(" port_0_settings(Gen 1): 0x%08x\n", log->port_0_settings[0]);
pout(" port_0_settings(Gen 2): 0x%08x\n", log->port_0_settings[1]);
pout(" port_0_settings(Gen 3): 0x%08x\n", log->port_0_settings[2]);
pout(" port_1_settings(Gen 1): 0x%08x\n", log->port_1_settings[0]);
pout(" port_1_settings(Gen 2): 0x%08x\n", log->port_1_settings[1]);
pout(" port_1_settings(Gen 3): 0x%08x\n", log->port_1_settings[2]);
pout(" port_2_settings(Gen 1): 0x%08x\n", log->port_2_settings[0]);
pout(" port_2_settings(Gen 2): 0x%08x\n", log->port_2_settings[1]);
pout(" port_2_settings(Gen 3): 0x%08x\n", log->port_2_settings[2]);
pout(" port_3_settings(Gen 1): 0x%08x\n", log->port_3_settings[0]);
pout(" port_3_settings(Gen 2): 0x%08x\n", log->port_3_settings[1]);
pout(" port_3_settings(Gen 3): 0x%08x\n", log->port_3_settings[2]);
pout(" port_4_settings(Gen 1): 0x%08x\n", log->port_4_settings[0]);
pout(" port_4_settings(Gen 2): 0x%08x\n", log->port_4_settings[1]);
pout(" port_4_settings(Gen 3): 0x%08x\n", log->port_4_settings[2]);
pout(" crc: 0x%04x\n", log->crc);
pout("\n");
}
static bool iprop_switch_routed_drive(ata_device * device, int drive_select)
{
// Declare a log page buffer and initialize it with what is on the drive currently
iprop_internal_log write_payload;
if (!ataReadLogExt(device, LOG_C0, 0, 0, &write_payload, 1))
return device->set_err(EIO, "intelliprop: Initial Read Log failed: %s", device->get_errmsg());
// Check the returned data is good
uint16_t const crc_check = iprop_crc16_1((uint8_t *)&write_payload,
sizeof(struct iprop_internal_log),
false);
//If this first read fails the crc check, the log can be still sent with routing information
//as long as everything else in the log is zeroed. So there is no need to return false.
if (crc_check != 0) {
if (ata_debugmode)
pout("Intelliprop WARNING: Received log crc(0x%04X) is invalid!\n", crc_check);
iprop_dump_log_structure(&write_payload);
memset(&write_payload, 0, sizeof(struct iprop_internal_log));
}
//The option to read the log, even if successful, could be useful
if (ata_debugmode)
iprop_dump_log_structure(&write_payload);
// Modify the current drive select to what we were given
write_payload.drive_select = (uint32_t)drive_select;
if (ata_debugmode)
pout("Intelliprop - Change to port 0x%08X.\n", write_payload.drive_select);
write_payload.log_passthrough = 0; // TEST (Set to 1, non hydra member drive will abort --> test error handling)
write_payload.tier_id = 0; // TEST (Set to non-zero, non hydra member drive will abort --> test error handling)
// Update the CRC area
uint16_t const crc_new = iprop_crc16_1((uint8_t *)&write_payload,
sizeof(struct iprop_internal_log) - sizeof(uint16_t),
false);
write_payload.crc = (crc_new >> 8) | (crc_new << 8);
// Check our CRC work
uint16_t const crc_check2 = iprop_crc16_1((uint8_t *)&write_payload,
sizeof(struct iprop_internal_log),
false);
if (crc_check2 != 0)
return device->set_err(EIO, "intelliprop: Re-calculated log crc(0x%04X) is invalid!", crc_check2);
// Apply the Write LOG
if (!ataWriteLogExt(device, LOG_C0, 0, &write_payload, 1))
return device->set_err(EIO, "intelliprop: Write Log failed: %s", device->get_errmsg());
// Check that the Write LOG was applied
iprop_internal_log check_payload;
if (!ataReadLogExt(device, LOG_C0, 0, 0, &check_payload, 1))
return device->set_err(EIO, "intelliprop: Secondary Read Log failed: %s", device->get_errmsg());
if (check_payload.drive_select != write_payload.drive_select) {
if (ata_debugmode > 1)
iprop_dump_log_structure(&check_payload);
return device->set_err(EIO, "intelliprop: Current drive select val(0x%08X) is not expected(0x%08X)",
check_payload.drive_select,
write_payload.drive_select);
}
return true;
}
namespace intelliprop {
class intelliprop_device
: public tunnelled_device<
/*implements*/ ata_device,
/*by using an*/ ata_device
>
{
public:
intelliprop_device(smart_interface * intf, unsigned phydrive, ata_device * atadev);
virtual ~intelliprop_device() throw();
virtual bool open();
virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out);
private:
unsigned m_phydrive;
};
intelliprop_device::intelliprop_device(smart_interface * intf, unsigned phydrive, ata_device * atadev)
: smart_device(intf, atadev->get_dev_name(), "intelliprop", "intelliprop"),
tunnelled_device<ata_device, ata_device>(atadev),
m_phydrive(phydrive)
{
set_info().info_name = strprintf("%s [intelliprop_disk_%u]", atadev->get_info_name(), phydrive);
}
intelliprop_device::~intelliprop_device() throw()
{
}
bool intelliprop_device::open()
{
if (!tunnelled_device<ata_device, ata_device>::open())
return false;
ata_device * atadev = get_tunnel_dev();
if (!iprop_switch_routed_drive(atadev, m_phydrive)) {
close();
return set_err(atadev->get_err());
}
return true;
}
bool intelliprop_device::ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out)
{
return get_tunnel_dev()->ata_pass_through(in, out);
}
}//namespace
ata_device * get_intelliprop_device(smart_interface * intf, unsigned phydrive, ata_device * atadev)
{
return new intelliprop::intelliprop_device(intf, phydrive, atadev);
}

25
dev_intelliprop.h Normal file
View File

@ -0,0 +1,25 @@
/*
* dev_intelliprop.h
*
* Home page of code is: http://www.smartmontools.org
*
* Copyright (C) 2012 Hank Wu <hank@areca.com.tw>
*
* 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/>.
*
*/
#ifndef DEV_INTELLIPROP_H
#define DEV_INTELLIPROP_H
#define DEV_INTELLIPROP_H_CVSID "$Id: dev_intelliprop.h 4370 2017-01-11 20:35:38Z chrfranke $"
ata_device * get_intelliprop_device(smart_interface * intf, unsigned phydrive, ata_device * atadev);
#endif

View File

@ -3,7 +3,7 @@
* *
* Home page of code is: http://www.smartmontools.org * Home page of code is: http://www.smartmontools.org
* *
* Copyright (C) 2008-16 Christian Franke <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2008-16 Christian Franke
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -18,6 +18,7 @@
#include "config.h" #include "config.h"
#include "int64.h" #include "int64.h"
#include "dev_interface.h" #include "dev_interface.h"
#include "dev_intelliprop.h"
#include "dev_tunnelled.h" #include "dev_tunnelled.h"
#include "atacmds.h" // ATA_SMART_CMD/STATUS #include "atacmds.h" // ATA_SMART_CMD/STATUS
#include "utility.h" #include "utility.h"
@ -32,7 +33,7 @@
#include <sys/timeb.h> #include <sys/timeb.h>
#endif #endif
const char * dev_interface_cpp_cvsid = "$Id: dev_interface.cpp 4283 2016-04-10 12:55:59Z chrfranke $" const char * dev_interface_cpp_cvsid = "$Id: dev_interface.cpp 4431 2017-08-08 19:38:15Z chrfranke $"
DEV_INTERFACE_H_CVSID; DEV_INTERFACE_H_CVSID;
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
@ -281,8 +282,8 @@ std::string smart_interface::get_valid_dev_types_str()
{ {
// default // default
std::string s = std::string s =
"ata, scsi, nvme[,NSID], sat[,auto][,N][+TYPE], " "ata, scsi, nvme[,NSID], sat[,auto][,N][+TYPE], usbcypress[,X], "
"usbcypress[,X], usbjmicron[,p][,x][,N], usbprolific, usbsunplus"; "usbjmicron[,p][,x][,N], usbprolific, usbsunplus, intelliprop,N[+TYPE]";
// append custom // append custom
std::string s2 = get_valid_custom_dev_types_str(); std::string s2 = get_valid_custom_dev_types_str();
if (!s2.empty()) { if (!s2.empty()) {
@ -422,6 +423,31 @@ smart_device * smart_interface::get_smart_device(const char * name, const char *
return get_sat_device(sattype.c_str(), basedev.release()->to_scsi()); return get_sat_device(sattype.c_str(), basedev.release()->to_scsi());
} }
else if (str_starts_with(type, "intelliprop")) {
// Parse "intelliprop,N[+base...]"
unsigned phydrive = ~0; int n = -1; char c = 0;
sscanf(type, "intelliprop,%u%n%c", &phydrive, &n, &c);
if (!((n == (int)strlen(type) || c == '+') && phydrive <= 3)) {
set_err(EINVAL, "Option '-d intelliprop,N' requires N between 0 and 3");
return 0;
}
const char * basetype = (type[n] ? type + n + 1 : "");
// Recurse to allocate base device, default is standard ATA
if (!*basetype)
basetype = "ata";
smart_device_auto_ptr basedev( get_smart_device(name, basetype) );
if (!basedev) {
set_err(EINVAL, "Type '%s': %s", type, get_errmsg());
return 0;
}
// Result must be ATA
if (!basedev->is_ata()) {
set_err(EINVAL, "Type '%s': Device type '%s' is not ATA", type, basetype);
return 0;
}
return get_intelliprop_device(this, phydrive, basedev.release()->to_ata());
}
else { else {
set_err(EINVAL, "Unknown device type '%s'", type); set_err(EINVAL, "Unknown device type '%s'", type);
return 0; return 0;

View File

@ -3,7 +3,7 @@
* *
* Home page of code is: http://www.smartmontools.org * Home page of code is: http://www.smartmontools.org
* *
* Copyright (C) 2008-16 Christian Franke <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2008-16 Christian Franke
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -25,7 +25,7 @@
#include <errno.h> #include <errno.h>
const char * dev_legacy_cpp_cvsid = "$Id: dev_legacy.cpp 4251 2016-03-26 16:48:32Z chrfranke $" const char * dev_legacy_cpp_cvsid = "$Id: dev_legacy.cpp 4431 2017-08-08 19:38:15Z chrfranke $"
DEV_INTERFACE_H_CVSID; DEV_INTERFACE_H_CVSID;
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

View File

@ -3,7 +3,7 @@
* *
* Home page of code is: http://www.smartmontools.org * Home page of code is: http://www.smartmontools.org
* *
* Copyright (C) 2008 Christian Franke <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2008 Christian Franke
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -18,7 +18,7 @@
#ifndef DEV_TUNNELLED_H #ifndef DEV_TUNNELLED_H
#define DEV_TUNNELLED_H #define DEV_TUNNELLED_H
#define DEV_TUNNELLED_H_CVSID "$Id: dev_tunnelled.h 4122 2015-08-27 19:08:07Z chrfranke $" #define DEV_TUNNELLED_H_CVSID "$Id: dev_tunnelled.h 4431 2017-08-08 19:38:15Z chrfranke $"
#include "dev_interface.h" #include "dev_interface.h"

View File

@ -1,145 +0,0 @@
#!/bin/bash
#
# do a smartmontools release
# (C) 2003-11 Bruce Allen, Guido Guenther
# (C) 2006-15 Christian Franke
# $Id: do_release 4071 2015-04-26 18:25:12Z chrfranke $
# Notes on generating releases:
# (1) update NEWS
# (2) update ChangeLog -- put in release number
# (3) update release number in configure.ac
# (4) to test, run without '--commit'
# (5) when satisfied, add option '--commit'
set -e
# Smartmontools Signing Key (through 2016)
KEYID=0xC4A4903A
inc_release()
{
MINOR=`echo $VERSION | cut -d. -f2`
MAJOR=`echo $VERSION | cut -d. -f1`
PERL_OLD=$MAJOR\\.$MINOR
((++MINOR))
NEW_VERSION=$MAJOR.$MINOR
PERL_NEW=$MAJOR\\.$MINOR
NEW_RELEASE="RELEASE_${NEW_VERSION//\./_}"
echo "New Version: $NEW_VERSION"
echo "New Release: $NEW_RELEASE"
}
COMMIT=
RC=
case "$1" in
--commit) COMMIT=yes; shift ;;
esac
case "$*" in
RC[1-9]) RC="$1" ;;
FINAL) ;;
*) echo "Usage: $0 [--commit] RC[1-9]|FINAL"; exit 1 ;;
esac
# Check workdir
case "`/bin/pwd`" in
*/trunk/smartmontools) WDROOT="../.."; DIRPAT="trunk" ;;
*/branches/*/smartmontools) WDROOT="../../.."; DIRPAT="branches/*" ;;
*) echo "`/bin/pwd`: no trunk or branch working dir"; exit 1 ;;
esac
if [ ! -d "$WDROOT/tags" ]; then
echo "tags directory missing"; exit 1
fi
REVX="`(cd $WDROOT && svnversion)`" || exit 1
REV="${REVX/%[PM]/}"; REV="${REV/%[PM]/}"
if [ -n "${REV//[0-9]/}" ]; then
echo "Working directory not clean: $REVX"; exit 1
fi
(cd $WDROOT && svn status) | while read s; do
case "`echo $s | tr -s ' '`" in
"M "$DIRPAT/smartmontools/ChangeLog) echo "$s: OK";;
"M "$DIRPAT/smartmontools/NEWS) echo "$s: OK";;
"M "$DIRPAT/smartmontools/configure.ac) echo "$s: OK";;
*) echo "$s: not allowed"; exit 1;;
esac
done
if [ $? -ne 0 ]; then
exit 1
fi
# Get release number
VERSION=`sed -n 's|^AC_INIT[^,]*, *\([0-9.]*\) *,.*$|\1|p' configure.ac`
if [ -z "$VERSION" ]; then
echo "AC_INIT not found in configure.ac"; exit 1
fi
VERSIONRC="$VERSION"
RELEASE="RELEASE_${VERSION//\./_}"
if [ "$RC" ]; then
VERSIONRC="${VERSION}-${RC/#RC/rc}"
RELEASE="${RELEASE}_${RC}"
fi
if [ -e "$WDROOT/tags/$RELEASE" ]; then
echo "tags/$RELEASE exists"; exit 1
fi
echo "r$REV: Release $VERSIONRC $RELEASE"
# Update timestamp
smartmontools_release_date=`date -u +"%Y-%m-%d"`
smartmontools_release_time=`date -u +"%T %Z"`
cat configure.ac | sed "s|smartmontools_release_date=.*|smartmontools_release_date=${smartmontools_release_date}|" > configure.tmp
cat configure.tmp | sed "s|smartmontools_release_time=.*|smartmontools_release_time=\"${smartmontools_release_time}\"|" > configure.ac
rm -f configure.tmp
# Review changes
svn diff
echo "==================================================================="
echo ">>> Continuing in 20 seconds ..."
sleep 20
set -v
# Create tag and commit
if [ "$COMMIT" = "yes" ]; then
svn mkdir $WDROOT/tags/$RELEASE
svn copy ../smartmontools $WDROOT/tags/$RELEASE/smartmontools
svn commit -m "Release $VERSIONRC $RELEASE" $WDROOT
fi
# Build
./autogen.sh
mkdir build
cd build
../configure
make distcheck || exit 1
make maintainer-clean
cd ..
TARFILE=smartmontools-$VERSIONRC.tar.gz
mv -f build/smartmontools-$VERSION.tar.gz $TARFILE
rm -rvf build
md5sum $TARFILE > $TARFILE.md5
# Increase release number
if [ -z "$RC" -a "$DIRPAT" = "trunk" ]; then
inc_release
if [ "$COMMIT" = "yes" ]; then
perl -p -i.bak -e "s/$PERL_OLD/$PERL_NEW/" configure.ac
# svn commit -m "Bump release number to $NEW_VERSION" configure.ac
fi
fi
# Sign tarball
if [ -n "$KEYID" ] && gpg --list-secret-keys $KEYID >/dev/null 2>/dev/null; then
gpg --default-key $KEYID --armor --detach-sign ./smartmontools-$VERSIONRC.tar.gz
fi

831
drivedb.h

File diff suppressed because it is too large Load Diff

View File

@ -31,6 +31,7 @@
#define NVME_PASSTHROUGH_CMD _IOWR('n', 0, struct nvme_pt_command) #define NVME_PASSTHROUGH_CMD _IOWR('n', 0, struct nvme_pt_command)
#if __FreeBSD_version < 1100110
struct nvme_command struct nvme_command
{ {
/* dword 0 */ /* dword 0 */
@ -143,6 +144,9 @@ struct nvme_pt_command {
*/ */
struct mtx * driver_lock; struct mtx * driver_lock;
}; };
#else
#include <dev/nvme/nvme.h>
#endif
#define nvme_completion_is_error(cpl) \ #define nvme_completion_is_error(cpl) \
((cpl)->status.sc != 0 || (cpl)->status.sct != 0) ((cpl)->status.sc != 0 || (cpl)->status.sct != 0)

501
install-sh Executable file
View File

@ -0,0 +1,501 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2016-01-11.22; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# 'make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
tab=' '
nl='
'
IFS=" $tab$nl"
# Set DOITPROG to "echo" to test this script.
doit=${DOITPROG-}
doit_exec=${doit:-exec}
# Put in absolute file names if you don't have them in your path;
# or use environment vars.
chgrpprog=${CHGRPPROG-chgrp}
chmodprog=${CHMODPROG-chmod}
chownprog=${CHOWNPROG-chown}
cmpprog=${CMPPROG-cmp}
cpprog=${CPPROG-cp}
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}
posix_mkdir=
# Desired mode of installed file.
mode=0755
chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f"
stripcmd=
src=
dst=
dir_arg=
dst_arg=
copy_on_change=false
is_target_a_directory=possibly
usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.
Options:
--help display this help and exit.
--version display version info and exit.
-c (ignored)
-C install only if different (preserve the last data modification time)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-s $stripprog installed files.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
RMPROG STRIPPROG
"
while test $# -ne 0; do
case $1 in
-c) ;;
-C) copy_on_change=true;;
-d) dir_arg=true;;
-g) chgrpcmd="$chgrpprog $2"
shift;;
--help) echo "$usage"; exit $?;;
-m) mode=$2
case $mode in
*' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
echo "$0: invalid mode: $mode" >&2
exit 1;;
esac
shift;;
-o) chowncmd="$chownprog $2"
shift;;
-s) stripcmd=$stripprog;;
-t)
is_target_a_directory=always
dst_arg=$2
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
shift;;
-T) is_target_a_directory=never;;
--version) echo "$0 $scriptversion"; exit $?;;
--) shift
break;;
-*) echo "$0: invalid option: $1" >&2
exit 1;;
*) break;;
esac
shift
done
# We allow the use of options -d and -T together, by making -d
# take the precedence; this is for compatibility with GNU install.
if test -n "$dir_arg"; then
if test -n "$dst_arg"; then
echo "$0: target directory not allowed when installing a directory." >&2
exit 1
fi
fi
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dst_arg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dst_arg"
shift # fnord
fi
shift # arg
dst_arg=$arg
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
done
fi
if test $# -eq 0; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call 'install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
if test -z "$dir_arg"; then
if test $# -gt 1 || test "$is_target_a_directory" = always; then
if test ! -d "$dst_arg"; then
echo "$0: $dst_arg: Is not a directory." >&2
exit 1
fi
fi
fi
if test -z "$dir_arg"; then
do_exit='(exit $ret); exit $ret'
trap "ret=129; $do_exit" 1
trap "ret=130; $do_exit" 2
trap "ret=141; $do_exit" 13
trap "ret=143; $do_exit" 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
case $mode in
# Optimize common cases.
*644) cp_umask=133;;
*755) cp_umask=22;;
*[0-7])
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw='% 200'
fi
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
*)
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw=,u+rw
fi
cp_umask=$mode$u_plus_rw;;
esac
fi
for src
do
# Protect names problematic for 'test' and other utilities.
case $src in
-* | [=\(\)!]) src=./$src;;
esac
if test -n "$dir_arg"; then
dst=$src
dstdir=$dst
test -d "$dstdir"
dstdir_status=$?
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dst_arg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dst_arg
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
if test -d "$dst"; then
if test "$is_target_a_directory" = never; then
echo "$0: $dst_arg: Is a directory" >&2
exit 1
fi
dstdir=$dst
dst=$dstdir/`basename "$src"`
dstdir_status=0
else
dstdir=`dirname "$dst"`
test -d "$dstdir"
dstdir_status=$?
fi
fi
obsolete_mkdir_used=false
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
# Create intermediate dirs using mode 755 as modified by the umask.
# This is like FreeBSD 'install' as of 1997-10-28.
umask=`umask`
case $stripcmd.$umask in
# Optimize common cases.
*[2367][2367]) mkdir_umask=$umask;;
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
*[0-7])
mkdir_umask=`expr $umask + 22 \
- $umask % 100 % 40 + $umask % 20 \
- $umask % 10 % 4 + $umask % 2
`;;
*) mkdir_umask=$umask,go-w;;
esac
# With -d, create the new directory with the user-specified mode.
# Otherwise, rely on $mkdir_umask.
if test -n "$dir_arg"; then
mkdir_mode=-m$mode
else
mkdir_mode=
fi
posix_mkdir=false
case $umask in
*[123567][0-7][0-7])
# POSIX mkdir -p sets u+wx bits regardless of umask, which
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
;;
*)
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
if (umask $mkdir_umask &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
then
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
ls_ld_tmpdir=`ls -ld "$tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/d" "$tmpdir"
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
fi
trap '' 0;;
esac;;
esac
if
$posix_mkdir && (
umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
)
then :
else
# The umask is ridiculous, or mkdir does not conform to POSIX,
# or it failed possibly due to a race condition. Create the
# directory the slow way, step by step, checking for races as we go.
case $dstdir in
/*) prefix='/';;
[-=\(\)!]*) prefix='./';;
*) prefix='';;
esac
oIFS=$IFS
IFS=/
set -f
set fnord $dstdir
shift
set +f
IFS=$oIFS
prefixes=
for d
do
test X"$d" = X && continue
prefix=$prefix$d
if test -d "$prefix"; then
prefixes=
else
if $posix_mkdir; then
(umask=$mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
# Don't fail if two instances are running concurrently.
test -d "$prefix" || exit 1
else
case $prefix in
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
*) qprefix=$prefix;;
esac
prefixes="$prefixes '$qprefix'"
fi
fi
prefix=$prefix/
done
if test -n "$prefixes"; then
# Don't fail if two instances are running concurrently.
(umask $mkdir_umask &&
eval "\$doit_exec \$mkdirprog $prefixes") ||
test -d "$dstdir" || exit 1
obsolete_mkdir_used=true
fi
fi
fi
if test -n "$dir_arg"; then
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
else
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
# Copy the file name to the temp name.
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
# If -C, don't bother to copy if it wouldn't change the file.
if $copy_on_change &&
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
set -f &&
set X $old && old=:$2:$4:$5:$6 &&
set X $new && new=:$2:$4:$5:$6 &&
set +f &&
test "$old" = "$new" &&
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
then
rm -f "$dsttmp"
else
# Rename the file to the real destination.
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
{
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
test ! -f "$dst" ||
$doit $rmcmd -f "$dst" 2>/dev/null ||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
} ||
{ echo "$0: cannot unlink or rename $dst" >&2
(exit 1); exit 1
}
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dst"
}
fi || exit 1
trap '' 0
fi
done
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:

View File

@ -3,7 +3,7 @@
* *
* Home page of code is: http://www.smartmontools.org * Home page of code is: http://www.smartmontools.org
* *
* Copyright (C) 2002-11 Bruce Allen <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2002-11 Bruce Allen
* Copyright (C) 2004-11 Christian Franke * Copyright (C) 2004-11 Christian Franke
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -20,7 +20,7 @@
#ifndef INT64_H_ #ifndef INT64_H_
#define INT64_H_ #define INT64_H_
#define INT64_H_CVSID "$Id: int64.h 4120 2015-08-27 16:12:21Z samm2 $" #define INT64_H_CVSID "$Id: int64.h 4431 2017-08-08 19:38:15Z chrfranke $"
// 64 bit integer typedefs and format strings // 64 bit integer typedefs and format strings

275
m4/pkg.m4 Normal file
View File

@ -0,0 +1,275 @@
dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
dnl serial 11 (pkg-config-0.29.1)
dnl
dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
dnl
dnl This program is free software; you can redistribute it and/or modify
dnl it under the terms of the GNU General Public License as published by
dnl the Free Software Foundation; either version 2 of the License, or
dnl (at your option) any later version.
dnl
dnl This program is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
dnl General Public License for more details.
dnl
dnl You should have received a copy of the GNU General Public License
dnl along with this program; if not, write to the Free Software
dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
dnl 02111-1307, USA.
dnl
dnl As a special exception to the GNU General Public License, if you
dnl distribute this file as part of a program that contains a
dnl configuration script generated by Autoconf, you may include it under
dnl the same distribution terms that you use for the rest of that
dnl program.
dnl PKG_PREREQ(MIN-VERSION)
dnl -----------------------
dnl Since: 0.29
dnl
dnl Verify that the version of the pkg-config macros are at least
dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's
dnl installed version of pkg-config, this checks the developer's version
dnl of pkg.m4 when generating configure.
dnl
dnl To ensure that this macro is defined, also add:
dnl m4_ifndef([PKG_PREREQ],
dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])])
dnl
dnl See the "Since" comment for each macro you use to see what version
dnl of the macros you require.
m4_defun([PKG_PREREQ],
[m4_define([PKG_MACROS_VERSION], [0.29.1])
m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
[m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
])dnl PKG_PREREQ
dnl PKG_PROG_PKG_CONFIG([MIN-VERSION])
dnl ----------------------------------
dnl Since: 0.16
dnl
dnl Search for the pkg-config tool and set the PKG_CONFIG variable to
dnl first found in the path. Checks that the version of pkg-config found
dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is
dnl used since that's the first version where most current features of
dnl pkg-config existed.
AC_DEFUN([PKG_PROG_PKG_CONFIG],
[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
fi
if test -n "$PKG_CONFIG"; then
_pkg_min_version=m4_default([$1], [0.9.0])
AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
PKG_CONFIG=""
fi
fi[]dnl
])dnl PKG_PROG_PKG_CONFIG
dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
dnl -------------------------------------------------------------------
dnl Since: 0.18
dnl
dnl Check to see whether a particular set of modules exists. Similar to
dnl PKG_CHECK_MODULES(), but does not set variables or print errors.
dnl
dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
dnl only at the first occurence in configure.ac, so if the first place
dnl it's called might be skipped (such as if it is within an "if", you
dnl have to call PKG_CHECK_EXISTS manually
AC_DEFUN([PKG_CHECK_EXISTS],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
if test -n "$PKG_CONFIG" && \
AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
m4_default([$2], [:])
m4_ifvaln([$3], [else
$3])dnl
fi])
dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
dnl ---------------------------------------------
dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting
dnl pkg_failed based on the result.
m4_define([_PKG_CONFIG],
[if test -n "$$1"; then
pkg_cv_[]$1="$$1"
elif test -n "$PKG_CONFIG"; then
PKG_CHECK_EXISTS([$3],
[pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes ],
[pkg_failed=yes])
else
pkg_failed=untried
fi[]dnl
])dnl _PKG_CONFIG
dnl _PKG_SHORT_ERRORS_SUPPORTED
dnl ---------------------------
dnl Internal check to see if pkg-config supports short errors.
AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
_pkg_short_errors_supported=yes
else
_pkg_short_errors_supported=no
fi[]dnl
])dnl _PKG_SHORT_ERRORS_SUPPORTED
dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
dnl [ACTION-IF-NOT-FOUND])
dnl --------------------------------------------------------------
dnl Since: 0.4.0
dnl
dnl Note that if there is a possibility the first call to
dnl PKG_CHECK_MODULES might not happen, you should be sure to include an
dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
AC_DEFUN([PKG_CHECK_MODULES],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
pkg_failed=no
AC_MSG_CHECKING([for $1])
_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
_PKG_CONFIG([$1][_LIBS], [libs], [$2])
m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
and $1[]_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.])
if test $pkg_failed = yes; then
AC_MSG_RESULT([no])
_PKG_SHORT_ERRORS_SUPPORTED
if test $_pkg_short_errors_supported = yes; then
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
else
$1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
m4_default([$4], [AC_MSG_ERROR(
[Package requirements ($2) were not met:
$$1_PKG_ERRORS
Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.
_PKG_TEXT])[]dnl
])
elif test $pkg_failed = untried; then
AC_MSG_RESULT([no])
m4_default([$4], [AC_MSG_FAILURE(
[The pkg-config script could not be found or is too old. Make sure it
is in your PATH or set the PKG_CONFIG environment variable to the full
path to pkg-config.
_PKG_TEXT
To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
])
else
$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
$1[]_LIBS=$pkg_cv_[]$1[]_LIBS
AC_MSG_RESULT([yes])
$3
fi[]dnl
])dnl PKG_CHECK_MODULES
dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
dnl [ACTION-IF-NOT-FOUND])
dnl ---------------------------------------------------------------------
dnl Since: 0.29
dnl
dnl Checks for existence of MODULES and gathers its build flags with
dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags
dnl and VARIABLE-PREFIX_LIBS from --libs.
dnl
dnl Note that if there is a possibility the first call to
dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to
dnl include an explicit call to PKG_PROG_PKG_CONFIG in your
dnl configure.ac.
AC_DEFUN([PKG_CHECK_MODULES_STATIC],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
_save_PKG_CONFIG=$PKG_CONFIG
PKG_CONFIG="$PKG_CONFIG --static"
PKG_CHECK_MODULES($@)
PKG_CONFIG=$_save_PKG_CONFIG[]dnl
])dnl PKG_CHECK_MODULES_STATIC
dnl PKG_INSTALLDIR([DIRECTORY])
dnl -------------------------
dnl Since: 0.27
dnl
dnl Substitutes the variable pkgconfigdir as the location where a module
dnl should install pkg-config .pc files. By default the directory is
dnl $libdir/pkgconfig, but the default can be changed by passing
dnl DIRECTORY. The user can override through the --with-pkgconfigdir
dnl parameter.
AC_DEFUN([PKG_INSTALLDIR],
[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])])
m4_pushdef([pkg_description],
[pkg-config installation directory @<:@]pkg_default[@:>@])
AC_ARG_WITH([pkgconfigdir],
[AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],,
[with_pkgconfigdir=]pkg_default)
AC_SUBST([pkgconfigdir], [$with_pkgconfigdir])
m4_popdef([pkg_default])
m4_popdef([pkg_description])
])dnl PKG_INSTALLDIR
dnl PKG_NOARCH_INSTALLDIR([DIRECTORY])
dnl --------------------------------
dnl Since: 0.27
dnl
dnl Substitutes the variable noarch_pkgconfigdir as the location where a
dnl module should install arch-independent pkg-config .pc files. By
dnl default the directory is $datadir/pkgconfig, but the default can be
dnl changed by passing DIRECTORY. The user can override through the
dnl --with-noarch-pkgconfigdir parameter.
AC_DEFUN([PKG_NOARCH_INSTALLDIR],
[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])])
m4_pushdef([pkg_description],
[pkg-config arch-independent installation directory @<:@]pkg_default[@:>@])
AC_ARG_WITH([noarch-pkgconfigdir],
[AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],,
[with_noarch_pkgconfigdir=]pkg_default)
AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir])
m4_popdef([pkg_default])
m4_popdef([pkg_description])
])dnl PKG_NOARCH_INSTALLDIR
dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
dnl -------------------------------------------
dnl Since: 0.28
dnl
dnl Retrieves the value of the pkg-config variable for the given module.
AC_DEFUN([PKG_CHECK_VAR],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
_PKG_CONFIG([$1], [variable="][$3]["], [$2])
AS_VAR_COPY([$1], [pkg_cv_][$1])
AS_VAR_IF([$1], [""], [$5], [$4])dnl
])dnl PKG_CHECK_VAR

215
missing Executable file
View File

@ -0,0 +1,215 @@
#! /bin/sh
# Common wrapper for a few potentially missing GNU programs.
scriptversion=2016-01-11.22; # UTC
# Copyright (C) 1996-2017 Free Software Foundation, Inc.
# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# 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.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
if test $# -eq 0; then
echo 1>&2 "Try '$0 --help' for more information"
exit 1
fi
case $1 in
--is-lightweight)
# Used by our autoconf macros to check whether the available missing
# script is modern enough.
exit 0
;;
--run)
# Back-compat with the calling convention used by older automake.
shift
;;
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due
to PROGRAM being missing or too old.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
Supported PROGRAM values:
aclocal autoconf autoheader autom4te automake makeinfo
bison yacc flex lex help2man
Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and
'g' are ignored when checking the name.
Send bug reports to <bug-automake@gnu.org>."
exit $?
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing $scriptversion (GNU Automake)"
exit $?
;;
-*)
echo 1>&2 "$0: unknown '$1' option"
echo 1>&2 "Try '$0 --help' for more information"
exit 1
;;
esac
# Run the given program, remember its exit status.
"$@"; st=$?
# If it succeeded, we are done.
test $st -eq 0 && exit 0
# Also exit now if we it failed (or wasn't found), and '--version' was
# passed; such an option is passed most likely to detect whether the
# program is present and works.
case $2 in --version|--help) exit $st;; esac
# Exit code 63 means version mismatch. This often happens when the user
# tries to use an ancient version of a tool on a file that requires a
# minimum version.
if test $st -eq 63; then
msg="probably too old"
elif test $st -eq 127; then
# Program was missing.
msg="missing on your system"
else
# Program was found and executed, but failed. Give up.
exit $st
fi
perl_URL=http://www.perl.org/
flex_URL=http://flex.sourceforge.net/
gnu_software_URL=http://www.gnu.org/software
program_details ()
{
case $1 in
aclocal|automake)
echo "The '$1' program is part of the GNU Automake package:"
echo "<$gnu_software_URL/automake>"
echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:"
echo "<$gnu_software_URL/autoconf>"
echo "<$gnu_software_URL/m4/>"
echo "<$perl_URL>"
;;
autoconf|autom4te|autoheader)
echo "The '$1' program is part of the GNU Autoconf package:"
echo "<$gnu_software_URL/autoconf/>"
echo "It also requires GNU m4 and Perl in order to run:"
echo "<$gnu_software_URL/m4/>"
echo "<$perl_URL>"
;;
esac
}
give_advice ()
{
# Normalize program name to check for.
normalized_program=`echo "$1" | sed '
s/^gnu-//; t
s/^gnu//; t
s/^g//; t'`
printf '%s\n' "'$1' is $msg."
configure_deps="'configure.ac' or m4 files included by 'configure.ac'"
case $normalized_program in
autoconf*)
echo "You should only need it if you modified 'configure.ac',"
echo "or m4 files included by it."
program_details 'autoconf'
;;
autoheader*)
echo "You should only need it if you modified 'acconfig.h' or"
echo "$configure_deps."
program_details 'autoheader'
;;
automake*)
echo "You should only need it if you modified 'Makefile.am' or"
echo "$configure_deps."
program_details 'automake'
;;
aclocal*)
echo "You should only need it if you modified 'acinclude.m4' or"
echo "$configure_deps."
program_details 'aclocal'
;;
autom4te*)
echo "You might have modified some maintainer files that require"
echo "the 'autom4te' program to be rebuilt."
program_details 'autom4te'
;;
bison*|yacc*)
echo "You should only need it if you modified a '.y' file."
echo "You may want to install the GNU Bison package:"
echo "<$gnu_software_URL/bison/>"
;;
lex*|flex*)
echo "You should only need it if you modified a '.l' file."
echo "You may want to install the Fast Lexical Analyzer package:"
echo "<$flex_URL>"
;;
help2man*)
echo "You should only need it if you modified a dependency" \
"of a man page."
echo "You may want to install the GNU Help2man package:"
echo "<$gnu_software_URL/help2man/>"
;;
makeinfo*)
echo "You should only need it if you modified a '.texi' file, or"
echo "any other file indirectly affecting the aspect of the manual."
echo "You might want to install the Texinfo package:"
echo "<$gnu_software_URL/texinfo/>"
echo "The spurious makeinfo call might also be the consequence of"
echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might"
echo "want to install GNU make:"
echo "<$gnu_software_URL/make/>"
;;
*)
echo "You might have modified some files without having the proper"
echo "tools for further handling them. Check the 'README' file, it"
echo "often tells you about the needed prerequisites for installing"
echo "this package. You may also peek at any GNU archive site, in"
echo "case some other package contains this missing '$1' program."
;;
esac
}
give_advice "$1" | sed -e '1s/^/WARNING: /' \
-e '2,$s/^/ /' >&2
# Propagate the correct exit status (expected to be 127 for a program
# not found, 63 for a program that failed due to version mismatch).
exit $st
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:

183
netbsd_nvme_ioctl.h Normal file
View File

@ -0,0 +1,183 @@
/* $NetBSD: nvmereg.h,v 1.1 2016/05/01 10:21:02 nonaka Exp $ */
/* $OpenBSD: nvmereg.h,v 1.10 2016/04/14 11:18:32 dlg Exp $ */
/*
* Copyright (c) 2014 David Gwynne <dlg@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/param.h>
struct nvme_sge {
uint8_t id;
uint8_t _reserved[15];
} __packed __aligned(8);
struct nvme_sqe {
uint8_t opcode;
uint8_t flags;
uint16_t cid;
uint32_t nsid;
uint8_t _reserved[8];
uint64_t mptr;
union {
uint64_t prp[2];
struct nvme_sge sge;
} __packed entry;
uint32_t cdw10;
uint32_t cdw11;
uint32_t cdw12;
uint32_t cdw13;
uint32_t cdw14;
uint32_t cdw15;
} __packed __aligned(8);
struct nvme_cqe {
uint32_t cdw0;
uint32_t _reserved;
uint16_t sqhd; /* SQ Head Pointer */
uint16_t sqid; /* SQ Identifier */
uint16_t cid; /* Command Identifier */
uint16_t flags;
#define NVME_CQE_DNR __BIT(15)
#define NVME_CQE_M __BIT(14)
#define NVME_CQE_SCT(_f) ((_f) & (0x07 << 8))
#define NVME_CQE_SCT_GENERIC (0x00 << 8)
#define NVME_CQE_SCT_COMMAND (0x01 << 8)
#define NVME_CQE_SCT_MEDIAERR (0x02 << 8)
#define NVME_CQE_SCT_VENDOR (0x07 << 8)
#define NVME_CQE_SC(_f) ((_f) & (0x7f << 1))
#define NVME_CQE_SC_SUCCESS (0x00 << 1)
#define NVME_CQE_SC_INVALID_OPCODE (0x01 << 1)
#define NVME_CQE_SC_INVALID_FIELD (0x02 << 1)
#define NVME_CQE_SC_CID_CONFLICT (0x03 << 1)
#define NVME_CQE_SC_DATA_XFER_ERR (0x04 << 1)
#define NVME_CQE_SC_ABRT_BY_NO_PWR (0x05 << 1)
#define NVME_CQE_SC_INTERNAL_DEV_ERR (0x06 << 1)
#define NVME_CQE_SC_CMD_ABRT_REQD (0x07 << 1)
#define NVME_CQE_SC_CMD_ABDR_SQ_DEL (0x08 << 1)
#define NVME_CQE_SC_CMD_ABDR_FUSE_ERR (0x09 << 1)
#define NVME_CQE_SC_CMD_ABDR_FUSE_MISS (0x0a << 1)
#define NVME_CQE_SC_INVALID_NS (0x0b << 1)
#define NVME_CQE_SC_CMD_SEQ_ERR (0x0c << 1)
#define NVME_CQE_SC_INVALID_LAST_SGL (0x0d << 1)
#define NVME_CQE_SC_INVALID_NUM_SGL (0x0e << 1)
#define NVME_CQE_SC_DATA_SGL_LEN (0x0f << 1)
#define NVME_CQE_SC_MDATA_SGL_LEN (0x10 << 1)
#define NVME_CQE_SC_SGL_TYPE_INVALID (0x11 << 1)
#define NVME_CQE_SC_LBA_RANGE (0x80 << 1)
#define NVME_CQE_SC_CAP_EXCEEDED (0x81 << 1)
#define NVME_CQE_NS_NOT_RDY (0x82 << 1)
#define NVME_CQE_RSV_CONFLICT (0x83 << 1)
#define NVME_CQE_PHASE __BIT(0)
} __packed __aligned(8);
/*-
* Copyright (C) 2012-2013 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#define NVME_PASSTHROUGH_CMD _IOWR('n', 0, struct nvme_pt_command)
#define nvme_completion_is_error(cpl) \
((NVME_CQE_SC((cpl)->flags) != NVME_CQE_SC_SUCCESS) \
|| (NVME_CQE_SCT((cpl)->flags) != NVME_CQE_SCT_GENERIC))
struct nvme_pt_command {
/*
* cmd is used to specify a passthrough command to a controller or
* namespace.
*
* The following fields from cmd may be specified by the caller:
* * opcode
* * nsid (namespace id) - for admin commands only
* * cdw10-cdw15
*
* Remaining fields must be set to 0 by the caller.
*/
struct nvme_sqe cmd;
/*
* cpl returns completion status for the passthrough command
* specified by cmd.
*
* The following fields will be filled out by the driver, for
* consumption by the caller:
* * cdw0
* * flags (except for phase)
*
* Remaining fields will be set to 0 by the driver.
*/
struct nvme_cqe cpl;
/* buf is the data buffer associated with this passthrough command. */
void *buf;
/*
* len is the length of the data buffer associated with this
* passthrough command.
*/
uint32_t len;
/*
* is_read = 1 if the passthrough command will read data into the
* supplied buffer from the controller.
*
* is_read = 0 if the passthrough command will write data from the
* supplied buffer to the controller.
*/
uint32_t is_read;
/*
* timeout (unit: ms)
*
* 0: use default timeout value
*/
uint32_t timeout;
};
#define NVME_PREFIX "/dev/nvme"
#define NVME_NS_PREFIX "ns"

View File

@ -21,7 +21,7 @@
#ifndef NVMECMDS_H #ifndef NVMECMDS_H
#define NVMECMDS_H #define NVMECMDS_H
#define NVMECMDS_H_CVSID "$Id: nvmecmds.h 4297 2016-04-16 16:48:01Z chrfranke $" #define NVMECMDS_H_CVSID "$Id: nvmecmds.h 4488 2017-09-25 11:54:15Z samm2 $"
#include "int64.h" #include "int64.h"
@ -92,7 +92,8 @@ struct nvme_id_ctrl {
unsigned int rtd3r; unsigned int rtd3r;
unsigned int rtd3e; unsigned int rtd3e;
unsigned int oaes; unsigned int oaes;
unsigned char rsvd96[160]; unsigned int ctratt;
unsigned char rsvd100[156];
unsigned short oacs; unsigned short oacs;
unsigned char acl; unsigned char acl;
unsigned char aerl; unsigned char aerl;
@ -110,10 +111,18 @@ struct nvme_id_ctrl {
unsigned char tnvmcap[16]; unsigned char tnvmcap[16];
unsigned char unvmcap[16]; unsigned char unvmcap[16];
unsigned int rpmbs; unsigned int rpmbs;
unsigned char rsvd316[196]; unsigned short edstt;
unsigned char dsto;
unsigned char fwug;
unsigned short kas;
unsigned short hctma;
unsigned short mntmt;
unsigned short mxtmt;
unsigned int sanicap;
unsigned char rsvd332[180];
unsigned char sqes; unsigned char sqes;
unsigned char cqes; unsigned char cqes;
unsigned char rsvd514[2]; unsigned short maxcmd;
unsigned int nn; unsigned int nn;
unsigned short oncs; unsigned short oncs;
unsigned short fuses; unsigned short fuses;
@ -126,7 +135,15 @@ struct nvme_id_ctrl {
unsigned short acwu; unsigned short acwu;
unsigned char rsvd534[2]; unsigned char rsvd534[2];
unsigned int sgls; unsigned int sgls;
unsigned char rsvd540[1508]; unsigned char rsvd540[228];
char subnqn[256];
unsigned char rsvd1024[768];
unsigned int ioccsz;
unsigned int iorcsz;
unsigned short icdoff;
unsigned char ctrattr;
unsigned char msdbd;
unsigned char rsvd1804[244];
struct nvme_id_power_state psd[32]; struct nvme_id_power_state psd[32];
unsigned char vs[1024]; unsigned char vs[1024];
}; };
@ -187,7 +204,11 @@ struct nvme_smart_log {
unsigned int warning_temp_time; unsigned int warning_temp_time;
unsigned int critical_comp_time; unsigned int critical_comp_time;
unsigned short temp_sensor[8]; unsigned short temp_sensor[8];
unsigned char rsvd216[296]; unsigned int thm_temp1_trans_count;
unsigned int thm_temp2_trans_count;
unsigned int thm_temp1_total_time;
unsigned int thm_temp2_total_time;
unsigned char rsvd232[280];
}; };
enum nvme_admin_opcode { enum nvme_admin_opcode {

View File

@ -3,7 +3,7 @@
* *
* Home page of code is: http://www.smartmontools.org * Home page of code is: http://www.smartmontools.org
* *
* Copyright (C) 2016 Christian Franke * Copyright (C) 2016-17 Christian Franke
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -18,7 +18,7 @@
#include "config.h" #include "config.h"
#include "nvmeprint.h" #include "nvmeprint.h"
const char * nvmeprint_cvsid = "$Id: nvmeprint.cpp 4311 2016-04-27 21:03:01Z chrfranke $" const char * nvmeprint_cvsid = "$Id: nvmeprint.cpp 4580 2017-11-03 19:41:14Z chrfranke $"
NVMEPRINT_H_CVSID; NVMEPRINT_H_CVSID;
#include "int64.h" #include "int64.h"
@ -156,6 +156,11 @@ static void print_drive_info(const nvme_id_ctrl & id_ctrl, const nvme_id_ns & id
lbacap_to_str(buf, id_ns.nuse, fmt_lba_bits)); lbacap_to_str(buf, id_ns.nuse, fmt_lba_bits));
pout("Namespace %u Formatted LBA Size: %s%u\n", nsid, align, (1U << fmt_lba_bits)); pout("Namespace %u Formatted LBA Size: %s%u\n", nsid, align, (1U << fmt_lba_bits));
if (show_all || nonempty(id_ns.eui64, sizeof(id_ns.eui64)))
pout("Namespace %u IEEE EUI-64: %s%02x%02x%02x %02x%02x%02x%02x%02x\n",
nsid, align, id_ns.eui64[0], id_ns.eui64[1], id_ns.eui64[2], id_ns.eui64[3],
id_ns.eui64[4], id_ns.eui64[5], id_ns.eui64[6], id_ns.eui64[7]);
} }
char td[DATEANDEPOCHLEN]; dateandtimezone(td); char td[DATEANDEPOCHLEN]; dateandtimezone(td);
@ -187,16 +192,21 @@ static void print_drive_capabilities(const nvme_id_ctrl & id_ctrl, const nvme_id
((id_ctrl.frmw & 0x10) ? ", no Reset required" : "")); ((id_ctrl.frmw & 0x10) ? ", no Reset required" : ""));
if (show_all || id_ctrl.oacs) if (show_all || id_ctrl.oacs)
pout("Optional Admin Commands (0x%04x): %s%s%s%s%s%s\n", id_ctrl.oacs, pout("Optional Admin Commands (0x%04x): %s%s%s%s%s%s%s%s%s%s%s\n", id_ctrl.oacs,
(!id_ctrl.oacs ? " -" : ""), (!id_ctrl.oacs ? " -" : ""),
((id_ctrl.oacs & 0x0001) ? " Security" : ""), ((id_ctrl.oacs & 0x0001) ? " Security" : ""),
((id_ctrl.oacs & 0x0002) ? " Format" : ""), ((id_ctrl.oacs & 0x0002) ? " Format" : ""),
((id_ctrl.oacs & 0x0004) ? " Frmw_DL" : ""), ((id_ctrl.oacs & 0x0004) ? " Frmw_DL" : ""),
((id_ctrl.oacs & 0x0008) ? " NS_Mngmt" : ""), ((id_ctrl.oacs & 0x0008) ? " NS_Mngmt" : ""),
((id_ctrl.oacs & ~0x000f) ? " *Other*" : "")); ((id_ctrl.oacs & 0x0010) ? " Self_Test" : ""), // NVMe 1.3 ...
((id_ctrl.oacs & 0x0020) ? " Directvs" : ""),
((id_ctrl.oacs & 0x0040) ? " MI_Snd/Rec" : ""),
((id_ctrl.oacs & 0x0080) ? " Vrt_Mngmt" : ""),
((id_ctrl.oacs & 0x0100) ? " Drbl_Bf_Cfg" : ""),
((id_ctrl.oacs & ~0x01ff) ? " *Other*" : ""));
if (show_all || id_ctrl.oncs) if (show_all || id_ctrl.oncs)
pout("Optional NVM Commands (0x%04x): %s%s%s%s%s%s%s%s\n", id_ctrl.oncs, pout("Optional NVM Commands (0x%04x): %s%s%s%s%s%s%s%s%s\n", id_ctrl.oncs,
(!id_ctrl.oncs ? " -" : ""), (!id_ctrl.oncs ? " -" : ""),
((id_ctrl.oncs & 0x0001) ? " Comp" : ""), ((id_ctrl.oncs & 0x0001) ? " Comp" : ""),
((id_ctrl.oncs & 0x0002) ? " Wr_Unc" : ""), ((id_ctrl.oncs & 0x0002) ? " Wr_Unc" : ""),
@ -204,7 +214,8 @@ static void print_drive_capabilities(const nvme_id_ctrl & id_ctrl, const nvme_id
((id_ctrl.oncs & 0x0008) ? " Wr_Zero" : ""), ((id_ctrl.oncs & 0x0008) ? " Wr_Zero" : ""),
((id_ctrl.oncs & 0x0010) ? " Sav/Sel_Feat" : ""), ((id_ctrl.oncs & 0x0010) ? " Sav/Sel_Feat" : ""),
((id_ctrl.oncs & 0x0020) ? " Resv" : ""), ((id_ctrl.oncs & 0x0020) ? " Resv" : ""),
((id_ctrl.oncs & ~0x003f) ? " *Other*" : "")); ((id_ctrl.oncs & 0x0040) ? " Timestmp" : ""), // NVMe 1.3
((id_ctrl.oncs & ~0x007f) ? " *Other*" : ""));
if (id_ctrl.mdts) if (id_ctrl.mdts)
pout("Maximum Data Transfer Size: %u Pages\n", (1U << id_ctrl.mdts)); pout("Maximum Data Transfer Size: %u Pages\n", (1U << id_ctrl.mdts));
@ -220,12 +231,13 @@ static void print_drive_capabilities(const nvme_id_ctrl & id_ctrl, const nvme_id
if (nsid && (show_all || id_ns.nsfeat)) { if (nsid && (show_all || id_ns.nsfeat)) {
const char * align = &(" "[nsid < 10 ? 0 : (nsid < 100 ? 1 : 2)]); const char * align = &(" "[nsid < 10 ? 0 : (nsid < 100 ? 1 : 2)]);
pout("Namespace %u Features (0x%02x): %s%s%s%s%s%s\n", nsid, id_ns.nsfeat, align, pout("Namespace %u Features (0x%02x): %s%s%s%s%s%s%s\n", nsid, id_ns.nsfeat, align,
(!id_ns.nsfeat ? " -" : ""), (!id_ns.nsfeat ? " -" : ""),
((id_ns.nsfeat & 0x01) ? " Thin_Prov" : ""), ((id_ns.nsfeat & 0x01) ? " Thin_Prov" : ""),
((id_ns.nsfeat & 0x02) ? " NA_Fields" : ""), ((id_ns.nsfeat & 0x02) ? " NA_Fields" : ""),
((id_ns.nsfeat & 0x04) ? " Dea/Unw_Error" : ""), ((id_ns.nsfeat & 0x04) ? " Dea/Unw_Error" : ""),
((id_ns.nsfeat & ~0x07) ? " *Other*" : "")); ((id_ns.nsfeat & 0x08) ? " No_ID_Reuse" : ""), // NVMe 1.3
((id_ns.nsfeat & ~0x0f) ? " *Other*" : ""));
} }
// Print Power States // Print Power States
@ -313,6 +325,14 @@ static void print_smart_log(const nvme_smart_log & smart_log, unsigned nsid,
pout("Temperature Sensor %d: %s\n", i + 1, pout("Temperature Sensor %d: %s\n", i + 1,
kelvin_to_str(buf, smart_log.temp_sensor[i])); kelvin_to_str(buf, smart_log.temp_sensor[i]));
} }
if (show_all || smart_log.thm_temp1_trans_count)
pout("Thermal Temp. 1 Transition Count: %d\n", smart_log.thm_temp1_trans_count);
if (show_all || smart_log.thm_temp2_trans_count)
pout("Thermal Temp. 2 Transition Count: %d\n", smart_log.thm_temp2_trans_count);
if (show_all || smart_log.thm_temp1_total_time)
pout("Thermal Temp. 1 Total Time: %d\n", smart_log.thm_temp1_total_time);
if (show_all || smart_log.thm_temp2_total_time)
pout("Thermal Temp. 2 Total Time: %d\n", smart_log.thm_temp2_total_time);
pout("\n"); pout("\n");
} }

View File

@ -34,19 +34,18 @@
#include <IOKit/storage/ata/ATASMARTLib.h> #include <IOKit/storage/ata/ATASMARTLib.h>
#include <CoreFoundation/CoreFoundation.h> #include <CoreFoundation/CoreFoundation.h>
// No, I don't know why there isn't a header for this.
#define kIOATABlockStorageDeviceClass "IOATABlockStorageDevice"
#include "config.h" #include "config.h"
#include "int64.h" #include "int64.h"
#include "atacmds.h" #include "atacmds.h"
#include "scsicmds.h" #include "scsicmds.h"
#include "nvmecmds.h"
#include "utility.h" #include "utility.h"
#include "os_darwin.h" #include "os_darwin.h"
#include "dev_interface.h" #include "dev_interface.h"
#define ARGUSED(x) ((void)(x))
// Needed by '-V' option (CVS versioning) of smartd/smartctl // Needed by '-V' option (CVS versioning) of smartd/smartctl
const char *os_darwin_cpp_cvsid="$Id: os_darwin.cpp 4214 2016-01-24 22:53:37Z samm2 $" \ const char *os_darwin_cpp_cvsid="$Id: os_darwin.cpp 4552 2017-10-11 10:11:35Z samm2 $" \
ATACMDS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_DARWIN_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID; ATACMDS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_DARWIN_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
// examples for smartctl // examples for smartctl
@ -75,10 +74,11 @@ static const char smartctl_examples[] =
static struct { static struct {
io_object_t ioob; io_object_t ioob;
IOCFPlugInInterface **plugin; IOCFPlugInInterface **plugin;
IOATASMARTInterface **smartIf; IOATASMARTInterface **smartIf; // ATA devices
IONVMeSMARTInterface **smartIfNVMe;
} devices[20]; } devices[20];
const char * dev_darwin_cpp_cvsid = "$Id: os_darwin.cpp 4214 2016-01-24 22:53:37Z samm2 $" const char * dev_darwin_cpp_cvsid = "$Id: os_darwin.cpp 4552 2017-10-11 10:11:35Z samm2 $"
DEV_INTERFACE_H_CVSID; DEV_INTERFACE_H_CVSID;
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
@ -109,7 +109,6 @@ protected:
int get_fd() const int get_fd() const
{ return m_fd; } { return m_fd; }
private: private:
int m_fd; ///< filedesc, -1 if not open. int m_fd; ///< filedesc, -1 if not open.
const char * m_mode; ///< Mode string for deviceopen(). const char * m_mode; ///< Mode string for deviceopen().
@ -128,15 +127,24 @@ bool darwin_smart_device::is_open() const
} }
// Determine whether 'dev' is a SMART-capable device. // Determine whether 'dev' is a SMART-capable device.
static bool is_smart_capable (io_object_t dev) { static bool is_smart_capable (io_object_t dev, const char * type) {
CFTypeRef smartCapableKey; CFTypeRef smartCapableKey = NULL;
CFDictionaryRef diskChars; CFDictionaryRef diskChars;
// If the device has kIOPropertySMARTCapableKey, then it's capable, // If the device has kIOPropertySMARTCapableKey, then it's capable,
// no matter what it looks like. // no matter what it looks like.
if (!strcmp("ATA", type)) {
smartCapableKey = IORegistryEntryCreateCFProperty smartCapableKey = IORegistryEntryCreateCFProperty
(dev, CFSTR (kIOPropertySMARTCapableKey), (dev, CFSTR (kIOPropertySMARTCapableKey),
kCFAllocatorDefault, 0); kCFAllocatorDefault, 0);
}
else if (!strcmp("NVME", type)) {
smartCapableKey = IORegistryEntryCreateCFProperty
(dev, CFSTR (kIOPropertyNVMeSMARTCapableKey),
kCFAllocatorDefault, 0);
}
if (smartCapableKey) if (smartCapableKey)
{ {
CFRelease (smartCapableKey); CFRelease (smartCapableKey);
@ -145,6 +153,7 @@ static bool is_smart_capable (io_object_t dev) {
// If it's an kIOATABlockStorageDeviceClass then we're successful // If it's an kIOATABlockStorageDeviceClass then we're successful
// only if its ATA features indicate it supports SMART. // only if its ATA features indicate it supports SMART.
// This will be broken for NVMe, however it is not needed
if (IOObjectConformsTo (dev, kIOATABlockStorageDeviceClass) if (IOObjectConformsTo (dev, kIOATABlockStorageDeviceClass)
&& (diskChars = (CFDictionaryRef)IORegistryEntryCreateCFProperty && (diskChars = (CFDictionaryRef)IORegistryEntryCreateCFProperty
(dev, CFSTR (kIOPropertyDeviceCharacteristicsKey), (dev, CFSTR (kIOPropertyDeviceCharacteristicsKey),
@ -180,7 +189,7 @@ bool darwin_smart_device::open()
const char *pathname = get_dev_name(); const char *pathname = get_dev_name();
char *type = const_cast<char*>(m_mode); char *type = const_cast<char*>(m_mode);
if (strcmp (type, "ATA") != 0) if (!(strcmp("ATA", type) || strcmp("NVME", type)))
{ {
set_err (EINVAL); set_err (EINVAL);
return false; return false;
@ -205,7 +214,7 @@ bool darwin_smart_device::open()
// allow user to just say 'disk0' // allow user to just say 'disk0'
devname = pathname; devname = pathname;
// Find the device. // Find the device. This part should be the same for the NVMe and ATA
if (devname) if (devname)
{ {
CFMutableDictionaryRef matcher; CFMutableDictionaryRef matcher;
@ -216,15 +225,13 @@ bool darwin_smart_device::open()
{ {
disk = IORegistryEntryFromPath (kIOMasterPortDefault, pathname); disk = IORegistryEntryFromPath (kIOMasterPortDefault, pathname);
} }
if (! disk) if (! disk)
{ {
set_err(ENOENT); set_err(ENOENT);
return false; return false;
} }
// Find a SMART-capable driver which is a parent of this device. // Find a SMART-capable driver which is a parent of this device.
while (! is_smart_capable (disk)) while (! is_smart_capable (disk, type))
{ {
IOReturn err; IOReturn err;
io_object_t prevdisk = disk; io_object_t prevdisk = disk;
@ -246,17 +253,35 @@ bool darwin_smart_device::open()
devices[devnum].plugin = NULL; devices[devnum].plugin = NULL;
devices[devnum].smartIf = NULL; devices[devnum].smartIf = NULL;
devices[devnum].smartIfNVMe = NULL;
CFUUIDRef pluginType = NULL;
CFUUIDRef smartInterfaceId = NULL;
void ** SMARTptr = NULL;
if (!strcmp("ATA", type)) {
pluginType = kIOATASMARTUserClientTypeID;
smartInterfaceId = kIOATASMARTInterfaceID;
SMARTptr = (void **)&devices[devnum].smartIf;
}
else if (!strcmp("NVME", type)) {
pluginType = kIONVMeSMARTUserClientTypeID;
smartInterfaceId = kIONVMeSMARTInterfaceID;
SMARTptr = (void **)&devices[devnum].smartIfNVMe;
}
// Create an interface to the ATA SMART library. // Create an interface to the ATA SMART library.
if (IOCreatePlugInInterfaceForService (disk, if (IOCreatePlugInInterfaceForService (disk,
kIOATASMARTUserClientTypeID, pluginType,
kIOCFPlugInInterfaceID, kIOCFPlugInInterfaceID,
&devices[devnum].plugin, &devices[devnum].plugin,
&dummy) == kIOReturnSuccess) &dummy) == kIOReturnSuccess)
(*devices[devnum].plugin)->QueryInterface (*devices[devnum].plugin)->QueryInterface
(devices[devnum].plugin, (devices[devnum].plugin,
CFUUIDGetUUIDBytes ( kIOATASMARTInterfaceID), CFUUIDGetUUIDBytes ( smartInterfaceId),
(void **)&devices[devnum].smartIf); SMARTptr);
else
return set_err(ENOSYS, "IOCreatePlugInInterfaceForService failed");
} }
@ -273,6 +298,8 @@ bool darwin_smart_device::close()
int fd = m_fd; m_fd = -1; int fd = m_fd; m_fd = -1;
if (devices[fd].smartIf) if (devices[fd].smartIf)
(*devices[fd].smartIf)->Release (devices[fd].smartIf); (*devices[fd].smartIf)->Release (devices[fd].smartIf);
if (devices[fd].smartIfNVMe)
(*devices[fd].smartIfNVMe)->Release (devices[fd].smartIfNVMe);
if (devices[fd].plugin) if (devices[fd].plugin)
IODestroyPlugInInterface (devices[fd].plugin); IODestroyPlugInInterface (devices[fd].plugin);
IOObjectRelease (devices[fd].ioob); IOObjectRelease (devices[fd].ioob);
@ -293,9 +320,9 @@ static int make_device_names (char*** devlist, const char* name) {
int result; int result;
int index; int index;
// We treat all devices as ATA so long as they support SMARTLib. if (!(strcmp("ATA", name) || strcmp("NVME", name))) {
if (strcmp (name, "ATA") != 0)
return 0; return 0;
}
err = IOServiceGetMatchingServices err = IOServiceGetMatchingServices
(kIOMasterPortDefault, IOServiceMatching (kIOBlockStorageDeviceClass), &i); (kIOMasterPortDefault, IOServiceMatching (kIOBlockStorageDeviceClass), &i);
@ -305,7 +332,7 @@ static int make_device_names (char*** devlist, const char* name) {
// Count the devices. // Count the devices.
result = 0; result = 0;
while ((device = IOIteratorNext (i)) != MACH_PORT_NULL) { while ((device = IOIteratorNext (i)) != MACH_PORT_NULL) {
if (is_smart_capable (device)) if (is_smart_capable (device, name))
result++; result++;
IOObjectRelease (device); IOObjectRelease (device);
} }
@ -317,7 +344,7 @@ static int make_device_names (char*** devlist, const char* name) {
*devlist = (char**)calloc (result, sizeof (char *)); *devlist = (char**)calloc (result, sizeof (char *));
index = 0; index = 0;
while ((device = IOIteratorNext (i)) != MACH_PORT_NULL) { while ((device = IOIteratorNext (i)) != MACH_PORT_NULL) {
if (is_smart_capable (device)) if (is_smart_capable (device, name))
{ {
io_string_t devName; io_string_t devName;
IORegistryEntryGetPath(device, kIOServicePlane, devName); IORegistryEntryGetPath(device, kIOServicePlane, devName);
@ -504,11 +531,64 @@ protected:
virtual scsi_device * get_scsi_device(const char * name, const char * type); virtual scsi_device * get_scsi_device(const char * name, const char * type);
virtual nvme_device * get_nvme_device(const char * name, const char * type,
unsigned nsid);
virtual smart_device * autodetect_smart_device(const char * name); virtual smart_device * autodetect_smart_device(const char * name);
}; };
/////////////////////////////////////////////////////////////////////////////
/// NVMe support
class darwin_nvme_device
: public /*implements*/ nvme_device,
public /*extends*/ darwin_smart_device
{
public:
darwin_nvme_device(smart_interface * intf, const char * dev_name,
const char * req_type, unsigned nsid);
virtual bool nvme_pass_through(const nvme_cmd_in & in, nvme_cmd_out & out);
};
darwin_nvme_device::darwin_nvme_device(smart_interface * intf, const char * dev_name,
const char * req_type, unsigned nsid)
: smart_device(intf, dev_name, "nvme", req_type),
nvme_device(nsid),
darwin_smart_device("NVME")
{
}
bool darwin_nvme_device::nvme_pass_through(const nvme_cmd_in & in, nvme_cmd_out & out)
{
ARGUSED(out);
int fd = get_fd();
IONVMeSMARTInterface **ifp = devices[fd].smartIfNVMe;
IONVMeSMARTInterface *smartIfNVMe ;
IOReturn err = 0;
unsigned int page = in.cdw10 & 0xff;
if (! ifp)
return -1;
smartIfNVMe = *ifp;
// currently only GetIdentifyData and SMARTReadData are supported
switch (in.opcode) {
case smartmontools::nvme_admin_identify:
err = smartIfNVMe->GetIdentifyData(ifp, (struct nvme_id_ctrl *) in.buffer, in.nsid); // FIXME
break;
case smartmontools::nvme_admin_get_log_page:
if(page == 0x02)
err = smartIfNVMe->SMARTReadData(ifp, (struct nvme_smart_log *) in.buffer);
else /* GetLogPage() is not working yet */
return set_err(ENOSYS, "NVMe admin command:0x%02x/page:0x%02x is not supported",
in.opcode, page);
break;
default:
return set_err(ENOSYS, "NVMe admin command 0x%02x is not supported", in.opcode);
}
return true;
}
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
std::string darwin_smart_interface::get_os_version_str() std::string darwin_smart_interface::get_os_version_str()
@ -537,9 +617,78 @@ scsi_device * darwin_smart_interface::get_scsi_device(const char *, const char *
return 0; // scsi devices are not supported [yet] return 0; // scsi devices are not supported [yet]
} }
nvme_device * darwin_smart_interface::get_nvme_device(const char * name, const char * type,
unsigned nsid)
{
return new darwin_nvme_device(this, name, type, nsid);
}
smart_device * darwin_smart_interface::autodetect_smart_device(const char * name) smart_device * darwin_smart_interface::autodetect_smart_device(const char * name)
{ // TODO - refactor as a function
// Acceptable device names are:
// /dev/disk*
// /dev/rdisk*
// disk*
// IOService:*
// IODeviceTree:*
const char *devname = NULL;
io_object_t disk;
if (strncmp (name, "/dev/rdisk", 10) == 0)
devname = name + 6;
else if (strncmp (name, "/dev/disk", 9) == 0)
devname = name + 5;
else if (strncmp (name, "disk", 4) == 0)
// allow user to just say 'disk0'
devname = name;
// Find the device. This part should be the same for the NVMe and ATA
if (devname) {
CFMutableDictionaryRef matcher;
matcher = IOBSDNameMatching (kIOMasterPortDefault, 0, devname);
disk = IOServiceGetMatchingService (kIOMasterPortDefault, matcher);
}
else {
disk = IORegistryEntryFromPath (kIOMasterPortDefault, name);
}
if (! disk) {
return 0;
}
io_registry_entry_t tmpdisk=disk;
while (! is_smart_capable (tmpdisk, "ATA"))
{ {
IOReturn err;
io_object_t prevdisk = tmpdisk;
// Find this device's parent and try again.
err = IORegistryEntryGetParentEntry (tmpdisk, kIOServicePlane, &tmpdisk);
if (err != kIOReturnSuccess || ! tmpdisk)
{
IOObjectRelease (prevdisk);
break;
}
}
if (tmpdisk)
return new darwin_ata_device(this, name, "");
tmpdisk=disk;
while (! is_smart_capable (tmpdisk, "NVME"))
{
IOReturn err;
io_object_t prevdisk = tmpdisk;
// Find this device's parent and try again.
err = IORegistryEntryGetParentEntry (tmpdisk, kIOServicePlane, &tmpdisk);
if (err != kIOReturnSuccess || ! tmpdisk)
{
IOObjectRelease (prevdisk);
break;
}
}
if (tmpdisk)
return new darwin_nvme_device(this, name, "", 0);
// try ATA as a last option, for compatibility
return new darwin_ata_device(this, name, ""); return new darwin_ata_device(this, name, "");
} }
@ -567,6 +716,20 @@ bool darwin_smart_interface::scan_smart_devices(smart_device_list & devlist,
return false; return false;
} }
} }
char * * nvmenames = 0; int numnvme = 0;
if (
#ifdef WITH_NVME_DEVICESCAN // TODO: Remove when NVMe support is no longer EXPERIMENTAL
!type ||
#else
type &&
#endif
!strcmp(type, "nvme")) {
numnvme = make_device_names(&nvmenames, "NVME");
if (numnvme < 0) {
set_err(ENOMEM);
return false;
}
}
// Add to devlist // Add to devlist
int i; int i;
@ -578,6 +741,14 @@ bool darwin_smart_interface::scan_smart_devices(smart_device_list & devlist,
devlist.push_back(atadev); devlist.push_back(atadev);
} }
free_devnames(atanames, numata); free_devnames(atanames, numata);
for (i = 0; i < numnvme; i++) {
nvme_device * nvmedev = get_nvme_device(nvmenames[i], type, 0); // default nsid
if (nvmedev)
devlist.push_back(nvmedev);
}
free_devnames(nvmenames, numnvme);
return true; return true;
} }

View File

@ -24,7 +24,9 @@
#ifndef OS_DARWIN_H_ #ifndef OS_DARWIN_H_
#define OS_DARWIN_H_ #define OS_DARWIN_H_
#define OS_DARWIN_H_CVSID "$Id: os_darwin.h 4120 2015-08-27 16:12:21Z samm2 $\n" #define OS_DARWIN_H_CVSID "$Id: os_darwin.h 4438 2017-09-20 18:00:42Z samm2 $\n"
#define kIOATABlockStorageDeviceClass "IOATABlockStorageDevice"
// Isn't in 10.3.9? // Isn't in 10.3.9?
@ -32,4 +34,95 @@
#define kIOPropertySMARTCapableKey "SMART Capable" #define kIOPropertySMARTCapableKey "SMART Capable"
#endif #endif
// NVMe definitions, non documented, experimental
#define kIOPropertyNVMeSMARTCapableKey "NVMe SMART Capable"
// Constant to init driver
#define kIONVMeSMARTUserClientTypeID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xAA, 0x0F, 0xA6, 0xF9, 0xC2, 0xD6, 0x45, 0x7F, 0xB1, 0x0B, \
0x59, 0xA1, 0x32, 0x53, 0x29, 0x2F)
// Constant to use plugin interface
#define kIONVMeSMARTInterfaceID CFUUIDGetConstantUUIDWithBytes(NULL, \
0xcc, 0xd1, 0xdb, 0x19, 0xfd, 0x9a, 0x4d, 0xaf, 0xbf, 0x95, \
0x12, 0x45, 0x4b, 0x23, 0xa, 0xb6)
// interface structure, obtained using lldb, could be incomplete or wrong
typedef struct IONVMeSMARTInterface
{
IUNKNOWN_C_GUTS;
UInt16 version;
UInt16 revision;
// NVMe smart data, returns nvme_smart_log structure
IOReturn ( *SMARTReadData )( void * interface,
struct nvme_smart_log * NVMeSMARTData );
// NVMe IdentifyData, returns nvme_id_ctrl per namespace
IOReturn ( *GetIdentifyData )( void * interface,
struct nvme_id_ctrl * NVMeIdentifyControllerStruct,
unsigned int ns );
// Always getting kIOReturnDeviceError
IOReturn ( *GetFieldCounters )( void * interface,
char * FieldCounters );
// Returns 0
IOReturn ( *ScheduleBGRefresh )( void * interface);
// Always returns kIOReturnDeviceError, probably expects pointer to some
// structure as an argument
IOReturn ( *GetLogPage )( void * interface, void * data, unsigned int, unsigned int);
/* GetSystemCounters Looks like a table with an attributes. Sample result:
0x101022200: 0x01 0x00 0x08 0x00 0x00 0x00 0x00 0x00
0x101022208: 0x00 0x00 0x00 0x00 0x02 0x00 0x08 0x00
0x101022210: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x101022218: 0x03 0x00 0x08 0x00 0xf1 0x74 0x26 0x01
0x101022220: 0x00 0x00 0x00 0x00 0x04 0x00 0x08 0x00
0x101022228: 0x0a 0x91 0xb1 0x00 0x00 0x00 0x00 0x00
0x101022230: 0x05 0x00 0x08 0x00 0x24 0x9f 0xfe 0x02
0x101022238: 0x00 0x00 0x00 0x00 0x06 0x00 0x08 0x00
0x101022240: 0x9b 0x42 0x38 0x02 0x00 0x00 0x00 0x00
0x101022248: 0x07 0x00 0x08 0x00 0xdd 0x08 0x00 0x00
0x101022250: 0x00 0x00 0x00 0x00 0x08 0x00 0x08 0x00
0x101022258: 0x07 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x101022260: 0x09 0x00 0x08 0x00 0x00 0x00 0x00 0x00
0x101022268: 0x00 0x00 0x00 0x00 0x0a 0x00 0x04 0x00
.........
0x101022488: 0x74 0x00 0x08 0x00 0x00 0x00 0x00 0x00
0x101022490: 0x00 0x00 0x00 0x00 0x75 0x00 0x40 0x02
0x101022498: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
*/
IOReturn ( *GetSystemCounters )( void * interface, char *, unsigned int *);
/* GetAlgorithmCounters returns mostly 0
0x102004000: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x102004008: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x102004010: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x102004018: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x102004020: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x102004028: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x102004038: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x102004040: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x102004048: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x102004050: 0x00 0x00 0x00 0x00 0x80 0x00 0x00 0x00
0x102004058: 0x80 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x102004060: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x102004068: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x102004070: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x102004078: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x102004080: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x102004088: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x102004090: 0x00 0x01 0x00 0x00 0x00 0x00 0x00 0x00
0x102004098: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
*/
IOReturn ( *GetAlgorithmCounters )( void * interface, char *, unsigned int *);
} IONVMeSMARTInterface;
#endif /* OS_DARWIN_H_ */ #endif /* OS_DARWIN_H_ */

View File

@ -80,7 +80,7 @@
#define PATHINQ_SETTINGS_SIZE 128 #define PATHINQ_SETTINGS_SIZE 128
#endif #endif
const char *os_XXXX_c_cvsid="$Id: os_freebsd.cpp 4257 2016-03-27 23:32:54Z samm2 $" \ const char *os_XXXX_c_cvsid="$Id: os_freebsd.cpp 4425 2017-04-24 16:34:16Z samm2 $" \
ATACMDS_H_CVSID CCISS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_FREEBSD_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID; ATACMDS_H_CVSID CCISS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_FREEBSD_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
#define NO_RETURN 0 #define NO_RETURN 0
@ -322,38 +322,6 @@ bool freebsd_ata_device::ata_pass_through(const ata_cmd_in & in, ata_cmd_out & o
out.out_regs.sector_count_16 = request.u.ata.count; out.out_regs.sector_count_16 = request.u.ata.count;
out.out_regs.lba_48 = request.u.ata.lba; out.out_regs.lba_48 = request.u.ata.lba;
// Command specific processing
if (in.in_regs.command == ATA_SMART_CMD
&& in.in_regs.features == ATA_SMART_STATUS
&& in.out_needed.lba_high)
{
unsigned const char normal_lo=0x4f, normal_hi=0xc2;
unsigned const char failed_lo=0xf4, failed_hi=0x2c;
// Cyl low and Cyl high unchanged means "Good SMART status"
if (!(out.out_regs.lba_mid==normal_lo && out.out_regs.lba_high==normal_hi)
// These values mean "Bad SMART status"
&& !(out.out_regs.lba_mid==failed_lo && out.out_regs.lba_high==failed_hi))
{
// We haven't gotten output that makes sense; print out some debugging info
char buf[512];
snprintf(buf, sizeof(buf),
"CMD=0x%02x\nFR =0x%02x\nNS =0x%02x\nSC =0x%02x\nCL =0x%02x\nCH =0x%02x\nRETURN =0x%04x\n",
(int)request.u.ata.command,
(int)request.u.ata.feature,
(int)request.u.ata.count,
(int)((request.u.ata.lba) & 0xff),
(int)((request.u.ata.lba>>8) & 0xff),
(int)((request.u.ata.lba>>16) & 0xff),
(int)request.error);
printwarning(BAD_SMART,buf);
out.out_regs.lba_high = failed_hi;
out.out_regs.lba_mid = failed_lo;
}
}
return true; return true;
} }
@ -397,15 +365,16 @@ int freebsd_atacam_device::do_cmd( struct ata_ioc_request* request, bool is_48bi
union ccb ccb; union ccb ccb;
int camflags; int camflags;
// FIXME:
// 48bit commands are broken in ATACAM before r242422/HEAD // 48bit commands are broken in ATACAM before r242422/HEAD
// and may cause system hang // and may cause system hang
// Waiting for MFC to make sure that bug is fixed, // First version with working support should be FreeBSD 9.2.0/RELEASE
// later version check needs to be added
#if (FREEBSDVER < 902001)
if(!strcmp("ata",m_camdev->sim_name) && is_48bit_cmd) { if(!strcmp("ata",m_camdev->sim_name) && is_48bit_cmd) {
set_err(ENOSYS, "48-bit ATA commands not implemented for legacy controllers"); set_err(ENOSYS, "48-bit ATA commands not implemented for legacy controllers");
return -1; return -1;
} }
#endif
memset(&ccb, 0, sizeof(ccb)); memset(&ccb, 0, sizeof(ccb));
@ -1936,6 +1905,8 @@ smart_device * freebsd_smart_interface::autodetect_smart_device(const char * nam
int i; int i;
const char * test_name = name; const char * test_name = name;
memset(&ccb, 0, sizeof(ccb));
// if dev_name null, or string length zero // if dev_name null, or string length zero
if (!name || !*name) if (!name || !*name)
return 0; return 0;

View File

@ -3,7 +3,7 @@
* *
* Home page of code is: http://www.smartmontools.org * Home page of code is: http://www.smartmontools.org
* *
* Copyright (C) 2003-8 Eduard Martinescu <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2003-8 Eduard Martinescu
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -82,7 +82,7 @@
#ifndef OS_FREEBSD_H_ #ifndef OS_FREEBSD_H_
#define OS_FREEBSD_H_ #define OS_FREEBSD_H_
#define OS_FREEBSD_H_CVSID "$Id: os_freebsd.h 4120 2015-08-27 16:12:21Z samm2 $" #define OS_FREEBSD_H_CVSID "$Id: os_freebsd.h 4431 2017-08-08 19:38:15Z chrfranke $"
#define MAX_NUM_DEV 26 #define MAX_NUM_DEV 26

View File

@ -3,9 +3,9 @@
* *
* Home page of code is: http://www.smartmontools.org * Home page of code is: http://www.smartmontools.org
* *
* Copyright (C) YEAR YOUR_NAME <smartmontools-support@lists.sourceforge.net> * Copyright (C) YEAR YOUR_NAME
* Copyright (C) 2003-8 Bruce Allen <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2003-8 Bruce Allen
* Copyright (C) 2008 Christian Franke <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2008 Christian Franke
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -30,7 +30,7 @@
To port smartmontools to the OS of your choice, please: To port smartmontools to the OS of your choice, please:
[0] Contact smartmontools-support@lists.sourceforge.net to check [0] Contact smartmontools-support@listi.jpberlin.de to check
that it's not already been done. that it's not already been done.
[1] Make copies of os_generic.h and os_generic.cpp called os_myOS.h [1] Make copies of os_generic.h and os_generic.cpp called os_myOS.h
@ -56,7 +56,7 @@
skeletons below. You can entirely eliminate the function skeletons below. You can entirely eliminate the function
'unsupported()'. 'unsupported()'.
[5] Contact smartmontools-support@lists.sourceforge.net to see [5] Contact smartmontools-support@listi.jpberlin.de to see
about checking your code into the smartmontools CVS archive. about checking your code into the smartmontools CVS archive.
*/ */
@ -83,7 +83,7 @@
// should have one *_H_CVSID macro appearing below for each file // should have one *_H_CVSID macro appearing below for each file
// appearing with #include "*.h" above. Please list these (below) in // appearing with #include "*.h" above. Please list these (below) in
// alphabetic/dictionary order. // alphabetic/dictionary order.
const char * os_XXXX_cpp_cvsid="$Id: os_generic.cpp 4120 2015-08-27 16:12:21Z samm2 $" const char * os_XXXX_cpp_cvsid="$Id: os_generic.cpp 4431 2017-08-08 19:38:15Z chrfranke $"
ATACMDS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_GENERIC_H_CVSID UTILITY_H_CVSID; ATACMDS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_GENERIC_H_CVSID UTILITY_H_CVSID;
// This is here to prevent compiler warnings for unused arguments of // This is here to prevent compiler warnings for unused arguments of

View File

@ -3,8 +3,8 @@
* *
* Home page of code is: http://www.smartmontools.org * Home page of code is: http://www.smartmontools.org
* *
* Copyright (C) YEAR YOUR_NAME <smartmontools-support@lists.sourceforge.net> * Copyright (C) YEAR YOUR_NAME
* Copyright (C) 2003-8 Bruce Allen <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2003-8 Bruce Allen
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -25,7 +25,7 @@
// In the three following lines, change 'GENERIC' to your OS name // In the three following lines, change 'GENERIC' to your OS name
#ifndef OS_GENERIC_H_ #ifndef OS_GENERIC_H_
#define OS_GENERIC_H_ #define OS_GENERIC_H_
#define OS_GENERIC_H_CVSID "$Id: os_generic.h 4120 2015-08-27 16:12:21Z samm2 $\n" #define OS_GENERIC_H_CVSID "$Id: os_generic.h 4431 2017-08-08 19:38:15Z chrfranke $\n"
// Additional material should start here. Note: to keep the '-V' CVS // Additional material should start here. Note: to keep the '-V' CVS
// reporting option working as intended, you should only #include // reporting option working as intended, you should only #include

View File

@ -63,6 +63,7 @@
#include <scsi/scsi.h> #include <scsi/scsi.h>
#include <scsi/scsi_ioctl.h> #include <scsi/scsi_ioctl.h>
#include <scsi/sg.h> #include <scsi/sg.h>
#include <linux/bsg.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
@ -102,7 +103,7 @@
#define ARGUSED(x) ((void)(x)) #define ARGUSED(x) ((void)(x))
const char * os_linux_cpp_cvsid = "$Id: os_linux.cpp 4295 2016-04-15 20:01:32Z chrfranke $" const char * os_linux_cpp_cvsid = "$Id: os_linux.cpp 4582 2017-11-03 20:54:56Z chrfranke $"
OS_LINUX_H_CVSID; OS_LINUX_H_CVSID;
extern unsigned char failuretest_permissive; extern unsigned char failuretest_permissive;
@ -510,28 +511,32 @@ int linux_ata_device::ata_command_interface(smart_command_set command, int selec
#define SCSI_IOCTL_SEND_COMMAND 1 #define SCSI_IOCTL_SEND_COMMAND 1
#endif #endif
#define SG_IO_PRESENT_UNKNOWN 0 #define SG_IO_USE_DETECT 0
#define SG_IO_PRESENT_YES 1 #define SG_IO_UNSUPP 1
#define SG_IO_PRESENT_NO 2 #define SG_IO_USE_V3 3
#define SG_IO_USE_V4 4
static int sg_io_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report, static int sg_io_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report,
int unknown); int sgio_ver);
static int sisc_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report); static int sisc_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report);
static int sg_io_state = SG_IO_PRESENT_UNKNOWN; static int sg_io_state = SG_IO_USE_DETECT;
/* Preferred implementation for issuing SCSI commands in linux. This /* Preferred implementation for issuing SCSI commands in linux. This
* function uses the SG_IO ioctl. Return 0 if command issued successfully * function uses the SG_IO ioctl. Return 0 if command issued successfully
* (various status values should still be checked). If the SCSI command * (various status values should still be checked). If the SCSI command
* cannot be issued then a negative errno value is returned. */ * cannot be issued then a negative errno value is returned. */
static int sg_io_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report, static int sg_io_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report,
int unknown) int sg_io_ver)
{ {
#ifndef SG_IO #ifndef SG_IO
ARGUSED(dev_fd); ARGUSED(iop); ARGUSED(report); ARGUSED(dev_fd); ARGUSED(iop); ARGUSED(report);
return -ENOTTY; return -ENOTTY;
#else #else
struct sg_io_hdr io_hdr;
/* we are filling structures for both versions, but using only one requested */
struct sg_io_hdr io_hdr_v3;
struct sg_io_v4 io_hdr_v4;
if (report > 0) { if (report > 0) {
int k, j; int k, j;
@ -540,6 +545,7 @@ static int sg_io_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report,
char buff[256]; char buff[256];
const int sz = (int)sizeof(buff); const int sz = (int)sizeof(buff);
pout(">>>> do_scsi_cmnd_io: sg_io_ver=%d\n", sg_io_ver);
np = scsi_get_opcode_name(ucp[0]); np = scsi_get_opcode_name(ucp[0]);
j = snprintf(buff, sz, " [%s: ", np ? np : "<unknown opcode>"); j = snprintf(buff, sz, " [%s: ", np ? np : "<unknown opcode>");
for (k = 0; k < (int)iop->cmnd_len; ++k) for (k = 0; k < (int)iop->cmnd_len; ++k)
@ -558,47 +564,111 @@ static int sg_io_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report,
snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n"); snprintf(&buff[j], (sz > j ? (sz - j) : 0), "]\n");
pout("%s", buff); pout("%s", buff);
} }
memset(&io_hdr, 0, sizeof(struct sg_io_hdr)); memset(&io_hdr_v3, 0, sizeof(struct sg_io_hdr));
io_hdr.interface_id = 'S'; memset(&io_hdr_v4, 0, sizeof(struct sg_io_v4));
io_hdr.cmd_len = iop->cmnd_len;
io_hdr.mx_sb_len = iop->max_sense_len; io_hdr_v3.interface_id = 'S';
io_hdr.dxfer_len = iop->dxfer_len; io_hdr_v3.cmd_len = iop->cmnd_len;
io_hdr.dxferp = iop->dxferp; io_hdr_v3.mx_sb_len = iop->max_sense_len;
io_hdr.cmdp = iop->cmnd; io_hdr_v3.dxfer_len = iop->dxfer_len;
io_hdr.sbp = iop->sensep; io_hdr_v3.dxferp = iop->dxferp;
io_hdr_v3.cmdp = iop->cmnd;
io_hdr_v3.sbp = iop->sensep;
/* sg_io_hdr interface timeout has millisecond units. Timeout of 0 /* sg_io_hdr interface timeout has millisecond units. Timeout of 0
defaults to 60 seconds. */ defaults to 60 seconds. */
io_hdr.timeout = ((0 == iop->timeout) ? 60 : iop->timeout) * 1000; io_hdr_v3.timeout = ((0 == iop->timeout) ? 60 : iop->timeout) * 1000;
io_hdr_v4.guard = 'Q';
io_hdr_v4.request_len = iop->cmnd_len;
io_hdr_v4.request = __u64(iop->cmnd);
io_hdr_v4.max_response_len = iop->max_sense_len;
io_hdr_v4.response = __u64(iop->sensep);
io_hdr_v4.timeout = ((0 == iop->timeout) ? 60 : iop->timeout) * 1000; // msec
switch (iop->dxfer_dir) { switch (iop->dxfer_dir) {
case DXFER_NONE: case DXFER_NONE:
io_hdr.dxfer_direction = SG_DXFER_NONE; io_hdr_v3.dxfer_direction = SG_DXFER_NONE;
break; break;
case DXFER_FROM_DEVICE: case DXFER_FROM_DEVICE:
io_hdr.dxfer_direction = SG_DXFER_FROM_DEV; io_hdr_v3.dxfer_direction = SG_DXFER_FROM_DEV;
io_hdr_v4.din_xfer_len = iop->dxfer_len;
io_hdr_v4.din_xferp = __u64(iop->dxferp);
break; break;
case DXFER_TO_DEVICE: case DXFER_TO_DEVICE:
io_hdr.dxfer_direction = SG_DXFER_TO_DEV; io_hdr_v3.dxfer_direction = SG_DXFER_TO_DEV;
io_hdr_v4.dout_xfer_len = iop->dxfer_len;
io_hdr_v4.dout_xferp = __u64(iop->dxferp);
break; break;
default: default:
pout("do_scsi_cmnd_io: bad dxfer_dir\n"); pout("do_scsi_cmnd_io: bad dxfer_dir\n");
return -EINVAL; return -EINVAL;
} }
iop->resp_sense_len = 0; iop->resp_sense_len = 0;
iop->scsi_status = 0; iop->scsi_status = 0;
iop->resid = 0; iop->resid = 0;
if (ioctl(dev_fd, SG_IO, &io_hdr) < 0) {
if (report && (! unknown)) void * io_hdr = NULL;
pout(" SG_IO ioctl failed, errno=%d [%s]\n", errno,
strerror(errno)); switch (sg_io_ver) {
case SG_IO_USE_V3:
io_hdr = &io_hdr_v3;
break;
case SG_IO_USE_V4:
io_hdr = &io_hdr_v4;
break;
default:
// should never be reached
errno = EOPNOTSUPP;
return -errno; return -errno;
} }
iop->resid = io_hdr.resid;
iop->scsi_status = io_hdr.status; if (ioctl(dev_fd, SG_IO, io_hdr) < 0) {
if (report)
pout(" SG_IO ioctl failed, errno=%d [%s], SG_IO_V%d\n", errno,
strerror(errno), sg_io_ver);
return -errno;
}
unsigned int sg_driver_status = 0, sg_transport_status = 0, sg_info = 0,
sg_duration = 0;
if (sg_io_ver == SG_IO_USE_V3) {
iop->resid = io_hdr_v3.resid;
iop->scsi_status = io_hdr_v3.status;
sg_driver_status = io_hdr_v3.driver_status;
sg_transport_status = io_hdr_v3.host_status;
sg_info = io_hdr_v3.info;
iop->resp_sense_len = io_hdr_v3.sb_len_wr;
sg_duration = io_hdr_v3.duration;
}
if (sg_io_ver == SG_IO_USE_V4) {
switch (iop->dxfer_dir) {
case DXFER_NONE:
iop->resid = 0;
break;
case DXFER_FROM_DEVICE:
iop->resid = io_hdr_v4.din_resid;
break;
case DXFER_TO_DEVICE:
iop->resid = io_hdr_v4.dout_resid;
break;
}
iop->scsi_status = io_hdr_v4.device_status;
sg_driver_status = io_hdr_v4.driver_status;
sg_transport_status = io_hdr_v4.transport_status;
sg_info = io_hdr_v4.info;
iop->resp_sense_len = io_hdr_v4.response_len;
sg_duration = io_hdr_v4.duration;
}
if (report > 0) { if (report > 0) {
pout(" scsi_status=0x%x, host_status=0x%x, driver_status=0x%x\n" pout(" scsi_status=0x%x, sg_transport_status=0x%x, sg_driver_status=0x%x\n"
" info=0x%x duration=%d milliseconds resid=%d\n", io_hdr.status, " sg_info=0x%x sg_duration=%d milliseconds resid=%d\n", iop->scsi_status,
io_hdr.host_status, io_hdr.driver_status, io_hdr.info, sg_transport_status, sg_driver_status, sg_info,
io_hdr.duration, io_hdr.resid); sg_duration, iop->resid);
if (report > 1) { if (report > 1) {
if (DXFER_FROM_DEVICE == iop->dxfer_dir) { if (DXFER_FROM_DEVICE == iop->dxfer_dir) {
int trunc, len; int trunc, len;
@ -616,17 +686,17 @@ static int sg_io_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report,
} }
} }
if (io_hdr.info & SG_INFO_CHECK) { /* error or warning */ if (sg_info & SG_INFO_CHECK) { /* error or warning */
int masked_driver_status = (LSCSI_DRIVER_MASK & io_hdr.driver_status); int masked_driver_status = (LSCSI_DRIVER_MASK & sg_driver_status);
if (0 != io_hdr.host_status) { if (0 != sg_transport_status) {
if ((LSCSI_DID_NO_CONNECT == io_hdr.host_status) || if ((LSCSI_DID_NO_CONNECT == sg_transport_status) ||
(LSCSI_DID_BUS_BUSY == io_hdr.host_status) || (LSCSI_DID_BUS_BUSY == sg_transport_status) ||
(LSCSI_DID_TIME_OUT == io_hdr.host_status)) (LSCSI_DID_TIME_OUT == sg_transport_status))
return -ETIMEDOUT; return -ETIMEDOUT;
else else
/* Check for DID_ERROR - workaround for aacraid driver quirk */ /* Check for DID_ERROR - workaround for aacraid driver quirk */
if (LSCSI_DID_ERROR != io_hdr.host_status) { if (LSCSI_DID_ERROR != sg_transport_status) {
return -EIO; /* catch all if not DID_ERR */ return -EIO; /* catch all if not DID_ERR */
} }
} }
@ -638,7 +708,6 @@ static int sg_io_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report,
} }
if (LSCSI_DRIVER_SENSE == masked_driver_status) if (LSCSI_DRIVER_SENSE == masked_driver_status)
iop->scsi_status = SCSI_STATUS_CHECK_CONDITION; iop->scsi_status = SCSI_STATUS_CHECK_CONDITION;
iop->resp_sense_len = io_hdr.sb_len_wr;
if ((SCSI_STATUS_CHECK_CONDITION == iop->scsi_status) && if ((SCSI_STATUS_CHECK_CONDITION == iop->scsi_status) &&
iop->sensep && (iop->resp_sense_len > 0)) { iop->sensep && (iop->resp_sense_len > 0)) {
if (report > 1) { if (report > 1) {
@ -807,22 +876,33 @@ static int do_normal_scsi_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop,
* other than ENODEV (no device) or permission then assume * other than ENODEV (no device) or permission then assume
* SCSI_IOCTL_SEND_COMMAND is the only option. */ * SCSI_IOCTL_SEND_COMMAND is the only option. */
switch (sg_io_state) { switch (sg_io_state) {
case SG_IO_PRESENT_UNKNOWN: case SG_IO_USE_DETECT:
/* ignore report argument */ /* ignore report argument */
if (0 == (res = sg_io_cmnd_io(dev_fd, iop, report, 1))) { /* Try SG_IO V3 first */
sg_io_state = SG_IO_PRESENT_YES; if (0 == (res = sg_io_cmnd_io(dev_fd, iop, report, SG_IO_USE_V3))) {
sg_io_state = SG_IO_USE_V3;
return 0; return 0;
} else if ((-ENODEV == res) || (-EACCES == res) || (-EPERM == res)) } else if ((-ENODEV == res) || (-EACCES == res) || (-EPERM == res))
return res; /* wait until we see a device */ return res; /* wait until we see a device */
sg_io_state = SG_IO_PRESENT_NO; /* See if we can use SG_IO V4 * */
/* drop through by design */ if (0 == (res = sg_io_cmnd_io(dev_fd, iop, report, SG_IO_USE_V4))) {
case SG_IO_PRESENT_NO: sg_io_state = SG_IO_USE_V4;
return 0;
} else if ((-ENODEV == res) || (-EACCES == res) || (-EPERM == res))
return res; /* wait until we see a device */
/* fallback to the SCSI_IOCTL_SEND_COMMAND */
sg_io_state = SG_IO_UNSUPP;
/* FALLTHRU */
case SG_IO_UNSUPP:
/* depricated SCSI_IOCTL_SEND_COMMAND ioctl */
return sisc_cmnd_io(dev_fd, iop, report); return sisc_cmnd_io(dev_fd, iop, report);
case SG_IO_PRESENT_YES: case SG_IO_USE_V3:
return sg_io_cmnd_io(dev_fd, iop, report, 0); case SG_IO_USE_V4:
/* use SG_IO V3 or V4 ioctl, depending on availabiliy */
return sg_io_cmnd_io(dev_fd, iop, report, sg_io_state);
default: default:
pout(">>>> do_scsi_cmnd_io: bad sg_io_state=%d\n", sg_io_state); pout(">>>> do_scsi_cmnd_io: bad sg_io_state=%d\n", sg_io_state);
sg_io_state = SG_IO_PRESENT_UNKNOWN; sg_io_state = SG_IO_USE_DETECT;
return -EIO; /* report error and reset state */ return -EIO; /* report error and reset state */
} }
} }
@ -3091,6 +3171,50 @@ static unsigned get_kernel_release()
return x * 100000 + y * 1000 + z; return x * 100000 + y * 1000 + z;
} }
// Check for SCSI host proc_name "hpsa"
static bool is_hpsa(const char * name)
{
char path[128];
snprintf(path, sizeof(path), "/sys/block/%s/device", name);
char * syshostpath = canonicalize_file_name(path);
if (!syshostpath)
return false;
char * syshost = strrchr(syshostpath, '/');
if (!syshost) {
free(syshostpath);
return false;
}
char * hostsep = strchr(++syshost, ':');
if (hostsep)
*hostsep = 0;
snprintf(path, sizeof(path), "/sys/class/scsi_host/host%s/proc_name", syshost);
free(syshostpath);
int fd = open(path, O_RDONLY);
if (fd < 0)
return false;
char proc_name[32];
ssize_t n = read(fd, proc_name, sizeof(proc_name) - 1);
close(fd);
if (n < 4)
return false;
proc_name[n] = 0;
if (proc_name[n - 1] == '\n')
proc_name[n - 1] = 0;
if (scsi_debugmode > 1)
pout("%s -> %s: \"%s\"\n", name, path, proc_name);
if (strcmp(proc_name, "hpsa"))
return false;
return true;
}
// Guess device type (ata or scsi) based on device name (Linux // Guess device type (ata or scsi) based on device name (Linux
// specific) SCSI device name in linux can be sd, sr, scd, st, nst, // specific) SCSI device name in linux can be sd, sr, scd, st, nst,
// osst, nosst and sg. // osst, nosst and sg.
@ -3143,7 +3267,11 @@ smart_device * linux_smart_interface::autodetect_smart_device(const char * name)
return get_sat_device(usbtype, new linux_scsi_device(this, name, "")); return get_sat_device(usbtype, new linux_scsi_device(this, name, ""));
} }
// No USB bridge found, assume regular SCSI device // Fail if hpsa driver
if (is_hpsa(test_name))
return missing_option("-d cciss,N");
// No USB bridge or hpsa driver found, assume regular SCSI device
return new linux_scsi_device(this, name, ""); return new linux_scsi_device(this, name, "");
} }
@ -3151,6 +3279,10 @@ smart_device * linux_smart_interface::autodetect_smart_device(const char * name)
if (str_starts_with(test_name, "scsi/")) if (str_starts_with(test_name, "scsi/"))
return new linux_scsi_device(this, name, ""); return new linux_scsi_device(this, name, "");
// form /dev/bsg/* or bsg/*
if (str_starts_with(test_name, "bsg/"))
return new linux_scsi_device(this, name, "");
// form /dev/ns* or ns* // form /dev/ns* or ns*
if (str_starts_with(test_name, "ns")) if (str_starts_with(test_name, "ns"))
return new linux_scsi_device(this, name, ""); return new linux_scsi_device(this, name, "");

View File

@ -3,7 +3,7 @@
* *
* Home page of code is: http://www.smartmontools.org * Home page of code is: http://www.smartmontools.org
* *
* Copyright (C) 2003-8 Bruce Allen <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2003-8 Bruce Allen
* *
* Derived from code that was * Derived from code that was
* *
@ -38,7 +38,7 @@
#ifndef OS_LINUX_H_ #ifndef OS_LINUX_H_
#define OS_LINUX_H_ #define OS_LINUX_H_
#define OS_LINUX_H_CVSID "$Id: os_linux.h 4120 2015-08-27 16:12:21Z samm2 $\n" #define OS_LINUX_H_CVSID "$Id: os_linux.h 4431 2017-08-08 19:38:15Z chrfranke $\n"
/* /*
The following definitions/macros/prototypes are used for three The following definitions/macros/prototypes are used for three

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,7 @@
* *
* Home page of code is: http://www.smartmontools.org * Home page of code is: http://www.smartmontools.org
* *
* Copyright (C) 2003-8 Sergey Svishchev <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2003-8 Sergey Svishchev
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -24,7 +24,7 @@
#ifndef OS_NETBSD_H_ #ifndef OS_NETBSD_H_
#define OS_NETBSD_H_ #define OS_NETBSD_H_
#define OS_NETBSD_H_CVSID "$Id: os_netbsd.h 4120 2015-08-27 16:12:21Z samm2 $\n" #define OS_NETBSD_H_CVSID "$Id: os_netbsd.h 4431 2017-08-08 19:38:15Z chrfranke $\n"
#include <sys/device.h> #include <sys/device.h>
#include <sys/param.h> #include <sys/param.h>

View File

@ -3,9 +3,9 @@
* *
* Home page of code is: http://www.smartmontools.org * Home page of code is: http://www.smartmontools.org
* *
* Copyright (C) 2004-10 David Snyder <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2004-10 David Snyder
* *
* Derived from os_netbsd.cpp by Sergey Svishchev <smartmontools-support@lists.sourceforge.net>, Copyright (C) 2003-8 * Derived from os_netbsd.cpp by Sergey Svishchev, Copyright (C) 2003-8
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -27,7 +27,7 @@
#include <errno.h> #include <errno.h>
const char * os_openbsd_cpp_cvsid = "$Id: os_openbsd.cpp 4321 2016-05-10 13:43:10Z chrfranke $" const char * os_openbsd_cpp_cvsid = "$Id: os_openbsd.cpp 4431 2017-08-08 19:38:15Z chrfranke $"
OS_OPENBSD_H_CVSID; OS_OPENBSD_H_CVSID;
enum warnings { enum warnings {

View File

@ -3,9 +3,9 @@
* *
* Home page of code is: http://www.smartmontools.org * Home page of code is: http://www.smartmontools.org
* *
* Copyright (C) 2004-8 David Snyder <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2004-8 David Snyder
* *
* Derived from os_netbsd.c by Sergey Svishchev <smartmontools-support@lists.sourceforge.net>, Copyright (C) 2003-8 * Derived from os_netbsd.c by Sergey Svishchev, Copyright (C) 2003-8
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -26,7 +26,7 @@
#ifndef OS_OPENBSD_H_ #ifndef OS_OPENBSD_H_
#define OS_OPENBSD_H_ #define OS_OPENBSD_H_
#define OS_OPENBSD_H_CVSID "$Id: os_openbsd.h 4120 2015-08-27 16:12:21Z samm2 $\n" #define OS_OPENBSD_H_CVSID "$Id: os_openbsd.h 4431 2017-08-08 19:38:15Z chrfranke $\n"
/* from NetBSD: atareg.h,v 1.17, by Manuel Bouyer */ /* from NetBSD: atareg.h,v 1.17, by Manuel Bouyer */
/* Actually fits _perfectly_ into OBSDs wdcreg.h, but... */ /* Actually fits _perfectly_ into OBSDs wdcreg.h, but... */

View File

@ -3,7 +3,7 @@
* *
* Home page of code is: http://www.smartmontools.org * Home page of code is: http://www.smartmontools.org
* *
* Copyright (C) 2004-8 Yuri Dario <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2004-8 Yuri Dario
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -22,6 +22,10 @@
*/ */
// These are needed to define prototypes for the functions defined below // These are needed to define prototypes for the functions defined below
#include "config.h"
#include "int64.h"
#include <ctype.h>
#include <errno.h> #include <errno.h>
#include "atacmds.h" #include "atacmds.h"
#include "scsicmds.h" #include "scsicmds.h"
@ -31,61 +35,12 @@
#include "os_os2.h" #include "os_os2.h"
// Needed by '-V' option (CVS versioning) of smartd/smartctl // Needed by '-V' option (CVS versioning) of smartd/smartctl
const char *os_XXXX_c_cvsid="$Id: os_os2.cpp 4120 2015-08-27 16:12:21Z samm2 $" \ const char *os_XXXX_c_cvsid="$Id: os_os2.cpp 4431 2017-08-08 19:38:15Z chrfranke $" \
ATACMDS_H_CVSID OS_XXXX_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID; ATACMDS_H_CVSID OS_XXXX_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
// global handle to device driver // global handle to device driver
static HFILE hDevice; static HFILE hDevice;
// Please eliminate the following block: both the two #includes and
// the 'unsupported()' function. They are only here to warn
// unsuspecting users that their Operating System is not supported! If
// you wish, you can use a similar warning mechanism for any of the
// functions in this file that you can not (or choose not to)
// implement.
#include "config.h"
typedef struct _IDEREGS {
UCHAR bFeaturesReg;
UCHAR bSectorCountReg;
UCHAR bSectorNumberReg;
UCHAR bCylLowReg;
UCHAR bCylHighReg;
UCHAR bDriveHeadReg;
UCHAR bCommandReg;
UCHAR bReserved;
} IDEREGS, *PIDEREGS, *LPIDEREGS;
static void unsupported(int which){
static int warninggiven[4];
if (which<0 || which>3)
return;
if (!warninggiven[which]) {
char msg;
warninggiven[which]=1;
switch (which) {
case 0:
msg="generate a list of devices";
break;
case 1:
msg="interface to Marvell-based SATA controllers";
break;
case 2:
msg="interface to 3ware-based RAID controllers";
break;
case 3:
msg="interface to SCSI devices";
break;
}
pout("Under OS/2, smartmontools can not %s\n");
}
return;
}
// print examples for smartctl. You should modify this function so // print examples for smartctl. You should modify this function so
// that the device paths are sensible for your OS, and to eliminate // that the device paths are sensible for your OS, and to eliminate
// unsupported commands (eg, 3ware controllers). // unsupported commands (eg, 3ware controllers).
@ -93,24 +48,21 @@ void print_smartctl_examples(){
printf("=================================================== SMARTCTL EXAMPLES =====\n\n"); printf("=================================================== SMARTCTL EXAMPLES =====\n\n");
#ifdef HAVE_GETOPT_LONG #ifdef HAVE_GETOPT_LONG
printf( printf(
" smartctl -a /dev/hda (Prints all SMART information)\n\n" " smartctl -a hd0 (Prints all SMART information)\n\n"
" smartctl --smart=on --offlineauto=on --saveauto=on /dev/hda\n" " smartctl --smart=on --offlineauto=on --saveauto=on hd0\n"
" (Enables SMART on first disk)\n\n" " (Enables SMART on first disk)\n\n"
" smartctl -t long /dev/hda (Executes extended disk self-test)\n\n" " smartctl -t long hd0 (Executes extended disk self-test)\n\n"
" smartctl --attributes --log=selftest --quietmode=errorsonly /dev/hda\n" " smartctl --attributes --log=selftest --quietmode=errorsonly hd0\n"
" (Prints Self-Test & Attribute errors)\n" " (Prints Self-Test & Attribute errors)\n"
" smartctl -a --device=3ware,2 /dev/sda\n"
" (Prints all SMART info for 3rd ATA disk on 3ware RAID controller)\n"
); );
#else #else
printf( printf(
" smartctl -a /dev/hda (Prints all SMART information)\n" " smartctl -a hd0 (Prints all SMART on first disk with DANIS506)\n"
" smartctl -s on -o on -S on /dev/hda (Enables SMART on first disk)\n" " smartctl -a ahci0 (Prints all SMART on first disk with OS2AHCI)\n"
" smartctl -t long /dev/hda (Executes extended disk self-test)\n" " smartctl -s on -o on -S on hd0 (Enables SMART on first disk)\n"
" smartctl -A -l selftest -q errorsonly /dev/hda\n" " smartctl -t long hd0 (Executes extended disk self-test)\n"
" smartctl -A -l selftest -q errorsonly hd0\n"
" (Prints Self-Test & Attribute errors)\n" " (Prints Self-Test & Attribute errors)\n"
" smartctl -a -d 3ware,2 /dev/sda\n"
" (Prints all SMART info for 3rd ATA disk on 3ware RAID controller)\n"
); );
#endif #endif
return; return;
@ -127,10 +79,8 @@ int guess_device_type (const char* dev_name) {
//printf( "dev_name %s\n", dev_name); //printf( "dev_name %s\n", dev_name);
dev_name = skipdev(dev_name); dev_name = skipdev(dev_name);
if (!strncmp(dev_name, "hd", 2)) if (!strncmp(dev_name, "hd", 2) || !strncmp(dev_name, "ahci", 4))
return CONTROLLER_ATA; return CONTROLLER_ATA;
if (!strncmp(dev_name, "scsi", 4))
return CONTROLLER_SCSI;
return CONTROLLER_UNKNOWN; return CONTROLLER_UNKNOWN;
} }
@ -140,9 +90,111 @@ int guess_device_type (const char* dev_name) {
// other N arrays each contain null-terminated character strings. In // other N arrays each contain null-terminated character strings. In
// the case N==0, no arrays are allocated because the array of 0 // the case N==0, no arrays are allocated because the array of 0
// pointers has zero length, equivalent to calling malloc(0). // pointers has zero length, equivalent to calling malloc(0).
int make_device_names (char*** devlist, const char* name) { int make_device_names (char*** devlist, const char* name) {
unsupported(0);
int result;
int index;
const int max_dev = 32; // scan only first 32 devices
// SCSI is not supported
if (strcmp (name, "ATA") != 0)
return 0; return 0;
// try to open DANIS
APIRET rc;
ULONG ActionTaken;
HFILE danisDev, ahciDev;
bool is_danis = 0, is_ahci = 0;
rc = DosOpen ((const char unsigned *)danisdev, &danisDev, &ActionTaken, 0, FILE_SYSTEM,
OPEN_ACTION_OPEN_IF_EXISTS, OPEN_SHARE_DENYNONE |
OPEN_FLAGS_NOINHERIT | OPEN_ACCESS_READONLY, NULL);
if (!rc)
is_danis = 1;
rc = DosOpen ((const char unsigned *)ahcidev, &ahciDev, &ActionTaken, 0, FILE_SYSTEM,
OPEN_ACTION_OPEN_IF_EXISTS, OPEN_SHARE_DENYNONE |
OPEN_FLAGS_NOINHERIT | OPEN_ACCESS_READONLY, NULL);
if (!rc)
is_ahci = 1;
// Count the devices.
result = 0;
DSKSP_CommandParameters Parms;
ULONG PLen = 1;
ULONG IDLen = 512;
struct ata_identify_device Id;
for(int i = 0; i < max_dev; i++) {
if (is_ahci) {
Parms.byPhysicalUnit = i;
rc = DosDevIOCtl (ahciDev, DSKSP_CAT_GENERIC, DSKSP_GET_INQUIRY_DATA,
(PVOID)&Parms, PLen, &PLen, (PVOID)&Id, IDLen, &IDLen);
if (!rc) result++;
}
if (is_danis) {
Parms.byPhysicalUnit = i + 0x80;
rc = DosDevIOCtl (danisDev, DSKSP_CAT_GENERIC, DSKSP_GET_INQUIRY_DATA,
(PVOID)&Parms, PLen, &PLen, (PVOID)&Id, IDLen, &IDLen);
if (!rc) result++;
}
}
*devlist = (char**)calloc (result, sizeof (char *));
if (! *devlist)
goto error;
index = 0;
// add devices
for(int i = 0; i < max_dev; i++) {
if (is_ahci) {
Parms.byPhysicalUnit = i;
rc = DosDevIOCtl (ahciDev, DSKSP_CAT_GENERIC, DSKSP_GET_INQUIRY_DATA,
(PVOID)&Parms, PLen, &PLen, (PVOID)&Id, IDLen, &IDLen);
if (!rc) {
asprintf(&(*devlist)[index], "ahci%d", i);
if (! (*devlist)[index])
goto error;
index++;
}
}
if (is_danis) {
Parms.byPhysicalUnit = i + 0x80;
rc = DosDevIOCtl (danisDev, DSKSP_CAT_GENERIC, DSKSP_GET_INQUIRY_DATA,
(PVOID)&Parms, PLen, &PLen, (PVOID)&Id, IDLen, &IDLen);
if (!rc) {
asprintf(&(*devlist)[index], "hd%d", i);
if (! (*devlist)[index])
goto error;
index++;
}
}
}
if (is_danis)
DosClose( danisDev);
if (is_ahci)
DosClose( ahciDev);
return result;
error:
if (*devlist)
{
for (index = 0; index < result; index++)
if ((*devlist)[index])
free ((*devlist)[index]);
free (*devlist);
}
if (is_danis)
DosClose( danisDev);
if (is_ahci)
DosClose( ahciDev);
return -1;
} }
// Like open(). Return non-negative integer handle, only used by the // Like open(). Return non-negative integer handle, only used by the
@ -151,33 +203,50 @@ int make_device_names (char*** devlist, const char* name) {
// array within this file (see os_freebsd.cpp for an example). If you // array within this file (see os_freebsd.cpp for an example). If you
// can not open the device (permission denied, does not exist, etc) // can not open the device (permission denied, does not exist, etc)
// set errno as open() does and return <0. // set errno as open() does and return <0.
int deviceopen(const char *pathname, char *type){ int deviceopen(const char *pathname, char * /* type */ ){
int fd; int fd = 0;
APIRET rc; APIRET rc;
ULONG ActionTaken; ULONG ActionTaken;
char * activedev = NULL;
pathname = skipdev(pathname);
// DANIS506 driver
if(strlen(pathname) > strlen(danispref)
&& strncmp(pathname, danispref, strlen(danispref)) == 0) {
fd = strtol(pathname + strlen(danispref), NULL, 10) + 0x80;
activedev = (char *)danisdev;
}
// OS2AHCI driver
if(strlen(pathname) > strlen(ahcipref)
&& strncmp(pathname, ahcipref, strlen(ahcipref)) == 0) {
fd = strtol(pathname + strlen(ahcipref), NULL, 10);
activedev = (char *)ahcidev;
}
if(!activedev) {
pout("Error: please specify hdX or ahciX device name\n");
return -1;
}
//printf( "deviceopen pathname %s\n", pathname); //printf( "deviceopen pathname %s\n", pathname);
rc = DosOpen ("\\DEV\\IBMS506$", &hDevice, &ActionTaken, 0, FILE_SYSTEM, rc = DosOpen ((const char unsigned *)activedev, &hDevice, &ActionTaken, 0, FILE_SYSTEM,
OPEN_ACTION_OPEN_IF_EXISTS, OPEN_SHARE_DENYNONE | OPEN_ACTION_OPEN_IF_EXISTS, OPEN_SHARE_DENYNONE |
OPEN_FLAGS_NOINHERIT | OPEN_ACCESS_READONLY, NULL); OPEN_FLAGS_NOINHERIT | OPEN_ACCESS_READONLY, NULL);
if (rc) { if (rc) {
char errmsg[256]; char errmsg[256];
snprintf(errmsg,256,"Smartctl open driver IBMS506$ failed (%d)", rc); snprintf(errmsg,256,"Smartctl open driver %s failed (%lu)", activedev, rc);
errmsg[255]='\0'; errmsg[255]='\0';
syserror(errmsg); syserror(errmsg);
return -1; return -1;
} }
pathname = skipdev(pathname);
fd = tolower(pathname[2]) - 'a';
return fd; return fd;
} }
// Like close(). Acts only on integer handles returned by // Like close(). Acts only on integer handles returned by
// deviceopen() above. // deviceopen() above.
int deviceclose(int fd){ int deviceclose(int /* fd */){
DosClose( hDevice); DosClose( hDevice);
hDevice = NULL; hDevice = NULL;
@ -185,43 +254,34 @@ int deviceclose(int fd){
return 0; return 0;
} }
static void print_ide_regs(const IDEREGS * r, int out)
{
pout("%s=0x%02x,%s=0x%02x, SC=0x%02x, NS=0x%02x, CL=0x%02x, CH=0x%02x, SEL=0x%02x\n",
(out?"STS":"CMD"), r->bCommandReg, (out?"ERR":" FR"), r->bFeaturesReg,
r->bSectorCountReg, r->bSectorNumberReg, r->bCylLowReg, r->bCylHighReg, r->bDriveHeadReg);
}
// //
// OS/2 direct ioctl interface to IBMS506$ // OS/2 direct ioctl interface to IBMS506$/OS2AHCI$
// //
int dani_ioctl( int device, int request, void* arg) static int dani_ioctl( int device, void* arg)
{ {
unsigned char* buff = (unsigned char*) arg; unsigned char* buff = (unsigned char*) arg;
APIRET rc; APIRET rc;
DSKSP_CommandParameters Parms; DSKSP_CommandParameters Parms;
ULONG PLen = 1; ULONG PLen = 1;
ULONG DLen = 512; //sizeof (*buf); ULONG DLen = 512; //sizeof (*buf);
UCHAR temp;
ULONG value = 0; ULONG value = 0;
IDEREGS regs;
// printf( "device %d, request 0x%x, arg[0] 0x%x, arg[2] 0x%x\n", device, request, buff[0], buff[2]); // printf( "device %d, request 0x%x, arg[0] 0x%x, arg[2] 0x%x\n", device, request, buff[0], buff[2]);
Parms.byPhysicalUnit = device; Parms.byPhysicalUnit = device;
switch( buff[0]) { switch( buff[0]) {
case WIN_IDENTIFY: case ATA_IDENTIFY_DEVICE:
rc = DosDevIOCtl (hDevice, DSKSP_CAT_GENERIC, DSKSP_GET_INQUIRY_DATA, rc = DosDevIOCtl (hDevice, DSKSP_CAT_GENERIC, DSKSP_GET_INQUIRY_DATA,
(PVOID)&Parms, PLen, &PLen, (PVOID)arg+4, DLen, &DLen); (PVOID)&Parms, PLen, &PLen, (UCHAR *)arg+4, DLen, &DLen);
if (rc != 0) if (rc != 0)
{ {
printf ("DANIS506 ATA GET HD Failed (%d,0x%x)\n", rc, rc); printf ("DANIS506 ATA DSKSP_GET_INQUIRY_DATA failed (%lu)\n", rc);
return -1; return -1;
} }
break; break;
case WIN_SMART: case ATA_SMART_CMD:
switch( buff[2]) { switch( buff[2]) {
case SMART_STATUS: case ATA_SMART_STATUS:
DLen = sizeof(value); DLen = sizeof(value);
// OS/2 already checks CL/CH in IBM1S506 code!! see s506rte.c (ddk) // OS/2 already checks CL/CH in IBM1S506 code!! see s506rte.c (ddk)
// value: -1=not supported, 0=ok, 1=failing // value: -1=not supported, 0=ok, 1=failing
@ -229,94 +289,94 @@ int dani_ioctl( int device, int request, void* arg)
(PVOID)&Parms, PLen, &PLen, (PVOID)&value, DLen, &DLen); (PVOID)&Parms, PLen, &PLen, (PVOID)&value, DLen, &DLen);
if (rc) if (rc)
{ {
printf ("DANIS506 ATA GET SMART_STATUS failed (%d,0x%x)\n", rc, rc); printf ("DANIS506 ATA GET SMART_STATUS failed (%lu)\n", rc);
return -1; return -1;
} }
buff[4] = (unsigned char)value; buff[4] = (unsigned char)value;
break; break;
case SMART_READ_VALUES: case ATA_SMART_READ_VALUES:
rc = DosDevIOCtl (hDevice, DSKSP_CAT_SMART, DSKSP_SMART_GET_ATTRIBUTES, rc = DosDevIOCtl (hDevice, DSKSP_CAT_SMART, DSKSP_SMART_GET_ATTRIBUTES,
(PVOID)&Parms, PLen, &PLen, (PVOID)arg+4, DLen, &DLen); (PVOID)&Parms, PLen, &PLen, (UCHAR *)arg+4, DLen, &DLen);
if (rc) if (rc)
{ {
printf ("DANIS506 ATA GET DSKSP_SMART_GET_ATTRIBUTES failed (%d,0x%x)\n", rc, rc); printf ("DANIS506 ATA GET DSKSP_SMART_GET_ATTRIBUTES failed (%lu)\n", rc);
return -1; return -1;
} }
break; break;
case SMART_READ_THRESHOLDS: case ATA_SMART_READ_THRESHOLDS:
rc = DosDevIOCtl (hDevice, DSKSP_CAT_SMART, DSKSP_SMART_GET_THRESHOLDS, rc = DosDevIOCtl (hDevice, DSKSP_CAT_SMART, DSKSP_SMART_GET_THRESHOLDS,
(PVOID)&Parms, PLen, &PLen, (PVOID)arg+4, DLen, &DLen); (PVOID)&Parms, PLen, &PLen, (UCHAR *)arg+4, DLen, &DLen);
if (rc) if (rc)
{ {
printf ("DANIS506 ATA GET DSKSP_SMART_GET_THRESHOLDS failed (%d,0x%x)\n", rc, rc); printf ("DANIS506 ATA GET DSKSP_SMART_GET_THRESHOLDS failed (%lu)\n", rc);
return -1; return -1;
} }
break; break;
case SMART_READ_LOG_SECTOR: case ATA_SMART_READ_LOG_SECTOR:
buff[4] = buff[1]; // copy select field buff[4] = buff[1]; // copy select field
rc = DosDevIOCtl (hDevice, DSKSP_CAT_SMART, DSKSP_SMART_READ_LOG, rc = DosDevIOCtl (hDevice, DSKSP_CAT_SMART, DSKSP_SMART_GET_LOG,
(PVOID)&Parms, PLen, &PLen, (PVOID)arg+4, DLen, &DLen); (PVOID)&Parms, PLen, &PLen, (UCHAR *)arg+4, DLen, &DLen);
if (rc) if (rc)
{ {
printf ("DANIS506 ATA GET DSKSP_SMART_READ_LOG failed (%d,0x%x)\n", rc, rc); printf ("DANIS506 ATA GET DSKSP_SMART_GET_LOG failed (%lu)\n", rc);
return -1; return -1;
} }
break; break;
case SMART_ENABLE: case ATA_SMART_ENABLE:
buff[0] = 1; // enable buff[0] = 1; // enable
DLen = 1; DLen = 1;
rc = DosDevIOCtl (hDevice, DSKSP_CAT_SMART, DSKSP_SMART_ONOFF, rc = DosDevIOCtl (hDevice, DSKSP_CAT_SMART, DSKSP_SMART_ONOFF,
(PVOID)&Parms, PLen, &PLen, (PVOID)buff, DLen, &DLen); (PVOID)&Parms, PLen, &PLen, (PVOID)buff, DLen, &DLen);
if (rc) { if (rc) {
printf ("DANIS506 ATA GET DSKSP_SMART_ONOFF failed (%d,0x%x)\n", rc, rc); printf ("DANIS506 ATA GET DSKSP_SMART_ONOFF failed (%lu)\n", rc);
return -1; return -1;
} }
break; break;
case SMART_DISABLE: case ATA_SMART_DISABLE:
buff[0] = 0; // disable buff[0] = 0; // disable
DLen = 1; DLen = 1;
rc = DosDevIOCtl (hDevice, DSKSP_CAT_SMART, DSKSP_SMART_ONOFF, rc = DosDevIOCtl (hDevice, DSKSP_CAT_SMART, DSKSP_SMART_ONOFF,
(PVOID)&Parms, PLen, &PLen, (PVOID)buff, DLen, &DLen); (PVOID)&Parms, PLen, &PLen, (PVOID)buff, DLen, &DLen);
if (rc) { if (rc) {
printf ("DANIS506 ATA GET DSKSP_SMART_ONOFF failed (%d,0x%x)\n", rc, rc); printf ("DANIS506 ATA GET DSKSP_SMART_ONOFF failed (%lu)\n", rc);
return -1; return -1;
} }
break; break;
#if 0 #if 0
case SMART_AUTO_OFFLINE: case ATA_SMART_AUTO_OFFLINE:
buff[0] = buff[3]; // select field buff[0] = buff[3]; // select field
DLen = 1; DLen = 1;
rc = DosDevIOCtl (hDevice, DSKSP_CAT_SMART, DSKSP_SMART_AUTO_OFFLINE, rc = DosDevIOCtl (hDevice, DSKSP_CAT_SMART, DSKSP_SMART_AUTO_OFFLINE,
(PVOID)&Parms, PLen, &PLen, (PVOID)buff, DLen, &DLen); (PVOID)&Parms, PLen, &PLen, (PVOID)buff, DLen, &DLen);
if (rc) { if (rc) {
printf ("DANIS506 ATA GET DSKSP_SMART_ONOFF failed (%d,0x%x)\n", rc, rc); printf ("DANIS506 ATA GET DSKSP_SMART_ONOFF failed (%lu)\n", rc);
return -1; return -1;
} }
break; break;
#endif #endif
case SMART_AUTOSAVE: case ATA_SMART_AUTOSAVE:
buff[0] = buff[3]; // select field buff[0] = buff[3]; // select field
DLen = 1; DLen = 1;
rc = DosDevIOCtl (hDevice, DSKSP_CAT_SMART, DSKSP_SMART_AUTOSAVE_ONOFF, rc = DosDevIOCtl (hDevice, DSKSP_CAT_SMART, DSKSP_SMART_AUTOSAVE_ONOFF,
(PVOID)&Parms, PLen, &PLen, (PVOID)buff, DLen, &DLen); (PVOID)&Parms, PLen, &PLen, (PVOID)buff, DLen, &DLen);
if (rc) { if (rc) {
printf ("DANIS506 ATA DSKSP_SMART_AUTOSAVE_ONOFF failed (%d,0x%x)\n", rc, rc); printf ("DANIS506 ATA DSKSP_SMART_AUTOSAVE_ONOFF failed (%lu)\n", rc);
return -1; return -1;
} }
break; break;
case SMART_IMMEDIATE_OFFLINE: case ATA_SMART_IMMEDIATE_OFFLINE:
buff[0] = buff[1]; // select field buff[0] = buff[1]; // select field
DLen = 1; DLen = 1;
rc = DosDevIOCtl (hDevice, DSKSP_CAT_SMART, DSKSP_SMART_EOLI, rc = DosDevIOCtl (hDevice, DSKSP_CAT_SMART, DSKSP_SMART_EXEC_OFFLINE,
(PVOID)&Parms, PLen, &PLen, (PVOID)buff, DLen, &DLen); (PVOID)&Parms, PLen, &PLen, (PVOID)buff, DLen, &DLen);
if (rc) { if (rc) {
printf ("DANIS506 ATA GET DSKSP_SMART_EXEC_OFFLINE failed (%d,0x%x)\n", rc, rc); printf ("DANIS506 ATA GET DSKSP_SMART_EXEC_OFFLINE failed (%lu)\n", rc);
return -1; return -1;
} }
break; break;
default: default:
fprintf( stderr, "device %d, request 0x%x, arg[0] 0x%x, arg[2] 0x%x\n", device, request, buff[0], buff[2]); fprintf( stderr, "device %d, arg[0] 0x%x, arg[2] 0x%x\n", device, buff[0], buff[2]);
fprintf( stderr, "unknown ioctl\n"); fprintf( stderr, "unknown ioctl\n");
return -1; return -1;
break; break;
@ -450,52 +510,14 @@ int ata_command_interface(int device, smart_command_set command, int select, cha
return -1; return -1;
} }
#if 0 // We are now calling ioctl wrapper to the driver.
// This command uses the HDIO_DRIVE_TASKFILE ioctl(). This is the // TODO: use PASSTHRU in case of OS2AHCI driver
// only ioctl() that can be used to WRITE data to the disk. if ((dani_ioctl(device, buff)))
if (command==WRITE_LOG) {
unsigned char task[sizeof(ide_task_request_t)+512];
ide_task_request_t *reqtask=(ide_task_request_t *) task;
task_struct_t *taskfile=(task_struct_t *) reqtask->io_ports;
int retval;
memset(task, 0, sizeof(task));
taskfile->data = 0;
taskfile->feature = ATA_SMART_WRITE_LOG_SECTOR;
taskfile->sector_count = 1;
taskfile->sector_number = select;
taskfile->low_cylinder = 0x4f;
taskfile->high_cylinder = 0xc2;
taskfile->device_head = 0;
taskfile->command = ATA_SMART_CMD;
reqtask->data_phase = TASKFILE_OUT;
reqtask->req_cmd = IDE_DRIVE_TASK_OUT;
reqtask->out_size = 512;
reqtask->in_size = 0;
// copy user data into the task request structure
memcpy(task+sizeof(ide_task_request_t), data, 512);
if ((retval=dani_ioctl(device, HDIO_DRIVE_TASKFILE, task))) {
if (retval==-EINVAL)
pout("Kernel lacks HDIO_DRIVE_TASKFILE support; compile kernel with CONFIG_IDE_TASKFILE_IO set\n");
return -1;
}
return 0;
}
#endif // 0
// We are now doing the HDIO_DRIVE_CMD type ioctl.
if ((dani_ioctl(device, HDIO_DRIVE_CMD, buff)))
return -1; return -1;
// There are two different types of ioctls(). The HDIO_DRIVE_TASK // There are two different types of ioctls(). The HDIO_DRIVE_TASK
// one is this: // one is this:
if (command==STATUS_CHECK){ if (command==STATUS_CHECK){
int retval;
// Cyl low and Cyl high unchanged means "Good SMART status" // Cyl low and Cyl high unchanged means "Good SMART status"
if (buff[4]==0) if (buff[4]==0)
return 0; return 0;
@ -522,8 +544,8 @@ int ata_command_interface(int device, smart_command_set command, int select, cha
return 0; return 0;
} }
// Interface to SCSI devices. See os_linux.c // Interface to SCSI devices. N/A under OS/2
int do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report) { int do_scsi_cmnd_io(int /* fd */, struct scsi_cmnd_io * /* iop */, int /* report */) {
unsupported(3); pout("SCSI interface is not implemented\n");
return -ENOSYS; return -ENOSYS;
} }

View File

@ -3,7 +3,7 @@
* *
* Home page of code is: http://www.smartmontools.org * Home page of code is: http://www.smartmontools.org
* *
* Copyright (C) 2004-8 Yuri Dario <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2004-8 Yuri Dario
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -18,7 +18,7 @@
#ifndef OS_OS2_H_ #ifndef OS_OS2_H_
#define OS_OS2_H_ #define OS_OS2_H_
#define OS_XXXX_H_CVSID "$Id: os_os2.h 4120 2015-08-27 16:12:21Z samm2 $\n" #define OS_XXXX_H_CVSID "$Id: os_os2.h 4431 2017-08-08 19:38:15Z chrfranke $\n"
// Additional material should start here. Note: to keep the '-V' CVS // Additional material should start here. Note: to keep the '-V' CVS
// reporting option working as intended, you should only #include // reporting option working as intended, you should only #include
@ -28,11 +28,11 @@
#define INCL_DOS #define INCL_DOS
#include <os2.h> #include <os2.h>
#include "os_os2\hdreg.h"
#include "os_linux.h" #include "os_linux.h"
#pragma pack(1) #pragma pack(1)
/* IOCTL definitions from s506oem.h (primarily required for SMART calls) */
#define DSKSP_CAT_SMART 0x80 /* SMART IOCTL category */ #define DSKSP_CAT_SMART 0x80 /* SMART IOCTL category */
#define DSKSP_SMART_ONOFF 0x20 /* turn SMART on or off */ #define DSKSP_SMART_ONOFF 0x20 /* turn SMART on or off */
#define DSKSP_SMART_AUTOSAVE_ONOFF 0x21 /* turn SMART autosave on or off */ #define DSKSP_SMART_AUTOSAVE_ONOFF 0x21 /* turn SMART autosave on or off */
@ -40,11 +40,9 @@
#define DSKSP_SMART_GETSTATUS 0x23 /* get SMART status (pass/fail) */ #define DSKSP_SMART_GETSTATUS 0x23 /* get SMART status (pass/fail) */
#define DSKSP_SMART_GET_ATTRIBUTES 0x24 /* get SMART attributes table */ #define DSKSP_SMART_GET_ATTRIBUTES 0x24 /* get SMART attributes table */
#define DSKSP_SMART_GET_THRESHOLDS 0x25 /* get SMART thresholds table */ #define DSKSP_SMART_GET_THRESHOLDS 0x25 /* get SMART thresholds table */
#define DSKSP_SMART_READ_LOG 0x26 #define DSKSP_SMART_GET_LOG 0x26 /* get SMART log table */
#define DSKSP_SMART_WRITE_LOG 0x27 #define DSKSP_SMART_AUTO_OFFLINE 0x27 /* set SMART offline autosave timer */
#define DSKSP_SMART_READ_LOG_EXT 0x28 #define DSKSP_SMART_EXEC_OFFLINE 0x28 /* execute SMART immediate offline */
#define DSKSP_SMART_WRITE_LOG_EXT 0x29
#define DSKSP_SMART_EOLI 0x30 /* EXECUTE OFF-LINE IMMEDIATE */
#define SMART_CMD_ON 1 /* on value for related SMART functions */ #define SMART_CMD_ON 1 /* on value for related SMART functions */
#define SMART_CMD_OFF 0 /* off value for related SMART functions */ #define SMART_CMD_OFF 0 /* off value for related SMART functions */
@ -67,4 +65,9 @@ struct SMART_ParamExt {
ULONG reserved; // reserved. must be set to 0 ULONG reserved; // reserved. must be set to 0
}; };
const char * danisdev="\\DEV\\IBMS506$"; // DANIS506
const char * danispref="hd";
const char * ahcidev="\\DEV\\OS2AHCI$"; // OS2AHCI
const char * ahcipref="ahci";
#endif /* OS_GENERIC_H_ */ #endif /* OS_GENERIC_H_ */

View File

@ -1,9 +0,0 @@
#! /bin/sh
CFLAGS="-s -Zomf -O3 -march=pentium -mcpu=pentium3" \
CXXFLAGS="-s -Zomf -O3 -march=pentium -mcpu=pentium3" \
LDFLAGS="-s -Zmap -Zhigh-mem -Zomf -Zexe -Zstack 0x100" \
LIBS=" -lsyslog -lsocket" \
LN_CP_F="cp.exe" \
RANLIB="echo" \
AR="emxomfar" \
./configure --prefix=/usr/local/smartmontools

View File

@ -1,333 +0,0 @@
#ifndef _LINUX_HDREG_H
#define _LINUX_HDREG_H
/*
* This file contains some defines for the AT-hd-controller.
* Various sources.
*/
#define HD_IRQ 14 /* the standard disk interrupt */
/* ide.c has its own port definitions in "ide.h" */
/* Hd controller regs. Ref: IBM AT Bios-listing */
#define HD_DATA 0x1f0 /* _CTL when writing */
#define HD_ERROR 0x1f1 /* see err-bits */
#define HD_NSECTOR 0x1f2 /* nr of sectors to read/write */
#define HD_SECTOR 0x1f3 /* starting sector */
#define HD_LCYL 0x1f4 /* starting cylinder */
#define HD_HCYL 0x1f5 /* high byte of starting cyl */
#define HD_CURRENT 0x1f6 /* 101dhhhh , d=drive, hhhh=head */
#define HD_STATUS 0x1f7 /* see status-bits */
#define HD_FEATURE HD_ERROR /* same io address, read=error, write=feature */
#define HD_PRECOMP HD_FEATURE /* obsolete use of this port - predates IDE */
#define HD_COMMAND HD_STATUS /* same io address, read=status, write=cmd */
#define HD_CMD 0x3f6 /* used for resets */
#define HD_ALTSTATUS 0x3f6 /* same as HD_STATUS but doesn't clear irq */
/* remainder is shared between hd.c, ide.c, ide-cd.c, and the hdparm utility */
/* Bits of HD_STATUS */
#define ERR_STAT 0x01
#define INDEX_STAT 0x02
#define ECC_STAT 0x04 /* Corrected error */
#define DRQ_STAT 0x08
#define SEEK_STAT 0x10
#define WRERR_STAT 0x20
#define READY_STAT 0x40
#define BUSY_STAT 0x80
/* Values for HD_COMMAND */
#define WIN_RESTORE 0x10
#define WIN_READ 0x20
#define WIN_WRITE 0x30
#define WIN_WRITE_VERIFY 0x3C
#define WIN_VERIFY 0x40
#define WIN_FORMAT 0x50
#define WIN_INIT 0x60
#define WIN_SEEK 0x70
#define WIN_DIAGNOSE 0x90
#define WIN_SPECIFY 0x91 /* set drive geometry translation */
#define WIN_IDLEIMMEDIATE 0xE1 /* force drive to become "ready" */
#define WIN_SETIDLE1 0xE3
#define WIN_SETIDLE2 0x97
#define WIN_STANDBYNOW1 0xE0
#define WIN_STANDBYNOW2 0x94
#define WIN_SLEEPNOW1 0xE6
#define WIN_SLEEPNOW2 0x99
#define WIN_CHECKPOWERMODE1 0xE5
#define WIN_CHECKPOWERMODE2 0x98
#define WIN_DOORLOCK 0xDE /* lock door on removable drives */
#define WIN_DOORUNLOCK 0xDF /* unlock door on removable drives */
#define WIN_MULTREAD 0xC4 /* read sectors using multiple mode */
#define WIN_MULTWRITE 0xC5 /* write sectors using multiple mode */
#define WIN_SETMULT 0xC6 /* enable/disable multiple mode */
#define WIN_IDENTIFY 0xEC /* ask drive to identify itself */
#define WIN_IDENTIFY_DMA 0xEE /* same as WIN_IDENTIFY, but DMA */
#define WIN_SETFEATURES 0xEF /* set special drive features */
#define WIN_READDMA 0xC8 /* read sectors using DMA transfers */
#define WIN_WRITEDMA 0xCA /* write sectors using DMA transfers */
#define WIN_QUEUED_SERVICE 0xA2 /* */
#define WIN_READDMA_QUEUED 0xC7 /* read sectors using Queued DMA transfers */
#define WIN_WRITEDMA_QUEUED 0xCC /* write sectors using Queued DMA transfers */
#define WIN_READ_BUFFER 0xE4 /* force read only 1 sector */
#define WIN_WRITE_BUFFER 0xE8 /* force write only 1 sector */
#define WIN_SMART 0xB0 /* self-monitoring and reporting */
/* Additional drive command codes used by ATAPI devices. */
#define WIN_PIDENTIFY 0xA1 /* identify ATAPI device */
#define WIN_SRST 0x08 /* ATAPI soft reset command */
#define WIN_PACKETCMD 0xA0 /* Send a packet command. */
#define DISABLE_SEAGATE 0xFB
#define EXABYTE_ENABLE_NEST 0xF0
/* WIN_SMART sub-commands */
#define SMART_READ_VALUES 0xd0
#define SMART_READ_THRESHOLDS 0xd1
#define SMART_AUTOSAVE 0xd2
#define SMART_SAVE 0xd3
#define SMART_IMMEDIATE_OFFLINE 0xd4
#define SMART_READ_LOG_SECTOR 0xd5
#define SMART_WRITE_LOG_SECTOR 0xd6
#define SMART_ENABLE 0xd8
#define SMART_DISABLE 0xd9
#define SMART_STATUS 0xda
#define SMART_AUTO_OFFLINE 0xdb
/* WIN_SETFEATURES sub-commands */
#define SETFEATURES_EN_WCACHE 0x02 /* Enable write cache */
#define SETFEATURES_XFER 0x03 /* Set transfer mode */
# define XFER_UDMA_7 0x47 /* 0100|0111 */
# define XFER_UDMA_6 0x46 /* 0100|0110 */
# define XFER_UDMA_5 0x45 /* 0100|0101 */
# define XFER_UDMA_4 0x44 /* 0100|0100 */
# define XFER_UDMA_3 0x43 /* 0100|0011 */
# define XFER_UDMA_2 0x42 /* 0100|0010 */
# define XFER_UDMA_1 0x41 /* 0100|0001 */
# define XFER_UDMA_0 0x40 /* 0100|0000 */
# define XFER_MW_DMA_2 0x22 /* 0010|0010 */
# define XFER_MW_DMA_1 0x21 /* 0010|0001 */
# define XFER_MW_DMA_0 0x20 /* 0010|0000 */
# define XFER_SW_DMA_2 0x12 /* 0001|0010 */
# define XFER_SW_DMA_1 0x11 /* 0001|0001 */
# define XFER_SW_DMA_0 0x10 /* 0001|0000 */
# define XFER_PIO_4 0x0C /* 0000|1100 */
# define XFER_PIO_3 0x0B /* 0000|1011 */
# define XFER_PIO_2 0x0A /* 0000|1010 */
# define XFER_PIO_1 0x09 /* 0000|1001 */
# define XFER_PIO_0 0x08 /* 0000|1000 */
# define XFER_PIO_SLOW 0x00 /* 0000|0000 */
#define SETFEATURES_DIS_DEFECT 0x04 /* Disable Defect Management */
#define SETFEATURES_EN_APM 0x05 /* Enable advanced power management */
#define SETFEATURES_DIS_MSN 0x31 /* Disable Media Status Notification */
#define SETFEATURES_DIS_RLA 0x55 /* Disable read look-ahead feature */
#define SETFEATURES_EN_RI 0x5D /* Enable release interrupt */
#define SETFEATURES_EN_SI 0x5E /* Enable SERVICE interrupt */
#define SETFEATURES_DIS_RPOD 0x66 /* Disable reverting to power on defaults */
#define SETFEATURES_DIS_WCACHE 0x82 /* Disable write cache */
#define SETFEATURES_EN_DEFECT 0x84 /* Enable Defect Management */
#define SETFEATURES_DIS_APM 0x85 /* Disable advanced power management */
#define SETFEATURES_EN_MSN 0x95 /* Enable Media Status Notification */
#define SETFEATURES_EN_RLA 0xAA /* Enable read look-ahead feature */
#define SETFEATURES_PREFETCH 0xAB /* Sets drive prefetch value */
#define SETFEATURES_EN_RPOD 0xCC /* Enable reverting to power on defaults */
#define SETFEATURES_DIS_RI 0xDD /* Disable release interrupt */
#define SETFEATURES_DIS_SI 0xDE /* Disable SERVICE interrupt */
/* WIN_SECURITY sub-commands */
#define SECURITY_SET_PASSWORD 0xBA /* 0xF1 */
#define SECURITY_UNLOCK 0xBB /* 0xF2 */
#define SECURITY_ERASE_PREPARE 0xBC /* 0xF3 */
#define SECURITY_ERASE_UNIT 0xBD /* 0xF4 */
#define SECURITY_FREEZE_LOCK 0xBE /* 0xF5 */
#define SECURITY_DISABLE_PASSWORD 0xBF /* 0xF6 */
/* Bits for HD_ERROR */
#define MARK_ERR 0x01 /* Bad address mark */
#define TRK0_ERR 0x02 /* couldn't find track 0 */
#define ABRT_ERR 0x04 /* Command aborted */
#define MCR_ERR 0x08 /* media change request */
#define ID_ERR 0x10 /* ID field not found */
#define ECC_ERR 0x40 /* Uncorrectable ECC error */
#define BBD_ERR 0x80 /* pre-EIDE meaning: block marked bad */
#define ICRC_ERR 0x80 /* new meaning: CRC error during transfer */
struct hd_geometry {
unsigned char heads;
unsigned char sectors;
unsigned short cylinders;
unsigned long start;
};
/* hd/ide ctl's that pass (arg) ptrs to user space are numbered 0x030n/0x031n */
#define HDIO_GETGEO 0x0301 /* get device geometry */
#define HDIO_GET_UNMASKINTR 0x0302 /* get current unmask setting */
#define HDIO_GET_MULTCOUNT 0x0304 /* get current IDE blockmode setting */
#define HDIO_OBSOLETE_IDENTITY 0x0307 /* OBSOLETE, DO NOT USE: returns 142 bytes */
#define HDIO_GET_KEEPSETTINGS 0x0308 /* get keep-settings-on-reset flag */
#define HDIO_GET_32BIT 0x0309 /* get current io_32bit setting */
#define HDIO_GET_NOWERR 0x030a /* get ignore-write-error flag */
#define HDIO_GET_DMA 0x030b /* get use-dma flag */
#define HDIO_GET_NICE 0x030c /* get nice flags */
#define HDIO_GET_IDENTITY 0x030d /* get IDE identification info */
#define HDIO_DRIVE_RESET 0x031c /* execute a device reset */
#define HDIO_TRISTATE_HWIF 0x031d /* execute a channel tristate */
#ifndef __EMX__
#define HDIO_DRIVE_TASK 0x031e /* execute task and special drive command */
#endif
#define HDIO_DRIVE_CMD 0x031f /* execute a special drive command */
#define HDIO_DRIVE_CMD_AEB HDIO_DRIVE_TASK
/* hd/ide ctl's that pass (arg) non-ptr values are numbered 0x032n/0x033n */
#define HDIO_SET_MULTCOUNT 0x0321 /* change IDE blockmode */
#define HDIO_SET_UNMASKINTR 0x0322 /* permit other irqs during I/O */
#define HDIO_SET_KEEPSETTINGS 0x0323 /* keep ioctl settings on reset */
#define HDIO_SET_32BIT 0x0324 /* change io_32bit flags */
#define HDIO_SET_NOWERR 0x0325 /* change ignore-write-error flag */
#define HDIO_SET_DMA 0x0326 /* change use-dma flag */
#define HDIO_SET_PIO_MODE 0x0327 /* reconfig interface to new speed */
#define HDIO_SCAN_HWIF 0x0328 /* register and (re)scan interface */
#define HDIO_SET_NICE 0x0329 /* set nice flags */
#define HDIO_UNREGISTER_HWIF 0x032a /* unregister interface */
/* BIG GEOMETRY */
struct hd_big_geometry {
unsigned char heads;
unsigned char sectors;
unsigned int cylinders;
unsigned long start;
};
/* hd/ide ctl's that pass (arg) ptrs to user space are numbered 0x033n/0x033n */
#define HDIO_GETGEO_BIG 0x0330 /* */
#define HDIO_GETGEO_BIG_RAW 0x0331 /* */
#define __NEW_HD_DRIVE_ID
/* structure returned by HDIO_GET_IDENTITY, as per ANSI ATA2 rev.2f spec */
struct hd_driveid {
unsigned short config; /* lots of obsolete bit flags */
unsigned short cyls; /* "physical" cyls */
unsigned short reserved2; /* reserved (word 2) */
unsigned short heads; /* "physical" heads */
unsigned short track_bytes; /* unformatted bytes per track */
unsigned short sector_bytes; /* unformatted bytes per sector */
unsigned short sectors; /* "physical" sectors per track */
unsigned short vendor0; /* vendor unique */
unsigned short vendor1; /* vendor unique */
unsigned short vendor2; /* vendor unique */
unsigned char serial_no[20]; /* 0 = not_specified */
unsigned short buf_type;
unsigned short buf_size; /* 512 byte increments; 0 = not_specified */
unsigned short ecc_bytes; /* for r/w long cmds; 0 = not_specified */
unsigned char fw_rev[8]; /* 0 = not_specified */
unsigned char model[40]; /* 0 = not_specified */
unsigned char max_multsect; /* 0=not_implemented */
unsigned char vendor3; /* vendor unique */
unsigned short dword_io; /* 0=not_implemented; 1=implemented */
unsigned char vendor4; /* vendor unique */
unsigned char capability; /* bits 0:DMA 1:LBA 2:IORDYsw 3:IORDYsup*/
unsigned short reserved50; /* reserved (word 50) */
unsigned char vendor5; /* vendor unique */
unsigned char tPIO; /* 0=slow, 1=medium, 2=fast */
unsigned char vendor6; /* vendor unique */
unsigned char tDMA; /* 0=slow, 1=medium, 2=fast */
unsigned short field_valid; /* bits 0:cur_ok 1:eide_ok */
unsigned short cur_cyls; /* logical cylinders */
unsigned short cur_heads; /* logical heads */
unsigned short cur_sectors; /* logical sectors per track */
unsigned short cur_capacity0; /* logical total sectors on drive */
unsigned short cur_capacity1; /* (2 words, misaligned int) */
unsigned char multsect; /* current multiple sector count */
unsigned char multsect_valid; /* when (bit0==1) multsect is ok */
unsigned int lba_capacity; /* total number of sectors */
unsigned short dma_1word; /* single-word dma info */
unsigned short dma_mword; /* multiple-word dma info */
unsigned short eide_pio_modes; /* bits 0:mode3 1:mode4 */
unsigned short eide_dma_min; /* min mword dma cycle time (ns) */
unsigned short eide_dma_time; /* recommended mword dma cycle time (ns) */
unsigned short eide_pio; /* min cycle time (ns), no IORDY */
unsigned short eide_pio_iordy; /* min cycle time (ns), with IORDY */
unsigned short words69_70[2]; /* reserved words 69-70 */
/* HDIO_GET_IDENTITY currently returns only words 0 through 70 */
unsigned short words71_74[4]; /* reserved words 71-74 */
unsigned short queue_depth; /* */
unsigned short words76_79[4]; /* reserved words 76-79 */
unsigned short major_rev_num; /* */
unsigned short minor_rev_num; /* */
unsigned short command_set_1; /* bits 0:Smart 1:Security 2:Removable 3:PM */
unsigned short command_set_2; /* bits 14:Smart Enabled 13:0 zero */
unsigned short cfsse; /* command set-feature supported extensions */
unsigned short cfs_enable_1; /* command set-feature enabled */
unsigned short cfs_enable_2; /* command set-feature enabled */
unsigned short csf_default; /* command set-feature default */
unsigned short dma_ultra; /* */
unsigned short word89; /* reserved (word 89) */
unsigned short word90; /* reserved (word 90) */
unsigned short CurAPMvalues; /* current APM values */
unsigned short word92; /* reserved (word 92) */
unsigned short hw_config; /* hardware config */
unsigned short words94_125[32];/* reserved words 94-125 */
unsigned short last_lun; /* reserved (word 126) */
unsigned short word127; /* reserved (word 127) */
unsigned short dlf; /* device lock function
* 15:9 reserved
* 8 security level 1:max 0:high
* 7:6 reserved
* 5 enhanced erase
* 4 expire
* 3 frozen
* 2 locked
* 1 en/disabled
* 0 capability
*/
unsigned short csfo; /* current set features options
* 15:4 reserved
* 3 auto reassign
* 2 reverting
* 1 read-look-ahead
* 0 write cache
*/
unsigned short words130_155[26];/* reserved vendor words 130-155 */
unsigned short word156;
unsigned short words157_159[3];/* reserved vendor words 157-159 */
unsigned short words160_255[95];/* reserved words 160-255 */
};
/*
* IDE "nice" flags. These are used on a per drive basis to determine
* when to be nice and give more bandwidth to the other devices which
* share the same IDE bus.
*/
#define IDE_NICE_DSC_OVERLAP (0) /* per the DSC overlap protocol */
#define IDE_NICE_ATAPI_OVERLAP (1) /* not supported yet */
#define IDE_NICE_0 (2) /* when sure that it won't affect us */
#define IDE_NICE_1 (3) /* when probably won't affect us much */
#define IDE_NICE_2 (4) /* when we know it's on our expense */
#ifdef __KERNEL__
/*
* These routines are used for kernel command line parameters from main.c:
*/
#include <linux/config.h>
#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
int ide_register(int io_port, int ctl_port, int irq);
void ide_unregister(unsigned int);
#endif /* CONFIG_BLK_DEV_IDE || CONFIG_BLK_DEV_IDE_MODULE */
#endif /* __KERNEL__ */
#endif /* _LINUX_HDREG_H */

View File

@ -3,8 +3,8 @@
* *
* Home page of code is: http://www.smartmontools.org * Home page of code is: http://www.smartmontools.org
* *
* Copyright (C) Joerg Hering <smartmontools-support@lists.sourceforge.net> * Copyright (C) Joerg Hering
* Copyright (C) 2003-8 Bruce Allen <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2003-8 Bruce Allen
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -23,7 +23,7 @@
*/ */
#ifndef OS_QNXNTO_H_ #ifndef OS_QNXNTO_H_
#define OS_QNXNTO_H_ #define OS_QNXNTO_H_
#define OS_QNXNTO_H_CVSID "$Id: os_qnxnto.h 4120 2015-08-27 16:12:21Z samm2 $\n" #define OS_QNXNTO_H_CVSID "$Id: os_qnxnto.h 4431 2017-08-08 19:38:15Z chrfranke $\n"
// Additional material should start here. Note: to keep the '-V' CVS // Additional material should start here. Note: to keep the '-V' CVS
// reporting option working as intended, you should only #include // reporting option working as intended, you should only #include

View File

@ -3,8 +3,8 @@
* *
* Home page of code is: http://www.smartmontools.org * Home page of code is: http://www.smartmontools.org
* *
* Copyright (C) 2003-8 SAWADA Keiji <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2003-8 SAWADA Keiji
* Copyright (C) 2003-8 Casper Dik <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2003-8 Casper Dik
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -25,7 +25,7 @@
#ifndef OS_SOLARIS_H_ #ifndef OS_SOLARIS_H_
#define OS_SOLARIS_H_ #define OS_SOLARIS_H_
#define OS_SOLARIS_H_CVSID "$Id: os_solaris.h 4120 2015-08-27 16:12:21Z samm2 $\n" #define OS_SOLARIS_H_CVSID "$Id: os_solaris.h 4431 2017-08-08 19:38:15Z chrfranke $\n"
// Additional material should start here. Note: to keep the '-V' CVS // Additional material should start here. Note: to keep the '-V' CVS
// reporting option working as intended, you should only #include // reporting option working as intended, you should only #include

View File

@ -3,7 +3,7 @@
* *
* Home page of code is: http://www.smartmontools.org * Home page of code is: http://www.smartmontools.org
* *
* Copyright (C) 2004-16 Christian Franke * Copyright (C) 2004-17 Christian Franke
* *
* Original AACRaid code: * Original AACRaid code:
* Copyright (C) 2015 Nidhi Malhotra <nidhi.malhotra@pmcs.com> * Copyright (C) 2015 Nidhi Malhotra <nidhi.malhotra@pmcs.com>
@ -112,7 +112,7 @@
#define strnicmp strncasecmp #define strnicmp strncasecmp
#endif #endif
const char * os_win32_cpp_cvsid = "$Id: os_win32.cpp 4293 2016-04-14 19:33:05Z chrfranke $"; const char * os_win32_cpp_cvsid = "$Id: os_win32.cpp 4559 2017-10-22 16:17:50Z chrfranke $";
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// Windows I/O-controls, some declarations are missing in the include files // Windows I/O-controls, some declarations are missing in the include files
@ -276,6 +276,45 @@ ASSERT_SIZEOF(STORAGE_DEVICE_DESCRIPTOR, 36+1+3);
ASSERT_SIZEOF(STORAGE_PROPERTY_QUERY, 8+1+3); ASSERT_SIZEOF(STORAGE_PROPERTY_QUERY, 8+1+3);
// IOCTL_STORAGE_QUERY_PROPERTY: Windows 10 enhancements
namespace win10 {
// enum STORAGE_PROPERTY_ID: new values
const STORAGE_PROPERTY_ID StorageAdapterProtocolSpecificProperty = (STORAGE_PROPERTY_ID)49;
const STORAGE_PROPERTY_ID StorageDeviceProtocolSpecificProperty = (STORAGE_PROPERTY_ID)50;
typedef enum _STORAGE_PROTOCOL_TYPE {
ProtocolTypeUnknown = 0,
ProtocolTypeScsi,
ProtocolTypeAta,
ProtocolTypeNvme,
ProtocolTypeSd
} STORAGE_PROTOCOL_TYPE;
typedef enum _STORAGE_PROTOCOL_NVME_DATA_TYPE {
NVMeDataTypeUnknown = 0,
NVMeDataTypeIdentify,
NVMeDataTypeLogPage,
NVMeDataTypeFeature
} STORAGE_PROTOCOL_NVME_DATA_TYPE;
typedef struct _STORAGE_PROTOCOL_SPECIFIC_DATA {
STORAGE_PROTOCOL_TYPE ProtocolType;
ULONG DataType;
ULONG ProtocolDataRequestValue;
ULONG ProtocolDataRequestSubValue;
ULONG ProtocolDataOffset;
ULONG ProtocolDataLength;
ULONG FixedProtocolReturnData;
ULONG Reserved[3];
} STORAGE_PROTOCOL_SPECIFIC_DATA;
ASSERT_SIZEOF(STORAGE_PROTOCOL_SPECIFIC_DATA, 40);
} // namespace win10
// IOCTL_STORAGE_PREDICT_FAILURE // IOCTL_STORAGE_PREDICT_FAILURE
ASSERT_CONST(IOCTL_STORAGE_PREDICT_FAILURE, 0x002d1100); ASSERT_CONST(IOCTL_STORAGE_PREDICT_FAILURE, 0x002d1100);
@ -1958,6 +1997,8 @@ class csmi_device
: virtual public /*extends*/ smart_device : virtual public /*extends*/ smart_device
{ {
public: public:
enum { max_number_of_ports = 32 };
/// Get bitmask of used ports /// Get bitmask of used ports
unsigned get_ports_used(); unsigned get_ports_used();
@ -1966,8 +2007,10 @@ protected:
: smart_device(never_called) : smart_device(never_called)
{ memset(&m_phy_ent, 0, sizeof(m_phy_ent)); } { memset(&m_phy_ent, 0, sizeof(m_phy_ent)); }
/// Get phy info typedef signed char port_2_index_map[max_number_of_ports];
bool get_phy_info(CSMI_SAS_PHY_INFO & phy_info);
/// Get phy info and port mapping, return #ports or -1 on error
int get_phy_info(CSMI_SAS_PHY_INFO & phy_info, port_2_index_map & p2i);
/// Select physical drive /// Select physical drive
bool select_port(int port); bool select_port(int port);
@ -1987,13 +2030,18 @@ private:
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
bool csmi_device::get_phy_info(CSMI_SAS_PHY_INFO & phy_info) int csmi_device::get_phy_info(CSMI_SAS_PHY_INFO & phy_info, port_2_index_map & p2i)
{ {
// max_number_of_ports must match CSMI_SAS_PHY_INFO.Phy[] array size
typedef char ASSERT_phy_info_size[
(int)(sizeof(phy_info.Phy) / sizeof(phy_info.Phy[0])) == max_number_of_ports ? 1 : -1]
ATTR_UNUSED;
// Get driver info to check CSMI support // Get driver info to check CSMI support
CSMI_SAS_DRIVER_INFO_BUFFER driver_info_buf; CSMI_SAS_DRIVER_INFO_BUFFER driver_info_buf;
memset(&driver_info_buf, 0, sizeof(driver_info_buf)); memset(&driver_info_buf, 0, sizeof(driver_info_buf));
if (!csmi_ioctl(CC_CSMI_SAS_GET_DRIVER_INFO, &driver_info_buf.IoctlHeader, sizeof(driver_info_buf))) if (!csmi_ioctl(CC_CSMI_SAS_GET_DRIVER_INFO, &driver_info_buf.IoctlHeader, sizeof(driver_info_buf)))
return false; return -1;
if (scsi_debugmode > 1) { if (scsi_debugmode > 1) {
const CSMI_SAS_DRIVER_INFO & driver_info = driver_info_buf.Information; const CSMI_SAS_DRIVER_INFO & driver_info = driver_info_buf.Information;
@ -2007,26 +2055,78 @@ bool csmi_device::get_phy_info(CSMI_SAS_PHY_INFO & phy_info)
CSMI_SAS_PHY_INFO_BUFFER phy_info_buf; CSMI_SAS_PHY_INFO_BUFFER phy_info_buf;
memset(&phy_info_buf, 0, sizeof(phy_info_buf)); memset(&phy_info_buf, 0, sizeof(phy_info_buf));
if (!csmi_ioctl(CC_CSMI_SAS_GET_PHY_INFO, &phy_info_buf.IoctlHeader, sizeof(phy_info_buf))) if (!csmi_ioctl(CC_CSMI_SAS_GET_PHY_INFO, &phy_info_buf.IoctlHeader, sizeof(phy_info_buf)))
return false; return -1;
phy_info = phy_info_buf.Information; phy_info = phy_info_buf.Information;
const int max_number_of_phys = sizeof(phy_info.Phy) / sizeof(phy_info.Phy[0]); if (phy_info.bNumberOfPhys > max_number_of_ports) {
if (phy_info.bNumberOfPhys > max_number_of_phys) set_err(EIO, "CSMI_SAS_PHY_INFO: Bogus NumberOfPhys=%d", phy_info.bNumberOfPhys);
return set_err(EIO, "CSMI_SAS_PHY_INFO: Bogus NumberOfPhys=%d", phy_info.bNumberOfPhys); return -1;
}
// Create port -> index map
// IRST Release
// Phy[i].Value 9.x 10.4 14.8 15.2
// ---------------------------------------------------
// bPortIdentifier 0xff 0xff port 0x00
// Identify.bPhyIdentifier port port port port
// Attached.bPhyIdentifier 0x00 0x00 0x00 port
// Empty ports in Phy[]? no ? yes yes
int number_of_ports;
for (int mode = 0; ; mode++) {
for (int i = 0; i < max_number_of_ports; i++)
p2i[i] = -1;
number_of_ports = 0;
bool unique = true;
for (int i = 0; i < max_number_of_ports; i++) {
const CSMI_SAS_PHY_ENTITY & pe = phy_info.Phy[i];
if (pe.Identify.bDeviceType == CSMI_SAS_NO_DEVICE_ATTACHED)
continue;
// Use a bPhyIdentifier or the bPortIdentifier if unique,
// otherwise use table index
int port;
switch (mode) {
case 0: port = pe.Attached.bPhyIdentifier; break;
case 1: port = pe.Identify.bPhyIdentifier; break;
case 2: port = pe.bPortIdentifier; break;
default: port = i; break;
}
if (!(port < max_number_of_ports && p2i[port] == -1)) {
unique = false;
break;
}
p2i[port] = i;
if (number_of_ports <= port)
number_of_ports = port + 1;
}
if (unique || mode > 2)
break;
}
if (scsi_debugmode > 1) { if (scsi_debugmode > 1) {
pout("CSMI_SAS_PHY_INFO: NumberOfPhys=%d\n", phy_info.bNumberOfPhys); pout("CSMI_SAS_PHY_INFO: NumberOfPhys=%d\n", phy_info.bNumberOfPhys);
for (int i = 0; i < max_number_of_phys; i++) { for (int i = 0; i < max_number_of_ports; i++) {
const CSMI_SAS_PHY_ENTITY & pe = phy_info.Phy[i]; const CSMI_SAS_PHY_ENTITY & pe = phy_info.Phy[i];
const CSMI_SAS_IDENTIFY & id = pe.Identify, & at = pe.Attached; const CSMI_SAS_IDENTIFY & id = pe.Identify, & at = pe.Attached;
if (id.bDeviceType == CSMI_SAS_NO_DEVICE_ATTACHED) if (id.bDeviceType == CSMI_SAS_NO_DEVICE_ATTACHED)
continue; continue;
pout("Phy[%d] Port: 0x%02x\n", i, pe.bPortIdentifier); int port = -1;
for (int p = 0; p < max_number_of_ports && port < 0; p++) {
if (p2i[p] == i)
port = p;
}
pout("Phy[%d] Port: %d\n", i, port);
pout(" Type: 0x%02x, 0x%02x\n", id.bDeviceType, at.bDeviceType); pout(" Type: 0x%02x, 0x%02x\n", id.bDeviceType, at.bDeviceType);
pout(" InitProto: 0x%02x, 0x%02x\n", id.bInitiatorPortProtocol, at.bInitiatorPortProtocol); pout(" InitProto: 0x%02x, 0x%02x\n", id.bInitiatorPortProtocol, at.bInitiatorPortProtocol);
pout(" TargetProto: 0x%02x, 0x%02x\n", id.bTargetPortProtocol, at.bTargetPortProtocol); pout(" TargetProto: 0x%02x, 0x%02x\n", id.bTargetPortProtocol, at.bTargetPortProtocol);
pout(" PortIdent: 0x%02x\n", pe.bPortIdentifier);
pout(" PhyIdent: 0x%02x, 0x%02x\n", id.bPhyIdentifier, at.bPhyIdentifier); pout(" PhyIdent: 0x%02x, 0x%02x\n", id.bPhyIdentifier, at.bPhyIdentifier);
const unsigned char * b = id.bSASAddress; const unsigned char * b = id.bSASAddress;
pout(" SASAddress: %02x %02x %02x %02x %02x %02x %02x %02x, ", pout(" SASAddress: %02x %02x %02x %02x %02x %02x %02x %02x, ",
@ -2037,20 +2137,23 @@ bool csmi_device::get_phy_info(CSMI_SAS_PHY_INFO & phy_info)
} }
} }
return true; return number_of_ports;
} }
unsigned csmi_device::get_ports_used() unsigned csmi_device::get_ports_used()
{ {
CSMI_SAS_PHY_INFO phy_info; CSMI_SAS_PHY_INFO phy_info;
if (!get_phy_info(phy_info)) port_2_index_map p2i;
int number_of_ports = get_phy_info(phy_info, p2i);
if (number_of_ports < 0)
return 0; return 0;
unsigned ports_used = 0; unsigned ports_used = 0;
for (unsigned i = 0; i < sizeof(phy_info.Phy) / sizeof(phy_info.Phy[0]); i++) { for (int p = 0; p < max_number_of_ports; p++) {
const CSMI_SAS_PHY_ENTITY & pe = phy_info.Phy[i]; int i = p2i[p];
if (pe.Identify.bDeviceType == CSMI_SAS_NO_DEVICE_ATTACHED) if (i < 0)
continue; continue;
const CSMI_SAS_PHY_ENTITY & pe = phy_info.Phy[i];
if (pe.Attached.bDeviceType == CSMI_SAS_NO_DEVICE_ATTACHED) if (pe.Attached.bDeviceType == CSMI_SAS_NO_DEVICE_ATTACHED)
continue; continue;
switch (pe.Attached.bTargetPortProtocol) { switch (pe.Attached.bTargetPortProtocol) {
@ -2061,55 +2164,30 @@ unsigned csmi_device::get_ports_used()
continue; continue;
} }
if (pe.bPortIdentifier == 0xff) ports_used |= (1 << p);
// Older (<= 9.*) Intel RST driver
ports_used |= (1 << i);
else
ports_used |= (1 << pe.bPortIdentifier);
} }
return ports_used; return ports_used;
} }
bool csmi_device::select_port(int port) bool csmi_device::select_port(int port)
{ {
if (!(0 <= port && port < max_number_of_ports))
return set_err(EINVAL, "Invalid port number %d", port);
CSMI_SAS_PHY_INFO phy_info; CSMI_SAS_PHY_INFO phy_info;
if (!get_phy_info(phy_info)) port_2_index_map p2i;
int number_of_ports = get_phy_info(phy_info, p2i);
if (number_of_ports < 0)
return false; return false;
// Find port int port_index = p2i[port];
int max_port = -1, port_index = -1;
for (unsigned i = 0; i < sizeof(phy_info.Phy) / sizeof(phy_info.Phy[0]); i++) {
const CSMI_SAS_PHY_ENTITY & pe = phy_info.Phy[i];
if (pe.Identify.bDeviceType == CSMI_SAS_NO_DEVICE_ATTACHED)
continue;
if (pe.bPortIdentifier == 0xff) {
// Older (<= 9.*) Intel RST driver
max_port = phy_info.bNumberOfPhys - 1;
if (i >= phy_info.bNumberOfPhys)
break;
if ((int)i != port)
continue;
}
else {
if (pe.bPortIdentifier > max_port)
max_port = pe.bPortIdentifier;
if (pe.bPortIdentifier != port)
continue;
}
port_index = i;
break;
}
if (port_index < 0) { if (port_index < 0) {
if (port <= max_port) if (port < number_of_ports)
return set_err(ENOENT, "Port %d is disabled", port); return set_err(ENOENT, "Port %d is disabled", port);
else else
return set_err(ENOENT, "Port %d does not exist (#ports: %d)", port, return set_err(ENOENT, "Port %d does not exist (#ports: %d)", port,
max_port + 1); number_of_ports);
} }
const CSMI_SAS_PHY_ENTITY & phy_ent = phy_info.Phy[port_index]; const CSMI_SAS_PHY_ENTITY & phy_ent = phy_info.Phy[port_index];
@ -2155,7 +2233,7 @@ bool csmi_ata_device::ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out)
ata_device::supports_output_regs | ata_device::supports_output_regs |
ata_device::supports_multi_sector | ata_device::supports_multi_sector |
ata_device::supports_48bit, ata_device::supports_48bit,
"CMSI") "CSMI")
) )
return false; return false;
@ -3674,7 +3752,7 @@ bool win_nvme_device::nvme_pass_through(const nvme_cmd_in & in, nvme_cmd_out & o
// Set NVMe command // Set NVMe command
pthru->SrbIoCtrl.HeaderLength = sizeof(SRB_IO_CONTROL); pthru->SrbIoCtrl.HeaderLength = sizeof(SRB_IO_CONTROL);
memcpy(pthru->SrbIoCtrl.Signature, NVME_SIG_STR, sizeof(NVME_SIG_STR)); memcpy(pthru->SrbIoCtrl.Signature, NVME_SIG_STR, sizeof(NVME_SIG_STR)-1);
pthru->SrbIoCtrl.Timeout = 60; pthru->SrbIoCtrl.Timeout = 60;
pthru->SrbIoCtrl.ControlCode = NVME_PASS_THROUGH_SRB_IO_CODE; pthru->SrbIoCtrl.ControlCode = NVME_PASS_THROUGH_SRB_IO_CODE;
pthru->SrbIoCtrl.ReturnCode = 0; pthru->SrbIoCtrl.ReturnCode = 0;
@ -3721,6 +3799,169 @@ bool win_nvme_device::nvme_pass_through(const nvme_cmd_in & in, nvme_cmd_out & o
} }
/////////////////////////////////////////////////////////////////////////////
// win10_nvme_device
class win10_nvme_device
: public /*implements*/ nvme_device,
public /*extends*/ win_smart_device
{
public:
win10_nvme_device(smart_interface * intf, const char * dev_name,
const char * req_type, unsigned nsid);
virtual bool open();
virtual bool nvme_pass_through(const nvme_cmd_in & in, nvme_cmd_out & out);
private:
bool open(int phydrive);
};
/////////////////////////////////////////////////////////////////////////////
win10_nvme_device::win10_nvme_device(smart_interface * intf, const char * dev_name,
const char * req_type, unsigned nsid)
: smart_device(intf, dev_name, "nvme", req_type),
nvme_device(nsid)
{
}
bool win10_nvme_device::open()
{
// TODO: Use common /dev/ parsing functions
const char * name = skipdev(get_dev_name()); int len = strlen(name);
// sd[a-z]([a-z])? => Physical drive 0-701
char drive[2 + 1] = ""; int n = -1;
if (sscanf(name, "sd%2[a-z]%n", drive, &n) == 1 && n == len)
return open(sdxy_to_phydrive(drive));
// pdN => Physical drive N
int phydrive = -1; n = -1;
if (sscanf(name, "pd%d%n", &phydrive, &n) == 1 && phydrive >= 0 && n == len)
return open(phydrive);
return set_err(EINVAL);
}
bool win10_nvme_device::open(int phydrive)
{
// TODO: Use common open function for all devices using "\\.\PhysicalDriveN"
char devpath[64];
snprintf(devpath, sizeof(devpath) - 1, "\\\\.\\PhysicalDrive%d", phydrive);
// No GENERIC_READ/WRITE access required, this works without admin rights
HANDLE h = CreateFileA(devpath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
(SECURITY_ATTRIBUTES *)0, OPEN_EXISTING, 0, (HANDLE)0);
if (h == INVALID_HANDLE_VALUE) {
long err = GetLastError();
if (nvme_debugmode > 1)
pout(" %s: Open failed, Error=%ld\n", devpath, err);
if (err == ERROR_FILE_NOT_FOUND)
set_err(ENOENT, "%s: not found", devpath);
else if (err == ERROR_ACCESS_DENIED)
set_err(EACCES, "%s: access denied", devpath);
else
set_err(EIO, "%s: Error=%ld", devpath, err);
return false;
}
if (nvme_debugmode > 1)
pout(" %s: successfully opened\n", devpath);
set_fh(h);
// Use broadcast namespace if no NSID specified
// TODO: Get NSID of current device
if (!get_nsid())
set_nsid(0xffffffff);
return true;
}
struct STORAGE_PROTOCOL_SPECIFIC_QUERY_WITH_BUFFER
{
struct { // STORAGE_PROPERTY_QUERY without AdditionalsParameters[1]
STORAGE_PROPERTY_ID PropertyId;
STORAGE_QUERY_TYPE QueryType;
} PropertyQuery;
win10::STORAGE_PROTOCOL_SPECIFIC_DATA ProtocolSpecific;
BYTE DataBuffer[1];
};
bool win10_nvme_device::nvme_pass_through(const nvme_cmd_in & in, nvme_cmd_out & out)
{
// Create buffer with appropriate size
raw_buffer spsq_raw_buf(offsetof(STORAGE_PROTOCOL_SPECIFIC_QUERY_WITH_BUFFER, DataBuffer) + in.size);
STORAGE_PROTOCOL_SPECIFIC_QUERY_WITH_BUFFER * spsq =
reinterpret_cast<STORAGE_PROTOCOL_SPECIFIC_QUERY_WITH_BUFFER *>(spsq_raw_buf.data());
// Set NVMe specifc STORAGE_PROPERTY_QUERY
spsq->PropertyQuery.QueryType = PropertyStandardQuery;
spsq->ProtocolSpecific.ProtocolType = win10::ProtocolTypeNvme;
switch (in.opcode) {
case smartmontools::nvme_admin_identify:
if (!in.nsid) // Identify controller
spsq->PropertyQuery.PropertyId = win10::StorageAdapterProtocolSpecificProperty;
else
spsq->PropertyQuery.PropertyId = win10::StorageDeviceProtocolSpecificProperty;
spsq->ProtocolSpecific.DataType = win10::NVMeDataTypeIdentify;
spsq->ProtocolSpecific.ProtocolDataRequestValue = in.cdw10;
break;
case smartmontools::nvme_admin_get_log_page:
spsq->PropertyQuery.PropertyId = win10::StorageDeviceProtocolSpecificProperty;
spsq->ProtocolSpecific.DataType = win10::NVMeDataTypeLogPage;
spsq->ProtocolSpecific.ProtocolDataRequestValue = in.cdw10 & 0xff; // LID only ?
break;
// TODO: nvme_admin_get_features
default:
return set_err(ENOSYS, "NVMe admin command 0x%02x not supported", in.opcode);
}
spsq->ProtocolSpecific.ProtocolDataRequestSubValue = in.nsid; // ?
spsq->ProtocolSpecific.ProtocolDataOffset = sizeof(spsq->ProtocolSpecific);
spsq->ProtocolSpecific.ProtocolDataLength = in.size;
if (in.direction() & nvme_cmd_in::data_out)
memcpy(spsq->DataBuffer, in.buffer, in.size);
if (nvme_debugmode > 1)
pout(" [STORAGE_QUERY_PROPERTY: Id=%u, Type=%u, Value=0x%08x, SubVal=0x%08x]\n",
(unsigned)spsq->PropertyQuery.PropertyId,
(unsigned)spsq->ProtocolSpecific.DataType,
(unsigned)spsq->ProtocolSpecific.ProtocolDataRequestValue,
(unsigned)spsq->ProtocolSpecific.ProtocolDataRequestSubValue);
// Call IOCTL_STORAGE_QUERY_PROPERTY
DWORD num_out = 0;
long err = 0;
if (!DeviceIoControl(get_fh(), IOCTL_STORAGE_QUERY_PROPERTY,
spsq, spsq_raw_buf.size(), spsq, spsq_raw_buf.size(),
&num_out, (OVERLAPPED*)0)) {
err = GetLastError();
}
if (nvme_debugmode > 1)
pout(" [STORAGE_QUERY_PROPERTY: ReturnData=0x%08x, Reserved[3]={0x%x, 0x%x, 0x%x}]\n",
(unsigned)spsq->ProtocolSpecific.FixedProtocolReturnData,
(unsigned)spsq->ProtocolSpecific.Reserved[0],
(unsigned)spsq->ProtocolSpecific.Reserved[1],
(unsigned)spsq->ProtocolSpecific.Reserved[2]);
// NVMe status is checked by IOCTL
if (err)
return set_err(EIO, "IOCTL_STORAGE_QUERY_PROPERTY(NVMe) failed, Error=%ld", err);
if (in.direction() & nvme_cmd_in::data_in)
memcpy(in.buffer, spsq->DataBuffer, in.size);
out.result = spsq->ProtocolSpecific.FixedProtocolReturnData; // Completion DW0 ?
return true;
}
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// win_smart_interface // win_smart_interface
// Platform specific interface // Platform specific interface
@ -3806,20 +4047,40 @@ std::string win_smart_interface::get_os_version_str()
} }
const char * w = 0; const char * w = 0;
unsigned build = 0;
if ( vi.dwPlatformId == VER_PLATFORM_WIN32_NT if ( vi.dwPlatformId == VER_PLATFORM_WIN32_NT
&& vi.dwMajorVersion <= 0xf && vi.dwMinorVersion <= 0xf) { && vi.dwMajorVersion <= 0xf && vi.dwMinorVersion <= 0xf) {
bool ws = (vi.wProductType <= VER_NT_WORKSTATION); switch ( (vi.dwMajorVersion << 4 | vi.dwMinorVersion) << 1
switch (vi.dwMajorVersion << 4 | vi.dwMinorVersion) { | (vi.wProductType > VER_NT_WORKSTATION ? 1 : 0) ) {
case 0x50: w = "2000"; break; case 0x50<<1 :
case 0x51: w = "xp"; break; case 0x50<<1 | 1: w = "2000"; break;
case 0x52: w = (!GetSystemMetrics(89/*SM_SERVERR2*/) case 0x51<<1 : w = "xp"; break;
? "2003" : "2003r2"); break; case 0x52<<1 : w = "xp64"; break;
case 0x60: w = (ws ? "vista" : "2008" ); break; case 0x52<<1 | 1: w = (!GetSystemMetrics(89/*SM_SERVERR2*/)
case 0x61: w = (ws ? "win7" : "2008r2"); break; ? "2003"
case 0x62: w = (ws ? "win8" : "2012" ); break; : "2003r2"); break;
case 0x63: w = (ws ? "win8.1": "2012r2"); break; case 0x60<<1 : w = "vista"; break;
case 0x64: w = (ws ? "w10tp" : "w10tps"); break; // 6.4 = Win 10 Technical Preview case 0x60<<1 | 1: w = "2008"; break;
case 0xa0: w = (ws ? "win10" : "2016" ); break; // 10.0 = Win 10 : Win Server 2016 (TP only?) case 0x61<<1 : w = "win7"; break;
case 0x61<<1 | 1: w = "2008r2"; break;
case 0x62<<1 : w = "win8"; break;
case 0x62<<1 | 1: w = "2012"; break;
case 0x63<<1 : w = "win8.1"; break;
case 0x63<<1 | 1: w = "2012r2"; break;
case 0xa0<<1 :
switch (vi.dwBuildNumber) {
case 10240: w = "w10-1507"; break;
case 10586: w = "w10-1511"; break;
case 14393: w = "w10-1607"; break;
case 15063: w = "w10-1703"; break;
case 16299: w = "w10-1709"; break;
default: w = "w10"; build = vi.dwBuildNumber; break;
} break;
case 0xa0<<1 | 1:
switch (vi.dwBuildNumber) {
case 14393: w = "2016-1607"; break;
default: w = "2016"; build = vi.dwBuildNumber; break;
} break;
} }
} }
@ -3833,6 +4094,8 @@ std::string win_smart_interface::get_os_version_str()
snprintf(vptr, vlen, "-%s%u.%u%s", snprintf(vptr, vlen, "-%s%u.%u%s",
(vi.dwPlatformId==VER_PLATFORM_WIN32_NT ? "nt" : "??"), (vi.dwPlatformId==VER_PLATFORM_WIN32_NT ? "nt" : "??"),
(unsigned)vi.dwMajorVersion, (unsigned)vi.dwMinorVersion, w64); (unsigned)vi.dwMajorVersion, (unsigned)vi.dwMinorVersion, w64);
else if (build)
snprintf(vptr, vlen, "-%s%s-b%u", w, w64, build);
else if (vi.wServicePackMinor) else if (vi.wServicePackMinor)
snprintf(vptr, vlen, "-%s%s-sp%u.%u", w, w64, vi.wServicePackMajor, vi.wServicePackMinor); snprintf(vptr, vlen, "-%s%s-sp%u.%u", w, w64, vi.wServicePackMajor, vi.wServicePackMinor);
else if (vi.wServicePackMajor) else if (vi.wServicePackMajor)
@ -3885,7 +4148,9 @@ scsi_device * win_smart_interface::get_scsi_device(const char * name, const char
nvme_device * win_smart_interface::get_nvme_device(const char * name, const char * type, nvme_device * win_smart_interface::get_nvme_device(const char * name, const char * type,
unsigned nsid) unsigned nsid)
{ {
if (str_starts_with(skipdev(name), "nvme"))
return new win_nvme_device(this, name, type, nsid); return new win_nvme_device(this, name, type, nsid);
return new win10_nvme_device(this, name, type, nsid);
} }
@ -3991,7 +4256,7 @@ std::string win_smart_interface::get_valid_custom_dev_types_str()
// Return value for device detection functions // Return value for device detection functions
enum win_dev_type { DEV_UNKNOWN = 0, DEV_ATA, DEV_SCSI, DEV_SAT, DEV_USB }; enum win_dev_type { DEV_UNKNOWN = 0, DEV_ATA, DEV_SCSI, DEV_SAT, DEV_USB, DEV_NVME };
// Return true if ATA drive behind a SAT layer // Return true if ATA drive behind a SAT layer
static bool is_sat(const STORAGE_DEVICE_DESCRIPTOR_DATA * data) static bool is_sat(const STORAGE_DEVICE_DESCRIPTOR_DATA * data)
@ -4061,6 +4326,9 @@ static win_dev_type get_controller_type(HANDLE hdevice, bool admin, GETVERSIONIN
case BusTypeUsb: case BusTypeUsb:
return DEV_USB; return DEV_USB;
case 0x11: // BusTypeNVMe?
return DEV_NVME;
default: default:
return DEV_UNKNOWN; return DEV_UNKNOWN;
} }
@ -4188,6 +4456,9 @@ smart_device * win_smart_interface::autodetect_smart_device(const char * name)
if (type == DEV_USB) if (type == DEV_USB)
return get_usb_device(name, phydrive, logdrive); return get_usb_device(name, phydrive, logdrive);
if (type == DEV_NVME)
return new win10_nvme_device(this, name, "", 0 /* use default nsid */);
return 0; return 0;
} }
@ -4251,7 +4522,7 @@ bool win_smart_interface::scan_smart_devices(smart_device_list & devlist,
char name[20]; char name[20];
if (ata || scsi || sat || usb) { if (ata || scsi || sat || usb || nvme) {
// Scan up to 128 drives and 2 3ware controllers // Scan up to 128 drives and 2 3ware controllers
const int max_raid = 2; const int max_raid = 2;
bool raid_seen[max_raid] = {false, false}; bool raid_seen[max_raid] = {false, false};
@ -4319,6 +4590,13 @@ bool win_smart_interface::scan_smart_devices(smart_device_list & devlist,
dev = new win_scsi_device(this, name, ""); dev = new win_scsi_device(this, name, "");
break; break;
case DEV_NVME:
// STORAGE_QUERY_PROPERTY returned NVMe
if (!nvme)
continue;
dev = new win10_nvme_device(this, name, "", 0 /* use default nsid */);
break;
default: default:
// Unknown type // Unknown type
continue; continue;

View File

@ -3,7 +3,7 @@
* *
* Home page of code is: http://www.smartmontools.org * Home page of code is: http://www.smartmontools.org
* *
* Copyright (C) 2004-14 Christian Franke <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2004-14 Christian Franke
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -20,7 +20,7 @@
#include "daemon_win32.h" #include "daemon_win32.h"
const char * daemon_win32_cpp_cvsid = "$Id: daemon_win32.cpp 4120 2015-08-27 16:12:21Z samm2 $" const char * daemon_win32_cpp_cvsid = "$Id: daemon_win32.cpp 4431 2017-08-08 19:38:15Z chrfranke $"
DAEMON_WIN32_H_CVSID; DAEMON_WIN32_H_CVSID;
#include <stdio.h> #include <stdio.h>

View File

@ -3,7 +3,7 @@
* *
* Home page of code is: http://www.smartmontools.org * Home page of code is: http://www.smartmontools.org
* *
* Copyright (C) 2004-12 Christian Franke <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2004-12 Christian Franke
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -18,7 +18,7 @@
#ifndef DAEMON_WIN32_H #ifndef DAEMON_WIN32_H
#define DAEMON_WIN32_H #define DAEMON_WIN32_H
#define DAEMON_WIN32_H_CVSID "$Id: daemon_win32.h 4120 2015-08-27 16:12:21Z samm2 $" #define DAEMON_WIN32_H_CVSID "$Id: daemon_win32.h 4431 2017-08-08 19:38:15Z chrfranke $"
#include <signal.h> #include <signal.h>

View File

@ -3,7 +3,7 @@
; ;
; Home page of code is: http://www.smartmontools.org ; Home page of code is: http://www.smartmontools.org
; ;
; Copyright (C) 2006-15 Christian Franke ; Copyright (C) 2006-17 Christian Franke
; ;
; This program is free software; you can redistribute it and/or modify ; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by ; it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
; You should have received a copy of the GNU General Public License ; You should have received a copy of the GNU General Public License
; (for example COPYING); If not, see <http://www.gnu.org/licenses/>. ; (for example COPYING); If not, see <http://www.gnu.org/licenses/>.
; ;
; $Id: installer.nsi 4174 2015-11-22 16:19:29Z chrfranke $ ; $Id: installer.nsi 4575 2017-10-29 16:06:18Z chrfranke $
; ;
@ -153,6 +153,8 @@ SectionGroup "!Program files"
MessageBox MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2 "Replace existing configuration file$\n$INSTDIR\bin\smartd.conf ?" /SD IDNO IDYES 0 IDNO +2 MessageBox MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2 "Replace existing configuration file$\n$INSTDIR\bin\smartd.conf ?" /SD IDNO IDYES 0 IDNO +2
File "${INPDIR}\doc\smartd.conf" File "${INPDIR}\doc\smartd.conf"
File "${INPDIR}\bin\smartd_mailer.ps1"
File "${INPDIR}\bin\smartd_mailer.conf.sample.ps1"
File "${INPDIR}\bin\smartd_warning.cmd" File "${INPDIR}\bin\smartd_warning.cmd"
!insertmacro FileExe "bin\wtssendmsg.exe" "" !insertmacro FileExe "bin\wtssendmsg.exe" ""
@ -208,12 +210,15 @@ Section "!Documentation" DOC_SECTION
File "${INPDIR}\doc\checksums??.txt" File "${INPDIR}\doc\checksums??.txt"
!endif !endif
File "${INPDIR}\doc\smartctl.8.html" File "${INPDIR}\doc\smartctl.8.html"
File "${INPDIR}\doc\smartctl.8.txt" File "${INPDIR}\doc\smartctl.8.pdf"
Delete "$INSTDIR\doc\smartctl.8.txt" ; TODO: Remove after smartmontools 6.6
File "${INPDIR}\doc\smartd.8.html" File "${INPDIR}\doc\smartd.8.html"
File "${INPDIR}\doc\smartd.8.txt" File "${INPDIR}\doc\smartd.8.pdf"
Delete "$INSTDIR\doc\smartd.8.txt" ; TODO: Remove after smartmontools 6.6
File "${INPDIR}\doc\smartd.conf" File "${INPDIR}\doc\smartd.conf"
File "${INPDIR}\doc\smartd.conf.5.html" File "${INPDIR}\doc\smartd.conf.5.html"
File "${INPDIR}\doc\smartd.conf.5.txt" File "${INPDIR}\doc\smartd.conf.5.pdf"
Delete "$INSTDIR\doc\smartd.conf.5.txt" ; TODO: Remove after smartmontools 6.6
SectionEnd SectionEnd
@ -240,8 +245,8 @@ Section "Uninstaller" UNINST_SECTION
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "UninstallString" '"$INSTDIR\uninst-smartmontools.exe"' WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "UninstallString" '"$INSTDIR\uninst-smartmontools.exe"'
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "Publisher" "smartmontools.org" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "Publisher" "smartmontools.org"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "URLInfoAbout" "https://www.smartmontools.org/" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "URLInfoAbout" "https://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" "HelpLink" "https://www.smartmontools.org/wiki/Help"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "URLUpdateInfo" "http://builds.smartmontools.org/" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "URLUpdateInfo" "https://builds.smartmontools.org/"
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "NoModify" 1 WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "NoModify" 1
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "NoRepair" 1 WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\smartmontools" "NoRepair" 1
WriteUninstaller "uninst-smartmontools.exe" WriteUninstaller "uninst-smartmontools.exe"
@ -302,9 +307,11 @@ Section "Start Menu Shortcuts" MENU_SECTION
!insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Daemon stop.lnk" "$INSTDIR\bin\runcmdu.exe" "smartd stop" !insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Daemon stop.lnk" "$INSTDIR\bin\runcmdu.exe" "smartd stop"
!insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Do all tests once (-q onecheck).lnk" "$INSTDIR\bin\runcmdu.exe" "smartd -q onecheck" !insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Do all tests once (-q onecheck).lnk" "$INSTDIR\bin\runcmdu.exe" "smartd -q onecheck"
!insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Debug mode (-d).lnk" "$INSTDIR\bin\runcmdu.exe" "smartd -d" !insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Debug mode (-d).lnk" "$INSTDIR\bin\runcmdu.exe" "smartd -d"
!insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\smartd Examples\smartd.conf (edit).lnk" "$EDITOR" "$INSTDIR\bin\smartd.conf" !insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\smartd Examples\smartd.conf (edit).lnk" "$EDITOR" '"$INSTDIR\bin\smartd.conf"'
CreateShortCut "$SMPROGRAMS\smartmontools\smartd Examples\smartd.conf (view).lnk" "$EDITOR" "$INSTDIR\bin\smartd.conf" CreateShortCut "$SMPROGRAMS\smartmontools\smartd Examples\smartd.conf (view).lnk" "$EDITOR" '"$INSTDIR\bin\smartd.conf"'
CreateShortCut "$SMPROGRAMS\smartmontools\smartd Examples\smartd.log (view).lnk" "$EDITOR" "$INSTDIR\bin\smartd.log" CreateShortCut "$SMPROGRAMS\smartmontools\smartd Examples\smartd.log (view).lnk" "$EDITOR" '"$INSTDIR\bin\smartd.log"'
CreateShortCut "$SMPROGRAMS\smartmontools\smartd Examples\smartd_mailer.conf.sample.ps1 (view).lnk" "$EDITOR" '"$INSTDIR\bin\smartd_mailer.conf.sample.ps1"'
!insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\smartd Examples\smartd_mailer.conf.ps1 (create, edit).lnk" "$EDITOR" '"$INSTDIR\bin\smartd_mailer.conf.ps1"'
; smartd service ; smartd service
!insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Service install, eventlog, 30min.lnk" "$INSTDIR\bin\runcmdu.exe" "smartd install" !insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\smartd Examples\Service install, eventlog, 30min.lnk" "$INSTDIR\bin\runcmdu.exe" "smartd install"
@ -322,13 +329,13 @@ Section "Start Menu Shortcuts" MENU_SECTION
CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\smartctl manual page (html).lnk" "$INSTDIR\doc\smartctl.8.html" CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\smartctl manual page (html).lnk" "$INSTDIR\doc\smartctl.8.html"
CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\smartd manual page (html).lnk" "$INSTDIR\doc\smartd.8.html" CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\smartd manual page (html).lnk" "$INSTDIR\doc\smartd.8.html"
CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\smartd.conf manual page (html).lnk" "$INSTDIR\doc\smartd.conf.5.html" CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\smartd.conf manual page (html).lnk" "$INSTDIR\doc\smartd.conf.5.html"
CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\smartctl manual page (txt).lnk" "$INSTDIR\doc\smartctl.8.txt" CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\smartctl manual page (pdf).lnk" "$INSTDIR\doc\smartctl.8.pdf"
CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\smartd manual page (txt).lnk" "$INSTDIR\doc\smartd.8.txt" CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\smartd manual page (pdf).lnk" "$INSTDIR\doc\smartd.8.pdf"
CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\smartd.conf manual page (txt).lnk" "$INSTDIR\doc\smartd.conf.5.txt" CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\smartd.conf manual page (pdf).lnk" "$INSTDIR\doc\smartd.conf.5.pdf"
CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\smartd.conf sample.lnk" "$EDITOR" "$INSTDIR\doc\smartd.conf" CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\smartd.conf sample.lnk" "$EDITOR" '"$INSTDIR\doc\smartd.conf"'
${If} ${FileExists} "$INSTDIR\bin\drivedb.h" ${If} ${FileExists} "$INSTDIR\bin\drivedb.h"
CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\drivedb.h (view).lnk" "$EDITOR" "$INSTDIR\bin\drivedb.h" CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\drivedb.h (view).lnk" "$EDITOR" '"$INSTDIR\bin\drivedb.h"'
!insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\Documentation\drivedb-add.h (create, edit).lnk" "$EDITOR" "$INSTDIR\bin\drivedb-add.h" !insertmacro CreateAdminShortCut "$SMPROGRAMS\smartmontools\Documentation\drivedb-add.h (create, edit).lnk" "$EDITOR" '"$INSTDIR\bin\drivedb-add.h"'
${EndIf} ${EndIf}
CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\ChangeLog.lnk" "$INSTDIR\doc\ChangeLog.txt" CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\ChangeLog.lnk" "$INSTDIR\doc\ChangeLog.txt"
CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\COPYING.lnk" "$INSTDIR\doc\COPYING.txt" CreateShortCut "$SMPROGRAMS\smartmontools\Documentation\COPYING.lnk" "$INSTDIR\doc\COPYING.txt"
@ -337,7 +344,7 @@ Section "Start Menu Shortcuts" MENU_SECTION
; Homepage ; Homepage
CreateShortCut "$SMPROGRAMS\smartmontools\smartmontools Home Page.lnk" "https://www.smartmontools.org/" CreateShortCut "$SMPROGRAMS\smartmontools\smartmontools Home Page.lnk" "https://www.smartmontools.org/"
CreateShortCut "$SMPROGRAMS\smartmontools\smartmontools Daily Builds.lnk" "http://builds.smartmontools.org/" CreateShortCut "$SMPROGRAMS\smartmontools\smartmontools Daily Builds.lnk" "https://builds.smartmontools.org/"
; drivedb.h update ; drivedb.h update
${If} ${FileExists} "$INSTDIR\bin\update-smart-drivedb.exe" ${If} ${FileExists} "$INSTDIR\bin\update-smart-drivedb.exe"
@ -438,19 +445,24 @@ Section "Uninstall"
Delete "$INSTDIR\bin\drivedb-add.h" Delete "$INSTDIR\bin\drivedb-add.h"
${EndIf} ${EndIf}
; Remove smartd_mailer.conf.ps1 file ?
${If} ${FileExists} "$INSTDIR\bin\smartd_mailer.conf.ps1"
MessageBox MB_YESNO|MB_ICONQUESTION|MB_DEFBUTTON2 "Delete mailer configuration file$\n$INSTDIR\bin\smartd_mailer.conf.ps1 ?" /SD IDNO IDYES 0 IDNO +2
Delete "$INSTDIR\bin\smartd_mailer.conf.ps1"
${EndIf}
; Remove files ; Remove files
Delete "$INSTDIR\bin\smartctl.exe" Delete "$INSTDIR\bin\smartctl.exe"
Delete "$INSTDIR\bin\smartctl-nc.exe" Delete "$INSTDIR\bin\smartctl-nc.exe"
Delete "$INSTDIR\bin\smartd.exe" Delete "$INSTDIR\bin\smartd.exe"
Delete "$INSTDIR\bin\smartd_mailer.ps1"
Delete "$INSTDIR\bin\smartd_mailer.conf.sample.ps1"
Delete "$INSTDIR\bin\smartd_warning.cmd" ; TODO: Check for modifications? Delete "$INSTDIR\bin\smartd_warning.cmd" ; TODO: Check for modifications?
Delete "$INSTDIR\bin\drivedb.h" Delete "$INSTDIR\bin\drivedb.h"
Delete "$INSTDIR\bin\drivedb.h.error" Delete "$INSTDIR\bin\drivedb.h.error"
Delete "$INSTDIR\bin\drivedb.h.lastcheck" Delete "$INSTDIR\bin\drivedb.h.lastcheck"
Delete "$INSTDIR\bin\drivedb.h.old" Delete "$INSTDIR\bin\drivedb.h.old"
Delete "$INSTDIR\bin\update-smart-drivedb.exe" Delete "$INSTDIR\bin\update-smart-drivedb.exe"
Delete "$INSTDIR\bin\smartctl-run.bat"
Delete "$INSTDIR\bin\smartd-run.bat"
Delete "$INSTDIR\bin\net-run.bat"
Delete "$INSTDIR\bin\runcmda.exe" Delete "$INSTDIR\bin\runcmda.exe"
Delete "$INSTDIR\bin\runcmda.exe.manifest" ; TODO: Remove after smartmontools 6.5 Delete "$INSTDIR\bin\runcmda.exe.manifest" ; TODO: Remove after smartmontools 6.5
Delete "$INSTDIR\bin\runcmdu.exe" Delete "$INSTDIR\bin\runcmdu.exe"
@ -466,12 +478,15 @@ Section "Uninstall"
Delete "$INSTDIR\doc\TODO.txt" Delete "$INSTDIR\doc\TODO.txt"
Delete "$INSTDIR\doc\checksums*.txt" Delete "$INSTDIR\doc\checksums*.txt"
Delete "$INSTDIR\doc\smartctl.8.html" Delete "$INSTDIR\doc\smartctl.8.html"
Delete "$INSTDIR\doc\smartctl.8.txt" Delete "$INSTDIR\doc\smartctl.8.pdf"
Delete "$INSTDIR\doc\smartctl.8.txt" ; TODO: Remove after smartmontools 6.6
Delete "$INSTDIR\doc\smartd.8.html" Delete "$INSTDIR\doc\smartd.8.html"
Delete "$INSTDIR\doc\smartd.8.txt" Delete "$INSTDIR\doc\smartd.8.pdf"
Delete "$INSTDIR\doc\smartd.8.txt" ; TODO: Remove after smartmontools 6.6
Delete "$INSTDIR\doc\smartd.conf" Delete "$INSTDIR\doc\smartd.conf"
Delete "$INSTDIR\doc\smartd.conf.5.html" Delete "$INSTDIR\doc\smartd.conf.5.html"
Delete "$INSTDIR\doc\smartd.conf.5.txt" Delete "$INSTDIR\doc\smartd.conf.5.pdf"
Delete "$INSTDIR\doc\smartd.conf.5.txt" ; TODO: Remove after smartmontools 6.6
Delete "$INSTDIR\uninst-smartmontools.exe" Delete "$INSTDIR\uninst-smartmontools.exe"
; Remove shortcuts ; Remove shortcuts

View File

@ -3,7 +3,7 @@
* *
* Home page of code is: http://www.smartmontools.org * Home page of code is: http://www.smartmontools.org
* *
* Copyright (C) 2011 Christian Franke <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2011 Christian Franke
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -15,7 +15,7 @@
* *
*/ */
char svnid[] = "$Id: runcmd.c 4120 2015-08-27 16:12:21Z samm2 $"; char svnid[] = "$Id: runcmd.c 4431 2017-08-08 19:38:15Z chrfranke $";
#include <stdio.h> #include <stdio.h>
#include <windows.h> #include <windows.h>

View File

@ -0,0 +1,31 @@
# Sample file for smartd_mailer.conf.ps1
#
# Home page of code is: http://www.smartmontools.org
# $Id: smartd_mailer.conf.sample.ps1 4338 2016-09-07 19:31:28Z chrfranke $
# SMTP Server
$smtpServer = "smtp.domain.local"
# Optional settings [default values in square brackets]
# Sender address ["smartd daemon <root@$hostname>"]
#$from = "Administrator <root@domain.local>"
# SMTP Port [25]
#$port = 587
# Use STARTTLS [$false]
#$useSsl = $true
# SMTP user name []
#$username = "USER"
# Plain text SMTP password []
#$password = "PASSWORD"
# Encrypted SMTP password []
# (embedded newlines, tabs and spaces are ignored)
#$passwordEnc = "
# 0123456789abcdef...
# ...
#"

View File

@ -0,0 +1,96 @@
#
# smartd mailer script
#
# Home page of code is: http://www.smartmontools.org
#
# Copyright (C) 2016 Christian Franke
#
# 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/>.
#
# $Id: smartd_mailer.ps1 4338 2016-09-07 19:31:28Z chrfranke $
#
$ErrorActionPreference = "Stop"
# Parse command line and check environment
$dryrun = $false
if (($args.Count -eq 1) -and ($args[0] -eq "--dryrun")) {
$dryrun = $true
}
$toCsv = $env:SMARTD_ADDRCSV
$subject = $env:SMARTD_SUBJECT
$file = $env:SMARTD_FULLMSGFILE
if (!((($args.Count -eq 0) -or $dryrun) -and $toCsv -and $subject -and $file)) {
echo `
"smartd mailer script
Usage:
set SMARTD_ADDRCSV='Comma separated mail addresses'
set SMARTD_SUBJECT='Mail Subject'
set SMARTD_FULLMSGFILE='X:\PATH\TO\Message.txt'
.\$($MyInvocation.MyCommand.Name) [--dryrun]
"
exit 1
}
# Set default sender address
if ($env:COMPUTERNAME -match '^[-_A-Za-z0-9]+$') {
$hostname = $env:COMPUTERNAME.ToLower()
} else {
$hostname = "unknown"
}
if ($env:USERDNSDOMAIN -match '^[-._A-Za-z0-9]+$') {
$hostname += ".$($env:USERDNSDOMAIN.ToLower())"
} elseif ( ($env:USERDOMAIN -match '^[-_A-Za-z0-9]+$') `
-and ($env:USERDOMAIN -ne $env:COMPUTERNAME) ) {
$hostname += ".$($env:USERDOMAIN.ToLower()).local"
} else {
$hostname += ".local"
}
$from = "smartd daemon <root@$hostname>"
# Read configuration
. .\smartd_mailer.conf.ps1
# Create parameters
$to = $toCsv.Split(",")
$body = Get-Content -Path $file | Out-String
$parm = @{
SmtpServer = $smtpServer; From = $from; To = $to
Subject = $subject; Body = $body
}
if ($port) {
$parm += @{ Port = $port }
}
if ($useSsl) {
$parm += @{ useSsl = $true }
}
if ($username -and ($password -or $passwordEnc)) {
if (!$passwordEnc) {
$secureString = ConvertTo-SecureString -String $password -AsPlainText -Force
} else {
$passwordEnc = $passwordEnc -replace '[\r\n\t ]',''
$secureString = ConvertTo-SecureString -String $passwordEnc
}
$credential = New-Object -Typename System.Management.Automation.PSCredential -Argumentlist $username,$secureString
$parm += @{ Credential = $credential }
}
# Send mail
if ($dryrun) {
echo "Send-MailMessage" @parm
} else {
Send-MailMessage @parm
}

View File

@ -1,37 +0,0 @@
//
// os_win32/smartd_res.rc.in
//
// $Id: smartd_res.rc.in 3878 2014-03-03 18:45:21Z chrfranke $
//
1 VERSIONINFO
FILEVERSION @BINARY_VERSION@
PRODUCTVERSION @BINARY_VERSION@
FILEFLAGSMASK 0x0
FILEFLAGS 0x0
FILEOS 0x4 // VOS__WINDOWS32
FILETYPE 0x1 // VFT_APP
FILESUBTYPE 0x0
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "04090000"
BEGIN
VALUE "CompanyName", "www.smartmontools.org"
VALUE "FileDescription", "SMART Disk Monitoring Daemon"
VALUE "FileVersion", "@TEXT_VERSION@"
VALUE "InternalName", "smartd"
VALUE "LegalCopyright", "(C) 2002-@YY@, Bruce Allen, Christian Franke, www.smartmontools.org"
VALUE "OriginalFilename", "smartd.exe"
VALUE "ProductName", "smartmontools"
VALUE "ProductVersion", "@TEXT_VERSION@"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0409, 0x0000
END
END
// eventlog MESSAGETABLE for syslog() emulation
#include "syslogevt.rc"

View File

@ -2,7 +2,9 @@
:: ::
:: smartd warning script :: smartd warning script
:: ::
:: Copyright (C) 2012-13 Christian Franke <smartmontools-support@lists.sourceforge.net> :: Home page of code is: http://www.smartmontools.org
::
:: Copyright (C) 2012-17 Christian Franke
:: ::
:: This program is free software; you can redistribute it and/or modify :: This program is free software; you can redistribute it and/or modify
:: it under the terms of the GNU General Public License as published by :: it under the terms of the GNU General Public License as published by
@ -12,24 +14,32 @@
:: You should have received a copy of the GNU General Public License :: You should have received a copy of the GNU General Public License
:: (for example COPYING); If not, see <http://www.gnu.org/licenses/>. :: (for example COPYING); If not, see <http://www.gnu.org/licenses/>.
:: ::
:: $Id: smartd_warning.cmd 3816 2013-06-09 16:16:11Z chrfranke $ :: $Id: smartd_warning.cmd 4569 2017-10-25 20:13:11Z chrfranke $
:: ::
verify other 2>nul
setlocal enableextensions enabledelayedexpansion
if errorlevel 1 goto UNSUPPORTED
set err= set err=
:: Change to script directory (not necessary if run from smartd service)
cd /d %~dp0
if errorlevel 1 goto ERROR
:: Parse options :: Parse options
set dryrun= set dryrun=
if "%1" == "--dryrun" ( if "%1" == "--dryrun" (
set dryrun=t set dryrun=--dryrun
shift shift
) )
if not "!dryrun!" == "" echo cd /d !cd!
if not "%1" == "" ( if not "%1" == "" (
echo smartd warning message script echo smartd warning message script
echo. echo.
echo Usage: echo Usage:
echo set SMARTD_MAILER='Path to external script, empty for "blat"' echo set SMARTD_MAILER='Path to external script, empty for "blat"'
echo set SMARTD_ADDRESS='Space separated mail adresses, empty if none' echo set SMARTD_ADDRESS='Space separated mail addresses, empty if none'
echo set SMARTD_MESSAGE='Error Message' echo set SMARTD_MESSAGE='Error Message'
echo set SMARTD_FAILTYPE='Type of failure, "EMailTest" for tests' echo set SMARTD_FAILTYPE='Type of failure, "EMailTest" for tests'
echo set SMARTD_TFIRST='Date of first message sent, empty if none' echo set SMARTD_TFIRST='Date of first message sent, empty if none'
@ -42,118 +52,157 @@ if not "%1" == "" (
echo :: set SMARTD_DEVICETYPE='Device type from -d directive, "auto" if none' echo :: set SMARTD_DEVICETYPE='Device type from -d directive, "auto" if none'
echo smartd_warning.cmd [--dryrun] echo smartd_warning.cmd [--dryrun]
goto EOF goto ERROR
) )
if "%SMARTD_ADDRESS%%SMARTD_MAILER%" == "" ( if "!SMARTD_ADDRESS!!SMARTD_MAILER!" == "" (
echo smartd_warning.cmd: SMARTD_ADDRESS or SMARTD_MAILER must be set echo smartd_warning.cmd: SMARTD_ADDRESS or SMARTD_MAILER must be set
goto EOF goto ERROR
) )
:: USERDNSDOMAIN may be unset if running as service :: USERDNSDOMAIN may be unset if running as service
if "%USERDNSDOMAIN%" == "" ( if "!USERDNSDOMAIN!" == "" (
for /f "delims== tokens=2 usebackq" %%d in (`WMIC PATH Win32_Computersystem WHERE "PartOfDomain=TRUE" GET Domain /VALUE 2^>nul ^| find "Domain=" 2^>nul`) do set USERDNSDOMAIN=%%~d for /f "delims== tokens=2 usebackq" %%d in (`wmic PATH Win32_Computersystem WHERE "PartOfDomain=TRUE" GET Domain /VALUE ^<nul 2^>nul`) do set USERDNSDOMAIN=%%~d
) )
:: Remove possible trailing \r appended by above command (requires %...%)
set USERDNSDOMAIN=%USERDNSDOMAIN%
:: Format subject :: Format subject
set SMARTD_SUBJECT=SMART error (%SMARTD_FAILTYPE%) detected on host: %COMPUTERNAME% set SMARTD_SUBJECT=SMART error (!SMARTD_FAILTYPE!) detected on host: !COMPUTERNAME!
:: Temp file for message :: Temp file for message
if not "%TMP%" == "" set SMARTD_FULLMSGFILE=%TMP%\smartd_warning-%RANDOM%.txt if not "!TMP!" == "" set SMARTD_FULLMSGFILE=!TMP!\smartd_warning-!RANDOM!.txt
if "%TMP%" == "" set SMARTD_FULLMSGFILE=smartd_warning-%RANDOM%.txt if "!TMP!" == "" set SMARTD_FULLMSGFILE=smartd_warning-!RANDOM!.txt
:: Format message :: Format message
( (
echo This message was generated by the smartd service running on: echo This message was generated by the smartd service running on:
echo. echo.
echo. host name: %COMPUTERNAME% echo. host name: !COMPUTERNAME!
if not "%USERDNSDOMAIN%" == "" echo. DNS domain: %USERDNSDOMAIN% if not "!USERDNSDOMAIN!" == "" echo. DNS domain: !USERDNSDOMAIN!
if "%USERDNSDOMAIN%" == "" echo. DNS domain: [Empty] if "!USERDNSDOMAIN!" == "" echo. DNS domain: [Empty]
if not "%USERDOMAIN%" == "" echo. Win domain: %USERDOMAIN% if not "!USERDOMAIN!" == "" echo. Win domain: !USERDOMAIN!
echo. echo.
echo The following warning/error was logged by the smartd service: echo The following warning/error was logged by the smartd service:
echo. echo.
:: SMARTD_MESSAGE and SMARTD_DEVICEINFO may contain parentheses if not "!SMARTD_MESSAGE!" == "" echo !SMARTD_MESSAGE!
for %%m in ("%SMARTD_MESSAGE%") do echo.%%~m if "!SMARTD_MESSAGE!" == "" echo [SMARTD_MESSAGE]
echo. echo.
echo Device info: echo Device info:
for %%m in ("%SMARTD_DEVICEINFO%") do echo.%%~m if not "!SMARTD_DEVICEINFO!" == "" echo !SMARTD_DEVICEINFO!
set m= if "!SMARTD_DEVICEINFO!" == "" echo [SMARTD_DEVICEINFO]
echo. echo.
echo For details see the event log or log file of smartd. echo For details see the event log or log file of smartd.
if not "%SMARTD_FAILTYPE%" == "EmailTest" ( if not "!SMARTD_FAILTYPE!" == "EmailTest" (
echo. echo.
echo You can also use the smartctl utility for further investigation. echo You can also use the smartctl utility for further investigation.
if not "%SMARTD_PREVCNT%" == "0" echo The original message about this issue was sent at %SMARTD_TFIRST% if not "!SMARTD_PREVCNT!" == "0" echo The original message about this issue was sent at !SMARTD_TFIRST!
if "%SMARTD_NEXTDAYS%" == "" ( if "!SMARTD_NEXTDAYS!" == "" (
echo No additional messages about this problem will be sent. echo No additional messages about this problem will be sent.
) else ( if "%SMARTD_NEXTDAYS%" == "1" ( ) else ( if "!SMARTD_NEXTDAYS!" == "1" (
echo Another message will be sent in 24 hours if the problem persists. echo Another message will be sent in 24 hours if the problem persists.
) else ( ) else (
echo Another message will be sent in %SMARTD_NEXTDAYS% days if the problem persists. echo Another message will be sent in !SMARTD_NEXTDAYS! days if the problem persists.
)) ))
) )
) > "%SMARTD_FULLMSGFILE%" ) > "!SMARTD_FULLMSGFILE!"
if errorlevel 1 goto ERROR
if not "%dryrun%" == "" ( if not "!dryrun!" == "" (
echo %SMARTD_FULLMSGFILE%: echo !SMARTD_FULLMSGFILE!:
type "%SMARTD_FULLMSGFILE%" type "!SMARTD_FULLMSGFILE!"
echo --EOF-- echo --EOF--
) )
:: Check first address :: Check first address
set first= set first=
for /F "tokens=1*" %%a in ("%SMARTD_ADDRESS%") do (set first=%%a) for /f "tokens=1*" %%a in ("!SMARTD_ADDRESS!") do (set first=%%a)
set wtssend= set wtssend=
if "%first%" == "console" set wtssend=-c if "!first!" == "console" set wtssend=-c
if "%first%" == "active" set wtssend=-a if "!first!" == "active" set wtssend=-a
if "%first%" == "connected" set wtssend=-s if "!first!" == "connected" set wtssend=-s
set first=
if not "%wtssend%" == "" ( if not "!wtssend!" == "" (
:: Show Message box(es) via WTSSendMessage() :: Show Message box(es) via WTSSendMessage()
if not "%dryrun%" == "" ( if not "!dryrun!" == "" (
echo call wtssendmsg %wtssend% "%SMARTD_SUBJECT%" - ^< "%SMARTD_FULLMSGFILE%" echo call .\wtssendmsg !wtssend! "!SMARTD_SUBJECT!" - ^< "!SMARTD_FULLMSGFILE!"
) else ( ) else (
call wtssendmsg %wtssend% "%SMARTD_SUBJECT%" - < "%SMARTD_FULLMSGFILE%" call .\wtssendmsg !wtssend! "!SMARTD_SUBJECT!" - < "!SMARTD_FULLMSGFILE!"
if errorlevel 1 set err=t if errorlevel 1 set err=t
) )
:: Remove first address :: Remove first address
for /F "tokens=1*" %%a in ("%SMARTD_ADDRESS%") do (set SMARTD_ADDRESS=%%b) for /f "tokens=1*" %%a in ("!SMARTD_ADDRESS!") do (set SMARTD_ADDRESS=%%b)
) )
set wtssend=
:: Make comma separated address list :: Make comma separated address list
set SMARTD_ADDRCSV= set SMARTD_ADDRCSV=
if not "%SMARTD_ADDRESS%" == "" set SMARTD_ADDRCSV=%SMARTD_ADDRESS: =,% if not "!SMARTD_ADDRESS!" == "" set SMARTD_ADDRCSV=!SMARTD_ADDRESS: =,!
:: Use blat mailer by default :: Default mailer is smartd_mailer.ps1 (if configured) or blat.exe
if not "%SMARTD_ADDRESS%" == "" if "%SMARTD_MAILER%" == "" set SMARTD_MAILER=blat if not "!SMARTD_ADDRESS!" == "" if "!SMARTD_MAILER!" == "" (
if not exist smartd_mailer.conf.ps1 set SMARTD_MAILER=blat
)
:: Get mailer extension
set ext=
for /f "delims=" %%f in ("!SMARTD_MAILER!") do (set ext=%%~xf)
:: Send mail or run command :: Send mail or run command
if not "%SMARTD_ADDRCSV%" == "" ( if "!ext!" == ".ps1" (
:: Run PowerShell script
if not "!dryrun!" == "" (
set esc=^^
echo PowerShell -NoProfile -ExecutionPolicy Bypass -Command !esc!^& '!SMARTD_MAILER!' ^<nul
) else (
PowerShell -NoProfile -ExecutionPolicy Bypass -Command ^& '!SMARTD_MAILER!' <nul
if errorlevel 1 set err=t
)
) else ( if not "!SMARTD_ADDRCSV!" == "" (
:: Send mail :: Send mail
if not "%dryrun%" == "" ( if "!SMARTD_MAILER!" == "" (
echo call "%SMARTD_MAILER%" - -q -subject "%SMARTD_SUBJECT%" -to "%SMARTD_ADDRCSV%" ^< "%SMARTD_FULLMSGFILE%"
:: Use smartd_mailer.ps1
if not "!dryrun!" == "" (
echo PowerShell -NoProfile -ExecutionPolicy Bypass -Command .\smartd_mailer.ps1 ^<nul
echo ==========
)
PowerShell -NoProfile -ExecutionPolicy Bypass -Command .\smartd_mailer.ps1 !dryrun! <nul
if errorlevel 1 set err=t
if not "!dryrun!" == "" echo ==========
) else ( ) else (
call "%SMARTD_MAILER%" - -q -subject "%SMARTD_SUBJECT%" -to "%SMARTD_ADDRCSV%" < "%SMARTD_FULLMSGFILE%"
:: Use blat mailer or compatible
if not "!dryrun!" == "" (
echo call "!SMARTD_MAILER!" - -q -subject "!SMARTD_SUBJECT!" -to "!SMARTD_ADDRCSV!" ^< "!SMARTD_FULLMSGFILE!"
) else (
call "!SMARTD_MAILER!" - -q -subject "!SMARTD_SUBJECT!" -to "!SMARTD_ADDRCSV!" < "!SMARTD_FULLMSGFILE!"
if errorlevel 1 set err=t if errorlevel 1 set err=t
) )
) else ( if not "%SMARTD_MAILER%" == "" ( )
) else ( if not "!SMARTD_MAILER!" == "" (
:: Run command :: Run command
if not "%dryrun%" == "" ( if not "!dryrun!" == "" (
echo call "%SMARTD_MAILER%" ^<nul echo call "!SMARTD_MAILER!" ^<nul
) else ( ) else (
call "%SMARTD_MAILER%" <nul call "!SMARTD_MAILER!" <nul
if errorlevel 1 set err=t if errorlevel 1 set err=t
) )
)) )))
del "%SMARTD_FULLMSGFILE%" >nul 2>nul del "!SMARTD_FULLMSGFILE!" >nul 2>nul
:EOF if not "!err!" == "" goto ERROR
if not "%err%" == "" goto ERROR 2>nul endlocal
exit /b 0
:ERROR
endlocal
exit /b 1

View File

@ -3,7 +3,7 @@
* *
* Home page of code is: http://www.smartmontools.org * Home page of code is: http://www.smartmontools.org
* *
* Copyright (C) 2004-8 Christian Franke <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2004-8 Christian Franke
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -19,7 +19,7 @@
#ifndef SYSLOG_H #ifndef SYSLOG_H
#define SYSLOG_H #define SYSLOG_H
#define SYSLOG_H_CVSID "$Id: syslog.h 4120 2015-08-27 16:12:21Z samm2 $\n" #define SYSLOG_H_CVSID "$Id: syslog.h 4431 2017-08-08 19:38:15Z chrfranke $\n"
#include <stdarg.h> #include <stdarg.h>

View File

@ -3,7 +3,7 @@
; * ; *
; * Home page of code is: http://www.smartmontools.org ; * Home page of code is: http://www.smartmontools.org
; * ; *
; * Copyright (C) 2004-10 Christian Franke <smartmontools-support@lists.sourceforge.net> ; * Copyright (C) 2004-10 Christian Franke
; * ; *
; * This program is free software; you can redistribute it and/or modify ; * This program is free software; you can redistribute it and/or modify
; * it under the terms of the GNU General Public License as published by ; * it under the terms of the GNU General Public License as published by
@ -16,7 +16,7 @@
; * ; *
; */ ; */
; ;
;// $Id: syslogevt.mc 4120 2015-08-27 16:12:21Z samm2 $ ;// $Id: syslogevt.mc 4431 2017-08-08 19:38:15Z chrfranke $
; ;
;// Use message compiler "mc" or "windmc" to generate ;// Use message compiler "mc" or "windmc" to generate
;// syslogevt.rc, syslogevt.h, msg00001.bin ;// syslogevt.rc, syslogevt.h, msg00001.bin

View File

@ -3,7 +3,7 @@
; ;
; Home page of code is: http://www.smartmontools.org ; Home page of code is: http://www.smartmontools.org
; ;
; Copyright (C) 2011-13 Christian Franke <smartmontools-support@lists.sourceforge.net> ; Copyright (C) 2011-13 Christian Franke
; ;
; This program is free software; you can redistribute it and/or modify ; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by ; it under the terms of the GNU General Public License as published by
@ -13,7 +13,7 @@
; You should have received a copy of the GNU General Public License ; You should have received a copy of the GNU General Public License
; (for example COPYING); If not, see <http://www.gnu.org/licenses/>. ; (for example COPYING); If not, see <http://www.gnu.org/licenses/>.
; ;
; $Id: update-smart-drivedb.nsi 4120 2015-08-27 16:12:21Z samm2 $ ; $Id: update-smart-drivedb.nsi 4431 2017-08-08 19:38:15Z chrfranke $
; ;

View File

@ -1,83 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{11A4B619-D97B-499F-AF17-CF9F80BF70E8}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>runcmd</RootNamespace>
<ProjectName>runcmd</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<IntDir>$(Configuration)\$(ProjectName).tmp\</IntDir>
<TargetName>$(ProjectName)u</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<IntDir>$(Configuration)\$(ProjectName).tmp\</IntDir>
<TargetName>$(ProjectName)u</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\runcmd.c" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,296 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{3AFEDCDD-D289-4543-A91D-EFBA6C710247}</ProjectGuid>
<RootNamespace>smartctl</RootNamespace>
<Keyword>Win32Proj</Keyword>
<ProjectName>smartctl</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\$(ProjectName).tmp\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\$(ProjectName).tmp\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.;..\..\getopt;..\..\regex;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_DEBUG;__func__=__FUNCTION__;HAVE_CONFIG_H;_USE_32BIT_TIME_T;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<DisableSpecificWarnings>4250</DisableSpecificWarnings>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>.;..\..\getopt;..\..\regex;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>NDEBUG;__func__=__FUNCTION__;HAVE_CONFIG_H;_USE_32BIT_TIME_T;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<DisableSpecificWarnings>4250</DisableSpecificWarnings>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\ataidentify.cpp" />
<ClCompile Include="..\..\dev_areca.cpp" />
<ClCompile Include="..\..\nvmecmds.cpp" />
<ClCompile Include="..\..\nvmeprint.cpp" />
<ClCompile Include="..\daemon_win32.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\syslog_win32.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\wmiquery.cpp" />
<ClCompile Include="..\..\regex\regcomp.c">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\regex\regex.c" />
<ClCompile Include="..\..\regex\regex_internal.c">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\regex\regexec.c">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\getopt\getopt.c" />
<ClCompile Include="..\..\getopt\getopt1.c" />
<ClCompile Include="..\..\atacmdnames.cpp" />
<ClCompile Include="..\..\atacmds.cpp" />
<ClCompile Include="..\..\ataprint.cpp" />
<ClCompile Include="..\..\cciss.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\dev_ata_cmd_set.cpp" />
<ClCompile Include="..\..\dev_interface.cpp" />
<ClCompile Include="..\..\dev_legacy.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\knowndrives.cpp" />
<ClCompile Include="..\..\os_darwin.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\os_freebsd.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\os_generic.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\os_linux.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\os_netbsd.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\os_openbsd.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\os_os2.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\os_qnxnto.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\os_solaris.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\os_win32.cpp" />
<ClCompile Include="..\..\scsiata.cpp" />
<ClCompile Include="..\..\scsicmds.cpp" />
<ClCompile Include="..\..\scsiprint.cpp" />
<ClCompile Include="..\..\smartctl.cpp" />
<ClCompile Include="..\..\smartd.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\utility.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\aacraid.h" />
<ClInclude Include="..\..\ataidentify.h" />
<ClInclude Include="..\..\dev_areca.h" />
<ClInclude Include="..\..\nvmecmds.h" />
<ClInclude Include="..\..\nvmeprint.h" />
<ClInclude Include="config.h" />
<ClInclude Include="svnversion.h" />
<CustomBuildStep Include="..\daemon_win32.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<CustomBuildStep Include="..\syslog.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<ClInclude Include="..\wbemcli_small.h" />
<ClInclude Include="..\wmiquery.h" />
<ClInclude Include="..\..\regex\regex.h" />
<ClInclude Include="..\..\regex\regex_internal.h" />
<ClInclude Include="..\..\getopt\getopt.h" />
<ClInclude Include="..\..\atacmdnames.h" />
<ClInclude Include="..\..\atacmds.h" />
<ClInclude Include="..\..\ataprint.h" />
<CustomBuildStep Include="..\..\cciss.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<ClInclude Include="..\..\cissio_freebsd.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClInclude>
<ClInclude Include="..\..\csmisas.h" />
<ClInclude Include="..\..\dev_ata_cmd_set.h" />
<ClInclude Include="..\..\dev_interface.h" />
<ClInclude Include="..\..\dev_tunnelled.h" />
<ClInclude Include="..\..\drivedb.h" />
<ClInclude Include="..\..\int64.h" />
<ClInclude Include="..\..\knowndrives.h" />
<CustomBuildStep Include="..\..\megaraid.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<CustomBuildStep Include="..\..\os_darwin.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<CustomBuildStep Include="..\..\os_freebsd.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<CustomBuildStep Include="..\..\os_generic.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<CustomBuildStep Include="..\..\os_linux.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<CustomBuildStep Include="..\..\os_netbsd.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<CustomBuildStep Include="..\..\os_openbsd.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<CustomBuildStep Include="..\..\os_os2.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<CustomBuildStep Include="..\..\os_qnxnto.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<CustomBuildStep Include="..\..\os_solaris.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<ClInclude Include="..\..\scsicmds.h" />
<ClInclude Include="..\..\scsiprint.h" />
<ClInclude Include="..\..\smartctl.h" />
<ClInclude Include="..\..\utility.h" />
</ItemGroup>
<ItemGroup>
<None Include="..\..\smartd_warning.sh.in" />
<None Include="..\installer.nsi" />
<None Include="..\smartctl_res.rc.in" />
<None Include="..\smartd_res.rc.in" />
<None Include="..\smartd_warning.cmd" />
<None Include="..\syslogevt.mc" />
<None Include="..\update-smart-drivedb.nsi" />
<None Include="..\..\AUTHORS" />
<None Include="..\..\autogen.sh" />
<None Include="..\..\ChangeLog" />
<None Include="..\..\config.h.in" />
<None Include="..\..\configure.ac" />
<None Include="..\..\do_release" />
<None Include="..\..\Doxyfile" />
<None Include="..\..\INSTALL" />
<None Include="..\..\Makefile.am" />
<None Include="..\..\NEWS" />
<None Include="..\..\README" />
<None Include="..\..\smartctl.8.in" />
<None Include="..\..\smartd.8.in" />
<None Include="..\..\smartd.conf.5.in" />
<None Include="..\..\smartd.initd.in" />
<None Include="..\..\TODO" />
<None Include="..\..\update-smart-drivedb.in" />
<None Include="..\..\WARNINGS" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="smartctl_res.rc" />
<ResourceCompile Include="smartd_res.rc">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ResourceCompile>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,176 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="os_win32">
<UniqueIdentifier>{9321e988-dd03-496d-9933-7c8b235a46bf}</UniqueIdentifier>
</Filter>
<Filter Include="regex">
<UniqueIdentifier>{bfbfd4ea-fae3-45ec-9cfb-c5424218c47c}</UniqueIdentifier>
</Filter>
<Filter Include="getopt">
<UniqueIdentifier>{8ff0bf5f-c96e-45c3-bcb4-7450cecfa0d4}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\daemon_win32.cpp">
<Filter>os_win32</Filter>
</ClCompile>
<ClCompile Include="..\syslog_win32.cpp">
<Filter>os_win32</Filter>
</ClCompile>
<ClCompile Include="..\wmiquery.cpp">
<Filter>os_win32</Filter>
</ClCompile>
<ClCompile Include="..\..\regex\regcomp.c">
<Filter>regex</Filter>
</ClCompile>
<ClCompile Include="..\..\regex\regex.c">
<Filter>regex</Filter>
</ClCompile>
<ClCompile Include="..\..\regex\regex_internal.c">
<Filter>regex</Filter>
</ClCompile>
<ClCompile Include="..\..\regex\regexec.c">
<Filter>regex</Filter>
</ClCompile>
<ClCompile Include="..\..\getopt\getopt.c">
<Filter>getopt</Filter>
</ClCompile>
<ClCompile Include="..\..\getopt\getopt1.c">
<Filter>getopt</Filter>
</ClCompile>
<ClCompile Include="..\..\atacmdnames.cpp" />
<ClCompile Include="..\..\atacmds.cpp" />
<ClCompile Include="..\..\ataprint.cpp" />
<ClCompile Include="..\..\cciss.cpp" />
<ClCompile Include="..\..\dev_ata_cmd_set.cpp" />
<ClCompile Include="..\..\dev_interface.cpp" />
<ClCompile Include="..\..\dev_legacy.cpp" />
<ClCompile Include="..\..\knowndrives.cpp" />
<ClCompile Include="..\..\os_darwin.cpp" />
<ClCompile Include="..\..\os_freebsd.cpp" />
<ClCompile Include="..\..\os_generic.cpp" />
<ClCompile Include="..\..\os_linux.cpp" />
<ClCompile Include="..\..\os_netbsd.cpp" />
<ClCompile Include="..\..\os_openbsd.cpp" />
<ClCompile Include="..\..\os_os2.cpp" />
<ClCompile Include="..\..\os_qnxnto.cpp" />
<ClCompile Include="..\..\os_solaris.cpp" />
<ClCompile Include="..\..\os_win32.cpp" />
<ClCompile Include="..\..\scsiata.cpp" />
<ClCompile Include="..\..\scsicmds.cpp" />
<ClCompile Include="..\..\scsiprint.cpp" />
<ClCompile Include="..\..\smartctl.cpp" />
<ClCompile Include="..\..\smartd.cpp" />
<ClCompile Include="..\..\utility.cpp" />
<ClCompile Include="..\..\ataidentify.cpp" />
<ClCompile Include="..\..\dev_areca.cpp" />
<ClCompile Include="..\..\nvmecmds.cpp" />
<ClCompile Include="..\..\nvmeprint.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\wbemcli_small.h">
<Filter>os_win32</Filter>
</ClInclude>
<ClInclude Include="..\wmiquery.h">
<Filter>os_win32</Filter>
</ClInclude>
<ClInclude Include="..\..\regex\regex.h">
<Filter>regex</Filter>
</ClInclude>
<ClInclude Include="..\..\regex\regex_internal.h">
<Filter>regex</Filter>
</ClInclude>
<ClInclude Include="..\..\getopt\getopt.h">
<Filter>getopt</Filter>
</ClInclude>
<ClInclude Include="..\..\aacraid.h" />
<ClInclude Include="..\..\atacmdnames.h" />
<ClInclude Include="..\..\atacmds.h" />
<ClInclude Include="..\..\ataprint.h" />
<ClInclude Include="..\..\cissio_freebsd.h" />
<ClInclude Include="..\..\csmisas.h" />
<ClInclude Include="..\..\dev_ata_cmd_set.h" />
<ClInclude Include="..\..\dev_interface.h" />
<ClInclude Include="..\..\dev_tunnelled.h" />
<ClInclude Include="..\..\drivedb.h" />
<ClInclude Include="..\..\int64.h" />
<ClInclude Include="..\..\knowndrives.h" />
<ClInclude Include="..\..\scsicmds.h" />
<ClInclude Include="..\..\scsiprint.h" />
<ClInclude Include="..\..\smartctl.h" />
<ClInclude Include="..\..\utility.h" />
<ClInclude Include="..\..\ataidentify.h" />
<ClInclude Include="..\..\dev_areca.h" />
<ClInclude Include="config.h" />
<ClInclude Include="svnversion.h" />
<ClInclude Include="..\..\nvmecmds.h" />
<ClInclude Include="..\..\nvmeprint.h" />
</ItemGroup>
<ItemGroup>
<None Include="..\installer.nsi">
<Filter>os_win32</Filter>
</None>
<None Include="..\update-smart-drivedb.nsi">
<Filter>os_win32</Filter>
</None>
<None Include="..\..\AUTHORS" />
<None Include="..\..\autogen.sh" />
<None Include="..\..\ChangeLog" />
<None Include="..\..\config.h.in" />
<None Include="..\..\configure.ac" />
<None Include="..\..\do_release" />
<None Include="..\..\Doxyfile" />
<None Include="..\..\INSTALL" />
<None Include="..\..\Makefile.am" />
<None Include="..\..\NEWS" />
<None Include="..\..\README" />
<None Include="..\..\smartctl.8.in" />
<None Include="..\..\smartd.8.in" />
<None Include="..\..\smartd.conf.5.in" />
<None Include="..\..\smartd.initd.in" />
<None Include="..\..\TODO" />
<None Include="..\..\update-smart-drivedb.in" />
<None Include="..\..\WARNINGS" />
<None Include="..\smartd_warning.cmd">
<Filter>os_win32</Filter>
</None>
<None Include="..\..\smartd_warning.sh.in" />
<None Include="..\smartctl_res.rc.in">
<Filter>os_win32</Filter>
</None>
<None Include="..\smartd_res.rc.in">
<Filter>os_win32</Filter>
</None>
<None Include="..\syslogevt.mc">
<Filter>os_win32</Filter>
</None>
</ItemGroup>
<ItemGroup>
<CustomBuildStep Include="..\daemon_win32.h">
<Filter>os_win32</Filter>
</CustomBuildStep>
<CustomBuildStep Include="..\syslog.h">
<Filter>os_win32</Filter>
</CustomBuildStep>
<CustomBuildStep Include="..\..\cciss.h" />
<CustomBuildStep Include="..\..\megaraid.h" />
<CustomBuildStep Include="..\..\os_darwin.h" />
<CustomBuildStep Include="..\..\os_freebsd.h" />
<CustomBuildStep Include="..\..\os_generic.h" />
<CustomBuildStep Include="..\..\os_linux.h" />
<CustomBuildStep Include="..\..\os_netbsd.h" />
<CustomBuildStep Include="..\..\os_openbsd.h" />
<CustomBuildStep Include="..\..\os_os2.h" />
<CustomBuildStep Include="..\..\os_qnxnto.h" />
<CustomBuildStep Include="..\..\os_solaris.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="smartctl_res.rc">
<Filter>os_win32</Filter>
</ResourceCompile>
<ResourceCompile Include="smartd_res.rc">
<Filter>os_win32</Filter>
</ResourceCompile>
</ItemGroup>
</Project>

View File

@ -1,322 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{C0762191-C2AC-40B6-A2EB-F1658BBDC4C6}</ProjectGuid>
<RootNamespace>smartd</RootNamespace>
<Keyword>Win32Proj</Keyword>
<ProjectName>smartd</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\$(ProjectName).tmp\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\$(ProjectName).tmp\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.;..;..\..\getopt;..\..\regex;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_DEBUG;HAVE_CONFIG_H;_USE_32BIT_TIME_T;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<DisableSpecificWarnings>4250</DisableSpecificWarnings>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<AdditionalIncludeDirectories>.;..;..\..\getopt;..\..\regex;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>NDEBUG;HAVE_CONFIG_H;_USE_32BIT_TIME_T;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<DisableSpecificWarnings>4250</DisableSpecificWarnings>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\ataidentify.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\dev_areca.cpp" />
<ClCompile Include="..\..\nvmecmds.cpp" />
<ClCompile Include="..\..\nvmeprint.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\daemon_win32.cpp" />
<ClCompile Include="..\syslog_win32.cpp" />
<ClCompile Include="..\wmiquery.cpp" />
<ClCompile Include="..\..\regex\regcomp.c">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\regex\regex.c" />
<ClCompile Include="..\..\regex\regex_internal.c">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\regex\regexec.c">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\getopt\getopt.c" />
<ClCompile Include="..\..\getopt\getopt1.c" />
<ClCompile Include="..\..\atacmdnames.cpp" />
<ClCompile Include="..\..\atacmds.cpp" />
<ClCompile Include="..\..\ataprint.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\cciss.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\dev_ata_cmd_set.cpp" />
<ClCompile Include="..\..\dev_interface.cpp" />
<ClCompile Include="..\..\dev_legacy.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\knowndrives.cpp" />
<ClCompile Include="..\..\os_darwin.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\os_freebsd.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\os_generic.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\os_linux.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\os_netbsd.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\os_openbsd.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\os_os2.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\os_qnxnto.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\os_solaris.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\os_win32.cpp" />
<ClCompile Include="..\..\scsiata.cpp" />
<ClCompile Include="..\..\scsicmds.cpp" />
<ClCompile Include="..\..\scsiprint.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\smartctl.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\..\smartd.cpp" />
<ClCompile Include="..\..\utility.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\aacraid.h" />
<ClInclude Include="..\..\ataidentify.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClInclude>
<ClInclude Include="..\..\dev_areca.h" />
<ClInclude Include="..\..\nvmecmds.h" />
<ClInclude Include="..\..\nvmeprint.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClInclude>
<ClInclude Include="..\daemon_win32.h" />
<ClInclude Include="..\syslog.h" />
<ClInclude Include="..\wbemcli_small.h" />
<ClInclude Include="..\wmiquery.h" />
<ClInclude Include="..\..\regex\regex.h" />
<ClInclude Include="..\..\regex\regex_internal.h" />
<ClInclude Include="..\..\getopt\getopt.h" />
<ClInclude Include="..\..\atacmdnames.h" />
<ClInclude Include="..\..\atacmds.h" />
<ClInclude Include="config.h" />
<ClInclude Include="svnversion.h" />
<CustomBuildStep Include="..\..\ataprint.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<CustomBuildStep Include="..\..\cciss.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<ClInclude Include="..\..\cissio_freebsd.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ClInclude>
<ClInclude Include="..\..\csmisas.h" />
<ClInclude Include="..\..\dev_ata_cmd_set.h" />
<ClInclude Include="..\..\dev_interface.h" />
<ClInclude Include="..\..\dev_tunnelled.h" />
<ClInclude Include="..\..\drivedb.h" />
<ClInclude Include="..\..\int64.h" />
<ClInclude Include="..\..\knowndrives.h" />
<CustomBuildStep Include="..\..\megaraid.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<CustomBuildStep Include="..\..\os_darwin.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<CustomBuildStep Include="..\..\os_freebsd.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<CustomBuildStep Include="..\..\os_generic.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<CustomBuildStep Include="..\..\os_linux.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<CustomBuildStep Include="..\..\os_netbsd.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<CustomBuildStep Include="..\..\os_openbsd.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<CustomBuildStep Include="..\..\os_os2.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<CustomBuildStep Include="..\..\os_qnxnto.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<CustomBuildStep Include="..\..\os_solaris.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<ClInclude Include="..\..\scsicmds.h" />
<CustomBuildStep Include="..\..\scsiprint.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<CustomBuildStep Include="..\..\smartctl.h">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<ClInclude Include="..\..\utility.h" />
</ItemGroup>
<ItemGroup>
<None Include="..\..\smartd_warning.sh.in" />
<None Include="..\installer.nsi" />
<None Include="..\smartctl_res.rc.in" />
<None Include="..\smartd_res.rc.in" />
<None Include="..\smartd_warning.cmd" />
<CustomBuild Include="..\syslogevt.mc">
<FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">mc -r $(IntDir) ..\syslogevt.mc</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">mc -r $(IntDir) ..\syslogevt.mc</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)syslogevt.rc;$(IntDir)msg00001.bin;syslogevt.h;%(Outputs)</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">mc -r $(IntDir) ..\syslogevt.mc</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">mc -r $(IntDir) ..\syslogevt.mc</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)syslogevt.rc;$(IntDir)msg00001.bin;syslogevt.h;%(Outputs)</Outputs>
</CustomBuild>
<None Include="..\update-smart-drivedb.nsi" />
<None Include="..\..\AUTHORS" />
<None Include="..\..\autogen.sh" />
<None Include="..\..\ChangeLog" />
<None Include="..\..\config.h.in" />
<None Include="..\..\configure.ac" />
<None Include="..\..\do_release" />
<None Include="..\..\Doxyfile" />
<None Include="..\..\INSTALL" />
<None Include="..\..\Makefile.am" />
<None Include="..\..\NEWS" />
<None Include="..\..\README" />
<None Include="..\..\smartctl.8.in" />
<None Include="..\..\smartd.8.in" />
<None Include="..\..\smartd.conf.5.in" />
<None Include="..\..\smartd.initd.in" />
<None Include="..\..\TODO" />
<None Include="..\..\update-smart-drivedb.in" />
<None Include="..\..\WARNINGS" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="smartctl_res.rc">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</ResourceCompile>
<ResourceCompile Include="smartd_res.rc">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)</AdditionalIncludeDirectories>
</ResourceCompile>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,178 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="os_win32">
<UniqueIdentifier>{44bb110e-4d44-4d5e-8186-354210a8d3ba}</UniqueIdentifier>
</Filter>
<Filter Include="regex">
<UniqueIdentifier>{fd3bb1d5-a72e-4f92-84a3-6eac97975ec7}</UniqueIdentifier>
</Filter>
<Filter Include="getopt">
<UniqueIdentifier>{1d1b67d5-219f-4e86-a5ff-9d94f1f751f9}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\daemon_win32.cpp">
<Filter>os_win32</Filter>
</ClCompile>
<ClCompile Include="..\syslog_win32.cpp">
<Filter>os_win32</Filter>
</ClCompile>
<ClCompile Include="..\wmiquery.cpp">
<Filter>os_win32</Filter>
</ClCompile>
<ClCompile Include="..\..\regex\regcomp.c">
<Filter>regex</Filter>
</ClCompile>
<ClCompile Include="..\..\regex\regex.c">
<Filter>regex</Filter>
</ClCompile>
<ClCompile Include="..\..\regex\regex_internal.c">
<Filter>regex</Filter>
</ClCompile>
<ClCompile Include="..\..\regex\regexec.c">
<Filter>regex</Filter>
</ClCompile>
<ClCompile Include="..\..\getopt\getopt.c">
<Filter>getopt</Filter>
</ClCompile>
<ClCompile Include="..\..\getopt\getopt1.c">
<Filter>getopt</Filter>
</ClCompile>
<ClCompile Include="..\..\atacmdnames.cpp" />
<ClCompile Include="..\..\atacmds.cpp" />
<ClCompile Include="..\..\ataprint.cpp" />
<ClCompile Include="..\..\cciss.cpp" />
<ClCompile Include="..\..\dev_ata_cmd_set.cpp" />
<ClCompile Include="..\..\dev_interface.cpp" />
<ClCompile Include="..\..\dev_legacy.cpp" />
<ClCompile Include="..\..\knowndrives.cpp" />
<ClCompile Include="..\..\os_darwin.cpp" />
<ClCompile Include="..\..\os_freebsd.cpp" />
<ClCompile Include="..\..\os_generic.cpp" />
<ClCompile Include="..\..\os_linux.cpp" />
<ClCompile Include="..\..\os_netbsd.cpp" />
<ClCompile Include="..\..\os_openbsd.cpp" />
<ClCompile Include="..\..\os_os2.cpp" />
<ClCompile Include="..\..\os_qnxnto.cpp" />
<ClCompile Include="..\..\os_solaris.cpp" />
<ClCompile Include="..\..\os_win32.cpp" />
<ClCompile Include="..\..\scsiata.cpp" />
<ClCompile Include="..\..\scsicmds.cpp" />
<ClCompile Include="..\..\scsiprint.cpp" />
<ClCompile Include="..\..\smartctl.cpp" />
<ClCompile Include="..\..\smartd.cpp" />
<ClCompile Include="..\..\utility.cpp" />
<ClCompile Include="..\..\ataidentify.cpp" />
<ClCompile Include="..\..\dev_areca.cpp" />
<ClCompile Include="..\..\nvmecmds.cpp" />
<ClCompile Include="..\..\nvmeprint.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\daemon_win32.h">
<Filter>os_win32</Filter>
</ClInclude>
<ClInclude Include="..\syslog.h">
<Filter>os_win32</Filter>
</ClInclude>
<ClInclude Include="..\wbemcli_small.h">
<Filter>os_win32</Filter>
</ClInclude>
<ClInclude Include="..\wmiquery.h">
<Filter>os_win32</Filter>
</ClInclude>
<ClInclude Include="..\..\regex\regex.h">
<Filter>regex</Filter>
</ClInclude>
<ClInclude Include="..\..\regex\regex_internal.h">
<Filter>regex</Filter>
</ClInclude>
<ClInclude Include="..\..\getopt\getopt.h">
<Filter>getopt</Filter>
</ClInclude>
<ClInclude Include="..\..\aacraid.h" />
<ClInclude Include="..\..\atacmdnames.h" />
<ClInclude Include="..\..\atacmds.h" />
<ClInclude Include="..\..\cissio_freebsd.h" />
<ClInclude Include="..\..\csmisas.h" />
<ClInclude Include="..\..\dev_ata_cmd_set.h" />
<ClInclude Include="..\..\dev_interface.h" />
<ClInclude Include="..\..\dev_tunnelled.h" />
<ClInclude Include="..\..\drivedb.h" />
<ClInclude Include="..\..\int64.h" />
<ClInclude Include="..\..\knowndrives.h" />
<ClInclude Include="..\..\scsicmds.h" />
<ClInclude Include="..\..\utility.h" />
<ClInclude Include="..\..\ataidentify.h" />
<ClInclude Include="..\..\dev_areca.h" />
<ClInclude Include="config.h" />
<ClInclude Include="svnversion.h" />
<ClInclude Include="..\..\nvmecmds.h" />
<ClInclude Include="..\..\nvmeprint.h" />
</ItemGroup>
<ItemGroup>
<None Include="..\installer.nsi">
<Filter>os_win32</Filter>
</None>
<None Include="..\update-smart-drivedb.nsi">
<Filter>os_win32</Filter>
</None>
<None Include="..\..\AUTHORS" />
<None Include="..\..\autogen.sh" />
<None Include="..\..\ChangeLog" />
<None Include="..\..\config.h.in" />
<None Include="..\..\configure.ac" />
<None Include="..\..\do_release" />
<None Include="..\..\Doxyfile" />
<None Include="..\..\INSTALL" />
<None Include="..\..\Makefile.am" />
<None Include="..\..\NEWS" />
<None Include="..\..\README" />
<None Include="..\..\smartctl.8.in" />
<None Include="..\..\smartd.8.in" />
<None Include="..\..\smartd.conf.5.in" />
<None Include="..\..\smartd.initd.in" />
<None Include="..\..\TODO" />
<None Include="..\..\update-smart-drivedb.in" />
<None Include="..\..\WARNINGS" />
<None Include="..\smartd_warning.cmd">
<Filter>os_win32</Filter>
</None>
<None Include="..\..\smartd_warning.sh.in" />
<None Include="..\smartctl_res.rc.in">
<Filter>os_win32</Filter>
</None>
<None Include="..\smartd_res.rc.in">
<Filter>os_win32</Filter>
</None>
</ItemGroup>
<ItemGroup>
<CustomBuildStep Include="..\..\ataprint.h" />
<CustomBuildStep Include="..\..\cciss.h" />
<CustomBuildStep Include="..\..\megaraid.h" />
<CustomBuildStep Include="..\..\os_darwin.h" />
<CustomBuildStep Include="..\..\os_freebsd.h" />
<CustomBuildStep Include="..\..\os_generic.h" />
<CustomBuildStep Include="..\..\os_linux.h" />
<CustomBuildStep Include="..\..\os_netbsd.h" />
<CustomBuildStep Include="..\..\os_openbsd.h" />
<CustomBuildStep Include="..\..\os_os2.h" />
<CustomBuildStep Include="..\..\os_qnxnto.h" />
<CustomBuildStep Include="..\..\os_solaris.h" />
<CustomBuildStep Include="..\..\scsiprint.h" />
<CustomBuildStep Include="..\..\smartctl.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="smartctl_res.rc">
<Filter>os_win32</Filter>
</ResourceCompile>
<ResourceCompile Include="smartd_res.rc">
<Filter>os_win32</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="..\syslogevt.mc">
<Filter>os_win32</Filter>
</CustomBuild>
</ItemGroup>
</Project>

View File

@ -1,38 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual C++ Express 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "smartctl", "smartctl.vcxproj", "{3AFEDCDD-D289-4543-A91D-EFBA6C710247}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "smartd", "smartd.vcxproj", "{C0762191-C2AC-40B6-A2EB-F1658BBDC4C6}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "runcmd", "runcmd.vcxproj", "{11A4B619-D97B-499F-AF17-CF9F80BF70E8}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wtssendmsg", "wtssendmsg.vcxproj", "{0B6B7D19-07AE-41DD-B70E-2F74362A4EC0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{3AFEDCDD-D289-4543-A91D-EFBA6C710247}.Debug|Win32.ActiveCfg = Debug|Win32
{3AFEDCDD-D289-4543-A91D-EFBA6C710247}.Debug|Win32.Build.0 = Debug|Win32
{3AFEDCDD-D289-4543-A91D-EFBA6C710247}.Release|Win32.ActiveCfg = Release|Win32
{3AFEDCDD-D289-4543-A91D-EFBA6C710247}.Release|Win32.Build.0 = Release|Win32
{C0762191-C2AC-40B6-A2EB-F1658BBDC4C6}.Debug|Win32.ActiveCfg = Debug|Win32
{C0762191-C2AC-40B6-A2EB-F1658BBDC4C6}.Debug|Win32.Build.0 = Debug|Win32
{C0762191-C2AC-40B6-A2EB-F1658BBDC4C6}.Release|Win32.ActiveCfg = Release|Win32
{C0762191-C2AC-40B6-A2EB-F1658BBDC4C6}.Release|Win32.Build.0 = Release|Win32
{11A4B619-D97B-499F-AF17-CF9F80BF70E8}.Debug|Win32.ActiveCfg = Debug|Win32
{11A4B619-D97B-499F-AF17-CF9F80BF70E8}.Debug|Win32.Build.0 = Debug|Win32
{11A4B619-D97B-499F-AF17-CF9F80BF70E8}.Release|Win32.ActiveCfg = Release|Win32
{11A4B619-D97B-499F-AF17-CF9F80BF70E8}.Release|Win32.Build.0 = Release|Win32
{0B6B7D19-07AE-41DD-B70E-2F74362A4EC0}.Debug|Win32.ActiveCfg = Debug|Win32
{0B6B7D19-07AE-41DD-B70E-2F74362A4EC0}.Debug|Win32.Build.0 = Debug|Win32
{0B6B7D19-07AE-41DD-B70E-2F74362A4EC0}.Release|Win32.ActiveCfg = Release|Win32
{0B6B7D19-07AE-41DD-B70E-2F74362A4EC0}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -1,82 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\wtssendmsg.c" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{0B6B7D19-07AE-41DD-B70E-2F74362A4EC0}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>wtssendmsg</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
<IntDir>$(Configuration)\$(ProjectName).tmp\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<IntDir>$(Configuration)\$(ProjectName).tmp\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_CRT_NONSTDC_NO_WARNINGS;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>wtsapi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_CRT_NONSTDC_NO_WARNINGS;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>wtsapi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,7 +1,7 @@
// //
// os_win32/smartctl_res.rc.in // os_win32/versioninfo.rc.in
// //
// $Id: smartctl_res.rc.in 3878 2014-03-03 18:45:21Z chrfranke $ // $Id: versioninfo.rc.in 4519 2017-10-08 15:41:54Z chrfranke $
// //
1 VERSIONINFO 1 VERSIONINFO
@ -18,11 +18,11 @@ BEGIN
BLOCK "04090000" BLOCK "04090000"
BEGIN BEGIN
VALUE "CompanyName", "www.smartmontools.org" VALUE "CompanyName", "www.smartmontools.org"
VALUE "FileDescription", "Control and Monitor Utility for SMART Disks" VALUE "FileDescription", "@DESC@"
VALUE "FileVersion", "@TEXT_VERSION@" VALUE "FileVersion", "@TEXT_VERSION@"
VALUE "InternalName", "smartctl" VALUE "InternalName", "@NAME@"
VALUE "LegalCopyright", "(C) 2002-@YY@, Bruce Allen, Christian Franke, www.smartmontools.org" VALUE "LegalCopyright", "(C) 2002-@YY@, Bruce Allen, Christian Franke, www.smartmontools.org"
VALUE "OriginalFilename", "smartctl.exe" VALUE "OriginalFilename", "@NAME@.exe"
VALUE "ProductName", "smartmontools" VALUE "ProductName", "smartmontools"
VALUE "ProductVersion", "@TEXT_VERSION@" VALUE "ProductVersion", "@TEXT_VERSION@"
END END

View File

@ -3,7 +3,7 @@
* *
* Home page of code is: http://www.smartmontools.org * Home page of code is: http://www.smartmontools.org
* *
* Copyright (C) 2011-13 Christian Franke <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2011-13 Christian Franke
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -23,7 +23,7 @@
#include <stdio.h> #include <stdio.h>
const char * wmiquery_cpp_cvsid = "$Id: wmiquery.cpp 4120 2015-08-27 16:12:21Z samm2 $" const char * wmiquery_cpp_cvsid = "$Id: wmiquery.cpp 4431 2017-08-08 19:38:15Z chrfranke $"
WMIQUERY_H_CVSID; WMIQUERY_H_CVSID;

View File

@ -3,7 +3,7 @@
* *
* Home page of code is: http://www.smartmontools.org * Home page of code is: http://www.smartmontools.org
* *
* Copyright (C) 2012 Christian Franke <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2012 Christian Franke
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -18,7 +18,7 @@
#define WINVER 0x0500 #define WINVER 0x0500
#define _WIN32_WINNT WINVER #define _WIN32_WINNT WINVER
char svnid[] = "$Id: wtssendmsg.c 4120 2015-08-27 16:12:21Z samm2 $"; char svnid[] = "$Id: wtssendmsg.c 4431 2017-08-08 19:38:15Z chrfranke $";
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -30,7 +30,7 @@ char svnid[] = "$Id: wtssendmsg.c 4120 2015-08-27 16:12:21Z samm2 $";
static int usage() static int usage()
{ {
printf("wtssendmsg $Revision: 4120 $ - Display a message box on client desktops\n" printf("wtssendmsg $Revision: 4431 $ - Display a message box on client desktops\n"
"Copyright (C) 2012 Christian Franke, smartmontools.org\n\n" "Copyright (C) 2012 Christian Franke, smartmontools.org\n\n"
"Usage: wtssendmsg [-cas] [-v] [\"Caption\"] \"Message\"|-\n" "Usage: wtssendmsg [-cas] [-v] [\"Caption\"] \"Message\"|-\n"
" wtssendmsg -v\n\n" " wtssendmsg -v\n\n"

View File

@ -4,7 +4,7 @@
* Home page of code is: http://www.smartmontools.org * Home page of code is: http://www.smartmontools.org
* *
* Copyright (C) 2006-15 Douglas Gilbert <dgilbert@interlog.com> * Copyright (C) 2006-15 Douglas Gilbert <dgilbert@interlog.com>
* Copyright (C) 2009-16 Christian Franke * Copyright (C) 2009-17 Christian Franke
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -62,7 +62,7 @@
#include "dev_ata_cmd_set.h" // ata_device_with_command_set #include "dev_ata_cmd_set.h" // ata_device_with_command_set
#include "dev_tunnelled.h" // tunnelled_device<> #include "dev_tunnelled.h" // tunnelled_device<>
const char * scsiata_cpp_cvsid = "$Id: scsiata.cpp 4276 2016-04-02 19:13:39Z chrfranke $"; const char * scsiata_cpp_cvsid = "$Id: scsiata.cpp 4386 2017-01-28 16:35:06Z chrfranke $";
/* This is a slightly stretched SCSI sense "descriptor" format header. /* This is a slightly stretched SCSI sense "descriptor" format header.
The addition is to allow the 0x70 and 0x71 response codes. The idea The addition is to allow the 0x70 and 0x71 response codes. The idea
@ -1170,7 +1170,6 @@ bool usbjmicron_device::get_registers(unsigned short addr,
io_hdr.dxfer_len = size; io_hdr.dxfer_len = size;
io_hdr.dxferp = buf; io_hdr.dxferp = buf;
io_hdr.cmnd = cdb; io_hdr.cmnd = cdb;
io_hdr.cmnd_len = sizeof(cdb);
io_hdr.cmnd_len = (!m_prolific ? 12 : 14); io_hdr.cmnd_len = (!m_prolific ? 12 : 14);
scsi_device * scsidev = get_tunnel_dev(); scsi_device * scsidev = get_tunnel_dev();

View File

@ -47,7 +47,7 @@
#include "dev_interface.h" #include "dev_interface.h"
#include "utility.h" #include "utility.h"
const char *scsicmds_c_cvsid="$Id: scsicmds.cpp 4243 2016-03-20 18:29:36Z chrfranke $" const char *scsicmds_c_cvsid="$Id: scsicmds.cpp 4414 2017-03-27 21:00:46Z chrfranke $"
SCSICMDS_H_CVSID; SCSICMDS_H_CVSID;
// Print SCSI debug messages? // Print SCSI debug messages?
@ -1493,7 +1493,6 @@ scsiCheckIE(scsi_device * device, int hasIELogPage, int hasTempLogPage,
UINT8 tBuf[252]; UINT8 tBuf[252];
struct scsi_sense_disect sense_info; struct scsi_sense_disect sense_info;
int err; int err;
int temperatureSet = 0;
UINT8 currTemp, trTemp; UINT8 currTemp, trTemp;
*asc = 0; *asc = 0;
@ -1534,7 +1533,7 @@ scsiCheckIE(scsi_device * device, int hasIELogPage, int hasTempLogPage,
} }
*asc = sense_info.asc; *asc = sense_info.asc;
*ascq = sense_info.ascq; *ascq = sense_info.ascq;
if ((! temperatureSet) && hasTempLogPage) { if (hasTempLogPage) {
if (0 == scsiGetTemp(device, &currTemp, &trTemp)) { if (0 == scsiGetTemp(device, &currTemp, &trTemp)) {
*currenttemp = currTemp; *currenttemp = currTemp;
*triptemp = trTemp; *triptemp = trTemp;

View File

@ -30,7 +30,7 @@
#ifndef SCSICMDS_H_ #ifndef SCSICMDS_H_
#define SCSICMDS_H_ #define SCSICMDS_H_
#define SCSICMDS_H_CVSID "$Id: scsicmds.h 4152 2015-10-17 16:08:21Z chrfranke $\n" #define SCSICMDS_H_CVSID "$Id: scsicmds.h 4557 2017-10-19 19:17:29Z samm2 $\n"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -304,8 +304,9 @@ Documentation, see http://www.storage.ibm.com/techsup/hddtech/prodspecs.htm */
/* SCSI command timeout values (units are seconds) */ /* SCSI command timeout values (units are seconds) */
#define SCSI_TIMEOUT_DEFAULT 20 // should be longer than the spin up time #define SCSI_TIMEOUT_DEFAULT 60 // should be longer than the spin up time
// of a disk in standby mode. // of a disk in JBOD.
#define SCSI_TIMEOUT_SELF_TEST (5 * 60 * 60) /* allow max 5 hours for */ #define SCSI_TIMEOUT_SELF_TEST (5 * 60 * 60) /* allow max 5 hours for */
/* extended foreground self test */ /* extended foreground self test */

View File

@ -40,7 +40,7 @@
#define GBUF_SIZE 65535 #define GBUF_SIZE 65535
const char * scsiprint_c_cvsid = "$Id: scsiprint.cpp 4292 2016-04-12 23:06:59Z dpgilbert $" const char * scsiprint_c_cvsid = "$Id: scsiprint.cpp 4415 2017-03-27 21:14:53Z chrfranke $"
SCSIPRINT_H_CVSID; SCSIPRINT_H_CVSID;
@ -1205,7 +1205,6 @@ show_sas_port_param(unsigned char * ucp, int param_len)
{ {
int j, m, n, nphys, t, sz, spld_len; int j, m, n, nphys, t, sz, spld_len;
unsigned char * vcp; unsigned char * vcp;
uint64_t ull;
char s[64]; char s[64];
sz = sizeof(s); sz = sizeof(s);
@ -1293,6 +1292,8 @@ show_sas_port_param(unsigned char * ucp, int param_len)
!! (vcp[6] & 8), !! (vcp[6] & 4), !! (vcp[6] & 2)); !! (vcp[6] & 8), !! (vcp[6] & 4), !! (vcp[6] & 2));
pout(" attached target port: ssp=%d stp=%d smp=%d\n", pout(" attached target port: ssp=%d stp=%d smp=%d\n",
!! (vcp[7] & 8), !! (vcp[7] & 4), !! (vcp[7] & 2)); !! (vcp[7] & 8), !! (vcp[7] & 4), !! (vcp[7] & 2));
if (!dont_print_serial_number) {
uint64_t ull;
for (n = 0, ull = vcp[8]; n < 8; ++n) { for (n = 0, ull = vcp[8]; n < 8; ++n) {
ull <<= 8; ull |= vcp[8 + n]; ull <<= 8; ull |= vcp[8 + n];
} }
@ -1301,6 +1302,7 @@ show_sas_port_param(unsigned char * ucp, int param_len)
ull <<= 8; ull |= vcp[16 + n]; ull <<= 8; ull |= vcp[16 + n];
} }
pout(" attached SAS address = 0x%" PRIx64 "\n", ull); pout(" attached SAS address = 0x%" PRIx64 "\n", ull);
}
pout(" attached phy identifier = %d\n", vcp[24]); pout(" attached phy identifier = %d\n", vcp[24]);
unsigned int ui; unsigned int ui;
ui = (vcp[32] << 24) | (vcp[33] << 16) | (vcp[34] << 8) | vcp[35]; ui = (vcp[32] << 24) | (vcp[33] << 16) | (vcp[34] << 8) | vcp[35];

View File

@ -3,7 +3,7 @@
* *
* Home page of code is: http://www.smartmontools.org * Home page of code is: http://www.smartmontools.org
* *
* Copyright (C) 2002-9 Bruce Allen <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2002-9 Bruce Allen
* Copyright (C) 2000 Michael Cornwell <cornwell@acm.org> * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
* *
* Additional SCSI work: * Additional SCSI work:
@ -29,7 +29,7 @@
#ifndef SCSI_PRINT_H_ #ifndef SCSI_PRINT_H_
#define SCSI_PRINT_H_ #define SCSI_PRINT_H_
#define SCSIPRINT_H_CVSID "$Id: scsiprint.h 4120 2015-08-27 16:12:21Z samm2 $\n" #define SCSIPRINT_H_CVSID "$Id: scsiprint.h 4431 2017-08-08 19:38:15Z chrfranke $\n"
// Options for scsiPrintMain // Options for scsiPrintMain
struct scsi_print_options struct scsi_print_options

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@
* Home page of code is: http://www.smartmontools.org * Home page of code is: http://www.smartmontools.org
* *
* Copyright (C) 2002-11 Bruce Allen * Copyright (C) 2002-11 Bruce Allen
* Copyright (C) 2008-16 Christian Franke * Copyright (C) 2008-17 Christian Franke
* Copyright (C) 2000 Michael Cornwell <cornwell@acm.org> * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -52,7 +52,7 @@
#include "smartctl.h" #include "smartctl.h"
#include "utility.h" #include "utility.h"
const char * smartctl_cpp_cvsid = "$Id: smartctl.cpp 4311 2016-04-27 21:03:01Z chrfranke $" const char * smartctl_cpp_cvsid = "$Id: smartctl.cpp 4585 2017-11-04 13:41:03Z chrfranke $"
CONFIG_H_CVSID SMARTCTL_H_CVSID; CONFIG_H_CVSID SMARTCTL_H_CVSID;
// Globals to control printing // Globals to control printing
@ -87,7 +87,8 @@ static void Usage()
" --identify[=[w][nvb]]\n" " --identify[=[w][nvb]]\n"
" Show words and bits from IDENTIFY DEVICE data (ATA)\n\n" " Show words and bits from IDENTIFY DEVICE data (ATA)\n\n"
" -g NAME, --get=NAME\n" " -g NAME, --get=NAME\n"
" Get device setting: all, aam, apm, lookahead, security, wcache, rcache, wcreorder\n\n" " Get device setting: all, aam, apm, dsn, lookahead, security,\n"
" wcache, rcache, wcreorder, wcache-sct\n\n"
" -a, --all\n" " -a, --all\n"
" Show all SMART information for device\n\n" " Show all SMART information for device\n\n"
" -x, --xall\n" " -x, --xall\n"
@ -102,14 +103,15 @@ static void Usage()
" -q TYPE, --quietmode=TYPE (ATA)\n" " -q TYPE, --quietmode=TYPE (ATA)\n"
" Set smartctl quiet mode to one of: errorsonly, silent, noserial\n\n" " Set smartctl quiet mode to one of: errorsonly, silent, noserial\n\n"
" -d TYPE, --device=TYPE\n" " -d TYPE, --device=TYPE\n"
" Specify device type to one of: %s\n\n" " Specify device type to one of:\n"
" %s\n\n" // TODO: fold this string
" -T TYPE, --tolerance=TYPE (ATA)\n" " -T TYPE, --tolerance=TYPE (ATA)\n"
" Tolerance: normal, conservative, permissive, verypermissive\n\n" " Tolerance: normal, conservative, permissive, verypermissive\n\n"
" -b TYPE, --badsum=TYPE (ATA)\n" " -b TYPE, --badsum=TYPE (ATA)\n"
" Set action on bad checksum to one of: warn, exit, ignore\n\n" " Set action on bad checksum to one of: warn, exit, ignore\n\n"
" -r TYPE, --report=TYPE\n" " -r TYPE, --report=TYPE\n"
" Report transactions (see man page)\n\n" " Report transactions (see man page)\n\n"
" -n MODE, --nocheck=MODE (ATA)\n" " -n MODE[,STATUS], --nocheck=MODE[,STATUS] (ATA)\n"
" No check if: never, sleep, standby, idle (see man page)\n\n", " No check if: never, sleep, standby, idle (see man page)\n\n",
getvalidarglist('d').c_str()); // TODO: Use this function also for other options ? getvalidarglist('d').c_str()); // TODO: Use this function also for other options ?
printf( printf(
@ -122,8 +124,9 @@ static void Usage()
" Enable/disable Attribute autosave on device (on/off)\n\n" " Enable/disable Attribute autosave on device (on/off)\n\n"
" -s NAME[,VALUE], --set=NAME[,VALUE]\n" " -s NAME[,VALUE], --set=NAME[,VALUE]\n"
" Enable/disable/change device setting: aam,[N|off], apm,[N|off],\n" " Enable/disable/change device setting: aam,[N|off], apm,[N|off],\n"
" lookahead,[on|off], security-freeze, standby,[N|off|now],\n" " dsn,[on|off], lookahead,[on|off], security-freeze,\n"
" wcache,[on|off], rcache,[on|off], wcreorder,[on|off]\n\n" " standby,[N|off|now], wcache,[on|off], rcache,[on|off],\n"
" wcreorder,[on|off[,p]], wcache-sct,[ata|on|off[,p]]\n\n"
); );
printf( printf(
"======================================= READ AND DISPLAY DATA OPTIONS =====\n\n" "======================================= READ AND DISPLAY DATA OPTIONS =====\n\n"
@ -137,12 +140,10 @@ static void Usage()
" Set output format for attributes: old, brief, hex[,id|val]\n\n" " Set output format for attributes: old, brief, hex[,id|val]\n\n"
" -l TYPE, --log=TYPE\n" " -l TYPE, --log=TYPE\n"
" Show device log. TYPE: error, selftest, selective, directory[,g|s],\n" " Show device log. TYPE: error, selftest, selective, directory[,g|s],\n"
" xerror[,N][,error], xselftest[,N][,selftest],\n" " xerror[,N][,error], xselftest[,N][,selftest], background,\n"
" background, sasphy[,reset], sataphy[,reset],\n" " sasphy[,reset], sataphy[,reset], scttemp[sts,hist],\n"
" scttemp[sts,hist], scttempint,N[,p],\n" " scttempint,N[,p], scterc[,N,M], devstat[,N], defects[,N], ssd,\n"
" scterc[,N,M], devstat[,N], ssd,\n" " gplog,N[,RANGE], smartlog,N[,RANGE], nvmelog,N,SIZE\n\n"
" gplog,N[,RANGE], smartlog,N[,RANGE],\n"
" nvmelog,N,SIZE\n\n"
" -v N,OPTION , --vendorattribute=N,OPTION (ATA)\n" " -v N,OPTION , --vendorattribute=N,OPTION (ATA)\n"
" Set display OPTION for vendor Attribute N (see man page)\n\n" " Set display OPTION for vendor Attribute N (see man page)\n\n"
" -F TYPE, --firmwarebug=TYPE (ATA)\n" " -F TYPE, --firmwarebug=TYPE (ATA)\n"
@ -195,6 +196,8 @@ static std::string getvalidarglist(int opt)
return "normal, conservative, permissive, verypermissive"; return "normal, conservative, permissive, verypermissive";
case 'b': case 'b':
return "warn, exit, ignore"; return "warn, exit, ignore";
case 'B':
return "[+]<FILE_NAME>";
case 'r': case 'r':
return "ioctl[,N], ataioctl[,N], scsiioctl[,N], nvmeioctl[,N]"; return "ioctl[,N], ataioctl[,N], scsiioctl[,N], nvmeioctl[,N]";
case opt_smart: case opt_smart:
@ -206,7 +209,7 @@ static std::string getvalidarglist(int opt)
"xerror[,N][,error], xselftest[,N][,selftest], " "xerror[,N][,error], xselftest[,N][,selftest], "
"background, sasphy[,reset], sataphy[,reset], " "background, sasphy[,reset], sataphy[,reset], "
"scttemp[sts,hist], scttempint,N[,p], " "scttemp[sts,hist], scttempint,N[,p], "
"scterc[,N,M], devstat[,N], ssd, " "scterc[,N,M], devstat[,N], defects[,N], ssd, "
"gplog,N[,RANGE], smartlog,N[,RANGE], " "gplog,N[,RANGE], smartlog,N[,RANGE], "
"nvmelog,N,SIZE"; "nvmelog,N,SIZE";
case 'P': case 'P':
@ -217,14 +220,15 @@ static std::string getvalidarglist(int opt)
case 'F': case 'F':
return std::string(get_valid_firmwarebug_args()) + ", swapid"; return std::string(get_valid_firmwarebug_args()) + ", swapid";
case 'n': case 'n':
return "never, sleep, standby, idle"; return "never, sleep[,STATUS], standby[,STATUS], idle[,STATUS]";
case 'f': case 'f':
return "old, brief, hex[,id|val]"; return "old, brief, hex[,id|val]";
case 'g': case 'g':
return "aam, apm, lookahead, security, wcache, rcache, wcreorder"; return "aam, apm, dsn, lookahead, security, wcache, rcache, wcreorder, wcache-sct";
case opt_set: case opt_set:
return "aam,[N|off], apm,[N|off], lookahead,[on|off], security-freeze, " return "aam,[N|off], apm,[N|off], dsn,[on|off], lookahead,[on|off], security-freeze, "
"standby,[N|off|now], wcache,[on|off], rcache,[on|off], wcreorder,[on|off]"; "standby,[N|off|now], wcache,[on|off], rcache,[on|off], wcreorder,[on|off[,p]], "
"wcache-sct,[ata|on|off[,p]]";
case 's': case 's':
return getvalidarglist(opt_smart)+", "+getvalidarglist(opt_set); return getvalidarglist(opt_smart)+", "+getvalidarglist(opt_set);
case opt_identify: case opt_identify:
@ -526,6 +530,17 @@ static const char * parse_options(int argc, char** argv,
badarg = true; badarg = true;
} }
} else if (str_starts_with(optarg, "defects")) {
int n1 = -1, n2 = -1, len = strlen(optarg);
unsigned val = ~0;
sscanf(optarg, "defects%n,%u%n", &n1, &val, &n2);
if (n1 == len)
ataopts.pending_defects_log = 31; // Entries of first page
else if (n2 == len && val <= 0xffff * 32 - 1)
ataopts.pending_defects_log = val;
else
badarg = true;
} else if (!strncmp(optarg, "xerror", sizeof("xerror")-1)) { } else if (!strncmp(optarg, "xerror", sizeof("xerror")-1)) {
int n1 = -1, n2 = -1, len = strlen(optarg); int n1 = -1, n2 = -1, len = strlen(optarg);
unsigned val = 8; unsigned val = 8;
@ -662,11 +677,14 @@ static const char * parse_options(int argc, char** argv,
ataopts.sct_erc_get = true; ataopts.sct_erc_get = true;
ataopts.sct_wcache_reorder_get = true; ataopts.sct_wcache_reorder_get = true;
ataopts.devstat_all_pages = true; ataopts.devstat_all_pages = true;
// ataopts.pending_defects_log = 31; // TODO: Add if no longer EXPERIMENTAL
ataopts.pending_defects_info = true; // TODO: Remove then
ataopts.sataphy = true; ataopts.sataphy = true;
ataopts.get_set_used = true; ataopts.get_set_used = true;
ataopts.get_aam = ataopts.get_apm = true; ataopts.get_aam = ataopts.get_apm = true;
ataopts.get_security = true; ataopts.get_security = true;
ataopts.get_lookahead = ataopts.get_wcache = true; ataopts.get_lookahead = ataopts.get_wcache = true;
ataopts.get_dsn = true;
scsiopts.get_rcd = scsiopts.get_wce = true; scsiopts.get_rcd = scsiopts.get_wce = true;
scsiopts.smart_background_log = true; scsiopts.smart_background_log = true;
scsiopts.smart_ss_media_log = true; scsiopts.smart_ss_media_log = true;
@ -798,16 +816,25 @@ static const char * parse_options(int argc, char** argv,
break; break;
case 'n': case 'n':
// skip disk check if in low-power mode // skip disk check if in low-power mode
if (!strcmp(optarg, "never")) if (!strcmp(optarg, "never")) {
ataopts.powermode = 1; // do not skip, but print mode ataopts.powermode = 1; // do not skip, but print mode
else if (!strcmp(optarg, "sleep")) }
else {
int n1 = -1, n2 = -1, len = strlen(optarg);
char s[7+1]; unsigned i = FAILPOWER;
sscanf(optarg, "%9[a-z]%n,%u%n", s, &n1, &i, &n2);
if (!((n1 == len || n2 == len) && i <= 255))
badarg = true;
else if (!strcmp(s, "sleep"))
ataopts.powermode = 2; ataopts.powermode = 2;
else if (!strcmp(optarg, "standby")) else if (!strcmp(s, "standby"))
ataopts.powermode = 3; ataopts.powermode = 3;
else if (!strcmp(optarg, "idle")) else if (!strcmp(s, "idle"))
ataopts.powermode = 4; ataopts.powermode = 4;
else else
badarg = true; badarg = true;
ataopts.powerexit = i;
}
break; break;
case 'f': case 'f':
if (!strcmp(optarg, "old")) { if (!strcmp(optarg, "old")) {
@ -856,8 +883,28 @@ static const char * parse_options(int argc, char** argv,
int n1 = -1, n2 = -1, n3 = -1, len = strlen(optarg); int n1 = -1, n2 = -1, n3 = -1, len = strlen(optarg);
if (sscanf(optarg, "%16[^,=]%n%*[,=]%n%u%n", name, &n1, &n2, &val, &n3) >= 1 if (sscanf(optarg, "%16[^,=]%n%*[,=]%n%u%n", name, &n1, &n2, &val, &n3) >= 1
&& (n1 == len || (!get && n2 > 0))) { && (n1 == len || (!get && n2 > 0))) {
bool on = (n2 > 0 && !strcmp(optarg+n2, "on")); bool on = false;
bool off = (n2 > 0 && !strcmp(optarg+n2, "off")); bool off = false;
bool ata = false;
bool persistent = false;
if (n2 > 0) {
int len2 = strlen(optarg + n2);
char * tmp = strstr(optarg+n2, ",p");
// handle ",p" in persistent options like: wcache-sct,[ata|on|off],p
if (tmp && (strlen(tmp) == 2)) {
persistent = true;
len2 = strlen(optarg+n2) - 2;
// the ,p option only works for set of SCT Feature Control command
if (strcmp(name, "wcache-sct") != 0 &&
strcmp(name, "wcreorder") != 0)
badarg = true;
}
on = !strncmp(optarg+n2, "on", len2);
off = !strncmp(optarg+n2, "off", len2);
ata = !strncmp(optarg+n2, "ata", len2);
}
if (n3 != len) if (n3 != len)
val = ~0U; val = ~0U;
@ -865,6 +912,7 @@ static const char * parse_options(int argc, char** argv,
ataopts.get_aam = ataopts.get_apm = true; ataopts.get_aam = ataopts.get_apm = true;
ataopts.get_security = true; ataopts.get_security = true;
ataopts.get_lookahead = ataopts.get_wcache = true; ataopts.get_lookahead = ataopts.get_wcache = true;
ataopts.get_dsn = true;
scsiopts.get_rcd = scsiopts.get_wce = true; scsiopts.get_rcd = scsiopts.get_wce = true;
} }
else if (!strcmp(name, "aam")) { else if (!strcmp(name, "aam")) {
@ -903,6 +951,7 @@ static const char * parse_options(int argc, char** argv,
badarg = true; badarg = true;
} }
else if (!strcmp(name, "wcreorder")) { else if (!strcmp(name, "wcreorder")) {
ataopts.sct_wcache_reorder_set_pers = persistent;
if (get) { if (get) {
ataopts.sct_wcache_reorder_get = true; ataopts.sct_wcache_reorder_get = true;
} }
@ -913,6 +962,20 @@ static const char * parse_options(int argc, char** argv,
else else
badarg = true; badarg = true;
} }
else if (!strcmp(name, "wcache-sct")) {
ataopts.sct_wcache_sct_set_pers = persistent;
if (get) {
ataopts.sct_wcache_sct_get = true;
}
else if (off)
ataopts.sct_wcache_sct_set = 3;
else if (on)
ataopts.sct_wcache_sct_set = 2;
else if (ata)
ataopts.sct_wcache_sct_set = 1;
else
badarg = true;
}
else if (!strcmp(name, "rcache")) { else if (!strcmp(name, "rcache")) {
if (get) if (get)
scsiopts.get_rcd = true; scsiopts.get_rcd = true;
@ -958,6 +1021,19 @@ static const char * parse_options(int argc, char** argv,
else else
badarg = true; badarg = true;
} }
else if (!strcmp(name, "dsn")) {
if (get) {
ataopts.get_dsn = true;
}
else if (off) {
ataopts.set_dsn = -1;
}
else if (on) {
ataopts.set_dsn = 1;
}
else
badarg = true;
}
else else
badarg = true; badarg = true;
} }
@ -1305,8 +1381,8 @@ static int main_worker(int argc, char **argv)
dev->get_info_name(), dev->get_dev_type(), get_protocol_info(dev.get())); dev->get_info_name(), dev->get_dev_type(), get_protocol_info(dev.get()));
if (dev->is_ata() && ataopts.powermode>=2 && dev->is_powered_down()) { if (dev->is_ata() && ataopts.powermode>=2 && dev->is_powered_down()) {
pout( "%s: Device is in %s mode, exit(%d)\n", dev->get_info_name(), "STANDBY (OS)", FAILPOWER ); pout("Device is in STANDBY (OS) mode, exit(%d)\n", ataopts.powerexit);
return FAILPOWER; return ataopts.powerexit;
} }
// Open device // Open device

View File

@ -3,8 +3,8 @@
* *
* Home page of code is: http://www.smartmontools.org * Home page of code is: http://www.smartmontools.org
* *
* Copyright (C) 2002-10 Bruce Allen <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2002-10 Bruce Allen
* Copyright (C) 2008-10 Christian Franke <smartmontools-support@lists.sourceforge.net> * Copyright (C) 2008-10 Christian Franke
* Copyright (C) 2000 Michael Cornwell <cornwell@acm.org> * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -26,7 +26,7 @@
#ifndef SMARTCTL_H_ #ifndef SMARTCTL_H_
#define SMARTCTL_H_ #define SMARTCTL_H_
#define SMARTCTL_H_CVSID "$Id: smartctl.h 4120 2015-08-27 16:12:21Z samm2 $\n" #define SMARTCTL_H_CVSID "$Id: smartctl.h 4431 2017-08-08 19:38:15Z chrfranke $\n"
// Return codes (bitmask) // Return codes (bitmask)

View File

@ -1,8 +1,8 @@
.ig .ig
Copyright (C) 2002-10 Bruce Allen Copyright (C) 2002-10 Bruce Allen
Copyright (C) 2004-16 Christian Franke Copyright (C) 2004-17 Christian Franke
$Id: smartd.8.in 4299 2016-04-16 19:45:57Z chrfranke $ $Id: smartd.8.in 4576 2017-10-29 16:41:44Z chrfranke $
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -18,6 +18,23 @@ Research Center), Jack Baskin School of Engineering, University of
California, Santa Cruz. http://ssrc.soe.ucsc.edu/ California, Santa Cruz. http://ssrc.soe.ucsc.edu/
.. ..
.\" Macros borrowed from pages generated with Pod::Man
.de Sp \" Vertical space (when we can't use .PP)
.if t .sp 0.4v
.if n .sp
..
.de Vb \" Begin verbatim text
.ft CW
.nf
.ne \\$1
..
.de Ve \" End verbatim text
.ft R
.fi
..
.\" Use groff extension \(aq (apostrophe quote, ASCII 0x27) if possible
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH SMARTD 8 "CURRENT_SVN_DATE" "CURRENT_SVN_VERSION" "SMART Monitoring Tools" .TH SMARTD 8 "CURRENT_SVN_DATE" "CURRENT_SVN_VERSION" "SMART Monitoring Tools"
.SH NAME .SH NAME
\fBsmartd\fP \- SMART Disk Monitoring Daemon \fBsmartd\fP \- SMART Disk Monitoring Daemon
@ -40,41 +57,41 @@ self-tests.
This version of \fBsmartd\fP is compatible with This version of \fBsmartd\fP is compatible with
ACS-3, ACS-2, ATA8-ACS, ATA/ATAPI-7 and earlier standards ACS-3, ACS-2, ATA8-ACS, ATA/ATAPI-7 and earlier standards
(see \fBREFERENCES\fP below). (see \fBREFERENCES\fP below).
.PP
\fBsmartd\fP will attempt to enable SMART monitoring on ATA devices \fBsmartd\fP will attempt to enable SMART monitoring on ATA devices
(equivalent to \fBsmartctl -s on\fP) and polls these and SCSI devices (equivalent to \fBsmartctl \-s on\fP) and polls these and SCSI devices
every 30 minutes (configurable), logging SMART errors and changes of every 30 minutes (configurable), logging SMART errors and changes of
SMART Attributes via the SYSLOG interface. The default location for SMART Attributes via the SYSLOG interface. The default location for
these SYSLOG notifications and warnings is system-dependent these SYSLOG notifications and warnings is system-dependent
(typically \fB/var/log/messages\fP or \fB/var/log/syslog\fP). (typically \fB/var/log/messages\fP or \fB/var/log/syslog\fP).
To change this default location, please see the \fB\'-l\'\fP To change this default location, please see the \*(Aq\-l\*(Aq
command-line option described below. command-line option described below.
.PP
In addition to logging to a file, \fBsmartd\fP can also be configured In addition to logging to a file, \fBsmartd\fP can also be configured
to send email warnings if problems are detected. Depending upon the to send email warnings if problems are detected. Depending upon the
type of problem, you may want to run self-tests on the disk, back up type of problem, you may want to run self-tests on the disk, back up
the disk, replace the disk, or use a manufacturer\'s utility to force the disk, replace the disk, or use a manufacturer's utility to force
reallocation of bad or unreadable disk sectors. If disk problems are reallocation of bad or unreadable disk sectors. If disk problems are
detected, please see the \fBsmartctl\fP manual page and the detected, please see the \fBsmartctl\fP manual page and the
\fBsmartmontools\fP web page/FAQ for further guidance. \fBsmartmontools\fP web page/FAQ for further guidance.
.PP
If you send a \fBUSR1\fP signal to \fBsmartd\fP it will immediately If you send a \fBUSR1\fP signal to \fBsmartd\fP it will immediately
check the status of the disks, and then return to polling the disks check the status of the disks, and then return to polling the disks
every 30 minutes. See the \fB\'\-i\'\fP option below for additional every 30 minutes.
details. See the \*(Aq\-i\*(Aq option below for additional details.
.PP
\fBsmartd\fP can be configured at start-up using the configuration \fBsmartd\fP can be configured at start-up using the configuration
file \fB/usr/local/etc/smartd.conf\fP (Windows: \fBEXEDIR/smartd.conf\fP). file \fB/usr/local/etc/smartd.conf\fP (Windows: \fBEXEDIR/smartd.conf\fP).
If the configuration file is subsequently modified, \fBsmartd\fP If the configuration file is subsequently modified, \fBsmartd\fP
can be told to re-read the configuration file by sending it a can be told to re-read the configuration file by sending it a
\fBHUP\fP signal, for example with the command: \fBHUP\fP signal, for example with the command:
.br .br
\fBkillall -HUP smartd\fP. \fBkillall \-HUP smartd\fP.
.br .br
.\" %IF OS Windows .\" %IF OS Windows
(Windows: See NOTES below.) (Windows: See NOTES below.)
.\" %ENDIF OS Windows .\" %ENDIF OS Windows
.PP
On startup, if \fBsmartd\fP finds a syntax error in the configuration On startup, if \fBsmartd\fP finds a syntax error in the configuration
file, it will print an error message and then exit. However if file, it will print an error message and then exit. However if
\fBsmartd\fP is already running, then is told with a \fBHUP\fP signal \fBsmartd\fP is already running, then is told with a \fBHUP\fP signal
@ -82,41 +99,43 @@ to re-read the configuration file, and then find a syntax error in
this file, it will print an error message and then continue, ignoring this file, it will print an error message and then continue, ignoring
the contents of the (faulty) configuration file, as if the \fBHUP\fP the contents of the (faulty) configuration file, as if the \fBHUP\fP
signal had never been received. signal had never been received.
.PP
When \fBsmartd\fP is running in debug mode, the \fBINT\fP signal When \fBsmartd\fP is running in debug mode, the \fBINT\fP signal
(normally generated from a shell with CONTROL-C) is treated in the (normally generated from a shell with CONTROL-C) is treated in the
same way as a \fBHUP\fP signal: it makes \fBsmartd\fP reload its same way as a \fBHUP\fP signal: it makes \fBsmartd\fP reload its
configuration file. To exit \fBsmartd\fP use CONTROL-\e configuration file.
To exit \fBsmartd\fP use CONTROL-\e.
.\" %IF OS Windows .\" %IF OS Windows
(Windows: CONTROL-Break). (Windows: CONTROL-Break).
.\" %ENDIF OS Windows .\" %ENDIF OS Windows
.PP
On startup, in the absence of the configuration file On startup, in the absence of the configuration file
\fB/usr/local/etc/smartd.conf\fP, the \fBsmartd\fP daemon first scans for all \fB/usr/local/etc/smartd.conf\fP, the \fBsmartd\fP daemon first scans for all
devices that support SMART. The scanning is done as follows: devices that support SMART. The scanning is done as follows:
.\" %IF OS Linux .\" %IF OS Linux
.IP \fBLINUX:\fP 9 .IP \fBLINUX:\fP 9
Examine all entries \fB"/dev/hd[a-t]"\fP for IDE/ATA Examine all entries \fB"/dev/hd[a\-t]"\fP for IDE/ATA
devices, and \fB"/dev/sd[a-z]"\fP, \fB"/dev/sd[a-c][a-z]"\fP devices, and \fB"/dev/sd[a\-z]"\fP, \fB"/dev/sd[a\-c][a\-z]"\fP
for ATA/SATA or SCSI/SAS devices. for ATA/SATA or SCSI/SAS devices.
Disks behind RAID controllers are not included. Disks behind RAID controllers are not included.
.Sp
[NEW EXPERIMENTAL SMARTD FEATURE] [NEW EXPERIMENTAL SMARTD FEATURE]
If directive \'\-d nvme\' If directive \*(Aq\-d nvme\*(Aq
.\" %IF ENABLE_NVME_DEVICESCAN .\" %IF ENABLE_NVME_DEVICESCAN
or no \'\-d\' directive or no \*(Aq\-d\*(Aq directive
.\" %ENDIF ENABLE_NVME_DEVICESCAN .\" %ENDIF ENABLE_NVME_DEVICESCAN
is specified, examine all entries \fB"/dev/nvme[0-99]"\fP for NVMe devices. is specified, examine all entries \fB"/dev/nvme[0\-99]"\fP for NVMe devices.
.\" %ENDIF OS Linux .\" %ENDIF OS Linux
.\" %IF OS FreeBSD .\" %IF OS FreeBSD
.IP \fBFREEBSD:\fP 9 .IP \fBFREEBSD:\fP 9
Authoritative list of disk devices is obtained from SCSI (CAM) and ATA subsystems. Authoritative list of disk devices is obtained from SCSI (CAM) and ATA
subsystems.
Disks behind RAID controllers are not included. Disks behind RAID controllers are not included.
.\" %ENDIF OS FreeBSD .\" %ENDIF OS FreeBSD
.\" %IF OS NetBSD OpenBSD .\" %IF OS NetBSD OpenBSD
.IP \fBNETBSD/OPENBSD:\fP 9 .IP \fBNETBSD/OPENBSD:\fP 9
Authoritative list of disk devices is obtained from sysctl Authoritative list of disk devices is obtained from sysctl
\'hw.disknames\'. \*(Aqhw.disknames\*(Aq.
.\" %ENDIF OS NetBSD OpenBSD .\" %ENDIF OS NetBSD OpenBSD
.\" %IF OS Solaris .\" %IF OS Solaris
.IP \fBSOLARIS:\fP 9 .IP \fBSOLARIS:\fP 9
@ -132,80 +151,89 @@ The IOService plane is scanned for ATA block storage devices.
Examine all entries \fB"/dev/sd[a\-z]"\fP, \fB"/dev/sd[a\-c][a\-z]"\fP Examine all entries \fB"/dev/sd[a\-z]"\fP, \fB"/dev/sd[a\-c][a\-z]"\fP
and \fB"/dev/sdd[a\-x]"\fP ("\\\\.\\PhysicalDrive[0\-127]") for and \fB"/dev/sdd[a\-x]"\fP ("\\\\.\\PhysicalDrive[0\-127]") for
IDE/(S)ATA and SCSI disk devices. IDE/(S)ATA and SCSI disk devices.
.Sp
If a 3ware 9000 controller is installed, examine all entries If a 3ware 9000 controller is installed, examine all entries
\fB"/dev/sdX,N"\fP for the first logical drive (\'unit\' \fB"/dev/sdX,N"\fP for the first logical drive (\*(Aqunit\*(Aq
\fB"/dev/sdX"\fP) and all physical disks (\'ports\' \fB",N"\fP) \fB"/dev/sdX"\fP) and all physical disks (\*(Aqports\*(Aq \fB",N"\fP)
detected behind this controller. Same for a second controller if present. detected behind this controller.
Same for a second controller if present.
If directive \'\-d csmi\' or no \'\-d\' directive is specified, .Sp
If directive \*(Aq\-d csmi\*(Aq or no \*(Aq\-d\*(Aq directive is specified,
examine all entries \fB"/dev/csmi[0\-9],N"\fP for drives behind an Intel examine all entries \fB"/dev/csmi[0\-9],N"\fP for drives behind an Intel
ICHxR controller with RST driver. ICHxR controller with RST driver.
.Sp
Disks behind Areca RAID controllers are not included. Disks behind Areca RAID controllers are not included.
.Sp
[NEW EXPERIMENTAL SMARTD FEATURE] [NEW EXPERIMENTAL SMARTD FEATURE]
If directive \'\-d nvme\' If directive \*(Aq\-d nvme\*(Aq
.\" %IF ENABLE_NVME_DEVICESCAN .\" %IF ENABLE_NVME_DEVICESCAN
or no \'\-d\' directive or no \*(Aq\-d\*(Aq directive
.\" %ENDIF ENABLE_NVME_DEVICESCAN .\" %ENDIF ENABLE_NVME_DEVICESCAN
is specified, examine all entries \fB"/dev/nvme[0-9]"\fP for NVMe devices. is specified, examine all entries \fB"/dev/sd[...]"\fP (see above)
and all entries \fB"/dev/nvme[0\-9]"\fP for NVMe devices.
.\" %ENDIF OS Windows Cygwin .\" %ENDIF OS Windows Cygwin
.PP .PP
\fBsmartd\fP then monitors \fBsmartd\fP then monitors
for \fIall\fP possible SMART errors (corresponding to the \fB\'\-a\'\fP for \fIall\fP possible SMART errors (corresponding to the \*(Aq\-a\*(Aq
Directive in the configuration file; see the \fBsmartd.conf\fP(5) man page). Directive in the configuration file; see the \fBsmartd.conf\fP(5) man page).
.Sp
.SH OPTIONS .SH OPTIONS
.TP .TP
.B \-A PREFIX, \-\-attributelog=PREFIX .B \-A PREFIX, \-\-attributelog=PREFIX
Writes \fBsmartd\fP attribute information (normalized and raw Writes \fBsmartd\fP attribute information (normalized and raw
attribute values) to files \'PREFIX\'\'MODEL\-SERIAL.ata.csv\' or \'PREFIX\'\'VENDOR\-MODEL\-SERIAL.scsi.csv\'. At each attribute values) to files \*(AqPREFIX\*(Aq\*(AqMODEL\-SERIAL.ata.csv\*(Aq
check cycle attributes are logged as a line of semicolon separated triplets or \*(AqPREFIX\*(Aq\*(AqVENDOR\-MODEL\-SERIAL.scsi.csv\*(Aq.
of the form "attribute-ID;attribute-norm-value;attribute-raw-value;". At each check cycle attributes are logged as a line of semicolon separated
For SCSI devices error counters and temperature recorded in the form "counter-name;counter-value;" triplets of the form "attribute-ID;attribute-norm-value;attribute-raw-value;".
For SCSI devices error counters and temperature recorded in the form
"counter-name;counter-value;".
Each line is led by a date string of the form "yyyy-mm-dd HH:MM:SS" (in UTC). Each line is led by a date string of the form "yyyy-mm-dd HH:MM:SS" (in UTC).
.Sp
.\" %IF ENABLE_ATTRIBUTELOG .\" %IF ENABLE_ATTRIBUTELOG
If this option is not specified, attribute information is written to files If this option is not specified, attribute information is written to files
\'/usr/local/var/lib/smartmontools/attrlog.MODEL\-SERIAL.ata.csv\'. \*(Aq/usr/local/var/lib/smartmontools/attrlog.MODEL\-SERIAL.ata.csv\*(Aq.
To disable attribute log files, specify this option with an empty string To disable attribute log files, specify this option with an empty string
argument: \'-A ""\'. argument: \*(Aq\-A ""\*(Aq.
.\" %ENDIF ENABLE_ATTRIBUTELOG .\" %ENDIF ENABLE_ATTRIBUTELOG
MODEL and SERIAL are build from drive identify information, invalid MODEL and SERIAL are build from drive identify information, invalid
characters are replaced by underline. characters are replaced by underline.
.Sp
If the PREFIX has the form \'/path/dir/\' (e.g. \'/var/lib/smartd/\'), then If the PREFIX has the form \*(Aq/path/dir/\*(Aq (e.g.\&
files \'MODEL\-SERIAL.ata.csv\' are created in directory \'/path/dir\'. \*(Aq/var/lib/smartd/\*(Aq), then files \*(AqMODEL\-SERIAL.ata.csv\*(Aq are
If the PREFIX has the form \'/path/name\' (e.g. \'/var/lib/misc/attrlog\-\'), created in directory \*(Aq/path/dir\*(Aq.
then files 'nameMODEL\-SERIAL.ata.csv' are created in directory '/path/'. If the PREFIX has the form \*(Aq/path/name\*(Aq (e.g.\&
\*(Aq/var/lib/misc/attrlog\-\*(Aq),
then files \*(AqnameMODEL\-SERIAL.ata.csv\*(Aq are created in directory
\*(Aq/path/\*(Aq.
The path must be absolute, except if debug mode is enabled. The path must be absolute, except if debug mode is enabled.
.TP .TP
.B \-B [+]FILE, \-\-drivedb=[+]FILE .B \-B [+]FILE, \-\-drivedb=[+]FILE
[ATA only] Read the drive database from FILE. The new database replaces [ATA only] Read the drive database from FILE. The new database replaces
the built in database by default. If \'+\' is specified, then the new entries the built in database by default. If \*(Aq+\*(Aq is specified, then the new
prepend the built in entries. entries prepend the built in entries.
Please see the \fBsmartctl\fP(8) man page for further details. Please see the \fBsmartctl\fP(8) man page for further details.
.TP .TP
.B \-c FILE, \-\-configfile=FILE .B \-c FILE, \-\-configfile=FILE
Read \fBsmartd\fP configuration Directives from FILE, instead of from Read \fBsmartd\fP configuration Directives from FILE, instead of from
the default location \fB/usr/local/etc/smartd.conf\fP (Windows: \fBEXEDIR/smartd.conf\fP). the default location \fB/usr/local/etc/smartd.conf\fP
(Windows: \fBEXEDIR/smartd.conf\fP).
If FILE does \fBnot\fP exist, then \fBsmartd\fP will print an error If FILE does \fBnot\fP exist, then \fBsmartd\fP will print an error
message and exit with nonzero status. Thus, \'\-c /usr/local/etc/smartd.conf\' message and exit with nonzero status.
can be used to verify the existence of the default configuration file. Thus, \*(Aq\-c /usr/local/etc/smartd.conf\*(Aq can be used to verify the
existence of the default configuration file.
By using \'\-\' for FILE, the configuration is read from standard .Sp
input. This is useful for commands like: By using \*(Aq\-\*(Aq for FILE, the configuration is read from standard input.
.nf This is useful for commands like:
.br
.B echo /dev/sdb \-m user@home \-M test | smartd \-c \- \-q onecheck .B echo /dev/sdb \-m user@home \-M test | smartd \-c \- \-q onecheck
.fi .br
to perform quick and simple checks without a configuration file. to perform quick and simple checks without a configuration file.
.\" %IF ENABLE_CAPABILITIES .\" %IF ENABLE_CAPABILITIES
.TP .TP
.B \-C, \-\-capabilities .B \-C, \-\-capabilities
[Linux only] Use libcap-ng to drop unneeded Linux process \fBcapabilities\fP(7). [Linux only] Use libcap-ng to drop unneeded Linux process \fBcapabilities\fP(7).
The following capabilities are kept: CAP_SYS_ADMIN, CAP_SYS_RAWIO, CAP_MKNOD. The following capabilities are kept: CAP_SYS_ADMIN, CAP_SYS_RAWIO, CAP_MKNOD.
.Sp
Warning: Mail notification does not work when used. Warning: Mail notification does not work when used.
.\" %ENDIF ENABLE_CAPABILITIES .\" %ENDIF ENABLE_CAPABILITIES
.TP .TP
@ -220,10 +248,10 @@ terminal with CONTROL-C) makes \fBsmartd\fP reload its configuration
file. Please use CONTROL-\e to exit file. Please use CONTROL-\e to exit
.\" %IF OS Windows .\" %IF OS Windows
(Windows: CONTROL-Break). (Windows: CONTROL-Break).
.Sp
[Windows only] The "debug" mode can be toggled by the command [Windows only] The "debug" mode can be toggled by the command
\fBsmartd sigusr2\fP. A new console for debug output is opened when \fBsmartd sigusr2\fP.
debug mode is enabled. A new console for debug output is opened when debug mode is enabled.
.\" %ENDIF OS Windows .\" %ENDIF OS Windows
.TP .TP
.B \-D, \-\-showdirectives .B \-D, \-\-showdirectives
@ -239,19 +267,19 @@ Prints usage message to STDOUT and exits.
Sets the interval between disk checks to \fIN\fP seconds, where Sets the interval between disk checks to \fIN\fP seconds, where
\fIN\fP is a decimal integer. The minimum allowed value is ten and \fIN\fP is a decimal integer. The minimum allowed value is ten and
the maximum is the largest positive integer that can be represented on the maximum is the largest positive integer that can be represented on
your system (often 2^31-1). The default is 1800 seconds. your system (often 2^31\-1). The default is 1800 seconds.
.Sp
Note that the superuser can make \fBsmartd\fP check the status of the Note that the superuser can make \fBsmartd\fP check the status of the
disks at any time by sending it the \fBSIGUSR1\fP signal, for example disks at any time by sending it the \fBSIGUSR1\fP signal, for example
with the command: with the command:
.nf .br
.B kill -SIGUSR1 <pid> .B kill \-SIGUSR1 <pid>
.fi .br
where \fB<pid>\fP is the process id number of \fBsmartd\fP. One may where \fB<pid>\fP is the process id number of \fBsmartd\fP. One may
also use: also use:
.nf .br
.B killall -USR1 smartd .B killall \-USR1 smartd
.fi .br
for the same purpose. for the same purpose.
.br .br
.\" %IF OS Windows .\" %IF OS Windows
@ -264,46 +292,46 @@ Here FACILITY is one of \fIlocal0\fP, \fIlocal1\fP, ..., \fIlocal7\fP,
or \fIdaemon\fP [default]. If this command-line option is not used, or \fIdaemon\fP [default]. If this command-line option is not used,
then by default messages from \fBsmartd\fP are logged to the facility then by default messages from \fBsmartd\fP are logged to the facility
\fIdaemon\fP. \fIdaemon\fP.
.Sp
If you would like to have \fBsmartd\fP messages logged somewhere other If you would like to have \fBsmartd\fP messages logged somewhere other
than the default location, include (for example) \'\-l local3\' in its than the default location, include (for example) \*(Aq\-l local3\*(Aq in its
start up argument list. start up argument list.
Tell the syslog daemon to log all messages from facility \fBlocal3\fP Tell the syslog daemon to log all messages from facility \fBlocal3\fP
to (for example) \'/var/log/smartd.log\'. to (for example) \*(Aq/var/log/smartd.log\*(Aq.
.Sp
For more detailed information, please refer to the man pages for For more detailed information, please refer to the man pages for
the local syslog daemon, typically \fBsyslogd\fP(8), \fBsyslog-ng\fP(8) the local syslog daemon, typically \fBsyslogd\fP(8), \fBsyslog-ng\fP(8)
or \fBrsyslogd\fP(8). or \fBrsyslogd\fP(8).
.\" %IF OS Cygwin .\" %IF OS Cygwin
.Sp
Cygwin: If no \fBsyslogd\fP is running, the \'\-l\' option has no effect. Cygwin: If no \fBsyslogd\fP is running, the \*(Aq\-l\*(Aq option has no effect.
In this case, all \fBsyslog\fP messages are written to Windows event log. In this case, all \fBsyslog\fP messages are written to Windows event log.
.\" %ENDIF OS Cygwin .\" %ENDIF OS Cygwin
.\" %IF OS Windows .\" %IF OS Windows
.Sp
Windows: Some \fBsyslog\fP functionality is implemented Windows: Some \fBsyslog\fP functionality is implemented
internally in \fBsmartd\fP as follows: If no \'\-l\' option internally in \fBsmartd\fP as follows: If no \*(Aq\-l\*(Aq option
(or \'\-l daemon\') is specified, messages are written to Windows (or \*(Aq\-l daemon\*(Aq) is specified, messages are written to Windows
event log or to file \fB./smartd.log\fP if event log is not available event log or to file \fB./smartd.log\fP if event log is not available
(access denied). By specifying other values of FACILITY, (access denied).
log output is redirected as follows: By specifying other values of FACILITY, log output is redirected as follows:
\'\-l local0\' to file \fB./smartd.log\fP, \*(Aq\-l local0\*(Aq to file \fB./smartd.log\fP,
\'\-l local1\' to standard output (redirect with \'>\' to any file), \*(Aq\-l local1\*(Aq to standard output (redirect with \*(Aq>\*(Aq to any file),
\'\-l local2\' to standard error, \*(Aq\-l local2\*(Aq to standard error,
\'\-l local[3-7]\': to file \fB./smartd[1-5].log\fP. \*(Aq\-l local[3\-7]\*(Aq: to file \fB./smartd[1\-5].log\fP.
.\" %ENDIF OS Windows .\" %ENDIF OS Windows
.TP .TP
.B \-n, \-\-no\-fork .B \-n, \-\-no\-fork
Do not fork into background; this is useful when executed from modern Do not fork into background; this is useful when executed from modern
init methods like initng, minit, supervise or systemd. init methods like initng, minit, supervise or systemd.
.\" %IF OS Cygwin .\" %IF OS Cygwin
.Sp
On Cygwin, this allows running \fBsmartd\fP as service via cygrunsrv, On Cygwin, this allows running \fBsmartd\fP as service via cygrunsrv,
see NOTES below. see NOTES below.
.\" %ENDIF OS Cygwin .\" %ENDIF OS Cygwin
.\" %IF OS Windows .\" %IF OS Windows
.Sp
On Windows, this option is not available, use \'\-\-service\' instead. On Windows, this option is not available, use \*(Aq\-\-service\*(Aq instead.
.\" %ENDIF OS Windows .\" %ENDIF OS Windows
.TP .TP
.B \-p NAME, \-\-pidfile=NAME .B \-p NAME, \-\-pidfile=NAME
@ -317,37 +345,37 @@ pidfile is removed.
.B \-q WHEN, \-\-quit=WHEN .B \-q WHEN, \-\-quit=WHEN
Specifies when, if ever, \fBsmartd\fP should exit. The valid Specifies when, if ever, \fBsmartd\fP should exit. The valid
arguments are to this option are: arguments are to this option are:
.Sp
.I nodev .I nodev
\- Exit if there are no devices to monitor, or if any errors are found \- Exit if there are no devices to monitor, or if any errors are found
at startup in the configuration file. This is the default. at startup in the configuration file. This is the default.
.Sp
.I errors .I errors
\- Exit if there are no devices to monitor, or if any errors are found \- Exit if there are no devices to monitor, or if any errors are found
in the configuration file /usr/local/etc/smartd.conf at startup or whenever it in the configuration file /usr/local/etc/smartd.conf at startup or whenever it
is reloaded. is reloaded.
.Sp
.I nodevstartup .I nodevstartup
\- Exit if there are no devices to monitor at startup. But continue \- Exit if there are no devices to monitor at startup. But continue
to run if no devices are found whenever the configuration file is to run if no devices are found whenever the configuration file is
reloaded. reloaded.
.Sp
.I never .I never
\- Only exit if a fatal error occurs (no remaining system memory, \- Only exit if a fatal error occurs (no remaining system memory,
invalid command line arguments). In this mode, even if there are no invalid command line arguments). In this mode, even if there are no
devices to monitor, or if the configuration file devices to monitor, or if the configuration file
\fB/usr/local/etc/smartd.conf\fP has errors, \fBsmartd\fP will continue to run, \fB/usr/local/etc/smartd.conf\fP has errors, \fBsmartd\fP will continue to run,
waiting to load a configuration file listing valid devices. waiting to load a configuration file listing valid devices.
.Sp
.I onecheck .I onecheck
\- Start \fBsmartd\fP in debug mode, then register devices, then check \- Start \fBsmartd\fP in debug mode, then register devices, then check
device\'s SMART status once, and then exit with zero exit status if all device's SMART status once, and then exit with zero exit status if all
of these steps worked correctly. of these steps worked correctly.
.Sp
This last option is intended for \'distribution-writers\' who want to This last option is intended for \*(Aqdistribution-writers\*(Aq who want to
create automated scripts to determine whether or not to automatically create automated scripts to determine whether or not to automatically
start up \fBsmartd\fP after installing smartmontools. After starting start up \fBsmartd\fP after installing smartmontools. After starting
\fBsmartd\fP with this command-line option, the distribution\'s install \fBsmartd\fP with this command-line option, the distribution's install
scripts should wait a reasonable length of time (say ten seconds). If scripts should wait a reasonable length of time (say ten seconds). If
\fBsmartd\fP has not exited with zero status by that time, the script \fBsmartd\fP has not exited with zero status by that time, the script
should send \fBsmartd\fP a SIGTERM or SIGKILL and assume that should send \fBsmartd\fP a SIGTERM or SIGKILL and assume that
@ -356,14 +384,14 @@ should send \fBsmartd\fP a SIGTERM or SIGKILL and assume that
\fBsmartd\fP in normal daemon mode. If \fBsmartd\fP is unable to \fBsmartd\fP in normal daemon mode. If \fBsmartd\fP is unable to
monitor any devices or encounters other problems then it will return monitor any devices or encounters other problems then it will return
with non-zero exit status. with non-zero exit status.
.Sp
.I showtests .I showtests
\- Start \fBsmartd\fP in debug mode, then register devices, then write \- Start \fBsmartd\fP in debug mode, then register devices, then write
a list of future scheduled self tests to stdout, and then exit with zero a list of future scheduled self tests to stdout, and then exit with zero
exit status if all of these steps worked correctly. exit status if all of these steps worked correctly.
Device's SMART status is not checked. Device's SMART status is not checked.
.Sp
This option is intended to test whether the '\-s REGEX' directives in This option is intended to test whether the \*(Aq\-s REGEX\*(Aq directives in
smartd.conf will have the desired effect. The output lists the next test smartd.conf will have the desired effect. The output lists the next test
schedules, limited to 5 tests per type and device. This is followed by a schedules, limited to 5 tests per type and device. This is followed by a
summary of all tests of each device within the next 90 days. summary of all tests of each device within the next 90 days.
@ -381,53 +409,58 @@ When used just once, it shows a record of the ioctl() transactions
with the device. When used more than once, the detail of these ioctl() with the device. When used more than once, the detail of these ioctl()
transactions are reported in greater detail. The valid arguments to transactions are reported in greater detail. The valid arguments to
this option are: this option are:
.Sp
.I ioctl .I ioctl
\- report all ioctl() transactions. \- report all ioctl() transactions.
.Sp
.I ataioctl .I ataioctl
\- report only ioctl() transactions with ATA devices. \- report only ioctl() transactions with ATA devices.
.Sp
.I scsiioctl .I scsiioctl
\- report only ioctl() transactions with SCSI devices. \- report only ioctl() transactions with SCSI devices.
.Sp
.\" %IF OS FreeBSD Linux Windows Cygwin .\" %IF OS Darwin FreeBSD Linux NetBSD Windows Cygwin
.I nvmeioctl .I nvmeioctl
\- [FreeBSD, Linux, Windows and Cygwin only] \- [NEW EXPERIMENTAL SMARTD FEATURE]
[NEW EXPERIMENTAL SMARTD FEATURE]
report only ioctl() transactions with NVMe devices. report only ioctl() transactions with NVMe devices.
.Sp
.\" %ENDIF OS FreeBSD Linux Windows Cygwin .\" %ENDIF OS Darwin FreeBSD Linux NetBSD Windows Cygwin
Any argument may include a positive integer to specify the level of Any argument may include a positive integer to specify the level of
detail that should be reported. The argument should be followed by a detail that should be reported. The argument should be followed by a
comma then the integer with no spaces. For example, \fIataioctl,2\fP comma then the integer with no spaces. For example, \fIataioctl,2\fP
The default level is 1, so \'\-r ataioctl,1\' and \'\-r ataioctl\' are The default level is 1, so \*(Aq\-r ataioctl,1\*(Aq and
equivalent. \*(Aq\-r ataioctl\*(Aq are equivalent.
.TP .TP
.B \-s PREFIX, \-\-savestates=PREFIX .B \-s PREFIX, \-\-savestates=PREFIX
Reads/writes \fBsmartd\fP state information from/to files Reads/writes \fBsmartd\fP state information from/to files
\'PREFIX\'\'MODEL\-SERIAL.ata.state\' or \'PREFIX\'\'VENDOR\-MODEL\-SERIAL.scsi.state\'. \*(AqPREFIX\*(Aq\*(AqMODEL\-SERIAL.ata.state\*(Aq or
\*(AqPREFIX\*(Aq\*(AqVENDOR\-MODEL\-SERIAL.scsi.state\*(Aq.
This preserves SMART attributes, drive min and max temperatures (\-W directive), This preserves SMART attributes, drive min and max temperatures (\-W directive),
info about last sent warning email info about last sent warning email
(\-m directive), and the time of next check of the self-test REGEXP (\-m directive), and the time of next check of the self-test REGEXP
(\-s directive) across boot cycles. (\-s directive) across boot cycles.
.Sp
.\" %IF ENABLE_SAVESTATES .\" %IF ENABLE_SAVESTATES
If this option is not specified, state information is maintained in files If this option is not specified, state information is maintained in files
\'/usr/local/var/lib/smartmontools/smartd.MODEL\-SERIAL.ata.state\' for ATA devices and \*(Aq/usr/local/var/lib/smartmontools/smartd.MODEL\-SERIAL.ata.state\*(Aq
\'/usr/local/var/lib/smartmontools/smartd.VENDOR\-MODEL\-SERIAL.scsi.state\' for SCSI devices. for ATA devices and
\*(Aq/usr/local/var/lib/smartmontools/smartd.VENDOR\-MODEL\-SERIAL.scsi.state\*(Aq
for SCSI devices.
To disable state files, specify this option with an empty string To disable state files, specify this option with an empty string
argument: \'\-s ""\'. argument: \*(Aq\-s ""\*(Aq.
.\" %ENDIF ENABLE_SAVESTATES .\" %ENDIF ENABLE_SAVESTATES
MODEL and SERIAL are build from drive identify information, invalid MODEL and SERIAL are build from drive identify information, invalid
characters are replaced by underline. characters are replaced by underline.
.Sp
If the PREFIX has the form \'/path/dir/\' (e.g. \'/var/lib/smartd/\'), then If the PREFIX has the form \*(Aq/path/dir/\*(Aq (e.g.\&
files \'MODEL\-SERIAL.ata.state\' are created in directory \'/path/dir\'. \*(Aq/var/lib/smartd/\*(Aq), then files \*(AqMODEL\-SERIAL.ata.state\*(Aq are
If the PREFIX has the form \'/path/name\' (e.g. \'/var/lib/misc/smartd\-\'), created in directory \*(Aq/path/dir\*(Aq.
then files 'nameMODEL\-SERIAL.ata.state' are created in directory '/path/'. If the PREFIX has the form \*(Aq/path/name\*(Aq (e.g.\&
\*(Aq/var/lib/misc/smartd\-\*(Aq),
then files \*(AqnameMODEL\-SERIAL.ata.state\*(Aq are created in directory
\*(Aq/path/\*(Aq.
The path must be absolute, except if debug mode is enabled. The path must be absolute, except if debug mode is enabled.
.Sp
The state information files are read on smartd startup. The files are The state information files are read on smartd startup. The files are
always (re)written after reading the configuration file, before rereading always (re)written after reading the configuration file, before rereading
the configuration file (SIGHUP), before smartd shutdown, and after a check the configuration file (SIGHUP), before smartd shutdown, and after a check
@ -453,190 +486,196 @@ The default script is
.B \-\-service .B \-\-service
[Windows only] Enables \fBsmartd\fP to run as a Windows service. [Windows only] Enables \fBsmartd\fP to run as a Windows service.
The option must be specified in the service command line as the first The option must be specified in the service command line as the first
argument. It should not be used from console. argument.
It should not be used from console.
See NOTES below for details. See NOTES below for details.
.\" %ENDIF OS Windows .\" %ENDIF OS Windows
.TP .TP
.B \-V, \-\-version, \-\-license, \-\-copyright .B \-V, \-\-version, \-\-license, \-\-copyright
Prints version, copyright, license, home page and SVN revision Prints version, copyright, license, home page and SVN revision
information for your copy of \fBsmartd\fP to STDOUT and then exits. information for your copy of \fBsmartd\fP to STDOUT and then exits.
Please include this information if you are reporting bugs or problems. .Sp
.SH EXAMPLES .SH EXAMPLES
.B smartd .B smartd
.br .br
Runs the daemon in forked mode. This is the normal way to run Runs the daemon in forked mode. This is the normal way to run
\fBsmartd\fP. \fBsmartd\fP.
Entries are logged to SYSLOG. Entries are logged to SYSLOG.
.Sp
.B smartd -d -i 30 .B smartd \-d \-i 30
.br .br
Run in foreground (debug) mode, checking the disk status Run in foreground (debug) mode, checking the disk status
every 30 seconds. every 30 seconds.
.Sp
.B smartd -q onecheck .B smartd \-q onecheck
.br .br
Registers devices, and checks the status of the devices exactly Registers devices, and checks the status of the devices exactly
once. The exit status (the shell once.
The exit status (the shell
.B $? .B $?
variable) will be zero if all went well, and nonzero if no devices variable) will be zero if all went well, and nonzero if no devices
were detected or some other problem was encountered. were detected or some other problem was encountered.
.\" %IF ENABLE_INITSCRIPT .\" %IF ENABLE_INITSCRIPT
.Sp
Note that \fBsmartmontools\fP provides a start-up script in Note that \fBsmartmontools\fP provides a start-up script in
\fB/usr/local/etc/rc.d/init.d/smartd\fP which is responsible for starting and \fB/usr/local/etc/rc.d/init.d/smartd\fP which is responsible for starting and
stopping the daemon via the normal init interface. Using this script, stopping the daemon via the normal init interface. Using this script,
you can start \fBsmartd\fP by giving the command: you can start \fBsmartd\fP by giving the command:
.nf .br
.B /usr/local/etc/rc.d/init.d/smartd start .B /usr/local/etc/rc.d/init.d/smartd start
.fi .br
and stop it by using the command: and stop it by using the command:
.nf .br
.B /usr/local/etc/rc.d/init.d/smartd stop .B /usr/local/etc/rc.d/init.d/smartd stop
.fi
.\" %ENDIF ENABLE_INITSCRIPT .\" %ENDIF ENABLE_INITSCRIPT
.Sp
.SH CONFIGURATION .SH CONFIGURATION
The syntax of the \fBsmartd.conf\fP(5) file is discussed separately. The syntax of the \fBsmartd.conf\fP(5) file is discussed separately.
.Sp
.SH NOTES .SH NOTES
\fBsmartd\fP \fBsmartd\fP
will make log entries at loglevel will make log entries at loglevel
.B LOG_INFO .B LOG_INFO
if the Normalized SMART Attribute values have changed, as reported using the if the Normalized SMART Attribute values have changed, as reported using the
.B \'\-t\', \'\-p\', .B \*(Aq\-t\*(Aq, \*(Aq\-p\*(Aq,
or or
.B \'\-u\' .B \*(Aq\-u\*(Aq
Directives. For example: Directives.
.nf For example:
.B \'Device: /dev/sda, SMART Attribute: 194 Temperature_Celsius changed from 94 to 93\' .br
.fi .B \*(AqDevice: /dev/sda, SMART Attribute: 194 Temperature_Celsius changed from 94 to 93\*(Aq
Note that in this message, the value given is the \'Normalized\' not the \'Raw\' .br
Attribute value (the disk temperature in this case is about 22 Note that in this message, the value given is the \*(AqNormalized\*(Aq not the
\*(AqRaw\*(Aq Attribute value (the disk temperature in this case is about 22
Celsius). The Celsius). The
.B \'-R\' .B \*(Aq\-R\*(Aq
and and
.B \'-r\' .B \*(Aq\-r\*(Aq
Directives modify this behavior, so that the information is printed Directives modify this behavior, so that the information is printed
with the Raw values as well, for example: with the Raw values as well, for example:
.nf .br
.B \'Device: /dev/sda, SMART Attribute: 194 Temperature_Celsius changed from 94 [Raw 22] to 93 [Raw 23]\' .B \*(AqDevice: /dev/sda, SMART Attribute: 194 Temperature_Celsius changed from 94 [Raw 22] to 93 [Raw 23]\*(Aq
.fi .br
Here the Raw values are the actual disk temperatures in Celsius. The Here the Raw values are the actual disk temperatures in Celsius. The
way in which the Raw values are printed, and the names under which the way in which the Raw values are printed, and the names under which the
Attributes are reported, is governed by the various Attributes are reported, is governed by the various
.B \'-v Num,Description\' .B \*(Aq\-v Num,Description\*(Aq
Directives described previously. Directives described previously.
.PP
Please see the Please see the
.B smartctl .B smartctl
manual page for further explanation of the differences between manual page for further explanation of the differences between
Normalized and Raw Attribute values. Normalized and Raw Attribute values.
.PP
\fBsmartd\fP \fBsmartd\fP
will make log entries at loglevel will make log entries at loglevel
.B LOG_CRIT .B LOG_CRIT
if a SMART Attribute has failed, for example: if a SMART Attribute has failed, for example:
.nf .br
.B \'Device: /dev/sdc, Failed SMART Attribute: 5 Reallocated_Sector_Ct\' .B \*(AqDevice: /dev/sdc, Failed SMART Attribute: 5 Reallocated_Sector_Ct\*(Aq
.fi .br
This loglevel is used for reporting enabled by the This loglevel is used for reporting enabled by the
.B \'\-H\', \-f\', \'\-l\ selftest\', .B \*(Aq\-H\*(Aq, \-f\*(Aq, \*(Aq\-l\ selftest\*(Aq,
and and
.B \'\-l\ error\' .B \*(Aq\-l\ error\*(Aq
Directives. Entries reporting failure of SMART Prefailure Attributes Directives. Entries reporting failure of SMART Prefailure Attributes
should not be ignored: they mean that the disk is failing. Use the should not be ignored: they mean that the disk is failing. Use the
.B smartctl .B smartctl
utility to investigate. utility to investigate.
.\" %IF OS Solaris .\" %IF OS Solaris
.PP
Under Solaris with the default \fB/etc/syslog.conf\fP configuration, Under Solaris with the default \fB/etc/syslog.conf\fP configuration,
messages below loglevel \fBLOG_NOTICE\fP will \fBnot\fP be recorded. messages below loglevel \fBLOG_NOTICE\fP will \fBnot\fP be recorded.
Hence all \fBsmartd\fP messages with loglevel \fBLOG_INFO\fP will be Hence all \fBsmartd\fP messages with loglevel \fBLOG_INFO\fP will be
lost. If you want to use the existing daemon facility to log all lost. If you want to use the existing daemon facility to log all
messages from \fBsmartd\fP, you should change \fB/etc/syslog.conf\fP messages from \fBsmartd\fP, you should change \fB/etc/syslog.conf\fP
from: from:
.nf .Vb 1
...;daemon.notice;... /var/adm/messages ...;daemon.notice;... /var/adm/messages
.fi .Ve
to read: to read:
.nf .Vb 1
...;daemon.info;... /var/adm/messages ...;daemon.info;... /var/adm/messages
.fi .Ve
Alternatively, you can use a local facility to log messages: please Alternatively, you can use a local facility to log messages: please
see the \fBsmartd\fP '\-l' command-line option described above. see the \fBsmartd\fP \*(Aq\-l\*(Aq command-line option described above.
.\" %ENDIF OS Solaris .\" %ENDIF OS Solaris
.\" %IF OS Cygwin .\" %IF OS Cygwin
.PP
The Cygwin Version of \fBsmartd\fP can be run as a service via the The Cygwin Version of \fBsmartd\fP can be run as a service via the
cygrunsrv tool. cygrunsrv tool.
.\" %IF ENABLE_INITSCRIPT .\" %IF ENABLE_INITSCRIPT
The start-up script provides Cygwin-specific commands to install and The start-up script provides Cygwin-specific commands to install and
remove the service: remove the service:
.nf .br
.B /usr/local/etc/rc.d/init.d/smartd install [options] .B /usr/local/etc/rc.d/init.d/smartd install [options]
.br
.B /usr/local/etc/rc.d/init.d/smartd remove .B /usr/local/etc/rc.d/init.d/smartd remove
.fi .br
The service can be started and stopped by the start-up script as usual The service can be started and stopped by the start-up script as usual
(see \fBEXAMPLES\fP above). (see \fBEXAMPLES\fP above).
.\" %ENDIF ENABLE_INITSCRIPT .\" %ENDIF ENABLE_INITSCRIPT
.\" %ENDIF OS Cygwin .\" %ENDIF OS Cygwin
.\" %IF OS Windows .\" %IF OS Windows
.PP
On Windows, the log messages are written to the event log or to a file. On Windows, the log messages are written to the event log or to a file.
See documentation of the '\-l FACILITY' option above for details. See documentation of the \*(Aq\-l FACILITY\*(Aq option above for details.
.PP
On Windows, the following built-in commands can be used to control On Windows, the following built-in commands can be used to control
\fBsmartd\fP, if running as a daemon: \fBsmartd\fP, if running as a daemon:
.PP
\'\fBsmartd status\fP\' \- check status \*(Aq\fBsmartd status\fP\*(Aq \- check status
.br
\'\fBsmartd stop\fP\' \- stop smartd \*(Aq\fBsmartd stop\fP\*(Aq \- stop smartd
.br
\'\fBsmartd reload\fP\' \- reread config file \*(Aq\fBsmartd reload\fP\*(Aq \- reread config file
.br
\'\fBsmartd restart\fP\' \- restart smartd \*(Aq\fBsmartd restart\fP\*(Aq \- restart smartd
.br
\'\fBsmartd sigusr1\fP\' \- check disks now \*(Aq\fBsmartd sigusr1\fP\*(Aq \- check disks now
.br
\'\fBsmartd sigusr2\fP\' \- toggle debug mode \*(Aq\fBsmartd sigusr2\fP\*(Aq \- toggle debug mode
.PP
The Windows Version of \fBsmartd\fP has buildin support for services: The Windows Version of \fBsmartd\fP has buildin support for services:
.PP
\'\fBsmartd install [options]\fP\' installs a service \*(Aq\fBsmartd install [options]\fP\*(Aq installs a service
named "smartd" (display name "SmartD Service") using the command line named "smartd" (display name "SmartD Service") using the command line
\'/INSTALLPATH/smartd.exe \-\-service [options]\'. \*(Aq/INSTALLPATH/smartd.exe \-\-service [options]\*(Aq.
This also installs smartd.exe as a event message file for the Windows This also installs smartd.exe as a event message file for the Windows
event viewer. event viewer.
.PP
\'\fBsmartd remove\fP\' can later be used to remove the service and \*(Aq\fBsmartd remove\fP\*(Aq can later be used to remove the service and
event message entries from the registry. event message entries from the registry.
.PP
Upon startup, the smartd service changes the working directory Upon startup, the smartd service changes the working directory
to its own installation path. If smartd.conf and blat.exe are stored to its own installation path. If smartd.conf and blat.exe are stored
in this directory, no \'-c\' option and \'-M exec\' directive is needed. in this directory, no \*(Aq\-c\*(Aq option and \*(Aq\-M exec\*(Aq directive
is needed.
The debug mode (\'\-d\', \'\-q onecheck\') does not work if smartd is .PP
running as service. The debug mode (\*(Aq\-d\*(Aq, \*(Aq\-q onecheck\*(Aq) does not work if
smartd is running as service.
The service can be controlled as usual with Windows commands \'net\' .PP
or \'sc\' (\'\fBnet start smartd\fP\', \'\fBnet stop smartd\fP\'). The service can be controlled as usual with Windows commands \*(Aqnet\*(Aq
or \*(Aqsc\*(Aq (\*(Aq\fBnet start smartd\fP\*(Aq,
Pausing the service (\'\fBnet pause smartd\fP\') sets the interval between \*(Aq\fBnet stop smartd\fP\*(Aq).
disk checks (\'\-i N\') to infinite. .PP
Pausing the service (\*(Aq\fBnet pause smartd\fP\*(Aq) sets the interval
Continuing the paused service (\'\fBnet continue smartd\fP\') resets the between disk checks (\*(Aq\-i N\*(Aq) to infinite.
interval and rereads the configuration file immediately (like \fBSIGHUP\fP): .PP
Continuing the paused service (\*(Aq\fBnet continue smartd\fP\*(Aq) resets the
Continuing a still running service (\'\fBnet continue smartd\fP\' without interval and rereads the configuration file immediately (like \fBSIGHUP\fP).
preceding \'\fBnet pause smartd\fP\') does not reread configuration but The \*(AqPARAMCHANGE\*(Aq service control command (\*(Aq\fBsc control smartd
paramchange\fP\*(Aq) has the same effect regardless of paused state.
.PP
Continuing a still running service (\*(Aq\fBnet continue smartd\fP\*(Aq without
preceding \*(Aq\fBnet pause smartd\fP\*(Aq) does not reread configuration but
checks disks immediately (like \fBSIGUSR1\fP). checks disks immediately (like \fBSIGUSR1\fP).
.\" %ENDIF OS Windows .\" %ENDIF OS Windows
.Sp
.SH LOG TIMESTAMP TIMEZONE .SH LOG TIMESTAMP TIMEZONE
When \fBsmartd\fP makes log entries, these are time-stamped. The time When \fBsmartd\fP makes log entries, these are time-stamped. The time
stamps are in the computer's local time zone, which is generally set stamps are in the computer's local time zone, which is generally set
using either the environment variable \'\fBTZ\fP\' or using a using either the environment variable \*(Aq\fBTZ\fP\*(Aq or using a
time-zone file such as \fB/etc/localtime\fP. You may wish to change time-zone file such as \fB/etc/localtime\fP. You may wish to change
the timezone while \fBsmartd\fP is running (for example, if you carry the timezone while \fBsmartd\fP is running (for example, if you carry
a laptop to a new time-zone and don't reboot it). Due to a bug in the a laptop to a new time-zone and don't reboot it). Due to a bug in the
@ -644,14 +683,15 @@ a laptop to a new time-zone and don't reboot it). Due to a bug in the
time-zone stamps of \fBsmartd\fP might not change. For some systems, time-zone stamps of \fBsmartd\fP might not change. For some systems,
\fBsmartd\fP will work around this problem \fIif\fP the time-zone is \fBsmartd\fP will work around this problem \fIif\fP the time-zone is
set using \fB/etc/localtime\fP. The work-around \fIfails\fP if the set using \fB/etc/localtime\fP. The work-around \fIfails\fP if the
time-zone is set using the \'\fBTZ\fP\' variable (or a file that it time-zone is set using the \*(Aq\fBTZ\fP\*(Aq variable (or a file that it
points to). points to).
.Sp
.SH EXIT STATUS .SH EXIT STATUS
The exit status (return value) of \fBsmartd\fP can have the following values: The exit status (return value) of \fBsmartd\fP can have the following values:
.TP .TP
.B 0: .B 0:
Daemon startup successful, or \fBsmartd\fP was killed by a SIGTERM (or in debug mode, a SIGQUIT). Daemon startup successful, or \fBsmartd\fP was killed by a SIGTERM
(or in debug mode, a SIGQUIT).
.TP .TP
.B 1: .B 1:
Commandline did not parse. Commandline did not parse.
@ -663,10 +703,11 @@ There was a syntax error in the config file.
Forking the daemon failed. Forking the daemon failed.
.TP .TP
.B 4: .B 4:
Couldn\'t create PID file. Couldn't create PID file.
.TP .TP
.B 5: .B 5:
Config file does not exist (only returned in conjunction with the \'\-c\' option). Config file does not exist (only returned in conjunction with the \*(Aq\-c\*(Aq
option).
.TP .TP
.B 6: .B 6:
Config file exists, but cannot be read. Config file exists, but cannot be read.
@ -676,7 +717,7 @@ Config file exists, but cannot be read.
ran out of memory during startup. ran out of memory during startup.
.TP .TP
.B 10: .B 10:
An inconsistency was found in \fBsmartd\fP\'s internal data An inconsistency was found in \fBsmartd\fP's internal data
structures. This should never happen. It must be due to either a structures. This should never happen. It must be due to either a
coding or compiler bug. \fIPlease\fP report such failures to coding or compiler bug. \fIPlease\fP report such failures to
smartmontools developers, see REPORTING BUGS below. smartmontools developers, see REPORTING BUGS below.
@ -684,11 +725,11 @@ smartmontools developers, see REPORTING BUGS below.
.B 16: .B 16:
A device explicitly listed in A device explicitly listed in
.B /usr/local/etc/smartd.conf .B /usr/local/etc/smartd.conf
can\'t be monitored. can't be monitored.
.TP .TP
.B 17: .B 17:
\fBsmartd\fP \fBsmartd\fP
didn\'t find any devices to monitor. didn't find any devices to monitor.
.TP .TP
.B 254: .B 254:
When in daemon mode, When in daemon mode,
@ -704,7 +745,7 @@ was killed by a signal that is not explicitly listed above. The exit
status is then 128 plus the signal number. For example if status is then 128 plus the signal number. For example if
\fBsmartd\fP \fBsmartd\fP
is killed by SIGKILL (signal 9) then the exit status is 137. is killed by SIGKILL (signal 9) then the exit status is 137.
.Sp
.\" %IF NOT OS Windows .\" %IF NOT OS Windows
.SH FILES .SH FILES
.TP .TP
@ -715,23 +756,23 @@ full path of this executable.
configuration file (see \fBsmartd.conf\fP(5) man page). configuration file (see \fBsmartd.conf\fP(5) man page).
.TP .TP
.B /usr/local/etc/smartd_warning.sh .B /usr/local/etc/smartd_warning.sh
script run on warnings (see \'\-M exec\' directive on script run on warnings (see \*(Aq\-w\*(Aq option above and \*(Aq\-M exec\*(Aq
\fBsmartd.conf\fP(5) man page). directive on \fBsmartd.conf\fP(5) man page).
.\" %IF ENABLE_SMARTDPLUGINDIR .\" %IF ENABLE_SMARTDPLUGINDIR
.TP .TP
.B /usr/local/etc/smartd_warning.d/ .B /usr/local/etc/smartd_warning.d/
plugin directory for smartd warning script (see \'\-m\' directive on plugin directory for smartd warning script (see \*(Aq\-m\*(Aq directive on
\fBsmartd.conf\fP(5) man page). \fBsmartd.conf\fP(5) man page).
.\" %ENDIF ENABLE_SMARTDPLUGINDIR .\" %ENDIF ENABLE_SMARTDPLUGINDIR
.\" %IF ENABLE_DRIVEDB .\" %IF ENABLE_DRIVEDB
.TP .TP
.B /usr/local/share/smartmontools/drivedb.h .B /usr/local/share/smartmontools/drivedb.h
drive database (see \'\-B\' option). drive database (see \*(Aq\-B\*(Aq option).
.\" %ENDIF ENABLE_DRIVEDB .\" %ENDIF ENABLE_DRIVEDB
.TP .TP
.B /usr/local/etc/smart_drivedb.h .B /usr/local/etc/smart_drivedb.h
optional local drive database (see \'\-B\' option). optional local drive database (see \*(Aq\-B\*(Aq option).
.Sp
.\" %ENDIF NOT OS Windows .\" %ENDIF NOT OS Windows
.SH AUTHORS .SH AUTHORS
\fBBruce Allen\fP (project initiator), \fBBruce Allen\fP (project initiator),
@ -745,52 +786,52 @@ optional local drive database (see \'\-B\' option).
\fBGabriele Pohl\fP (wiki & development team support), \fBGabriele Pohl\fP (wiki & development team support),
.br .br
\fBAlex Samorukov\fP (FreeBSD port and more, new Trac wiki). \fBAlex Samorukov\fP (FreeBSD port and more, new Trac wiki).
.PP
Many other individuals have made contributions and corrections, Many other individuals have made contributions and corrections,
see AUTHORS, ChangeLog and repository files. see AUTHORS, ChangeLog and repository files.
.PP
The first smartmontools code was derived from the smartsuite package, The first smartmontools code was derived from the smartsuite package,
written by Michael Cornwell and Andre Hedrick. written by Michael Cornwell and Andre Hedrick.
.Sp
.SH REPORTING BUGS .SH REPORTING BUGS
To submit a bug report, create a ticket in smartmontools wiki: To submit a bug report, create a ticket in smartmontools wiki:
.br .br
<\fBhttp://www.smartmontools.org/\fP>. <\fBhttps://www.smartmontools.org/\fP>.
.br .br
Alternatively send the info to the smartmontools support mailing list: Alternatively send the info to the smartmontools support mailing list:
.br .br
<\fBhttps://lists.sourceforge.net/lists/listinfo/smartmontools-support\fB>. <\fBhttps://listi.jpberlin.de/mailman/listinfo/smartmontools-support\fB>.
.Sp
.SH SEE ALSO .SH SEE ALSO
\fBsmartd.conf\fP(5), \fBsmartctl\fP(8). \fBsmartd.conf\fP(5), \fBsmartctl\fP(8).
.\" %IF ENABLE_UPDATE_SMART_DRIVEDB .\" %IF ENABLE_UPDATE_SMART_DRIVEDB
.br .br
\fBupdate-smart-drivedb\fP(8). \fBupdate-smart-drivedb\fP(8).
.\" %ENDIF ENABLE_UPDATE_SMART_DRIVEDB .\" %ENDIF ENABLE_UPDATE_SMART_DRIVEDB
.Sp
.SH REFERENCES .SH REFERENCES
Please see the following web site for more info: Please see the following web site for more info:
\fBhttp://www.smartmontools.org/\fP <\fBhttps://www.smartmontools.org/\fP>
.PP
An introductory article about smartmontools is \fIMonitoring Hard An introductory article about smartmontools is \fIMonitoring Hard
Disks with SMART\fP, by Bruce Allen, Linux Journal, January 2004, Disks with SMART\fP, by Bruce Allen, Linux Journal, January 2004,
pages 74-77. This is \fBhttp://www.linuxjournal.com/article/6983\fP pages 74\(en77.
online. See <\fBhttps://www.linuxjournal.com/article/6983\fP>.
.PP
If you would like to understand better how SMART works, and what it If you would like to understand better how SMART works, and what it
does, a good place to start is with Sections 4.8 and 6.54 of the first does, a good place to start is with Sections 4.8 and 6.54 of the first
volume of the \'AT Attachment with Packet Interface-7\' (ATA/ATAPI-7) volume of the \*(AqAT Attachment with Packet Interface-7\*(Aq (ATA/ATAPI-7)
specification Revision 4b. This documents the SMART functionality which the specification Revision 4b. This documents the SMART functionality which the
\fBsmartmontools\fP utilities provide access to. \fBsmartmontools\fP utilities provide access to.
.PP
The functioning of SMART was originally defined by the SFF-8035i The functioning of SMART was originally defined by the SFF-8035i
revision 2 and the SFF-8055i revision 1.4 specifications. These are revision 2 and the SFF-8055i revision 1.4 specifications. These are
publications of the Small Form Factors (SFF) Committee. publications of the Small Form Factors (SFF) Committee.
.PP
Links to these and other documents may be found on the Links page of the Links to these and other documents may be found on the Links page of the
\fBsmartmontools\fP Wiki at \fBhttp://www.smartmontools.org/wiki/Links\fP . \fBsmartmontools\fP Wiki at <\fBhttps://www.smartmontools.org/wiki/Links\fP>.
.Sp
.SH PACKAGE VERSION .SH PACKAGE VERSION
CURRENT_SVN_VERSION CURRENT_SVN_DATE CURRENT_SVN_REV CURRENT_SVN_VERSION CURRENT_SVN_DATE CURRENT_SVN_REV
.br .br
$Id: smartd.8.in 4299 2016-04-16 19:45:57Z chrfranke $ $Id: smartd.8.in 4576 2017-10-29 16:41:44Z chrfranke $

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
* Home page of code is: http://www.smartmontools.org * Home page of code is: http://www.smartmontools.org
* *
* Copyright (C) 2002-11 Bruce Allen * Copyright (C) 2002-11 Bruce Allen
* Copyright (C) 2008-16 Christian Franke * Copyright (C) 2008-17 Christian Franke
* Copyright (C) 2000 Michael Cornwell <cornwell@acm.org> * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
* Copyright (C) 2008 Oliver Bock <brevilo@users.sourceforge.net> * Copyright (C) 2008 Oliver Bock <brevilo@users.sourceforge.net>
* *
@ -100,7 +100,7 @@ typedef int pid_t;
#define SIGQUIT_KEYNAME "CONTROL-\\" #define SIGQUIT_KEYNAME "CONTROL-\\"
#endif // _WIN32 #endif // _WIN32
const char * smartd_cpp_cvsid = "$Id: smartd.cpp 4308 2016-04-24 13:36:10Z chrfranke $" const char * smartd_cpp_cvsid = "$Id: smartd.cpp 4556 2017-10-15 17:31:30Z chrfranke $"
CONFIG_H_CVSID; CONFIG_H_CVSID;
using namespace smartmontools; using namespace smartmontools;
@ -157,7 +157,11 @@ static std::string configfile_alt;
static std::string warning_script; static std::string warning_script;
// command-line: when should we exit? // command-line: when should we exit?
static int quit=0; enum quit_t {
QUIT_NODEV, QUIT_NODEVSTARTUP, QUIT_NEVER, QUIT_ONECHECK,
QUIT_SHOWTESTS, QUIT_ERRORS
};
static quit_t quit = QUIT_NODEV;
// command-line; this is the default syslog(3) log facility to use. // command-line; this is the default syslog(3) log facility to use.
static int facility=LOG_DAEMON; static int facility=LOG_DAEMON;
@ -238,6 +242,7 @@ struct dev_config
std::string state_file; // Path of the persistent state file, empty if none std::string state_file; // Path of the persistent state file, empty if none
std::string attrlog_file; // Path of the persistent attrlog file, empty if none std::string attrlog_file; // Path of the persistent attrlog file, empty if none
bool ignore; // Ignore this entry bool ignore; // Ignore this entry
bool id_is_unique; // True if dev_idinfo is unique (includes S/N or WWN)
bool smartcheck; // Check SMART status bool smartcheck; // Check SMART status
bool usagefailed; // Check for failed Usage Attributes bool usagefailed; // Check for failed Usage Attributes
bool prefail; // Track changes in Prefail Attributes bool prefail; // Track changes in Prefail Attributes
@ -277,6 +282,7 @@ struct dev_config
int set_standby; // set(1..255->0..254) standby timer int set_standby; // set(1..255->0..254) standby timer
bool set_security_freeze; // Freeze ATA security bool set_security_freeze; // Freeze ATA security
int set_wcache; // disable(-1), enable(1) write cache int set_wcache; // disable(-1), enable(1) write cache
int set_dsn; // disable(0x2), enable(0x1) DSN
bool sct_erc_set; // set SCT ERC to: bool sct_erc_set; // set SCT ERC to:
unsigned short sct_erc_readtime; // ERC read time (deciseconds) unsigned short sct_erc_readtime; // ERC read time (deciseconds)
@ -297,6 +303,7 @@ struct dev_config
dev_config::dev_config() dev_config::dev_config()
: lineno(0), : lineno(0),
ignore(false), ignore(false),
id_is_unique(false),
smartcheck(false), smartcheck(false),
usagefailed(false), usagefailed(false),
prefail(false), prefail(false),
@ -324,7 +331,7 @@ dev_config::dev_config()
set_lookahead(0), set_lookahead(0),
set_standby(0), set_standby(0),
set_security_freeze(false), set_security_freeze(false),
set_wcache(0), set_wcache(0), set_dsn(0),
sct_erc_set(false), sct_erc_set(false),
sct_erc_readtime(0), sct_erc_writetime(0), sct_erc_readtime(0), sct_erc_writetime(0),
curr_pending_id(0), offl_pending_id(0), curr_pending_id(0), offl_pending_id(0),
@ -429,6 +436,8 @@ struct temp_dev_state
unsigned char temperature; // last recorded Temperature (in Celsius) unsigned char temperature; // last recorded Temperature (in Celsius)
time_t tempmin_delay; // time where Min Temperature tracking will start time_t tempmin_delay; // time where Min Temperature tracking will start
bool removed; // true if open() failed for removable device
bool powermodefail; // true if power mode check failed bool powermodefail; // true if power mode check failed
int powerskipcnt; // Number of checks skipped due to idle or standby mode int powerskipcnt; // Number of checks skipped due to idle or standby mode
int lastpowermodeskipped; // the last power mode that was skipped int lastpowermodeskipped; // the last power mode that was skipped
@ -462,6 +471,7 @@ temp_dev_state::temp_dev_state()
not_cap_selective(false), not_cap_selective(false),
temperature(0), temperature(0),
tempmin_delay(0), tempmin_delay(0),
removed(false),
powermodefail(false), powermodefail(false),
powerskipcnt(0), powerskipcnt(0),
lastpowermodeskipped(0), lastpowermodeskipped(0),
@ -794,7 +804,7 @@ static bool write_dev_attrlog(const char * path, const dev_state & state)
fprintf(f, "\tnon-medium-errors;%" PRIu64 ";", state.scsi_nonmedium_error.nme.counterPC0); fprintf(f, "\tnon-medium-errors;%" PRIu64 ";", state.scsi_nonmedium_error.nme.counterPC0);
} }
// write SCSI current temperature if it is monitored // write SCSI current temperature if it is monitored
if(state.TempPageSupported && state.temperature) if (state.temperature)
fprintf(f, "\ttemperature;%d;", state.temperature); fprintf(f, "\ttemperature;%d;", state.temperature);
// end of line // end of line
fprintf(f, "\n"); fprintf(f, "\n");
@ -1199,6 +1209,7 @@ static void reset_warning_mail(const dev_config & cfg, dev_state & state, int wh
#ifndef _WIN32 #ifndef _WIN32
// Output multiple lines via separate syslog(3) calls. // Output multiple lines via separate syslog(3) calls.
__attribute_format_printf(2, 0)
static void vsyslog_lines(int priority, const char * fmt, va_list ap) static void vsyslog_lines(int priority, const char * fmt, va_list ap)
{ {
char buf[512+EBUFLEN]; // enough space for exec cmd output in MailWarning() char buf[512+EBUFLEN]; // enough space for exec cmd output in MailWarning()
@ -1313,14 +1324,13 @@ static bool WaitForPidFile()
static void DaemonInit() static void DaemonInit()
{ {
#ifndef _WIN32 #ifndef _WIN32
pid_t pid;
int i;
// flush all buffered streams. Else we might get two copies of open // flush all buffered streams. Else we might get two copies of open
// streams since both parent and child get copies of the buffers. // streams since both parent and child get copies of the buffers.
fflush(NULL); fflush(NULL);
if (do_fork) { if (do_fork) {
pid_t pid;
if ((pid=fork()) < 0) { if ((pid=fork()) < 0) {
// unable to fork! // unable to fork!
PrintOut(LOG_CRIT,"smartd unable to fork daemon process!\n"); PrintOut(LOG_CRIT,"smartd unable to fork daemon process!\n");
@ -1352,21 +1362,16 @@ static void DaemonInit()
} }
// close any open file descriptors // close any open file descriptors
for (i=getdtablesize();i>=0;--i) for (int i = getdtablesize(); --i >= 0; )
close(i); close(i);
#define NO_warn_unused_result(cmd) { if (cmd) {} ; } // redirect any IO attempts to /dev/null and change to root directory
int fd = open("/dev/null", O_RDWR);
// redirect any IO attempts to /dev/null for stdin if (!(fd == 0 && dup(fd) == 1 && dup(fd) == 2 && !chdir("/"))) {
i=open("/dev/null",O_RDWR); PrintOut(LOG_CRIT, "smartd unable to redirect to /dev/null or to chdir to root!\n");
if (i>=0) { EXIT(EXIT_STARTUP);
// stdout }
NO_warn_unused_result(dup(i));
// stderr
NO_warn_unused_result(dup(i));
};
umask(0022); umask(0022);
NO_warn_unused_result(chdir("/"));
if (do_fork) if (do_fork)
PrintOut(LOG_INFO, "smartd has fork()ed into background mode. New PID=%d.\n", (int)getpid()); PrintOut(LOG_INFO, "smartd has fork()ed into background mode. New PID=%d.\n", (int)getpid());
@ -1431,8 +1436,8 @@ static void Directives()
" -l TYPE Monitor SMART log or self-test status:\n" " -l TYPE Monitor SMART log or self-test status:\n"
" error, selftest, xerror, offlinests[,ns], selfteststs[,ns]\n" " error, selftest, xerror, offlinests[,ns], selfteststs[,ns]\n"
" -l scterc,R,W Set SCT Error Recovery Control\n" " -l scterc,R,W Set SCT Error Recovery Control\n"
" -e Change device setting: aam,[N|off], apm,[N|off], lookahead,[on|off],\n" " -e Change device setting: aam,[N|off], apm,[N|off], dsn,[on|off],\n"
" security-freeze, standby,[N|off], wcache,[on|off]\n" " lookahead,[on|off], security-freeze, standby,[N|off], wcache,[on|off]\n"
" -f Monitor 'Usage' Attributes, report failures\n" " -f Monitor 'Usage' Attributes, report failures\n"
" -m ADD Send email warning to address ADD\n" " -m ADD Send email warning to address ADD\n"
" -M TYPE Modify email warning behavior (see man page)\n" " -M TYPE Modify email warning behavior (see man page)\n"
@ -1469,6 +1474,8 @@ static const char *GetValidArgList(char opt)
case 'A': case 'A':
case 's': case 's':
return "<PATH_PREFIX>"; return "<PATH_PREFIX>";
case 'B':
return "[+]<FILE_NAME>";
case 'c': case 'c':
return "<FILE_NAME>, -"; return "<FILE_NAME>, -";
case 'l': case 'l':
@ -1477,7 +1484,6 @@ static const char *GetValidArgList(char opt)
return "nodev, errors, nodevstartup, never, onecheck, showtests"; return "nodev, errors, nodevstartup, never, onecheck, showtests";
case 'r': case 'r':
return "ioctl[,N], ataioctl[,N], scsiioctl[,N], nvmeioctl[,N]"; return "ioctl[,N], ataioctl[,N], scsiioctl[,N], nvmeioctl[,N]";
case 'B':
case 'p': case 'p':
case 'w': case 'w':
return "<FILE_NAME>"; return "<FILE_NAME>";
@ -1744,12 +1750,32 @@ static void format_set_result_msg(std::string & msg, const char * name, bool ok,
msg += ":on"; msg += ":on";
} }
// Return true and print message if CFG.dev_idinfo is already in PREV_CFGS
static bool is_duplicate_dev_idinfo(const dev_config & cfg, const dev_config_vector & prev_cfgs)
{
if (!cfg.id_is_unique)
return false;
for (unsigned i = 0; i < prev_cfgs.size(); i++) {
if (!prev_cfgs[i].id_is_unique)
continue;
if (cfg.dev_idinfo != prev_cfgs[i].dev_idinfo.c_str())
continue;
PrintOut(LOG_INFO, "Device: %s, same identity as %s, ignored\n",
cfg.dev_name.c_str(), prev_cfgs[i].dev_name.c_str());
return true;
}
return false;
}
// TODO: Add '-F swapid' directive // TODO: Add '-F swapid' directive
const bool fix_swapped_id = false; const bool fix_swapped_id = false;
// scan to see what ata devices there are, and if they support SMART // scan to see what ata devices there are, and if they support SMART
static int ATADeviceScan(dev_config & cfg, dev_state & state, ata_device * atadev) static int ATADeviceScan(dev_config & cfg, dev_state & state, ata_device * atadev,
const dev_config_vector * prev_cfgs)
{ {
int supported=0; int supported=0;
struct ata_identify_device drive; struct ata_identify_device drive;
@ -1791,9 +1817,16 @@ static int ATADeviceScan(dev_config & cfg, dev_state & state, ata_device * atade
char cap[32]; char cap[32];
cfg.dev_idinfo = strprintf("%s, S/N:%s, %sFW:%s, %s", model, serial, wwn, firmware, cfg.dev_idinfo = strprintf("%s, S/N:%s, %sFW:%s, %s", model, serial, wwn, firmware,
format_capacity(cap, sizeof(cap), sizes.capacity, ".")); format_capacity(cap, sizeof(cap), sizes.capacity, "."));
cfg.id_is_unique = true; // TODO: Check serial?
PrintOut(LOG_INFO, "Device: %s, %s\n", name, cfg.dev_idinfo.c_str()); PrintOut(LOG_INFO, "Device: %s, %s\n", name, cfg.dev_idinfo.c_str());
// Check for duplicates
if (prev_cfgs && is_duplicate_dev_idinfo(cfg, *prev_cfgs)) {
CloseDevice(atadev, name);
return 1;
}
// Show if device in database, and use preset vendor attribute // Show if device in database, and use preset vendor attribute
// options unless user has requested otherwise. // options unless user has requested otherwise.
if (cfg.ignorepresets) if (cfg.ignorepresets)
@ -2106,6 +2139,10 @@ static int ATADeviceScan(dev_config & cfg, dev_state & state, ata_device * atade
format_set_result_msg(msg, "Wr-cache", ata_set_features(atadev, format_set_result_msg(msg, "Wr-cache", ata_set_features(atadev,
(cfg.set_wcache > 0? ATA_ENABLE_WRITE_CACHE : ATA_DISABLE_WRITE_CACHE)), cfg.set_wcache); (cfg.set_wcache > 0? ATA_ENABLE_WRITE_CACHE : ATA_DISABLE_WRITE_CACHE)), cfg.set_wcache);
if (cfg.set_dsn)
format_set_result_msg(msg, "DSN", ata_set_features(atadev,
ATA_ENABLE_DISABLE_DSN, (cfg.set_dsn > 0 ? 0x1 : 0x2)));
if (cfg.set_security_freeze) if (cfg.set_security_freeze)
format_set_result_msg(msg, "Security freeze", format_set_result_msg(msg, "Security freeze",
ata_nodata_command(atadev, ATA_SECURITY_FREEZE_LOCK)); ata_nodata_command(atadev, ATA_SECURITY_FREEZE_LOCK));
@ -2174,7 +2211,8 @@ static int ATADeviceScan(dev_config & cfg, dev_state & state, ata_device * atade
// on success, return 0. On failure, return >0. Never return <0, // on success, return 0. On failure, return >0. Never return <0,
// please. // please.
static int SCSIDeviceScan(dev_config & cfg, dev_state & state, scsi_device * scsidev) static int SCSIDeviceScan(dev_config & cfg, dev_state & state, scsi_device * scsidev,
const dev_config_vector * prev_cfgs)
{ {
int err, req_len, avail_len, version, len; int err, req_len, avail_len, version, len;
const char *device = cfg.name.c_str(); const char *device = cfg.name.c_str();
@ -2253,12 +2291,19 @@ static int SCSIDeviceScan(dev_config & cfg, dev_state & state, scsi_device * scs
(lu_id[0] ? ", lu id: " : ""), (lu_id[0] ? lu_id : ""), (lu_id[0] ? ", lu id: " : ""), (lu_id[0] ? lu_id : ""),
(serial[0] ? ", S/N: " : ""), (serial[0] ? serial : ""), (serial[0] ? ", S/N: " : ""), (serial[0] ? serial : ""),
(si_str[0] ? ", " : ""), (si_str[0] ? si_str : "")); (si_str[0] ? ", " : ""), (si_str[0] ? si_str : ""));
cfg.id_is_unique = (lu_id[0] || serial[0]);
// format "model" string // format "model" string
scsi_format_id_string(vendor, (const unsigned char *)&inqBuf[8], 8); scsi_format_id_string(vendor, (const unsigned char *)&inqBuf[8], 8);
scsi_format_id_string(model, (const unsigned char *)&inqBuf[16], 16); scsi_format_id_string(model, (const unsigned char *)&inqBuf[16], 16);
PrintOut(LOG_INFO, "Device: %s, %s\n", device, cfg.dev_idinfo.c_str()); PrintOut(LOG_INFO, "Device: %s, %s\n", device, cfg.dev_idinfo.c_str());
// Check for duplicates
if (prev_cfgs && is_duplicate_dev_idinfo(cfg, *prev_cfgs)) {
CloseDevice(scsidev, device);
return 1;
}
// check that device is ready for commands. IE stores its stuff on // check that device is ready for commands. IE stores its stuff on
// the media. // the media.
if ((err = scsiTestUnitReady(scsidev))) { if ((err = scsiTestUnitReady(scsidev))) {
@ -2345,13 +2390,14 @@ static int SCSIDeviceScan(dev_config & cfg, dev_state & state, scsi_device * scs
&asc, &ascq, &currenttemp, &triptemp)) { &asc, &ascq, &currenttemp, &triptemp)) {
PrintOut(LOG_INFO, "Device: %s, unexpectedly failed to read SMART values\n", device); PrintOut(LOG_INFO, "Device: %s, unexpectedly failed to read SMART values\n", device);
state.SuppressReport = 1; state.SuppressReport = 1;
if (cfg.tempdiff || cfg.tempinfo || cfg.tempcrit) { }
if ( (state.SuppressReport || !currenttemp)
&& (cfg.tempdiff || cfg.tempinfo || cfg.tempcrit)) {
PrintOut(LOG_INFO, "Device: %s, can't monitor Temperature, ignoring -W %d,%d,%d\n", PrintOut(LOG_INFO, "Device: %s, can't monitor Temperature, ignoring -W %d,%d,%d\n",
device, cfg.tempdiff, cfg.tempinfo, cfg.tempcrit); device, cfg.tempdiff, cfg.tempinfo, cfg.tempcrit);
cfg.tempdiff = cfg.tempinfo = cfg.tempcrit = 0; cfg.tempdiff = cfg.tempinfo = cfg.tempcrit = 0;
} }
} }
}
// capability check: self-test-log // capability check: self-test-log
if (cfg.selftest){ if (cfg.selftest){
@ -2442,7 +2488,8 @@ static int nvme_get_max_temp_kelvin(const nvme_smart_log & smart_log)
return k; return k;
} }
static int NVMeDeviceScan(dev_config & cfg, dev_state & state, nvme_device * nvmedev) static int NVMeDeviceScan(dev_config & cfg, dev_state & state, nvme_device * nvmedev,
const dev_config_vector * prev_cfgs)
{ {
const char *name = cfg.name.c_str(); const char *name = cfg.name.c_str();
@ -2472,9 +2519,16 @@ static int NVMeDeviceScan(dev_config & cfg, dev_state & state, nvme_device * nvm
format_capacity(capstr, sizeof(capstr), capacity, "."); format_capacity(capstr, sizeof(capstr), capacity, ".");
cfg.dev_idinfo = strprintf("%s, S/N:%s, FW:%s%s%s%s", model, serial, firmware, cfg.dev_idinfo = strprintf("%s, S/N:%s, FW:%s%s%s%s", model, serial, firmware,
nsstr, (capstr[0] ? ", " : ""), capstr); nsstr, (capstr[0] ? ", " : ""), capstr);
cfg.id_is_unique = true; // TODO: Check serial?
PrintOut(LOG_INFO, "Device: %s, %s\n", name, cfg.dev_idinfo.c_str()); PrintOut(LOG_INFO, "Device: %s, %s\n", name, cfg.dev_idinfo.c_str());
// Check for duplicates
if (prev_cfgs && is_duplicate_dev_idinfo(cfg, *prev_cfgs)) {
CloseDevice(nvmedev, name);
return 1;
}
// Read SMART/Health log // Read SMART/Health log
nvme_smart_log smart_log; nvme_smart_log smart_log;
if (!nvme_read_smart_log(nvmedev, smart_log)) { if (!nvme_read_smart_log(nvmedev, smart_log)) {
@ -2530,6 +2584,68 @@ static int NVMeDeviceScan(dev_config & cfg, dev_state & state, nvme_device * nvm
return 0; return 0;
} }
// Open device for next check, return false on error
static bool open_device(const dev_config & cfg, dev_state & state, smart_device * device,
const char * type)
{
const char * name = cfg.name.c_str();
// If user has asked, test the email warning system
if (cfg.emailtest)
MailWarning(cfg, state, 0, "TEST EMAIL from smartd for device: %s", name);
// User may have requested (with the -n Directive) to leave the disk
// alone if it is in idle or standby mode. In this case check the
// power mode first before opening the device for full access,
// and exit without check if disk is reported in standby.
if (device->is_ata() && cfg.powermode && !state.powermodefail && !state.removed) {
// Note that 'is_powered_down()' handles opening the device itself, and
// can be used before calling 'open()' (that's the whole point of 'is_powered_down()'!).
if (device->is_powered_down())
{
// skip at most powerskipmax checks
if (!cfg.powerskipmax || state.powerskipcnt<cfg.powerskipmax) {
// report first only except if state has changed, avoid waking up system disk
if ((!state.powerskipcnt || state.lastpowermodeskipped != -1) && !cfg.powerquiet) {
PrintOut(LOG_INFO, "Device: %s, is in %s mode, suspending checks\n", name, "STANDBY (OS)");
state.lastpowermodeskipped = -1;
}
state.powerskipcnt++;
return false;
}
}
}
// if we can't open device, fail gracefully rather than hard --
// perhaps the next time around we'll be able to open it
if (!device->open()) {
// For removable devices, print error message only once and suppress email
if (!cfg.removable) {
PrintOut(LOG_INFO, "Device: %s, open() of %s device failed: %s\n", name, type, device->get_errmsg());
MailWarning(cfg, state, 9, "Device: %s, unable to open %s device", name, type);
}
else if (!state.removed) {
PrintOut(LOG_INFO, "Device: %s, removed %s device: %s\n", name, type, device->get_errmsg());
state.removed = true;
}
else if (debugmode)
PrintOut(LOG_INFO, "Device: %s, %s device still removed: %s\n", name, type, device->get_errmsg());
return false;
}
if (debugmode)
PrintOut(LOG_INFO,"Device: %s, opened %s device\n", name, type);
if (!cfg.removable)
reset_warning_mail(cfg, state, 9, "open of %s device worked again", type);
else if (state.removed) {
PrintOut(LOG_INFO, "Device: %s, reconnected %s device\n", name, type);
state.removed = false;
}
return true;
}
// If the self-test log has got more self-test errors (or more recent // If the self-test log has got more self-test errors (or more recent
// self-test errors) recorded, then notify user. // self-test errors) recorded, then notify user.
static void CheckSelfTestLogs(const dev_config & cfg, dev_state & state, int newi) static void CheckSelfTestLogs(const dev_config & cfg, dev_state & state, int newi)
@ -3129,46 +3245,10 @@ static void check_attribute(const dev_config & cfg, dev_state & state,
static int ATACheckDevice(const dev_config & cfg, dev_state & state, ata_device * atadev, static int ATACheckDevice(const dev_config & cfg, dev_state & state, ata_device * atadev,
bool firstpass, bool allow_selftests) bool firstpass, bool allow_selftests)
{ {
const char * name = cfg.name.c_str(); if (!open_device(cfg, state, atadev, "ATA"))
// If user has asked, test the email warning system
if (cfg.emailtest)
MailWarning(cfg, state, 0, "TEST EMAIL from smartd for device: %s", name);
// User may have requested (with the -n Directive) to leave the disk
// alone if it is in idle or standby mode. In this case check the
// power mode first before opening the device for full access,
// and exit without check if disk is reported in standby.
if (cfg.powermode && !state.powermodefail) {
// Note that 'is_powered_down()' handles opening the device itself, and
// can be used before calling 'open()' (that's the whole point of 'is_powered_down()'!).
if (atadev->is_powered_down())
{
// skip at most powerskipmax checks
if (!cfg.powerskipmax || state.powerskipcnt<cfg.powerskipmax) {
// report first only except if state has changed, avoid waking up system disk
if ((!state.powerskipcnt || state.lastpowermodeskipped != -1) && !cfg.powerquiet) {
PrintOut(LOG_INFO, "Device: %s, is in %s mode, suspending checks\n", name, "STANDBY (OS)");
state.lastpowermodeskipped = -1;
}
state.powerskipcnt++;
return 0;
}
}
}
// if we can't open device, fail gracefully rather than hard --
// perhaps the next time around we'll be able to open it. ATAPI
// cd/dvd devices will hang awaiting media if O_NONBLOCK is not
// given (see linux cdrom driver).
if (!atadev->open()) {
PrintOut(LOG_INFO, "Device: %s, open() failed: %s\n", name, atadev->get_errmsg());
MailWarning(cfg, state, 9, "Device: %s, unable to open device", name);
return 1; return 1;
}
if (debugmode) const char * name = cfg.name.c_str();
PrintOut(LOG_INFO,"Device: %s, opened ATA device\n", name);
reset_warning_mail(cfg, state, 9, "open device worked again");
// user may have requested (with the -n Directive) to leave the disk // user may have requested (with the -n Directive) to leave the disk
// alone if it is in idle or sleeping mode. In this case check the // alone if it is in idle or sleeping mode. In this case check the
@ -3407,21 +3487,10 @@ static int ATACheckDevice(const dev_config & cfg, dev_state & state, ata_device
static int SCSICheckDevice(const dev_config & cfg, dev_state & state, scsi_device * scsidev, bool allow_selftests) static int SCSICheckDevice(const dev_config & cfg, dev_state & state, scsi_device * scsidev, bool allow_selftests)
{ {
const char * name = cfg.name.c_str(); if (!open_device(cfg, state, scsidev, "SCSI"))
// If the user has asked for it, test the email warning system
if (cfg.emailtest)
MailWarning(cfg, state, 0, "TEST EMAIL from smartd for device: %s", name);
// if we can't open device, fail gracefully rather than hard --
// perhaps the next time around we'll be able to open it
if (!scsidev->open()) {
PrintOut(LOG_INFO, "Device: %s, open() failed: %s\n", name, scsidev->get_errmsg());
MailWarning(cfg, state, 9, "Device: %s, unable to open device", name);
return 1; return 1;
} else if (debugmode)
PrintOut(LOG_INFO,"Device: %s, opened SCSI device\n", name); const char * name = cfg.name.c_str();
reset_warning_mail(cfg, state, 9, "open device worked again");
UINT8 asc = 0, ascq = 0; UINT8 asc = 0, ascq = 0;
UINT8 currenttemp = 0, triptemp = 0; UINT8 currenttemp = 0, triptemp = 0;
@ -3448,7 +3517,7 @@ static int SCSICheckDevice(const dev_config & cfg, dev_state & state, scsi_devic
PrintOut(LOG_INFO,"Device: %s, SMART health: passed\n", name); PrintOut(LOG_INFO,"Device: %s, SMART health: passed\n", name);
// check temperature limits // check temperature limits
if (cfg.tempdiff || cfg.tempinfo || cfg.tempcrit || !cfg.attrlog_file.empty()) if (cfg.tempdiff || cfg.tempinfo || cfg.tempcrit)
CheckTemperature(cfg, state, currenttemp, triptemp); CheckTemperature(cfg, state, currenttemp, triptemp);
// check if number of selftest errors has increased (note: may also DECREASE) // check if number of selftest errors has increased (note: may also DECREASE)
@ -3483,6 +3552,9 @@ static int SCSICheckDevice(const dev_config & cfg, dev_state & state, scsi_devic
scsiDecodeNonMediumErrPage(tBuf, &state.scsi_nonmedium_error.nme); scsiDecodeNonMediumErrPage(tBuf, &state.scsi_nonmedium_error.nme);
state.scsi_nonmedium_error.found=1; state.scsi_nonmedium_error.found=1;
} }
// store temperature if not done by CheckTemperature() above
if (!(cfg.tempdiff || cfg.tempinfo || cfg.tempcrit))
state.temperature = currenttemp;
} }
CloseDevice(scsidev, name); CloseDevice(scsidev, name);
return 0; return 0;
@ -3490,21 +3562,10 @@ static int SCSICheckDevice(const dev_config & cfg, dev_state & state, scsi_devic
static int NVMeCheckDevice(const dev_config & cfg, dev_state & state, nvme_device * nvmedev) static int NVMeCheckDevice(const dev_config & cfg, dev_state & state, nvme_device * nvmedev)
{ {
const char * name = cfg.name.c_str(); if (!open_device(cfg, state, nvmedev, "NVMe"))
// TODO: Use common open function for ATA/SCSI/NVMe
// If user has asked, test the email warning system
if (cfg.emailtest)
MailWarning(cfg, state, 0, "TEST EMAIL from smartd for device: %s", name);
if (!nvmedev->open()) {
PrintOut(LOG_INFO, "Device: %s, open() failed: %s\n", name, nvmedev->get_errmsg());
MailWarning(cfg, state, 9, "Device: %s, unable to open device", name);
return 1; return 1;
}
if (debugmode) const char * name = cfg.name.c_str();
PrintOut(LOG_INFO,"Device: %s, opened NVMe device\n", name);
reset_warning_mail(cfg, state, 9, "open device worked again");
// Read SMART/Health log // Read SMART/Health log
nvme_smart_log smart_log; nvme_smart_log smart_log;
@ -3831,7 +3892,7 @@ static void printoutvaliddirectiveargs(int priority, char d)
PrintOut(priority, "%s", get_valid_firmwarebug_args()); PrintOut(priority, "%s", get_valid_firmwarebug_args());
break; break;
case 'e': case 'e':
PrintOut(priority, "aam,[N|off], apm,[N|off], lookahead,[on|off], " PrintOut(priority, "aam,[N|off], apm,[N|off], lookahead,[on|off], dsn,[on|off] "
"security-freeze, standby,[N|off], wcache,[on|off]"); "security-freeze, standby,[N|off], wcache,[on|off]");
break; break;
} }
@ -4353,6 +4414,14 @@ static int ParseToken(char * token, dev_config & cfg, smart_devtype_list & scan_
else else
badarg = true; badarg = true;
} }
else if (!strcmp(arg2, "dsn")) {
if (off)
cfg.set_dsn = -1;
else if (on)
cfg.set_dsn = 1;
else
badarg = true;
}
else else
badarg = true; badarg = true;
} }
@ -4730,23 +4799,24 @@ static void ParseOpts(int argc, char **argv)
switch(optchar) { switch(optchar) {
case 'q': case 'q':
// when to quit // when to quit
if (!(strcmp(optarg,"nodev"))) { if (!strcmp(optarg, "nodev"))
quit=0; quit = QUIT_NODEV;
} else if (!(strcmp(optarg,"nodevstartup"))) { else if (!strcmp(optarg, "nodevstartup"))
quit=1; quit = QUIT_NODEVSTARTUP;
} else if (!(strcmp(optarg,"never"))) { else if (!strcmp(optarg, "never"))
quit=2; quit = QUIT_NEVER;
} else if (!(strcmp(optarg,"onecheck"))) { else if (!strcmp(optarg, "onecheck")) {
quit=3; quit = QUIT_ONECHECK;
debugmode = 1; debugmode = 1;
} else if (!(strcmp(optarg,"showtests"))) {
quit=4;
debugmode=1;
} else if (!(strcmp(optarg,"errors"))) {
quit=5;
} else {
badarg = true;
} }
else if (!strcmp(optarg, "showtests")) {
quit = QUIT_SHOWTESTS;
debugmode = 1;
}
else if (!strcmp(optarg, "errors"))
quit = QUIT_ERRORS;
else
badarg = true;
break; break;
case 'l': case 'l':
// set the log facility level // set the log facility level
@ -5003,20 +5073,6 @@ static int MakeConfigEntries(const dev_config & base_cfg,
return devlist.size(); return devlist.size();
} }
static void CanNotRegister(const char *name, const char *type, int line, bool scandirective)
{
if (!debugmode && scandirective)
return;
if (line)
PrintOut(scandirective?LOG_INFO:LOG_CRIT,
"Unable to register %s device %s at line %d of file %s\n",
type, name, line, configfile);
else
PrintOut(LOG_INFO,"Unable to register %s device %s\n",
type, name);
return;
}
// Returns negative value (see ParseConfigFile()) if config file // Returns negative value (see ParseConfigFile()) if config file
// had errors, else number of entries which may be zero or positive. // had errors, else number of entries which may be zero or positive.
static int ReadOrMakeConfigEntries(dev_config_vector & conf_entries, smart_device_list & scanned_devs) static int ReadOrMakeConfigEntries(dev_config_vector & conf_entries, smart_device_list & scanned_devs)
@ -5101,6 +5157,89 @@ static bool is_duplicate_device(const smart_device * dev,
return false; return false;
} }
// Register one device, return false on error
static bool register_device(dev_config & cfg, dev_state & state, smart_device_auto_ptr & dev,
const dev_config_vector * prev_cfgs)
{
bool scanning;
if (!dev) {
// Get device of appropriate type
dev = smi()->get_smart_device(cfg.name.c_str(), cfg.dev_type.c_str());
if (!dev) {
if (cfg.dev_type.empty())
PrintOut(LOG_INFO, "Device: %s, unable to autodetect device type\n", cfg.name.c_str());
else
PrintOut(LOG_INFO, "Device: %s, unsupported device type '%s'\n", cfg.name.c_str(), cfg.dev_type.c_str());
return false;
}
scanning = false;
}
else {
// Use device from device scan
scanning = true;
}
// Save old info
smart_device::device_info oldinfo = dev->get_info();
// Open with autodetect support, may return 'better' device
dev.replace( dev->autodetect_open() );
// Report if type has changed
if (oldinfo.dev_type != dev->get_dev_type())
PrintOut(LOG_INFO, "Device: %s, type changed from '%s' to '%s'\n",
cfg.name.c_str(), oldinfo.dev_type.c_str(), dev->get_dev_type());
// Return if autodetect_open() failed
if (!dev->is_open()) {
if (debugmode || !scanning)
PrintOut(LOG_INFO, "Device: %s, open() failed: %s\n", dev->get_info_name(), dev->get_errmsg());
return false;
}
// Update informal name
cfg.name = dev->get_info().info_name;
PrintOut(LOG_INFO, "Device: %s, opened\n", cfg.name.c_str());
int status;
const char * typemsg;
// register ATA device
if (dev->is_ata()){
typemsg = "ATA";
status = ATADeviceScan(cfg, state, dev->to_ata(), prev_cfgs);
}
// or register SCSI device
else if (dev->is_scsi()){
typemsg = "SCSI";
status = SCSIDeviceScan(cfg, state, dev->to_scsi(), prev_cfgs);
}
// or register NVMe device
else if (dev->is_nvme()) {
typemsg = "NVMe";
status = NVMeDeviceScan(cfg, state, dev->to_nvme(), prev_cfgs);
}
else {
PrintOut(LOG_INFO, "Device: %s, neither ATA, SCSI nor NVMe device\n", cfg.name.c_str());
return false;
}
if (status) {
if (!scanning || debugmode) {
if (cfg.lineno)
PrintOut(scanning ? LOG_INFO : LOG_CRIT,
"Unable to register %s device %s at line %d of file %s\n",
typemsg, cfg.name.c_str(), cfg.lineno, configfile);
else
PrintOut(LOG_INFO, "Unable to register %s device %s\n",
typemsg, cfg.name.c_str());
}
return false;
}
return true;
}
// This function tries devices from conf_entries. Each one that can be // This function tries devices from conf_entries. Each one that can be
// registered is moved onto the [ata|scsi]devices lists and removed // registered is moved onto the [ata|scsi]devices lists and removed
// from the conf_entries list. // from the conf_entries list.
@ -5129,11 +5268,10 @@ static void RegisterDevices(const dev_config_vector & conf_entries, smart_device
continue; continue;
} }
// get device of appropriate type
smart_device_auto_ptr dev; smart_device_auto_ptr dev;
bool scanning = false;
// Device may already be detected during devicescan // Device may already be detected during devicescan
bool scanning = false;
if (i < scanned_devs.size()) { if (i < scanned_devs.size()) {
dev = scanned_devs.release(i); dev = scanned_devs.release(i);
if (dev) { if (dev) {
@ -5147,71 +5285,24 @@ static void RegisterDevices(const dev_config_vector & conf_entries, smart_device
} }
} }
if (!dev) { // Register device
dev = smi()->get_smart_device(cfg.name.c_str(), cfg.dev_type.c_str()); // If scanning, pass dev_idinfo of previous devices for duplicate check
if (!dev) {
if (cfg.dev_type.empty())
PrintOut(LOG_INFO,"Device: %s, unable to autodetect device type\n", cfg.name.c_str());
else
PrintOut(LOG_INFO,"Device: %s, unsupported device type '%s'\n", cfg.name.c_str(), cfg.dev_type.c_str());
continue;
}
}
// Save old info
smart_device::device_info oldinfo = dev->get_info();
// Open with autodetect support, may return 'better' device
dev.replace( dev->autodetect_open() );
// Report if type has changed
if (oldinfo.dev_type != dev->get_dev_type())
PrintOut(LOG_INFO,"Device: %s, type changed from '%s' to '%s'\n",
cfg.name.c_str(), oldinfo.dev_type.c_str(), dev->get_dev_type());
if (!dev->is_open()) {
// For linux+devfs, a nonexistent device gives a strange error
// message. This makes the error message a bit more sensible.
// If no debug and scanning - don't print errors
if (debugmode || !scanning)
PrintOut(LOG_INFO, "Device: %s, open() failed: %s\n", dev->get_info_name(), dev->get_errmsg());
continue;
}
// Update informal name
cfg.name = dev->get_info().info_name;
PrintOut(LOG_INFO, "Device: %s, opened\n", cfg.name.c_str());
// Prepare initial state
dev_state state; dev_state state;
if (!register_device(cfg, state, dev, (scanning ? &configs : 0))) {
// register ATA devices // if device is explictly listed and we can't register it, then
if (dev->is_ata()){ // exit unless the user has specified that the device is removable
if (ATADeviceScan(cfg, state, dev->to_ata())) { if (!scanning) {
CanNotRegister(cfg.name.c_str(), "ATA", cfg.lineno, scanning); if (!(cfg.removable || quit == QUIT_NEVER)) {
dev.reset(); PrintOut(LOG_CRIT, "Unable to register device %s (no Directive -d removable). Exiting.\n", cfg.name.c_str());
EXIT(EXIT_BADDEV);
} }
PrintOut(LOG_INFO, "Device: %s, not available\n", cfg.name.c_str());
// Prevent retry of registration
ignored_entries.push_back(cfg);
} }
// or register SCSI devices continue;
else if (dev->is_scsi()){
if (SCSIDeviceScan(cfg, state, dev->to_scsi())) {
CanNotRegister(cfg.name.c_str(), "SCSI", cfg.lineno, scanning);
dev.reset();
}
}
// or register NVMe devices
else if (dev->is_nvme()) {
if (NVMeDeviceScan(cfg, state, dev->to_nvme())) {
CanNotRegister(cfg.name.c_str(), "NVMe", cfg.lineno, scanning);
dev.reset();
}
}
else {
PrintOut(LOG_INFO, "Device: %s, neither ATA, SCSI nor NVMe device\n", cfg.name.c_str());
dev.reset();
} }
if (dev) {
// move onto the list of devices // move onto the list of devices
configs.push_back(cfg); configs.push_back(cfg);
states.push_back(state); states.push_back(state);
@ -5219,17 +5310,6 @@ static void RegisterDevices(const dev_config_vector & conf_entries, smart_device
if (!scanning) if (!scanning)
numnoscan = devices.size(); numnoscan = devices.size();
} }
// if device is explictly listed and we can't register it, then
// exit unless the user has specified that the device is removable
else if (!scanning) {
if (cfg.removable || quit==2)
PrintOut(LOG_INFO, "Device %s not available\n", cfg.name.c_str());
else {
PrintOut(LOG_CRIT, "Unable to register device %s (no Directive -d removable). Exiting.\n", cfg.name.c_str());
EXIT(EXIT_BADDEV);
}
}
}
init_disable_standby_check(configs); init_disable_standby_check(configs);
} }
@ -5320,7 +5400,8 @@ static int main_worker(int argc, char **argv)
if (!(configs.size() == devices.size() && configs.size() == states.size())) if (!(configs.size() == devices.size() && configs.size() == states.size()))
throw std::logic_error("Invalid result from RegisterDevices"); throw std::logic_error("Invalid result from RegisterDevices");
} }
else if (quit==2 || ((quit==0 || quit==1) && !firstpass)) { else if ( quit == QUIT_NEVER
|| ((quit == QUIT_NODEV || quit == QUIT_NODEVSTARTUP) && !firstpass)) {
// user has asked to continue on error in configuration file // user has asked to continue on error in configuration file
if (!firstpass) if (!firstpass)
PrintOut(LOG_INFO,"Reusing previous configuration\n"); PrintOut(LOG_INFO,"Reusing previous configuration\n");
@ -5332,7 +5413,7 @@ static int main_worker(int argc, char **argv)
} }
// Log number of devices we are monitoring... // Log number of devices we are monitoring...
if (devices.size() > 0 || quit==2 || (quit==1 && !firstpass)) { if (devices.size() > 0 || quit == QUIT_NEVER || (quit == QUIT_NODEVSTARTUP && !firstpass)) {
int numata = 0, numscsi = 0; int numata = 0, numscsi = 0;
for (unsigned i = 0; i < devices.size(); i++) { for (unsigned i = 0; i < devices.size(); i++) {
const smart_device * dev = devices.at(i); const smart_device * dev = devices.at(i);
@ -5349,7 +5430,7 @@ static int main_worker(int argc, char **argv)
return EXIT_NODEV; return EXIT_NODEV;
} }
if (quit==4) { if (quit == QUIT_SHOWTESTS) {
// user has asked to print test schedule // user has asked to print test schedule
PrintTestSchedule(configs, states, devices); PrintTestSchedule(configs, states, devices);
return 0; return 0;
@ -5375,7 +5456,7 @@ static int main_worker(int argc, char **argv)
// check all devices once, // check all devices once,
// self tests are not started in first pass unless '-q onecheck' is specified // self tests are not started in first pass unless '-q onecheck' is specified
CheckDevicesOnce(configs, states, devices, firstpass, (!firstpass || quit==3)); CheckDevicesOnce(configs, states, devices, firstpass, (!firstpass || quit == QUIT_ONECHECK));
// Write state files // Write state files
if (!state_path_prefix.empty()) if (!state_path_prefix.empty())
@ -5387,7 +5468,7 @@ static int main_worker(int argc, char **argv)
write_all_dev_attrlogs(configs, states); write_all_dev_attrlogs(configs, states);
// user has asked us to exit after first check // user has asked us to exit after first check
if (quit==3) { if (quit == QUIT_ONECHECK) {
PrintOut(LOG_INFO,"Started with '-q onecheck' option. All devices sucessfully checked once.\n" PrintOut(LOG_INFO,"Started with '-q onecheck' option. All devices sucessfully checked once.\n"
"smartd is exiting (exit status 0)\n"); "smartd is exiting (exit status 0)\n");
return 0; return 0;

View File

@ -1,8 +1,8 @@
#! /bin/sh #! /bin/sh
# smartmontools init file for smartd # smartmontools init file for smartd
# Copyright (C) 2002-8 Bruce Allen <smartmontools-support@lists.sourceforge.net> # Copyright (C) 2002-8 Bruce Allen
# $Id: smartd.initd.in 4120 2015-08-27 16:12:21Z samm2 $ # $Id: smartd.initd.in 4431 2017-08-08 19:38:15Z chrfranke $
# For RedHat and cousins: # For RedHat and cousins:
# chkconfig: 2345 40 40 # chkconfig: 2345 40 40
@ -45,7 +45,7 @@ report_unsupported () {
echo "Currently the smartmontools package has no init script for" echo "Currently the smartmontools package has no init script for"
echo "the $1 OS/distribution. If you can provide one or this" echo "the $1 OS/distribution. If you can provide one or this"
echo "one works after removing some ifdefs, please contact" echo "one works after removing some ifdefs, please contact"
echo "smartmontools-support@lists.sourceforge.net." echo "smartmontools-support@listi.jpberlin.de."
exit 1 exit 1
} }
@ -147,7 +147,7 @@ if [ -f /etc/redhat-release -o -f /etc/yellowdog-release -o -f /etc/mandrake-rel
elif [ -f /etc/slackware-version ] ; then elif [ -f /etc/slackware-version ] ; then
# Source configuration file. This should define the shell variable smartd_opts. # Source configuration file. This should define the shell variable smartd_opts.
# Email smartmontools-support@lists.sourceforge.net if there is a better choice # Email smartmontools-support mailing list if there is a better choice
# of path for Slackware. # of path for Slackware.
[ -r /etc/sysconfig/smartmontools ] && . /etc/sysconfig/smartmontools [ -r /etc/sysconfig/smartmontools ] && . /etc/sysconfig/smartmontools
@ -494,7 +494,7 @@ elif uname -a | grep FreeBSD > /dev/null 2>&1 ; then
elif uname -a | grep SunOS > /dev/null 2>&1 ; then elif uname -a | grep SunOS > /dev/null 2>&1 ; then
# Source configuration file. This should define the shell variable smartd_opts. # Source configuration file. This should define the shell variable smartd_opts.
# Email smartmontools-support@lists.sourceforge.net if there is a better choice # Email smartmontools-support mailing list if there is a better choice
# of path for Solaris # of path for Solaris
[ -r /etc/default/smartmontools ] && . /etc/default/smartmontools [ -r /etc/default/smartmontools ] && . /etc/default/smartmontools
@ -543,7 +543,7 @@ built into ATA and SCSI Hard Drives. \
http://www.smartmontools.org/" http://www.smartmontools.org/"
# Source configuration file. This should define the shell variable smartd_opts. # Source configuration file. This should define the shell variable smartd_opts.
# Email smartmontools-support@lists.sourceforge.net if there is a better choice # Email smartmontools-support mailing list if there is a better choice
# of path for Cygwin # of path for Cygwin
[ -r /etc/sysconfig/smartmontools ] && . /etc/sysconfig/smartmontools [ -r /etc/sysconfig/smartmontools ] && . /etc/sysconfig/smartmontools
@ -658,5 +658,5 @@ fi
# One should NEVER arrive here, except for a badly written case above, # One should NEVER arrive here, except for a badly written case above,
# that fails to exit. # that fails to exit.
echo "SOMETHING IS WRONG WITH THE SMARTD STARTUP SCRIPT" echo "SOMETHING IS WRONG WITH THE SMARTD STARTUP SCRIPT"
echo "PLEASE CONTACT smartmontools-support@lists.sourceforge.net" echo "PLEASE CONTACT smartmontools-support@listi.jpberlin.de"
exit 1 exit 1

View File

@ -2,7 +2,9 @@
# #
# smartd warning script # smartd warning script
# #
# Copyright (C) 2012-14 Christian Franke <smartmontools-support@lists.sourceforge.net> # Home page of code is: http://www.smartmontools.org
#
# Copyright (C) 2012-16 Christian Franke
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
@ -12,12 +14,13 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# (for example COPYING); If not, see <http://www.gnu.org/licenses/>. # (for example COPYING); If not, see <http://www.gnu.org/licenses/>.
# #
# $Id: smartd_warning.sh.in 3932 2014-06-29 19:02:38Z chrfranke $ # $Id: smartd_warning.sh.in 4351 2016-10-17 18:53:40Z chrfranke $
# #
set -e set -e
# Set by config.status # Set by config.status
@ENABLE_SCRIPTPATH_TRUE@export PATH="@scriptpath@"
PACKAGE="@PACKAGE@" PACKAGE="@PACKAGE@"
VERSION="@VERSION@" VERSION="@VERSION@"
prefix="@prefix@" prefix="@prefix@"

View File

@ -1,8 +1,8 @@
.ig .ig
Copyright (C) 2013 Hannes von Haugwitz <hannes@vonhaugwitz.com> Copyright (C) 2013 Hannes von Haugwitz <hannes@vonhaugwitz.com>
Copyright (C) 2014-16 Christian Franke Copyright (C) 2014-17 Christian Franke
$Id: update-smart-drivedb.8.in 4223 2016-02-26 20:18:40Z chrfranke $ $Id: update-smart-drivedb.8.in 4584 2017-11-03 22:43:32Z chrfranke $
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -13,15 +13,28 @@ You should have received a copy of the GNU General Public License
(for example COPYING); If not, see <http://www.gnu.org/licenses/>. (for example COPYING); If not, see <http://www.gnu.org/licenses/>.
.. ..
.\" Macros borrowed from pages generated with Pod::Man
.de Vb \" Begin verbatim text
.ft CW
.nf
.ne \\$1
..
.de Ve \" End verbatim text
.ft R
.fi
..
.\" Use groff extension \(aq (apostrophe quote, ASCII 0x27) if possible
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.TH UPDATE-SMART-DRIVEDB 8 "CURRENT_SVN_DATE" "CURRENT_SVN_VERSION" "SMART Monitoring Tools" .TH UPDATE-SMART-DRIVEDB 8 "CURRENT_SVN_DATE" "CURRENT_SVN_VERSION" "SMART Monitoring Tools"
.SH NAME .SH NAME
update-smart-drivedb \- update smartmontools drive database update-smart-drivedb \- update smartmontools drive database
.Sp
.SH "SYNOPSIS" .SH "SYNOPSIS"
.B update-smart-drivedb .B update-smart-drivedb
.RI [ OPTIONS ] .RI [ OPTIONS ]
.RI [ DESTFILE ] .RI [ DESTFILE ]
.Sp
.SH "DESCRIPTION" .SH "DESCRIPTION"
.\" %IF NOT OS ALL .\" %IF NOT OS ALL
.\"! [This man page is generated for the OS_MAN_FILTER version of smartmontools. .\"! [This man page is generated for the OS_MAN_FILTER version of smartmontools.
@ -33,10 +46,9 @@ updates
.B /usr/local/share/smartmontools/drivedb.h .B /usr/local/share/smartmontools/drivedb.h
or or
.I DESTFILE .I DESTFILE
from smartmontools SVN repository. from branches/RELEASE_6_0_DRIVEDB of smartmontools SVN repository.
.PP
It tries to download first from the current branch and then from The tools used for downloading are either
trunk. The tools used for downloading are either
.BR curl (1), .BR curl (1),
.BR wget (1), .BR wget (1),
.BR lynx (1), .BR lynx (1),
@ -50,18 +62,22 @@ trunk. The tools used for downloading are either
.\" %ENDIF OS OpenBSD .\" %ENDIF OS OpenBSD
or or
.BR svn (1). .BR svn (1).
.PP
[NEW EXPERIMENTAL UPDATE-SMART-DRIVEDB FEATURE]
The downloaded file is verified with OpenPGP/GPG key ID DFD22559.
The public key block is included in the script.
.PP
The old file is kept if the downloaded file is identical (ignoring The old file is kept if the downloaded file is identical (ignoring
the differences in Id string) otherwise it is moved to the differences in Id string) otherwise it is moved to
.BR drivedb.h.old . .BR drivedb.h.old .
.Sp
.SH "OPTIONS" .SH "OPTIONS"
.TP .TP
.B \-s SMARTCTL .B \-s SMARTCTL
Use the Use the
.BR smartctl (8) .BR smartctl (8)
executable at path SMARTCTL for drive database syntax check. executable at path SMARTCTL for drive database syntax check.
The form \'\-s \-\' disables the syntax check. The form \*(Aq\-s \-\*(Aq disables the syntax check.
The default is The default is
.BR /usr/local/sbin/smartctl . .BR /usr/local/sbin/smartctl .
.TP .TP
@ -79,7 +95,8 @@ TOOL is one of:
The default is the first one found in PATH. The default is the first one found in PATH.
.TP .TP
.B \-u LOCATION .B \-u LOCATION
Use URL of LOCATION for download. LOCATION is one of: Use URL of LOCATION for download.
LOCATION is one of:
.br .br
.I sf .I sf
(Sourceforge code browser via HTTPS), (Sourceforge code browser via HTTPS),
@ -96,6 +113,11 @@ Use URL of LOCATION for download. LOCATION is one of:
The default is The default is
.IR svn . .IR svn .
.TP .TP
.B \-\-trunk
Download from SVN trunk.
This requires \*(Aq\-\-no\-verify\*(Aq unless the trunk version is still
identical to branches/RELEASE_6_0_DRIVEDB.
.TP
.B \-\-cacert FILE .B \-\-cacert FILE
Use CA certificates from FILE to verify the peer. Use CA certificates from FILE to verify the peer.
.TP .TP
@ -104,24 +126,33 @@ Use CA certificate files from DIR to verify the peer.
.TP .TP
.B \-\-insecure .B \-\-insecure
Don't abort download if certificate verification fails. Don't abort download if certificate verification fails.
This option is also required if a HTTP URL is selected with \'-u\' option. This option is also required if a HTTP URL is selected with \*(Aq\-u\*(Aq
option.
.TP
.B \-\-no\-verify
Don't verify signature with GnuPG.
.TP
.B \-\-export\-key
Print the OpenPGP/GPG public key block.
.TP .TP
.B \-\-dryrun .B \-\-dryrun
Print download commands only. Print download commands only.
.TP .TP
.B \-v .B \-v
Verbose output. Verbose output.
.Sp
.SH "EXAMPLES" .SH "EXAMPLES"
.nf .Vb 2
# update-smart-drivedb # update-smart-drivedb
/usr/local/share/smartmontools/drivedb.h updated from branches/RELEASE_6_0_DRIVEDB /usr/local/share/smartmontools/drivedb.h updated from \e
.fi branches/RELEASE_6_0_DRIVEDB
.Ve
.Sp
.SH "EXIT STATUS" .SH "EXIT STATUS"
The exit status is 0 if the database has been successfully The exit status is 0 if the database has been successfully
updated. If an error occurs the exit status is 1. updated.
If an error occurs the exit status is 1.
.Sp
.SH FILES .SH FILES
.TP .TP
.B /usr/local/sbin/update-smart-drivedb .B /usr/local/sbin/update-smart-drivedb
@ -133,34 +164,40 @@ used to check syntax of new drive database.
.B /usr/local/share/smartmontools/drivedb.h .B /usr/local/share/smartmontools/drivedb.h
current drive database. current drive database.
.TP .TP
.B /usr/local/share/smartmontools/drivedb.h.old .B /usr/local/share/smartmontools/drivedb.h.raw
previous drive database. current drive database with unexpanded SVN Id string.
.TP .TP
.B /usr/local/share/smartmontools/drivedb.h.error .B /usr/local/share/smartmontools/drivedb.h.raw.asc
new drive database if rejected due to syntax errors. signature file.
.TP
.B /usr/local/share/smartmontools/drivedb.h.*old*
previous files.
.TP
.B /usr/local/share/smartmontools/drivedb.h.*error*
new files if rejected due to errors.
.TP .TP
.B /usr/local/share/smartmontools/drivedb.h.lastcheck .B /usr/local/share/smartmontools/drivedb.h.lastcheck
empty file created if downloaded file was identical. empty file created if downloaded file was identical.
.Sp
.SH AUTHORS .SH AUTHORS
\fBChristian Franke\fP. \fBChristian Franke\fP.
.br .br
This manual page was originally written by This manual page was originally written by
.BR "Hannes von Haugwitz <hannes@vonhaugwitz.com>" . .BR "Hannes von Haugwitz <hannes@vonhaugwitz.com>" .
.Sp
.SH REPORTING BUGS .SH REPORTING BUGS
To submit a bug report, create a ticket in smartmontools wiki: To submit a bug report, create a ticket in smartmontools wiki:
.br .br
<\fBhttp://www.smartmontools.org/\fP>. <\fBhttps://www.smartmontools.org/\fP>.
.br .br
Alternatively send the info to the smartmontools support mailing list: Alternatively send the info to the smartmontools support mailing list:
.br .br
<\fBhttps://lists.sourceforge.net/lists/listinfo/smartmontools-support\fB>. <\fBhttps://listi.jpberlin.de/mailman/listinfo/smartmontools-support\fB>.
.Sp
.SH SEE ALSO .SH SEE ALSO
\fBsmartctl\fP(8), \fBsmartd\fP(8). \fBsmartctl\fP(8), \fBsmartd\fP(8).
.Sp
.SH PACKAGE VERSION .SH PACKAGE VERSION
CURRENT_SVN_VERSION CURRENT_SVN_DATE CURRENT_SVN_REV CURRENT_SVN_VERSION CURRENT_SVN_DATE CURRENT_SVN_REV
.br .br
$Id: update-smart-drivedb.8.in 4223 2016-02-26 20:18:40Z chrfranke $ $Id: update-smart-drivedb.8.in 4584 2017-11-03 22:43:32Z chrfranke $

View File

@ -2,7 +2,9 @@
# #
# smartmontools drive database update script # smartmontools drive database update script
# #
# Copyright (C) 2010-16 Christian Franke # Home page of code is: http://www.smartmontools.org
#
# Copyright (C) 2010-17 Christian Franke
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
@ -12,12 +14,13 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# (for example COPYING); If not, see <http://www.gnu.org/licenses/>. # (for example COPYING); If not, see <http://www.gnu.org/licenses/>.
# #
# $Id: update-smart-drivedb.in 4224 2016-02-26 20:29:24Z chrfranke $ # $Id: update-smart-drivedb.in 4584 2017-11-03 22:43:32Z chrfranke $
# #
set -e set -e
# Set by config.status # Set by config.status
@ENABLE_SCRIPTPATH_TRUE@export PATH="@scriptpath@"
PACKAGE="@PACKAGE@" PACKAGE="@PACKAGE@"
VERSION="@VERSION@" VERSION="@VERSION@"
prefix="@prefix@" prefix="@prefix@"
@ -36,6 +39,9 @@ BRANCH="@DRIVEDB_BRANCH@"
# Default drivedb location # Default drivedb location
DRIVEDB="$drivedbdir/drivedb.h" DRIVEDB="$drivedbdir/drivedb.h"
# GnuPG used to verify signature (disabled if empty)
GPG="@gnupg@"
# Smartctl used for syntax check # Smartctl used for syntax check
SMARTCTL="$sbindir/smartctl" SMARTCTL="$sbindir/smartctl"
@ -57,16 +63,18 @@ Usage: $myname [OPTIONS] [DESTFILE]
svn (SVN repository via HTTPS) [default] svn (SVN repository via HTTPS) [default]
svni (SVN repository via HTTP) svni (SVN repository via HTTP)
trac (Trac code browser via HTTPS) trac (Trac code browser via HTTPS)
--trunk Download from SVN trunk (may require '--no-verify')
--cacert FILE Use CA certificates from FILE to verify the peer --cacert FILE Use CA certificates from FILE to verify the peer
--capath DIR Use CA certificate files from DIR to verify the peer --capath DIR Use CA certificate files from DIR to verify the peer
--insecure Don't abort download if certificate verification fails --insecure Don't abort download if certificate verification fails
--no-verify Don't verify signature
--export-key Print the OpenPGP/GPG public key block
--dryrun Print download commands only --dryrun Print download commands only
-v Verbose output -v Verbose output
Updates $DRIVEDB Updates $DRIVEDB
or DESTFILE from smartmontools SVN repository. or DESTFILE from branches/$BRANCH of smartmontools
Tries to download first from branch $BRANCH SVN repository.
and then from trunk.
EOF EOF
exit 1 exit 1
} }
@ -149,7 +157,7 @@ vrun2()
# download URL FILE # download URL FILE
download() download()
{ {
local f u se rc local f u rc
u=$1; f=$2 u=$1; f=$2
rc=0 rc=0
@ -207,15 +215,136 @@ download()
return $rc return $rc
} }
# check_file FILE FIRST_CHAR MIN_SIZE MAX_SIZE
check_file()
{
local firstchar f maxsize minsize size
test -z "$dryrun" || return 0
f=$1; firstchar=$2; minsize=$3; maxsize=$4
# Check first chars
case `dd if="$f" bs=1 count=1 2>/dev/null` in
$firstchar) ;;
\<) echo "HTML error message"; return 1 ;;
*) echo "unknown file contents"; return 1 ;;
esac
# Check file size
size=`wc -c < "$f"`
if test "$size" -lt $minsize; then
echo "too small file size $size bytes"
return 1
fi
if test "$size" -gt $maxsize; then
echo "too large file size $size bytes"
return 1
fi
return 0
}
# unexpand_svn_id < INFILE > OUTFILE
unexpand_svn_id()
{
sed 's,\$''Id'': drivedb\.h [0-9][0-9]* 2[-0-9]* [012][:0-9]*Z [a-z][a-z]* \$,$''Id''$,'
}
# Smartmontools Signing Key (through 2018)
# <smartmontools-database@listi.jpberlin.de>
# Key ID DFD22559
public_key="\
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQENBFgOYoEBCAC93841SlFmpp6640hKUvZ8PbZR6OGnZnMXD6QRVzpibXGZXUDB
f6unujun5Ql4ObAWt6QuRqz5Gk2gF8tcOfN6edR/uK5gyX2rlWVLoZKOV91a3aDI
iIDh018tLWOpHg3VxgHL6f0iMcFogUYnD5zhC5Z2GVhFb/cVpj+ocZWcxQLQGPVv
uZPUQWrvdpFEzcnxPMtJJDqXEChzhrdFTXGm69ERxULOro7yDmG1Y5xWmhdGnPPM
cuCXVVlADz/Gh1w+ay7RqFnzPjqjQmHAuggns467TJEcS0yiX4LJnEoKLyPGen9L
FH6z38xHCNt4Da05/OeRgXwVLH9M95lu8d6TABEBAAG0U1NtYXJ0bW9udG9vbHMg
U2lnbmluZyBLZXkgKHRocm91Z2ggMjAxOCkgPHNtYXJ0bW9udG9vbHMtZGF0YWJh
c2VAbGlzdGkuanBiZXJsaW4uZGU+iQFBBBMBAgArAhsDBQkEHA0ABgsJCAcDAgYV
CAIJCgsEFgIDAQIeAQIXgAUCWe5KCQIZAQAKCRDzh2PO39IlWbM5CAC6GNFXkJEu
Beu1TV2e3N47IwZDsQXypn8DGBVh5VmhFGVHPO5dgBBGXEHBcpiFk6RGXOqyLQar
bZd0qmGaTCuakUU5MipCB/fPEpOm15CSPzJIAAHz0HiDgJc8YW+JfGUA6P4EHa+r
OyYcfCu66NNYTjBQJ/wHcwcuIY1xNzEMhb4TCEcM/Nex9zZ7d0+WTWsK4U8m3ui3
IDESRssCzTTjc5gH/tMz8KuEwY3v91mHc0/vNYVQZx9atWOuuj3JJKqdr8oll/qo
/33gIadY66dgArQhqybdPFCEKckhoHvlPxoqg7XPKSw6oyBxM/0wf/gM5MGsUImD
qu1djwVlKH7xiQEcBBMBAgAGBQJZ7kylAAoJEC/N7AvTrxqroQQH/jrZAGT5t8uy
zRTzJCf3Bco8FqwKcfw8hhpF1Uaypa+quxkpYz9PtP+3e9lGxl0XSEzOwHjfgGWX
ISUOM1ufVxo2hSLG87yO7naFAtylL8l0Zny8Fb6kmT9f3vMktbHdXHUTDNrCUkoE
lEwwDK3qaur8IPUaIKeSTC3C8E/DVnasLs9cpOs2LPIKr3ishbqbHNeWOgGyHbA4
KCtvQzBhun9drmtQJW6OyCC9FcIoqPSFM/bs2KHf7qATNu9kSMg/YWw7WLAD4GPq
H9us1GigQ0h6Y4KG5EgmkFvuQFPLHvT4rtqv51zzs1iwFh4+GIagFp+HJ2jnlp+G
cZcySlwfnem0V1NtYXJ0bW9udG9vbHMgU2lnbmluZyBLZXkgKHRocm91Z2ggMjAx
OCkgPHNtYXJ0bW9udG9vbHMtZGF0YWJhc2VAbGlzdHMuc291cmNlZm9yZ2UubmV0
PokBPgQTAQIAKAUCWA5igQIbAwUJBBwNAAYLCQgHAwIGFQgCCQoLBBYCAwECHgEC
F4AACgkQ84djzt/SJVldMQf+MxE3PM70mnIr/Dcrubt8AA3JeMkThNV2xFe9Rdkl
4tJ1ogU8T5PCgMqJ4Gei9mUmbiQu1CKLSf9k/oxBRcLZK8Fav+BMj0+4YERfZx7J
Qzou3f0RX8u3pc/+pRXLE6lH/Luk453NzqM3tCFyWgw89dEzFlwYpWx7AfxiFwvH
ShEPNKZdEp+aBAu8oW9lSKiwLNFsembSGVh+5+3yMiKK02oOdC/NPKTnxxDgvzl4
Ulm3dNjI3uuBtFNFvs6qKk8CXV9AfM2993QxaCtRMph/ymqX4zXcecvJYpn3vulF
bAzDTzge7TVhkmaupzDNLeE8IS5sgUjSOM1x3+2SkBiVSYkBHAQTAQIABgUCWA5k
YwAKCRDfDxpJxKSQOp+/CADTlsgisoXI6b+0oohRaD4ZVl5eBtkvTrxNQf6EF7Z1
uPkVOqi1OLWFGyAmbeLcRmN6c4/DVcaa6GAG7GA+KQwVPRCyC+9Ibsn/+uG6ZFXA
ez+0eG9NxOfkCnYH8ZP8o2VH+9uKJlGGujh9o5r1SNGVifoLGTc8NkWCW+MAKj8d
w8WW+wDc80YrdCRrSyLrRU9NLTSE4pIJWKcHLwG63xkXHQPPR1lsJgzdAalfEv1T
QdIF3sM+GXp4lZ6buahFDiILBh1vj+5C9TdpWZAlqHDYFICa7Rv/MvQa4O9UUl3S
lN3sed8zwAmL3HeoXE5tBu8iatMaS9e3BmSsVYlhd/q+iQEcBBMBAgAGBQJYDmSW
AAoJEC/N7AvTrxqr8HsH+QGQuhHYt9Syccd8AF36psyT03mqgbGLMZL8H9ngoa9Z
qVMq7O8Aqz23SGTtuNuw6EyrcHo7Dy1311GftshI6arsFNJxE2ZNGIfGocRxu9m3
Ez+AysWT9sxz/haHE+d58NTg+/7R8YWS1q+Tk6m8dA0Xyf3tMBsIJfj0zJvuGMbC
Lmd93Yw4nk76qtSn9UHbnf76UJN5SctAd8+gK3uO6O4XDcZqC06xkWKl193lzcC8
sZJBdI15NszC3y/epnILDDMBUNQMBm/XlCYQUetyrJnAVzFGXurtjEXQ/DDnbfy2
Z8efoG8rtq7v3fxS1TC5jSVOIEqOE4TwzRz1Y/dfqSU=
=CNK4
-----END PGP PUBLIC KEY BLOCK-----
"
# gpg_verify FILE.asc FILE
gpg_verify()
{
local gnupgtmp opts out rc
opts="--quiet ${q:+--no-secmem-warnin} --batch --no-tty"
# Create temp home dir
gnupgtmp="$tmpdir/.gnupg.$$.tmp"
rm -f -r "$gnupgtmp"
mkdir "$gnupgtmp" || exit 1
chmod 0700 "$gnupgtmp"
# Import public key
"$GPG" $opts --homedir="$gnupgtmp" --import <<EOF
$public_key
EOF
test $? = 0 || exit 1
# Verify
rc=0
out=`"$GPG" $opts --homedir="$gnupgtmp" --verify "$1" "$2" </dev/null 2>&1` || rc=1
vecho "$out"
rm -f -r "$gnupgtmp"
return $rc
}
# mv_all PREFIX OLD NEW
mv_all()
{
mv "${1}${2}" "${1}${3}"
mv "${1}${2}.raw" "${1}${3}.raw"
mv "${1}${2}.raw.asc" "${1}${3}.raw.asc"
}
# Parse options # Parse options
smtctl=$SMARTCTL smtctl=$SMARTCTL
tool= tool=
url= url=
q="-q" q="-q"
dryrun= dryrun=
trunk=
cacert= cacert=
capath= capath=
insecure= insecure=
no_verify=
while true; do case $1 in while true; do case $1 in
-s) -s)
@ -237,6 +366,9 @@ while true; do case $1 in
--dryrun) --dryrun)
dryrun=t ;; dryrun=t ;;
--trunk)
trunk=trunk ;;
--cacert) --cacert)
shift; test -n "$1" || usage shift; test -n "$1" || usage
cacert=$1 ;; cacert=$1 ;;
@ -248,6 +380,15 @@ while true; do case $1 in
--insecure) --insecure)
insecure=t ;; insecure=t ;;
--no-verify)
no_verify=t ;;
--export-key)
cat <<EOF
$public_key
EOF
exit 0 ;;
-*) -*)
usage ;; usage ;;
@ -291,95 +432,104 @@ case "$tool:$insecure" in
lynx:t) warning "'--insecure' is ignored if '-t lynx' is used" ;; lynx:t) warning "'--insecure' is ignored if '-t lynx' is used" ;;
esac esac
# Try possible branch first, then trunk # Check for smartctl
errmsg= if [ "$smtctl" != "-" ]; then
errmsg2= "$smtctl" -V >/dev/null 2>&1 \
for location in "branches/$BRANCH" "trunk"; do || error "$smtctl: not found ('-s -' to ignore)"
test -z "$errmsg" || errmsg2=$errmsg fi
vecho "Download from $location with $tool"
# Adjust URL # Check for GnuPG
case $location in if [ -z "$no_verify" ]; then
trunk) src=$url ;; test -n "$GPG" \
*) src=`echo "$url" | sed "s,/trunk/,/$location/,"` ;; || error "GnuPG is not available ('--no-verify' to ignore)"
esac "$GPG" --version >/dev/null 2>&1 \
|| error "$GPG: not found ('--no-verify' to ignore)"
fi
# Use destination directory as temp directory for gpg
tmpdir=`dirname "$DEST"`
# Adjust URLs
src=`echo "$url" | sed "s,/trunk/,/branches/$BRANCH/,"`
src_asc=`echo "$src" | sed "s,/drivedb\.h,/drivedb.h.raw.asc,"`
test -z "$trunk" || src=$url
# Download # Download
test -n "$dryrun" || rm -f "$DEST.new" || exit 1 test -n "$dryrun" || rm -f "$DEST.new" "$DEST.new.raw" "$DEST.new.raw.asc"
vecho "Download ${trunk:-branches/$BRANCH}/drivedb.h with $tool"
rc=0 rc=0
download "$src" "$DEST.new" || rc=$? download "$src" "$DEST.new" || rc=$?
test -z "$dryrun" || continue
errmsg=
if [ $rc != 0 ]; then if [ $rc != 0 ]; then
errmsg="download from $location failed ($tool: exit $rc)" rm -f "$DEST.new"
continue error "${trunk:-$BRANCH}/drivedb.h: download failed ($tool: exit $rc)"
fi
if ! errmsg=`check_file "$DEST.new" '/' 10000 1000000`; then
mv "$DEST.new" "$DEST.error"
error "$DEST.error: $errmsg"
fi fi
# Check file contents vecho "Download branches/$BRANCH/drivedb.h.raw.asc with $tool"
case `sed 1q "$DEST.new"` in rc=0
/*) ;; download "$src_asc" "$DEST.new.raw.asc" || rc=$?
\<*) if [ $rc != 0 ]; then
errmsg="download from $location failed (HTML error message)" rm -f "$DEST.new" "$DEST.new.raw.asc"
continue ;; error "$BRANCH/drivedb.h.raw.asc: download failed ($tool: exit $rc)"
*)
errmsg="download from $location failed (Unknown file contents)"
continue ;;
esac
# Check file size
size=`wc -c < "$DEST.new"`
if [ "$size" -lt 10000 ]; then
errmsg="download from $location failed (too small file size $size bytes)"
continue
fi fi
if [ "$size" -gt 1000000 ]; then if ! errmsg=`check_file "$DEST.new.raw.asc" '-' 200 2000`; then
errmsg="download from $location failed (too large file size $size bytes)" rm -f "$DEST.new"
break mv "$DEST.new.raw.asc" "$DEST.error.raw.asc"
error "$DEST.error.raw.asc: $errmsg"
fi fi
break
done
test -z "$dryrun" || exit 0 test -z "$dryrun" || exit 0
if [ -n "$errmsg" ]; then # Create raw file with unexpanded SVN Id
rm -f "$DEST.new" # (This assumes newlines are LF and not CR/LF)
test -z "$errmsg2" || echo "$myname: $errmsg2" >&2 unexpand_svn_id < "$DEST.new" > "$DEST.new.raw"
error "$errmsg"
fi
# Adjust timestamp and permissions # Adjust timestamps and permissions
touch "$DEST.new" touch "$DEST.new" "$DEST.new.raw" "$DEST.new.raw.asc"
chmod 0644 "$DEST.new" chmod 0644 "$DEST.new" "$DEST.new.raw" "$DEST.new.raw.asc"
if [ -z "$no_verify" ]; then
# Verify raw file
if ! gpg_verify "$DEST.new.raw.asc" "$DEST.new.raw"; then
mv_all "$DEST" ".new" ".error"
test -n "$trunk" || error "$DEST.error.raw: *** BAD signature ***"
error "$DEST.error.raw: signature from branch no longer valid ('--no-verify' to ignore)"
fi
fi
if [ "$smtctl" != "-" ]; then if [ "$smtctl" != "-" ]; then
# Check syntax # Check syntax
rm -f "$DEST.error" if ! "$smtctl" -B "$DEST.new" -P showall >/dev/null; then
if "$smtctl" -B "$DEST.new" -P showall >/dev/null; then mv_all "$DEST" ".new" ".error"
test -n "$q" || echo "$smtctl: syntax OK" error "$DEST.error: rejected by $smtctl, probably no longer compatible"
else
mv "$DEST.new" "$DEST.error"
echo "$DEST.error: rejected by $smtctl, probably no longer compatible" >&2
exit 1
fi fi
vecho "$smtctl: syntax OK"
fi fi
# Keep old file if identical, ignore missing Id keyword expansion in new file # Keep old file if identical, ignore missing Id keyword expansion in new file
rm -f "$DEST.lastcheck" rm -f "$DEST.lastcheck"
if [ -f "$DEST" ]; then if [ -f "$DEST" ]; then
if cmp "$DEST" "$DEST.new" >/dev/null 2>/dev/null \ if [ -f "$DEST.raw" ] && [ -f "$DEST.raw.asc" ]; then
|| cat "$DEST" | sed 's|\$''Id''[^$]*\$|$''Id''$|' \ if cmp "$DEST.raw" "$DEST.new.raw" >/dev/null 2>&1 \
| cmp - "$DEST.new" >/dev/null 2>/dev/null; then && cmp "$DEST.raw.asc" "$DEST.new.raw.asc" >/dev/null 2>&1 \
rm -f "$DEST.new" && { cmp "$DEST" "$DEST.new" >/dev/null 2>&1 \
|| cmp "$DEST.raw" "$DEST.new" >/dev/null 2>&1; }
then
rm -f "$DEST.new" "$DEST.new.raw" "$DEST.new.raw.asc"
touch "$DEST.lastcheck" touch "$DEST.lastcheck"
echo "$DEST is already up to date" echo "$DEST is already up to date"
exit 0 exit 0
fi fi
mv_all "$DEST" "" ".old"
else
mv "$DEST" "$DEST.old" mv "$DEST" "$DEST.old"
fi fi
fi
mv "$DEST.new" "$DEST" mv_all "$DEST" ".new" ""
echo "$DEST updated from $location"
echo "$DEST updated from ${trunk:-branches/$BRANCH}${no_verify:+ (NOT VERIFIED)}"

View File

@ -4,7 +4,7 @@
* Home page of code is: http://www.smartmontools.org * Home page of code is: http://www.smartmontools.org
* *
* Copyright (C) 2002-12 Bruce Allen * Copyright (C) 2002-12 Bruce Allen
* Copyright (C) 2008-16 Christian Franke * Copyright (C) 2008-17 Christian Franke
* Copyright (C) 2000 Michael Cornwell <cornwell@acm.org> * Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -52,7 +52,7 @@
#include "atacmds.h" #include "atacmds.h"
#include "dev_interface.h" #include "dev_interface.h"
const char * utility_cpp_cvsid = "$Id: utility.cpp 4309 2016-04-24 14:59:15Z chrfranke $" const char * utility_cpp_cvsid = "$Id: utility.cpp 4583 2017-11-03 21:10:09Z chrfranke $"
UTILITY_H_CVSID INT64_H_CVSID; UTILITY_H_CVSID INT64_H_CVSID;
const char * packet_types[] = { const char * packet_types[] = {
@ -90,7 +90,7 @@ std::string format_version_info(const char * prog_name, bool full /*= false*/)
"(build date " __DATE__ ")" // checkout without expansion of Id keywords "(build date " __DATE__ ")" // checkout without expansion of Id keywords
#endif #endif
" [%s] " BUILD_INFO "\n" " [%s] " BUILD_INFO "\n"
"Copyright (C) 2002-16, Bruce Allen, Christian Franke, www.smartmontools.org\n", "Copyright (C) 2002-17, Bruce Allen, Christian Franke, www.smartmontools.org\n",
prog_name, smi()->get_os_version_str().c_str() prog_name, smi()->get_os_version_str().c_str()
); );
if (!full) if (!full)
@ -315,6 +315,11 @@ void dateandtimezoneepoch(char *buffer, time_t tval){
lenm1=strlen(datebuffer)-1; lenm1=strlen(datebuffer)-1;
datebuffer[lenm1>=0?lenm1:0]='\0'; datebuffer[lenm1>=0?lenm1:0]='\0';
#if defined(_WIN32) && defined(_MSC_VER)
// tzname is missing in MSVC14
#define tzname _tzname
#endif
// correct timezone name // correct timezone name
if (tmval->tm_isdst==0) if (tmval->tm_isdst==0)
// standard time zone // standard time zone
@ -733,7 +738,7 @@ const char * format_capacity(char * str, int strsize, uint64_t val,
} }
// return (v)sprintf() formatted std::string // return (v)sprintf() formatted std::string
__attribute_format_printf(1, 0)
std::string vstrprintf(const char * fmt, va_list ap) std::string vstrprintf(const char * fmt, va_list ap)
{ {
char buf[512]; char buf[512];
@ -782,7 +787,14 @@ int safe_snprintf(char *buf, int size, const char *fmt, ...)
return i; return i;
} }
#else // HAVE_WORKING_SNPRINTF static void check_snprintf() {}
#elif defined(__GNUC__) && (__GNUC__ >= 7)
// G++ 7+: Assume sane implementation and avoid -Wformat-truncation warning
static void check_snprintf() {}
#else
static void check_snprintf() static void check_snprintf()
{ {
@ -790,8 +802,7 @@ static void check_snprintf()
int n1 = snprintf(buf, 8, "123456789"); int n1 = snprintf(buf, 8, "123456789");
int n2 = snprintf(buf, 0, "X"); int n2 = snprintf(buf, 0, "X");
if (!(!strcmp(buf, "1234567") && n1 == 9 && n2 == 1)) if (!(!strcmp(buf, "1234567") && n1 == 9 && n2 == 1))
throw std::logic_error("Function snprintf() does not conform to C99,\n" throw std::logic_error("Function snprintf() does not conform to C99");
"please contact " PACKAGE_BUGREPORT);
} }
#endif // HAVE_WORKING_SNPRINTF #endif // HAVE_WORKING_SNPRINTF
@ -800,7 +811,5 @@ static void check_snprintf()
void check_config() void check_config()
{ {
check_endianness(); check_endianness();
#ifdef HAVE_WORKING_SNPRINTF
check_snprintf(); check_snprintf();
#endif
} }