GQuark  bd_swap_error_quark (void) {
        return g_quark_from_static_string ("g-bd-swap-error-quark");
}

static gboolean  bd_swap_is_tech_avail_stub (BDSwapTech tech G_GNUC_UNUSED, guint64 mode G_GNUC_UNUSED, GError **error) {
    bd_utils_log_format (BD_UTILS_LOG_CRIT, "The function 'bd_swap_is_tech_avail' called, but not implemented!");
    g_set_error (error, BD_INIT_ERROR, BD_INIT_ERROR_NOT_IMPLEMENTED,
                "The function 'bd_swap_is_tech_avail' called, but not implemented!");
    return FALSE;
}

static gboolean  (*_bd_swap_is_tech_avail) (BDSwapTech tech, guint64 mode, GError **error) = bd_swap_is_tech_avail_stub;

/**
 * bd_swap_is_tech_avail:
 * @tech: the queried tech
 * @mode: a bit mask of queried modes of operation (#BDSwapTechMode) for @tech
 * @error: (out) (optional): place to store error (details about why the @tech-@mode combination is not available)
 *
 * Returns: whether the @tech-@mode combination is available -- supported by the
 *          plugin implementation and having all the runtime dependencies available
 */
gboolean  bd_swap_is_tech_avail (BDSwapTech tech, guint64 mode, GError **error) {
    return _bd_swap_is_tech_avail (tech, mode, error);
}


static gboolean  bd_swap_mkswap_stub (const gchar *device G_GNUC_UNUSED, const gchar *label G_GNUC_UNUSED, const gchar *uuid G_GNUC_UNUSED, const BDExtraArg **extra G_GNUC_UNUSED, GError **error) {
    bd_utils_log_format (BD_UTILS_LOG_CRIT, "The function 'bd_swap_mkswap' called, but not implemented!");
    g_set_error (error, BD_INIT_ERROR, BD_INIT_ERROR_NOT_IMPLEMENTED,
                "The function 'bd_swap_mkswap' called, but not implemented!");
    return FALSE;
}

static gboolean  (*_bd_swap_mkswap) (const gchar *device, const gchar *label, const gchar *uuid, const BDExtraArg **extra, GError **error) = bd_swap_mkswap_stub;

/**
 * bd_swap_mkswap:
 * @device: a device to create swap space on
 * @label: (nullable): a label for the swap space device
 * @uuid: (nullable): UUID for the swap space device
 * @extra: (nullable) (array zero-terminated=1): extra options for the creation (right now
 *                                                 passed to the 'mkswap' utility)
 * @error: (out) (optional): place to store error (if any)
 *
 * Returns: whether the swap space was successfully created or not
 *
 * Tech category: %BD_SWAP_TECH_SWAP-%BD_SWAP_TECH_MODE_CREATE
 */
gboolean  bd_swap_mkswap (const gchar *device, const gchar *label, const gchar *uuid, const BDExtraArg **extra, GError **error) {
    return _bd_swap_mkswap (device, label, uuid, extra, error);
}


static gboolean  bd_swap_swapon_stub (const gchar *device G_GNUC_UNUSED, gint priority G_GNUC_UNUSED, GError **error) {
    bd_utils_log_format (BD_UTILS_LOG_CRIT, "The function 'bd_swap_swapon' called, but not implemented!");
    g_set_error (error, BD_INIT_ERROR, BD_INIT_ERROR_NOT_IMPLEMENTED,
                "The function 'bd_swap_swapon' called, but not implemented!");
    return FALSE;
}

static gboolean  (*_bd_swap_swapon) (const gchar *device, gint priority, GError **error) = bd_swap_swapon_stub;

/**
 * bd_swap_swapon:
 * @device: swap device to activate
 * @priority: priority of the activated device or -1 to use the default
 * @error: (out) (optional): place to store error (if any)
 *
 * Returns: whether the swap device was successfully activated or not
 *
 * Tech category: %BD_SWAP_TECH_SWAP-%BD_SWAP_TECH_MODE_ACTIVATE_DEACTIVATE
 */
gboolean  bd_swap_swapon (const gchar *device, gint priority, GError **error) {
    return _bd_swap_swapon (device, priority, error);
}


static gboolean  bd_swap_swapoff_stub (const gchar *device G_GNUC_UNUSED, GError **error) {
    bd_utils_log_format (BD_UTILS_LOG_CRIT, "The function 'bd_swap_swapoff' called, but not implemented!");
    g_set_error (error, BD_INIT_ERROR, BD_INIT_ERROR_NOT_IMPLEMENTED,
                "The function 'bd_swap_swapoff' called, but not implemented!");
    return FALSE;
}

static gboolean  (*_bd_swap_swapoff) (const gchar *device, GError **error) = bd_swap_swapoff_stub;

/**
 * bd_swap_swapoff:
 * @device: swap device to deactivate
 * @error: (out) (optional): place to store error (if any)
 *
 * Returns: whether the swap device was successfully deactivated or not
 *
 * Tech category: %BD_SWAP_TECH_SWAP-%BD_SWAP_TECH_MODE_ACTIVATE_DEACTIVATE
 */
gboolean  bd_swap_swapoff (const gchar *device, GError **error) {
    return _bd_swap_swapoff (device, error);
}


static gboolean  bd_swap_swapstatus_stub (const gchar *device G_GNUC_UNUSED, GError **error) {
    bd_utils_log_format (BD_UTILS_LOG_CRIT, "The function 'bd_swap_swapstatus' called, but not implemented!");
    g_set_error (error, BD_INIT_ERROR, BD_INIT_ERROR_NOT_IMPLEMENTED,
                "The function 'bd_swap_swapstatus' called, but not implemented!");
    return FALSE;
}

static gboolean  (*_bd_swap_swapstatus) (const gchar *device, GError **error) = bd_swap_swapstatus_stub;

/**
 * bd_swap_swapstatus:
 * @device: swap device to get status of
 * @error: (out) (optional): place to store error (if any)
 *
 * Returns: %TRUE if the swap device is active, %FALSE if not active or failed
 * to determine (@error) is set not a non-NULL value in such case)
 *
 * Tech category: %BD_SWAP_TECH_SWAP-%BD_SWAP_TECH_MODE_QUERY
 */
gboolean  bd_swap_swapstatus (const gchar *device, GError **error) {
    return _bd_swap_swapstatus (device, error);
}


static gboolean  bd_swap_check_label_stub (const gchar *label G_GNUC_UNUSED, GError **error) {
    bd_utils_log_format (BD_UTILS_LOG_CRIT, "The function 'bd_swap_check_label' called, but not implemented!");
    g_set_error (error, BD_INIT_ERROR, BD_INIT_ERROR_NOT_IMPLEMENTED,
                "The function 'bd_swap_check_label' called, but not implemented!");
    return FALSE;
}

static gboolean  (*_bd_swap_check_label) (const gchar *label, GError **error) = bd_swap_check_label_stub;

/**
 * bd_swap_check_label:
 * @label: label to check
 * @error: (out) (optional): place to store error
 *
 * Returns: whether @label is a valid label for swap or not
 *          (reason is provided in @error)
 *
 * Tech category: always available
 */
gboolean  bd_swap_check_label (const gchar *label, GError **error) {
    return _bd_swap_check_label (label, error);
}


static gboolean  bd_swap_set_label_stub (const gchar *device G_GNUC_UNUSED, const gchar *label G_GNUC_UNUSED, GError **error) {
    bd_utils_log_format (BD_UTILS_LOG_CRIT, "The function 'bd_swap_set_label' called, but not implemented!");
    g_set_error (error, BD_INIT_ERROR, BD_INIT_ERROR_NOT_IMPLEMENTED,
                "The function 'bd_swap_set_label' called, but not implemented!");
    return FALSE;
}

static gboolean  (*_bd_swap_set_label) (const gchar *device, const gchar *label, GError **error) = bd_swap_set_label_stub;

/**
 * bd_swap_set_label:
 * @device: a device to set label on
 * @label: label that will be set
 * @error: (out) (optional): place to store error (if any)
 *
 * Returns: whether the label was successfully set or not
 *
 * Tech category: %BD_SWAP_TECH_SWAP-%BD_SWAP_TECH_MODE_SET_LABEL
 */
gboolean  bd_swap_set_label (const gchar *device, const gchar *label, GError **error) {
    return _bd_swap_set_label (device, label, error);
}


static gboolean  bd_swap_check_uuid_stub (const gchar *uuid G_GNUC_UNUSED, GError **error) {
    bd_utils_log_format (BD_UTILS_LOG_CRIT, "The function 'bd_swap_check_uuid' called, but not implemented!");
    g_set_error (error, BD_INIT_ERROR, BD_INIT_ERROR_NOT_IMPLEMENTED,
                "The function 'bd_swap_check_uuid' called, but not implemented!");
    return FALSE;
}

static gboolean  (*_bd_swap_check_uuid) (const gchar *uuid, GError **error) = bd_swap_check_uuid_stub;

/**
 * bd_swap_check_uuid:
 * @uuid: UUID to check
 * @error: (out) (optional): place to store error
 *
 * Returns: whether @uuid is a valid UUID for swap or not
 *          (reason is provided in @error)
 *
 * Tech category: always available
 */
gboolean  bd_swap_check_uuid (const gchar *uuid, GError **error) {
    return _bd_swap_check_uuid (uuid, error);
}


static gboolean  bd_swap_set_uuid_stub (const gchar *device G_GNUC_UNUSED, const gchar *uuid G_GNUC_UNUSED, GError **error) {
    bd_utils_log_format (BD_UTILS_LOG_CRIT, "The function 'bd_swap_set_uuid' called, but not implemented!");
    g_set_error (error, BD_INIT_ERROR, BD_INIT_ERROR_NOT_IMPLEMENTED,
                "The function 'bd_swap_set_uuid' called, but not implemented!");
    return FALSE;
}

static gboolean  (*_bd_swap_set_uuid) (const gchar *device, const gchar *uuid, GError **error) = bd_swap_set_uuid_stub;

/**
 * bd_swap_set_uuid:
 * @device: a device to set UUID on
 * @uuid: UUID that will be set
 * @error: (out) (optional): place to store error (if any)
 *
 * Returns: whether the UUID was successfully set or not
 *
 * Tech category: %BD_SWAP_TECH_SWAP-%BD_SWAP_TECH_MODE_SET_UUID
 */
gboolean  bd_swap_set_uuid (const gchar *device, const gchar *uuid, GError **error) {
    return _bd_swap_set_uuid (device, uuid, error);
}


static gpointer load_swap_from_plugin(const gchar *so_name) {
    void *handle = NULL;
    char *error = NULL;
    gboolean (*init_fn) (void) = NULL;

    handle = dlopen(so_name, RTLD_LAZY | RTLD_NODELETE);
    if (!handle) {
        bd_utils_log_format (BD_UTILS_LOG_WARNING, "failed to load module swap: %s", dlerror());
        return NULL;
    }

    dlerror();
    * (void**) (&init_fn) = dlsym(handle, "bd_swap_init");
    if ((error = dlerror()) != NULL)
        bd_utils_log_format (BD_UTILS_LOG_DEBUG, "failed to load the init() function for swap: %s", error);
    /* coverity[dead_error_condition] */
    if (init_fn && !init_fn()) {
        dlclose(handle);
        return NULL;
    }
    init_fn = NULL;

    dlerror();
    * (void**) (&_bd_swap_is_tech_avail) = dlsym(handle, "bd_swap_is_tech_avail");
    if ((error = dlerror()) != NULL) {
        bd_utils_log_format (BD_UTILS_LOG_WARNING, "failed to load bd_swap_is_tech_avail: %s", error);
        _bd_swap_is_tech_avail = bd_swap_is_tech_avail_stub;
    }

    dlerror();
    * (void**) (&_bd_swap_mkswap) = dlsym(handle, "bd_swap_mkswap");
    if ((error = dlerror()) != NULL) {
        bd_utils_log_format (BD_UTILS_LOG_WARNING, "failed to load bd_swap_mkswap: %s", error);
        _bd_swap_mkswap = bd_swap_mkswap_stub;
    }

    dlerror();
    * (void**) (&_bd_swap_swapon) = dlsym(handle, "bd_swap_swapon");
    if ((error = dlerror()) != NULL) {
        bd_utils_log_format (BD_UTILS_LOG_WARNING, "failed to load bd_swap_swapon: %s", error);
        _bd_swap_swapon = bd_swap_swapon_stub;
    }

    dlerror();
    * (void**) (&_bd_swap_swapoff) = dlsym(handle, "bd_swap_swapoff");
    if ((error = dlerror()) != NULL) {
        bd_utils_log_format (BD_UTILS_LOG_WARNING, "failed to load bd_swap_swapoff: %s", error);
        _bd_swap_swapoff = bd_swap_swapoff_stub;
    }

    dlerror();
    * (void**) (&_bd_swap_swapstatus) = dlsym(handle, "bd_swap_swapstatus");
    if ((error = dlerror()) != NULL) {
        bd_utils_log_format (BD_UTILS_LOG_WARNING, "failed to load bd_swap_swapstatus: %s", error);
        _bd_swap_swapstatus = bd_swap_swapstatus_stub;
    }

    dlerror();
    * (void**) (&_bd_swap_check_label) = dlsym(handle, "bd_swap_check_label");
    if ((error = dlerror()) != NULL) {
        bd_utils_log_format (BD_UTILS_LOG_WARNING, "failed to load bd_swap_check_label: %s", error);
        _bd_swap_check_label = bd_swap_check_label_stub;
    }

    dlerror();
    * (void**) (&_bd_swap_set_label) = dlsym(handle, "bd_swap_set_label");
    if ((error = dlerror()) != NULL) {
        bd_utils_log_format (BD_UTILS_LOG_WARNING, "failed to load bd_swap_set_label: %s", error);
        _bd_swap_set_label = bd_swap_set_label_stub;
    }

    dlerror();
    * (void**) (&_bd_swap_check_uuid) = dlsym(handle, "bd_swap_check_uuid");
    if ((error = dlerror()) != NULL) {
        bd_utils_log_format (BD_UTILS_LOG_WARNING, "failed to load bd_swap_check_uuid: %s", error);
        _bd_swap_check_uuid = bd_swap_check_uuid_stub;
    }

    dlerror();
    * (void**) (&_bd_swap_set_uuid) = dlsym(handle, "bd_swap_set_uuid");
    if ((error = dlerror()) != NULL) {
        bd_utils_log_format (BD_UTILS_LOG_WARNING, "failed to load bd_swap_set_uuid: %s", error);
        _bd_swap_set_uuid = bd_swap_set_uuid_stub;
    }

    return handle;
}

static gboolean unload_swap (gpointer handle) {
    char *error = NULL;
    gboolean (*close_fn) (void) = NULL;

    _bd_swap_is_tech_avail = bd_swap_is_tech_avail_stub;
    _bd_swap_mkswap = bd_swap_mkswap_stub;
    _bd_swap_swapon = bd_swap_swapon_stub;
    _bd_swap_swapoff = bd_swap_swapoff_stub;
    _bd_swap_swapstatus = bd_swap_swapstatus_stub;
    _bd_swap_check_label = bd_swap_check_label_stub;
    _bd_swap_set_label = bd_swap_set_label_stub;
    _bd_swap_check_uuid = bd_swap_check_uuid_stub;
    _bd_swap_set_uuid = bd_swap_set_uuid_stub;

    dlerror();
    * (void**) (&close_fn) = dlsym(handle, "bd_swap_close");
    if (((error = dlerror()) != NULL) || !close_fn)
        bd_utils_log_format (BD_UTILS_LOG_DEBUG, "failed to load the close_plugin() function for swap: %s", error);
    /* coverity[dead_error_condition] */
    if (close_fn) {
        close_fn();
    }

    return dlclose(handle) == 0;
}

