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