Commit 47c3e15d11b8888174b1b6e4bf202399b273ac94
1 parent
da7c8f92
Changed code style. Added 'optional' attribute field and another attribute for Intel Enterprise SSDs
Showing
2 changed files
with
74 additions
and
63 deletions
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<int,SMARTAttr> prepareAttrMap(int driveType) | @@ -79,16 +83,25 @@ map<int,SMARTAttr> 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<int,SMARTAttr> prepareAttrMap(int driveType) | @@ -96,14 +109,12 @@ map<int,SMARTAttr> 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 |