diff --git a/sm5/CHANGELOG b/sm5/CHANGELOG index bc0a26b1b264fc5560ee2f0f799603e8950ad705..4686c3784d20b35ffa9e7011c4955c1c7cb16ff8 100644 --- a/sm5/CHANGELOG +++ b/sm5/CHANGELOG @@ -1,6 +1,6 @@ CHANGELOG for smartmontools -$Id: CHANGELOG,v 1.44 2002/11/12 21:16:25 ballen4705 Exp $ +$Id: CHANGELOG,v 1.45 2002/11/13 10:04:12 ballen4705 Exp $ Copyright (C) 2002 Bruce Allen <smartmontools-support@lists.sourceforge.net> @@ -25,6 +25,9 @@ NOTES FOR FUTURE RELEASES: see TODO file. CURRENT RELEASE (see VERSION file in this directory): + Modified SCSI device check to also send warning emails if + requested in directives file. + Added a new smartd configuration file Directive: -M ADDRESS. This sends a single warning email to ADDRESS for failures or errors detected with the -c, -L, -l, or -f Directives. diff --git a/sm5/TODO b/sm5/TODO index 18b73f8deeb5a85f53cff21859ac6e42646a6a6d..5d14b147374d44e79ed0b2a631d9da1c49d2fd19 100644 --- a/sm5/TODO +++ b/sm5/TODO @@ -4,7 +4,7 @@ Home page of code is: http://smartmontools.sourceforge.net Copyright (C) 2002 Bruce Allen <smartmontools-support@lists.sourceforge.net> -$Id: TODO,v 1.21 2002/11/07 21:51:34 ballen4705 Exp $ +$Id: TODO,v 1.22 2002/11/13 10:04:12 ballen4705 Exp $ 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 @@ -58,7 +58,6 @@ should probably be the default option if there is no configuration file. Add following config file directives: - -m USER@ADDRESS send email to user if critical problems found -f enable autosave of attributes -o enable automatic offline testing @@ -66,9 +65,6 @@ Use daemon (8) function instead of do-it-yourself daemon_init(). But, does it close all open file descriptors? Must read glibc code to see: documentation unclear. -Automatically generate smartd.conf.5 man page by extraction of source -from smartd.8 man page, or simply split them up. - General Fixes ------------- diff --git a/sm5/VERSION b/sm5/VERSION index 425151f3a411f5e088d7753e7c8d016303b1b9d1..87523dd7a0632907d61799465827c3f08825fa47 100644 --- a/sm5/VERSION +++ b/sm5/VERSION @@ -1 +1 @@ -40 +41 diff --git a/sm5/smartd.8 b/sm5/smartd.8 index ff8f6de74b59d9f7c0ab44cf60a6662fb3383ad1..decb4b56faaf40af9526087ec51108ee54355029 100644 --- a/sm5/smartd.8 +++ b/sm5/smartd.8 @@ -1,6 +1,6 @@ \# Copyright (C) 2002 Bruce Allen <smartmontools-support@lists.sourceforge.net> \# -\# $Id: smartd.8,v 1.26 2002/11/12 21:16:25 ballen4705 Exp $ +\# $Id: smartd.8,v 1.27 2002/11/13 10:04:13 ballen4705 Exp $ \# \# 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 @@ -16,7 +16,7 @@ \# Research Center), Jack Baskin School of Engineering, University of \# California, Santa Cruz. http://ssrc.soe.ucsc.edu/ \# -.TH SMARTD 8 "$Date: 2002/11/12 21:16:25 $" "smartmontools-5.0" +.TH SMARTD 8 "$Date: 2002/11/13 10:04:13 $" "smartmontools-5.0" .SH NAME smartd \- S.M.A.R.T. Daemon .SH SYNOPSIS @@ -204,7 +204,7 @@ Section below! .nf .B # First ATA disk on each of two interfaces: .B # -.B \ \ /dev/hda -a +.B \ \ /dev/hda -a -M admin@yoyodyne.com,root@localhost .B \ \ /dev/hdc -a -I 194 -I 5 -i 12 .B # .nf @@ -251,8 +251,8 @@ configuration file. Note that .B these are NOT command-line options for .B smartd. The Directives below may appear in any order, -following the device name. For the moment, apart from the '\-S' -Directive, these Directives only apply to ATA disks. +following the device name. For the moment, apart from the '\-S' and '\-M' +Directives, these Directives only apply to ATA disks. .B For ATA disks, if .B no Directives appear, the disk will not be monitored. The '\-a' Directive will try to monitor everything possible. @@ -540,4 +540,4 @@ Please let us know if there is an on\-line source for this document. .SH CVS ID OF THIS PAGE: -$Id: smartd.8,v 1.26 2002/11/12 21:16:25 ballen4705 Exp $ +$Id: smartd.8,v 1.27 2002/11/13 10:04:13 ballen4705 Exp $ diff --git a/sm5/smartd.c b/sm5/smartd.c index b5773ecfcca42c58c1e6f8d09f373023588b6de1..8121b91768318fd25110416f300376adc142196a 100644 --- a/sm5/smartd.c +++ b/sm5/smartd.c @@ -45,7 +45,7 @@ // CVS ID strings extern const char *CVSid1, *CVSid2; -const char *CVSid6="$Id: smartd.c,v 1.61 2002/11/13 07:39:50 ballen4705 Exp $" +const char *CVSid6="$Id: smartd.c,v 1.62 2002/11/13 10:04:13 ballen4705 Exp $" CVSID1 CVSID2 CVSID3 CVSID4 CVSID7; // global variable used for control of printing, passing arguments, etc. @@ -245,7 +245,7 @@ void Directives() { printout(LOG_INFO," # Comment: text after a hash sign is ignored\n"); printout(LOG_INFO," \\ Line continuation character\n"); printout(LOG_INFO,"Attribute ID is a decimal integer 1 <= ID <= 255\n"); - printout(LOG_INFO,"All but -S Directive are only implemented for ATA devices\n"); + printout(LOG_INFO,"All but -S and -M Directives are only implemented for ATA devices\n"); printout(LOG_INFO,"Example: /dev/hda -a\n"); return; } @@ -274,7 +274,6 @@ int opendevice(char *device){ return fd; } -// returns 1 if problem, else zero int closedevice(int fd, char *name){ if (close(fd)){ if (errno<sys_nerr) @@ -433,14 +432,20 @@ int atadevicescan2(atadevices_t *devices, cfgfile *cfg){ // This function is hard to read and ought to be rewritten. Why in the // world is the four-byte integer cast to a pointer to an eight-byte // object?? Can anyone explain this obscurity? -int scsidevicescan(scsidevices_t *devices, char *device){ +int scsidevicescan(scsidevices_t *devices, cfgfile *cfg){ int i, fd, smartsupport; + char *device=cfg->name; unsigned char tBuf[4096]; + + // should we try to register this as a SCSI device? + if (!(cfg->tryscsi)) + return 1; - printout(LOG_INFO,"Device: %s, opening\n", device); + // open the device if ((fd=opendevice(device))<0) // device open failed return 1; + printout(LOG_INFO,"Device: %s, opened\n", device); // check that it's ready for commands if (!testunitready(fd)){ @@ -475,7 +480,8 @@ int scsidevicescan(scsidevices_t *devices, char *device){ printout(LOG_INFO, "Device: %s, is SMART capable. Adding to \"monitor\" list.\n",device); // since device points to global memory, just keep that address - devices[numscsidevices].devicename=device; + devices->devicename=device; + devices->cfg=cfg; // register the supported functionality. The smartd code does not // seem to make any further use of this information. @@ -483,16 +489,18 @@ int scsidevicescan(scsidevices_t *devices, char *device){ for ( i = 4; i < tBuf[3] + LOGPAGEHDRSIZE ; i++){ switch ( tBuf[i]){ case TEMPERATURE_PAGE: - devices[numscsidevices].TempPageSupported = 1; + devices->TempPageSupported = 1; break; case SMART_PAGE: - devices[numscsidevices].SmartPageSupported = 1; + devices->SmartPageSupported = 1; break; default: break; } } } + + // increment number of SCSI devices found numscsidevices++; closedevice(fd, device); return 0; @@ -708,11 +716,12 @@ int ataCheckDevice(atadevices_t *drive){ -int scsiCheckDevice( scsidevices_t *drive){ +int scsiCheckDevice(scsidevices_t *drive){ UINT8 returnvalue; UINT8 currenttemp; UINT8 triptemp; int fd; + cfgfile *cfg=drive->cfg; // if we can't open device, fail gracefully rather than hard -- // perhaps the next time around we'll be able to open it @@ -724,10 +733,13 @@ int scsiCheckDevice( scsidevices_t *drive){ if (scsiCheckSmart(fd, drive->SmartPageSupported, &returnvalue, ¤ttemp, &triptemp)) printout(LOG_INFO, "Device: %s, failed to read SMART values\n", drive->devicename); - if (returnvalue) + if (returnvalue) { printout(LOG_CRIT, "Device: %s, SMART Failure: (%d) %s\n", drive->devicename, (int)returnvalue, scsiSmartGetSenseCode(returnvalue)); - else + printandmail(cfg->address, cfg->maildata, LOG_CRIT, "Device: %s, SMART Failure: (%d) %s\n", drive->devicename, + (int)returnvalue, scsiSmartGetSenseCode(returnvalue)); + } + else if (debugmode) printout(LOG_INFO,"Device: %s, Acceptable Attribute: %d\n", drive->devicename, (int)returnvalue); // Seems to completely ignore what capabilities were found on the @@ -1291,7 +1303,7 @@ int main (int argc, char **argv){ cantregister(config[i].name, "ATA", config[i].lineno); // then register SCSI devices - if (config[i].tryscsi && scsidevicescan(scsidevicesptr, config[i].name)) + if (config[i].tryscsi && scsidevicescan(scsidevicesptr+numscsidevices, config+i)) cantregister(config[i].name, "SCSI", config[i].lineno); } diff --git a/sm5/smartd.conf b/sm5/smartd.conf index 4336bd731b1ec324ec1811e81729b098f74bd8d5..ffad86d5ce669f1677bd0444b2d81075a0029443 100644 --- a/sm5/smartd.conf +++ b/sm5/smartd.conf @@ -31,23 +31,24 @@ DEVICESCAN # HERE IS A LIST OF DIRECTIVES FOR THIS CONFIGURATION FILE -# -A Device is an ATA device -# -S Device is a SCSI device -# -C N Check disks every N seconds. N must be 10 or greater -# -P Ignore lack of SMART (for disks before ATA-3 Rev 4) -# -c Monitor SMART Health Status -# -l Monitor SMART Error Log for changes -# -L Monitor SMART Self-Test Log for new errors -# -f Monitor for failure of any 'Usage' Attributes -# -p Report changes in 'Prefailure' Attributes -# -u Report changes in 'Usage' Attributes -# -t Equivalent to -p and -u Directives -# -i ID Ignore Attribute ID for -f Directive -# -I ID Ignore Attribute ID for -p, -u or -t Directive -# # Comment: text after a hash sign is ignored -# \ Line continuation character +# -A Device is an ATA device +# -S Device is a SCSI device +# -C N Check disks every N seconds. N must be 10 or greater +# -P Ignore lack of SMART (for disks before ATA-3 Rev 4) +# -c Monitor SMART Health Status +# -l Monitor SMART Error Log for changes +# -L Monitor SMART Self-Test Log for new errors +# -f Monitor for failure of any 'Usage' Attributes +# -M ADD Send warning email to ADD for -c, -l, -L, and -f +# -p Report changes in 'Prefailure' Attributes +# -u Report changes in 'Usage' Attributes +# -t Equivalent to -p and -u Directives +# -i ID Ignore Attribute ID for -f Directive +# -I ID Ignore Attribute ID for -p, -u or -t Directive +# # Comment: text after a hash sign is ignored +# \ Line continuation character # Attribute ID is a decimal integer 1 <= ID <= 255 -# All but -S directive are only implemented for ATA devices +# All but -S and -M directives are only implemented for ATA devices # # If the test string DEVICESCAN is the first uncommented text # then smartd will scan for devices /dev/hd[a-l] and /dev/sd[a-z] diff --git a/sm5/smartd.cpp b/sm5/smartd.cpp index f1da8343d27db81fa26010d60caaf0c7f19defdd..0220296ec6302394a8bf66ce2d15c6f3769000d2 100644 --- a/sm5/smartd.cpp +++ b/sm5/smartd.cpp @@ -45,7 +45,7 @@ // CVS ID strings extern const char *CVSid1, *CVSid2; -const char *CVSid6="$Id: smartd.cpp,v 1.61 2002/11/13 07:39:50 ballen4705 Exp $" +const char *CVSid6="$Id: smartd.cpp,v 1.62 2002/11/13 10:04:13 ballen4705 Exp $" CVSID1 CVSID2 CVSID3 CVSID4 CVSID7; // global variable used for control of printing, passing arguments, etc. @@ -245,7 +245,7 @@ void Directives() { printout(LOG_INFO," # Comment: text after a hash sign is ignored\n"); printout(LOG_INFO," \\ Line continuation character\n"); printout(LOG_INFO,"Attribute ID is a decimal integer 1 <= ID <= 255\n"); - printout(LOG_INFO,"All but -S Directive are only implemented for ATA devices\n"); + printout(LOG_INFO,"All but -S and -M Directives are only implemented for ATA devices\n"); printout(LOG_INFO,"Example: /dev/hda -a\n"); return; } @@ -274,7 +274,6 @@ int opendevice(char *device){ return fd; } -// returns 1 if problem, else zero int closedevice(int fd, char *name){ if (close(fd)){ if (errno<sys_nerr) @@ -433,14 +432,20 @@ int atadevicescan2(atadevices_t *devices, cfgfile *cfg){ // This function is hard to read and ought to be rewritten. Why in the // world is the four-byte integer cast to a pointer to an eight-byte // object?? Can anyone explain this obscurity? -int scsidevicescan(scsidevices_t *devices, char *device){ +int scsidevicescan(scsidevices_t *devices, cfgfile *cfg){ int i, fd, smartsupport; + char *device=cfg->name; unsigned char tBuf[4096]; + + // should we try to register this as a SCSI device? + if (!(cfg->tryscsi)) + return 1; - printout(LOG_INFO,"Device: %s, opening\n", device); + // open the device if ((fd=opendevice(device))<0) // device open failed return 1; + printout(LOG_INFO,"Device: %s, opened\n", device); // check that it's ready for commands if (!testunitready(fd)){ @@ -475,7 +480,8 @@ int scsidevicescan(scsidevices_t *devices, char *device){ printout(LOG_INFO, "Device: %s, is SMART capable. Adding to \"monitor\" list.\n",device); // since device points to global memory, just keep that address - devices[numscsidevices].devicename=device; + devices->devicename=device; + devices->cfg=cfg; // register the supported functionality. The smartd code does not // seem to make any further use of this information. @@ -483,16 +489,18 @@ int scsidevicescan(scsidevices_t *devices, char *device){ for ( i = 4; i < tBuf[3] + LOGPAGEHDRSIZE ; i++){ switch ( tBuf[i]){ case TEMPERATURE_PAGE: - devices[numscsidevices].TempPageSupported = 1; + devices->TempPageSupported = 1; break; case SMART_PAGE: - devices[numscsidevices].SmartPageSupported = 1; + devices->SmartPageSupported = 1; break; default: break; } } } + + // increment number of SCSI devices found numscsidevices++; closedevice(fd, device); return 0; @@ -708,11 +716,12 @@ int ataCheckDevice(atadevices_t *drive){ -int scsiCheckDevice( scsidevices_t *drive){ +int scsiCheckDevice(scsidevices_t *drive){ UINT8 returnvalue; UINT8 currenttemp; UINT8 triptemp; int fd; + cfgfile *cfg=drive->cfg; // if we can't open device, fail gracefully rather than hard -- // perhaps the next time around we'll be able to open it @@ -724,10 +733,13 @@ int scsiCheckDevice( scsidevices_t *drive){ if (scsiCheckSmart(fd, drive->SmartPageSupported, &returnvalue, ¤ttemp, &triptemp)) printout(LOG_INFO, "Device: %s, failed to read SMART values\n", drive->devicename); - if (returnvalue) + if (returnvalue) { printout(LOG_CRIT, "Device: %s, SMART Failure: (%d) %s\n", drive->devicename, (int)returnvalue, scsiSmartGetSenseCode(returnvalue)); - else + printandmail(cfg->address, cfg->maildata, LOG_CRIT, "Device: %s, SMART Failure: (%d) %s\n", drive->devicename, + (int)returnvalue, scsiSmartGetSenseCode(returnvalue)); + } + else if (debugmode) printout(LOG_INFO,"Device: %s, Acceptable Attribute: %d\n", drive->devicename, (int)returnvalue); // Seems to completely ignore what capabilities were found on the @@ -1291,7 +1303,7 @@ int main (int argc, char **argv){ cantregister(config[i].name, "ATA", config[i].lineno); // then register SCSI devices - if (config[i].tryscsi && scsidevicescan(scsidevicesptr, config[i].name)) + if (config[i].tryscsi && scsidevicescan(scsidevicesptr+numscsidevices, config+i)) cantregister(config[i].name, "SCSI", config[i].lineno); } diff --git a/sm5/smartd.h b/sm5/smartd.h index c5e2677a618459ca5deec6b818775907a5283c5a..fb64bc6b5f56be677eb215c01cbefb838c8ff9cd 100644 --- a/sm5/smartd.h +++ b/sm5/smartd.h @@ -23,7 +23,7 @@ */ #ifndef CVSID7 -#define CVSID7 "$Id: smartd.h,v 1.20 2002/11/12 21:16:25 ballen4705 Exp $\n" +#define CVSID7 "$Id: smartd.h,v 1.21 2002/11/13 10:04:13 ballen4705 Exp $\n" #endif // Configuration file @@ -58,15 +58,6 @@ #define TRUE 0x01 #define FALSE 0x00 -// used to store a list of SCSI devices to monitor. Devicename points -// to a malloced name string. -typedef struct scsidevices_s { - unsigned char SmartPageSupported; - unsigned char TempPageSupported; - unsigned char Temperature; - char *devicename; -} scsidevices_t; - // If user has requested email warning messages, then this structure // stores the information about them. @@ -119,6 +110,16 @@ typedef struct atadevices_s { char *devicename; } atadevices_t; +// used to store a list of SCSI devices to monitor. Devicename points +// to a malloced name string. +typedef struct scsidevices_s { + unsigned char SmartPageSupported; + unsigned char TempPageSupported; + unsigned char Temperature; + char *devicename; + cfgfile *cfg; +} scsidevices_t; + // Declare our own printing functions... void printout(int priority,char *fmt, ...) __attribute__ ((format(printf, 2, 3))); diff --git a/sm5/smartmontools.spec b/sm5/smartmontools.spec index 2f01725f06379fd8a263a4d862fd416f8cc8c8f4..b9fadec88f4727c4ef4238ee2c98d26c5d901002 100644 --- a/sm5/smartmontools.spec +++ b/sm5/smartmontools.spec @@ -29,7 +29,7 @@ Packager: Bruce Allen <smartmontools-support@lists.sourceforge.net> # http://ftp1.sourceforge.net/smartmontools/smartmontools-%{version}-%{release}.tar.gz # CVS ID of this file is: -# $Id: smartmontools.spec,v 1.60 2002/11/13 07:41:05 ballen4705 Exp $ +# $Id: smartmontools.spec,v 1.61 2002/11/13 10:04:13 ballen4705 Exp $ # Copyright (C) 2002 Bruce Allen <smartmontools-support@lists.sourceforge.net> # Home page: http://smartmontools.sourceforge.net/ @@ -234,6 +234,7 @@ fi %define date %(echo `LC_ALL="C" date +"%a %b %d %Y"`) %changelog * Wed Nov 13 2002 Bruce Allen <smartmontools-support@lists.sourceforge.net> +- smartd SCSI devices: can now send warning email message on failure - Added a new smartd configuration file Directive: -M ADDRESS. This sends a single warning email to ADDRESS for failures or errors detected with the -c, -L, -l, or -f Directives.