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 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);
... ...