smartctl.cpp 8.95 KB
Newer Older
1
//  $Id: smartctl.cpp,v 1.11 2002/10/21 08:49:23 ballen4705 Exp $
ballen4705's avatar
ballen4705 committed
2
3
4
/*
 * smartctl.c
 *
5
6
 * Home page of code is: http://smartmontools.sourceforge.net
 *
ballen4705's avatar
ballen4705 committed
7
 * Copyright (C) 2002 Bruce Allen <smartmontools-support@lists.sourceforge.net>
ballen4705's avatar
ballen4705 committed
8
9
10
11
12
13
14
15
16
17
 * 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.
ballen4705's avatar
ballen4705 committed
18
19
20
21
22
23
 *
 * This code was originally developed as a Senior Thesis by Michael 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/
 *
ballen4705's avatar
ballen4705 committed
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
 */


#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;
60
unsigned char smart009minutes         = FALSE;
61
int           testcase                = -1;
ballen4705's avatar
ballen4705 committed
62
63
64
65
66
67
68
69


/*  void Usage (void) 
	prints help information for command syntax */



void Usage ( void){
70
  printf( "Usage: smartctl -[options] [device]\n\n");
ballen4705's avatar
ballen4705 committed
71
  printf( "Read Only Options:\n");
72
73
74
75
76
77
78
79
80
81
82
  printf( "\t\t%c\t\tShow version, 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 S.M.A.R.T. Drive Info      (ATA and SCSI)\n",  DRIVEINFO);
  printf( "\t\t%c\t\tShow S.M.A.R.T. Status          (ATA and SCSI)\n",  CHECKSMART);
  printf( "\t\t%c\t\tShow S.M.A.R.T. General Attributes  (ATA Only)\n",  GENERALSMARTVALUES);
  printf( "\t\t%c\t\tShow S.M.A.R.T. Vendor 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( "\n");
  printf( "Vendor-specific Display Options:\n");
  printf( "\t\t%c\t\tRaw Attribute 009 is minutes        (ATA Only)\n",  SMART009MINUTES);
ballen4705's avatar
ballen4705 committed
83
84
  printf( "\n");
  printf( "Enable/Disable Options:\n");
85
86
87
88
89
90
  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);
ballen4705's avatar
ballen4705 committed
91
92
  printf( "\n");
  printf( "Test Options:\n");
93
94
95
96
97
  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 );
98
  printf( "\t\t%c\t\tExecute Self Test Abort (ATA Only)\n",                 SMARTSELFTESTABORT );
ballen4705's avatar
ballen4705 committed
99
100
101
  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");
102
103
  printf("\tsmartctl -X   /dev/hda   (Executes extended disk self-test)\n\n");
  printf("Please see the man pages or %s for further information.\n",PROJECTHOME);
ballen4705's avatar
ballen4705 committed
104
105
106

}

107
108
109
110
111
112
const char opts[] = { 
  DRIVEINFO, CHECKSMART, SMARTVERBOSEALL, SMARTVENDORATTRIB,
  GENERALSMARTVALUES, SMARTERRORLOG, SMARTSELFTESTLOG, SMARTDISABLE,
  SMARTENABLE, SMARTAUTOOFFLINEENABLE, SMARTAUTOOFFLINEDISABLE,
  SMARTEXEOFFIMMEDIATE, SMARTSHORTSELFTEST, SMARTEXTENDSELFTEST, 
  SMARTSHORTCAPSELFTEST, SMARTEXTENDCAPSELFTEST, SMARTSELFTESTABORT,
113
  SMARTAUTOSAVEENABLE,SMARTAUTOSAVEDISABLE,PRINTCOPYLEFT,SMART009MINUTES,'\0'
114
};
ballen4705's avatar
ballen4705 committed
115

116
/*      Takes command options and sets features to be run */	
ballen4705's avatar
ballen4705 committed
117
void ParseOpts (int argc, char** argv){
118
119
120
  int optchar;
  extern char *optarg;
  extern int optopt, optind, opterr;
ballen4705's avatar
ballen4705 committed
121
  
122
123
  opterr=1;
  while (-1 != (optchar = getopt(argc, argv, opts))) {
ballen4705's avatar
ballen4705 committed
124
    switch (optchar){
125
126
127
    case SMART009MINUTES:
      smart009minutes=TRUE;
      break;
ballen4705's avatar
ballen4705 committed
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
    case PRINTCOPYLEFT :
      printcopyleft=TRUE;
      break;
    case DRIVEINFO :
      driveinfo  = TRUE;
      break;		
    case CHECKSMART :
      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;
177
      testcase=OFFLINE_FULL_SCAN;
ballen4705's avatar
ballen4705 committed
178
179
180
      break;
    case SMARTSHORTSELFTEST :
      smartshortselftest = TRUE;
181
      testcase=SHORT_SELF_TEST;
ballen4705's avatar
ballen4705 committed
182
183
184
      break;
    case SMARTEXTENDSELFTEST :
      smartextendselftest = TRUE;
185
      testcase=EXTEND_SELF_TEST;
ballen4705's avatar
ballen4705 committed
186
187
188
      break;
    case SMARTSHORTCAPSELFTEST:
      smartshortcapselftest = TRUE;
189
      testcase=SHORT_CAPTIVE_SELF_TEST;
ballen4705's avatar
ballen4705 committed
190
191
192
      break;
    case SMARTEXTENDCAPSELFTEST:
      smartextendcapselftest = TRUE;
193
      testcase=EXTEND_CAPTIVE_SELF_TEST;
ballen4705's avatar
ballen4705 committed
194
195
196
      break;
    case SMARTSELFTESTABORT:
      smartselftestabort = TRUE;
197
      testcase=ABORT_SELF_TEST;
ballen4705's avatar
ballen4705 committed
198
199
200
201
202
203
204
205
      break;
    default:
      Usage();
      exit (-1);	
    }
    
    if ( (smartexeoffimmediate + smartshortselftest +
	  smartextendselftest + smartshortcapselftest +
206
	  smartextendcapselftest +smartselftestabort ) > 1){
ballen4705's avatar
ballen4705 committed
207
      Usage();
208
      printf ("\nERROR: smartctl can only run a single test (or abort) at a time.\n\n");
ballen4705's avatar
ballen4705 committed
209
210
211
212
213
214
215
216
217
218
219
      exit(-1);
    }
  }
}

/* Main Program */

int main (int argc, char **argv){
  int fd;
  char *device;
  
220
  printf("smartctl version %d.%d-%d Copyright (C) 2002 Bruce Allen\n",RELEASE_MAJOR,RELEASE_MINOR,SMARTMONTOOLS_VERSION);
221
  printf("Home page of smartctl is %s\n",PROJECTHOME);
222
  
ballen4705's avatar
ballen4705 committed
223
224
225
226
227
  // Part input arguments
  ParseOpts (argc,argv);
  
  // Print Copyright/License info if needed
  if (printcopyleft){
228
    printf("\nsmartctl comes with ABSOLUTELY NO WARRANTY. This\n");
ballen4705's avatar
ballen4705 committed
229
230
    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");
231
    printf("See http://www.gnu.org for further details.\n\n");
232
    printf("CVS version ID %s\n","$Id: smartctl.cpp,v 1.11 2002/10/21 08:49:23 ballen4705 Exp $");
233
234
    if (argc==2)
      exit(0);
ballen4705's avatar
ballen4705 committed
235
236
237
238
239
240
241
242
 }

  // Further argument checking
  if ( argc != 3 ){
    Usage();
    exit (-1);
  }
    
243
244
  // open device - read-only mode is enough to issue needed commands
  fd = open ( device=argv[2], O_RDONLY );
ballen4705's avatar
ballen4705 committed
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
  
  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;
}