⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smartd.c

📁 Linux下
💻 C
字号:
/* * smartd.c * * 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 "atacmds.h"#include "scsicmds.h"#include "smartd.h"int daemon_init(void){   pid_t pid;   if ( (pid = fork()) < 0)      return -1;   else if (pid != 0)      exit (0);   setsid ();   chdir("/");   umask(0);   return(0);}/*  void Usage (void) 	prints help information for command syntax */void Usage ( void){   printf( "smartd version %i.%i - S.M.A.R.T. Daemon\n",            VERSION_MAJOR, VERSION_MINOR);   printf( "useage: smartd -[opts] \n");   printf( "Read Only Commands:\n");   printf( "\t\t%c\t\tStart smartd in debug Mode\n",DEBUGMODE);}	/*  void ParseOpts ( chars *opts) 	Takes command options and sets features to be run */	void ParseOpts ( char *opts){   int i = 0;   char options[255];	   strcpy ( (char *) &options, opts);   if ( options[0] != '-' )   {      Usage();      exit (-1);   }   for (i = 1; options[i] != '\0'; i++ )   {      switch (options[i])      {         case DEBUGMODE :            debugmode  = TRUE;            break;         case EMAILNOTIFICATION:            emailnotification = TRUE;            break;         default:            Usage();            exit (-1);	      }   }}void failurenotify ( char *message){}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]++ )   {      fd = 0;      if (debugmode)         printf("Reading Device %s\n", device);	      fd = open ( device , O_RDWR );      if ( fd >= 0)      {         if (ataReadHDIdentity ( fd, &drive) == 0 )          {             if (ataSmartSupport (drive) )              {                if (ataEnableSmart)                {                    devices[numatadevices].fd = fd;                    strcpy((char *) &devices[numatadevices].devicename,                           (char*) &device);                    devices[numatadevices].drive = drive;                    if ( ataReadSmartValues ( fd,                          &devices[numatadevices].smartval) != 0 )                    {                        syslog (LOG_INFO,                                 "Device: %s, Read Smart Values Failed\n",                                 device);                    }                    if ( ataReadSmartThresholds ( fd,                          &devices[numatadevices].smartthres) != 0 )                    {                        syslog (LOG_INFO,                                 "Device: %s, Read Smart Thresholds Failed\n",                                 device);                    }                    if (debugmode)                        printf("%s Found and is SMART capable\n",                                devices[numatadevices].devicename);                    syslog (LOG_INFO,                             "Device: %s, Found and is SMART capable\n",                             device);                    devices[numatadevices].selftest =                         isSupportSelfTest(devices[numatadevices].smartval);                    numatadevices++;               }                  }         }      }   }}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]++ )   {      fd = 0;      if (debugmode)         printf("Reading Device %s\n", device);      fd = open ( device , O_RDWR );      if(debugmode)         printf ("Device: %s, File Descriptor: %d \n", device, fd);      if ( fd >= 0)      {         if (  testunitready (fd) == 0 )          {            if (modesense ( fd, 0x1c, (UINT8 *) &tBuf) != 0)            {               if(debugmode)                   printf ("Device: %s, Failed read of ModePage 1C \n", device);            }            else            {            if ( scsiSmartSupport( fd, (UINT8 *) &smartsupport) == 0)            {			               if (!(smartsupport & DEXCPT_ENABLE))               {                  devices[numscsidevices].fd = fd;                  strcpy((char *) &devices[numscsidevices].devicename,                         (char*) &device);							                  if (debugmode)                    printf("%s Found and is SMART capable\n",                             devices[numscsidevices].devicename);                                   syslog (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 b ){    int i;    for ( i =0; i < NUMBER_ATA_SMART_ATTRIBUTES; i++)    {       if( device->smartval.vendor_attributes[i].id & b.vendor_attributes[i].id            & (device->smartval.vendor_attributes[i].current            != b.vendor_attributes[i].current))       {           syslog (LOG_INFO, "Device: %s, S.M.A.R.T. Attribute: %i Changed %i\n",                  device->devicename,                   device->smartval.vendor_attributes[i].id,                   (device->smartval.vendor_attributes[i].current                    - b.vendor_attributes[i].current));       } 	}  }int ataCheckDevice( atadevices_t *drive){	struct ata_smart_values tempsmartval;	struct ata_smart_thresholds tempsmartthres;	if ( ataReadSmartValues ( drive->fd, &tempsmartval) != 0 )	{       syslog (LOG_INFO, "%s:Failed to read smart values\n", drive->devicename);	}	if ( ataReadSmartThresholds ( drive->fd, &tempsmartthres) != 0 )	{       syslog (LOG_INFO, "%s:Failed to read smart thresholds\n", 					    drive->devicename);	}			    if (ataCheckSmart( tempsmartval, tempsmartthres))	{		if(debugmode)			printf ("Device: %s, Failed attribute: %i\n", drive->devicename,                      ataCheckSmart( tempsmartval, tempsmartthres));    	else			syslog (LOG_CRIT, "Device: %s, Failed attribute: %i\n", drive->devicename, 						ataCheckSmart( tempsmartval, tempsmartthres));	}					if(debugmode)		printf ("Device: %s, S.M.A.R.T. Failure attribute: %i\n", drive->devicename, 				ataCheckSmart( tempsmartval, tempsmartthres));				ataCompareSmartValues (drive , tempsmartval);				/* Copy the values back to the structure */	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)	{       syslog (LOG_INFO, "%s:Failed to read smart values\n", drive->devicename);	}		if ( returnvalue )	{		if(debugmode)			printf ("Device: %s, S.M.A.R.T. Failure: (%02x) %s\n", drive->devicename, 					returnvalue, scsiSmartGetSenseCode( returnvalue) );		else			syslog (LOG_CRIT, "Device: %s, S.M.A.R.T. Failure: (%02x) %s\n", drive->devicename, 					returnvalue, scsiSmartGetSenseCode( returnvalue) );	}					else	{		if(debugmode)			printf ("Device: %s, Okay attribute: %d\n", drive->devicename, returnvalue);   	}	if ( currenttemp )	{		if ( (currenttemp != drive->Temperature) && ( drive->Temperature) )			syslog (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++)		{			if ( ataCheckDevice (  &atadevices[i]) != 0 )			{				exit (-1); /* never reached */			}				}				for (i = 0; i < numscsidevices;i++)		{			if ( scsiCheckDevice (  &scsidevices[i]) != 0 )			{				exit (-1); /* never reached */			}				}						sleep ( checktime );	}}/* Main Program */int main (int argv, char **argc){		atadevices_t atadevices[MAXATADEVICES], *atadevicesptr;	scsidevices_t scsidevices[MAXSCSIDEVICES], *scsidevicesptr;		numatadevices=0;	numscsidevices=0;		scsidevicesptr = scsidevices;	atadevicesptr = atadevices;	if ( *(argc+1) != NULL)		ParseOpts ( *(argc+1));	syslog (LOG_INFO, "smartd started\n");	if (!debugmode)	{		daemon_init();	}	/*	fork into indepentant process */	atadevicescan (atadevicesptr); 	scsidevicescan (scsidevicesptr);		CheckDevices ( atadevicesptr, scsidevicesptr); 	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -