Commit 47c3e15d11b8888174b1b6e4bf202399b273ac94

Authored by Imanol-Mikel Barba Sabariego
1 parent da7c8f92

Changed code style. Added 'optional' attribute field and another attribute for Intel Enterprise SSDs

check_smart/check_smart.cpp
... ... @@ -2,76 +2,80 @@
2 2  
3 3 const char *servicename = (const char*)"SMART";
4 4  
5   -int getSmartAttrValue(string line)
6   -{
  5 +int getSmartAttrValue(string line) {
7 6 return stoi(line.substr(line.find_last_of(" ")+1));
8 7 }
9 8  
10   -int getSmartAttrID(string line)
11   -{
  9 +int getSmartAttrID(string line) {
12 10 size_t first = line.find_first_not_of(' ');
13 11 size_t last = line.find_first_of(' ',first);
14 12 int id = -1;
15   - try {id = stoi(line.substr(first,last-first));}
16   - catch(...){}
  13 + try {
  14 + id = stoi(line.substr(first,last-first));
  15 + }
  16 + catch(...){
  17 + return -1;
  18 + }
17 19 return id;
18 20 }
19 21  
20   -int checkDriveType(const char* disk)
21   -{
  22 +int checkDriveType(const char* disk) {
22 23 string output = "";
23 24 string RRLine = "";
24 25 string line= "";
25 26  
26 27 int rc = run_smartctl_cmd(string(SMARTCTL_CMD_INFO), disk,&output);
27   - if(rc)
28   - {
  28 + if(rc) {
29 29 cout << "Error reading SMART data from disk " << disk << endl;
30 30 exit(3);
31 31 }
32 32  
33 33 stringstream sstream;
34 34 sstream.str(output);
35   - while(getline(sstream,line) && RRLine == "")
36   - {
  35 + while(getline(sstream,line) && RRLine == "") {
37 36 size_t found = line.find(ROTATION_INFO_STR);
38   - if(found != string::npos) {RRLine = line;}
  37 + if(found != string::npos) {
  38 + RRLine = line;
  39 + }
39 40 }
40   - if(RRLine != "")
41   - {
  41 + if(RRLine != "") {
42 42 size_t found = RRLine.find(SSD_DEV_STR);
43   - if(found != string::npos) {return SSD;}
  43 + if(found != string::npos) {
  44 + return SSD;
  45 + }
44 46 }
45 47 return HDD;
46 48 }
47 49  
48   -map<int,SMARTAttr> prepareAttrMap(int driveType)
49   -{
  50 +map<int,SMARTAttr> prepareAttrMap(int driveType) {
50 51 map<int,SMARTAttr> map;
51 52  
52 53 SMARTAttr realloc;
53 54 realloc.name = "Reallocated_Sector_Ct";
54 55 realloc.value = -1;
55 56 realloc.severity = WARN;
  57 + realloc.optional = false;
56 58 map[REALLOC_SEC_COUNT_ID] = realloc;
57 59  
58 60 SMARTAttr pending;
59 61 SMARTAttr off_uncorrect;
60 62 SMARTAttr wear;
  63 + SMARTAttr wearout;
61 64 SMARTAttr badblocks;
62 65 SMARTAttr rep_uncorrect;
63 66  
64   - switch(driveType)
65   - {
  67 + switch(driveType) {
66 68 case HDD:
67 69 pending.name = "Current_Pending_Sector";
68 70 pending.value = -1;
69 71 pending.severity = CRIT;
  72 + pending.optional = false;
70 73 map[CURRENT_PENDING_SEC_ID] = pending;
71 74  
72 75 off_uncorrect.name = "Offline_Uncorrectable";
73 76 off_uncorrect.value = -1;
74 77 off_uncorrect.severity = CRIT;
  78 + off_uncorrect.optional = false;
75 79 map[OFFLINE_UNCORRECT_ID] = off_uncorrect;
76 80  
77 81 break;
... ... @@ -79,16 +83,25 @@ map&lt;int,SMARTAttr&gt; prepareAttrMap(int driveType)
79 83 wear.name = "Wear_Leveling_Count";
80 84 wear.value = -1;
81 85 wear.severity = WARN;
  86 + wear.optional = true;
82 87 map[WEAR_COUNT_ID] = wear;
83 88  
  89 + wearout.name = "Media_Wearout_Indicator";
  90 + wearout.value = -1;
  91 + wearout.severity = WARN;
  92 + wearout.optional = true;
  93 + map[WEAR_COUNT_ID] = wearout;
  94 +
84 95 badblocks.name = "Runtime_Bad_Block";
85 96 badblocks.value = -1;
86 97 badblocks.severity = CRIT;
  98 + badblocks.optional = false;
87 99 map[RUNTIME_BAD_BLOCKS_IDD] = badblocks;
88 100  
89 101 rep_uncorrect.name = "Reported_Uncorrect";
90 102 rep_uncorrect.value = -1;
91 103 rep_uncorrect.severity = CRIT;
  104 + rep_uncorrect.optional = false;
92 105 map[REP_UNCORRECT_ID] = rep_uncorrect;
93 106  
94 107 break;
... ... @@ -96,14 +109,12 @@ map&lt;int,SMARTAttr&gt; prepareAttrMap(int driveType)
96 109 return map;
97 110 }
98 111  
99   -int evalStatus(const char* disk, int driveType, string *status)
100   -{
  112 +int evalStatus(const char* disk, int driveType, string *status) {
101 113 string output = "";
102 114 string line = "";
103 115  
104 116 int rc = run_smartctl_cmd(string(SMARTCTL_CMD_ATTRS), disk,&output);
105   - if(rc)
106   - {
  117 + if(rc) {
107 118 cout << "Error reading SMART data from disk " << disk << endl;
108 119 exit(UNKN);
109 120 }
... ... @@ -112,34 +123,42 @@ int evalStatus(const char* disk, int driveType, string *status)
112 123  
113 124 stringstream sstream;
114 125 sstream.str(output);
115   - while(getline(sstream,line))
116   - {
117   - for(map<int,SMARTAttr>::iterator it = attrMap.begin(); it != attrMap.end(); ++it)
118   - {
  126 + while(getline(sstream,line)) {
  127 + for(map<int,SMARTAttr>::iterator it = attrMap.begin(); it != attrMap.end(); ++it) {
119 128 int id = it->first;
120   - if(getSmartAttrID(line) == id) {attrMap[id].value = getSmartAttrValue(line);}
  129 + int attrID = getSmartAttrID(line);
  130 + if(attrID == -1) {
  131 + continue;
  132 + }
  133 + if(getSmartAttrID(line) == id) {
  134 + attrMap[id].value = getSmartAttrValue(line);
  135 + }
121 136 }
122 137 }
123 138 int ret = OK;
124 139 *status = string(disk);
125   - for(map<int,SMARTAttr>::iterator it = attrMap.begin(); it != attrMap.end(); ++it)
126   - {
  140 + for(map<int,SMARTAttr>::iterator it = attrMap.begin(); it != attrMap.end(); ++it) {
127 141 int id = it->first;
128 142 SMARTAttr attr = it->second;
129 143  
130   - if(attr.value == -1)
131   - {
  144 + if(attr.value == -1) {
  145 + if(attr.optional) {
  146 + continue;
  147 + }
132 148 *status = string(disk) + " status UNKNOWN";
133 149 return UNKN;
134 150 }
135 151 int veredict = 0;
136   - if(attr.value) {veredict = attr.severity;}
137   - switch(veredict)
138   - {
  152 + if(attr.value) {
  153 + veredict = attr.severity;
  154 + }
  155 + switch(veredict) {
139 156 case OK:
140 157 break;
141 158 case WARN:
142   - if(ret == OK) {ret = WARN;}
  159 + if(ret == OK) {
  160 + ret = WARN;
  161 + }
143 162 break;
144 163 case CRIT:
145 164 ret = CRIT;
... ... @@ -150,8 +169,7 @@ int evalStatus(const char* disk, int driveType, string *status)
150 169 return ret;
151 170 }
152 171  
153   -int run_smartctl_cmd(const string command, const char* disk, string* output)
154   -{
  172 +int run_smartctl_cmd(const string command, const char* disk, string* output) {
155 173 int uid = getuid();
156 174 setreuid(0,0);
157 175  
... ... @@ -161,15 +179,12 @@ int run_smartctl_cmd(const string command, const char* disk, string* output)
161 179 return rc;
162 180 }
163 181  
164   -void printVersion()
165   -{
  182 +void printVersion() {
166 183 cout << "check_smart v" << VERSION << endl << endl;
167 184 }
168 185  
169   -void printHelp(bool longVersion)
170   -{
171   - if(longVersion)
172   - {
  186 +void printHelp(bool longVersion) {
  187 + if(longVersion) {
173 188 printVersion();
174 189 cout << "Checks for pending, reallocated or uncorrectable sectors in disks using SMART" << endl << "WARNING: Requires the setuid bit to be set to run as root" << endl << endl;
175 190 printHelp(false);
... ... @@ -185,8 +200,7 @@ void printHelp(bool longVersion)
185 200 cout << "Usage: " << endl << "check_smart [-hV] DISKS..." << endl << endl;
186 201 }
187 202  
188   -void set_timeout(unsigned int sec)
189   -{
  203 +void set_timeout(unsigned int sec) {
190 204 struct itimerval timer;
191 205 timer.it_value.tv_sec = sec;
192 206 timer.it_value.tv_usec = 0;
... ... @@ -200,14 +214,11 @@ void set_timeout(unsigned int sec)
200 214 sigaction (SIGVTALRM, &sa, 0);
201 215 }
202 216  
203   -int main(int argc, char **argv)
204   -{
  217 +int main(int argc, char **argv) {
205 218 set_timeout(10);
206 219 int c;
207   - while ((c = getopt (argc, argv, "Vh")) != -1)
208   - {
209   - switch(c)
210   - {
  220 + while ((c = getopt (argc, argv, "Vh")) != -1) {
  221 + switch(c) {
211 222 case 'h':
212 223 printHelp(true);
213 224 return OK;
... ... @@ -220,8 +231,7 @@ int main(int argc, char **argv)
220 231 }
221 232 }
222 233  
223   - if(argc == 1)
224   - {
  234 + if(argc == 1) {
225 235 cout << "No disks checked" << endl;
226 236 return 3;
227 237 }
... ... @@ -229,11 +239,9 @@ int main(int argc, char **argv)
229 239 string *results = new string[argc-1];
230 240 int returnCode = OK;
231 241  
232   - for(int i = 1; i < argc; i++)
233   - {
  242 + for(int i = 1; i < argc; i++) {
234 243 int driveType = checkDriveType(argv[i]);
235   - switch(driveType)
236   - {
  244 + switch(driveType) {
237 245 case HDD:
238 246 case SSD:
239 247 break;
... ... @@ -243,8 +251,7 @@ int main(int argc, char **argv)
243 251 break;
244 252 }
245 253  
246   - switch(evalStatus(argv[i],driveType,&(results[i-1])))
247   - {
  254 + switch(evalStatus(argv[i],driveType,&(results[i-1]))) {
248 255 case OK:
249 256 break;
250 257 case WARN:
... ... @@ -253,6 +260,9 @@ int main(int argc, char **argv)
253 260 case CRIT:
254 261 returnCode = CRIT;
255 262 break;
  263 + case UNKN:
  264 + returnCode = UNKN;
  265 + break;
256 266 }
257 267 }
258 268  
... ... @@ -261,8 +271,7 @@ int main(int argc, char **argv)
261 271 else if(returnCode == WARN) {cout << " WARNING - disk status: ";}
262 272 else if(returnCode == CRIT) {cout << " CRITICAL - disk status: ";}
263 273 else if(returnCode == UNKN) {cout << " UNKNOWN - disk status: ";}
264   - for(int i = 0; i < (argc-1); i++)
265   - {
  274 + for(int i = 0; i < (argc-1); i++) {
266 275 cout << results[i];
267 276 if(i != (argc-2)) {cout << ", ";}
268 277 }
... ...
check_smart/check_smart.h
... ... @@ -31,6 +31,7 @@
31 31 #define CURRENT_PENDING_SEC_ID 197
32 32 #define OFFLINE_UNCORRECT_ID 198
33 33 #define WEAR_COUNT_ID 177
  34 +#define MEDIA_WEAROUT_INDICATOR 233
34 35 #define RUNTIME_BAD_BLOCKS_IDD 183
35 36 #define REP_UNCORRECT_ID 187
36 37  
... ... @@ -44,6 +45,7 @@ struct SMARTAttr
44 45 string name;
45 46 int value;
46 47 int severity;
  48 + bool optional;
47 49 }; typedef struct SMARTAttr SMARTAttr;
48 50  
49 51  
... ...