From 0acbf358539a008ab3fb7ab2616287888aa60b16 Mon Sep 17 00:00:00 2001 From: ballen4705 <ballen4705@4ea69e1a-61f1-4043-bf83-b5c94c648137> Date: Wed, 13 Nov 2002 10:04:13 +0000 Subject: [PATCH] Added code to send warning emails for SCSI devices also. git-svn-id: https://smartmontools.svn.sourceforge.net/svnroot/smartmontools/trunk@256 4ea69e1a-61f1-4043-bf83-b5c94c648137 --- sm5/CHANGELOG | 5 ++++- sm5/TODO | 6 +----- sm5/VERSION | 2 +- sm5/smartd.8 | 12 ++++++------ sm5/smartd.c | 36 ++++++++++++++++++++++++------------ sm5/smartd.conf | 33 +++++++++++++++++---------------- sm5/smartd.cpp | 36 ++++++++++++++++++++++++------------ sm5/smartd.h | 21 +++++++++++---------- sm5/smartmontools.spec | 3 ++- 9 files changed, 90 insertions(+), 64 deletions(-) diff --git a/sm5/CHANGELOG b/sm5/CHANGELOG index bc0a26b1b..4686c3784 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 18b73f8de..5d14b1473 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 425151f3a..87523dd7a 100644 --- a/sm5/VERSION +++ b/sm5/VERSION @@ -1 +1 @@ -40 +41 diff --git a/sm5/smartd.8 b/sm5/smartd.8 index ff8f6de74..decb4b56f 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 b5773ecfc..8121b9176 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 4336bd731..ffad86d5c 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 f1da8343d..0220296ec 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 c5e2677a6..fb64bc6b5 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 2f01725f0..b9fadec88 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. -- GitLab