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

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

parent b2065c1f
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.2 2002/10/10 13:21:15 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 " PROJECTHOME "/\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("Home page of project is %s\n\n",PROJECTHOME);
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\n");
printf("CVS version ID %s\n","$Id: smartctl.cpp,v 1.2 2002/10/10 13:21:15 ballen4705 Exp $");
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.3 2002/10/10 13:21:17 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[]=
"Home page of smartd is " PROJECTHOME "\n\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\n"
"CVS Version ID $Id: smartd.cpp,v 1.3 2002/10/10 13:21:17 ballen4705 Exp $\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:
debugmode=1;
Usage();
exit(-1);
}
}
if (printcopyleft){
debugmode=1;
printout(LOG_INFO,"smartd version %d.%d Copyright (C) Bruce Allen 2002\n",VERSION_MAJOR,VERSION_MINOR);
printout(LOG_INFO,copyleftstring);
exit(0);
}
printout(LOG_INFO,"smartd version %d.%d Copyright (C) Bruce Allen 2002\n",VERSION_MAJOR,VERSION_MINOR);
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