Vojtech Trefny bb6266
From 94d707dd225104ba14422eeb43c73b1f742b12da 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 bb6266
Subject: [PATCH 1/7] 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 bb6266
 src/plugins/lvm-dbus.c      |  75 ++++++++-
Vojtech Trefny 0711d4
 src/plugins/lvm.c           |  97 ++++++++++--
Vojtech Trefny 0711d4
 src/plugins/lvm.h           |   4 +
Vojtech Trefny bd3730
 tests/library_test.py       | 304 ++++++++++++++++++++----------------
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 bb6266
 8 files changed, 470 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 bb6266
index c695c111..23f68b81 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 bb6266
index 51572c9a..b47ed0ef 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 bb6266
@@ -241,11 +243,20 @@ static gboolean setup_dbus_connection (GError **error) {
Vojtech Trefny bb6266
     return TRUE;
Vojtech Trefny bb6266
 }
Vojtech Trefny bb6266
 
Vojtech Trefny bb6266
+static volatile guint avail_deps = 0;
Vojtech Trefny bb6266
 static volatile guint avail_dbus_deps = 0;
Vojtech Trefny bb6266
 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 bb6266
@@ -378,6 +389,8 @@ gboolean bd_lvm_is_tech_avail (BDLVMTech tech, guint64 mode, GError **error) {
Vojtech Trefny bb6266
         return check_dbus_deps (&avail_dbus_deps, DBUS_DEPS_LVMDBUSD_MASK, dbus_deps, DBUS_DEPS_LAST, &deps_check_lock, error) &&
Vojtech Trefny bb6266
                check_features (&avail_features, FEATURES_VDO_MASK, features, FEATURES_LAST, &deps_check_lock, error) &&
Vojtech Trefny bb6266
                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 bb6266
@@ -515,6 +528,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 bb6266
@@ -536,8 +550,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 bb6266
@@ -558,6 +572,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 bb6266
@@ -2654,6 +2673,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 bb6266
index 26af0d19..42ee0f90 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 bb6266
@@ -2033,6 +2056,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 bb6266
index 2162d769..8063693f 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 bb6266
index 08e44fdc..efd17bd2 100644
Vojtech Trefny 0711d4
--- a/tests/library_test.py
Vojtech Trefny 0711d4
+++ b/tests/library_test.py
Vojtech Trefny bd3730
@@ -13,18 +13,178 @@ 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
+        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 bd3730
+        with fake_path("tests/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 bd3730
+        with fake_path("tests/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 bd3730
@@ -185,6 +345,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 bd3730
@@ -206,7 +372,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 bd3730
@@ -243,139 +409,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 bd3730
 
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 bd3730
-
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 bb6266
index 3fb7946a..ae26c6d2 100644
Vojtech Trefny 0711d4
--- a/tests/lvm_dbus_tests.py
Vojtech Trefny 0711d4
+++ b/tests/lvm_dbus_tests.py
Vojtech Trefny bb6266
@@ -50,6 +50,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 bb6266
@@ -61,8 +66,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 bb6266
@@ -250,6 +254,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 bb6266
index 7be8f1ab..11d8c94e 100644
Vojtech Trefny 0711d4
--- a/tests/lvm_test.py
Vojtech Trefny 0711d4
+++ b/tests/lvm_test.py
Vojtech Trefny bb6266
@@ -39,10 +39,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 bb6266
@@ -56,6 +63,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 bb6266
@@ -236,6 +245,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 bb6266
@@ -1406,6 +1453,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 bb6266
index 8e7f5a5a..d3faf3cf 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 bb6266
2.37.3
Vojtech Trefny 0711d4
Vojtech Trefny 0711d4
Vojtech Trefny bb6266
From 707de091b8848b95cc78faa4299119844aab4172 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 bb6266
Subject: [PATCH 2/7] 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 bb6266
index 23f68b81..b869afcc 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 bb6266
index b47ed0ef..86ca28ca 100644
Vojtech Trefny 0711d4
--- a/src/plugins/lvm-dbus.c
Vojtech Trefny 0711d4
+++ b/src/plugins/lvm-dbus.c
Vojtech Trefny bb6266
@@ -3950,3 +3950,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 bb6266
index 42ee0f90..3bd8fae1 100644
Vojtech Trefny 0711d4
--- a/src/plugins/lvm.c
Vojtech Trefny 0711d4
+++ b/src/plugins/lvm.c
Vojtech Trefny bb6266
@@ -3250,3 +3250,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 bb6266
index 8063693f..5ca2a9d7 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 bb6266
index ea059060..8574ab04 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 bb6266
index ae26c6d2..82e4761d 100644
Vojtech Trefny 0711d4
--- a/tests/lvm_dbus_tests.py
Vojtech Trefny 0711d4
+++ b/tests/lvm_dbus_tests.py
Vojtech Trefny bb6266
@@ -12,7 +12,7 @@ from contextlib import contextmanager
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 bb6266
@@ -1785,3 +1785,38 @@ class LvmConfigTestPvremove(LvmPVonlyTestCase):
Vojtech Trefny bb6266
         BlockDev.lvm_set_global_config("")
Vojtech Trefny bb6266
         succ = BlockDev.lvm_pvremove(self.loop_dev)
Vojtech Trefny bb6266
         self.assertTrue(succ)
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 bb6266
index 11d8c94e..6ddeaa6a 100644
Vojtech Trefny 0711d4
--- a/tests/lvm_test.py
Vojtech Trefny 0711d4
+++ b/tests/lvm_test.py
Vojtech Trefny bb6266
@@ -11,7 +11,7 @@ import time
Vojtech Trefny bb6266
 from contextlib import contextmanager
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 bb6266
@@ -1765,3 +1765,38 @@ class LvmConfigTestPvremove(LvmPVonlyTestCase):
Vojtech Trefny bb6266
         BlockDev.lvm_set_global_config("")
Vojtech Trefny bb6266
         succ = BlockDev.lvm_pvremove(self.loop_dev)
Vojtech Trefny bb6266
         self.assertTrue(succ)
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 bb6266
2.37.3
Vojtech Trefny 0711d4
Vojtech Trefny 0711d4
Vojtech Trefny bb6266
From 4c832576df8918c269db8fe2cb7eb74e45628d6c 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 bb6266
Subject: [PATCH 3/7] 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 bb6266
index b869afcc..b8cde70b 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 bb6266
index 86ca28ca..7f48e422 100644
Vojtech Trefny 0711d4
--- a/src/plugins/lvm-dbus.c
Vojtech Trefny 0711d4
+++ b/src/plugins/lvm-dbus.c
Vojtech Trefny bb6266
@@ -3951,6 +3951,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 bb6266
@@ -3969,6 +4027,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 bb6266
@@ -3995,6 +4059,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 bb6266
index 3bd8fae1..73d5005f 100644
Vojtech Trefny 0711d4
--- a/src/plugins/lvm.c
Vojtech Trefny 0711d4
+++ b/src/plugins/lvm.c
Vojtech Trefny bb6266
@@ -3251,6 +3251,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 bb6266
@@ -3269,6 +3317,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 bb6266
@@ -3295,6 +3349,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 bb6266
index 5ca2a9d7..fabf091f 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 bb6266
index 82e4761d..792c1cc8 100644
Vojtech Trefny 0711d4
--- a/tests/lvm_dbus_tests.py
Vojtech Trefny 0711d4
+++ b/tests/lvm_dbus_tests.py
Vojtech Trefny bb6266
@@ -1820,3 +1820,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 bb6266
index 6ddeaa6a..73fb1030 100644
Vojtech Trefny 0711d4
--- a/tests/lvm_test.py
Vojtech Trefny 0711d4
+++ b/tests/lvm_test.py
Vojtech Trefny bb6266
@@ -1800,3 +1800,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 bb6266
2.37.3
Vojtech Trefny 0711d4
Vojtech Trefny 0711d4
Vojtech Trefny bb6266
From 2fdec5f7e42de869d4b2ec80dce597d22dd57617 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 bb6266
Subject: [PATCH 4/7] 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 bb6266
index 792c1cc8..e55535cc 100644
Vojtech Trefny 0711d4
--- a/tests/lvm_dbus_tests.py
Vojtech Trefny 0711d4
+++ b/tests/lvm_dbus_tests.py
Vojtech Trefny bb6266
@@ -1800,6 +1800,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 bb6266
@@ -1821,6 +1827,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 bb6266
index 73fb1030..907b4f59 100644
Vojtech Trefny 0711d4
--- a/tests/lvm_test.py
Vojtech Trefny 0711d4
+++ b/tests/lvm_test.py
Vojtech Trefny bb6266
@@ -1780,6 +1780,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 bb6266
@@ -1801,6 +1807,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 bb6266
2.37.3
Vojtech Trefny 0711d4
Vojtech Trefny 0711d4
Vojtech Trefny bb6266
From 1809a41c0b2b99c8d6a077b5aa70834686980181 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 bb6266
Subject: [PATCH 5/7] 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 bb6266
index e55535cc..8ae670d5 100644
Vojtech Trefny 0711d4
--- a/tests/lvm_dbus_tests.py
Vojtech Trefny 0711d4
+++ b/tests/lvm_dbus_tests.py
Vojtech Trefny bb6266
@@ -1800,7 +1800,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 bb6266
@@ -1827,13 +1827,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 bb6266
index 907b4f59..095e4bac 100644
Vojtech Trefny 0711d4
--- a/tests/lvm_test.py
Vojtech Trefny 0711d4
+++ b/tests/lvm_test.py
Vojtech Trefny bb6266
@@ -1780,7 +1780,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 bb6266
@@ -1807,13 +1807,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 bb6266
2.37.3
Vojtech Trefny 0711d4
Vojtech Trefny 0711d4
Vojtech Trefny bb6266
From 1c2f1d20a3cfa522b78ab007e8e4f9a5a4bb579d 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 bb6266
Subject: [PATCH 6/7] 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
 tests/lvm_dbus_tests.py | 12 ++++++++++++
Vojtech Trefny 0711d4
 tests/lvm_test.py       | 12 ++++++++++++
Vojtech Trefny bb6266
 2 files changed, 24 insertions(+)
Vojtech Trefny 0711d4
Vojtech Trefny 0711d4
diff --git a/tests/lvm_dbus_tests.py b/tests/lvm_dbus_tests.py
Vojtech Trefny bb6266
index 8ae670d5..61c898c1 100644
Vojtech Trefny 0711d4
--- a/tests/lvm_dbus_tests.py
Vojtech Trefny 0711d4
+++ b/tests/lvm_dbus_tests.py
Vojtech Trefny bb6266
@@ -1843,3 +1843,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 bb6266
index 095e4bac..36ff10ec 100644
Vojtech Trefny 0711d4
--- a/tests/lvm_test.py
Vojtech Trefny 0711d4
+++ b/tests/lvm_test.py
Vojtech Trefny bb6266
@@ -1823,3 +1823,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 bb6266
2.37.3
Vojtech Trefny 0711d4
Vojtech Trefny 0711d4
Vojtech Trefny bb6266
From 05cfb84777c5472550673a1f2150ca357718b3f2 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 bb6266
Subject: [PATCH 7/7] 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 bb6266
index 7f48e422..d4b542e2 100644
Vojtech Trefny 0711d4
--- a/src/plugins/lvm-dbus.c
Vojtech Trefny 0711d4
+++ b/src/plugins/lvm-dbus.c
Vojtech Trefny bb6266
@@ -3964,9 +3964,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 bb6266
index 73d5005f..03211f8a 100644
Vojtech Trefny 0711d4
--- a/src/plugins/lvm.c
Vojtech Trefny 0711d4
+++ b/src/plugins/lvm.c
Vojtech Trefny bb6266
@@ -3263,9 +3263,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 bb6266
2.37.3
Vojtech Trefny 0711d4