GQuark bd_loop_error_quark (void) {
return g_quark_from_static_string ("g-bd-loop-error-quark");
}
static gboolean bd_loop_is_tech_avail_stub (BDLoopTech tech, guint64 mode, GError **error) {
g_critical ("The function 'bd_loop_is_tech_avail' called, but not implemented!");
g_set_error (error, BD_INIT_ERROR, BD_INIT_ERROR_NOT_IMPLEMENTED,
"The function 'bd_loop_is_tech_avail' called, but not implemented!");
return FALSE;
}
static gboolean (*_bd_loop_is_tech_avail) (BDLoopTech tech, guint64 mode, GError **error) = bd_loop_is_tech_avail_stub;
/**
* bd_loop_is_tech_avail:
* @tech: the queried tech
* @mode: a bit mask of queried modes of operation (#BDLoopTechMode) for @tech
* @error: (out): 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_loop_is_tech_avail (BDLoopTech tech, guint64 mode, GError **error) {
return _bd_loop_is_tech_avail (tech, mode, error);
}
static gchar* bd_loop_get_backing_file_stub (const gchar *dev_name, GError **error) {
g_critical ("The function 'bd_loop_get_backing_file' called, but not implemented!");
g_set_error (error, BD_INIT_ERROR, BD_INIT_ERROR_NOT_IMPLEMENTED,
"The function 'bd_loop_get_backing_file' called, but not implemented!");
return NULL;
}
static gchar* (*_bd_loop_get_backing_file) (const gchar *dev_name, GError **error) = bd_loop_get_backing_file_stub;
/**
* bd_loop_get_backing_file:
* @dev_name: name of the loop device to get backing file for (e.g. "loop0")
* @error: (out): place to store error (if any)
*
* Returns: (transfer full): path of the device's backing file or %NULL if none
* is found
*
* Tech category: %BD_LOOP_TECH_LOOP-%BD_LOOP_TECH_MODE_QUERY
*/
gchar* bd_loop_get_backing_file (const gchar *dev_name, GError **error) {
return _bd_loop_get_backing_file (dev_name, error);
}
static gchar* bd_loop_get_loop_name_stub (const gchar *file, GError **error) {
g_critical ("The function 'bd_loop_get_loop_name' called, but not implemented!");
g_set_error (error, BD_INIT_ERROR, BD_INIT_ERROR_NOT_IMPLEMENTED,
"The function 'bd_loop_get_loop_name' called, but not implemented!");
return NULL;
}
static gchar* (*_bd_loop_get_loop_name) (const gchar *file, GError **error) = bd_loop_get_loop_name_stub;
/**
* bd_loop_get_loop_name:
* @file: path of the backing file to get loop name for
* @error: (out): place to store error (if any)
*
* Returns: (transfer full): name of the loop device associated with the given @file
*
* Tech category: %BD_LOOP_TECH_LOOP-%BD_LOOP_TECH_MODE_QUERY
*/
gchar* bd_loop_get_loop_name (const gchar *file, GError **error) {
return _bd_loop_get_loop_name (file, error);
}
static gboolean bd_loop_setup_stub (const gchar *file, guint64 offset, guint64 size, gboolean read_only, gboolean part_scan, const gchar **loop_name, GError **error) {
g_critical ("The function 'bd_loop_setup' called, but not implemented!");
g_set_error (error, BD_INIT_ERROR, BD_INIT_ERROR_NOT_IMPLEMENTED,
"The function 'bd_loop_setup' called, but not implemented!");
return FALSE;
}
static gboolean (*_bd_loop_setup) (const gchar *file, guint64 offset, guint64 size, gboolean read_only, gboolean part_scan, const gchar **loop_name, GError **error) = bd_loop_setup_stub;
/**
* bd_loop_setup:
* @file: file to setup as a loop device
* @offset: offset of the start of the device (in @file)
* @size: maximum size of the device (or 0 to leave unspecified)
* @read_only: whether to setup as read-only (%TRUE) or read-write (%FALSE)
* @part_scan: whether to enforce partition scan on the newly created device or not
* @loop_name: (allow-none) (out): if not %NULL, it is used to store the name of the loop device
* @error: (out): place to store error (if any)
*
* Returns: whether the @file was successfully setup as a loop device or not
*
* Tech category: %BD_LOOP_TECH_LOOP-%BD_LOOP_TECH_MODE_CREATE
*/
gboolean bd_loop_setup (const gchar *file, guint64 offset, guint64 size, gboolean read_only, gboolean part_scan, const gchar **loop_name, GError **error) {
return _bd_loop_setup (file, offset, size, read_only, part_scan, loop_name, error);
}
static gboolean bd_loop_setup_from_fd_stub (gint fd, guint64 offset, guint64 size, gboolean read_only, gboolean part_scan, const gchar **loop_name, GError **error) {
g_critical ("The function 'bd_loop_setup_from_fd' called, but not implemented!");
g_set_error (error, BD_INIT_ERROR, BD_INIT_ERROR_NOT_IMPLEMENTED,
"The function 'bd_loop_setup_from_fd' called, but not implemented!");
return FALSE;
}
static gboolean (*_bd_loop_setup_from_fd) (gint fd, guint64 offset, guint64 size, gboolean read_only, gboolean part_scan, const gchar **loop_name, GError **error) = bd_loop_setup_from_fd_stub;
/**
* bd_loop_setup_from_fd:
* @fd: file descriptor for a file to setup as a new loop device
* @offset: offset of the start of the device (in file given by @fd)
* @size: maximum size of the device (or 0 to leave unspecified)
* @read_only: whether to setup as read-only (%TRUE) or read-write (%FALSE)
* @part_scan: whether to enforce partition scan on the newly created device or not
* @loop_name: (allow-none) (out): if not %NULL, it is used to store the name of the loop device
* @error: (out): place to store error (if any)
*
* Returns: whether an new loop device was successfully setup for @fd or not
*
* Tech category: %BD_LOOP_TECH_LOOP-%BD_LOOP_TECH_MODE_CREATE
*/
gboolean bd_loop_setup_from_fd (gint fd, guint64 offset, guint64 size, gboolean read_only, gboolean part_scan, const gchar **loop_name, GError **error) {
return _bd_loop_setup_from_fd (fd, offset, size, read_only, part_scan, loop_name, error);
}
static gboolean bd_loop_teardown_stub (const gchar *loop, GError **error) {
g_critical ("The function 'bd_loop_teardown' called, but not implemented!");
g_set_error (error, BD_INIT_ERROR, BD_INIT_ERROR_NOT_IMPLEMENTED,
"The function 'bd_loop_teardown' called, but not implemented!");
return FALSE;
}
static gboolean (*_bd_loop_teardown) (const gchar *loop, GError **error) = bd_loop_teardown_stub;
/**
* bd_loop_teardown:
* @loop: path or name of the loop device to tear down
* @error: (out): place to store error (if any)
*
* Returns: whether the @loop device was successfully torn down or not
*
* Tech category: %BD_LOOP_TECH_LOOP-%BD_LOOP_TECH_MODE_DESTROY
*/
gboolean bd_loop_teardown (const gchar *loop, GError **error) {
return _bd_loop_teardown (loop, error);
}
static gboolean bd_loop_get_autoclear_stub (const gchar *loop, GError **error) {
g_critical ("The function 'bd_loop_get_autoclear' called, but not implemented!");
g_set_error (error, BD_INIT_ERROR, BD_INIT_ERROR_NOT_IMPLEMENTED,
"The function 'bd_loop_get_autoclear' called, but not implemented!");
return FALSE;
}
static gboolean (*_bd_loop_get_autoclear) (const gchar *loop, GError **error) = bd_loop_get_autoclear_stub;
/**
* bd_loop_get_autoclear:
* @loop: path or name of the loop device
* @error: (out): place to store error (if any)
*
* Returns: whether the autoclear flag is set on the @loop device or not (if %FALSE, @error may be set)
*
* Tech category: %BD_LOOP_TECH_LOOP-%BD_LOOP_TECH_MODE_QUERY
*/
gboolean bd_loop_get_autoclear (const gchar *loop, GError **error) {
return _bd_loop_get_autoclear (loop, error);
}
static gboolean bd_loop_set_autoclear_stub (const gchar *loop, gboolean autoclear, GError **error) {
g_critical ("The function 'bd_loop_set_autoclear' called, but not implemented!");
g_set_error (error, BD_INIT_ERROR, BD_INIT_ERROR_NOT_IMPLEMENTED,
"The function 'bd_loop_set_autoclear' called, but not implemented!");
return FALSE;
}
static gboolean (*_bd_loop_set_autoclear) (const gchar *loop, gboolean autoclear, GError **error) = bd_loop_set_autoclear_stub;
/**
* bd_loop_set_autoclear:
* @loop: path or name of the loop device
* @autoclear: whether to set or unset the autoclear flag
* @error: (out): place to store error (if any)
*
* Returns: whether the autoclear flag was successfully set on the @loop device or not
*
* Tech category: %BD_LOOP_TECH_LOOP-%BD_LOOP_TECH_MODE_MODIFY
*/
gboolean bd_loop_set_autoclear (const gchar *loop, gboolean autoclear, GError **error) {
return _bd_loop_set_autoclear (loop, autoclear, error);
}
static gpointer load_loop_from_plugin(const gchar *so_name) {
void *handle = NULL;
char *error = NULL;
gboolean (*check_fn) (void) = NULL;
gboolean (*init_fn) (void) = NULL;
handle = dlopen(so_name, RTLD_LAZY);
if (!handle) {
g_warning("failed to load module loop: %s", dlerror());
return NULL;
}
dlerror();
* (void**) (&check_fn) = dlsym(handle, "bd_loop_check_deps");
if ((error = dlerror()) != NULL)
g_debug("failed to load the check() function for loop: %s", error);
/* coverity[dead_error_condition] */
if (!g_getenv ("LIBBLOCKDEV_SKIP_DEP_CHECKS") && check_fn && !check_fn()) {
dlclose(handle);
return NULL;
}
check_fn = NULL;
dlerror();
* (void**) (&init_fn) = dlsym(handle, "bd_loop_init");
if ((error = dlerror()) != NULL)
g_debug("failed to load the init() function for loop: %s", error);
/* coverity[dead_error_condition] */
if (init_fn && !init_fn()) {
dlclose(handle);
return NULL;
}
init_fn = NULL;
dlerror();
* (void**) (&_bd_loop_is_tech_avail) = dlsym(handle, "bd_loop_is_tech_avail");
if ((error = dlerror()) != NULL)
g_warning("failed to load bd_loop_is_tech_avail: %s", error);
dlerror();
* (void**) (&_bd_loop_get_backing_file) = dlsym(handle, "bd_loop_get_backing_file");
if ((error = dlerror()) != NULL)
g_warning("failed to load bd_loop_get_backing_file: %s", error);
dlerror();
* (void**) (&_bd_loop_get_loop_name) = dlsym(handle, "bd_loop_get_loop_name");
if ((error = dlerror()) != NULL)
g_warning("failed to load bd_loop_get_loop_name: %s", error);
dlerror();
* (void**) (&_bd_loop_setup) = dlsym(handle, "bd_loop_setup");
if ((error = dlerror()) != NULL)
g_warning("failed to load bd_loop_setup: %s", error);
dlerror();
* (void**) (&_bd_loop_setup_from_fd) = dlsym(handle, "bd_loop_setup_from_fd");
if ((error = dlerror()) != NULL)
g_warning("failed to load bd_loop_setup_from_fd: %s", error);
dlerror();
* (void**) (&_bd_loop_teardown) = dlsym(handle, "bd_loop_teardown");
if ((error = dlerror()) != NULL)
g_warning("failed to load bd_loop_teardown: %s", error);
dlerror();
* (void**) (&_bd_loop_get_autoclear) = dlsym(handle, "bd_loop_get_autoclear");
if ((error = dlerror()) != NULL)
g_warning("failed to load bd_loop_get_autoclear: %s", error);
dlerror();
* (void**) (&_bd_loop_set_autoclear) = dlsym(handle, "bd_loop_set_autoclear");
if ((error = dlerror()) != NULL)
g_warning("failed to load bd_loop_set_autoclear: %s", error);
return handle;
}
static gboolean unload_loop (gpointer handle) {
char *error = NULL;
gboolean (*close_fn) (void) = NULL;
_bd_loop_is_tech_avail = bd_loop_is_tech_avail_stub;
_bd_loop_get_backing_file = bd_loop_get_backing_file_stub;
_bd_loop_get_loop_name = bd_loop_get_loop_name_stub;
_bd_loop_setup = bd_loop_setup_stub;
_bd_loop_setup_from_fd = bd_loop_setup_from_fd_stub;
_bd_loop_teardown = bd_loop_teardown_stub;
_bd_loop_get_autoclear = bd_loop_get_autoclear_stub;
_bd_loop_set_autoclear = bd_loop_set_autoclear_stub;
dlerror();
* (void**) (&close_fn) = dlsym(handle, "bd_loop_close");
if (((error = dlerror()) != NULL) || !close_fn)
g_debug("failed to load the close_plugin() function for loop: %s", error);
/* coverity[dead_error_condition] */
if (close_fn) {
close_fn();
}
return dlclose(handle) == 0;
}