## SMART

SMART — S.M.A.R.T. device reporting and management.

## Functions

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 ()

## Types and Values

#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

## Includes

    #include <smart.h>

## Description

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.

#### libatasmart plugin

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

#### smartmontools plugin

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.

#### Attribute naming and value interpretation

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.

#### Attribute validation

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.

#### Device type detection, multipath

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"

## Functions

### bd_smart_check_deps ()

    gboolean
    bd_smart_check_deps (void);

#### Returns

whether the plugin's runtime dependencies are satisfied or not

Function checking plugin's runtime dependencies.

### bd_smart_close ()

    void
    bd_smart_close (void);

Cleans up after the plugin. **This function is called automatically by the library's functions that unload it.**

### bd_smart_init ()

    gboolean
    bd_smart_init (void);

Initializes the plugin. **This function is called automatically by the library's initialization functions.**

### bd_smart_error_quark ()

    GQuark
    bd_smart_error_quark (void);

[skip]

### bd_smart_is_tech_avail ()

    gboolean
    bd_smart_is_tech_avail (BDSmartTech tech,
                            guint64 mode,
                            GError **error);

#### Parameters

tech | the queried tech |
mode | a bit mask of queried modes of operation (BDSmartTechMode) for `tech` |
error | place to store error (details about why the `tech` -`mode` combination is not available). | [out][nullable]

#### Returns

whether the `tech` -`mode` combination is available -- supported by the plugin implementation and having all the runtime dependencies available

### bd_smart_ata_get_info ()

    BDSmartATA *
    bd_smart_ata_get_info (const gchar *device,
                           const BDExtraArg **extra,
                           GError **error);

Retrieve SMART information from the drive.

#### Parameters

device | device to check. |
extra | extra options to pass through. | [nullable][array zero-terminated=1]
error | place to store error (if any). | [out][optional]

#### Returns

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]

### bd_smart_ata_get_info_from_data ()

    BDSmartATA *
    bd_smart_ata_get_info_from_data (const guint8 *data,
                                     gsize data_len,
                                     GError **error);

Retrieve SMART information from the supplied data.

#### Parameters

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]

#### Returns

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]

### bd_smart_ata_copy ()

    BDSmartATA *
    bd_smart_ata_copy (BDSmartATA *data);

Creates a new copy of `data` .

[skip]

#### Parameters

data | `BDSmartATA` to copy. | [nullable]

### bd_smart_ata_free ()

    void
    bd_smart_ata_free (BDSmartATA *data);

Frees `data` .

[skip]

#### Parameters

data | `BDSmartATA` to free. | [nullable]

### bd_smart_ata_attribute_copy ()

    BDSmartATAAttribute *
    bd_smart_ata_attribute_copy (BDSmartATAAttribute *attr);

Creates a new copy of `attr` .

[skip]

#### Parameters

attr | `BDSmartATAAttribute` to copy. | [nullable]

### bd_smart_ata_attribute_free ()

    void
    bd_smart_ata_attribute_free (BDSmartATAAttribute *attr);

Frees `attr` .

[skip]

#### Parameters

attr | `BDSmartATAAttribute` to free. | [nullable]

### bd_smart_scsi_get_info ()

    BDSmartSCSI *
    bd_smart_scsi_get_info (const gchar *device,
                            const BDExtraArg **extra,
                            GError **error);

Retrieve SMART information from SCSI or SAS-compliant drive.

#### Parameters

device | device to check. |
extra | extra options to pass through. | [nullable][array zero-terminated=1]
error | place to store error (if any). | [out][optional]

#### Returns

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]

### bd_smart_scsi_free ()

    void
    bd_smart_scsi_free (BDSmartSCSI *data);

Frees `data` .

[skip]

#### Parameters

data | `BDSmartSCSI` to free. | [nullable]

### bd_smart_scsi_copy ()

    BDSmartSCSI *
    bd_smart_scsi_copy (BDSmartSCSI *data);

Creates a new copy of `data` .

[skip]

#### Parameters

data | `BDSmartSCSI` to copy. | [nullable]

### bd_smart_set_enabled ()

    gboolean
    bd_smart_set_enabled (const gchar *device,
                          gboolean enabled,
                          const BDExtraArg **extra,
                          GError **error);

Enables or disables SMART functionality on device.

#### Parameters

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]

#### Returns

`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`

### bd_smart_device_self_test ()

    gboolean
    bd_smart_device_self_test (const gchar *device,
                               BDSmartSelfTestOp operation,
                               const BDExtraArg **extra,
                               GError **error);

Executes or aborts device self-test.

#### Parameters

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]

#### Returns

`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`

## Types and Values

### BD_SMART_ERROR

    #define             BD_SMART_ERROR

### enum BDSmartError

#### Members

BD_SMART_ERROR_TECH_UNAVAIL | SMART support not available. |
BD_SMART_ERROR_FAILED | General error. |
BD_SMART_ERROR_INVALID_ARGUMENT | Invalid argument. |

### enum BDSmartTech

#### Members

BD_SMART_TECH_ATA |  |
BD_SMART_TECH_SCSI |  |

### enum BDSmartTechMode

#### Members

BD_SMART_TECH_MODE_INFO |  |
BD_SMART_TECH_MODE_SELFTEST |  |

### BD_SMART_TYPE_ATA

    #define BD_SMART_TYPE_ATA (bd_smart_ata_get_type ())

### BD_SMART_TYPE_ATA_ATTRIBUTE

    #define BD_SMART_TYPE_ATA_ATTRIBUTE (bd_smart_ata_attribute_get_type ())

### BDSmartATAAttribute

    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;

#### Members

guint8 `id`; | Attribute Identifier. |
gchar *`name`; | A free-form representation of the attribute name, implementation-dependent (e.g. libatasmart internal strings or smartmontools' drivedb.h names). |
gchar *`well_known_name`; | Translated well-known attribute name (in libatasmart style, e.g. 'raw-read-error-rate') or `NULL` in case of unknown, untrusted or vendor-specific value. |
gint `value`; | The normalized value or -1 if unknown. |
gint `worst`; | The worst normalized value of -1 if unknown. |
gint `threshold`; | The threshold of a normalized value or -1 if unknown. |
gboolean `failed_past`; | Indicates a failure that happened in the past (the normalized worst value is below the threshold). |
gboolean `failing_now`; | Indicates a failure that is happening now (the normalized value is below the threshold). |
guint64 `value_raw`; | The raw value of the attribute. |
guint16 `flags`; | Bitmask of attribute flags. See BDSmartATAAttributeFlag. |
gint64 `pretty_value`; | Numerical representation of the parsed raw value, presented in `pretty_value_unit` units. |
BDSmartATAAttributeUnit `pretty_value_unit`; | The unit of the parsed raw value. |
gchar *`pretty_value_string`; | A free-form string representation of the raw value intended for user presentation or `NULL`. |

### enum BDSmartATAAttributeUnit

#### Members

BD_SMART_ATA_ATTRIBUTE_UNIT_UNKNOWN | Unknown. |
BD_SMART_ATA_ATTRIBUTE_UNIT_NONE | Dimensionless value. |
BD_SMART_ATA_ATTRIBUTE_UNIT_MSECONDS | Milliseconds. |
BD_SMART_ATA_ATTRIBUTE_UNIT_SECTORS | Sectors. |
BD_SMART_ATA_ATTRIBUTE_UNIT_MKELVIN | Millikelvin. |
BD_SMART_ATA_ATTRIBUTE_UNIT_SMALL_PERCENT | Percentage with 3 decimal points. |
BD_SMART_ATA_ATTRIBUTE_UNIT_PERCENT | Integer percentage. |
BD_SMART_ATA_ATTRIBUTE_UNIT_MB | Megabytes. |

### enum BDSmartATAAttributeFlag

#### Members

BD_SMART_ATA_ATTRIBUTE_FLAG_PREFAILURE

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.

BD_SMART_ATA_ATTRIBUTE_FLAG_ONLINE | 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. |
BD_SMART_ATA_ATTRIBUTE_FLAG_PERFORMANCE | Performance type bit (vendor specific). |
BD_SMART_ATA_ATTRIBUTE_FLAG_ERROR_RATE | Errorrate type bit (vendor specific). |
BD_SMART_ATA_ATTRIBUTE_FLAG_EVENT_COUNT | Eventcount bit (vendor specific). |
BD_SMART_ATA_ATTRIBUTE_FLAG_SELF_PRESERVING | Selfpereserving bit (vendor specific). |
BD_SMART_ATA_ATTRIBUTE_FLAG_OTHER | Reserved. |

### enum BDSmartATACapabilities

#### Members

BD_SMART_ATA_CAP_ATTRIBUTE_AUTOSAVE | Saves SMART data before entering power-saving mode. |
BD_SMART_ATA_CAP_AUTOSAVE_TIMER | Supports SMART auto save timer. |
BD_SMART_ATA_CAP_ERROR_LOGGING | Error logging supported. |
BD_SMART_ATA_CAP_GP_LOGGING | General Purpose Logging supported. |

### enum BDSmartATAOfflineDataCollectionCapabilities

#### Members

BD_SMART_ATA_OFFLINE_DATA_COLLECTION_CAP_NOT_SUPPORTED | Offline data collection not supported. |
BD_SMART_ATA_OFFLINE_DATA_COLLECTION_CAP_EXEC_OFFLINE_IMMEDIATE | Execute Offline Immediate function supported. |
BD_SMART_ATA_OFFLINE_DATA_COLLECTION_CAP_OFFLINE_ABORT | Abort Offline collection upon new command. |
BD_SMART_ATA_OFFLINE_DATA_COLLECTION_CAP_OFFLINE_SURFACE_SCAN | Offline surface scan supported. |
BD_SMART_ATA_OFFLINE_DATA_COLLECTION_CAP_SELF_TEST | Self-test supported. |
BD_SMART_ATA_OFFLINE_DATA_COLLECTION_CAP_CONVEYANCE_SELF_TEST | Conveyance Self-test supported. |
BD_SMART_ATA_OFFLINE_DATA_COLLECTION_CAP_SELECTIVE_SELF_TEST | Selective Self-test supported. |

### enum BDSmartATAOfflineDataCollectionStatus

#### Members

BD_SMART_ATA_OFFLINE_DATA_COLLECTION_STATUS_NEVER_STARTED | Offline data collection activity was never started. |
BD_SMART_ATA_OFFLINE_DATA_COLLECTION_STATUS_NO_ERROR | Offline data collection activity was completed without error. Indicates a passed test. |
BD_SMART_ATA_OFFLINE_DATA_COLLECTION_STATUS_IN_PROGRESS | Offline data collection activity is in progress. |
BD_SMART_ATA_OFFLINE_DATA_COLLECTION_STATUS_SUSPENDED_INTR | Offline data collection activity was suspended by an interrupting command from host. |
BD_SMART_ATA_OFFLINE_DATA_COLLECTION_STATUS_ABORTED_INTR | Offline data collection activity was aborted by an interrupting command from host. |
BD_SMART_ATA_OFFLINE_DATA_COLLECTION_STATUS_ABORTED_ERROR | Offline data collection activity was aborted by the device with a fatal error. Indicates a failed test. |
BD_SMART_ATA_OFFLINE_DATA_COLLECTION_STATUS_VENDOR_SPECIFIC | Offline data collection activity is in a Vendor Specific state. |
BD_SMART_ATA_OFFLINE_DATA_COLLECTION_STATUS_RESERVED | Offline data collection activity is in a Reserved state. |

### enum BDSmartATASelfTestStatus

#### Members

BD_SMART_ATA_SELF_TEST_STATUS_COMPLETED_NO_ERROR | The previous self-test routine completed without error or no self-test has ever been run. |
BD_SMART_ATA_SELF_TEST_STATUS_ABORTED_HOST | The self-test routine was aborted by the host. |
BD_SMART_ATA_SELF_TEST_STATUS_INTR_HOST_RESET | The self-test routine was interrupted by the host with a hard or soft reset. |
BD_SMART_ATA_SELF_TEST_STATUS_ERROR_FATAL | 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. |
BD_SMART_ATA_SELF_TEST_STATUS_ERROR_UNKNOWN | The previous self-test completed having a test element that failed and the test element that failed is not known. |
BD_SMART_ATA_SELF_TEST_STATUS_ERROR_ELECTRICAL | The previous self-test completed having the electrical element of the test failed. |
BD_SMART_ATA_SELF_TEST_STATUS_ERROR_SERVO | The previous self-test completed having the servo (and/or seek) element of the test failed. |
BD_SMART_ATA_SELF_TEST_STATUS_ERROR_READ | The previous self-test completed having the read element of the test failed. |
BD_SMART_ATA_SELF_TEST_STATUS_ERROR_HANDLING | The previous self-test completed having a test element that failed and the device is suspected of having handling damage. |
BD_SMART_ATA_SELF_TEST_STATUS_IN_PROGRESS | Self-test routine in progress. |

### BDSmartATA

    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;

#### Members

gboolean `smart_supported`; | Indicates that the device has SMART capability. |
gboolean `smart_enabled`; | Indicates that the SMART support is enabled. |
gboolean `overall_status_passed`; | `TRUE` if the device SMART overall-health self-assessment test result has passed. |
BDSmartATAOfflineDataCollectionStatus `offline_data_collection_status`; | The offline data collection status. See BDSmartATAOfflineDataCollectionStatus. |
gboolean `auto_offline_data_collection_enabled`; | `TRUE` if Automatic Offline Data Collection is enabled. Only supported with the smartmontools plugin. |
gint `offline_data_collection_completion`; | Total time in seconds to complete Offline data collection. |
guint `offline_data_collection_capabilities`; | Bitmask of offline data collection capabilities, see BDSmartATAOfflineDataCollectionCapabilities. Only supported with the smartmontools plugin. |
BDSmartATASelfTestStatus `self_test_status`; | Self-test execution status. See BDSmartATASelfTestStatus. |
gint `self_test_percent_remaining`; | The percentage remaining of a running self-test. |
gint `self_test_polling_short`; | Short self-test routine recommended polling time in minutes or 0 if not supported. |
gint `self_test_polling_extended`; | Extended self-test routine recommended polling time in minutes or 0 if not supported. |
gint `self_test_polling_conveyance`; | Conveyance self-test routine recommended polling time in minutes or 0 if not supported. |
guint `smart_capabilities`; | Bitmask of device misc. SMART capabilities. See BDSmartATACapabilities. Only supported with the smartmontools plugin. |
BDSmartATAAttribute **`attributes`; | A list of reported SMART attributes. | [array zero-terminated=1]
guint `power_on_time`; | The count of minutes in power-on state. |
guint64 `power_cycle_count`; | The count of full hard disk power on/off cycles. |
guint `temperature`; | The current drive temperature in Kelvin or 0 when temperature is not reported. |

### enum BDSmartSCSIInformationalException

#### Members

BD_SMART_SCSI_INFORMATIONAL_EXCEPTION_NONE | No SCSI Informational Exception raised. |
BD_SMART_SCSI_INFORMATIONAL_EXCEPTION_ABORTED_COMMAND | Warning - aborted command [asc 0x0b, ascq 0x00]. |
BD_SMART_SCSI_INFORMATIONAL_EXCEPTION_TEMPERATURE_EXCEEDED | Warning - specified temperature exceeded [asc 0x0b, ascq 0x01]. |
BD_SMART_SCSI_INFORMATIONAL_EXCEPTION_ENCLOSURE_DEGRADED | Warning - enclosure degraded [asc 0x0b, ascq 0x02]. |
BD_SMART_SCSI_INFORMATIONAL_EXCEPTION_BACKGROUND_SELFTEST_FAILED | Warning - background self-test failed [asc 0x0b, ascq 0x03]. |
BD_SMART_SCSI_INFORMATIONAL_EXCEPTION_BACKGROUND_PRESCAN_MEDIUM_ERROR | Warning - background pre-scan detected medium error [asc 0x0b, ascq 0x04]. |
BD_SMART_SCSI_INFORMATIONAL_EXCEPTION_BACKGROUND_SCAN_MEDIUM_ERROR | Warning - background medium scan detected medium error [asc 0x0b, ascq 0x05]. |
BD_SMART_SCSI_INFORMATIONAL_EXCEPTION_NV_CACHE_VOLATILE | Warning - non-volatile cache now volatile [asc 0x0b, ascq 0x06]. |
BD_SMART_SCSI_INFORMATIONAL_EXCEPTION_NV_CACHE_DEGRADED_POWER | Warning - degraded power to non-volatile cache [asc 0x0b, ascq 0x07]. |
BD_SMART_SCSI_INFORMATIONAL_EXCEPTION_POWER_LOSS_EXPECTED | Warning - power loss expected [asc 0x0b, ascq 0x08]. |
BD_SMART_SCSI_INFORMATIONAL_EXCEPTION_STATISTICS_NOTIFICATION | Warning - device statistics notification active [asc 0x0b, ascq 0x09]. |
BD_SMART_SCSI_INFORMATIONAL_EXCEPTION_HIGH_CRITICAL_TEMP | Warning - high critical temperature limit exceeded [asc 0x0b, ascq 0x0a]. |
BD_SMART_SCSI_INFORMATIONAL_EXCEPTION_LOW_CRITICAL_TEMP | Warning - low critical temperature limit exceeded [asc 0x0b, ascq 0x0b]. |
BD_SMART_SCSI_INFORMATIONAL_EXCEPTION_HIGH_OPERATING_TEMP | Warning - high operating temperature limit exceeded [asc 0x0b, ascq 0x0c]. |
BD_SMART_SCSI_INFORMATIONAL_EXCEPTION_LOW_OPERATING_TEMP | Warning - low operating temperature limit exceeded [asc 0x0b, ascq 0x0d]. |
BD_SMART_SCSI_INFORMATIONAL_EXCEPTION_HIGH_CRITICAL_HUMIDITY | Warning - high critical humidity limit exceeded [asc 0x0b, ascq 0x0e]. |
BD_SMART_SCSI_INFORMATIONAL_EXCEPTION_LOW_CRITICAL_HUMIDITY | Warning - low critical humidity limit exceeded [asc 0x0b, ascq 0x0f]. |
BD_SMART_SCSI_INFORMATIONAL_EXCEPTION_HIGH_OPERATING_HUMIDITY | Warning - high operating humidity limit exceeded [asc 0x0b, ascq 0x10]. |
BD_SMART_SCSI_INFORMATIONAL_EXCEPTION_LOW_OPERATING_HUMIDITY | Warning - low operating humidity limit exceeded [asc 0x0b, ascq 0x11]. |
BD_SMART_SCSI_INFORMATIONAL_EXCEPTION_MICROCODE_SECURITY_RISK | Warning - microcode security at risk [asc 0x0b, ascq 0x12]. |
BD_SMART_SCSI_INFORMATIONAL_EXCEPTION_MICROCODE_SIGNATURE_VALIDATION_FAILURE | Warning - microcode digital signature validation failure [asc 0x0b, ascq 0x13]. |
BD_SMART_SCSI_INFORMATIONAL_EXCEPTION_PHYSICAL_ELEMENT_STATUS_CHANGE | Warning - physical element status change [asc 0x0b, ascq 0x14]. |
BD_SMART_SCSI_INFORMATIONAL_EXCEPTION_FAILURE_PREDICTION_THRESH | Failure prediction threshold exceeded [asc 0x5d, ascq 0x00, ascq 0xff]. |
BD_SMART_SCSI_INFORMATIONAL_EXCEPTION_MEDIA_FAILURE_PREDICTION_THRESH | Media failure prediction threshold exceeded [asc 0x5d, ascq 0x01]. |
BD_SMART_SCSI_INFORMATIONAL_EXCEPTION_LOGICAL_UNIT_FAILURE_PREDICTION_THRESH | Logical unit failure prediction threshold exceeded [asc 0x5d, ascq 0x02]. |
BD_SMART_SCSI_INFORMATIONAL_EXCEPTION_SPARE_EXHAUSTION_PREDICTION_THRESH | Spare area exhaustion prediction threshold exceeded [asc 0x5d, ascq 0x03]. |
BD_SMART_SCSI_INFORMATIONAL_EXCEPTION_HARDWARE_IMPENDING_FAILURE | Hardware impending failure [asc 0x5d, ascq 0x10..0x1d]. |
BD_SMART_SCSI_INFORMATIONAL_EXCEPTION_CONTROLLER_IMPENDING_FAILURE | Controller impending failure [asc 0x5d, ascq 0x20..0x2c]. |
BD_SMART_SCSI_INFORMATIONAL_EXCEPTION_DATA_CHANNEL_IMPENDING_FAILURE | Data channel impending failure [asc 0x5d, ascq 0x30..0x3c]. |
BD_SMART_SCSI_INFORMATIONAL_EXCEPTION_SERVO_IMPENDING_FAILURE | Servo impending failure [asc 0x5d, ascq 0x40..0x4c]. |
BD_SMART_SCSI_INFORMATIONAL_EXCEPTION_SPINDLE_IMPENDING_FAILURE | Spindle impending failure [asc 0x5d, ascq 0x50..0x5c]. |
BD_SMART_SCSI_INFORMATIONAL_EXCEPTION_FIRMWARE_IMPENDING_FAILURE | Firmware impending failure [asc 0x5d, ascq 0x60..0x6c]. |
BD_SMART_SCSI_INFORMATIONAL_EXCEPTION_MEDIA_ENDURANCE_LIMIT | Media impending failure endurance limit met [asc 0x5d, ascq 0x73]. |
BD_SMART_SCSI_INFORMATIONAL_EXCEPTION_UNSPECIFIED | Unspecified warning. |

### enum BDSmartSCSIBackgroundScanStatus

#### Members

BD_SMART_SCSI_BACKGROUND_SCAN_STATUS_NO_SCANS_ACTIVE | No scans active. |
BD_SMART_SCSI_BACKGROUND_SCAN_STATUS_SCAN_ACTIVE | Scan is active. |
BD_SMART_SCSI_BACKGROUND_SCAN_STATUS_PRESCAN_ACTIVE | Pre-scan is active. |
BD_SMART_SCSI_BACKGROUND_SCAN_STATUS_HALTED_ERROR_FATAL | Halted due to fatal error. |
BD_SMART_SCSI_BACKGROUND_SCAN_STATUS_HALTED_PATTERN_VENDOR_SPECIFIC | Halted due to a vendor specific pattern of error. |
BD_SMART_SCSI_BACKGROUND_SCAN_STATUS_HALTED_ERROR_PLIST | Halted due to medium formatted without P-List. |
BD_SMART_SCSI_BACKGROUND_SCAN_STATUS_HALTED_VENDOR_SPECIFIC | Halted - vendor specific cause. |
BD_SMART_SCSI_BACKGROUND_SCAN_STATUS_HALTED_TEMPERATURE | Halted due to temperature out of range. |
BD_SMART_SCSI_BACKGROUND_SCAN_STATUS_BMS_TIMER | Waiting until BMS interval timer expires. |

### BDSmartSCSI

    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;

#### Members

gboolean `smart_supported`; | Indicates that the device has SMART capability. |
gboolean `smart_enabled`; | Indicates that the SMART support is enabled. |
gboolean `overall_status_passed`; | `TRUE` if the device SMART overall-health self-assessment test result has passed, `FALSE` otherwise with `scsi_ie` fields set. |
BDSmartSCSIInformationalException `scsi_ie`; | The reported SCSI Informational Exception in a simplified form. See BDSmartSCSIInformationalException. |
guint8 `scsi_ie_asc`; | The reported SCSI Informational Exception ASC (Additional Sense Code) value (only values of 0xb - warnings and 0x5d - impending failures are taken in account). |
guint8 `scsi_ie_ascq`; | The reported SCSI Informational Exception ASCQ (Additional Sense Code Qualifier) value. |
gchar *`scsi_ie_string`; | String representation of the current SCSI Informational Exception. |
BDSmartSCSIBackgroundScanStatus `background_scan_status`; | Background scan status, see BDSmartSCSIBackgroundScanStatus. |
gdouble `background_scan_progress`; | Percent of a background scan progress. |
guint `background_scan_runs`; | Number of background scans performed. |
guint `background_medium_scan_runs`; | Number of background medium scans performed. |
guint `read_errors_corrected_eccfast`; | Error counter log - read errors corrected by ECC fast. |
guint `read_errors_corrected_eccdelayed`; | Error counter log - read errors corrected by ECC delayed. |
guint `read_errors_corrected_rereads`; | Error counter log - read errors corrected by rereads. |
guint `read_errors_corrected_total`; | Error counter log - total read errors corrected. |
guint `read_errors_uncorrected`; | Error counter log - total uncorrected read errors. |
guint64 `read_processed_bytes`; | Error counter log - total bytes processed. |
guint `write_errors_corrected_eccfast`; | Error counter log - write errors corrected by ECC fast. |
guint `write_errors_corrected_eccdelayed`; | Error counter log - write errors corrected by ECC delayed. |
guint `write_errors_corrected_rewrites`; | Error counter log - write errors corrected by rewrites. |
guint `write_errors_corrected_total`; | Error counter log - total write errors corrected. |
guint `write_errors_uncorrected`; | Error counter log - total uncorrected write errors. |
guint64 `write_processed_bytes`; | Error counter log - total bytes processed. |
guint `start_stop_cycle_count`; | Accumulated start-stop cycles. |
guint `start_stop_cycle_lifetime`; | Specified cycle count over device lifetime. |
guint `load_unload_cycle_count`; | Accumulated load-unload cycles. |
guint `load_unload_cycle_lifetime`; | Specified load-unload count over device lifetime. |
guint `scsi_grown_defect_list`; | Elements in grown defect list. |
guint `power_on_time`; | Accumulated power on time in minutes. |
gboolean `temperature_warning_enabled`; | Indicates that temperature warning is enabled. |
guint `temperature`; | The current drive temperature in Kelvin or 0 when temperature is not reported. |
guint `temperature_drive_trip`; | The drive trip temperature in Kelvin or 0 when temperature is not reported. |

### enum BDSmartSelfTestOp

#### Members

BD_SMART_SELF_TEST_OP_ABORT | Abort a running SMART self-test. |
BD_SMART_SELF_TEST_OP_OFFLINE | SMART Immediate Offline Test in background (ATA) or a default self test in foreground (SCSI). |
BD_SMART_SELF_TEST_OP_SHORT | SMART Short Self Test in background (ATA) or "Background short" self-test (SCSI). |
BD_SMART_SELF_TEST_OP_LONG | SMART Extended Self Test in background (ATA) or "Background long" self-test (SCSI). |
BD_SMART_SELF_TEST_OP_CONVEYANCE | SMART Conveyance Self Test in background (ATA only). |