Commit 75922917e5d1248178427de2e4b8a55ffd667589
1 parent
e89eb607
Fix incorrect attr matching
Some manufacturers do have different meanings for different SMART attr IDs, and some change the name too, so: - We're gonna do matching by name - We're gonna define two attributes with each different name that points to the same attribute - We're gonna define duplicated attributes as optional
Showing
2 changed files
with
48 additions
and
29 deletions
check_smart/check_smart.cpp
... | ... | @@ -42,6 +42,15 @@ int getSmartAttrID(string line) { |
42 | 42 | return id; |
43 | 43 | } |
44 | 44 | |
45 | +std::string getSmartAttrName(std::string line) { | |
46 | + size_t first = line.find_first_not_of(' ', line.find_first_of(' ',line.find_first_not_of(' '))); | |
47 | + size_t last = line.find_first_of(' ', first); | |
48 | + if(first == std::string::npos || last == std::string::npos) { | |
49 | + return ""; | |
50 | + } | |
51 | + return line.substr(first,last-first); | |
52 | +} | |
53 | + | |
45 | 54 | int checkDriveType(const char* disk) { |
46 | 55 | string output = ""; |
47 | 56 | string RRLine = ""; |
... | ... | @@ -70,20 +79,21 @@ int checkDriveType(const char* disk) { |
70 | 79 | return HDD; |
71 | 80 | } |
72 | 81 | |
73 | -map<int,SMARTAttr> prepareAttrMap(int driveType) { | |
74 | - map<int,SMARTAttr> map; | |
75 | - map[REALLOC_SEC_COUNT_ID] = reallocated; | |
76 | - map[REP_UNCORRECT_ID] = rep_uncorrect; | |
82 | +map<std::string, SMARTAttr*> prepareAttrMap(int driveType) { | |
83 | + map<std::string, SMARTAttr*> map; | |
84 | + map[REALLOC_SEC_COUNT_NAME] = &reallocated; | |
85 | + map[REP_UNCORRECT_NAME] = &rep_uncorrect; | |
86 | + map[UNCORRECT_COUNT_NAME] = &rep_uncorrect; | |
77 | 87 | |
78 | 88 | switch(driveType) { |
79 | 89 | case HDD: |
80 | - map[CURRENT_PENDING_SEC_ID] = pending; | |
81 | - map[OFFLINE_UNCORRECT_ID] = off_uncorrect; | |
90 | + map[CURRENT_PENDING_SEC_NAME] = &pending; | |
91 | + map[OFFLINE_UNCORRECT_NAME] = &off_uncorrect; | |
82 | 92 | break; |
83 | 93 | case SSD: |
84 | - map[WEAR_COUNT_ID] = wear; | |
85 | - map[MEDIA_WEAROUT_ID] = wearout; | |
86 | - map[RUNTIME_BAD_BLOCKS_ID] = badblocks; | |
94 | + map[WEAR_COUNT_NAME] = &wear; | |
95 | + map[MEDIA_WEAROUT_NAME] = &wearout; | |
96 | + map[RUNTIME_BAD_BLOCKS_NAME] = &badblocks; | |
87 | 97 | break; |
88 | 98 | } |
89 | 99 | return map; |
... | ... | @@ -99,30 +109,30 @@ int evalStatus(const char* disk, int driveType, string *status) { |
99 | 109 | exit(UNKN); |
100 | 110 | } |
101 | 111 | |
102 | - map<int,SMARTAttr> attrMap = prepareAttrMap(driveType); | |
112 | + map<std::string, SMARTAttr*> attrMap = prepareAttrMap(driveType); | |
103 | 113 | |
104 | 114 | stringstream sstream; |
105 | 115 | sstream.str(output); |
106 | 116 | while(getline(sstream,line)) { |
107 | - for(map<int,SMARTAttr>::iterator it = attrMap.begin(); it != attrMap.end(); ++it) { | |
108 | - int id = it->first; | |
109 | - int attrID = getSmartAttrID(line); | |
110 | - if(attrID == -1) { | |
117 | + for(map<std::string, SMARTAttr*>::iterator it = attrMap.begin(); it != attrMap.end(); ++it) { | |
118 | + std::string name = it->first; | |
119 | + std::string attrName = getSmartAttrName(line); | |
120 | + if(attrName == "") { | |
111 | 121 | continue; |
112 | 122 | } |
113 | - if(getSmartAttrID(line) == id) { | |
114 | - attrMap[id].value = getSmartAttrValue(line, attrMap[id].col); | |
123 | + if(attrName == name) { | |
124 | + attrMap[name]->value = getSmartAttrValue(line, attrMap[name]->col); | |
115 | 125 | } |
116 | 126 | } |
117 | 127 | } |
118 | 128 | int ret = OK; |
119 | 129 | *status = string(disk); |
120 | - for(map<int,SMARTAttr>::iterator it = attrMap.begin(); it != attrMap.end(); ++it) { | |
121 | - int id = it->first; | |
122 | - SMARTAttr attr = it->second; | |
130 | + for(map<std::string, SMARTAttr*>::iterator it = attrMap.begin(); it != attrMap.end(); ++it) { | |
131 | + std::string name = it->first; | |
132 | + SMARTAttr* attr = it->second; | |
123 | 133 | |
124 | - if(attr.value == -1) { | |
125 | - if(attr.optional) { | |
134 | + if(attr->value == -1) { | |
135 | + if(attr->optional) { | |
126 | 136 | continue; |
127 | 137 | } |
128 | 138 | *status = string(disk) + " status UNKNOWN"; |
... | ... | @@ -131,18 +141,18 @@ int evalStatus(const char* disk, int driveType, string *status) { |
131 | 141 | |
132 | 142 | int veredict = 0; |
133 | 143 | |
134 | - if(attr.lower_than) { | |
135 | - if(attr.value < attr.threshold_warn) { | |
144 | + if(attr->lower_than) { | |
145 | + if(attr->value < attr->threshold_warn) { | |
136 | 146 | veredict = WARN; |
137 | 147 | } |
138 | - if(attr.threshold_crit != -1 && attr.value < attr.threshold_crit) { | |
148 | + if(attr->threshold_crit != -1 && attr->value < attr->threshold_crit) { | |
139 | 149 | veredict = CRIT; |
140 | 150 | } |
141 | 151 | } else { |
142 | - if(attr.value > attr.threshold_warn) { | |
152 | + if(attr->value > attr->threshold_warn) { | |
143 | 153 | veredict = WARN; |
144 | 154 | } |
145 | - if(attr.threshold_crit != -1 && attr.value > attr.threshold_crit) { | |
155 | + if(attr->threshold_crit != -1 && attr->value > attr->threshold_crit) { | |
146 | 156 | veredict = CRIT; |
147 | 157 | } |
148 | 158 | } |
... | ... | @@ -159,7 +169,7 @@ int evalStatus(const char* disk, int driveType, string *status) { |
159 | 169 | ret = CRIT; |
160 | 170 | break; |
161 | 171 | } |
162 | - *status += " " + attr.name + ":" + to_string(attr.value); | |
172 | + *status += " " + attr->name + ":" + to_string(attr->value); | |
163 | 173 | } |
164 | 174 | return ret; |
165 | 175 | } | ... | ... |
check_smart/check_smart.h
... | ... | @@ -35,6 +35,15 @@ |
35 | 35 | #define RUNTIME_BAD_BLOCKS_ID 183 |
36 | 36 | #define REP_UNCORRECT_ID 187 |
37 | 37 | |
38 | +#define REALLOC_SEC_COUNT_NAME "Reallocated_Sector_Ct" | |
39 | +#define CURRENT_PENDING_SEC_NAME "Current_Pending_Sector" | |
40 | +#define OFFLINE_UNCORRECT_NAME "Offline_Uncorrectable" | |
41 | +#define WEAR_COUNT_NAME "Wear_Leveling_Count" | |
42 | +#define MEDIA_WEAROUT_NAME "Media_Wearout_Indicator" | |
43 | +#define RUNTIME_BAD_BLOCKS_NAME "Runtime_Bad_Block" | |
44 | +#define REP_UNCORRECT_NAME "Reported_Uncorrect" | |
45 | +#define UNCORRECT_COUNT_NAME "Uncorrectable_Error_Cnt" | |
46 | + | |
38 | 47 | #define HDD 0 |
39 | 48 | #define SSD 1 |
40 | 49 | |
... | ... | @@ -115,7 +124,7 @@ SMARTAttr badblocks = { |
115 | 124 | .value = -1, |
116 | 125 | .threshold_warn = 0, |
117 | 126 | .threshold_crit = 0, |
118 | - .optional = false, | |
127 | + .optional = true, | |
119 | 128 | .col = 9, |
120 | 129 | .lower_than = false, |
121 | 130 | }; |
... | ... | @@ -131,7 +140,7 @@ SMARTAttr rep_uncorrect = { |
131 | 140 | .lower_than = false, |
132 | 141 | }; |
133 | 142 | |
134 | -map<int,SMARTAttr> prepareAttrMap(int driveType); | |
143 | +map<std::string, SMARTAttr*> prepareAttrMap(int driveType); | |
135 | 144 | int getSmartAttrValue(string line); |
136 | 145 | int getSmartAttrID(string line); |
137 | 146 | int run_smartctl_cmd(const string command, const char* disk, string* output); | ... | ... |