diff --git a/sm5/scsiprint.c b/sm5/scsiprint.c index bdfbcf8f11e5e6d7c3a97447a515ddc24c4de23c..c0fcb28d52d64621cdd5b99cefb9d7e33521a75e 100644 --- a/sm5/scsiprint.c +++ b/sm5/scsiprint.c @@ -40,7 +40,7 @@ #define GBUF_SIZE 65535 -const char* scsiprint_c_cvsid="$Id: scsiprint.c,v 1.66 2003/11/19 06:11:01 dpgilbert Exp $" +const char* scsiprint_c_cvsid="$Id: scsiprint.c,v 1.67 2003/11/19 07:50:39 ballen4705 Exp $" EXTERN_H_CVSID SCSICMDS_H_CVSID SCSIPRINT_H_CVSID SMARTCTL_H_CVSID UTILITY_H_CVSID; // control block which points to external global control variables @@ -842,7 +842,7 @@ int scsiPrintMain(int fd) if (con->smartautosavedisable) { if (scsiSetControlGLTSD(fd, 1, modese_len)) { - pout("Disbale autosave (set GLTSD bit) failed\n"); + pout("Disable autosave (set GLTSD bit) failed\n"); failuretest(OPTIONAL_CMD,returnval |= FAILSMART); } } @@ -881,8 +881,8 @@ int scsiPrintMain(int fd) if (con->smarterrorlog) { scsiPrintErrorCounterLog(fd); if (1 == scsiFetchControlGLTSD(fd, modese_len, 1)) - pout("\n[GLTSD (global logging target save disable) set. " - "Enable save with '-S on']\n"); + pout("\n[GLTSD (Global Logging Target Save Disable) set. " + "Enable Save with '-S on']\n"); } if (con->smartselftestlog) { if (! checkedSupportedLogPages) diff --git a/sm5/scsiprint.cpp b/sm5/scsiprint.cpp index 29e3f03a862f6ad4792b8e3f5005876866c4c1e0..a2544dec69c8c733c4053d493752590b4983c387 100644 --- a/sm5/scsiprint.cpp +++ b/sm5/scsiprint.cpp @@ -40,7 +40,7 @@ #define GBUF_SIZE 65535 -const char* scsiprint_c_cvsid="$Id: scsiprint.cpp,v 1.66 2003/11/19 06:11:01 dpgilbert Exp $" +const char* scsiprint_c_cvsid="$Id: scsiprint.cpp,v 1.67 2003/11/19 07:50:39 ballen4705 Exp $" EXTERN_H_CVSID SCSICMDS_H_CVSID SCSIPRINT_H_CVSID SMARTCTL_H_CVSID UTILITY_H_CVSID; // control block which points to external global control variables @@ -842,7 +842,7 @@ int scsiPrintMain(int fd) if (con->smartautosavedisable) { if (scsiSetControlGLTSD(fd, 1, modese_len)) { - pout("Disbale autosave (set GLTSD bit) failed\n"); + pout("Disable autosave (set GLTSD bit) failed\n"); failuretest(OPTIONAL_CMD,returnval |= FAILSMART); } } @@ -881,8 +881,8 @@ int scsiPrintMain(int fd) if (con->smarterrorlog) { scsiPrintErrorCounterLog(fd); if (1 == scsiFetchControlGLTSD(fd, modese_len, 1)) - pout("\n[GLTSD (global logging target save disable) set. " - "Enable save with '-S on']\n"); + pout("\n[GLTSD (Global Logging Target Save Disable) set. " + "Enable Save with '-S on']\n"); } if (con->smartselftestlog) { if (! checkedSupportedLogPages) diff --git a/sm5/smartctl.8.in b/sm5/smartctl.8.in index ec542b684577482f1e99b409871539162c1ec244..e43554a37c63bb874269813863c6a6af9e41ee62 100644 --- a/sm5/smartctl.8.in +++ b/sm5/smartctl.8.in @@ -1,7 +1,7 @@ .ig Copyright (C) 2002-3 Bruce Allen <smartmontools-support@lists.sourceforge.net> - $Id: smartctl.8.in,v 1.14 2003/11/19 06:19:09 dpgilbert Exp $ + $Id: smartctl.8.in,v 1.15 2003/11/19 07:50:39 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 @@ -18,7 +18,7 @@ California, Santa Cruz. http://ssrc.soe.ucsc.edu/ .. -.TH SMARTCTL 8 "$Date: 2003/11/19 06:19:09 $" RELEASE +.TH SMARTCTL 8 "$Date: 2003/11/19 07:50:39 $" RELEASE .SH NAME \fBsmartctl\fP \- Control and Monitor Utility for SMART Disks @@ -29,7 +29,7 @@ .B /usr/sbin/smartctl .SH PACKAGE VERSION -\fBRELEASE\fP "$Date: 2003/11/19 06:19:09 $" +\fBRELEASE\fP "$Date: 2003/11/19 07:50:39 $" .SH DESCRIPTION \fBsmartctl\fP controls the Self-Monitoring, Analysis and Reporting @@ -343,15 +343,17 @@ Attributes. The valid arguments to this option are \fIon\fP and \fIoff\fP. Note that this feature is preserved across disk power cycles, so you should only need to issue it once. -For SCSI devices this toggles the value of the GLTSD (Global Logging Target -Saving Disabled) bit in the Control mode page. Some disk manufacturers -by default set this bit which inhibits error counters, power up hours and -other useful data being placed in non-volatile store. This means these values -will probably be reset to zero the next time the device is power cycled. -If the GLTSD bit is set then a warning is issued when \'smartctl \-a\' is -run. Use \fIon\fP to clear this bit and hence enable saving counters -to non-volatile store. For extreme streaming video type applications -you might consider setting it to \fIoff\fP. +For SCSI devices this toggles the value of the Global Logging Target +Save Disabled (GLTSD) bit in the Control Mode Page. Some disk +manufacturers set this bit by default. This prevents error counters, +power-up hours and other useful data from being placed in non-volatile +storage, so these values may be reset to zero the next time the device +is power-cycled. If the GLTSD bit is set then \'smartctl \-a\' will +issue a warning. Use \fIon\fP to clear the GLTSD bit and thus enable +saving counters to non-volatile storage. For extreme streaming-video +type applications you might consider using \fIoff\fP to set the GLTSD +bit. + .TP .B SMART READ AND DISPLAY DATA OPTIONS: .TP @@ -996,4 +998,4 @@ these documents may be found in the References section of the .SH CVS ID OF THIS PAGE: -$Id: smartctl.8.in,v 1.14 2003/11/19 06:19:09 dpgilbert Exp $ +$Id: smartctl.8.in,v 1.15 2003/11/19 07:50:39 ballen4705 Exp $ diff --git a/sm5/smartd.8.in b/sm5/smartd.8.in index 601280ebd6157a63c9a316b2aed63d5e01966f95..a738a0a5508fdad235e224f7678058cfa49b4b7a 100644 --- a/sm5/smartd.8.in +++ b/sm5/smartd.8.in @@ -1,7 +1,7 @@ .ig Copyright (C) 2002-3 Bruce Allen <smartmontools-support@lists.sourceforge.net> -$Id: smartd.8.in,v 1.16 2003/11/19 06:17:53 dpgilbert Exp $ +$Id: smartd.8.in,v 1.17 2003/11/19 07:50:39 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 @@ -17,7 +17,7 @@ Cornwell at the Concurrent Systems Laboratory (now part of the Storage Systems Research Center), Jack Baskin School of Engineering, University of California, Santa Cruz. http://ssrc.soe.ucsc.edu/ .. -.TH SMARTD 8 "$Date: 2003/11/19 06:17:53 $" RELEASE +.TH SMARTD 8 "$Date: 2003/11/19 07:50:39 $" RELEASE .SH NAME \fBsmartd\fP \- SMART Disk Monitoring Daemon @@ -28,7 +28,7 @@ University of California, Santa Cruz. http://ssrc.soe.ucsc.edu/ .B /usr/sbin/smartd .SH PACKAGE VERSION -\fBRELEASE\fP "$Date: 2003/11/19 06:17:53 $" +\fBRELEASE\fP "$Date: 2003/11/19 07:50:39 $" .SH DESCRIPTION \fBsmartd\fP is a daemon that monitors the Self-Monitoring, Analysis @@ -554,13 +554,10 @@ command-line option documentation for further information about this feature. .TP .B \-S VALUE -Enables or disables Attribute Autosave when -.B smartd +Enables or disables Attribute Autosave when \fBsmartd\fP starts up and has no further effect. The valid arguments to this -Directive are \fIon\fP and \fIoff\fP. Also effects SCSI devices. -[Please see the -.B smartctl \-S -command-line option.] +Directive are \fIon\fP and \fIoff\fP. Also affects SCSI devices. +[Please see the \fBsmartctl \-S\fP command-line option.] .TP .B \-H Check the SMART health status of the disk. If any Prefailure @@ -1352,4 +1349,4 @@ smartmontools home page at \fBhttp://smartmontools.sourceforge.net/\fP . .SH CVS ID OF THIS PAGE: -$Id: smartd.8.in,v 1.16 2003/11/19 06:17:53 dpgilbert Exp $ +$Id: smartd.8.in,v 1.17 2003/11/19 07:50:39 ballen4705 Exp $ diff --git a/sm5/smartd.c b/sm5/smartd.c index 2f35ff5caee22628e875074d818ff1a1f8426a7a..81885708656fe2de795ca6c2fb3cab94ee2ba8cf 100644 --- a/sm5/smartd.c +++ b/sm5/smartd.c @@ -65,7 +65,7 @@ extern const char *atacmdnames_c_cvsid, *atacmds_c_cvsid, *ataprint_c_cvsid, *escalade_c_cvsid, *knowndrives_c_cvsid, *os_XXXX_c_cvsid, *scsicmds_c_cvsid, *utility_c_cvsid; -const char *smartd_c_cvsid="$Id: smartd.c,v 1.244 2003/11/19 06:12:40 dpgilbert Exp $" +const char *smartd_c_cvsid="$Id: smartd.c,v 1.245 2003/11/19 07:50:39 ballen4705 Exp $" ATACMDS_H_CVSID ATAPRINT_H_CVSID CONFIG_H_CVSID EXTERN_H_CVSID KNOWNDRIVES_H_CVSID SCSICMDS_H_CVSID SMARTD_H_CVSID UTILITY_H_CVSID; @@ -1118,7 +1118,7 @@ static int SCSIDeviceScan(cfgfile *cfg) { if (scsiSetControlGLTSD(fd, 0, cfg->modese_len)) PrintOut(LOG_INFO,"Device: %s, could not enable autosave (clear GLTSD bit).\n",device); else - PrintOut(LOG_INFO,"Device: %s, enabled autosave (clear GLTSD bit).\n",device); + PrintOut(LOG_INFO,"Device: %s, enabled autosave (cleared GLTSD bit).\n",device); } // tell user we are registering device @@ -1600,6 +1600,9 @@ void printoutvaliddirectiveargs(int priority, char d) { char *s=NULL; switch (d) { + case 's': + PrintOut(priority, "S,n or L,n or S,n,m-p or L,n,m-p withh n,m,p integers"); + break; case 'd': PrintOut(priority, "ata, scsi, removable, 3ware,N"); break; @@ -1663,6 +1666,61 @@ int GetInteger(char *arg, char *name, char *token, int lineno, char *configfile, return val; } +#define SCHEDULE_SELFTESTS 0 + +#if SCHEDULE_SELFTESTS +char ParseTestTime(char *arg, int *dt, int *range) { + char null='\0'; + char *endptr1, *endptr2,*endptr3; + + // check that pointer is not null + if (!arg) + return null; + + // that first character is L or S + if (arg[0]!='L' && arg[0]!='S') + return null; + + // that second character is comma + if (arg[1]!=',') + return null; + + if (!arg[2]) + return null; + + // that third character is a number + *dt=strtol(arg+2, &endptr1, 10); + + if (!endptr1[0]) + // we read a number, and nothing follows + return arg[0]; + + if (endptr1==arg+2 || endptr1[0] != ',') + return null; + + if (!endptr1[1]) + return null; + + range[0]=strtol(endptr1+1,&endptr2, 10); + + if (!endptr2[0]) + return null; + + if (endptr2==endptr1+1 || endptr2[0] !='-') + return null; + + if (!endptr2[1]) + return null; + + range[1]=strtol(endptr2+1,&endptr3, 10); + + if (*endptr3) + return null; + + return arg[0]+32; +} +#endif + // This function returns 1 if it has correctly parsed one token (and // any arguments), else zero if no tokens remain. It returns -1 if an // error was encountered. @@ -1809,6 +1867,7 @@ int ParseToken(char *token,cfgfile *cfg){ cfg->errorlog=1; break; case 'o': + // automatic offline testing enable/disable if ((arg = strtok(NULL, delim)) == NULL) { missingarg = 1; } else if (!strcmp(arg, "on")) { @@ -1820,6 +1879,7 @@ int ParseToken(char *token,cfgfile *cfg){ } break; case 'S': + // automatic attribute autosave enable/disable if ((arg = strtok(NULL, delim)) == NULL) { missingarg = 1; } else if (!strcmp(arg, "on")) { @@ -1830,6 +1890,54 @@ int ParseToken(char *token,cfgfile *cfg){ badarg = 1; } break; +#if SCHEDULE_SELFTESTS + case 's': + // scheduled self-testing interval, times + if ((arg = strtok(NULL, delim)) == NULL) { + missingarg = 1; + } else { + int dt, range[2]={0,24}; + char type=ParseTestTime(arg, &dt, range); + + if (!type) + badarg=1; + else { + int shortform=type=='L' || type=='S'; + if (type=='l' || type=='s') + type -=32; + + if (dt<1 || dt>65535) { + PrintOut(LOG_CRIT, + "File %s line %d (drive %s): Directive %s %c,n%s\n" + "schedules a self-test n hours after the last one, where 1 <= n <= 65535.\n" + "You have: %s %s so n=%d.\n", + configfile, lineno, name, token, type, shortform?"":",m-p", token, arg, dt); + return -1; + } + + if (!shortform && (range[0]<0 || range[1]>24 || range[0]>=range[1])) { + PrintOut(LOG_CRIT, + "File %s line %d (drive %s): Directive %s %c,n,m-p\n" + "schedules a self-test in the time between m hours after midnight\n" + "and p hours after midnight, where 0 <= m <= 23 and 1 <= p <= 24 and m < p.\n" + "You have: %s %s so m=%d and p=%d.\n", + configfile, lineno, name, token, type, token, arg, range[0], range[1]); + return -1; + } + if (type=='S') { + cfg->runshort=dt; + cfg->runshorttime[0]=range[0]; + cfg->runshorttime[1]=range[1]; + } + else { + cfg->runlong=dt; + cfg->runlongtime[0]=range[0]; + cfg->runlongtime[1]=range[1]; + } + } + } + break; +#endif case 'M': // email warning option if ((arg = strtok(NULL, delim)) == NULL) { diff --git a/sm5/smartd.conf.5.in b/sm5/smartd.conf.5.in index d26ebd983a700340f294049811736a9e580c8f37..7338f25483ed7a51686d35a97a64b4fc2f65ec30 100644 --- a/sm5/smartd.conf.5.in +++ b/sm5/smartd.conf.5.in @@ -1,7 +1,7 @@ .ig Copyright (C) 2002-3 Bruce Allen <smartmontools-support@lists.sourceforge.net> -$Id: smartd.conf.5.in,v 1.10 2003/11/14 07:41:40 ballen4705 Exp $ +$Id: smartd.conf.5.in,v 1.11 2003/11/19 07:50:39 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 @@ -17,11 +17,11 @@ at the Concurrent Systems Laboratory (now part of the Storage Systems Research Center), Jack Baskin School of Engineering, University of California, Santa Cruz. http://ssrc.soe.ucsc.edu/ .. -.TH SMARTD.CONF 5 "$Date: 2003/11/14 07:41:40 $" RELEASE +.TH SMARTD.CONF 5 "$Date: 2003/11/19 07:50:39 $" RELEASE .SH NAME \fBsmartd.conf\fP \- SMART Disk Monitoring Daemon Configuration File \- \fBRELEASE\fP .SH PACKAGE VERSION -RELEASE "$Date: 2003/11/14 07:41:40 $" +RELEASE "$Date: 2003/11/19 07:50:39 $" .SH DESCRIPTION \fB/etc/smartd.conf\fP is the configuration file for the \fBsmartd\fP @@ -284,12 +284,10 @@ command-line option documentation for further information about this feature. .TP .B \-S VALUE -Enables or disables Attribute Autosave when -.B smartd +Enables or disables Attribute Autosave when \fBsmartd\fP starts up and has no further effect. The valid arguments to this -Directive are \fIon\fP and \fIoff\fP. [Please see the -.B smartctl \-S -command-line option.] +Directive are \fIon\fP and \fIoff\fP. Also affects SCSI devices. +[Please see the \fBsmartctl \-S\fP command-line option.] .TP .B \-H Check the SMART health status of the disk. If any Prefailure @@ -950,4 +948,4 @@ SEE ALSO: .SH CVS ID OF THIS PAGE: -$Id: smartd.conf.5.in,v 1.10 2003/11/14 07:41:40 ballen4705 Exp $ +$Id: smartd.conf.5.in,v 1.11 2003/11/19 07:50:39 ballen4705 Exp $ diff --git a/sm5/smartd.cpp b/sm5/smartd.cpp index e2171aece1c0a3f769cb0ef5d26285bbdf9355c2..5be0ffac63fd161789e3531f2b7f0b09df1d1148 100644 --- a/sm5/smartd.cpp +++ b/sm5/smartd.cpp @@ -65,7 +65,7 @@ extern const char *atacmdnames_c_cvsid, *atacmds_c_cvsid, *ataprint_c_cvsid, *escalade_c_cvsid, *knowndrives_c_cvsid, *os_XXXX_c_cvsid, *scsicmds_c_cvsid, *utility_c_cvsid; -const char *smartd_c_cvsid="$Id: smartd.cpp,v 1.244 2003/11/19 06:12:40 dpgilbert Exp $" +const char *smartd_c_cvsid="$Id: smartd.cpp,v 1.245 2003/11/19 07:50:39 ballen4705 Exp $" ATACMDS_H_CVSID ATAPRINT_H_CVSID CONFIG_H_CVSID EXTERN_H_CVSID KNOWNDRIVES_H_CVSID SCSICMDS_H_CVSID SMARTD_H_CVSID UTILITY_H_CVSID; @@ -1118,7 +1118,7 @@ static int SCSIDeviceScan(cfgfile *cfg) { if (scsiSetControlGLTSD(fd, 0, cfg->modese_len)) PrintOut(LOG_INFO,"Device: %s, could not enable autosave (clear GLTSD bit).\n",device); else - PrintOut(LOG_INFO,"Device: %s, enabled autosave (clear GLTSD bit).\n",device); + PrintOut(LOG_INFO,"Device: %s, enabled autosave (cleared GLTSD bit).\n",device); } // tell user we are registering device @@ -1600,6 +1600,9 @@ void printoutvaliddirectiveargs(int priority, char d) { char *s=NULL; switch (d) { + case 's': + PrintOut(priority, "S,n or L,n or S,n,m-p or L,n,m-p withh n,m,p integers"); + break; case 'd': PrintOut(priority, "ata, scsi, removable, 3ware,N"); break; @@ -1663,6 +1666,61 @@ int GetInteger(char *arg, char *name, char *token, int lineno, char *configfile, return val; } +#define SCHEDULE_SELFTESTS 0 + +#if SCHEDULE_SELFTESTS +char ParseTestTime(char *arg, int *dt, int *range) { + char null='\0'; + char *endptr1, *endptr2,*endptr3; + + // check that pointer is not null + if (!arg) + return null; + + // that first character is L or S + if (arg[0]!='L' && arg[0]!='S') + return null; + + // that second character is comma + if (arg[1]!=',') + return null; + + if (!arg[2]) + return null; + + // that third character is a number + *dt=strtol(arg+2, &endptr1, 10); + + if (!endptr1[0]) + // we read a number, and nothing follows + return arg[0]; + + if (endptr1==arg+2 || endptr1[0] != ',') + return null; + + if (!endptr1[1]) + return null; + + range[0]=strtol(endptr1+1,&endptr2, 10); + + if (!endptr2[0]) + return null; + + if (endptr2==endptr1+1 || endptr2[0] !='-') + return null; + + if (!endptr2[1]) + return null; + + range[1]=strtol(endptr2+1,&endptr3, 10); + + if (*endptr3) + return null; + + return arg[0]+32; +} +#endif + // This function returns 1 if it has correctly parsed one token (and // any arguments), else zero if no tokens remain. It returns -1 if an // error was encountered. @@ -1809,6 +1867,7 @@ int ParseToken(char *token,cfgfile *cfg){ cfg->errorlog=1; break; case 'o': + // automatic offline testing enable/disable if ((arg = strtok(NULL, delim)) == NULL) { missingarg = 1; } else if (!strcmp(arg, "on")) { @@ -1820,6 +1879,7 @@ int ParseToken(char *token,cfgfile *cfg){ } break; case 'S': + // automatic attribute autosave enable/disable if ((arg = strtok(NULL, delim)) == NULL) { missingarg = 1; } else if (!strcmp(arg, "on")) { @@ -1830,6 +1890,54 @@ int ParseToken(char *token,cfgfile *cfg){ badarg = 1; } break; +#if SCHEDULE_SELFTESTS + case 's': + // scheduled self-testing interval, times + if ((arg = strtok(NULL, delim)) == NULL) { + missingarg = 1; + } else { + int dt, range[2]={0,24}; + char type=ParseTestTime(arg, &dt, range); + + if (!type) + badarg=1; + else { + int shortform=type=='L' || type=='S'; + if (type=='l' || type=='s') + type -=32; + + if (dt<1 || dt>65535) { + PrintOut(LOG_CRIT, + "File %s line %d (drive %s): Directive %s %c,n%s\n" + "schedules a self-test n hours after the last one, where 1 <= n <= 65535.\n" + "You have: %s %s so n=%d.\n", + configfile, lineno, name, token, type, shortform?"":",m-p", token, arg, dt); + return -1; + } + + if (!shortform && (range[0]<0 || range[1]>24 || range[0]>=range[1])) { + PrintOut(LOG_CRIT, + "File %s line %d (drive %s): Directive %s %c,n,m-p\n" + "schedules a self-test in the time between m hours after midnight\n" + "and p hours after midnight, where 0 <= m <= 23 and 1 <= p <= 24 and m < p.\n" + "You have: %s %s so m=%d and p=%d.\n", + configfile, lineno, name, token, type, token, arg, range[0], range[1]); + return -1; + } + if (type=='S') { + cfg->runshort=dt; + cfg->runshorttime[0]=range[0]; + cfg->runshorttime[1]=range[1]; + } + else { + cfg->runlong=dt; + cfg->runlongtime[0]=range[0]; + cfg->runlongtime[1]=range[1]; + } + } + } + break; +#endif case 'M': // email warning option if ((arg = strtok(NULL, delim)) == NULL) { diff --git a/sm5/smartd.h b/sm5/smartd.h index 38cb8c9e92b5faaaf0a206a12209ba3451433dd0..4975b6e81643b4eb7d4162bf704ca2eda7271b6c 100644 --- a/sm5/smartd.h +++ b/sm5/smartd.h @@ -27,7 +27,7 @@ #ifndef SMARTD_H_CVSID -#define SMARTD_H_CVSID "$Id: smartd.h,v 1.59 2003/11/17 05:21:06 ballen4705 Exp $\n" +#define SMARTD_H_CVSID "$Id: smartd.h,v 1.60 2003/11/19 07:50:39 ballen4705 Exp $\n" #endif // Configuration file @@ -167,6 +167,10 @@ typedef struct configfile_s { char showpresets; // Show database entry for this device char removable; // Device may disappear (not be present) unsigned char selflogcount; // total number of self-test errors + unsigned short runshort; // interval to run short self test on + unsigned short runlong; // interval to run long self test on + signed char runshorttime[2]; // 1+start/stop time run for short tests + signed char runlongtime[2]; // 1+start/stop time run for short tests unsigned char notused1[3]; // for packing alignment unsigned short selfloghour; // lifetime hours of last self-test error char *emailcmdline; // Program for sending mail (or NULL)