Top |
gboolean | bd_smart_check_deps () |
void | bd_smart_close () |
gboolean | bd_smart_init () |
GQuark | bd_smart_error_quark () |
gboolean | bd_smart_is_tech_avail () |
BDSmartATA * | bd_smart_ata_get_info () |
BDSmartATA * | bd_smart_ata_get_info_from_data () |
BDSmartATA * | bd_smart_ata_copy () |
void | bd_smart_ata_free () |
BDSmartATAAttribute * | bd_smart_ata_attribute_copy () |
void | bd_smart_ata_attribute_free () |
BDSmartSCSI * | bd_smart_scsi_get_info () |
void | bd_smart_scsi_free () |
BDSmartSCSI * | bd_smart_scsi_copy () |
gboolean | bd_smart_set_enabled () |
gboolean | bd_smart_device_self_test () |
#define | BD_SMART_ERROR |
enum | BDSmartError |
enum | BDSmartTech |
enum | BDSmartTechMode |
#define | BD_SMART_TYPE_ATA |
#define | BD_SMART_TYPE_ATA_ATTRIBUTE |
BDSmartATAAttribute | |
enum | BDSmartATAAttributeUnit |
enum | BDSmartATAAttributeFlag |
enum | BDSmartATACapabilities |
enum | BDSmartATAOfflineDataCollectionCapabilities |
enum | BDSmartATAOfflineDataCollectionStatus |
enum | BDSmartATASelfTestStatus |
BDSmartATA | |
enum | BDSmartSCSIInformationalException |
enum | BDSmartSCSIBackgroundScanStatus |
BDSmartSCSI | |
enum | BDSmartSelfTestOp |
Plugin for ATA and SCSI/SAS S.M.A.R.T. device reporting and management. For NVMe
health reporting please use the native nvme
plugin.
This libblockdev plugin strives to provide good enough abstraction on top of vastly
different backend implementations. Two plugin implementations are available:
libatasmart
(default) and smartmontools
(experimental).
Not all plugin implementations provide full functionality and it is advised
to use standard libblockdev tech query functions for feature availability testing.
For example, the libatasmart
plugin only provides ATA functionality and error
is returned when any SCSI function is called.
An implementation proven for over a decade, being essentially a port of UDisks code.
The libatasmart
library is reasonably lightweight with minimal dependencies,
light on I/O and consuming C API directly with clearly defined data types.
However essentially no quirks or any drive database is present in the library
(apart from a couple of very old laptop drives).
In contrast to libatasmart, the smartmontools project is a feature-rich implementation supporting specialties like vendor-specific data blocks. It is a considerably heavier implementation I/O-wise due to device type detection and retrieval of more data blocks from the drive.
There's no C API at the moment and the plugin resorts to executing the smartctl
command and parsing its JSON output, that is by nature loosely-defined. This
presents challenges in data type conversions, interpretation of printed values
and volatile JSON key presence. Besides, executing external commands always brings
certain performance overhead and caution is advised when retrieving SMART data
from multiple drives in parallel.
Check BDSmartATAAttribute for the struct members overview first. The plugin public API provides both the implementation-specific attribute names/values as well as unified ('well-known', translated) interpretation that is preferred for general use.
The well_known_name
property follows the libatasmart-style naming -
e.g. 'power-on-hours'
. Unknown or untrusted attributes are either provided
in the form of 'attribute-123'
or by NULL
.
Similarly, value of an attribute is provided in variety of interpretations, subject to availability:
the value
, worst
and threshold
are normalized values in typical S.M.A.R.T. fashion
the value_raw
as a 64-bit untranslated value with no further context
of which bits are actually valid for a particular attribute
the pretty_value_string
as an implementation-specific string representation,
intended for end-user display
the pretty_value
and pretty_value_unit
as a libatasmart-style of unified value/type pair
Both libblockdev plugins strive for best effort of providing accurate values, however there are often challenges ranging from string-to-number conversion, multiple values being unpacked from a single raw number or not having enough context provided by the underlying library for a trusted value interpretation.
It may seem obvious to use numerical attribute ID as an authoritative attribute identifier, however in reality drive vendors tend not to stick with public specifications. Attributes are often reused for vendor-specific values and this differs from model to model even for a single vendor. This is more often the case with SSD drives than traditional HDDs.
Historically it brought confusion and false alarms on user's end and eventually
led to some form of quirk database in most projects. Maintaining such database
is a lifetime task and the only successful effort is the smartmontools' drivedb.h
collection. Quirks are needed for about everything - meaning of a particular
attribute (i.e. a 'well-known' name), interpretation of a raw value, all this
filtered by drive model string and firmware revision.
However even there not everything is consistent and slight variations in a 'well-known' name can be found. Besides, the attribute naming syntax differs from our chosen libatasmart-style form.
For this reason an internal libblockdev translation table has been introduced to ensure a bit of consistency. The translation table is kept conservative, is by no means complete and may get extended in future libblockdev releases. As a result, some attributes may be reported as 'untrusted' or 'unknown'.
The translation table at this point doesn't handle 'moves' where a different attribute ID has been assigned for otherwise well defined attribute.
An experimental drivedb.h
parser is provided for the libatasmart plugin
as an additional tier of validation based on actual drive model + firmware match.
Being a C header file, the drivedb.h
definitions are compiled in the plugin.
There's no support for loading external drivedb.h
file though. This however
only serves for validation. Providing backwards mapping to libatasmart-style
of attributes is considered as a TODO.
There's a big difference in how a drive is accessed. While libatasmart
performs
only very basic device type detection based on parent subsystem as retrieved from
the udev database, smartctl
implements logic to determine which protocol to use,
supporting variety of passthrough mechanisms and interface bridges. Such detection
is not always reliable though, having known issues with dm-multipath
for example.
For this case most plugin functions consume the extra
argument allowing
callers to specify arguments such as --device=
for device type override. This
is only supported by the smartmontools plugin and ignored by the libatasmart
plugin.
As a well kept secret libatasmart has historically supported device type override
via the ID_ATA_SMART_ACCESS
udev property. There's no public C API for this and
libblockdev generally tends to avoid any udev interaction, leaving the burden
to callers.
Valid values for this property include:
'sat16'
: 16 Byte SCSI ATA SAT Passthru
'sat12'
: 12 Byte SCSI ATA SAT Passthru
'linux-ide'
: Native Linux IDE
'sunplus'
: SunPlus USB/ATA bridges
'jmicron'
: JMicron USB/ATA bridges
'none'
: No access method, avoid any I/O and ignore the device
'auto'
: Autodetection based on parent subsystem (default)
A common example to override QEMU ATA device type, which often requires legacy IDE protocol:
1 |
KERNEL=="sd*", ENV{ID_VENDOR}=="ATA", ENV{ID_MODEL}=="QEMU_HARDDISK", ENV{ID_ATA}=="1", ENV{ID_ATA_SMART_ACCESS}="linux-ide" |
An example of blacklisting a USB device, in case of errors caused by reading SMART data:
1 |
ATTRS{idVendor}=="152d", ATTRS{idProduct}=="2329", ENV{ID_ATA_SMART_ACCESS}="none" |
void
bd_smart_close (void
);
Cleans up after the plugin. **This function is called automatically by the library's functions that unload it.**
gboolean
bd_smart_init (void
);
Initializes the plugin. **This function is called automatically by the library's initialization functions.**
gboolean bd_smart_is_tech_avail (BDSmartTech tech
,guint64 mode
,GError **error
);
tech |
the queried tech |
|
mode |
a bit mask of queried modes of operation (BDSmartTechMode) for |
|
error |
place to store error (details about why the |
[out][nullable] |
BDSmartATA * bd_smart_ata_get_info (const gchar *device
,const BDExtraArg **extra
,GError **error
);
Retrieve SMART information from the drive.
device |
device to check. |
|
extra |
extra options to pass through. |
[nullable][array zero-terminated=1] |
error |
place to store error (if any). |
[out][optional] |
ATA SMART log or NULL
in case of an error (with error
set).
Tech category: BD_SMART_TECH_ATA
-BD_SMART_TECH_MODE_INFO
.
[transfer full]
BDSmartATA * bd_smart_ata_get_info_from_data (const guint8 *data
,gsize data_len
,GError **error
);
Retrieve SMART information from the supplied data.
data |
binary data to parse. |
[array length=data_len] |
data_len |
length of the data supplied. |
|
error |
place to store error (if any). |
[out][optional] |
ATA SMART log or NULL
in case of an error (with error
set).
Tech category: BD_SMART_TECH_ATA
-BD_SMART_TECH_MODE_INFO
.
[transfer full]
BDSmartATA *
bd_smart_ata_copy (BDSmartATA *data
);
Creates a new copy of data
.
[skip]
BDSmartATAAttribute *
bd_smart_ata_attribute_copy (BDSmartATAAttribute *attr
);
Creates a new copy of attr
.
[skip]
void
bd_smart_ata_attribute_free (BDSmartATAAttribute *attr
);
Frees attr
.
[skip]
BDSmartSCSI * bd_smart_scsi_get_info (const gchar *device
,const BDExtraArg **extra
,GError **error
);
Retrieve SMART information from SCSI or SAS-compliant drive.
device |
device to check. |
|
extra |
extra options to pass through. |
[nullable][array zero-terminated=1] |
error |
place to store error (if any). |
[out][optional] |
SCSI SMART log or NULL
in case of an error (with error
set).
Tech category: BD_SMART_TECH_SCSI
-BD_SMART_TECH_MODE_INFO
.
[transfer full]
BDSmartSCSI *
bd_smart_scsi_copy (BDSmartSCSI *data
);
Creates a new copy of data
.
[skip]
gboolean bd_smart_set_enabled (const gchar *device
,gboolean enabled
,const BDExtraArg **extra
,GError **error
);
Enables or disables SMART functionality on device.
device |
SMART-capable device. |
|
enabled |
whether to enable or disable the SMART functionality |
|
extra |
extra options to pass through. |
[nullable][array zero-terminated=1] |
error |
place to store error (if any). |
[out][optional] |
TRUE
when the functionality was set successfully or FALSE
in case of an error (with error
set).
Tech category: BD_SMART_TECH_ATA
-BD_SMART_TECH_MODE_INFO
gboolean bd_smart_device_self_test (const gchar *device
,BDSmartSelfTestOp operation
,const BDExtraArg **extra
,GError **error
);
Executes or aborts device self-test.
device |
device to trigger the test on. |
|
operation |
BDSmartSelfTestOp self-test operation. |
|
extra |
extra options to pass through. |
[nullable][array zero-terminated=1] |
error |
place to store error (if any). |
[out][optional] |
TRUE
when the self-test was triggered successfully or FALSE
in case of an error (with error
set).
Tech category: BD_SMART_TECH_ATA
-BD_SMART_TECH_MODE_SELFTEST
#define BD_SMART_TYPE_ATA_ATTRIBUTE (bd_smart_ata_attribute_get_type ())
typedef struct { guint8 id; gchar *name; gchar *well_known_name; gint value; gint worst; gint threshold; gboolean failed_past; gboolean failing_now; guint64 value_raw; guint16 flags; gint64 pretty_value; BDSmartATAAttributeUnit pretty_value_unit; gchar *pretty_value_string; } BDSmartATAAttribute;
Attribute Identifier. |
||
A free-form representation of the attribute name, implementation-dependent (e.g. libatasmart internal strings or smartmontools' drivedb.h names). |
||
Translated well-known attribute name (in libatasmart style, e.g. 'raw-read-error-rate') or |
||
The normalized value or -1 if unknown. |
||
The worst normalized value of -1 if unknown. |
||
The threshold of a normalized value or -1 if unknown. |
||
Indicates a failure that happened in the past (the normalized worst value is below the threshold). |
||
Indicates a failure that is happening now (the normalized value is below the threshold). |
||
The raw value of the attribute. |
||
Bitmask of attribute flags. See BDSmartATAAttributeFlag. |
||
Numerical representation of the parsed raw value, presented in |
||
BDSmartATAAttributeUnit |
The unit of the parsed raw value. |
|
A free-form string representation of the raw value intended for user presentation or |
Pre-failure/advisory bit: If the value of this bit equals zero, an attribute value less than or equal to its corresponding attribute threshold indicates an advisory condition where the usage or age of the device has exceeded its intended design life period. If the value of this bit equals one, an attribute value less than or equal to its corresponding attribute threshold indicates a prefailure condition where imminent loss of data is being predicted. |
||
On-line data collection bit: If the value of this bit equals zero, then the attribute value is updated only during off-line data collection activities. If the value of this bit equals one, then the attribute value is updated during normal operation of the device or during both normal operation and off-line testing. |
||
Performance type bit (vendor specific). |
||
Errorrate type bit (vendor specific). |
||
Eventcount bit (vendor specific). |
||
Selfpereserving bit (vendor specific). |
||
Reserved. |
Offline data collection activity was never started. |
||
Offline data collection activity was completed without error. Indicates a passed test. |
||
Offline data collection activity is in progress. |
||
Offline data collection activity was suspended by an interrupting command from host. |
||
Offline data collection activity was aborted by an interrupting command from host. |
||
Offline data collection activity was aborted by the device with a fatal error. Indicates a failed test. |
||
Offline data collection activity is in a Vendor Specific state. |
||
Offline data collection activity is in a Reserved state. |
The previous self-test routine completed without error or no self-test has ever been run. |
||
The self-test routine was aborted by the host. |
||
The self-test routine was interrupted by the host with a hard or soft reset. |
||
A fatal error or unknown test error occurred while the device was executing its self-test routine and the device was unable to complete the self-test routine. |
||
The previous self-test completed having a test element that failed and the test element that failed is not known. |
||
The previous self-test completed having the electrical element of the test failed. |
||
The previous self-test completed having the servo (and/or seek) element of the test failed. |
||
The previous self-test completed having the read element of the test failed. |
||
The previous self-test completed having a test element that failed and the device is suspected of having handling damage. |
||
Self-test routine in progress. |
typedef struct { gboolean smart_supported; gboolean smart_enabled; gboolean overall_status_passed; BDSmartATAOfflineDataCollectionStatus offline_data_collection_status; gboolean auto_offline_data_collection_enabled; gint offline_data_collection_completion; guint offline_data_collection_capabilities; BDSmartATASelfTestStatus self_test_status; gint self_test_percent_remaining; gint self_test_polling_short; gint self_test_polling_extended; gint self_test_polling_conveyance; guint smart_capabilities; BDSmartATAAttribute **attributes; guint power_on_time; guint64 power_cycle_count; guint temperature; } BDSmartATA;
Indicates that the device has SMART capability. |
||
Indicates that the SMART support is enabled. |
||
|
||
BDSmartATAOfflineDataCollectionStatus |
The offline data collection status. See BDSmartATAOfflineDataCollectionStatus. |
|
|
||
Total time in seconds to complete Offline data collection. |
||
Bitmask of offline data collection capabilities, see BDSmartATAOfflineDataCollectionCapabilities. Only supported with the smartmontools plugin. |
||
BDSmartATASelfTestStatus |
Self-test execution status. See BDSmartATASelfTestStatus. |
|
The percentage remaining of a running self-test. |
||
Short self-test routine recommended polling time in minutes or 0 if not supported. |
||
Extended self-test routine recommended polling time in minutes or 0 if not supported. |
||
Conveyance self-test routine recommended polling time in minutes or 0 if not supported. |
||
Bitmask of device misc. SMART capabilities. See BDSmartATACapabilities. Only supported with the smartmontools plugin. |
||
BDSmartATAAttribute ** |
A list of reported SMART attributes. |
[array zero-terminated=1] |
The count of minutes in power-on state. |
||
The count of full hard disk power on/off cycles. |
||
The current drive temperature in Kelvin or 0 when temperature is not reported. |
typedef struct { gboolean smart_supported; gboolean smart_enabled; gboolean overall_status_passed; BDSmartSCSIInformationalException scsi_ie; guint8 scsi_ie_asc; guint8 scsi_ie_ascq; gchar *scsi_ie_string; BDSmartSCSIBackgroundScanStatus background_scan_status; gdouble background_scan_progress; guint background_scan_runs; guint background_medium_scan_runs; guint read_errors_corrected_eccfast; guint read_errors_corrected_eccdelayed; guint read_errors_corrected_rereads; guint read_errors_corrected_total; guint read_errors_uncorrected; guint64 read_processed_bytes; guint write_errors_corrected_eccfast; guint write_errors_corrected_eccdelayed; guint write_errors_corrected_rewrites; guint write_errors_corrected_total; guint write_errors_uncorrected; guint64 write_processed_bytes; guint start_stop_cycle_count; guint start_stop_cycle_lifetime; guint load_unload_cycle_count; guint load_unload_cycle_lifetime; guint scsi_grown_defect_list; guint power_on_time; gboolean temperature_warning_enabled; guint temperature; guint temperature_drive_trip; } BDSmartSCSI;
Indicates that the device has SMART capability. |
||
Indicates that the SMART support is enabled. |
||
|
||
BDSmartSCSIInformationalException |
The reported SCSI Informational Exception in a simplified form. See BDSmartSCSIInformationalException. |
|
The reported SCSI Informational Exception ASC (Additional Sense Code) value (only values of 0xb - warnings and 0x5d - impending failures are taken in account). |
||
The reported SCSI Informational Exception ASCQ (Additional Sense Code Qualifier) value. |
||
String representation of the current SCSI Informational Exception. |
||
BDSmartSCSIBackgroundScanStatus |
Background scan status, see BDSmartSCSIBackgroundScanStatus. |
|
Percent of a background scan progress. |
||
Number of background scans performed. |
||
Number of background medium scans performed. |
||
Error counter log - read errors corrected by ECC fast. |
||
Error counter log - read errors corrected by ECC delayed. |
||
Error counter log - read errors corrected by rereads. |
||
Error counter log - total read errors corrected. |
||
Error counter log - total uncorrected read errors. |
||
Error counter log - total bytes processed. |
||
Error counter log - write errors corrected by ECC fast. |
||
Error counter log - write errors corrected by ECC delayed. |
||
Error counter log - write errors corrected by rewrites. |
||
Error counter log - total write errors corrected. |
||
Error counter log - total uncorrected write errors. |
||
Error counter log - total bytes processed. |
||
Accumulated start-stop cycles. |
||
Specified cycle count over device lifetime. |
||
Accumulated load-unload cycles. |
||
Specified load-unload count over device lifetime. |
||
Elements in grown defect list. |
||
Accumulated power on time in minutes. |
||
Indicates that temperature warning is enabled. |
||
The current drive temperature in Kelvin or 0 when temperature is not reported. |
||
The drive trip temperature in Kelvin or 0 when temperature is not reported. |
Abort a running SMART self-test. |
||
SMART Immediate Offline Test in background (ATA) or a default self test in foreground (SCSI). |
||
SMART Short Self Test in background (ATA) or "Background short" self-test (SCSI). |
||
SMART Extended Self Test in background (ATA) or "Background long" self-test (SCSI). |
||
SMART Conveyance Self Test in background (ATA only). |