-
Notifications
You must be signed in to change notification settings - Fork 3
/
smart.h
316 lines (281 loc) · 8.14 KB
/
smart.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
/*
* SMART Nagios/Icinga Disk Check
* ------------------------------
*
* License
* -------
* (C) 2015-2017 Simon Murray <[email protected]>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _smart_H_
#define _smart_H_
#include <stdint.h>
#include <iostream>
using namespace std;
/* Class Declarations */
class SmartAttribute;
class SmartThreshold;
/* SMART functions */
const uint8_t SMART_READ_DATA = 0xd0;
const uint8_t SMART_READ_THRESHOLDS = 0xd1;
const uint8_t SMART_READ_LOG = 0xd5;
const uint8_t SMART_RETURN_STATUS = 0xda;
/* SMART off-line status */
const uint8_t SMART_OFF_LINE_STATUS_NEVER_STARTED = 0x00;
const uint8_t SMART_OFF_LINE_STATUS_COMPLETED = 0x02;
const uint8_t SMART_OFF_LINE_STATUS_IN_PROGRESS = 0x03;
const uint8_t SMART_OFF_LINE_STATUS_SUSPENDED = 0x04;
const uint8_t SMART_OFF_LINE_STATUS_ABORTED_HOST = 0x05;
const uint8_t SMART_OFF_LINE_STATUS_ABORTED_DEVICE = 0x06;
/* Attributes in a smart_data page */
const uint8_t SMART_ATTRIBUTE_NUM = 30;
/*
* Struct: smart_attribute
* -----------------------
* Vendor specific SMART attribute as returned by a SMART READ DATA ATA
* command.
*/
typedef struct __attribute__((packed)) {
uint8_t id;
uint16_t flags;
uint8_t value;
uint8_t worst;
uint32_t raw_lo;
uint16_t raw_hi;
uint8_t pad;
} smart_attribute;
/*
* Struct: smart_data
* ------------------
* Standardized ATA SMART data returned by SMART READ DATA
*/
typedef struct __attribute__((packed)) {
uint16_t version;
smart_attribute attributes[SMART_ATTRIBUTE_NUM];
uint8_t offline_data_collection_status;
uint8_t self_test_execution_status;
uint16_t offline_collection_time;
uint8_t vendor_specific1;
uint8_t offline_collection_capability;
uint16_t smart_capability;
uint8_t error_logging_capbility;
uint8_t vendor_specific2;
uint8_t short_self_test_polling_time;
uint8_t extended_self_test_polling_time;
uint8_t conveyance_self_test_polling_time;
uint16_t extended_self_test_routine_polling_time;
uint8_t reserved[9];
uint8_t vendor_specific3[125];
uint8_t checksum;
} smart_data;
/*
* Struct: smart_threshold
* -----------------------
* Vendor specific SMART threshold as returned by a SMART READ THRESHOLDS
* ATA command. This is now obsolete, and should be rolled up by the device
* into and LBA field which can be attained via the SMART RETURN STATUS
* command
*/
typedef struct __attribute__((packed)) {
uint8_t id;
uint8_t threshold;
uint8_t pad[10];
} smart_threshold;
/*
* Struct: smart_thresholds
* ------------------------
* Standardized ATA SMART threshold data returned by SMART READ THRESHOLDS
*/
typedef struct __attribute__((packed)) {
uint16_t version;
smart_threshold thresholds[SMART_ATTRIBUTE_NUM];
uint8_t reserved[149];
uint8_t checksum;
} smart_thresholds;
/*
* Struct: smart_log_directory
* -------------------------
* Structure defining the directory version and number of logs available
* for each address. Index 0 is the version, this is kept as an array to
* enable resue of ATA_LOG_ADDRESS_* macros.
*/
typedef struct {
uint16_t data_blocks[256];
} smart_log_directory;
/*
* Struct: smart_log_command
* -------------------------
* SMART log command
*/
typedef struct __attribute__((packed)) {
uint8_t command;
uint8_t feature;
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
uint32_t lba: 24;
uint32_t count: 8;
#else
uint32_t count: 8;
uint32_t lba: 24;
#endif
uint8_t device;
uint8_t init;
uint32_t timestamp;
} smart_log_command;
/*
* Struct: smart_log_error
* -----------------------
* SMART log error structure defining LBA, device, status, timestamp etc.
*/
typedef struct __attribute__((packed)) {
uint8_t reserved;
uint8_t error;
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
uint32_t lba: 24;
uint32_t count: 8;
#else
uint32_t count: 8;
uint32_t lba: 24;
#endif
uint8_t device;
uint8_t status;
uint8_t extended[19];
uint8_t state;
uint16_t timestamp;
} smart_log_error;
/*
* Struct: smart_log_data
* ----------------------
* Sructure to hold an error and the preceding commands leading up to it
*/
typedef struct __attribute__((packed)) {
smart_log_command command[5];
smart_log_error error;
} smart_log_data;
/*
* Struct: smart_log_summary
* -------------------------
* Top level log summary containing upto 5 errors
*/
typedef struct __attribute__((packed)) {
uint8_t version;
uint8_t index;
smart_log_data data[5];
uint16_t count;
uint8_t reserved[57];
uint8_t checksum;
} smart_log_summary;
/*
* Class: SmartAttribute
* ---------------
* Wraps up the smart attribute and formatting
*/
class SmartAttribute {
public:
/**
* Function: SmartAttribute::SmartAttribute(const smart_attribute&)
* ----------------------------------------------------------------
* Class constructor to munge raw data structures into a sensible format
* attribute: Reference to a smart_attribute structure
*/
SmartAttribute(const smart_attribute& attribute);
/**
* Function SmartAttribute::getID()
* --------------------------------
* Returns the SMART attribute ID
*/
inline uint8_t getID() const {
return id;
}
/**
* Function SmartAttribute::getPreFail()
* -------------------------------------
* Return whether this attribute predicts failure within 24h
*/
inline bool getPreFail() const {
return pre_fail;
}
/**
* Function: SmartAttribute:getRaw()
* ---------------------------------
* Return the sanitised raw value
*/
inline uint64_t getRaw() const {
return raw;
}
/**
* Function: SmartAttribute::idValid()
* -----------------------------------
* Checks whether a SMART ID is valid
*/
inline bool idValid() const {
return id != 0;
}
/**
* Function: SmartAttribute::valueValid()
* --------------------------------------
* Checks whether a SMART value is within the valid limits
*/
inline bool valueValid() const {
return value > 0x0 && value < 0xfe;
}
/**
* Function: SmartAttribute::operator<=(const SmartThreshold&)
* -----------------------------------------------------------
* Compares a value to a threshold
* threshold: Reference to a SmartThreshold object to check against
*/
bool operator<=(const SmartThreshold& threshold) const;
friend ostream& operator<<(ostream& o, const SmartAttribute& id);
private:
uint8_t id;
bool pre_fail;
bool offline;
uint8_t value;
uint64_t raw;
};
/**
* Function: operator<<(ostream&, const SmartAttribute&)
* ----------------------------------------
* Function to dump human readable text to an output stream
* o: Class implmenting std::ostream
* id: Reference to a SmartAttribute class
*/
ostream& operator<<(ostream& o, const SmartAttribute& attribute);
/**
* Class: SmartThreshold
* ---------------------
* Wrapper for a SMART threshold
*/
class SmartThreshold {
public:
/**
* Function: SmartThreshold::SmartThreshold(const smart_threshold&)
* ----------------------------------------------------------------
* Class constructor to create a SmartThreshold object from raw data
* threshold: Reference to a smart_threshold object
*/
SmartThreshold(const smart_threshold& threshold);
/**
* Function: SmartThreshold::getThreshold()
* ----------------------------------------
* Accessor method for the threshold value
*/
inline uint8_t getThreshold() const {
return threshold;
}
private:
uint8_t threshold;
};
#endif//_smart_H_