Blame SOURCES/0007-lvm-devices-file-support.patch

940a02
From e364883416785d51ff8eb132b63bd802ab0ccfe9 Mon Sep 17 00:00:00 2001
940a02
From: Vojtech Trefny <vtrefny@redhat.com>
940a02
Date: Tue, 13 Jul 2021 13:22:05 +0200
940a02
Subject: [PATCH 1/8] lvm: Allow configuring global "device filter" for LVM
940a02
 commands
940a02
940a02
Starting with 2.03.12 LVM introduces a new system for telling LVM
940a02
which devices it should use. The old device filters in config are
940a02
no longer working and we need to use either the system.devices
940a02
config file in /etc/lvm/devices (default behaviour) or specify
940a02
all allowed devices using the new --devices option. Because this
940a02
option must be specified for every call which might be incovenient
940a02
for our users, this commit introduces a new function to configure
940a02
this globally, which we already do for the --config option.
940a02
---
940a02
 src/lib/plugin_apis/lvm.api |  23 +++
940a02
 src/plugins/lvm-dbus.c      |  74 ++++++++-
940a02
 src/plugins/lvm.c           |  97 ++++++++++--
940a02
 src/plugins/lvm.h           |   4 +
940a02
 tests/library_test.py       | 304 ++++++++++++++++++++----------------
940a02
 tests/lvm_dbus_tests.py     |  47 +++++-
940a02
 tests/lvm_test.py           |  50 ++++++
940a02
 tests/overrides_test.py     |  23 ++-
940a02
 8 files changed, 469 insertions(+), 153 deletions(-)
940a02
940a02
diff --git a/src/lib/plugin_apis/lvm.api b/src/lib/plugin_apis/lvm.api
940a02
index 563c104..62f602f 100644
940a02
--- a/src/lib/plugin_apis/lvm.api
940a02
+++ b/src/lib/plugin_apis/lvm.api
940a02
@@ -601,6 +601,7 @@ typedef enum {
940a02
     BD_LVM_TECH_CACHE_CALCS,
940a02
     BD_LVM_TECH_GLOB_CONF,
940a02
     BD_LVM_TECH_VDO,
940a02
+    BD_LVM_TECH_DEVICES,
940a02
 } BDLVMTech;
940a02
 
940a02
 typedef enum {
940a02
@@ -1214,6 +1215,28 @@ gboolean bd_lvm_set_global_config (const gchar *new_config, GError **error);
940a02
  */
940a02
 gchar* bd_lvm_get_global_config (GError **error);
940a02
 
940a02
+/**
940a02
+ * bd_lvm_set_devices_filter:
940a02
+ * @devices: (allow-none) (array zero-terminated=1): list of devices for lvm commands to work on
940a02
+ * @error: (out): place to store error (if any)
940a02
+ *
940a02
+ * Returns: whether the devices filter was successfully set or not
940a02
+ *
940a02
+ * Tech category: %BD_LVM_TECH_DEVICES no mode (it is ignored)
940a02
+ */
940a02
+gboolean bd_lvm_set_devices_filter (const gchar **devices, GError **error);
940a02
+
940a02
+/**
940a02
+ * bd_lvm_get_devices_filter:
940a02
+ * @error: (out): place to store error (if any)
940a02
+ *
940a02
+ * Returns: (transfer full) (array zero-terminated=1): a copy of a string representation of
940a02
+ *                                                     the currently set LVM devices filter
940a02
+ *
940a02
+ * Tech category: %BD_LVM_TECH_DEVICES no mode (it is ignored)
940a02
+ */
940a02
+gchar** bd_lvm_get_devices_filter (GError **error);
940a02
+
940a02
 /**
940a02
  * bd_lvm_cache_get_default_md_size:
940a02
  * @cache_size: size of the cache to determine MD size for
940a02
diff --git a/src/plugins/lvm-dbus.c b/src/plugins/lvm-dbus.c
940a02
index 144551f..d1726ed 100644
940a02
--- a/src/plugins/lvm-dbus.c
940a02
+++ b/src/plugins/lvm-dbus.c
940a02
@@ -35,6 +35,8 @@
940a02
 static GMutex global_config_lock;
940a02
 static gchar *global_config_str = NULL;
940a02
 
940a02
+static gchar *global_devices_str = NULL;
940a02
+
940a02
 #define LVM_BUS_NAME "com.redhat.lvmdbus1"
940a02
 #define LVM_OBJ_PREFIX "/com/redhat/lvmdbus1"
940a02
 #define MANAGER_OBJ "/com/redhat/lvmdbus1/Manager"
940a02
@@ -247,6 +249,14 @@ static volatile guint avail_features = 0;
940a02
 static volatile guint avail_module_deps = 0;
940a02
 static GMutex deps_check_lock;
940a02
 
940a02
+#define DEPS_LVMDEVICES 0
940a02
+#define DEPS_LVMDEVICES_MASK (1 << DEPS_LVMDEVICES)
940a02
+#define DEPS_LAST 1
940a02
+
940a02
+static const UtilDep deps[DEPS_LAST] = {
940a02
+    {"lvmdevices", NULL, NULL, NULL},
940a02
+};
940a02
+
940a02
 #define DBUS_DEPS_LVMDBUSD 0
940a02
 #define DBUS_DEPS_LVMDBUSD_MASK (1 << DBUS_DEPS_LVMDBUSD)
940a02
 #define DBUS_DEPS_LAST 1
940a02
@@ -385,6 +395,8 @@ gboolean bd_lvm_is_tech_avail (BDLVMTech tech, guint64 mode, GError **error) {
940a02
             return check_dbus_deps (&avail_dbus_deps, DBUS_DEPS_LVMDBUSD_MASK, dbus_deps, DBUS_DEPS_LAST, &deps_check_lock, error) &&
940a02
                    check_features (&avail_features, FEATURES_VDO_MASK, features, FEATURES_LAST, &deps_check_lock, error) &&
940a02
                    check_module_deps (&avail_module_deps, MODULE_DEPS_VDO_MASK, module_deps, MODULE_DEPS_LAST, &deps_check_lock, error);
940a02
+    case BD_LVM_TECH_DEVICES:
940a02
+        return check_deps (&avail_deps, DEPS_LVMDEVICES_MASK, deps, DEPS_LAST, &deps_check_lock, error);
940a02
     default:
940a02
         /* everything is supported by this implementation of the plugin */
940a02
         return check_dbus_deps (&avail_dbus_deps, DBUS_DEPS_LVMDBUSD_MASK, dbus_deps, DBUS_DEPS_LAST, &deps_check_lock, error);
940a02
@@ -522,6 +534,7 @@ static gboolean unbox_params_and_add (GVariant *params, GVariantBuilder *builder
940a02
 
940a02
 static GVariant* call_lvm_method (const gchar *obj, const gchar *intf, const gchar *method, GVariant *params, GVariant *extra_params, const BDExtraArg **extra_args, guint64 *task_id, guint64 *progress_id, gboolean lock_config, GError **error) {
940a02
     GVariant *config = NULL;
940a02
+    GVariant *devices = NULL;
940a02
     GVariant *param = NULL;
940a02
     GVariantIter iter;
940a02
     GVariantBuilder builder;
940a02
@@ -543,8 +556,8 @@ static GVariant* call_lvm_method (const gchar *obj, const gchar *intf, const gch
940a02
     if (lock_config)
940a02
         g_mutex_lock (&global_config_lock);
940a02
 
940a02
-    if (global_config_str || extra_params || extra_args) {
940a02
-        if (global_config_str || extra_args) {
940a02
+    if (global_config_str || global_devices_str || extra_params || extra_args) {
940a02
+        if (global_config_str || global_devices_str || extra_args) {
940a02
             /* add the global config to the extra_params */
940a02
             g_variant_builder_init (&extra_builder, G_VARIANT_TYPE_DICTIONARY);
940a02
 
940a02
@@ -565,6 +578,11 @@ static GVariant* call_lvm_method (const gchar *obj, const gchar *intf, const gch
940a02
                 g_variant_builder_add (&extra_builder, "{sv}", "--config", config);
940a02
                 added_extra = TRUE;
940a02
             }
940a02
+            if (global_devices_str) {
940a02
+                devices = g_variant_new ("s", global_devices_str);
940a02
+                g_variant_builder_add (&extra_builder, "{sv}", "--devices", devices);
940a02
+                added_extra = TRUE;
940a02
+            }
940a02
 
940a02
             if (added_extra)
940a02
                 config_extra_params = g_variant_builder_end (&extra_builder);
940a02
@@ -2651,6 +2669,58 @@ gchar* bd_lvm_get_global_config (GError **error UNUSED) {
940a02
     return ret;
940a02
 }
940a02
 
940a02
+/**
940a02
+ * bd_lvm_set_devices_filter:
940a02
+ * @devices: (allow-none) (array zero-terminated=1): list of devices for lvm commands to work on
940a02
+ * @error: (out): place to store error (if any)
940a02
+ *
940a02
+ * Returns: whether the devices filter was successfully set or not
940a02
+ *
940a02
+ * Tech category: %BD_LVM_TECH_DEVICES no mode (it is ignored)
940a02
+ */
940a02
+gboolean bd_lvm_set_devices_filter (const gchar **devices, GError **error) {
940a02
+    if (!bd_lvm_is_tech_avail (BD_LVM_TECH_DEVICES, 0, error))
940a02
+        return FALSE;
940a02
+
940a02
+    g_mutex_lock (&global_config_lock);
940a02
+
940a02
+    /* first free the old value */
940a02
+    g_free (global_devices_str);
940a02
+
940a02
+    /* now store the new one */
940a02
+    if (!devices || !(*devices))
940a02
+        global_devices_str = NULL;
940a02
+    else
940a02
+        global_devices_str = g_strjoinv (",", (gchar **) devices);
940a02
+
940a02
+    g_mutex_unlock (&global_config_lock);
940a02
+    return TRUE;
940a02
+}
940a02
+
940a02
+/**
940a02
+ * bd_lvm_get_devices_filter:
940a02
+ * @error: (out): place to store error (if any)
940a02
+ *
940a02
+ * Returns: (transfer full) (array zero-terminated=1): a copy of a string representation of
940a02
+ *                                                     the currently set LVM devices filter
940a02
+ *
940a02
+ * Tech category: %BD_LVM_TECH_DEVICES no mode (it is ignored)
940a02
+ */
940a02
+gchar** bd_lvm_get_devices_filter (GError **error UNUSED) {
940a02
+    gchar **ret = NULL;
940a02
+
940a02
+    g_mutex_lock (&global_config_lock);
940a02
+
940a02
+    if (global_devices_str)
940a02
+        ret = g_strsplit (global_devices_str, ",", -1);
940a02
+    else
940a02
+        ret = NULL;
940a02
+
940a02
+    g_mutex_unlock (&global_config_lock);
940a02
+
940a02
+    return ret;
940a02
+}
940a02
+
940a02
 /**
940a02
  * bd_lvm_cache_get_default_md_size:
940a02
  * @cache_size: size of the cache to determine MD size for
940a02
diff --git a/src/plugins/lvm.c b/src/plugins/lvm.c
940a02
index 2be1dbd..c0d8198 100644
940a02
--- a/src/plugins/lvm.c
940a02
+++ b/src/plugins/lvm.c
940a02
@@ -34,6 +34,8 @@
940a02
 static GMutex global_config_lock;
940a02
 static gchar *global_config_str = NULL;
940a02
 
940a02
+static gchar *global_devices_str = NULL;
940a02
+
940a02
 /**
940a02
  * SECTION: lvm
940a02
  * @short_description: plugin for operations with LVM
940a02
@@ -212,10 +214,13 @@ static GMutex deps_check_lock;
940a02
 
940a02
 #define DEPS_LVM 0
940a02
 #define DEPS_LVM_MASK (1 << DEPS_LVM)
940a02
-#define DEPS_LAST 1
940a02
+#define DEPS_LVMDEVICES 1
940a02
+#define DEPS_LVMDEVICES_MASK (1 << DEPS_LVMDEVICES)
940a02
+#define DEPS_LAST 2
940a02
 
940a02
 static const UtilDep deps[DEPS_LAST] = {
940a02
     {"lvm", LVM_MIN_VERSION, "version", "LVM version:\\s+([\\d\\.]+)"},
940a02
+    {"lvmdevices", NULL, NULL, NULL},
940a02
 };
940a02
 
940a02
 #define FEATURES_VDO 0
940a02
@@ -327,6 +332,8 @@ gboolean bd_lvm_is_tech_avail (BDLVMTech tech, guint64 mode, GError **error) {
940a02
     case BD_LVM_TECH_VDO:
940a02
             return check_features (&avail_features, FEATURES_VDO_MASK, features, FEATURES_LAST, &deps_check_lock, error) &&
940a02
                    check_module_deps (&avail_module_deps, MODULE_DEPS_VDO_MASK, module_deps, MODULE_DEPS_LAST, &deps_check_lock, error);
940a02
+    case BD_LVM_TECH_DEVICES:
940a02
+            return check_deps (&avail_deps, DEPS_LVMDEVICES_MASK, deps, DEPS_LAST, &deps_check_lock, error);
940a02
     default:
940a02
         /* everything is supported by this implementation of the plugin */
940a02
         return check_deps (&avail_deps, DEPS_LVM_MASK, deps, DEPS_LAST, &deps_check_lock, error);
940a02
@@ -337,6 +344,8 @@ static gboolean call_lvm_and_report_error (const gchar **args, const BDExtraArg
940a02
     gboolean success = FALSE;
940a02
     guint i = 0;
940a02
     guint args_length = g_strv_length ((gchar **) args);
940a02
+    g_autofree gchar *config_arg = NULL;
940a02
+    g_autofree gchar *devices_arg = NULL;
940a02
 
940a02
     if (!check_deps (&avail_deps, DEPS_LVM_MASK, deps, DEPS_LAST, &deps_check_lock, error))
940a02
         return FALSE;
940a02
@@ -345,20 +354,26 @@ static gboolean call_lvm_and_report_error (const gchar **args, const BDExtraArg
940a02
     if (lock_config)
940a02
         g_mutex_lock (&global_config_lock);
940a02
 
940a02
-    /* allocate enough space for the args plus "lvm", "--config" and NULL */
940a02
-    const gchar **argv = g_new0 (const gchar*, args_length + 3);
940a02
+    /* allocate enough space for the args plus "lvm", "--config", "--devices" and NULL */
940a02
+    const gchar **argv = g_new0 (const gchar*, args_length + 4);
940a02
 
940a02
     /* construct argv from args with "lvm" prepended */
940a02
     argv[0] = "lvm";
940a02
     for (i=0; i < args_length; i++)
940a02
         argv[i+1] = args[i];
940a02
-    argv[args_length + 1] = global_config_str ? g_strdup_printf("--config=%s", global_config_str) : NULL;
940a02
-    argv[args_length + 2] = NULL;
940a02
+    if (global_config_str) {
940a02
+        config_arg = g_strdup_printf("--config=%s", global_config_str);
940a02
+        argv[++args_length] = config_arg;
940a02
+    }
940a02
+    if (global_devices_str) {
940a02
+        devices_arg = g_strdup_printf("--devices=%s", global_devices_str);
940a02
+        argv[++args_length] = devices_arg;
940a02
+    }
940a02
+    argv[++args_length] = NULL;
940a02
 
940a02
     success = bd_utils_exec_and_report_error (argv, extra, error);
940a02
     if (lock_config)
940a02
         g_mutex_unlock (&global_config_lock);
940a02
-    g_free ((gchar *) argv[args_length + 1]);
940a02
     g_free (argv);
940a02
 
940a02
     return success;
940a02
@@ -368,6 +383,8 @@ static gboolean call_lvm_and_capture_output (const gchar **args, const BDExtraAr
940a02
     gboolean success = FALSE;
940a02
     guint i = 0;
940a02
     guint args_length = g_strv_length ((gchar **) args);
940a02
+    g_autofree gchar *config_arg = NULL;
940a02
+    g_autofree gchar *devices_arg = NULL;
940a02
 
940a02
     if (!check_deps (&avail_deps, DEPS_LVM_MASK, deps, DEPS_LAST, &deps_check_lock, error))
940a02
         return FALSE;
940a02
@@ -375,19 +392,25 @@ static gboolean call_lvm_and_capture_output (const gchar **args, const BDExtraAr
940a02
     /* don't allow global config string changes during the run */
940a02
     g_mutex_lock (&global_config_lock);
940a02
 
940a02
-    /* allocate enough space for the args plus "lvm", "--config" and NULL */
940a02
-    const gchar **argv = g_new0 (const gchar*, args_length + 3);
940a02
+    /* allocate enough space for the args plus "lvm", "--config", "--devices" and NULL */
940a02
+    const gchar **argv = g_new0 (const gchar*, args_length + 4);
940a02
 
940a02
     /* construct argv from args with "lvm" prepended */
940a02
     argv[0] = "lvm";
940a02
     for (i=0; i < args_length; i++)
940a02
         argv[i+1] = args[i];
940a02
-    argv[args_length + 1] = global_config_str ? g_strdup_printf("--config=%s", global_config_str) : NULL;
940a02
-    argv[args_length + 2] = NULL;
940a02
+    if (global_config_str) {
940a02
+        config_arg = g_strdup_printf("--config=%s", global_config_str);
940a02
+        argv[++args_length] = config_arg;
940a02
+    }
940a02
+    if (global_devices_str) {
940a02
+        devices_arg = g_strdup_printf("--devices=%s", global_devices_str);
940a02
+        argv[++args_length] = devices_arg;
940a02
+    }
940a02
+    argv[++args_length] = NULL;
940a02
 
940a02
     success = bd_utils_exec_and_capture_output (argv, extra, output, error);
940a02
     g_mutex_unlock (&global_config_lock);
940a02
-    g_free ((gchar *) argv[args_length + 1]);
940a02
     g_free (argv);
940a02
 
940a02
     return success;
940a02
@@ -2018,6 +2041,58 @@ gchar* bd_lvm_get_global_config (GError **error UNUSED) {
940a02
     return ret;
940a02
 }
940a02
 
940a02
+/**
940a02
+ * bd_lvm_set_devices_filter:
940a02
+ * @devices: (allow-none) (array zero-terminated=1): list of devices for lvm commands to work on
940a02
+ * @error: (out): place to store error (if any)
940a02
+ *
940a02
+ * Returns: whether the devices filter was successfully set or not
940a02
+ *
940a02
+ * Tech category: %BD_LVM_TECH_DEVICES no mode (it is ignored)
940a02
+ */
940a02
+gboolean bd_lvm_set_devices_filter (const gchar **devices, GError **error) {
940a02
+    if (!bd_lvm_is_tech_avail (BD_LVM_TECH_DEVICES, 0, error))
940a02
+        return FALSE;
940a02
+
940a02
+    g_mutex_lock (&global_config_lock);
940a02
+
940a02
+    /* first free the old value */
940a02
+    g_free (global_devices_str);
940a02
+
940a02
+    /* now store the new one */
940a02
+    if (!devices || !(*devices))
940a02
+        global_devices_str = NULL;
940a02
+    else
940a02
+        global_devices_str = g_strjoinv (",", (gchar **) devices);
940a02
+
940a02
+    g_mutex_unlock (&global_config_lock);
940a02
+    return TRUE;
940a02
+}
940a02
+
940a02
+/**
940a02
+ * bd_lvm_get_devices_filter:
940a02
+ * @error: (out): place to store error (if any)
940a02
+ *
940a02
+ * Returns: (transfer full) (array zero-terminated=1): a copy of a string representation of
940a02
+ *                                                     the currently set LVM devices filter
940a02
+ *
940a02
+ * Tech category: %BD_LVM_TECH_DEVICES no mode (it is ignored)
940a02
+ */
940a02
+gchar** bd_lvm_get_devices_filter (GError **error UNUSED) {
940a02
+    gchar **ret = NULL;
940a02
+
940a02
+    g_mutex_lock (&global_config_lock);
940a02
+
940a02
+    if (global_devices_str)
940a02
+        ret = g_strsplit (global_devices_str, ",", -1);
940a02
+    else
940a02
+        ret = NULL;
940a02
+
940a02
+    g_mutex_unlock (&global_config_lock);
940a02
+
940a02
+    return ret;
940a02
+}
940a02
+
940a02
 /**
940a02
  * bd_lvm_cache_get_default_md_size:
940a02
  * @cache_size: size of the cache to determine MD size for
940a02
diff --git a/src/plugins/lvm.h b/src/plugins/lvm.h
940a02
index 2162d76..8063693 100644
940a02
--- a/src/plugins/lvm.h
940a02
+++ b/src/plugins/lvm.h
940a02
@@ -216,6 +216,7 @@ typedef enum {
940a02
     BD_LVM_TECH_CACHE_CALCS,
940a02
     BD_LVM_TECH_GLOB_CONF,
940a02
     BD_LVM_TECH_VDO,
940a02
+    BD_LVM_TECH_DEVICES,
940a02
 } BDLVMTech;
940a02
 
940a02
 typedef enum {
940a02
@@ -289,6 +290,9 @@ gboolean bd_lvm_thsnapshotcreate (const gchar *vg_name, const gchar *origin_name
940a02
 gboolean bd_lvm_set_global_config (const gchar *new_config, GError **error);
940a02
 gchar* bd_lvm_get_global_config (GError **error);
940a02
 
940a02
+gboolean bd_lvm_set_devices_filter (const gchar **devices, GError **error);
940a02
+gchar** bd_lvm_get_devices_filter (GError **error);
940a02
+
940a02
 guint64 bd_lvm_cache_get_default_md_size (guint64 cache_size, GError **error);
940a02
 const gchar* bd_lvm_cache_get_mode_str (BDLVMCacheMode mode, GError **error);
940a02
 BDLVMCacheMode bd_lvm_cache_get_mode_from_str (const gchar *mode_str, GError **error);
940a02
diff --git a/tests/library_test.py b/tests/library_test.py
940a02
index 08e44fd..efd17bd 100644
940a02
--- a/tests/library_test.py
940a02
+++ b/tests/library_test.py
940a02
@@ -13,18 +13,178 @@ class LibraryOpsTestCase(unittest.TestCase):
940a02
     # all plugins except for 'btrfs', 'fs' and 'mpath' -- these don't have all
940a02
     # the dependencies on CentOS/Debian and we don't need them for this test
940a02
     requested_plugins = BlockDev.plugin_specs_from_names(("crypto", "dm",
940a02
-                                                          "kbd", "loop", "lvm",
940a02
+                                                          "kbd", "loop",
940a02
                                                           "mdraid", "part", "swap"))
940a02
 
940a02
+    @classmethod
940a02
+    def setUpClass(cls):
940a02
+        if not BlockDev.is_initialized():
940a02
+            BlockDev.init(cls.requested_plugins, None)
940a02
+        else:
940a02
+            BlockDev.reinit(cls.requested_plugins, True, None)
940a02
+
940a02
+    @classmethod
940a02
+    def tearDownClass(cls):
940a02
+        BlockDev.switch_init_checks(True)
940a02
+
940a02
+    def my_log_func(self, level, msg):
940a02
+        # not much to verify here
940a02
+        self.assertTrue(isinstance(level, int))
940a02
+        self.assertTrue(isinstance(msg, str))
940a02
+
940a02
+        self.log += msg + "\n"
940a02
+
940a02
+    @tag_test(TestTags.CORE)
940a02
+    def test_logging_setup(self):
940a02
+        """Verify that setting up logging works as expected"""
940a02
+
940a02
+        self.assertTrue(BlockDev.reinit(self.requested_plugins, False, self.my_log_func))
940a02
+
940a02
+        succ = BlockDev.utils_exec_and_report_error(["true"])
940a02
+        self.assertTrue(succ)
940a02
+
940a02
+        # reinit with no logging function should change nothing about logging
940a02
+        self.assertTrue(BlockDev.reinit(self.requested_plugins, False, None))
940a02
+
940a02
+        succ, out = BlockDev.utils_exec_and_capture_output(["echo", "hi"])
940a02
+        self.assertTrue(succ)
940a02
+        self.assertEqual(out, "hi\n")
940a02
+
940a02
+        match = re.search(r'Running \[(\d+)\] true', self.log)
940a02
+        self.assertIsNot(match, None)
940a02
+        task_id1 = match.group(1)
940a02
+        match = re.search(r'Running \[(\d+)\] echo hi', self.log)
940a02
+        self.assertIsNot(match, None)
940a02
+        task_id2 = match.group(1)
940a02
+
940a02
+        self.assertIn("...done [%s] (exit code: 0)" % task_id1, self.log)
940a02
+        self.assertIn("stdout[%s]:" % task_id1, self.log)
940a02
+        self.assertIn("stderr[%s]:" % task_id1, self.log)
940a02
+
940a02
+        self.assertIn("stdout[%s]: hi" % task_id2, self.log)
940a02
+        self.assertIn("stderr[%s]:" % task_id2, self.log)
940a02
+        self.assertIn("...done [%s] (exit code: 0)" % task_id2, self.log)
940a02
+
940a02
+    @tag_test(TestTags.CORE)
940a02
+    def test_require_plugins(self):
940a02
+        """Verify that loading only required plugins works as expected"""
940a02
+
940a02
+        ps = BlockDev.PluginSpec()
940a02
+        ps.name = BlockDev.Plugin.SWAP
940a02
+        ps.so_name = ""
940a02
+        self.assertTrue(BlockDev.reinit([ps], True, None))
940a02
+        self.assertEqual(BlockDev.get_available_plugin_names(), ["swap"])
940a02
+        self.assertTrue(BlockDev.reinit(self.requested_plugins, True, None))
940a02
+
940a02
+    @tag_test(TestTags.CORE)
940a02
+    def test_not_implemented(self):
940a02
+        """Verify that unloaded/unimplemented functions report errors"""
940a02
+
940a02
+        # should be loaded and working
940a02
+        self.assertTrue(BlockDev.md_canonicalize_uuid("3386ff85:f5012621:4a435f06:1eb47236"))
940a02
+
940a02
+        ps = BlockDev.PluginSpec()
940a02
+        ps.name = BlockDev.Plugin.SWAP
940a02
+        ps.so_name = ""
940a02
+        self.assertTrue(BlockDev.reinit([ps], True, None))
940a02
+        self.assertEqual(BlockDev.get_available_plugin_names(), ["swap"])
940a02
+
940a02
+        # no longer loaded
940a02
+        with self.assertRaises(GLib.GError):
940a02
+            BlockDev.md_canonicalize_uuid("3386ff85:f5012621:4a435f06:1eb47236")
940a02
+
940a02
+        self.assertTrue(BlockDev.reinit(self.requested_plugins, True, None))
940a02
+
940a02
+        # loaded again
940a02
+        self.assertTrue(BlockDev.md_canonicalize_uuid("3386ff85:f5012621:4a435f06:1eb47236"))
940a02
+
940a02
+    def test_ensure_init(self):
940a02
+        """Verify that ensure_init just returns when already initialized"""
940a02
+
940a02
+        # the library is already initialized, ensure_init() shonuld do nothing
940a02
+        avail_plugs = BlockDev.get_available_plugin_names()
940a02
+        self.assertTrue(BlockDev.ensure_init(self.requested_plugins, None))
940a02
+        self.assertEqual(avail_plugs, BlockDev.get_available_plugin_names())
940a02
+
940a02
+        # reinit with a subset of plugins
940a02
+        plugins = BlockDev.plugin_specs_from_names(["swap", "part"])
940a02
+        self.assertTrue(BlockDev.reinit(plugins, True, None))
940a02
+        self.assertEqual(set(BlockDev.get_available_plugin_names()), set(["swap", "part"]))
940a02
+
940a02
+        # ensure_init with the same subset -> nothing should change
940a02
+        self.assertTrue(BlockDev.ensure_init(plugins, None))
940a02
+        self.assertEqual(set(BlockDev.get_available_plugin_names()), set(["swap", "part"]))
940a02
+
940a02
+        # ensure_init with more plugins -> extra plugins should be loaded
940a02
+        plugins = BlockDev.plugin_specs_from_names(["swap", "part", "crypto"])
940a02
+        self.assertTrue(BlockDev.ensure_init(plugins, None))
940a02
+        self.assertEqual(set(BlockDev.get_available_plugin_names()), set(["swap", "part", "crypto"]))
940a02
+
940a02
+        # reinit to unload all plugins
940a02
+        self.assertTrue(BlockDev.reinit([], True, None))
940a02
+        self.assertEqual(BlockDev.get_available_plugin_names(), [])
940a02
+
940a02
+        # ensure_init to load all plugins back
940a02
+        self.assertTrue(BlockDev.ensure_init(self.requested_plugins, None))
940a02
+        self.assertGreaterEqual(len(BlockDev.get_available_plugin_names()), 7)
940a02
+
940a02
+    def test_try_reinit(self):
940a02
+        """Verify that try_reinit() works as expected"""
940a02
+
940a02
+        # try reinitializing with only some utilities being available and thus
940a02
+        # only some plugins able to load
940a02
+        with fake_path("tests/lib_missing_utils", keep_utils=["swapon", "swapoff", "mkswap", "swaplabel"]):
940a02
+            succ, loaded = BlockDev.try_reinit(self.requested_plugins, True, None)
940a02
+            self.assertFalse(succ)
940a02
+            for plug_name in ("swap", "crypto"):
940a02
+                self.assertIn(plug_name, loaded)
940a02
+
940a02
+        # reset back to all plugins
940a02
+        self.assertTrue(BlockDev.reinit(self.requested_plugins, True, None))
940a02
+
940a02
+        # now the same with a subset of plugins requested
940a02
+        plugins = BlockDev.plugin_specs_from_names(["swap", "crypto"])
940a02
+        with fake_path("tests/lib_missing_utils", keep_utils=["swapon", "swapoff", "mkswap", "swaplabel"]):
940a02
+            succ, loaded = BlockDev.try_reinit(plugins, True, None)
940a02
+            self.assertTrue(succ)
940a02
+            self.assertEqual(set(loaded), set(["swap", "crypto"]))
940a02
+
940a02
+    def test_non_en_init(self):
940a02
+        """Verify that the library initializes with lang different from en_US"""
940a02
+
940a02
+        orig_lang = os.environ.get("LANG")
940a02
+        os.environ["LANG"] = "cs.CZ_UTF-8"
940a02
+        self.assertTrue(BlockDev.reinit(self.requested_plugins, True, None))
940a02
+        if orig_lang:
940a02
+            os.environ["LANG"] = orig_lang
940a02
+        else:
940a02
+            del os.environ["LANG"]
940a02
+        self.assertTrue(BlockDev.reinit(self.requested_plugins, True, None))
940a02
+
940a02
+
940a02
+class PluginsTestCase(unittest.TestCase):
940a02
+    # only LVM plugin for this test
940a02
+    requested_plugins = BlockDev.plugin_specs_from_names(("lvm",))
940a02
+
940a02
     orig_config_dir = ""
940a02
 
940a02
     @classmethod
940a02
     def setUpClass(cls):
940a02
+        BlockDev.switch_init_checks(False)
940a02
         if not BlockDev.is_initialized():
940a02
             BlockDev.init(cls.requested_plugins, None)
940a02
         else:
940a02
             BlockDev.reinit(cls.requested_plugins, True, None)
940a02
 
940a02
+        try:
940a02
+            cls.devices_avail = BlockDev.lvm_is_tech_avail(BlockDev.LVMTech.DEVICES, 0)
940a02
+        except:
940a02
+            cls.devices_avail = False
940a02
+
940a02
+    @classmethod
940a02
+    def tearDownClass(cls):
940a02
+        BlockDev.switch_init_checks(True)
940a02
+
940a02
     def setUp(self):
940a02
         self.orig_config_dir = os.environ.get("LIBBLOCKDEV_CONFIG_DIR", "")
940a02
         self.addCleanup(self._clean_up)
940a02
@@ -185,6 +345,12 @@ class LibraryOpsTestCase(unittest.TestCase):
940a02
     def test_plugin_fallback(self):
940a02
         """Verify that fallback when loading plugins works as expected"""
940a02
 
940a02
+        if not self.devices_avail:
940a02
+            self.skipTest("skipping plugin fallback test: missing some LVM dependencies")
940a02
+
940a02
+        BlockDev.switch_init_checks(True)
940a02
+        self.addCleanup(BlockDev.switch_init_checks, False)
940a02
+
940a02
         # library should be successfully initialized
940a02
         self.assertTrue(BlockDev.is_initialized())
940a02
 
940a02
@@ -206,7 +372,7 @@ class LibraryOpsTestCase(unittest.TestCase):
940a02
 
940a02
         # now reinit the library with the config preferring the new build
940a02
         orig_conf_dir = os.environ.get("LIBBLOCKDEV_CONFIG_DIR")
940a02
-        os.environ["LIBBLOCKDEV_CONFIG_DIR"] = "tests/plugin_prio_conf.d"
940a02
+        os.environ["LIBBLOCKDEV_CONFIG_DIR"] = "tests/test_configs/plugin_prio_conf.d"
940a02
         self.assertTrue(BlockDev.reinit(self.requested_plugins, True, None))
940a02
 
940a02
         # the original plugin should be loaded because the new one should fail
940a02
@@ -243,139 +409,9 @@ class LibraryOpsTestCase(unittest.TestCase):
940a02
 
940a02
         self.assertEqual(BlockDev.lvm_get_max_lv_size(), orig_max_size)
940a02
 
940a02
-    def my_log_func(self, level, msg):
940a02
-        # not much to verify here
940a02
-        self.assertTrue(isinstance(level, int))
940a02
-        self.assertTrue(isinstance(msg, str))
940a02
-
940a02
-        self.log += msg + "\n"
940a02
-
940a02
-    @tag_test(TestTags.CORE)
940a02
-    def test_logging_setup(self):
940a02
-        """Verify that setting up logging works as expected"""
940a02
-
940a02
-        self.assertTrue(BlockDev.reinit(self.requested_plugins, False, self.my_log_func))
940a02
-
940a02
-        succ = BlockDev.utils_exec_and_report_error(["true"])
940a02
-        self.assertTrue(succ)
940a02
-
940a02
-        # reinit with no logging function should change nothing about logging
940a02
-        self.assertTrue(BlockDev.reinit(self.requested_plugins, False, None))
940a02
-
940a02
-        succ, out = BlockDev.utils_exec_and_capture_output(["echo", "hi"])
940a02
-        self.assertTrue(succ)
940a02
-        self.assertEqual(out, "hi\n")
940a02
-
940a02
-        match = re.search(r'Running \[(\d+)\] true', self.log)
940a02
-        self.assertIsNot(match, None)
940a02
-        task_id1 = match.group(1)
940a02
-        match = re.search(r'Running \[(\d+)\] echo hi', self.log)
940a02
-        self.assertIsNot(match, None)
940a02
-        task_id2 = match.group(1)
940a02
-
940a02
-        self.assertIn("...done [%s] (exit code: 0)" % task_id1, self.log)
940a02
-        self.assertIn("stdout[%s]:" % task_id1, self.log)
940a02
-        self.assertIn("stderr[%s]:" % task_id1, self.log)
940a02
-
940a02
-        self.assertIn("stdout[%s]: hi" % task_id2, self.log)
940a02
-        self.assertIn("stderr[%s]:" % task_id2, self.log)
940a02
-        self.assertIn("...done [%s] (exit code: 0)" % task_id2, self.log)
940a02
-
940a02
-    @tag_test(TestTags.CORE)
940a02
-    def test_require_plugins(self):
940a02
-        """Verify that loading only required plugins works as expected"""
940a02
-
940a02
-        ps = BlockDev.PluginSpec()
940a02
-        ps.name = BlockDev.Plugin.SWAP
940a02
-        ps.so_name = ""
940a02
-        self.assertTrue(BlockDev.reinit([ps], True, None))
940a02
-        self.assertEqual(BlockDev.get_available_plugin_names(), ["swap"])
940a02
-        self.assertTrue(BlockDev.reinit(self.requested_plugins, True, None))
940a02
-
940a02
-    @tag_test(TestTags.CORE)
940a02
-    def test_not_implemented(self):
940a02
-        """Verify that unloaded/unimplemented functions report errors"""
940a02
-
940a02
-        # should be loaded and working
940a02
-        self.assertTrue(BlockDev.lvm_get_max_lv_size() > 0)
940a02
 
940a02
-        ps = BlockDev.PluginSpec()
940a02
-        ps.name = BlockDev.Plugin.SWAP
940a02
-        ps.so_name = ""
940a02
-        self.assertTrue(BlockDev.reinit([ps], True, None))
940a02
-        self.assertEqual(BlockDev.get_available_plugin_names(), ["swap"])
940a02
-
940a02
-        # no longer loaded
940a02
-        with self.assertRaises(GLib.GError):
940a02
-            BlockDev.lvm_get_max_lv_size()
940a02
-
940a02
-        self.assertTrue(BlockDev.reinit(self.requested_plugins, True, None))
940a02
-
940a02
-        # loaded again
940a02
-        self.assertTrue(BlockDev.lvm_get_max_lv_size() > 0)
940a02
-
940a02
-    def test_ensure_init(self):
940a02
-        """Verify that ensure_init just returns when already initialized"""
940a02
-
940a02
-        # the library is already initialized, ensure_init() shonuld do nothing
940a02
-        avail_plugs = BlockDev.get_available_plugin_names()
940a02
-        self.assertTrue(BlockDev.ensure_init(self.requested_plugins, None))
940a02
-        self.assertEqual(avail_plugs, BlockDev.get_available_plugin_names())
940a02
-
940a02
-        # reinit with a subset of plugins
940a02
-        plugins = BlockDev.plugin_specs_from_names(["swap", "lvm"])
940a02
-        self.assertTrue(BlockDev.reinit(plugins, True, None))
940a02
-        self.assertEqual(set(BlockDev.get_available_plugin_names()), set(["swap", "lvm"]))
940a02
-
940a02
-        # ensure_init with the same subset -> nothing should change
940a02
-        self.assertTrue(BlockDev.ensure_init(plugins, None))
940a02
-        self.assertEqual(set(BlockDev.get_available_plugin_names()), set(["swap", "lvm"]))
940a02
-
940a02
-        # ensure_init with more plugins -> extra plugins should be loaded
940a02
-        plugins = BlockDev.plugin_specs_from_names(["swap", "lvm", "crypto"])
940a02
-        self.assertTrue(BlockDev.ensure_init(plugins, None))
940a02
-        self.assertEqual(set(BlockDev.get_available_plugin_names()), set(["swap", "lvm", "crypto"]))
940a02
-
940a02
-        # reinit to unload all plugins
940a02
-        self.assertTrue(BlockDev.reinit([], True, None))
940a02
-        self.assertEqual(BlockDev.get_available_plugin_names(), [])
940a02
-
940a02
-        # ensure_init to load all plugins back
940a02
-        self.assertTrue(BlockDev.ensure_init(self.requested_plugins, None))
940a02
-        self.assertGreaterEqual(len(BlockDev.get_available_plugin_names()), 8)
940a02
-
940a02
-    def test_try_reinit(self):
940a02
-        """Verify that try_reinit() works as expected"""
940a02
-
940a02
-        # try reinitializing with only some utilities being available and thus
940a02
-        # only some plugins able to load
940a02
-        with fake_path("tests/lib_missing_utils", keep_utils=["swapon", "swapoff", "mkswap", "lvm", "swaplabel"]):
940a02
-            succ, loaded = BlockDev.try_reinit(self.requested_plugins, True, None)
940a02
-            self.assertFalse(succ)
940a02
-            for plug_name in ("swap", "lvm", "crypto"):
940a02
-                self.assertIn(plug_name, loaded)
940a02
-
940a02
-        # reset back to all plugins
940a02
-        self.assertTrue(BlockDev.reinit(self.requested_plugins, True, None))
940a02
-
940a02
-        # now the same with a subset of plugins requested
940a02
-        plugins = BlockDev.plugin_specs_from_names(["lvm", "swap", "crypto"])
940a02
-        with fake_path("tests/lib_missing_utils", keep_utils=["swapon", "swapoff", "mkswap", "lvm","swaplabel"]):
940a02
-            succ, loaded = BlockDev.try_reinit(plugins, True, None)
940a02
-            self.assertTrue(succ)
940a02
-            self.assertEqual(set(loaded), set(["swap", "lvm", "crypto"]))
940a02
-
940a02
-    def test_non_en_init(self):
940a02
-        """Verify that the library initializes with lang different from en_US"""
940a02
-
940a02
-        orig_lang = os.environ.get("LANG")
940a02
-        os.environ["LANG"] = "cs.CZ_UTF-8"
940a02
-        self.assertTrue(BlockDev.reinit(self.requested_plugins, True, None))
940a02
-        if orig_lang:
940a02
-            os.environ["LANG"] = orig_lang
940a02
-        else:
940a02
-            del os.environ["LANG"]
940a02
-        self.assertTrue(BlockDev.reinit(self.requested_plugins, True, None))
940a02
+class DepChecksTestCase(unittest.TestCase):
940a02
+    requested_plugins = BlockDev.plugin_specs_from_names(( "swap",))
940a02
 
940a02
     def test_dep_checks_disabled(self):
940a02
         """Verify that disabling runtime dep checks works"""
940a02
diff --git a/tests/lvm_dbus_tests.py b/tests/lvm_dbus_tests.py
940a02
index 4882da8..35ace37 100644
940a02
--- a/tests/lvm_dbus_tests.py
940a02
+++ b/tests/lvm_dbus_tests.py
940a02
@@ -33,6 +33,11 @@ class LVMTestCase(unittest.TestCase):
940a02
             else:
940a02
                 BlockDev.reinit([cls.ps, cls.ps2], True, None)
940a02
 
940a02
+        try:
940a02
+            cls.devices_avail = BlockDev.lvm_is_tech_avail(BlockDev.LVMTech.DEVICES, 0)
940a02
+        except:
940a02
+            cls.devices_avail = False
940a02
+
940a02
     @classmethod
940a02
     def _get_lvm_version(cls):
940a02
         _ret, out, _err = run_command("lvm version")
940a02
@@ -44,8 +49,7 @@ class LVMTestCase(unittest.TestCase):
940a02
 @unittest.skipUnless(lvm_dbus_running, "LVM DBus not running")
940a02
 class LvmNoDevTestCase(LVMTestCase):
940a02
 
940a02
-    def __init__(self, *args, **kwargs):
940a02
-        super(LvmNoDevTestCase, self).__init__(*args, **kwargs)
940a02
+    def setUp(self):
940a02
         self._log = ""
940a02
 
940a02
     @tag_test(TestTags.NOSTORAGE)
940a02
@@ -227,6 +231,45 @@ class LvmNoDevTestCase(LVMTestCase):
940a02
         succ = BlockDev.lvm_set_global_config(None)
940a02
         self.assertTrue(succ)
940a02
 
940a02
+    @tag_test(TestTags.NOSTORAGE)
940a02
+    def test_get_set_global_devices_filter(self):
940a02
+        """Verify that getting and setting LVM devices filter works as expected"""
940a02
+        if not self.devices_avail:
940a02
+            self.skipTest("skipping LVM devices filter test: not supported")
940a02
+
940a02
+        # setup logging
940a02
+        self.assertTrue(BlockDev.reinit([self.ps], False, self._store_log))
940a02
+
940a02
+        # no global config set initially
940a02
+        self.assertListEqual(BlockDev.lvm_get_devices_filter(), [])
940a02
+
940a02
+        # set and try to get back
940a02
+        succ = BlockDev.lvm_set_devices_filter(["/dev/sda"])
940a02
+        self.assertTrue(succ)
940a02
+        self.assertListEqual(BlockDev.lvm_get_devices_filter(), ["/dev/sda"])
940a02
+
940a02
+        # reset and try to get back
940a02
+        succ = BlockDev.lvm_set_devices_filter(None)
940a02
+        self.assertTrue(succ)
940a02
+        self.assertListEqual(BlockDev.lvm_get_devices_filter(), [])
940a02
+
940a02
+        # set twice and try to get back twice
940a02
+        succ = BlockDev.lvm_set_devices_filter(["/dev/sda"])
940a02
+        self.assertTrue(succ)
940a02
+        succ = BlockDev.lvm_set_devices_filter(["/dev/sdb"])
940a02
+        self.assertTrue(succ)
940a02
+        self.assertEqual(BlockDev.lvm_get_devices_filter(), ["/dev/sdb"])
940a02
+
940a02
+        # set something sane and check it's really used
940a02
+        succ = BlockDev.lvm_set_devices_filter(["/dev/sdb", "/dev/sdc"])
940a02
+        BlockDev.lvm_pvscan()
940a02
+        self.assertIn("'--devices'", self._log)
940a02
+        self.assertIn("'/dev/sdb,/dev/sdc'", self._log)
940a02
+
940a02
+        # reset back to default
940a02
+        succ = BlockDev.lvm_set_devices_filter(None)
940a02
+        self.assertTrue(succ)
940a02
+
940a02
     @tag_test(TestTags.NOSTORAGE)
940a02
     def test_cache_get_default_md_size(self):
940a02
         """Verify that default cache metadata size is calculated properly"""
940a02
diff --git a/tests/lvm_test.py b/tests/lvm_test.py
940a02
index eb94c91..b37a879 100644
940a02
--- a/tests/lvm_test.py
940a02
+++ b/tests/lvm_test.py
940a02
@@ -22,10 +22,17 @@ class LVMTestCase(unittest.TestCase):
940a02
         ps.so_name = "libbd_lvm.so.2"
940a02
         cls.requested_plugins = [ps]
940a02
 
940a02
+        BlockDev.switch_init_checks(False)
940a02
         if not BlockDev.is_initialized():
940a02
             BlockDev.init(cls.requested_plugins, None)
940a02
         else:
940a02
             BlockDev.reinit(cls.requested_plugins, True, None)
940a02
+        BlockDev.switch_init_checks(True)
940a02
+
940a02
+        try:
940a02
+            cls.devices_avail = BlockDev.lvm_is_tech_avail(BlockDev.LVMTech.DEVICES, 0)
940a02
+        except:
940a02
+            cls.devices_avail = False
940a02
 
940a02
     @classmethod
940a02
     def _get_lvm_version(cls):
940a02
@@ -39,6 +46,8 @@ class LVMTestCase(unittest.TestCase):
940a02
 class LvmNoDevTestCase(LVMTestCase):
940a02
     def __init__(self, *args, **kwargs):
940a02
         super(LvmNoDevTestCase, self).__init__(*args, **kwargs)
940a02
+
940a02
+    def setUp(self):
940a02
         self._log = ""
940a02
 
940a02
     @tag_test(TestTags.NOSTORAGE)
940a02
@@ -213,6 +222,44 @@ class LvmNoDevTestCase(LVMTestCase):
940a02
         succ = BlockDev.lvm_set_global_config(None)
940a02
         self.assertTrue(succ)
940a02
 
940a02
+    @tag_test(TestTags.NOSTORAGE)
940a02
+    def test_get_set_global_devices_filter(self):
940a02
+        """Verify that getting and setting LVM devices filter works as expected"""
940a02
+        if not self.devices_avail:
940a02
+            self.skipTest("skipping LVM devices filter test: not supported")
940a02
+
940a02
+        # setup logging
940a02
+        self.assertTrue(BlockDev.reinit(self.requested_plugins, False, self._store_log))
940a02
+
940a02
+        # no global config set initially
940a02
+        self.assertListEqual(BlockDev.lvm_get_devices_filter(), [])
940a02
+
940a02
+        # set and try to get back
940a02
+        succ = BlockDev.lvm_set_devices_filter(["/dev/sda"])
940a02
+        self.assertTrue(succ)
940a02
+        self.assertListEqual(BlockDev.lvm_get_devices_filter(), ["/dev/sda"])
940a02
+
940a02
+        # reset and try to get back
940a02
+        succ = BlockDev.lvm_set_devices_filter(None)
940a02
+        self.assertTrue(succ)
940a02
+        self.assertListEqual(BlockDev.lvm_get_devices_filter(), [])
940a02
+
940a02
+        # set twice and try to get back twice
940a02
+        succ = BlockDev.lvm_set_devices_filter(["/dev/sda"])
940a02
+        self.assertTrue(succ)
940a02
+        succ = BlockDev.lvm_set_devices_filter(["/dev/sdb"])
940a02
+        self.assertTrue(succ)
940a02
+        self.assertEqual(BlockDev.lvm_get_devices_filter(), ["/dev/sdb"])
940a02
+
940a02
+        # set something sane and check it's really used
940a02
+        succ = BlockDev.lvm_set_devices_filter(["/dev/sdb", "/dev/sdc"])
940a02
+        BlockDev.lvm_lvs(None)
940a02
+        self.assertIn("--devices=/dev/sdb,/dev/sdc", self._log)
940a02
+
940a02
+        # reset back to default
940a02
+        succ = BlockDev.lvm_set_devices_filter(None)
940a02
+        self.assertTrue(succ)
940a02
+
940a02
     @tag_test(TestTags.NOSTORAGE)
940a02
     def test_cache_get_default_md_size(self):
940a02
         """Verify that default cache metadata size is calculated properly"""
940a02
@@ -1335,6 +1382,9 @@ class LvmPVVGcachedThpoolstatsTestCase(LvmPVVGLVTestCase):
940a02
 
940a02
 class LVMUnloadTest(LVMTestCase):
940a02
     def setUp(self):
940a02
+        if not self.devices_avail:
940a02
+            self.skipTest("skipping LVM unload test: missing some LVM dependencies")
940a02
+
940a02
         # make sure the library is initialized with all plugins loaded for other
940a02
         # tests
940a02
         self.addCleanup(BlockDev.reinit, self.requested_plugins, True, None)
940a02
diff --git a/tests/overrides_test.py b/tests/overrides_test.py
940a02
index 8e7f5a5..d3faf3c 100644
940a02
--- a/tests/overrides_test.py
940a02
+++ b/tests/overrides_test.py
940a02
@@ -15,10 +15,12 @@ class OverridesTest(unittest.TestCase):
940a02
 
940a02
     @classmethod
940a02
     def setUpClass(cls):
940a02
+        BlockDev.switch_init_checks(False)
940a02
         if not BlockDev.is_initialized():
940a02
             BlockDev.init(cls.requested_plugins, None)
940a02
         else:
940a02
             BlockDev.reinit(cls.requested_plugins, True, None)
940a02
+        BlockDev.switch_init_checks(True)
940a02
 
940a02
 class OverridesTestCase(OverridesTest):
940a02
     @tag_test(TestTags.NOSTORAGE, TestTags.CORE)
940a02
@@ -65,7 +67,20 @@ class OverridesTestCase(OverridesTest):
940a02
         self.assertEqual(BlockDev.lvm_get_thpool_padding(11 * 1024**2),
940a02
                          expected_padding)
940a02
 
940a02
-class OverridesUnloadTestCase(OverridesTest):
940a02
+class OverridesUnloadTestCase(unittest.TestCase):
940a02
+    # all plugins except for 'btrfs', 'fs' and 'mpath' -- these don't have all
940a02
+    # the dependencies on CentOS/Debian and we don't need them for this test
940a02
+    requested_plugins = BlockDev.plugin_specs_from_names(("crypto", "dm",
940a02
+                                                          "kbd", "loop",
940a02
+                                                          "mdraid", "part", "swap"))
940a02
+
940a02
+    @classmethod
940a02
+    def setUpClass(cls):
940a02
+        if not BlockDev.is_initialized():
940a02
+            BlockDev.init(cls.requested_plugins, None)
940a02
+        else:
940a02
+            BlockDev.reinit(cls.requested_plugins, True, None)
940a02
+
940a02
     def tearDown(self):
940a02
         # make sure the library is initialized with all plugins loaded for other
940a02
         # tests
940a02
@@ -80,7 +95,7 @@ class OverridesUnloadTestCase(OverridesTest):
940a02
 
940a02
         # no longer loaded
940a02
         with self.assertRaises(BlockDev.BlockDevNotImplementedError):
940a02
-            BlockDev.lvm.get_max_lv_size()
940a02
+            BlockDev.md.canonicalize_uuid("3386ff85:f5012621:4a435f06:1eb47236")
940a02
 
940a02
         # load the plugins back
940a02
         self.assertTrue(BlockDev.reinit(self.requested_plugins, True, None))
940a02
@@ -92,9 +107,9 @@ class OverridesUnloadTestCase(OverridesTest):
940a02
 
940a02
         # the exception should be properly inherited from two classes
940a02
         with self.assertRaises(NotImplementedError):
940a02
-            BlockDev.lvm.get_max_lv_size()
940a02
+            BlockDev.md.canonicalize_uuid("3386ff85:f5012621:4a435f06:1eb47236")
940a02
         with self.assertRaises(BlockDev.BlockDevError):
940a02
-            BlockDev.lvm.get_max_lv_size()
940a02
+            BlockDev.md.canonicalize_uuid("3386ff85:f5012621:4a435f06:1eb47236")
940a02
 
940a02
         # load the plugins back
940a02
         self.assertTrue(BlockDev.reinit(self.requested_plugins, True, None))
940a02
-- 
940a02
2.31.1
940a02
940a02
940a02
From bebd74962db6fb7b5314be411a4d02b21554d80f Mon Sep 17 00:00:00 2001
940a02
From: Vojtech Trefny <vtrefny@redhat.com>
940a02
Date: Tue, 13 Jul 2021 13:27:32 +0200
940a02
Subject: [PATCH 2/8] lvm: Add functions for managing LVM devices file
940a02
940a02
Currently covers only --adddev and --deldev from the lvmdevices
940a02
command.
940a02
---
940a02
 src/lib/plugin_apis/lvm.api         | 26 +++++++++++++++
940a02
 src/plugins/lvm-dbus.c              | 52 +++++++++++++++++++++++++++++
940a02
 src/plugins/lvm.c                   | 52 +++++++++++++++++++++++++++++
940a02
 src/plugins/lvm.h                   |  3 ++
940a02
 src/python/gi/overrides/BlockDev.py | 15 +++++++++
940a02
 tests/lvm_dbus_tests.py             | 37 +++++++++++++++++++-
940a02
 tests/lvm_test.py                   | 37 +++++++++++++++++++-
940a02
 7 files changed, 220 insertions(+), 2 deletions(-)
940a02
940a02
diff --git a/src/lib/plugin_apis/lvm.api b/src/lib/plugin_apis/lvm.api
940a02
index 62f602f..bce2920 100644
940a02
--- a/src/lib/plugin_apis/lvm.api
940a02
+++ b/src/lib/plugin_apis/lvm.api
940a02
@@ -1685,4 +1685,30 @@ GHashTable* bd_lvm_vdo_get_stats_full (const gchar *vg_name, const gchar *pool_n
940a02
  */
940a02
 BDLVMVDOStats* bd_lvm_vdo_get_stats (const gchar *vg_name, const gchar *pool_name, GError **error);
940a02
 
940a02
+/**
940a02
+ * bd_lvm_devices_add:
940a02
+ * @device: device (PV) to add to the devices file
940a02
+ * @devices_file: (allow-none): LVM devices file or %NULL for default
940a02
+ * @extra: (allow-none) (array zero-terminated=1): extra options for the lvmdevices command
940a02
+ * @error: (out): place to store error (if any)
940a02
+ *
940a02
+ * Returns: whether the @device was successfully added to @devices_file or not
940a02
+ *
940a02
+ * Tech category: %BD_LVM_TECH_DEVICES no mode (it is ignored)
940a02
+ */
940a02
+gboolean bd_lvm_devices_add (const gchar *device, const gchar *devices_file, const BDExtraArg **extra, GError **error);
940a02
+
940a02
+/**
940a02
+ * bd_lvm_devices_delete:
940a02
+ * @device: device (PV) to delete from the devices file
940a02
+ * @devices_file: (allow-none): LVM devices file or %NULL for default
940a02
+ * @extra: (allow-none) (array zero-terminated=1): extra options for the lvmdevices command
940a02
+ * @error: (out): place to store error (if any)
940a02
+ *
940a02
+ * Returns: whether the @device was successfully removed from @devices_file or not
940a02
+ *
940a02
+ * Tech category: %BD_LVM_TECH_DEVICES no mode (it is ignored)
940a02
+ */
940a02
+gboolean bd_lvm_devices_delete (const gchar *device, const gchar *devices_file, const BDExtraArg **extra, GError **error);
940a02
+
940a02
 #endif  /* BD_LVM_API */
940a02
diff --git a/src/plugins/lvm-dbus.c b/src/plugins/lvm-dbus.c
940a02
index d1726ed..44d2794 100644
940a02
--- a/src/plugins/lvm-dbus.c
940a02
+++ b/src/plugins/lvm-dbus.c
940a02
@@ -3938,3 +3938,55 @@ BDLVMVDOStats* bd_lvm_vdo_get_stats (const gchar *vg_name, const gchar *pool_nam
940a02
 
940a02
     return stats;
940a02
 }
940a02
+
940a02
+/**
940a02
+ * bd_lvm_devices_add:
940a02
+ * @device: device (PV) to add to the devices file
940a02
+ * @devices_file: (allow-none): LVM devices file or %NULL for default
940a02
+ * @extra: (allow-none) (array zero-terminated=1): extra options for the lvmdevices command
940a02
+ * @error: (out): place to store error (if any)
940a02
+ *
940a02
+ * Returns: whether the @device was successfully added to @devices_file or not
940a02
+ *
940a02
+ * Tech category: %BD_LVM_TECH_DEVICES no mode (it is ignored)
940a02
+ */
940a02
+gboolean bd_lvm_devices_add (const gchar *device, const gchar *devices_file, const BDExtraArg **extra, GError **error) {
940a02
+    const gchar *args[5] = {"lvmdevices", "--adddev", device, NULL, NULL};
940a02
+    g_autofree gchar *devfile = NULL;
940a02
+
940a02
+    if (!bd_lvm_is_tech_avail (BD_LVM_TECH_DEVICES, 0, error))
940a02
+        return FALSE;
940a02
+
940a02
+    if (devices_file) {
940a02
+        devfile = g_strdup_printf ("--devicesfile=%s", devices_file);
940a02
+        args[3] = devfile;
940a02
+    }
940a02
+
940a02
+    return bd_utils_exec_and_report_error (args, extra, error);
940a02
+}
940a02
+
940a02
+/**
940a02
+ * bd_lvm_devices_delete:
940a02
+ * @device: device (PV) to delete from the devices file
940a02
+ * @devices_file: (allow-none): LVM devices file or %NULL for default
940a02
+ * @extra: (allow-none) (array zero-terminated=1): extra options for the lvmdevices command
940a02
+ * @error: (out): place to store error (if any)
940a02
+ *
940a02
+ * Returns: whether the @device was successfully removed from @devices_file or not
940a02
+ *
940a02
+ * Tech category: %BD_LVM_TECH_DEVICES no mode (it is ignored)
940a02
+ */
940a02
+gboolean bd_lvm_devices_delete (const gchar *device, const gchar *devices_file, const BDExtraArg **extra, GError **error) {
940a02
+    const gchar *args[5] = {"lvmdevices", "--deldev", device, NULL, NULL};
940a02
+    g_autofree gchar *devfile = NULL;
940a02
+
940a02
+    if (!bd_lvm_is_tech_avail (BD_LVM_TECH_DEVICES, 0, error))
940a02
+        return FALSE;
940a02
+
940a02
+    if (devices_file) {
940a02
+        devfile = g_strdup_printf ("--devicesfile=%s", devices_file);
940a02
+        args[3] = devfile;
940a02
+    }
940a02
+
940a02
+    return bd_utils_exec_and_report_error (args, extra, error);
940a02
+}
940a02
diff --git a/src/plugins/lvm.c b/src/plugins/lvm.c
940a02
index c0d8198..94c6a22 100644
940a02
--- a/src/plugins/lvm.c
940a02
+++ b/src/plugins/lvm.c
940a02
@@ -3235,3 +3235,55 @@ BDLVMVDOStats* bd_lvm_vdo_get_stats (const gchar *vg_name, const gchar *pool_nam
940a02
 
940a02
     return stats;
940a02
 }
940a02
+
940a02
+/**
940a02
+ * bd_lvm_devices_add:
940a02
+ * @device: device (PV) to add to the devices file
940a02
+ * @devices_file: (allow-none): LVM devices file or %NULL for default
940a02
+ * @extra: (allow-none) (array zero-terminated=1): extra options for the lvmdevices command
940a02
+ * @error: (out): place to store error (if any)
940a02
+ *
940a02
+ * Returns: whether the @device was successfully added to @devices_file or not
940a02
+ *
940a02
+ * Tech category: %BD_LVM_TECH_DEVICES no mode (it is ignored)
940a02
+ */
940a02
+gboolean bd_lvm_devices_add (const gchar *device, const gchar *devices_file, const BDExtraArg **extra, GError **error) {
940a02
+    const gchar *args[5] = {"lvmdevices", "--adddev", device, NULL, NULL};
940a02
+    g_autofree gchar *devfile = NULL;
940a02
+
940a02
+    if (!bd_lvm_is_tech_avail (BD_LVM_TECH_DEVICES, 0, error))
940a02
+        return FALSE;
940a02
+
940a02
+    if (devices_file) {
940a02
+        devfile = g_strdup_printf ("--devicesfile=%s", devices_file);
940a02
+        args[3] = devfile;
940a02
+    }
940a02
+
940a02
+    return bd_utils_exec_and_report_error (args, extra, error);
940a02
+}
940a02
+
940a02
+/**
940a02
+ * bd_lvm_devices_delete:
940a02
+ * @device: device (PV) to delete from the devices file
940a02
+ * @devices_file: (allow-none): LVM devices file or %NULL for default
940a02
+ * @extra: (allow-none) (array zero-terminated=1): extra options for the lvmdevices command
940a02
+ * @error: (out): place to store error (if any)
940a02
+ *
940a02
+ * Returns: whether the @device was successfully removed from @devices_file or not
940a02
+ *
940a02
+ * Tech category: %BD_LVM_TECH_DEVICES no mode (it is ignored)
940a02
+ */
940a02
+gboolean bd_lvm_devices_delete (const gchar *device, const gchar *devices_file, const BDExtraArg **extra, GError **error) {
940a02
+    const gchar *args[5] = {"lvmdevices", "--deldev", device, NULL, NULL};
940a02
+    g_autofree gchar *devfile = NULL;
940a02
+
940a02
+    if (!bd_lvm_is_tech_avail (BD_LVM_TECH_DEVICES, 0, error))
940a02
+        return FALSE;
940a02
+
940a02
+    if (devices_file) {
940a02
+        devfile = g_strdup_printf ("--devicesfile=%s", devices_file);
940a02
+        args[3] = devfile;
940a02
+    }
940a02
+
940a02
+    return bd_utils_exec_and_report_error (args, extra, error);
940a02
+}
940a02
diff --git a/src/plugins/lvm.h b/src/plugins/lvm.h
940a02
index 8063693..5ca2a9d 100644
940a02
--- a/src/plugins/lvm.h
940a02
+++ b/src/plugins/lvm.h
940a02
@@ -333,4 +333,7 @@ BDLVMVDOWritePolicy bd_lvm_get_vdo_write_policy_from_str (const gchar *policy_st
940a02
 BDLVMVDOStats* bd_lvm_vdo_get_stats (const gchar *vg_name, const gchar *pool_name, GError **error);
940a02
 GHashTable* bd_lvm_vdo_get_stats_full (const gchar *vg_name, const gchar *pool_name, GError **error);
940a02
 
940a02
+gboolean bd_lvm_devices_add (const gchar *device, const gchar *devices_file, const BDExtraArg **extra, GError **error);
940a02
+gboolean bd_lvm_devices_delete (const gchar *device, const gchar *devices_file, const BDExtraArg **extra, GError **error);
940a02
+
940a02
 #endif /* BD_LVM */
940a02
diff --git a/src/python/gi/overrides/BlockDev.py b/src/python/gi/overrides/BlockDev.py
940a02
index f768c8b..715a262 100644
940a02
--- a/src/python/gi/overrides/BlockDev.py
940a02
+++ b/src/python/gi/overrides/BlockDev.py
940a02
@@ -724,6 +724,21 @@ def lvm_vdo_pool_convert(vg_name, lv_name, pool_name, virtual_size, index_memory
940a02
     return _lvm_vdo_pool_convert(vg_name, lv_name, pool_name, virtual_size, index_memory, compression, deduplication, write_policy, extra)
940a02
 __all__.append("lvm_vdo_pool_convert")
940a02
 
940a02
+_lvm_devices_add = BlockDev.lvm_devices_add
940a02
+@override(BlockDev.lvm_devices_add)
940a02
+def lvm_devices_add(device, devices_file=None, extra=None, **kwargs):
940a02
+    extra = _get_extra(extra, kwargs)
940a02
+    return _lvm_devices_add(device, devices_file, extra)
940a02
+__all__.append("lvm_devices_add")
940a02
+
940a02
+_lvm_devices_delete = BlockDev.lvm_devices_delete
940a02
+@override(BlockDev.lvm_devices_delete)
940a02
+def lvm_devices_delete(device, devices_file=None, extra=None, **kwargs):
940a02
+    extra = _get_extra(extra, kwargs)
940a02
+    return _lvm_devices_delete(device, devices_file, extra)
940a02
+__all__.append("lvm_devices_delete")
940a02
+
940a02
+
940a02
 _md_get_superblock_size = BlockDev.md_get_superblock_size
940a02
 @override(BlockDev.md_get_superblock_size)
940a02
 def md_get_superblock_size(size, version=None):
940a02
diff --git a/tests/lvm_dbus_tests.py b/tests/lvm_dbus_tests.py
940a02
index 35ace37..fb1a9ed 100644
940a02
--- a/tests/lvm_dbus_tests.py
940a02
+++ b/tests/lvm_dbus_tests.py
940a02
@@ -10,7 +10,7 @@ import subprocess
940a02
 from distutils.version import LooseVersion
940a02
 from itertools import chain
940a02
 
940a02
-from utils import create_sparse_tempfile, create_lio_device, delete_lio_device, run_command, TestTags, tag_test
940a02
+from utils import create_sparse_tempfile, create_lio_device, delete_lio_device, run_command, TestTags, tag_test, read_file
940a02
 from gi.repository import BlockDev, GLib
940a02
 
940a02
 import dbus
940a02
@@ -1696,3 +1696,38 @@ class LVMVDOTest(LVMTestCase):
940a02
 
940a02
         full_stats = BlockDev.lvm_vdo_get_stats_full("testVDOVG", "vdoPool")
940a02
         self.assertIn("writeAmplificationRatio", full_stats.keys())
940a02
+
940a02
+
940a02
+class LvmTestDevicesFile(LvmPVonlyTestCase):
940a02
+    devicefile = "bd_lvm_dbus_tests.devices"
940a02
+
940a02
+    @classmethod
940a02
+    def tearDownClass(cls):
940a02
+        shutil.rmtree("/etc/lvm/devices/" + cls.devicefile, ignore_errors=True)
940a02
+
940a02
+        super(LvmTestDevicesFile, cls).tearDownClass()
940a02
+
940a02
+    def test_devices_add_delete(self):
940a02
+        if not self.devices_avail:
940a02
+            self.skipTest("skipping LVM devices file test: not supported")
940a02
+
940a02
+        succ = BlockDev.lvm_pvcreate(self.loop_dev)
940a02
+        self.assertTrue(succ)
940a02
+
940a02
+        with self.assertRaises(GLib.GError):
940a02
+            BlockDev.lvm_devices_add("/non/existing/device", self.devicefile)
940a02
+
940a02
+        with self.assertRaises(GLib.GError):
940a02
+            BlockDev.lvm_devices_delete(self.loop_dev, self.devicefile)
940a02
+
940a02
+        succ = BlockDev.lvm_devices_add(self.loop_dev, self.devicefile)
940a02
+        self.assertTrue(succ)
940a02
+
940a02
+        dfile = read_file("/etc/lvm/devices/" + self.devicefile)
940a02
+        self.assertIn(self.loop_dev, dfile)
940a02
+
940a02
+        succ = BlockDev.lvm_devices_delete(self.loop_dev, self.devicefile)
940a02
+        self.assertTrue(succ)
940a02
+
940a02
+        dfile = read_file("/etc/lvm/devices/" + self.devicefile)
940a02
+        self.assertNotIn(self.loop_dev, dfile)
940a02
diff --git a/tests/lvm_test.py b/tests/lvm_test.py
940a02
index b37a879..786434f 100644
940a02
--- a/tests/lvm_test.py
940a02
+++ b/tests/lvm_test.py
940a02
@@ -9,7 +9,7 @@ import shutil
940a02
 import subprocess
940a02
 from distutils.version import LooseVersion
940a02
 
940a02
-from utils import create_sparse_tempfile, create_lio_device, delete_lio_device, fake_utils, fake_path, TestTags, tag_test, run_command
940a02
+from utils import create_sparse_tempfile, create_lio_device, delete_lio_device, fake_utils, fake_path, TestTags, tag_test, run_command, read_file
940a02
 from gi.repository import BlockDev, GLib
940a02
 
940a02
 
940a02
@@ -1682,3 +1682,38 @@ class LVMVDOTest(LVMTestCase):
940a02
 
940a02
         full_stats = BlockDev.lvm_vdo_get_stats_full("testVDOVG", "vdoPool")
940a02
         self.assertIn("writeAmplificationRatio", full_stats.keys())
940a02
+
940a02
+
940a02
+class LvmTestDevicesFile(LvmPVonlyTestCase):
940a02
+    devicefile = "bd_lvm_test.devices"
940a02
+
940a02
+    @classmethod
940a02
+    def tearDownClass(cls):
940a02
+        shutil.rmtree("/etc/lvm/devices/" + cls.devicefile, ignore_errors=True)
940a02
+
940a02
+        super(LvmTestDevicesFile, cls).tearDownClass()
940a02
+
940a02
+    def test_devices_add_delete(self):
940a02
+        if not self.devices_avail:
940a02
+            self.skipTest("skipping LVM devices file test: not supported")
940a02
+
940a02
+        succ = BlockDev.lvm_pvcreate(self.loop_dev)
940a02
+        self.assertTrue(succ)
940a02
+
940a02
+        with self.assertRaises(GLib.GError):
940a02
+            BlockDev.lvm_devices_add("/non/existing/device", self.devicefile)
940a02
+
940a02
+        with self.assertRaises(GLib.GError):
940a02
+            BlockDev.lvm_devices_delete(self.loop_dev, self.devicefile)
940a02
+
940a02
+        succ = BlockDev.lvm_devices_add(self.loop_dev, self.devicefile)
940a02
+        self.assertTrue(succ)
940a02
+
940a02
+        dfile = read_file("/etc/lvm/devices/" + self.devicefile)
940a02
+        self.assertIn(self.loop_dev, dfile)
940a02
+
940a02
+        succ = BlockDev.lvm_devices_delete(self.loop_dev, self.devicefile)
940a02
+        self.assertTrue(succ)
940a02
+
940a02
+        dfile = read_file("/etc/lvm/devices/" + self.devicefile)
940a02
+        self.assertNotIn(self.loop_dev, dfile)
940a02
-- 
940a02
2.31.1
940a02
940a02
940a02
From 8d8cbe7169cb94b01e7064a0d00b7d86baf5e652 Mon Sep 17 00:00:00 2001
940a02
From: Vojtech Trefny <vtrefny@redhat.com>
940a02
Date: Fri, 15 Oct 2021 13:18:54 +0200
940a02
Subject: [PATCH 3/8] lvm: Report special error when system.devices file is not
940a02
 enabled
940a02
940a02
This can be disabled either in LVM by a compile time option or
940a02
by a lvm.conf option so we should report a specific error for this
940a02
case so users can distinguish between the feature not being enabled
940a02
and not being supported at all.
940a02
---
940a02
 src/lib/plugin_apis/lvm.api |  1 +
940a02
 src/plugins/lvm-dbus.c      | 70 +++++++++++++++++++++++++++++++++++++
940a02
 src/plugins/lvm.c           | 60 +++++++++++++++++++++++++++++++
940a02
 src/plugins/lvm.h           |  1 +
940a02
 tests/lvm_dbus_tests.py     | 15 ++++++++
940a02
 tests/lvm_test.py           | 15 ++++++++
940a02
 6 files changed, 162 insertions(+)
940a02
940a02
diff --git a/src/lib/plugin_apis/lvm.api b/src/lib/plugin_apis/lvm.api
940a02
index bce2920..b96bcfd 100644
940a02
--- a/src/lib/plugin_apis/lvm.api
940a02
+++ b/src/lib/plugin_apis/lvm.api
940a02
@@ -44,6 +44,7 @@ typedef enum {
940a02
     BD_LVM_ERROR_FAIL,
940a02
     BD_LVM_ERROR_NOT_SUPPORTED,
940a02
     BD_LVM_ERROR_VDO_POLICY_INVAL,
940a02
+    BD_LVM_ERROR_DEVICES_DISABLED,
940a02
 } BDLVMError;
940a02
 
940a02
 typedef enum {
940a02
diff --git a/src/plugins/lvm-dbus.c b/src/plugins/lvm-dbus.c
940a02
index 44d2794..22204d5 100644
940a02
--- a/src/plugins/lvm-dbus.c
940a02
+++ b/src/plugins/lvm-dbus.c
940a02
@@ -3939,6 +3939,64 @@ BDLVMVDOStats* bd_lvm_vdo_get_stats (const gchar *vg_name, const gchar *pool_nam
940a02
     return stats;
940a02
 }
940a02
 
940a02
+/* check whether the LVM devices file is enabled by LVM
940a02
+ * we use the existence of the "lvmdevices" command to check whether the feature is available
940a02
+ * or not, but this can still be disabled either in LVM or in lvm.conf
940a02
+ */
940a02
+static gboolean _lvm_devices_enabled () {
940a02
+    const gchar *args[6] = {"lvmconfig", "--typeconfig", NULL, "devices/use_devicesfile", NULL, NULL};
940a02
+    gboolean ret = FALSE;
940a02
+    GError *loc_error = NULL;
940a02
+    gchar *output = NULL;
940a02
+    gboolean enabled = FALSE;
940a02
+    gint scanned = 0;
940a02
+    g_autofree gchar *config_arg = NULL;
940a02
+
940a02
+    /* try current config first -- if we get something from this it means the feature is
940a02
+       explicitly enabled or disabled by system lvm.conf or using the --config option */
940a02
+    args[2] = "current";
940a02
+
940a02
+    /* make sure to include the global config from us when getting the current config value */
940a02
+    g_mutex_lock (&global_config_lock);
940a02
+    if (global_config_str) {
940a02
+        config_arg = g_strdup_printf ("--config=%s", global_config_str);
940a02
+        args[4] = config_arg;
940a02
+    }
940a02
+
940a02
+    ret = bd_utils_exec_and_capture_output (args, NULL, &output, &loc_error);
940a02
+    g_mutex_unlock (&global_config_lock);
940a02
+    if (ret) {
940a02
+        scanned = sscanf (output, "use_devicesfile=%u", &enabled);
940a02
+        g_free (output);
940a02
+        if (scanned != 1)
940a02
+            return FALSE;
940a02
+
940a02
+        return enabled;
940a02
+    } else {
940a02
+        g_clear_error (&loc_error);
940a02
+        g_free (output);
940a02
+    }
940a02
+
940a02
+    output = NULL;
940a02
+
940a02
+    /* now try default */
940a02
+    args[2] = "default";
940a02
+    ret = bd_utils_exec_and_capture_output (args, NULL, &output, &loc_error);
940a02
+    if (ret) {
940a02
+        scanned = sscanf (output, "# use_devicesfile=%u", &enabled);
940a02
+        g_free (output);
940a02
+        if (scanned != 1)
940a02
+            return FALSE;
940a02
+
940a02
+        return enabled;
940a02
+    } else {
940a02
+        g_clear_error (&loc_error);
940a02
+        g_free (output);
940a02
+    }
940a02
+
940a02
+    return FALSE;
940a02
+}
940a02
+
940a02
 /**
940a02
  * bd_lvm_devices_add:
940a02
  * @device: device (PV) to add to the devices file
940a02
@@ -3957,6 +4015,12 @@ gboolean bd_lvm_devices_add (const gchar *device, const gchar *devices_file, con
940a02
     if (!bd_lvm_is_tech_avail (BD_LVM_TECH_DEVICES, 0, error))
940a02
         return FALSE;
940a02
 
940a02
+    if (!_lvm_devices_enabled ()) {
940a02
+        g_set_error (error, BD_LVM_ERROR, BD_LVM_ERROR_DEVICES_DISABLED,
940a02
+                     "LVM devices file not enabled.");
940a02
+        return FALSE;
940a02
+    }
940a02
+
940a02
     if (devices_file) {
940a02
         devfile = g_strdup_printf ("--devicesfile=%s", devices_file);
940a02
         args[3] = devfile;
940a02
@@ -3983,6 +4047,12 @@ gboolean bd_lvm_devices_delete (const gchar *device, const gchar *devices_file,
940a02
     if (!bd_lvm_is_tech_avail (BD_LVM_TECH_DEVICES, 0, error))
940a02
         return FALSE;
940a02
 
940a02
+    if (!_lvm_devices_enabled ()) {
940a02
+        g_set_error (error, BD_LVM_ERROR, BD_LVM_ERROR_DEVICES_DISABLED,
940a02
+                     "LVM devices file not enabled.");
940a02
+        return FALSE;
940a02
+    }
940a02
+
940a02
     if (devices_file) {
940a02
         devfile = g_strdup_printf ("--devicesfile=%s", devices_file);
940a02
         args[3] = devfile;
940a02
diff --git a/src/plugins/lvm.c b/src/plugins/lvm.c
940a02
index 94c6a22..605fcb0 100644
940a02
--- a/src/plugins/lvm.c
940a02
+++ b/src/plugins/lvm.c
940a02
@@ -3236,6 +3236,54 @@ BDLVMVDOStats* bd_lvm_vdo_get_stats (const gchar *vg_name, const gchar *pool_nam
940a02
     return stats;
940a02
 }
940a02
 
940a02
+/* check whether the LVM devices file is enabled by LVM
940a02
+ * we use the existence of the "lvmdevices" command to check whether the feature is available
940a02
+ * or not, but this can still be disabled either in LVM or in lvm.conf
940a02
+ */
940a02
+static gboolean _lvm_devices_enabled () {
940a02
+    const gchar *args[5] = {"config", "--typeconfig", NULL, "devices/use_devicesfile", NULL};
940a02
+    gboolean ret = FALSE;
940a02
+    GError *loc_error = NULL;
940a02
+    gchar *output = NULL;
940a02
+    gboolean enabled = FALSE;
940a02
+    gint scanned = 0;
940a02
+
940a02
+    /* try current config first -- if we get something from this it means the feature is
940a02
+       explicitly enabled or disabled by system lvm.conf or using the --config option */
940a02
+    args[2] = "current";
940a02
+    ret = call_lvm_and_capture_output (args, NULL, &output, &loc_error);
940a02
+    if (ret) {
940a02
+        scanned = sscanf (output, "use_devicesfile=%u", &enabled);
940a02
+        g_free (output);
940a02
+        if (scanned != 1)
940a02
+            return FALSE;
940a02
+
940a02
+        return enabled;
940a02
+    } else {
940a02
+        g_clear_error (&loc_error);
940a02
+        g_free (output);
940a02
+    }
940a02
+
940a02
+    output = NULL;
940a02
+
940a02
+    /* now try default */
940a02
+    args[2] = "default";
940a02
+    ret = call_lvm_and_capture_output (args, NULL, &output, &loc_error);
940a02
+    if (ret) {
940a02
+        scanned = sscanf (output, "# use_devicesfile=%u", &enabled);
940a02
+        g_free (output);
940a02
+        if (scanned != 1)
940a02
+            return FALSE;
940a02
+
940a02
+        return enabled;
940a02
+    } else {
940a02
+        g_clear_error (&loc_error);
940a02
+        g_free (output);
940a02
+    }
940a02
+
940a02
+    return FALSE;
940a02
+}
940a02
+
940a02
 /**
940a02
  * bd_lvm_devices_add:
940a02
  * @device: device (PV) to add to the devices file
940a02
@@ -3254,6 +3302,12 @@ gboolean bd_lvm_devices_add (const gchar *device, const gchar *devices_file, con
940a02
     if (!bd_lvm_is_tech_avail (BD_LVM_TECH_DEVICES, 0, error))
940a02
         return FALSE;
940a02
 
940a02
+    if (!_lvm_devices_enabled ()) {
940a02
+        g_set_error (error, BD_LVM_ERROR, BD_LVM_ERROR_DEVICES_DISABLED,
940a02
+                     "LVM devices file not enabled.");
940a02
+        return FALSE;
940a02
+    }
940a02
+
940a02
     if (devices_file) {
940a02
         devfile = g_strdup_printf ("--devicesfile=%s", devices_file);
940a02
         args[3] = devfile;
940a02
@@ -3280,6 +3334,12 @@ gboolean bd_lvm_devices_delete (const gchar *device, const gchar *devices_file,
940a02
     if (!bd_lvm_is_tech_avail (BD_LVM_TECH_DEVICES, 0, error))
940a02
         return FALSE;
940a02
 
940a02
+    if (!_lvm_devices_enabled ()) {
940a02
+        g_set_error (error, BD_LVM_ERROR, BD_LVM_ERROR_DEVICES_DISABLED,
940a02
+                     "LVM devices file not enabled.");
940a02
+        return FALSE;
940a02
+    }
940a02
+
940a02
     if (devices_file) {
940a02
         devfile = g_strdup_printf ("--devicesfile=%s", devices_file);
940a02
         args[3] = devfile;
940a02
diff --git a/src/plugins/lvm.h b/src/plugins/lvm.h
940a02
index 5ca2a9d..fabf091 100644
940a02
--- a/src/plugins/lvm.h
940a02
+++ b/src/plugins/lvm.h
940a02
@@ -53,6 +53,7 @@ typedef enum {
940a02
     BD_LVM_ERROR_FAIL,
940a02
     BD_LVM_ERROR_NOT_SUPPORTED,
940a02
     BD_LVM_ERROR_VDO_POLICY_INVAL,
940a02
+    BD_LVM_ERROR_DEVICES_DISABLED,
940a02
 } BDLVMError;
940a02
 
940a02
 typedef enum {
940a02
diff --git a/tests/lvm_dbus_tests.py b/tests/lvm_dbus_tests.py
940a02
index fb1a9ed..c411c9e 100644
940a02
--- a/tests/lvm_dbus_tests.py
940a02
+++ b/tests/lvm_dbus_tests.py
940a02
@@ -1731,3 +1731,18 @@ class LvmTestDevicesFile(LvmPVonlyTestCase):
940a02
 
940a02
         dfile = read_file("/etc/lvm/devices/" + self.devicefile)
940a02
         self.assertNotIn(self.loop_dev, dfile)
940a02
+
940a02
+    def test_devices_enabled(self):
940a02
+        if not self.devices_avail:
940a02
+            self.skipTest("skipping LVM devices file test: not supported")
940a02
+
940a02
+        self.addCleanup(BlockDev.lvm_set_global_config, "")
940a02
+
940a02
+        # checking if the feature is enabled or disabled is hard so lets just disable
940a02
+        # the devices file using the global config and check lvm_devices_add fails
940a02
+        # with the correct exception message
940a02
+        succ = BlockDev.lvm_set_global_config("devices { use_devicesfile=0 }")
940a02
+        self.assertTrue(succ)
940a02
+
940a02
+        with self.assertRaisesRegex(GLib.GError, "LVM devices file not enabled."):
940a02
+            BlockDev.lvm_devices_add("", self.devicefile)
940a02
diff --git a/tests/lvm_test.py b/tests/lvm_test.py
940a02
index 786434f..315dd07 100644
940a02
--- a/tests/lvm_test.py
940a02
+++ b/tests/lvm_test.py
940a02
@@ -1717,3 +1717,18 @@ class LvmTestDevicesFile(LvmPVonlyTestCase):
940a02
 
940a02
         dfile = read_file("/etc/lvm/devices/" + self.devicefile)
940a02
         self.assertNotIn(self.loop_dev, dfile)
940a02
+
940a02
+    def test_devices_enabled(self):
940a02
+        if not self.devices_avail:
940a02
+            self.skipTest("skipping LVM devices file test: not supported")
940a02
+
940a02
+        self.addCleanup(BlockDev.lvm_set_global_config, "")
940a02
+
940a02
+        # checking if the feature is enabled or disabled is hard so lets just disable
940a02
+        # the devices file using the global config and check lvm_devices_add fails
940a02
+        # with the correct exception message
940a02
+        succ = BlockDev.lvm_set_global_config("devices { use_devicesfile=0 }")
940a02
+        self.assertTrue(succ)
940a02
+
940a02
+        with self.assertRaisesRegex(GLib.GError, "LVM devices file not enabled."):
940a02
+            BlockDev.lvm_devices_add("", self.devicefile)
940a02
-- 
940a02
2.31.1
940a02
940a02
940a02
From 81df85e7ea6e129e78074b6967f80c505d1b08f0 Mon Sep 17 00:00:00 2001
940a02
From: Vojtech Trefny <vtrefny@redhat.com>
940a02
Date: Fri, 15 Oct 2021 14:21:03 +0200
940a02
Subject: [PATCH 4/8] lvm: Force enable LVM devices file for LvmTestDevicesFile
940a02
940a02
This feauture might be disabled in lvm.conf so to be able to test
940a02
it we need to override this. The correct handling of the disabled
940a02
state is checked in a separate test case.
940a02
---
940a02
 tests/lvm_dbus_tests.py | 8 ++++++++
940a02
 tests/lvm_test.py       | 8 ++++++++
940a02
 2 files changed, 16 insertions(+)
940a02
940a02
diff --git a/tests/lvm_dbus_tests.py b/tests/lvm_dbus_tests.py
940a02
index c411c9e..9cfc647 100644
940a02
--- a/tests/lvm_dbus_tests.py
940a02
+++ b/tests/lvm_dbus_tests.py
940a02
@@ -1711,6 +1711,12 @@ class LvmTestDevicesFile(LvmPVonlyTestCase):
940a02
         if not self.devices_avail:
940a02
             self.skipTest("skipping LVM devices file test: not supported")
940a02
 
940a02
+        self.addCleanup(BlockDev.lvm_set_global_config, "")
940a02
+
940a02
+        # force-enable the feature, it might be disabled by default
940a02
+        succ = BlockDev.lvm_set_global_config("devices { use_devicesfile=1 }")
940a02
+        self.assertTrue(succ)
940a02
+
940a02
         succ = BlockDev.lvm_pvcreate(self.loop_dev)
940a02
         self.assertTrue(succ)
940a02
 
940a02
@@ -1732,6 +1738,8 @@ class LvmTestDevicesFile(LvmPVonlyTestCase):
940a02
         dfile = read_file("/etc/lvm/devices/" + self.devicefile)
940a02
         self.assertNotIn(self.loop_dev, dfile)
940a02
 
940a02
+        BlockDev.lvm_set_global_config("")
940a02
+
940a02
     def test_devices_enabled(self):
940a02
         if not self.devices_avail:
940a02
             self.skipTest("skipping LVM devices file test: not supported")
940a02
diff --git a/tests/lvm_test.py b/tests/lvm_test.py
940a02
index 315dd07..ea3b7f8 100644
940a02
--- a/tests/lvm_test.py
940a02
+++ b/tests/lvm_test.py
940a02
@@ -1697,6 +1697,12 @@ class LvmTestDevicesFile(LvmPVonlyTestCase):
940a02
         if not self.devices_avail:
940a02
             self.skipTest("skipping LVM devices file test: not supported")
940a02
 
940a02
+        self.addCleanup(BlockDev.lvm_set_global_config, "")
940a02
+
940a02
+        # force-enable the feature, it might be disabled by default
940a02
+        succ = BlockDev.lvm_set_global_config("devices { use_devicesfile=1 }")
940a02
+        self.assertTrue(succ)
940a02
+
940a02
         succ = BlockDev.lvm_pvcreate(self.loop_dev)
940a02
         self.assertTrue(succ)
940a02
 
940a02
@@ -1718,6 +1724,8 @@ class LvmTestDevicesFile(LvmPVonlyTestCase):
940a02
         dfile = read_file("/etc/lvm/devices/" + self.devicefile)
940a02
         self.assertNotIn(self.loop_dev, dfile)
940a02
 
940a02
+        BlockDev.lvm_set_global_config("")
940a02
+
940a02
     def test_devices_enabled(self):
940a02
         if not self.devices_avail:
940a02
             self.skipTest("skipping LVM devices file test: not supported")
940a02
-- 
940a02
2.31.1
940a02
940a02
940a02
From 01237b62bb8ad67def7c937185c42152503fbc6f Mon Sep 17 00:00:00 2001
940a02
From: Vojtech Trefny <vtrefny@redhat.com>
940a02
Date: Fri, 12 Nov 2021 14:51:39 +0100
940a02
Subject: [PATCH 5/8] tests: Fix resetting global LVM config after LVM devices
940a02
 file test
940a02
940a02
We need to set the config to None/NULL not to an empty string.
940a02
---
940a02
 tests/lvm_dbus_tests.py | 6 +++---
940a02
 tests/lvm_test.py       | 6 +++---
940a02
 2 files changed, 6 insertions(+), 6 deletions(-)
940a02
940a02
diff --git a/tests/lvm_dbus_tests.py b/tests/lvm_dbus_tests.py
940a02
index 9cfc647..d422869 100644
940a02
--- a/tests/lvm_dbus_tests.py
940a02
+++ b/tests/lvm_dbus_tests.py
940a02
@@ -1711,7 +1711,7 @@ class LvmTestDevicesFile(LvmPVonlyTestCase):
940a02
         if not self.devices_avail:
940a02
             self.skipTest("skipping LVM devices file test: not supported")
940a02
 
940a02
-        self.addCleanup(BlockDev.lvm_set_global_config, "")
940a02
+        self.addCleanup(BlockDev.lvm_set_global_config, None)
940a02
 
940a02
         # force-enable the feature, it might be disabled by default
940a02
         succ = BlockDev.lvm_set_global_config("devices { use_devicesfile=1 }")
940a02
@@ -1738,13 +1738,13 @@ class LvmTestDevicesFile(LvmPVonlyTestCase):
940a02
         dfile = read_file("/etc/lvm/devices/" + self.devicefile)
940a02
         self.assertNotIn(self.loop_dev, dfile)
940a02
 
940a02
-        BlockDev.lvm_set_global_config("")
940a02
+        BlockDev.lvm_set_global_config(None)
940a02
 
940a02
     def test_devices_enabled(self):
940a02
         if not self.devices_avail:
940a02
             self.skipTest("skipping LVM devices file test: not supported")
940a02
 
940a02
-        self.addCleanup(BlockDev.lvm_set_global_config, "")
940a02
+        self.addCleanup(BlockDev.lvm_set_global_config, None)
940a02
 
940a02
         # checking if the feature is enabled or disabled is hard so lets just disable
940a02
         # the devices file using the global config and check lvm_devices_add fails
940a02
diff --git a/tests/lvm_test.py b/tests/lvm_test.py
940a02
index ea3b7f8..882cdf2 100644
940a02
--- a/tests/lvm_test.py
940a02
+++ b/tests/lvm_test.py
940a02
@@ -1697,7 +1697,7 @@ class LvmTestDevicesFile(LvmPVonlyTestCase):
940a02
         if not self.devices_avail:
940a02
             self.skipTest("skipping LVM devices file test: not supported")
940a02
 
940a02
-        self.addCleanup(BlockDev.lvm_set_global_config, "")
940a02
+        self.addCleanup(BlockDev.lvm_set_global_config, None)
940a02
 
940a02
         # force-enable the feature, it might be disabled by default
940a02
         succ = BlockDev.lvm_set_global_config("devices { use_devicesfile=1 }")
940a02
@@ -1724,13 +1724,13 @@ class LvmTestDevicesFile(LvmPVonlyTestCase):
940a02
         dfile = read_file("/etc/lvm/devices/" + self.devicefile)
940a02
         self.assertNotIn(self.loop_dev, dfile)
940a02
 
940a02
-        BlockDev.lvm_set_global_config("")
940a02
+        BlockDev.lvm_set_global_config(None)
940a02
 
940a02
     def test_devices_enabled(self):
940a02
         if not self.devices_avail:
940a02
             self.skipTest("skipping LVM devices file test: not supported")
940a02
 
940a02
-        self.addCleanup(BlockDev.lvm_set_global_config, "")
940a02
+        self.addCleanup(BlockDev.lvm_set_global_config, None)
940a02
 
940a02
         # checking if the feature is enabled or disabled is hard so lets just disable
940a02
         # the devices file using the global config and check lvm_devices_add fails
940a02
-- 
940a02
2.31.1
940a02
940a02
940a02
From 2f33f2af18efa0b337f8383cb6f137d6211fe7fb Mon Sep 17 00:00:00 2001
940a02
From: Vojtech Trefny <vtrefny@redhat.com>
940a02
Date: Fri, 12 Nov 2021 15:10:45 +0100
940a02
Subject: [PATCH 6/8] lvm: Do not set global config to and empty string
940a02
940a02
If we set it to an empty string we end up running "--config"
940a02
without a parameter and lvm will use whatever is next parameter
940a02
like the device path for pvremove.
940a02
---
940a02
 src/plugins/lvm-dbus.c  |  5 ++++-
940a02
 src/plugins/lvm.c       |  5 ++++-
940a02
 tests/lvm_dbus_tests.py | 12 ++++++++++++
940a02
 tests/lvm_test.py       | 12 ++++++++++++
940a02
 4 files changed, 32 insertions(+), 2 deletions(-)
940a02
940a02
diff --git a/src/plugins/lvm-dbus.c b/src/plugins/lvm-dbus.c
940a02
index 22204d5..b7bd019 100644
940a02
--- a/src/plugins/lvm-dbus.c
940a02
+++ b/src/plugins/lvm-dbus.c
940a02
@@ -2644,7 +2644,10 @@ gboolean bd_lvm_set_global_config (const gchar *new_config, GError **error UNUSE
940a02
     g_free (global_config_str);
940a02
 
940a02
     /* now store the new one */
940a02
-    global_config_str = g_strdup (new_config);
940a02
+    if (!new_config || g_strcmp0 (new_config, "") == 0)
940a02
+         global_config_str = NULL;
940a02
+    else
940a02
+        global_config_str = g_strdup (new_config);
940a02
 
940a02
     g_mutex_unlock (&global_config_lock);
940a02
     return TRUE;
940a02
diff --git a/src/plugins/lvm.c b/src/plugins/lvm.c
940a02
index 605fcb0..124fce7 100644
940a02
--- a/src/plugins/lvm.c
940a02
+++ b/src/plugins/lvm.c
940a02
@@ -2016,7 +2016,10 @@ gboolean bd_lvm_set_global_config (const gchar *new_config, GError **error UNUSE
940a02
     g_free (global_config_str);
940a02
 
940a02
     /* now store the new one */
940a02
-    global_config_str = g_strdup (new_config);
940a02
+    if (!new_config || g_strcmp0 (new_config, "") == 0)
940a02
+         global_config_str = NULL;
940a02
+    else
940a02
+        global_config_str = g_strdup (new_config);
940a02
 
940a02
     g_mutex_unlock (&global_config_lock);
940a02
     return TRUE;
940a02
diff --git a/tests/lvm_dbus_tests.py b/tests/lvm_dbus_tests.py
940a02
index d422869..5516afe 100644
940a02
--- a/tests/lvm_dbus_tests.py
940a02
+++ b/tests/lvm_dbus_tests.py
940a02
@@ -1754,3 +1754,15 @@ class LvmTestDevicesFile(LvmPVonlyTestCase):
940a02
 
940a02
         with self.assertRaisesRegex(GLib.GError, "LVM devices file not enabled."):
940a02
             BlockDev.lvm_devices_add("", self.devicefile)
940a02
+
940a02
+
940a02
+class LvmConfigTestPvremove(LvmPVonlyTestCase):
940a02
+
940a02
+    @tag_test(TestTags.REGRESSION)
940a02
+    def test_set_empty_config(self):
940a02
+        succ = BlockDev.lvm_pvcreate(self.loop_dev)
940a02
+        self.assertTrue(succ)
940a02
+
940a02
+        BlockDev.lvm_set_global_config("")
940a02
+        succ = BlockDev.lvm_pvremove(self.loop_dev)
940a02
+        self.assertTrue(succ)
940a02
diff --git a/tests/lvm_test.py b/tests/lvm_test.py
940a02
index 882cdf2..e349817 100644
940a02
--- a/tests/lvm_test.py
940a02
+++ b/tests/lvm_test.py
940a02
@@ -1740,3 +1740,15 @@ class LvmTestDevicesFile(LvmPVonlyTestCase):
940a02
 
940a02
         with self.assertRaisesRegex(GLib.GError, "LVM devices file not enabled."):
940a02
             BlockDev.lvm_devices_add("", self.devicefile)
940a02
+
940a02
+
940a02
+class LvmConfigTestPvremove(LvmPVonlyTestCase):
940a02
+
940a02
+    @tag_test(TestTags.REGRESSION)
940a02
+    def test_set_empty_config(self):
940a02
+        succ = BlockDev.lvm_pvcreate(self.loop_dev)
940a02
+        self.assertTrue(succ)
940a02
+
940a02
+        BlockDev.lvm_set_global_config("")
940a02
+        succ = BlockDev.lvm_pvremove(self.loop_dev)
940a02
+        self.assertTrue(succ)
940a02
-- 
940a02
2.31.1
940a02
940a02
940a02
From 2a4e610027a2c2a315054b84a323ce973939ca2d Mon Sep 17 00:00:00 2001
940a02
From: Vojtech Trefny <vtrefny@redhat.com>
940a02
Date: Tue, 16 Mar 2021 12:05:37 +0100
940a02
Subject: [PATCH 7/8] vdo: Do not use g_memdup in bd_vdo_stats_copy
940a02
940a02
g_memdup is deprecated and the replacement g_memdup2 is not yet
940a02
available so lets just do the copy manually.
940a02
---
940a02
 src/lib/plugin_apis/vdo.api | 17 ++++++++++++++++-
940a02
 src/plugins/vdo.c           | 17 ++++++++++++++++-
940a02
 2 files changed, 32 insertions(+), 2 deletions(-)
940a02
940a02
diff --git a/src/lib/plugin_apis/vdo.api b/src/lib/plugin_apis/vdo.api
940a02
index 936f8e0..312de4e 100644
940a02
--- a/src/lib/plugin_apis/vdo.api
940a02
+++ b/src/lib/plugin_apis/vdo.api
940a02
@@ -170,7 +170,22 @@ void bd_vdo_stats_free (BDVDOStats *stats) {
940a02
  * Deprecated: 2.24: Use LVM-VDO integration instead.
940a02
  */
940a02
 BDVDOStats* bd_vdo_stats_copy (BDVDOStats *stats) {
940a02
-    return g_memdup (stats, sizeof (BDVDOStats));
940a02
+    if (stats == NULL)
940a02
+        return NULL;
940a02
+
940a02
+    BDVDOStats *new_stats = g_new0 (BDVDOStats, 1);
940a02
+
940a02
+    new_stats->block_size = stats->block_size;
940a02
+    new_stats->logical_block_size = stats->logical_block_size;
940a02
+    new_stats->physical_blocks = stats->physical_blocks;
940a02
+    new_stats->data_blocks_used = stats->data_blocks_used;
940a02
+    new_stats->overhead_blocks_used = stats->overhead_blocks_used;
940a02
+    new_stats->logical_blocks_used = stats->logical_blocks_used;
940a02
+    new_stats->used_percent = stats->used_percent;
940a02
+    new_stats->saving_percent = stats->saving_percent;
940a02
+    new_stats->write_amplification_ratio = stats->write_amplification_ratio;
940a02
+
940a02
+    return new_stats;
940a02
 }
940a02
 
940a02
 GType bd_vdo_stats_get_type () {
940a02
diff --git a/src/plugins/vdo.c b/src/plugins/vdo.c
940a02
index 2352394..d443099 100644
940a02
--- a/src/plugins/vdo.c
940a02
+++ b/src/plugins/vdo.c
940a02
@@ -81,7 +81,22 @@ void bd_vdo_stats_free (BDVDOStats *stats) {
940a02
 }
940a02
 
940a02
 BDVDOStats* bd_vdo_stats_copy (BDVDOStats *stats) {
940a02
-    return g_memdup (stats, sizeof (BDVDOStats));
940a02
+    if (stats == NULL)
940a02
+        return NULL;
940a02
+
940a02
+    BDVDOStats *new_stats = g_new0 (BDVDOStats, 1);
940a02
+
940a02
+    new_stats->block_size = stats->block_size;
940a02
+    new_stats->logical_block_size = stats->logical_block_size;
940a02
+    new_stats->physical_blocks = stats->physical_blocks;
940a02
+    new_stats->data_blocks_used = stats->data_blocks_used;
940a02
+    new_stats->overhead_blocks_used = stats->overhead_blocks_used;
940a02
+    new_stats->logical_blocks_used = stats->logical_blocks_used;
940a02
+    new_stats->used_percent = stats->used_percent;
940a02
+    new_stats->saving_percent = stats->saving_percent;
940a02
+    new_stats->write_amplification_ratio = stats->write_amplification_ratio;
940a02
+
940a02
+    return new_stats;
940a02
 }
940a02
 
940a02
 
940a02
-- 
940a02
2.31.1
940a02
940a02
940a02
From 577ea466e3b7af464137e087907ba980ad3994ee Mon Sep 17 00:00:00 2001
940a02
From: Vojtech Trefny <vtrefny@redhat.com>
940a02
Date: Fri, 26 Nov 2021 15:19:55 +0100
940a02
Subject: [PATCH 8/8] lvm: Use "lvmconfig full" to get valid config instead of
940a02
 "current"
940a02
940a02
"lvmconfig current" doesn't work together with --config even if we
940a02
don't override the "use_devicefile" key. "lvmconfig full" seems to
940a02
be working in all cases.
940a02
---
940a02
 src/plugins/lvm-dbus.c | 4 ++--
940a02
 src/plugins/lvm.c      | 4 ++--
940a02
 2 files changed, 4 insertions(+), 4 deletions(-)
940a02
940a02
diff --git a/src/plugins/lvm-dbus.c b/src/plugins/lvm-dbus.c
940a02
index b7bd019..825c5e9 100644
940a02
--- a/src/plugins/lvm-dbus.c
940a02
+++ b/src/plugins/lvm-dbus.c
940a02
@@ -3955,9 +3955,9 @@ static gboolean _lvm_devices_enabled () {
940a02
     gint scanned = 0;
940a02
     g_autofree gchar *config_arg = NULL;
940a02
 
940a02
-    /* try current config first -- if we get something from this it means the feature is
940a02
+    /* try full config first -- if we get something from this it means the feature is
940a02
        explicitly enabled or disabled by system lvm.conf or using the --config option */
940a02
-    args[2] = "current";
940a02
+    args[2] = "full";
940a02
 
940a02
     /* make sure to include the global config from us when getting the current config value */
940a02
     g_mutex_lock (&global_config_lock);
940a02
diff --git a/src/plugins/lvm.c b/src/plugins/lvm.c
940a02
index 124fce7..21320f3 100644
940a02
--- a/src/plugins/lvm.c
940a02
+++ b/src/plugins/lvm.c
940a02
@@ -3251,9 +3251,9 @@ static gboolean _lvm_devices_enabled () {
940a02
     gboolean enabled = FALSE;
940a02
     gint scanned = 0;
940a02
 
940a02
-    /* try current config first -- if we get something from this it means the feature is
940a02
+    /* try full config first -- if we get something from this it means the feature is
940a02
        explicitly enabled or disabled by system lvm.conf or using the --config option */
940a02
-    args[2] = "current";
940a02
+    args[2] = "full";
940a02
     ret = call_lvm_and_capture_output (args, NULL, &output, &loc_error);
940a02
     if (ret) {
940a02
         scanned = sscanf (output, "use_devicesfile=%u", &enabled);
940a02
-- 
940a02
2.31.1
940a02