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