Skip to content
Snippets Groups Projects
Commit 2024615f authored by ballen4705's avatar ballen4705
Browse files

Using new check function (really call SMART status command)

git-svn-id: https://smartmontools.svn.sourceforge.net/svnroot/smartmontools/trunk@84 4ea69e1a-61f1-4043-bf83-b5c94c648137
parent 105c594b
No related branches found
No related tags found
No related merge requests found
......@@ -30,7 +30,7 @@
#include <errno.h>
#include "atacmds.h"
const char *CVSid1="$Id: atacmds.c,v 1.17 2002/10/22 09:50:53 ballen4705 Exp $\n" "\t" CVSID1 ;
const char *CVSid1="$Id: atacmds.c,v 1.18 2002/10/22 14:57:43 ballen4705 Exp $\n" "\t" CVSID1 ;
// These Drive Identity tables are taken from hdparm 5.2, and are also
// given in the ATA/ATAPI specs for the IDENTIFY DEVICE command. Note
......@@ -517,7 +517,9 @@ int ataSmartStatus2(int device){
return 1;
// We haven't gotten output that makes sense; print out some debugging info
perror("SMART Status returned register values that don't make sense:\n");
perror("SMART Status command failed:");
printf("Please get assistance from %s\n",PROJECTHOME);
printf("Register values returned from SMART Status command are:\n");
printf("CMD=0x%02x\n",parms[0]);
printf("FR =0x%02x\n",parms[1]);
printf("NS =0x%02x\n",parms[2]);
......@@ -525,7 +527,6 @@ int ataSmartStatus2(int device){
printf("CL =0x%02x\n",parms[4]);
printf("CH =0x%02x\n",parms[5]);
printf("SEL=0x%02x\n",parms[6]);
return -1;
}
......@@ -626,16 +627,34 @@ int isSupportSelfTest (struct ata_smart_values data){
// to its corresponding attribute threshold indicates a pre-failure
// condition where imminent loss of data is being predicted."
int ataCheckSmart (struct ata_smart_values data, struct ata_smart_thresholds thresholds){
// onlyfailing=0 : are or were any age or prefailure attributes <= threshold
// onlyfailing=1: are any prefailure attributes <= threshold now
int ataCheckSmart (struct ata_smart_values data,
struct ata_smart_thresholds thresholds,
int onlyfailed){
int i;
// loop over all attributes
for (i=0; i<NUMBER_ATA_SMART_ATTRIBUTES; i++){
if (data.vendor_attributes[i].id &&
thresholds.thres_entries[i].id &&
data.vendor_attributes[i].status.flag.prefailure &&
(data.vendor_attributes[i].current <= thresholds.thres_entries[i].threshold) &&
(thresholds.thres_entries[i].threshold != 0xFE))
return data.vendor_attributes[i].id;
// pointers to disk's values and vendor's thresholds
struct ata_smart_attribute *disk=data.vendor_attributes+i;
struct ata_smart_threshold_entry *thre=thresholds.thres_entries+i;
// consider only valid attributes
if (disk->id && thre->id){
int failednow,failedever;
failednow =disk->current <= thre->threshold;
failedever=disk->worst <= thre->threshold;
if (!onlyfailed && failedever)
return disk->id;
if (onlyfailed && failednow && disk->status.flag.prefailure)
return disk->id;
}
}
return 0;
}
......@@ -30,7 +30,7 @@
#include <errno.h>
#include "atacmds.h"
const char *CVSid1="$Id: atacmds.cpp,v 1.17 2002/10/22 09:50:53 ballen4705 Exp $\n" "\t" CVSID1 ;
const char *CVSid1="$Id: atacmds.cpp,v 1.18 2002/10/22 14:57:43 ballen4705 Exp $\n" "\t" CVSID1 ;
// These Drive Identity tables are taken from hdparm 5.2, and are also
// given in the ATA/ATAPI specs for the IDENTIFY DEVICE command. Note
......@@ -517,7 +517,9 @@ int ataSmartStatus2(int device){
return 1;
// We haven't gotten output that makes sense; print out some debugging info
perror("SMART Status returned register values that don't make sense:\n");
perror("SMART Status command failed:");
printf("Please get assistance from %s\n",PROJECTHOME);
printf("Register values returned from SMART Status command are:\n");
printf("CMD=0x%02x\n",parms[0]);
printf("FR =0x%02x\n",parms[1]);
printf("NS =0x%02x\n",parms[2]);
......@@ -525,7 +527,6 @@ int ataSmartStatus2(int device){
printf("CL =0x%02x\n",parms[4]);
printf("CH =0x%02x\n",parms[5]);
printf("SEL=0x%02x\n",parms[6]);
return -1;
}
......@@ -626,16 +627,34 @@ int isSupportSelfTest (struct ata_smart_values data){
// to its corresponding attribute threshold indicates a pre-failure
// condition where imminent loss of data is being predicted."
int ataCheckSmart (struct ata_smart_values data, struct ata_smart_thresholds thresholds){
// onlyfailing=0 : are or were any age or prefailure attributes <= threshold
// onlyfailing=1: are any prefailure attributes <= threshold now
int ataCheckSmart (struct ata_smart_values data,
struct ata_smart_thresholds thresholds,
int onlyfailed){
int i;
// loop over all attributes
for (i=0; i<NUMBER_ATA_SMART_ATTRIBUTES; i++){
if (data.vendor_attributes[i].id &&
thresholds.thres_entries[i].id &&
data.vendor_attributes[i].status.flag.prefailure &&
(data.vendor_attributes[i].current <= thresholds.thres_entries[i].threshold) &&
(thresholds.thres_entries[i].threshold != 0xFE))
return data.vendor_attributes[i].id;
// pointers to disk's values and vendor's thresholds
struct ata_smart_attribute *disk=data.vendor_attributes+i;
struct ata_smart_threshold_entry *thre=thresholds.thres_entries+i;
// consider only valid attributes
if (disk->id && thre->id){
int failednow,failedever;
failednow =disk->current <= thre->threshold;
failedever=disk->worst <= thre->threshold;
if (!onlyfailed && failedever)
return disk->id;
if (onlyfailed && failednow && disk->status.flag.prefailure)
return disk->id;
}
}
return 0;
}
......@@ -26,7 +26,7 @@
#define _ATACMDS_H_
#ifndef CVSID1
#define CVSID1 "$Id: atacmds.h,v 1.15 2002/10/22 09:44:55 ballen4705 Exp $\n"
#define CVSID1 "$Id: atacmds.h,v 1.16 2002/10/22 14:57:43 ballen4705 Exp $\n"
#endif
// These are the major and minor versions for smartd and smartctl
......@@ -330,7 +330,9 @@ int ataSmartSupport ( struct hd_driveid drive);
int ataIsSmartEnabled(struct hd_driveid drive);
/* Check SMART for Threshold failure */
int ataCheckSmart ( struct ata_smart_values data, struct ata_smart_thresholds thresholds);
// onlyfailed=0 : are or were any age or prefailure attributes <= threshold
// onlyfailed=1: are any prefailure attributes <= threshold now
int ataCheckSmart ( struct ata_smart_values data, struct ata_smart_thresholds thresholds, int onlyfailed);
int ataSmartStatus2(int device);
......
......@@ -28,7 +28,7 @@
#include "smartctl.h"
#include "extern.h"
const char *CVSid4="$Id: ataprint.c,v 1.20 2002/10/22 12:09:14 ballen4705 Exp $\n"
const char *CVSid4="$Id: ataprint.c,v 1.21 2002/10/22 14:57:43 ballen4705 Exp $\n"
"\t" CVSID2 "\t" CVSID3 "\t" CVSID6 ;
// Function for printing ASCII byte-swapped strings, skipping white
......@@ -96,8 +96,9 @@ void ataPrintDriveInfo (struct hd_driveid drive){
if (version>=3)
return;
printf("SMART is only available in ATA Version 3 Revision 3 or greater.\n\n");
exit (0);
printf("SMART is only available in ATA Version 3 Revision 3 or greater.\n");
printf("We will try to proceed in spite of this.\n");
return;
}
......@@ -357,8 +358,7 @@ void PrintSmartExtendedSelfTestPollingTime ( struct ata_smart_values data)
}
// onlyfailing is a bitflag
// onlyfailing=0 : all values
// onlyfailing=0 : print all attribute values
// onlyfailing=1: just ones that are currently failed and have prefailure bit set
// onlyfailing=2: ones that are failed, or have failed with or without prefailure bit set
void PrintSmartAttribWithThres (struct ata_smart_values data,
......@@ -384,10 +384,10 @@ void PrintSmartAttribWithThres (struct ata_smart_values data,
// These break out of the loop if we are only printing certain entries...
if (onlyfailed==1 && (!disk->status.flag.prefailure || !failednow))
break;
continue;
if (onlyfailed==2 && !failedever)
break;
continue;
// print header only if needed
if (needheader){
......@@ -486,7 +486,7 @@ void ataPrintGeneralSmartValues ( struct ata_smart_values data)
}
// Is not (currently) used in ANY code
void ataPrintSmartThresholds (struct ata_smart_thresholds data)
{
int i;
......@@ -807,18 +807,20 @@ void ataPrintSmartAttribName ( unsigned char id ){
Called by smartctl to access ataprint
**/
void ataPrintMain (int fd){
// Initialize to zero just in case some SMART routines don't work
struct hd_driveid drive;
struct ata_smart_values smartval;
struct ata_smart_thresholds smartthres;
struct ata_smart_errorlog smarterror;
struct ata_smart_selftestlog smartselftest;
int timewait;
void ataPrintMain (int fd){
int timewait,code;
// Start by getting Drive ID information. We need this, to know if SMART is supported.
if (ataReadHDIdentity(fd,&drive)){
printf("Smartctl: Hard Drive Read Identity Failed\n\n");
exit(-1);
}
// Print most drive identity information if requested
......@@ -830,8 +832,14 @@ void ataPrintMain (int fd){
// now check if drive supports SMART; otherwise time to exit
if (!ataSmartSupport(drive)){
printf("SMART support is: Unavailable - device lacks SMART capability.\n");
printf(" Checking to be sure by trying SMART ENABLE command.\n");
if (ataEnableSmart(fd)){
printf(" No SMART functionality found. Sorry.\n");
exit(0);
}
else
printf(" SMART appears to work. Continuing.\n");
}
// Now print remaining drive info: is SMART enabled?
if (driveinfo){
......@@ -852,7 +860,6 @@ void ataPrintMain (int fd){
if (smartenable){
if (ataEnableSmart(fd)) {
printf("Smartctl: SMART Enable Failed.\n\n");
exit(-1);
}
else
printf("SMART Enabled.\n");
......@@ -868,59 +875,50 @@ void ataPrintMain (int fd){
if (smartdisable){
if (ataDisableSmart(fd)) {
printf( "Smartctl: SMART Disable Failed.\n\n");
exit(-1);
}
printf("SMART Disabled. Use option -%c to enable it.\n",SMARTENABLE);
exit (0);
}
// Let's ALWAYS issue this command to get the SMART status
code=ataSmartStatus2(fd);
// Enable/Disable Auto-save attributes
if (smartautosaveenable){
if (ataEnableAutoSave(fd)){
if (ataEnableAutoSave(fd))
printf( "Smartctl: SMART Enable Attribute Autosave Failed.\n\n");
exit(-1);
}
printf("SMART Attribute Autosave Enabled\n");
else
printf("SMART Attribute Autosave Enabled.\n");
}
if (smartautosavedisable){
if (ataDisableAutoSave(fd)){
if (ataDisableAutoSave(fd))
printf( "Smartctl: SMART Disable Attribute Autosave Failed.\n\n");
exit(-1);
}
printf("SMART Attribute Autosave Disabled\n");
else
printf("SMART Attribute Autosave Disabled.\n");
}
// for everything else read values and thresholds are needed
if (ataReadSmartValues(fd, &smartval)){
if (ataReadSmartValues(fd, &smartval))
printf("Smartctl: SMART Values Read Failed.\n\n");
exit (-1);
}
if (ataReadSmartThresholds(fd, &smartthres)){
if (ataReadSmartThresholds(fd, &smartthres))
printf("Smartctl: SMART Thresholds Read Failed.\n\n");
exit (-1);
}
// Enable/Disable Off-line testing
if (smartautoofflineenable){
if (!isSupportAutomaticTimer (smartval)){
printf("Device does not support SMART Automatic Timers.\n\n");
exit(-1);
}
if (ataEnableAutoOffline (fd)){
if (ataEnableAutoOffline (fd))
printf( "Smartctl: SMART Enable Automatic Offline Failed.\n\n");
exit(-1);
}
else
printf ("SMART Automatic Offline Testing Enabled every four hours.\n");
}
if (smartautoofflinedisable){
if (!isSupportAutomaticTimer (smartval)){
if (!isSupportAutomaticTimer (smartval))
printf("Device does not support SMART Automatic Timers.\n\n");
exit(-1);
}
if ( ataDisableAutoOffline (fd)){
if (ataDisableAutoOffline (fd))
printf("Smartctl: SMART Disable Automatic Offline Failed.\n\n");
exit(-1);
}
else
printf("SMART Automatic Offline Testing Disabled.\n");
}
......@@ -928,13 +926,28 @@ void ataPrintMain (int fd){
if (checksmart || generalsmartvalues || smartvendorattrib || smarterrorlog || smartselftestlog)
printf("\n=== START OF READ SMART DATA SECTION ===\n");
// Check SMART status
if (checksmart)
// Eventually when working use the ataSmartStatus2 function here.
// This will then not require read values & thresholds above, and
// shouldl be moved in the code to just before the read values &
// thresholds statements.
ataPseudoCheckSmart(smartval, smartthres);
// Check SMART status (use previously returned value)
if (checksmart){
if (code) {
printf("SMART overall-health self-assessment test result: FAILED!\n"
"Drive failure expected in less than 24 hours. SAVE ALL DATA\n");
if (ataCheckSmart(smartval, smartthres,1)){
printf("Here is a list of failing attributes. Use -%c option to investigate.\n",
SMARTVENDORATTRIB);
PrintSmartAttribWithThres(smartval, smartthres,1);
}
else
printf("Unable to confirm any failing attributes.\n");
}
else {
printf("SMART overall-health self-assessment test result: PASSED\n");
if (ataCheckSmart(smartval, smartthres,0)){
printf("Note: SMART attributes shown below are or were below threshold. "
"Use -%c option to investigate\n",SMARTVENDORATTRIB);
PrintSmartAttribWithThres(smartval, smartthres,2);
}
}
}
// Print general SMART values
if (generalsmartvalues)
......
......@@ -28,7 +28,7 @@
#include "smartctl.h"
#include "extern.h"
const char *CVSid4="$Id: ataprint.cpp,v 1.20 2002/10/22 12:09:14 ballen4705 Exp $\n"
const char *CVSid4="$Id: ataprint.cpp,v 1.21 2002/10/22 14:57:43 ballen4705 Exp $\n"
"\t" CVSID2 "\t" CVSID3 "\t" CVSID6 ;
// Function for printing ASCII byte-swapped strings, skipping white
......@@ -96,8 +96,9 @@ void ataPrintDriveInfo (struct hd_driveid drive){
if (version>=3)
return;
printf("SMART is only available in ATA Version 3 Revision 3 or greater.\n\n");
exit (0);
printf("SMART is only available in ATA Version 3 Revision 3 or greater.\n");
printf("We will try to proceed in spite of this.\n");
return;
}
......@@ -357,8 +358,7 @@ void PrintSmartExtendedSelfTestPollingTime ( struct ata_smart_values data)
}
// onlyfailing is a bitflag
// onlyfailing=0 : all values
// onlyfailing=0 : print all attribute values
// onlyfailing=1: just ones that are currently failed and have prefailure bit set
// onlyfailing=2: ones that are failed, or have failed with or without prefailure bit set
void PrintSmartAttribWithThres (struct ata_smart_values data,
......@@ -384,10 +384,10 @@ void PrintSmartAttribWithThres (struct ata_smart_values data,
// These break out of the loop if we are only printing certain entries...
if (onlyfailed==1 && (!disk->status.flag.prefailure || !failednow))
break;
continue;
if (onlyfailed==2 && !failedever)
break;
continue;
// print header only if needed
if (needheader){
......@@ -486,7 +486,7 @@ void ataPrintGeneralSmartValues ( struct ata_smart_values data)
}
// Is not (currently) used in ANY code
void ataPrintSmartThresholds (struct ata_smart_thresholds data)
{
int i;
......@@ -807,18 +807,20 @@ void ataPrintSmartAttribName ( unsigned char id ){
Called by smartctl to access ataprint
**/
void ataPrintMain (int fd){
// Initialize to zero just in case some SMART routines don't work
struct hd_driveid drive;
struct ata_smart_values smartval;
struct ata_smart_thresholds smartthres;
struct ata_smart_errorlog smarterror;
struct ata_smart_selftestlog smartselftest;
int timewait;
void ataPrintMain (int fd){
int timewait,code;
// Start by getting Drive ID information. We need this, to know if SMART is supported.
if (ataReadHDIdentity(fd,&drive)){
printf("Smartctl: Hard Drive Read Identity Failed\n\n");
exit(-1);
}
// Print most drive identity information if requested
......@@ -830,8 +832,14 @@ void ataPrintMain (int fd){
// now check if drive supports SMART; otherwise time to exit
if (!ataSmartSupport(drive)){
printf("SMART support is: Unavailable - device lacks SMART capability.\n");
printf(" Checking to be sure by trying SMART ENABLE command.\n");
if (ataEnableSmart(fd)){
printf(" No SMART functionality found. Sorry.\n");
exit(0);
}
else
printf(" SMART appears to work. Continuing.\n");
}
// Now print remaining drive info: is SMART enabled?
if (driveinfo){
......@@ -852,7 +860,6 @@ void ataPrintMain (int fd){
if (smartenable){
if (ataEnableSmart(fd)) {
printf("Smartctl: SMART Enable Failed.\n\n");
exit(-1);
}
else
printf("SMART Enabled.\n");
......@@ -868,59 +875,50 @@ void ataPrintMain (int fd){
if (smartdisable){
if (ataDisableSmart(fd)) {
printf( "Smartctl: SMART Disable Failed.\n\n");
exit(-1);
}
printf("SMART Disabled. Use option -%c to enable it.\n",SMARTENABLE);
exit (0);
}
// Let's ALWAYS issue this command to get the SMART status
code=ataSmartStatus2(fd);
// Enable/Disable Auto-save attributes
if (smartautosaveenable){
if (ataEnableAutoSave(fd)){
if (ataEnableAutoSave(fd))
printf( "Smartctl: SMART Enable Attribute Autosave Failed.\n\n");
exit(-1);
}
printf("SMART Attribute Autosave Enabled\n");
else
printf("SMART Attribute Autosave Enabled.\n");
}
if (smartautosavedisable){
if (ataDisableAutoSave(fd)){
if (ataDisableAutoSave(fd))
printf( "Smartctl: SMART Disable Attribute Autosave Failed.\n\n");
exit(-1);
}
printf("SMART Attribute Autosave Disabled\n");
else
printf("SMART Attribute Autosave Disabled.\n");
}
// for everything else read values and thresholds are needed
if (ataReadSmartValues(fd, &smartval)){
if (ataReadSmartValues(fd, &smartval))
printf("Smartctl: SMART Values Read Failed.\n\n");
exit (-1);
}
if (ataReadSmartThresholds(fd, &smartthres)){
if (ataReadSmartThresholds(fd, &smartthres))
printf("Smartctl: SMART Thresholds Read Failed.\n\n");
exit (-1);
}
// Enable/Disable Off-line testing
if (smartautoofflineenable){
if (!isSupportAutomaticTimer (smartval)){
printf("Device does not support SMART Automatic Timers.\n\n");
exit(-1);
}
if (ataEnableAutoOffline (fd)){
if (ataEnableAutoOffline (fd))
printf( "Smartctl: SMART Enable Automatic Offline Failed.\n\n");
exit(-1);
}
else
printf ("SMART Automatic Offline Testing Enabled every four hours.\n");
}
if (smartautoofflinedisable){
if (!isSupportAutomaticTimer (smartval)){
if (!isSupportAutomaticTimer (smartval))
printf("Device does not support SMART Automatic Timers.\n\n");
exit(-1);
}
if ( ataDisableAutoOffline (fd)){
if (ataDisableAutoOffline (fd))
printf("Smartctl: SMART Disable Automatic Offline Failed.\n\n");
exit(-1);
}
else
printf("SMART Automatic Offline Testing Disabled.\n");
}
......@@ -928,13 +926,28 @@ void ataPrintMain (int fd){
if (checksmart || generalsmartvalues || smartvendorattrib || smarterrorlog || smartselftestlog)
printf("\n=== START OF READ SMART DATA SECTION ===\n");
// Check SMART status
if (checksmart)
// Eventually when working use the ataSmartStatus2 function here.
// This will then not require read values & thresholds above, and
// shouldl be moved in the code to just before the read values &
// thresholds statements.
ataPseudoCheckSmart(smartval, smartthres);
// Check SMART status (use previously returned value)
if (checksmart){
if (code) {
printf("SMART overall-health self-assessment test result: FAILED!\n"
"Drive failure expected in less than 24 hours. SAVE ALL DATA\n");
if (ataCheckSmart(smartval, smartthres,1)){
printf("Here is a list of failing attributes. Use -%c option to investigate.\n",
SMARTVENDORATTRIB);
PrintSmartAttribWithThres(smartval, smartthres,1);
}
else
printf("Unable to confirm any failing attributes.\n");
}
else {
printf("SMART overall-health self-assessment test result: PASSED\n");
if (ataCheckSmart(smartval, smartthres,0)){
printf("Note: SMART attributes shown below are or were below threshold. "
"Use -%c option to investigate\n",SMARTVENDORATTRIB);
PrintSmartAttribWithThres(smartval, smartthres,2);
}
}
}
// Print general SMART values
if (generalsmartvalues)
......
......@@ -36,7 +36,7 @@
#include "smartd.h"
extern const char *CVSid1, *CVSid2;
const char *CVSid3="$Id: smartd.c,v 1.12 2002/10/22 09:50:54 ballen4705 Exp $\n"
const char *CVSid3="$Id: smartd.c,v 1.13 2002/10/22 14:57:43 ballen4705 Exp $\n"
"\t" CVSID1 "\t" CVSID4 "\t" CVSID7 ;
int daemon_init(void){
......@@ -214,7 +214,7 @@ int ataCheckDevice( atadevices_t *drive){
printout(LOG_INFO, "%s:Failed to read smart thresholds\n",drive->devicename);
// See if any vendor attributes are below minimum, and print them out
if ((failed=ataCheckSmart(tempsmartval,tempsmartthres)))
if ((failed=ataCheckSmart(tempsmartval,tempsmartthres,1)))
printout(LOG_CRIT,"Device: %s, Failed attribute: %i\n",drive->devicename,failed);
// WHEN IT WORKS, we should here add a call to ataSmartStatus2()
......
......@@ -36,7 +36,7 @@
#include "smartd.h"
extern const char *CVSid1, *CVSid2;
const char *CVSid3="$Id: smartd.cpp,v 1.12 2002/10/22 09:50:54 ballen4705 Exp $\n"
const char *CVSid3="$Id: smartd.cpp,v 1.13 2002/10/22 14:57:43 ballen4705 Exp $\n"
"\t" CVSID1 "\t" CVSID4 "\t" CVSID7 ;
int daemon_init(void){
......@@ -214,7 +214,7 @@ int ataCheckDevice( atadevices_t *drive){
printout(LOG_INFO, "%s:Failed to read smart thresholds\n",drive->devicename);
// See if any vendor attributes are below minimum, and print them out
if ((failed=ataCheckSmart(tempsmartval,tempsmartthres)))
if ((failed=ataCheckSmart(tempsmartval,tempsmartthres,1)))
printout(LOG_CRIT,"Device: %s, Failed attribute: %i\n",drive->devicename,failed);
// WHEN IT WORKS, we should here add a call to ataSmartStatus2()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment