Commit 75922917e5d1248178427de2e4b8a55ffd667589

Authored by Imanol-Mikel Barba Sabariego
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
check_smart/check_smart.cpp
@@ -42,6 +42,15 @@ int getSmartAttrID(string line) { @@ -42,6 +42,15 @@ int getSmartAttrID(string line) {
42 return id; 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 int checkDriveType(const char* disk) { 54 int checkDriveType(const char* disk) {
46 string output = ""; 55 string output = "";
47 string RRLine = ""; 56 string RRLine = "";
@@ -70,20 +79,21 @@ int checkDriveType(const char* disk) { @@ -70,20 +79,21 @@ int checkDriveType(const char* disk) {
70 return HDD; 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 switch(driveType) { 88 switch(driveType) {
79 case HDD: 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 break; 92 break;
83 case SSD: 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 break; 97 break;
88 } 98 }
89 return map; 99 return map;
@@ -99,30 +109,30 @@ int evalStatus(const char* disk, int driveType, string *status) { @@ -99,30 +109,30 @@ int evalStatus(const char* disk, int driveType, string *status) {
99 exit(UNKN); 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 stringstream sstream; 114 stringstream sstream;
105 sstream.str(output); 115 sstream.str(output);
106 while(getline(sstream,line)) { 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 continue; 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 int ret = OK; 128 int ret = OK;
119 *status = string(disk); 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 continue; 136 continue;
127 } 137 }
128 *status = string(disk) + " status UNKNOWN"; 138 *status = string(disk) + " status UNKNOWN";
@@ -131,18 +141,18 @@ int evalStatus(const char* disk, int driveType, string *status) { @@ -131,18 +141,18 @@ int evalStatus(const char* disk, int driveType, string *status) {
131 141
132 int veredict = 0; 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 veredict = WARN; 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 veredict = CRIT; 149 veredict = CRIT;
140 } 150 }
141 } else { 151 } else {
142 - if(attr.value > attr.threshold_warn) { 152 + if(attr->value > attr->threshold_warn) {
143 veredict = WARN; 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 veredict = CRIT; 156 veredict = CRIT;
147 } 157 }
148 } 158 }
@@ -159,7 +169,7 @@ int evalStatus(const char* disk, int driveType, string *status) { @@ -159,7 +169,7 @@ int evalStatus(const char* disk, int driveType, string *status) {
159 ret = CRIT; 169 ret = CRIT;
160 break; 170 break;
161 } 171 }
162 - *status += " " + attr.name + ":" + to_string(attr.value); 172 + *status += " " + attr->name + ":" + to_string(attr->value);
163 } 173 }
164 return ret; 174 return ret;
165 } 175 }
check_smart/check_smart.h
@@ -35,6 +35,15 @@ @@ -35,6 +35,15 @@
35 #define RUNTIME_BAD_BLOCKS_ID 183 35 #define RUNTIME_BAD_BLOCKS_ID 183
36 #define REP_UNCORRECT_ID 187 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 #define HDD 0 47 #define HDD 0
39 #define SSD 1 48 #define SSD 1
40 49
@@ -115,7 +124,7 @@ SMARTAttr badblocks = { @@ -115,7 +124,7 @@ SMARTAttr badblocks = {
115 .value = -1, 124 .value = -1,
116 .threshold_warn = 0, 125 .threshold_warn = 0,
117 .threshold_crit = 0, 126 .threshold_crit = 0,
118 - .optional = false, 127 + .optional = true,
119 .col = 9, 128 .col = 9,
120 .lower_than = false, 129 .lower_than = false,
121 }; 130 };
@@ -131,7 +140,7 @@ SMARTAttr rep_uncorrect = { @@ -131,7 +140,7 @@ SMARTAttr rep_uncorrect = {
131 .lower_than = false, 140 .lower_than = false,
132 }; 141 };
133 142
134 -map<int,SMARTAttr> prepareAttrMap(int driveType); 143 +map<std::string, SMARTAttr*> prepareAttrMap(int driveType);
135 int getSmartAttrValue(string line); 144 int getSmartAttrValue(string line);
136 int getSmartAttrID(string line); 145 int getSmartAttrID(string line);
137 int run_smartctl_cmd(const string command, const char* disk, string* output); 146 int run_smartctl_cmd(const string command, const char* disk, string* output);