Skip to content
Snippets Groups Projects
Commit 535a767c authored by (no author)'s avatar (no author)
Browse files

This commit was manufactured by cvs2svn to create tag 'RELEASE_5_0'.

parent e89aa066
No related branches found
No related tags found
No related merge requests found
# The "checkoutlist" file is used to support additional version controlled
# administrative files in $CVSROOT/CVSROOT, such as template files.
#
# The first entry on a line is a filename which will be checked out from
# the corresponding RCS file in the $CVSROOT/CVSROOT directory.
# The remainder of the line is an error message to use if the file cannot
# be checked out.
#
# File format:
#
# [<whitespace>]<filename><whitespace><error message><end-of-line>
#
# comment lines begin with '#'
# The "commitinfo" file is used to control pre-commit checks.
# The filter on the right is invoked with the repository and a list
# of files to check. A non-zero exit of the filter program will
# cause the commit to be aborted.
#
# The first entry on a line is a regular expression which is tested
# against the directory that the change is being committed to, relative
# to the $CVSROOT. For the first match that is found, then the remainder
# of the line is the name of the filter to run.
#
# If the repository name does not match any of the regular expressions in this
# file, the "DEFAULT" line is used, if it is specified.
#
# If the name "ALL" appears as a regular expression it is always used
# in addition to the first matching regex or "DEFAULT".
# Set this to "no" if pserver shouldn't check system users/passwords
#SystemAuth=no
# Put CVS lock files in this directory rather than directly in the repository.
#LockDir=/var/lock/cvs
# Set `TopLevelAdmin' to `yes' to create a CVS directory at the top
# level of the new working directory when using the `cvs checkout'
# command.
#TopLevelAdmin=no
# Set `LogHistory' to `all' or `TOFEWGCMAR' to log all transactions to the
# history file, or a subset as needed (ie `TMAR' logs all write operations)
#LogHistory=TOFEWGCMAR
# This file affects handling of files based on their names.
#
# The -t/-f options allow one to treat directories of files
# as a single file, or to transform a file in other ways on
# its way in and out of CVS.
#
# The -m option specifies whether CVS attempts to merge files.
#
# The -k option specifies keyword expansion (e.g. -kb for binary).
#
# Format of wrapper file ($CVSROOT/CVSROOT/cvswrappers or .cvswrappers)
#
# wildcard [option value][option value]...
#
# where option is one of
# -f from cvs filter value: path to filter
# -t to cvs filter value: path to filter
# -m update methodology value: MERGE or COPY
# -k expansion mode value: b, o, kkv, &c
#
# and value is a single-quote delimited value.
# For example:
#*.gif -k 'b'
# The "editinfo" file is used to allow verification of logging
# information. It works best when a template (as specified in the
# rcsinfo file) is provided for the logging procedure. Given a
# template with locations for, a bug-id number, a list of people who
# reviewed the code before it can be checked in, and an external
# process to catalog the differences that were code reviewed, the
# following test can be applied to the code:
#
# Making sure that the entered bug-id number is correct.
# Validating that the code that was reviewed is indeed the code being
# checked in (using the bug-id number or a seperate review
# number to identify this particular code set.).
#
# If any of the above test failed, then the commit would be aborted.
#
# Actions such as mailing a copy of the report to each reviewer are
# better handled by an entry in the loginfo file.
#
# One thing that should be noted is the the ALL keyword is not
# supported. There can be only one entry that matches a given
# repository.
# The "loginfo" file controls where "cvs commit" log information
# is sent. The first entry on a line is a regular expression which must match
# the directory that the change is being made to, relative to the
# $CVSROOT. If a match is found, then the remainder of the line is a filter
# program that should expect log information on its standard input.
#
# If the repository name does not match any of the regular expressions in this
# file, the "DEFAULT" line is used, if it is specified.
#
# If the name ALL appears as a regular expression it is always used
# in addition to the first matching regex or DEFAULT.
#
# You may specify a format string as part of the
# filter. The string is composed of a `%' followed
# by a single format character, or followed by a set of format
# characters surrounded by `{' and `}' as separators. The format
# characters are:
#
# s = file name
# V = old version number (pre-checkin)
# v = new version number (post-checkin)
#
# For example:
#DEFAULT (echo ""; id; echo %s; date; cat) >> $CVSROOT/CVSROOT/commitlog
# or
#DEFAULT (echo ""; id; echo %{sVv}; date; cat) >> $CVSROOT/CVSROOT/commitlog
# Three different line formats are valid:
# key -a aliases...
# key [options] directory
# key [options] directory files...
#
# Where "options" are composed of:
# -i prog Run "prog" on "cvs commit" from top-level of module.
# -o prog Run "prog" on "cvs checkout" of module.
# -e prog Run "prog" on "cvs export" of module.
# -t prog Run "prog" on "cvs rtag" of module.
# -u prog Run "prog" on "cvs update" of module.
# -d dir Place module in directory "dir" instead of module name.
# -l Top-level directory only -- do not recurse.
#
# NOTE: If you change any of the "Run" options above, you'll have to
# release and re-checkout any working directories of these modules.
#
# And "directory" is a path to a directory relative to $CVSROOT.
#
# The "-a" option specifies an alias. An alias is interpreted as if
# everything on the right of the "-a" had been typed on the command line.
#
# You can encode a module within a module by using the special '&'
# character to interpose another module into the current module. This
# can be useful for creating a module that consists of many directories
# spread out over the entire source repository.
# The "notify" file controls where notifications from watches set by
# "cvs watch add" or "cvs edit" are sent. The first entry on a line is
# a regular expression which is tested against the directory that the
# change is being made to, relative to the $CVSROOT. If it matches,
# then the remainder of the line is a filter program that should contain
# one occurrence of %s for the user to notify, and information on its
# standard input.
#
# "ALL" or "DEFAULT" can be used in place of the regular expression.
#
# For example:
#ALL mail %s -s "CVS notification"
# The "rcsinfo" file is used to control templates with which the editor
# is invoked on commit and import.
#
# The first entry on a line is a regular expression which is tested
# against the directory that the change is being made to, relative to the
# $CVSROOT. For the first match that is found, then the remainder of the
# line is the name of the file that contains the template.
#
# If the repository name does not match any of the regular expressions in this
# file, the "DEFAULT" line is used, if it is specified.
#
# If the name "ALL" appears as a regular expression it is always used
# in addition to the first matching regex or "DEFAULT".
# The "taginfo" file is used to control pre-tag checks.
# The filter on the right is invoked with the following arguments:
#
# $1 -- tagname
# $2 -- operation "add" for tag, "mov" for tag -F, and "del" for tag -d
# $3 -- repository
# $4-> file revision [file revision ...]
#
# A non-zero exit of the filter program will cause the tag to be aborted.
#
# The first entry on a line is a regular expression which is tested
# against the directory that the change is being committed to, relative
# to the $CVSROOT. For the first match that is found, then the remainder
# of the line is the name of the filter to run.
#
# If the repository name does not match any of the regular expressions in this
# file, the "DEFAULT" line is used, if it is specified.
#
# If the name "ALL" appears as a regular expression it is always used
# in addition to the first matching regex or "DEFAULT".
# The "verifymsg" file is used to allow verification of logging
# information. It works best when a template (as specified in the
# rcsinfo file) is provided for the logging procedure. Given a
# template with locations for, a bug-id number, a list of people who
# reviewed the code before it can be checked in, and an external
# process to catalog the differences that were code reviewed, the
# following test can be applied to the code:
#
# Making sure that the entered bug-id number is correct.
# Validating that the code that was reviewed is indeed the code being
# checked in (using the bug-id number or a seperate review
# number to identify this particular code set.).
#
# If any of the above test failed, then the commit would be aborted.
#
# Actions such as mailing a copy of the report to each reviewer are
# better handled by an entry in the loginfo file.
#
# One thing that should be noted is the the ALL keyword is not
# supported. There can be only one entry that matches a given
# repository.
// $Id: atacmds.cpp,v 1.1 2002/10/09 17:56:58 ballen4705 Exp $
/*
* atacmds.c
*
* Copyright (C) 2002 Bruce Allen <ballen@uwm.edu>
* Copyright (C) 1999-2000 Michael Cornwell <cornwell@acm.org>
* Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* You should have received a copy of the GNU General Public License
* (for example COPYING); if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdio.h>
#include <string.h>
#include "atacmds.h"
int ataReadHDIdentity ( int device, struct hd_driveid *buf)
{
if (ioctl ( device , HDIO_GET_IDENTITY, buf ) != 0)
{
perror ("ATA GET HD Failed");
return -1;
}
return 0;
}
int ataVersionInfo ( struct hd_driveid drive)
{
int i;
int atavalue = 0;
#ifdef DEBUG
#ifdef __NEW_HD_DRIVE_ID
printf ("Debug: Ata Version: %04x\n", drive.major_rev_num);
#else
printf ("Debug: Ata Version: %04x\n", drive.word80);
#endif
#endif
#ifdef __NEW_HD_DRIVE_ID
if ( (drive.major_rev_num == 0xffff) || (drive.major_rev_num == 0x000) )
#else
if ( (drive.word80 == 0xffff) || (drive.word80 == 0x000) )
#endif
{
return -1;
}
for ( i = 1; i < 16; i++ )
{
#ifdef __NEW_HD_DRIVE_ID
if ( drive.major_rev_num & ( 0x1 << i) )
#else
#endif
{
atavalue = i;
}
}
return atavalue;
}
int ataSmartSupport ( struct hd_driveid drive)
{
#ifdef __NEW_HD_DRIVE_ID
if ( drive.command_set_1 & 0x0001 ){
#else
if ( drive.command_sets & 0x0001 ){
#endif
return (1); /* drive supports S.M.A.R.T. and is disabled */
}
return (0);
}
int ataReadSmartValues (int device, struct ata_smart_values *data)
{
int i;
unsigned char chksum;
unsigned char buf[ HDIO_DRIVE_CMD_HDR_SIZE +
ATA_SMART_SEC_SIZE] =
{ WIN_SMART, 0, SMART_READ_VALUES, 1};
if (ioctl ( device , HDIO_DRIVE_CMD, (unsigned char *) &buf ) != 0)
{
perror ("Smart Values Read failed");
return -1;
}
chksum = 0;
for ( i = HDIO_DRIVE_CMD_HDR_SIZE;
i < ATA_SMART_SEC_SIZE + HDIO_DRIVE_CMD_HDR_SIZE;
i++ )
chksum += buf[i];
if ( (unsigned char) chksum != 0)
{
perror ("Smart Read Failed, Chksum error");
return -1;
}
memcpy( data,
&buf[HDIO_DRIVE_CMD_HDR_SIZE] ,
ATA_SMART_SEC_SIZE );
return 0;
}
int ataReadSelfTestLog (int device, struct ata_smart_selftestlog *data)
{
int i;
unsigned char chksum=0;
unsigned char buf[ HDIO_DRIVE_CMD_HDR_SIZE +
ATA_SMART_SEC_SIZE] =
{ WIN_SMART, 0x06, SMART_READ_LOG_SECTOR, 1};
if (ioctl ( device , HDIO_DRIVE_CMD, (unsigned char *) &buf ) != 0)
{
perror ("Smart Error Log Read failed");
return -1;
}
// compute checksum
for (i=0;i<ATA_SMART_SEC_SIZE;i++)
chksum+=buf[HDIO_DRIVE_CMD_HDR_SIZE+i];
if (chksum){
fprintf(stderr,"Smart Self Test Log Checksum Incorrect!\n");
return -1;
}
memcpy( data, &buf[HDIO_DRIVE_CMD_HDR_SIZE] , ATA_SMART_SEC_SIZE);
return 0;
}
int ataReadErrorLog (int device, struct ata_smart_errorlog *data)
{
int i;
unsigned char chksum=0;
unsigned char buf[ HDIO_DRIVE_CMD_HDR_SIZE +
ATA_SMART_SEC_SIZE] =
{ WIN_SMART, 0x01, SMART_READ_LOG_SECTOR, 1};
if (ioctl ( device , HDIO_DRIVE_CMD, (unsigned char *) &buf ) != 0)
{
perror ("Smart Error Log Read failed");
return -1;
}
// compute checksum
for (i=0;i<ATA_SMART_SEC_SIZE;i++)
chksum+=buf[HDIO_DRIVE_CMD_HDR_SIZE+i];
if (chksum){
fprintf(stderr,"Smart Error Log Checksum Incorrect!\n");
return -1;
}
memcpy( data, &buf[HDIO_DRIVE_CMD_HDR_SIZE] , ATA_SMART_SEC_SIZE);
return 0;
}
int ataReadSmartThresholds ( int device, struct ata_smart_thresholds *data)
{
unsigned char buf[ HDIO_DRIVE_CMD_HDR_SIZE +
ATA_SMART_SEC_SIZE] =
{ WIN_SMART, 1, SMART_READ_THRESHOLDS, 1};
if (ioctl ( device , HDIO_DRIVE_CMD, (unsigned char *) &buf ) != 0)
{
perror ("Smart Thresholds Read failed");
return -1;
}
memcpy( data, &buf[HDIO_DRIVE_CMD_HDR_SIZE] , ATA_SMART_SEC_SIZE);
return 0;
}
int ataSetSmartThresholds ( int device, struct ata_smart_thresholds *data)
{
unsigned char buf[ HDIO_DRIVE_CMD_HDR_SIZE +
ATA_SMART_SEC_SIZE] =
{ WIN_SMART, 1, 0xD7, 1};
memcpy( &buf[HDIO_DRIVE_CMD_HDR_SIZE], data , ATA_SMART_SEC_SIZE);
if (ioctl ( device , HDIO_DRIVE_CMD, (unsigned char *) &buf ) != 0)
{
perror ("Smart Thresholds Read failed");
return -1;
}
return 0;
}
int ataEnableSmart (int device )
{
unsigned char parms[4] = { WIN_SMART, 1, SMART_ENABLE, 0};
if (ioctl ( device , HDIO_DRIVE_CMD, &parms ) != 0)
{
perror ("Smart Enable failed");
return -1;
}
return 0;
}
int ataDisableSmart (int device )
{
unsigned char parms[4] = { WIN_SMART, 1, SMART_DISABLE, 0};
if (ioctl ( device , HDIO_DRIVE_CMD, &parms ) != 0)
{
perror ("Smart Disable failed");
return -1;
}
return 0;
}
int ataEnableAutoSave(int device){
unsigned char parms[4] = { WIN_SMART, 241, SMART_AUTOSAVE, 0};
if (ioctl ( device , HDIO_DRIVE_CMD, &parms ) != 0)
{
perror ("Smart Enable Auto-save failed");
return -1;
}
return 0;
};
int ataDisableAutoSave(int device){
unsigned char parms[4] = { WIN_SMART, 0, SMART_AUTOSAVE, 0};
if (ioctl ( device , HDIO_DRIVE_CMD, &parms ) != 0)
{
perror ("Smart Disable Auto-save failed");
return -1;
}
return 0;
};
int ataEnableAutoOffline (int device )
{
/* timer hard coded to 4 hours */
unsigned char parms[4] = { WIN_SMART, 248, SMART_AUTO_OFFLINE, 0};
if (ioctl ( device , HDIO_DRIVE_CMD, &parms ) != 0)
{
perror ("Smart Enable Automatic Offline failed");
return -1;
}
return 0;
}
int ataDisableAutoOffline (int device )
{
unsigned char parms[4] = { WIN_SMART, 0, SMART_AUTO_OFFLINE, 0};
if (ioctl ( device , HDIO_DRIVE_CMD, &parms ) != 0)
{
perror ("Smart Disable Automatic Offline failed");
return -1;
}
return 0;
}
int ataSmartStatus (int device )
{
unsigned char parms[4] = { WIN_SMART, 0, SMART_STATUS, 0};
if (ioctl ( device , HDIO_DRIVE_CMD, &parms) != 0)
{
return -1;
}
return 0;
}
int ataSmartTest (int device, int testtype)
{
unsigned char parms[4] = { WIN_SMART, testtype,
SMART_IMMEDIATE_OFFLINE, 0};
if (ioctl ( device , HDIO_DRIVE_CMD, &parms) != 0)
{
perror ("Smart Offline failed");
return -1;
}
printf("Completed Off-line command\n");
return 0;
}
int ataSmartOfflineTest (int device)
{
return ataSmartTest( device, OFFLINE_FULL_SCAN );
}
int ataSmartShortSelfTest (int device)
{
return ataSmartTest( device, SHORT_SELF_TEST );
}
int ataSmartExtendSelfTest (int device)
{
return ataSmartTest( device, EXTEND_SELF_TEST );
}
int ataSmartShortCapSelfTest (int device)
{
return ataSmartTest( device, SHORT_CAPTIVE_SELF_TEST );
}
int ataSmartExtendCapSelfTest (int device)
{
return ataSmartTest( device, EXTEND_CAPTIVE_SELF_TEST );
}
int ataSmartSelfTestAbort (int device)
{
return ataSmartTest( device, 127 );
}
/* Test Time Functions */
int isOfflineTestTime ( struct ata_smart_values data)
{
return (int) data.total_time_to_complete_off_line;
}
int isShortSelfTestTime ( struct ata_smart_values data)
{
return (int) data.short_test_completion_time;
}
int isExtendedSelfTestTime ( struct ata_smart_values data)
{
return (int) data.extend_test_completion_time;
}
int isSmartErrorLogCapable ( struct ata_smart_values data)
{
return data.errorlog_capability & 0x01;
}
int isSupportExecuteOfflineImmediate ( struct ata_smart_values data)
{
return data.offline_data_collection_capability & 0x01;
}
int isSupportAutomaticTimer ( struct ata_smart_values data)
{
return data.offline_data_collection_capability & 0x02;
}
int isSupportOfflineAbort ( struct ata_smart_values data)
{
return data.offline_data_collection_capability & 0x04;
}
int isSupportOfflineSurfaceScan ( struct ata_smart_values data)
{
return data.offline_data_collection_capability & 0x08;
}
int isSupportSelfTest (struct ata_smart_values data)
{
return data.offline_data_collection_capability & 0x10;
}
int ataCheckSmart ( struct ata_smart_values data, struct ata_smart_thresholds thresholds)
{
int i;
for ( i = 0 ; i < 30 ; i++ )
{
if ( (data.vendor_attributes[i].id !=0) &&
(thresholds.thres_entries[i].id != 0) &&
(data.vendor_attributes[i].status.flag.prefailure) &&
(data.vendor_attributes[i].current <
thresholds.thres_entries[i].threshold) &&
(thresholds.thres_entries[i].threshold != 0xFE) )
{
return i;
}
}
return 0;
}
This diff is collapsed.
This diff is collapsed.
// $Id: scsiprint.cpp,v 1.1 2002/10/09 17:56:58 ballen4705 Exp $
/*
* scsiprint.c
*
* Copyright (C) 2002 Bruce Allen <ballen@uwm.edu>
* Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* You should have received a copy of the GNU General Public License
* (for example COPYING); if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include "smartctl.h"
#include "extern.h"
#include "scsicmds.h"
#include "scsiprint.h"
#define GBUF_SIZE 65535
UINT8 gBuf[GBUF_SIZE];
UINT8 gSmartPage = 0;
UINT8 gTempPage = 0;
UINT8 gSelfTestPage = 0;
UINT8 gStartStopPage = 0;
UINT8 gTapeAlertsPage = 0;
void scsiGetSupportPages ( int device)
{
int i;
if (logsense ( device , SUPPORT_LOG_PAGES, (UINT8 *) &gBuf) != 0)
{
perror ( "Log Sense failed");
exit (1);
}
for ( i = 4; i < gBuf[3] + LOGPAGEHDRSIZE ; i++)
{
switch ( gBuf[i])
{
case TEMPERATURE_PAGE:
gTempPage = 1;
break;
case STARTSTOP_CYCLE_COUNTER_PAGE:
gStartStopPage = 1;
break;
case SELFTEST_RESULTS_PAGE:
gSelfTestPage = 1;
break;
case SMART_PAGE:
gSmartPage = 1;
break;
case TAPE_ALERTS_PAGE:
gTapeAlertsPage = 1;
break;
default:
break;
}
}
}
void scsiGetSmartData (int device)
{
UINT8 returnvalue;
UINT8 currenttemp;
UINT8 triptemp;
if ( scsiCheckSmart(device, gSmartPage,
&returnvalue, &currenttemp, &triptemp ) != 0)
{
perror ( "scsiGetSmartData Failed");
exit (1);
}
if ( returnvalue )
printf("S.M.A.R.T. Sense: (%02x) %s\n", (UINT8) returnvalue,
scsiSmartGetSenseCode(returnvalue));
else
printf("S.M.A.R.T. Sense: Okay!\n");
if ( (currenttemp || triptemp) && !gTempPage)
{
printf("Current Drive Temperature: %d C\n", currenttemp);
printf("Drive Trip Temperature: %d C\n", triptemp);
}
}
void scsiGetTapeAlertsData (int device)
{
unsigned short pagelength;
unsigned short parametercode;
int i;
int failure = 0;
if ( logsense( device, TAPE_ALERTS_PAGE, (UINT8 *) &gBuf) != 0)
{
perror ( "scsiGetSmartData Failed");
exit (1);
}
if ( gBuf[0] != 0x2e )
{
printf("TapeAlerts Log Sense Failed\n");
exit(-1);
}
pagelength = (unsigned short) gBuf[2] << 8 | gBuf[3];
for ( i = 4; i < pagelength;i+=5 )
{
parametercode = (unsigned short) gBuf[i] << 8 | gBuf[i+1];
if (gBuf[i+4])
{
printf("Tape Alerts Error!!!\n%s\n",
scsiTapeAlertsTapeDevice(parametercode));
failure = 1;
}
}
if(!failure)
printf("No Tape Alerts Failure\n");
}
void scsiGetStartStopData ( int device)
{
UINT32 currentStartStop;
UINT32 recommendedStartStop;
if ( logsense( device, STARTSTOP_CYCLE_COUNTER_PAGE, (UINT8 *) &gBuf) != 0)
{
perror ( "scsiGetStartStopData Failed");
exit (1);
}
if ( gBuf[0] != STARTSTOP_CYCLE_COUNTER_PAGE )
{
printf("StartStop Log Sense Failed\n");
exit(-1);
}
recommendedStartStop= (UINT32) gBuf[28]<< 24 | gBuf[29] << 8 |
gBuf[30] << 16 | gBuf[31];
currentStartStop= (UINT32) gBuf[36]<< 24 | gBuf[37] << 8 |
gBuf[38] << 16 | gBuf[39];
printf("Current start stop count: %u times\n", currentStartStop);
printf("Recommended start stop count: %u times\n", recommendedStartStop);
}
void scsiGetDriveInfo ( int device)
{
char manufacturer[9];
char product[17];
char revision[5];
UINT8 smartsupport;
if (stdinquiry ( device, (UINT8 *) &gBuf) != 0)
{
perror ( "Standard Inquiry failed");
}
memset ( &manufacturer, 0, 8);
manufacturer[8] = '\0';
strncpy ((char *) &manufacturer, (char *) &gBuf[8], 8);
memset ( &product, 0, 16);
strncpy ((char *) &product, (char *) &gBuf[16], 16);
product[16] = '\0';
memset ( &revision, 0, 4);
strncpy ((char *) &revision, (char *) &gBuf[32], 4);
revision[4] = '\0';
printf("Device: %s %s Version: %s\n", manufacturer, product, revision);
if ( scsiSmartSupport( device, (UINT8 *) &smartsupport) != 0)
{
printf("Device does not support %s\n",(gBuf[0] & 0x1f)?
"TapeAlerts": "S.M.A.R.T.");
exit (1);
}
printf("Device supports %s and is %s\n%s\n",
(gBuf[0] & 0x1f)? "TapeAlerts" : "S.M.A.R.T.",
(smartsupport & DEXCPT_ENABLE)? "Disable" : "Enabled",
(smartsupport & EWASC_ENABLE)? "Temperature Warning Enabled":
"Temperature Warning Disabled or Not Supported");
}
void scsiSmartEnable( int device)
{
/* Enable Exception Control */
if ( scsiSmartDEXCPTDisable(device) != 0)
{
exit (1);
}
printf("S.M.A.R.T. enabled\n");
if (scsiSmartEWASCEnable(device) != 0)
{
printf("Temperature Warning not Supported\n");
}
else
{
printf("Temperature Warning Enabled\n");
}
return;
}
void scsiSmartDisable (int device)
{
if ( scsiSmartDEXCPTEnable(device) != 0)
{
exit (1);
}
printf("S.M.A.R.T. Disabled\n");
}
void scsiPrintTemp (int device)
{
UINT8 temp;
UINT8 trip;
if ( scsiGetTemp(device, &temp, &trip) != 0)
{
exit (1);
}
printf("Current Drive Temperature: %d C\n", temp);
printf("Drive Trip Temperature: %d C\n", trip);
}
void scsiPrintStopStart ( int device )
{
/**
unsigned int css;
if ( scsiGetStartStop(device, unsigned int *css) != 0)
{
exit (1);
}
printf ("Start Stop Count: %d\n", css);
**/
}
void scsiPrintMain (int fd)
{
if (driveinfo)
scsiGetDriveInfo(fd);
if (smartenable)
scsiSmartEnable(fd);
if (smartdisable)
scsiSmartDisable(fd);
if (checksmart)
{
scsiGetSupportPages (fd);
if(gTapeAlertsPage)
scsiGetTapeAlertsData (fd);
else
{
scsiGetSmartData(fd);
if(gTempPage)
scsiPrintTemp(fd);
if(gStartStopPage)
scsiGetStartStopData (fd);
}
}
if ( smartexeoffimmediate )
{
if ( scsiSmartOfflineTest (fd) != 0)
{
printf( "Smartctl: Smart Offline Failed\n");
exit(-1);
}
printf ("Drive Command Successful offline test has begun\n");
printf ("Use smartctl -%c to abort test\n", SMARTSELFTESTABORT);
}
if ( smartshortcapselftest )
{
if ( scsiSmartShortCapSelfTest (fd) != 0)
{
printf( "Smartctl: Smart Short Self Test Failed\n");
exit(-1);
}
printf ("Drive Command Successful Short Self test has begun\n");
printf ("Use smartctl -%c to abort test\n", SMARTSELFTESTABORT);
}
if ( smartshortselftest )
{
if ( scsiSmartShortSelfTest (fd) != 0)
{
printf( "Smartctl: Smart Short Self Test Failed\n");
exit(-1);
}
printf ("Drive Command Successful Short Self test has begun\n");
printf ("Use smartctl -%c to abort test\n", SMARTSELFTESTABORT);
}
if ( smartextendselftest )
{
if ( scsiSmartExtendSelfTest (fd) != 0)
{
printf( "S.M.A.R.T. Extendend Self Test Failed\n");
exit(-1);
}
printf ("Drive Command Successful Extended Self test has begun\n");
printf ("Use smartctl -%c to abort test\n", SMARTSELFTESTABORT);
}
if ( smartextendcapselftest )
{
if ( scsiSmartExtendCapSelfTest (fd) != 0)
{
printf( "S.M.A.R.T. Extendend Self Test Failed\n");
exit(-1);
}
printf ("Drive Command Successful Extended Self test has begun\n");
printf ("Use smartctl -%c to abort test\n", SMARTSELFTESTABORT);
}
if ( smartselftestabort )
{
if ( scsiSmartSelfTestAbort (fd) != 0)
{
printf( "S.M.A.R.T. Self Test Abort Failed\n");
exit(-1);
}
printf ("Drive Command Successful self test aborted\n");
}
}
// $Id: smartctl.cpp,v 1.1 2002/10/09 17:56:58 ballen4705 Exp $
/*
* smartctl.c
*
* Copyright (C) 2002 Bruce Allen <ballen@uwm.edu>
* Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* You should have received a copy of the GNU General Public License
* (for example COPYING); if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdio.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/hdreg.h>
#include <sys/fcntl.h>
#include <sys/types.h>
#include <string.h>
#include "smartctl.h"
#include "atacmds.h"
#include "ataprint.h"
#include "scsicmds.h"
#include "scsiprint.h"
unsigned char driveinfo = FALSE;
unsigned char checksmart = FALSE;
unsigned char smartvendorattrib = FALSE;
unsigned char generalsmartvalues = FALSE;
unsigned char smartselftestlog = FALSE;
unsigned char smarterrorlog = FALSE;
unsigned char smartdisable = FALSE;
unsigned char smartenable = FALSE;
unsigned char smartstatus = FALSE;
unsigned char smartexeoffimmediate = FALSE;
unsigned char smartshortselftest = FALSE;
unsigned char smartextendselftest = FALSE;
unsigned char smartshortcapselftest = FALSE;
unsigned char smartextendcapselftest = FALSE;
unsigned char smartselftestabort = FALSE;
unsigned char smartautoofflineenable = FALSE;
unsigned char smartautoofflinedisable = FALSE;
unsigned char smartautosaveenable = FALSE;
unsigned char smartautosavedisable = FALSE;
unsigned char printcopyleft = FALSE;
/* void Usage (void)
prints help information for command syntax */
void Usage ( void){
printf( "smartctl version %i.%i - S.M.A.R.T. Control Program\n",
VERSION_MAJOR, VERSION_MINOR);
printf("Home page of project is http://sourceforge.net/projects/smartmontools\n\n");
printf( "usage: smartctl -[options] [device]\n");
printf( "Read Only Options:\n");
printf( "\t\t%c\t\tPrint Copyright and License information\n",
PRINTCOPYLEFT);
printf( "\t\t%c\t\tShow All S.M.A.R.T. Information (ATA and SCSI)\n",
SMARTVERBOSEALL);
printf( "\t\t%c\t\tShow General S.M.A.R.T. Attributes (ATA Only)\n",
GENERALSMARTVALUES);
printf( "\t\t%c\t\tShow Vendor S.M.A.R.T. Attributes (ATA Only)\n",
SMARTVENDORATTRIB);
printf( "\t\t%c\t\tShow S.M.A.R.T. Drive Error Log (ATA Only\n",
SMARTERRORLOG);
printf( "\t\t%c\t\tShow S.M.A.R.T. Drive Self Test Log (ATA Only)\n",
SMARTSELFTESTLOG);
printf( "\t\t%c\t\tShow S.M.A.R.T. Drive Info (ATA and SCSI)\n", DRIVEINFO);
printf( "\t\t%c\t\tCheck S.M.A.R.T. Status (ATA and SCSI)\n", CHECKSMART);
printf( "\n");
printf( "Enable/Disable Options:\n");
printf( "\t\t%c\t\tEnable S.M.A.R.T. data collection (ATA and SCSI)\n",
SMARTENABLE);
printf( "\t\t%c\t\tDisable S.M.A.R.T.data collection (ATA and SCSI)\n",
SMARTDISABLE);
printf( "\t\t%c\t\tEnable S.M.A.R.T. Automatic Offline Test (ATA Only)\n",
SMARTAUTOOFFLINEENABLE);
printf( "\t\t%c\t\tDisable S.M.A.R.T. Automatic Offline Test (ATA Only)\n",
SMARTAUTOOFFLINEDISABLE);
printf( "\t\t%c\t\tEnable S.M.A.R.T. Attribute Autosave (ATA Only)\n",
SMARTAUTOSAVEENABLE);
printf( "\t\t%c\t\tDisable S.M.A.R.T. Attribute Autosave (ATA Only)\n",
SMARTAUTOSAVEDISABLE);
printf( "\n");
printf( "Test Options:\n");
printf( "\t\t%c\t\tExecute Off-line data collection (ATA Only)\n",
SMARTEXEOFFIMMEDIATE);
printf( "\t\t%c\t\tExecute Short Self Test (ATA Only)\n",
SMARTSHORTSELFTEST );
printf( "\t\t%c\t\tExecute Short Self Test (Captive Mode) (ATA Only)\n",
SMARTSHORTCAPSELFTEST );
printf( "\t\t%c\t\tExecute Extended Self Test (ATA Only)\n",
SMARTEXTENDSELFTEST );
printf( "\t\t%c\t\tExecute Extended Self Test (Captive Mode) (ATA Only)\n",
SMARTEXTENDCAPSELFTEST );
printf( "\t\t%c\t\tExecute Self Test Abort (ATA Only)\n\n",
SMARTSELFTESTABORT );
printf( "Examples:\n");
printf("\tsmartctl -etf /dev/hda (Enables S.M.A.R.T. on first disk)\n");
printf("\tsmartctl -a /dev/hda (Prints all S.M.A.R.T. information)\n");
printf("\tsmartctl -X /dev/hda (Executes extended disk self-test)\n");
printf("Please see the man pages or the web site for further information.\n");
}
/* void ParseOpts ( chars *opts)
Takes command options and sets features to be run */
void ParseOpts (int argc, char** argv){
int optchar;
extern char *optarg;
extern int optopt, optind;
const char opts[] = {
DRIVEINFO, CHECKSMART, SMARTVERBOSEALL, SMARTVENDORATTRIB,
GENERALSMARTVALUES, SMARTERRORLOG, SMARTSELFTESTLOG, SMARTDISABLE,
SMARTENABLE, SMARTAUTOOFFLINEENABLE, SMARTAUTOOFFLINEDISABLE,
SMARTEXEOFFIMMEDIATE, SMARTSHORTSELFTEST, SMARTEXTENDSELFTEST,
SMARTSHORTCAPSELFTEST, SMARTEXTENDCAPSELFTEST, SMARTSELFTESTABORT,
SMARTAUTOSAVEENABLE,SMARTAUTOSAVEDISABLE,PRINTCOPYLEFT,'\0'
};
while(EOF != (optchar = getopt(argc, argv, opts))) {
switch (optchar){
case PRINTCOPYLEFT :
printcopyleft=TRUE;
break;
case DRIVEINFO :
driveinfo = TRUE;
break;
case CHECKSMART :
driveinfo = TRUE;
checksmart = TRUE;
break;
case SMARTVERBOSEALL :
driveinfo = TRUE;
checksmart = TRUE;
generalsmartvalues = TRUE;
smartvendorattrib = TRUE;
smarterrorlog = TRUE;
smartselftestlog = TRUE;
break;
case SMARTVENDORATTRIB :
smartvendorattrib = TRUE;
break;
case GENERALSMARTVALUES :
generalsmartvalues = TRUE;
break;
case SMARTERRORLOG :
smarterrorlog = TRUE;
break;
case SMARTSELFTESTLOG :
smartselftestlog = TRUE;
break;
case SMARTDISABLE :
smartdisable = TRUE;
break;
case SMARTENABLE :
smartenable = TRUE;
break;
case SMARTAUTOSAVEENABLE:
smartautosaveenable = TRUE;
break;
case SMARTAUTOSAVEDISABLE:
smartautosavedisable = TRUE;
break;
case SMARTAUTOOFFLINEENABLE:
smartautoofflineenable = TRUE;
break;
case SMARTAUTOOFFLINEDISABLE:
smartautoofflinedisable = TRUE;
break;
case SMARTEXEOFFIMMEDIATE:
smartexeoffimmediate = TRUE;
break;
case SMARTSHORTSELFTEST :
smartshortselftest = TRUE;
break;
case SMARTEXTENDSELFTEST :
smartextendselftest = TRUE;
break;
case SMARTSHORTCAPSELFTEST:
smartshortcapselftest = TRUE;
break;
case SMARTEXTENDCAPSELFTEST:
smartextendcapselftest = TRUE;
break;
case SMARTSELFTESTABORT:
smartselftestabort = TRUE;
break;
default:
Usage();
exit (-1);
}
if ( (smartexeoffimmediate + smartshortselftest +
smartextendselftest + smartshortcapselftest +
smartextendcapselftest ) > 1){
Usage();
printf ("\n ERROR: smartctl can only run a single test at a time \n");
exit(-1);
}
}
}
/* Main Program */
int main (int argc, char **argv){
int fd;
char *device;
// Part input arguments
ParseOpts (argc,argv);
// Print Copyright/License info if needed
if (printcopyleft){
printf("smartctl version %d.%d Copyright (C) 2002 Bruce Allen\n",VERSION_MAJOR,VERSION_MINOR);
printf("CVS version ID %s\n","$Id: smartctl.cpp,v 1.1 2002/10/09 17:56:58 ballen4705 Exp $");
printf("Home page of project is http://sourceforge.net/projects/smartmontools\n\n");
printf("smartctl comes with ABSOLUTELY NO WARRANTY. This\n");
printf("is free software, and you are welcome to redistribute it\n");
printf("under the terms of the GNU General Public License Version 2.\n");
printf("See http://www.gnu.org for further details.\n");
exit(0);
}
// Further argument checking
if ( argc != 3 ){
Usage();
exit (-1);
}
/* open device */
fd = open ( device=argv[2], O_RDWR );
if ( fd < 0) {
perror ( "Device open failed");
exit(-1);
}
if ( device[5] == 'h')
ataPrintMain (fd );
else if (device[5] == 's')
scsiPrintMain (fd);
else
Usage();
return 0;
}
// $Id: smartd.cpp,v 1.2 2002/10/09 18:01:18 ballen4705 Exp $
/*
* smartd.c
*
* Copyright (C) 2002 Bruce Allen <ballen@uwm.edu>
* Copyright (C) 2000 Michael Cornwell <cornwell@acm.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* You should have received a copy of the GNU General Public License
* (for example COPYING); if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <linux/hdreg.h>
#include <syslog.h>
#include <stdarg.h>
#include "atacmds.h"
#include "scsicmds.h"
#include "smartd.h"
int daemon_init(void){
pid_t pid;
if ( (pid = fork()) < 0)
// unable to fork!
return -1;
else if (pid != 0)
// we are the parent process -- exit
exit (0);
// from here on, we are the child process
setsid ();
chdir("/");
umask(0);
return(0);
}
// This function prints either to stdout or to the syslog as needed
void printout(int priority,char *fmt, ...){
va_list ap;
// initialize variable argument list
va_start(ap,fmt);
if (debugmode)
vprintf(fmt,ap);
else
vsyslog(priority,fmt,ap);
va_end(ap);
return;
}
/* prints help information for command syntax */
void Usage ( void){
printout(LOG_INFO,"smartd version %i.%i - S.M.A.R.T. Daemon\n",
VERSION_MAJOR, VERSION_MINOR);
printout(LOG_INFO,"usage: smartd -[opts] \n");
printout(LOG_INFO,"Read Only Commands:\n");
printout(LOG_INFO,"\t\t%c\t\tStart smartd in debug Mode\n",DEBUGMODE);
printout(LOG_INFO,"\t\t%c\t\tPrint License and Copyright information\n",PRINTCOPYLEFT);
}
// scan to see what ata devices there are, and if they support SMART
void atadevicescan ( atadevices_t *devices){
int i;
int fd;
struct hd_driveid drive;
char device[] = "/dev/hda";
for(i=0;i<MAXATADEVICES;i++,device[7]++ ){
printout(LOG_INFO,"Reading Device %s\n", device);
fd = open ( device , O_RDWR );
if ( fd < 0)
// no such device
continue;
if (ataReadHDIdentity (fd,&drive) || !ataSmartSupport(drive) || ataEnableSmart(fd)){
// device exists, but not able to do SMART
close(fd);
printout(LOG_INFO,"Device: %s, Found but not SMART capable, or couldn't enable SMART\n",device);
continue;
}
// device exists, and does SMART. Add to list
devices[numatadevices].fd = fd;
strcpy(devices[numatadevices].devicename, device);
devices[numatadevices].drive = drive;
if (ataReadSmartValues (fd,&devices[numatadevices].smartval)){
printout(LOG_INFO,"Device: %s, Read Smart Values Failed\n",device);
}
if (ataReadSmartThresholds (fd,&devices[numatadevices].smartthres)){
printout(LOG_INFO,"Device: %s, Read Smart Thresholds Failed\n",device);
}
printout(LOG_INFO,"%s Found and is SMART capable\n",device);
devices[numatadevices].selftest =
isSupportSelfTest(devices[numatadevices].smartval);
numatadevices++;
}
}
// This function is hard to read and ought to be rewritten
// A couple of obvious questions -- why isn't fd always closed if not used?
// Why in the world is thea four-byte integer cast to a pointer to an eight-byte object??
void scsidevicescan ( scsidevices_t *devices){
int i, fd, smartsupport;
unsigned char tBuf[4096];
char device[] = "/dev/sda";
for(i = 0; i < MAXSCSIDEVICES ; i++,device[7]++ ){
printout(LOG_INFO,"Reading Device %s\n", device);
fd = open ( device , O_RDWR );
if ( fd >= 0 && !testunitready (fd)) {
if (modesense ( fd, 0x1c, (UINT8 *) &tBuf) != 0){
printout(LOG_INFO,"Device: %s, Failed read of ModePage 1C \n", device);
close(fd);
}
else
if ( scsiSmartSupport( fd, (UINT8 *) &smartsupport) == 0){
if (!(smartsupport & DEXCPT_ENABLE)){
devices[numscsidevices].fd = fd;
strcpy(devices[numscsidevices].devicename,device);
printout(LOG_INFO, "Device: %s, Found and is SMART capable\n",device);
if (logsense ( fd , SUPPORT_LOG_PAGES, (UINT8 *) &tBuf) == 0){
for ( i = 4; i < tBuf[3] + LOGPAGEHDRSIZE ; i++){
switch ( tBuf[i]){
case TEMPERATURE_PAGE:
devices[numscsidevices].TempPageSupported = 1;
break;
case SMART_PAGE:
devices[numscsidevices].SmartPageSupported = 1;
break;
default:
break;
}
}
}
numscsidevices++;
}
}
}
}
}
void ataCompareSmartValues (atadevices_t *device, struct ata_smart_values new ){
int i;
int oldval,newval,idold,idnew;
for ( i =0; i < NUMBER_ATA_SMART_ATTRIBUTES; i++){
// which device is it?
idnew=new.vendor_attributes[i].id;
idold=device->smartval.vendor_attributes[i].id;
if (idold && idnew){
// if it's a valid attribute, compare values
newval=new.vendor_attributes[i].current;
oldval=device->smartval.vendor_attributes[i].current;
if (oldval!=newval)
// values have changed; print them
printout(LOG_INFO, "Device: %s, S.M.A.R.T. Attribute: %i Changed from %i to %i\n",
device->devicename,idnew,oldval,newval);
}
}
}
int ataCheckDevice( atadevices_t *drive){
struct ata_smart_values tempsmartval;
struct ata_smart_thresholds tempsmartthres;
int failed;
// Coming into this function, *drive contains the last values measured,
// and we read the NEW values into tempsmartval
if (ataReadSmartValues(drive->fd,&tempsmartval))
printout(LOG_INFO, "%s:Failed to read smart values\n", drive->devicename);
// and we read the new thresholds into tempsmartthres
if (ataReadSmartThresholds (drive->fd, &tempsmartthres))
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)))
printout(LOG_CRIT,"Device: %s, Failed attribute: %i\n",drive->devicename,failed);
// see if any values have changed. Second argument is new values
ataCompareSmartValues (drive , tempsmartval);
// Save the new values into *drive for the next time around
drive->smartval = tempsmartval;
drive->smartthres = tempsmartthres;
return 0;
}
int scsiCheckDevice( scsidevices_t *drive)
{
UINT8 returnvalue;
UINT8 currenttemp;
UINT8 triptemp;
currenttemp = triptemp = 0;
if (scsiCheckSmart( drive->fd, drive->SmartPageSupported, &returnvalue, &currenttemp, &triptemp ) != 0)
printout(LOG_INFO, "%s:Failed to read smart values\n", drive->devicename);
if (returnvalue)
printout(LOG_CRIT, "Device: %s, S.M.A.R.T. Failure: (%02x) %s\n", drive->devicename,
returnvalue, scsiSmartGetSenseCode( returnvalue) );
else
printout(LOG_INFO,"Device: %s, Okay attribute: %d\n", drive->devicename, returnvalue);
if (currenttemp){
if ( (currenttemp != drive->Temperature) && ( drive->Temperature) )
printout(LOG_INFO, "Device: %s, Temperature changed %d degrees to %d degress since last reading\n",
drive->devicename, (int) (currenttemp - drive->Temperature), (unsigned int) currenttemp );
drive->Temperature = currenttemp;
}
return 0;
}
void CheckDevices ( atadevices_t *atadevices, scsidevices_t *scsidevices)
{
int i;
while (1){
for (i = 0; i < numatadevices;i++)
ataCheckDevice ( &atadevices[i]);
for (i = 0; i < numscsidevices;i++)
scsiCheckDevice ( &scsidevices[i]);
sleep ( checktime );
}
}
char copyleftstring[]=
"\nHome page of smartd is http://sourceforge.net/projects/smartmontools\n\n"
"CVS Version ID $Id: smartd.cpp,v 1.2 2002/10/09 18:01:18 ballen4705 Exp $\n"
"smartd comes with ABSOLUTELY NO WARRANTY. This\n"
"is free software, and you are welcome to redistribute it\n"
"under the terms of the GNU General Public License Version 2.\n"
"See http://www.gnu.org for further details.\n";
/* Main Program */
int main (int argc, char **argv){
atadevices_t atadevices[MAXATADEVICES], *atadevicesptr;
scsidevices_t scsidevices[MAXSCSIDEVICES], *scsidevicesptr;
int optchar;
extern char *optarg;
extern int optopt, optind;
const char opts[] = { DEBUGMODE, EMAILNOTIFICATION, PRINTCOPYLEFT,'\0' };
numatadevices=0;
numscsidevices=0;
scsidevicesptr = scsidevices;
atadevicesptr = atadevices;
while(EOF != (optchar = getopt(argc, argv, opts))){
switch(optchar) {
case PRINTCOPYLEFT:
printcopyleft=TRUE;
break;
case DEBUGMODE :
debugmode = TRUE;
break;
case EMAILNOTIFICATION:
emailnotification = TRUE;
break;
case '?':
default:
Usage();
exit(-1);
}
}
if (printcopyleft){
printout(LOG_INFO,copyleftstring);
exit(0);
}
printout(LOG_INFO, "smartd started\n");
if (!debugmode){
daemon_init();
}
/* fork into independent process */
atadevicescan (atadevicesptr);
scsidevicescan (scsidevicesptr);
CheckDevices ( atadevicesptr, scsidevicesptr);
return 0;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment