LCOV - code coverage report
Current view: top level - lib/plugin_apis - smart.c (source / functions) Coverage Total Hit
Test: libblockdev Coverage Report Lines: 62.1 % 153 95
Test Date: 2026-01-26 13:19:28 Functions: 66.7 % 24 16
Legend: Lines: hit not hit

            Line data    Source code
       1          133 : GQuark  bd_smart_error_quark (void) {
       2          133 :         return g_quark_from_static_string ("g-bd-smart-error-quark");
       3              : }
       4              : 
       5              : /**
       6              :  * BDSmartATAAttribute:
       7              :  * @id: Attribute Identifier.
       8              :  * @name: A free-form representation of the attribute name, implementation-dependent (e.g. libatasmart internal strings or smartmontools' drivedb.h names).
       9              :  * @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.
      10              :  * @value: The normalized value or -1 if unknown.
      11              :  * @worst: The worst normalized value of -1 if unknown.
      12              :  * @threshold: The threshold of a normalized value or -1 if unknown.
      13              :  * @failed_past: Indicates a failure that happened in the past (the normalized worst value is below the threshold).
      14              :  * @failing_now: Indicates a failure that is happening now (the normalized value is below the threshold).
      15              :  * @value_raw: The raw value of the attribute.
      16              :  * @flags: Bitmask of attribute flags. See #BDSmartATAAttributeFlag.
      17              :  * @pretty_value: Numerical representation of the parsed raw value, presented in @pretty_value_unit units.
      18              :  * @pretty_value_unit: The unit of the parsed raw value.
      19              :  * @pretty_value_string: A free-form string representation of the raw value intended for user presentation or %NULL.
      20              :  */
      21              : /**
      22              :  * bd_smart_ata_attribute_free: (skip)
      23              :  * @attr: (nullable): %BDSmartATAAttribute to free
      24              :  *
      25              :  * Frees @attr.
      26              :  */
      27         1419 : void  bd_smart_ata_attribute_free (BDSmartATAAttribute *attr) {
      28         1419 :         if (attr == NULL)
      29            0 :         return;
      30         1419 :     g_free (attr->name);
      31         1419 :     g_free (attr->well_known_name);
      32         1419 :     g_free (attr->pretty_value_string);
      33         1419 :     g_free (attr);
      34              : }
      35              : 
      36              : /**
      37              :  * bd_smart_ata_attribute_copy: (skip)
      38              :  * @attr: (nullable): %BDSmartATAAttribute to copy
      39              :  *
      40              :  * Creates a new copy of @attr.
      41              :  */
      42          944 : BDSmartATAAttribute * bd_smart_ata_attribute_copy (BDSmartATAAttribute *attr) {
      43              :         BDSmartATAAttribute *new_attr;
      44              : 
      45          944 :     if (attr == NULL)
      46            0 :         return NULL;
      47              : 
      48          944 :     new_attr = g_new0 (BDSmartATAAttribute, 1);
      49          944 :     memcpy (new_attr, attr, sizeof (BDSmartATAAttribute));
      50          944 :     new_attr->name = g_strdup (attr->name);
      51          944 :     new_attr->well_known_name = g_strdup (attr->well_known_name);
      52          944 :     new_attr->pretty_value_string = g_strdup (attr->pretty_value_string);
      53              : 
      54          944 :     return new_attr;
      55              : }
      56              : 
      57         2362 : GType  bd_smart_ata_attribute_get_type () {
      58              :         static GType type = 0;
      59              : 
      60         2362 :     if (G_UNLIKELY (type == 0)) {
      61            1 :         type = g_boxed_type_register_static ("BDSmartATAAttribute",
      62              :                                              (GBoxedCopyFunc) bd_smart_ata_attribute_copy,
      63              :                                              (GBoxedFreeFunc) bd_smart_ata_attribute_free);
      64              :     }
      65         2362 :     return type;
      66              : }
      67              : 
      68              : /**
      69              :  * BDSmartATA:
      70              :  * @smart_supported: Indicates that the device has SMART capability.
      71              :  * @smart_enabled: Indicates that the SMART support is enabled.
      72              :  * @overall_status_passed: %TRUE if the device SMART overall-health self-assessment test result has passed.
      73              :  * @offline_data_collection_status: The offline data collection status. See #BDSmartATAOfflineDataCollectionStatus.
      74              :  * @auto_offline_data_collection_enabled: %TRUE if Automatic Offline Data Collection is enabled. Only supported with the smartmontools plugin.
      75              :  * @offline_data_collection_completion: Total time in seconds to complete Offline data collection.
      76              :  * @offline_data_collection_capabilities: Bitmask of offline data collection capabilities, see #BDSmartATAOfflineDataCollectionCapabilities. Only supported with the smartmontools plugin.
      77              :  * @self_test_status: Self-test execution status. See #BDSmartATASelfTestStatus.
      78              :  * @self_test_percent_remaining: The percentage remaining of a running self-test.
      79              :  * @self_test_polling_short: Short self-test routine recommended polling time in minutes or 0 if not supported.
      80              :  * @self_test_polling_extended: Extended self-test routine recommended polling time in minutes or 0 if not supported.
      81              :  * @self_test_polling_conveyance: Conveyance self-test routine recommended polling time in minutes or 0 if not supported.
      82              :  * @smart_capabilities: Bitmask of device misc. SMART capabilities. See #BDSmartATACapabilities. Only supported with the smartmontools plugin.
      83              :  * @attributes: (array zero-terminated=1): A list of reported SMART attributes.
      84              :  * @power_on_time: The count of minutes in power-on state.
      85              :  * @power_cycle_count: The count of full hard disk power on/off cycles.
      86              :  * @temperature: The current drive temperature in Kelvin or 0 when temperature is not reported.
      87              :  */
      88              : /**
      89              :  * bd_smart_ata_free: (skip)
      90              :  * @data: (nullable): %BDSmartATA to free
      91              :  *
      92              :  * Frees @data.
      93              :  */
      94           30 : void  bd_smart_ata_free (BDSmartATA *data) {
      95              :         BDSmartATAAttribute **attr;
      96              : 
      97           30 :     if (data == NULL)
      98            0 :         return;
      99              : 
     100          505 :     for (attr = data->attributes; attr && *attr; attr++)
     101          475 :         bd_smart_ata_attribute_free (*attr);
     102           30 :     g_free (data->attributes);
     103           30 :     g_free (data);
     104              : }
     105              : 
     106              : /**
     107              :  * bd_smart_ata_copy: (skip)
     108              :  * @data: (nullable): %BDSmartATA to copy
     109              :  *
     110              :  * Creates a new copy of @data.
     111              :  */
     112            0 : BDSmartATA * bd_smart_ata_copy (BDSmartATA *data) {
     113              :         BDSmartATA *new_data;
     114              :     BDSmartATAAttribute **attr;
     115              :     GPtrArray *ptr_array;
     116              : 
     117            0 :     if (data == NULL)
     118            0 :         return NULL;
     119              : 
     120            0 :     new_data = g_new0 (BDSmartATA, 1);
     121            0 :     memcpy (new_data, data, sizeof (BDSmartATA));
     122              : 
     123            0 :     ptr_array = g_ptr_array_new ();
     124            0 :     for (attr = data->attributes; attr && *attr; attr++)
     125            0 :         g_ptr_array_add (ptr_array, bd_smart_ata_attribute_copy (*attr));
     126            0 :     g_ptr_array_add (ptr_array, NULL);
     127            0 :     new_data->attributes = (BDSmartATAAttribute **) g_ptr_array_free (ptr_array, FALSE);
     128              : 
     129            0 :     return new_data;
     130              : }
     131              : 
     132          228 : GType  bd_smart_ata_get_type () {
     133              :         static GType type = 0;
     134              : 
     135          228 :     if (G_UNLIKELY (type == 0)) {
     136            1 :         type = g_boxed_type_register_static ("BDSmartATA",
     137              :                                              (GBoxedCopyFunc) bd_smart_ata_copy,
     138              :                                              (GBoxedFreeFunc) bd_smart_ata_free);
     139              :     }
     140          228 :     return type;
     141              : }
     142              : 
     143              : /**
     144              :  * BDSmartSCSI:
     145              :  * @smart_supported: Indicates that the device has SMART capability.
     146              :  * @smart_enabled: Indicates that the SMART support is enabled.
     147              :  * @overall_status_passed: %TRUE if the device SMART overall-health self-assessment test result has passed, %FALSE otherwise with @scsi_ie fields set.
     148              :  * @scsi_ie: The reported SCSI Informational Exception in a simplified form. See #BDSmartSCSIInformationalException.
     149              :  * @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).
     150              :  * @scsi_ie_ascq: The reported SCSI Informational Exception ASCQ (Additional Sense Code Qualifier) value.
     151              :  * @scsi_ie_string: String representation of the current SCSI Informational Exception.
     152              :  * @background_scan_status: Background scan status, see #BDSmartSCSIBackgroundScanStatus.
     153              :  * @background_scan_progress: Percent of a background scan progress.
     154              :  * @background_scan_runs: Number of background scans performed.
     155              :  * @background_medium_scan_runs: Number of background medium scans performed.
     156              :  * @read_errors_corrected_eccfast: Error counter log - read errors corrected by ECC fast.
     157              :  * @read_errors_corrected_eccdelayed: Error counter log - read errors corrected by ECC delayed.
     158              :  * @read_errors_corrected_rereads: Error counter log - read errors corrected by rereads.
     159              :  * @read_errors_corrected_total: Error counter log - total read errors corrected.
     160              :  * @read_errors_uncorrected: Error counter log - total uncorrected read errors.
     161              :  * @read_processed_bytes: Error counter log - total bytes processed.
     162              :  * @write_errors_corrected_eccfast: Error counter log - write errors corrected by ECC fast.
     163              :  * @write_errors_corrected_eccdelayed: Error counter log - write errors corrected by ECC delayed.
     164              :  * @write_errors_corrected_rewrites: Error counter log - write errors corrected by rewrites.
     165              :  * @write_errors_corrected_total: Error counter log - total write errors corrected.
     166              :  * @write_errors_uncorrected: Error counter log - total uncorrected write errors.
     167              :  * @write_processed_bytes: Error counter log - total bytes processed.
     168              :  * @start_stop_cycle_count: Accumulated start-stop cycles.
     169              :  * @start_stop_cycle_lifetime: Specified cycle count over device lifetime.
     170              :  * @load_unload_cycle_count: Accumulated load-unload cycles.
     171              :  * @load_unload_cycle_lifetime: Specified load-unload count over device lifetime.
     172              :  * @scsi_grown_defect_list: Elements in grown defect list.
     173              :  * @power_on_time: Accumulated power on time in minutes.
     174              :  * @temperature_warning_enabled: Indicates that temperature warning is enabled.
     175              :  * @temperature: The current drive temperature in Kelvin or 0 when temperature is not reported.
     176              :  * @temperature_drive_trip: The drive trip temperature in Kelvin or 0 when temperature is not reported.
     177              :  */
     178              : /**
     179              :  * bd_smart_scsi_free: (skip)
     180              :  * @data: (nullable): %BDSmartSCSI to free
     181              :  *
     182              :  * Frees @data.
     183              :  */
     184            6 : void  bd_smart_scsi_free (BDSmartSCSI *data) {
     185            6 :         if (data == NULL)
     186            0 :         return;
     187              : 
     188            6 :     g_free (data->scsi_ie_string);
     189            6 :     g_free (data);
     190              : }
     191              : 
     192              : /**
     193              :  * bd_smart_scsi_copy: (skip)
     194              :  * @data: (nullable): %BDSmartSCSI to copy
     195              :  *
     196              :  * Creates a new copy of @data.
     197              :  */
     198            0 : BDSmartSCSI * bd_smart_scsi_copy (BDSmartSCSI *data) {
     199              :         BDSmartSCSI *new_data;
     200              : 
     201            0 :     if (data == NULL)
     202            0 :         return NULL;
     203              : 
     204            0 :     new_data = g_new0 (BDSmartSCSI, 1);
     205            0 :     memcpy (new_data, data, sizeof (BDSmartSCSI));
     206            0 :     new_data->scsi_ie_string = g_strdup (data->scsi_ie_string);
     207              : 
     208            0 :     return new_data;
     209              : }
     210              : 
     211           45 : GType  bd_smart_scsi_get_type () {
     212              :         static GType type = 0;
     213              : 
     214           45 :     if (G_UNLIKELY (type == 0)) {
     215            1 :         type = g_boxed_type_register_static ("BDSmartSCSI",
     216              :                                              (GBoxedCopyFunc) bd_smart_scsi_copy,
     217              :                                              (GBoxedFreeFunc) bd_smart_scsi_free);
     218              :     }
     219           45 :     return type;
     220              : }
     221              : 
     222            0 : static gboolean  bd_smart_is_tech_avail_stub (BDSmartTech tech G_GNUC_UNUSED, G_GNUC_UNUSED guint64 mode G_GNUC_UNUSED, GError **error) {
     223            0 :     bd_utils_log_format (BD_UTILS_LOG_CRIT, "The function 'bd_smart_is_tech_avail' called, but not implemented!");
     224            0 :     g_set_error (error, BD_INIT_ERROR, BD_INIT_ERROR_NOT_IMPLEMENTED,
     225              :                 "The function 'bd_smart_is_tech_avail' called, but not implemented!");
     226            0 :     return FALSE;
     227              : }
     228              : 
     229              : static gboolean  (*_bd_smart_is_tech_avail) (BDSmartTech tech, G_GNUC_UNUSED guint64 mode, GError **error) = bd_smart_is_tech_avail_stub;
     230              : 
     231              : /**
     232              :  * bd_smart_is_tech_avail:
     233              :  * @tech: the queried tech
     234              :  * @mode: a bit mask of queried modes of operation (#BDSmartTechMode) for @tech
     235              :  * @error: (out) (nullable): place to store error (details about why the @tech-@mode combination is not available)
     236              :  *
     237              :  * Returns: whether the @tech-@mode combination is available -- supported by the
     238              :  *          plugin implementation and having all the runtime dependencies available
     239              :  */
     240            5 : gboolean  bd_smart_is_tech_avail (BDSmartTech tech, G_GNUC_UNUSED guint64 mode, GError **error) {
     241            5 :     return _bd_smart_is_tech_avail (tech, mode, error);
     242              : }
     243              : 
     244              : 
     245            0 : static BDSmartATA * bd_smart_ata_get_info_stub (const gchar *device G_GNUC_UNUSED, const BDExtraArg **extra G_GNUC_UNUSED, GError **error) {
     246            0 :     bd_utils_log_format (BD_UTILS_LOG_CRIT, "The function 'bd_smart_ata_get_info' called, but not implemented!");
     247            0 :     g_set_error (error, BD_INIT_ERROR, BD_INIT_ERROR_NOT_IMPLEMENTED,
     248              :                 "The function 'bd_smart_ata_get_info' called, but not implemented!");
     249            0 :     return NULL;
     250              : }
     251              : 
     252              : static BDSmartATA * (*_bd_smart_ata_get_info) (const gchar *device, const BDExtraArg **extra, GError **error) = bd_smart_ata_get_info_stub;
     253              : 
     254              : /**
     255              :  * bd_smart_ata_get_info:
     256              :  * @device: device to check.
     257              :  * @extra: (nullable) (array zero-terminated=1): extra options to pass through.
     258              :  * @error: (out) (optional): place to store error (if any).
     259              :  *
     260              :  * Retrieve SMART information from the drive.
     261              :  *
     262              :  * Returns: (transfer full): ATA SMART log or %NULL in case of an error (with @error set).
     263              :  *
     264              :  * Tech category: %BD_SMART_TECH_ATA-%BD_SMART_TECH_MODE_INFO
     265              :  */
     266           28 : BDSmartATA * bd_smart_ata_get_info (const gchar *device, const BDExtraArg **extra, GError **error) {
     267           28 :     return _bd_smart_ata_get_info (device, extra, error);
     268              : }
     269              : 
     270              : 
     271            0 : static BDSmartATA * bd_smart_ata_get_info_from_data_stub (const guint8 *data G_GNUC_UNUSED, gsize data_len G_GNUC_UNUSED, GError **error) {
     272            0 :     bd_utils_log_format (BD_UTILS_LOG_CRIT, "The function 'bd_smart_ata_get_info_from_data' called, but not implemented!");
     273            0 :     g_set_error (error, BD_INIT_ERROR, BD_INIT_ERROR_NOT_IMPLEMENTED,
     274              :                 "The function 'bd_smart_ata_get_info_from_data' called, but not implemented!");
     275            0 :     return NULL;
     276              : }
     277              : 
     278              : static BDSmartATA * (*_bd_smart_ata_get_info_from_data) (const guint8 *data, gsize data_len, GError **error) = bd_smart_ata_get_info_from_data_stub;
     279              : 
     280              : /**
     281              :  * bd_smart_ata_get_info_from_data:
     282              :  * @data: (array length=data_len): binary data to parse.
     283              :  * @data_len: length of the data supplied.
     284              :  * @error: (out) (optional): place to store error (if any).
     285              :  *
     286              :  * Retrieve SMART information from the supplied data.
     287              :  *
     288              :  * Returns: (transfer full): ATA SMART log or %NULL in case of an error (with @error set).
     289              :  *
     290              :  * Tech category: %BD_SMART_TECH_ATA-%BD_SMART_TECH_MODE_INFO
     291              :  */
     292           23 : BDSmartATA * bd_smart_ata_get_info_from_data (const guint8 *data, gsize data_len, GError **error) {
     293           23 :     return _bd_smart_ata_get_info_from_data (data, data_len, error);
     294              : }
     295              : 
     296              : 
     297            0 : static BDSmartSCSI * bd_smart_scsi_get_info_stub (const gchar *device G_GNUC_UNUSED, const BDExtraArg **extra G_GNUC_UNUSED, GError **error) {
     298            0 :     bd_utils_log_format (BD_UTILS_LOG_CRIT, "The function 'bd_smart_scsi_get_info' called, but not implemented!");
     299            0 :     g_set_error (error, BD_INIT_ERROR, BD_INIT_ERROR_NOT_IMPLEMENTED,
     300              :                 "The function 'bd_smart_scsi_get_info' called, but not implemented!");
     301            0 :     return NULL;
     302              : }
     303              : 
     304              : static BDSmartSCSI * (*_bd_smart_scsi_get_info) (const gchar *device, const BDExtraArg **extra, GError **error) = bd_smart_scsi_get_info_stub;
     305              : 
     306              : /**
     307              :  * bd_smart_scsi_get_info:
     308              :  * @device: device to check.
     309              :  * @extra: (nullable) (array zero-terminated=1): extra options to pass through.
     310              :  * @error: (out) (optional): place to store error (if any).
     311              :  *
     312              :  * Retrieve SMART information from SCSI or SAS-compliant drive.
     313              :  *
     314              :  * Returns: (transfer full): SCSI SMART log or %NULL in case of an error (with @error set).
     315              :  *
     316              :  * Tech category: %BD_SMART_TECH_SCSI-%BD_SMART_TECH_MODE_INFO
     317              :  */
     318           22 : BDSmartSCSI * bd_smart_scsi_get_info (const gchar *device, const BDExtraArg **extra, GError **error) {
     319           22 :     return _bd_smart_scsi_get_info (device, extra, error);
     320              : }
     321              : 
     322              : 
     323            0 : static gboolean  bd_smart_set_enabled_stub (const gchar *device G_GNUC_UNUSED, gboolean enabled G_GNUC_UNUSED, const BDExtraArg **extra G_GNUC_UNUSED, GError **error) {
     324            0 :     bd_utils_log_format (BD_UTILS_LOG_CRIT, "The function 'bd_smart_set_enabled' called, but not implemented!");
     325            0 :     g_set_error (error, BD_INIT_ERROR, BD_INIT_ERROR_NOT_IMPLEMENTED,
     326              :                 "The function 'bd_smart_set_enabled' called, but not implemented!");
     327            0 :     return FALSE;
     328              : }
     329              : 
     330              : static gboolean  (*_bd_smart_set_enabled) (const gchar *device, gboolean enabled, const BDExtraArg **extra, GError **error) = bd_smart_set_enabled_stub;
     331              : 
     332              : /**
     333              :  * bd_smart_set_enabled:
     334              :  * @device: SMART-capable device.
     335              :  * @enabled: whether to enable or disable the SMART functionality
     336              :  * @extra: (nullable) (array zero-terminated=1): extra options to pass through.
     337              :  * @error: (out) (optional): place to store error (if any).
     338              :  *
     339              :  * Enables or disables SMART functionality on device.
     340              :  *
     341              :  * Returns: %TRUE when the functionality was set successfully or %FALSE in case of an error (with @error set).
     342              :  *
     343              :  * Tech category: %BD_SMART_TECH_ATA-%BD_SMART_TECH_MODE_INFO
     344              :  */
     345           30 : gboolean  bd_smart_set_enabled (const gchar *device, gboolean enabled, const BDExtraArg **extra, GError **error) {
     346           30 :     return _bd_smart_set_enabled (device, enabled, extra, error);
     347              : }
     348              : 
     349              : 
     350            0 : static gboolean  bd_smart_device_self_test_stub (const gchar *device G_GNUC_UNUSED, BDSmartSelfTestOp operation G_GNUC_UNUSED, const BDExtraArg **extra G_GNUC_UNUSED, GError **error) {
     351            0 :     bd_utils_log_format (BD_UTILS_LOG_CRIT, "The function 'bd_smart_device_self_test' called, but not implemented!");
     352            0 :     g_set_error (error, BD_INIT_ERROR, BD_INIT_ERROR_NOT_IMPLEMENTED,
     353              :                 "The function 'bd_smart_device_self_test' called, but not implemented!");
     354            0 :     return FALSE;
     355              : }
     356              : 
     357              : static gboolean  (*_bd_smart_device_self_test) (const gchar *device, BDSmartSelfTestOp operation, const BDExtraArg **extra, GError **error) = bd_smart_device_self_test_stub;
     358              : 
     359              : /**
     360              :  * bd_smart_device_self_test:
     361              :  * @device: device to trigger the test on.
     362              :  * @operation: #BDSmartSelfTestOp self-test operation.
     363              :  * @extra: (nullable) (array zero-terminated=1): extra options to pass through.
     364              :  * @error: (out) (optional): place to store error (if any).
     365              :  *
     366              :  * Executes or aborts device self-test.
     367              :  *
     368              :  * Returns: %TRUE when the self-test was triggered successfully or %FALSE in case of an error (with @error set).
     369              :  *
     370              :  * Tech category: %BD_SMART_TECH_ATA-%BD_SMART_TECH_MODE_SELFTEST
     371              :  */
     372           78 : gboolean  bd_smart_device_self_test (const gchar *device, BDSmartSelfTestOp operation, const BDExtraArg **extra, GError **error) {
     373           78 :     return _bd_smart_device_self_test (device, operation, extra, error);
     374              : }
     375              : 
     376              : 
     377            3 : static gpointer load_smart_from_plugin(const gchar *so_name) {
     378            3 :     void *handle = NULL;
     379            3 :     char *error = NULL;
     380            3 :     gboolean (*init_fn) (void) = NULL;
     381              : 
     382            3 :     handle = dlopen(so_name, RTLD_LAZY);
     383            3 :     if (!handle) {
     384            0 :         bd_utils_log_format (BD_UTILS_LOG_WARNING, "failed to load module smart: %s", dlerror());
     385            0 :         return NULL;
     386              :     }
     387              : 
     388            3 :     dlerror();
     389            3 :     * (void**) (&init_fn) = dlsym(handle, "bd_smart_init");
     390            3 :     if ((error = dlerror()) != NULL)
     391            0 :         bd_utils_log_format (BD_UTILS_LOG_DEBUG, "failed to load the init() function for smart: %s", error);
     392              :     /* coverity[dead_error_condition] */
     393            3 :     if (init_fn && !init_fn()) {
     394            0 :         dlclose(handle);
     395            0 :         return NULL;
     396              :     }
     397            3 :     init_fn = NULL;
     398              : 
     399            3 :     dlerror();
     400            3 :     * (void**) (&_bd_smart_is_tech_avail) = dlsym(handle, "bd_smart_is_tech_avail");
     401            3 :     if ((error = dlerror()) != NULL)
     402            0 :         bd_utils_log_format (BD_UTILS_LOG_WARNING, "failed to load bd_smart_is_tech_avail: %s", error);
     403              : 
     404            3 :     dlerror();
     405            3 :     * (void**) (&_bd_smart_ata_get_info) = dlsym(handle, "bd_smart_ata_get_info");
     406            3 :     if ((error = dlerror()) != NULL)
     407            0 :         bd_utils_log_format (BD_UTILS_LOG_WARNING, "failed to load bd_smart_ata_get_info: %s", error);
     408              : 
     409            3 :     dlerror();
     410            3 :     * (void**) (&_bd_smart_ata_get_info_from_data) = dlsym(handle, "bd_smart_ata_get_info_from_data");
     411            3 :     if ((error = dlerror()) != NULL)
     412            0 :         bd_utils_log_format (BD_UTILS_LOG_WARNING, "failed to load bd_smart_ata_get_info_from_data: %s", error);
     413              : 
     414            3 :     dlerror();
     415            3 :     * (void**) (&_bd_smart_scsi_get_info) = dlsym(handle, "bd_smart_scsi_get_info");
     416            3 :     if ((error = dlerror()) != NULL)
     417            0 :         bd_utils_log_format (BD_UTILS_LOG_WARNING, "failed to load bd_smart_scsi_get_info: %s", error);
     418              : 
     419            3 :     dlerror();
     420            3 :     * (void**) (&_bd_smart_set_enabled) = dlsym(handle, "bd_smart_set_enabled");
     421            3 :     if ((error = dlerror()) != NULL)
     422            0 :         bd_utils_log_format (BD_UTILS_LOG_WARNING, "failed to load bd_smart_set_enabled: %s", error);
     423              : 
     424            3 :     dlerror();
     425            3 :     * (void**) (&_bd_smart_device_self_test) = dlsym(handle, "bd_smart_device_self_test");
     426            3 :     if ((error = dlerror()) != NULL)
     427            0 :         bd_utils_log_format (BD_UTILS_LOG_WARNING, "failed to load bd_smart_device_self_test: %s", error);
     428              : 
     429            3 :     return handle;
     430              : }
     431              : 
     432            3 : static gboolean unload_smart (gpointer handle) {
     433            3 :     char *error = NULL;
     434            3 :     gboolean (*close_fn) (void) = NULL;
     435              : 
     436            3 :     _bd_smart_is_tech_avail = bd_smart_is_tech_avail_stub;
     437            3 :     _bd_smart_ata_get_info = bd_smart_ata_get_info_stub;
     438            3 :     _bd_smart_ata_get_info_from_data = bd_smart_ata_get_info_from_data_stub;
     439            3 :     _bd_smart_scsi_get_info = bd_smart_scsi_get_info_stub;
     440            3 :     _bd_smart_set_enabled = bd_smart_set_enabled_stub;
     441            3 :     _bd_smart_device_self_test = bd_smart_device_self_test_stub;
     442              : 
     443            3 :     dlerror();
     444            3 :     * (void**) (&close_fn) = dlsym(handle, "bd_smart_close");
     445            3 :     if (((error = dlerror()) != NULL) || !close_fn)
     446            0 :         bd_utils_log_format (BD_UTILS_LOG_DEBUG, "failed to load the close_plugin() function for smart: %s", error);
     447              :     /* coverity[dead_error_condition] */
     448            3 :     if (close_fn) {
     449            3 :         close_fn();
     450              :     }
     451              : 
     452            3 :     return dlclose(handle) == 0;
     453              : }
     454              : 
        

Generated by: LCOV version 2.0-1