diff --git a/SOURCES/0004-lvm-Add-a-function-to-activate-LVs-in-shared-mode.patch b/SOURCES/0004-lvm-Add-a-function-to-activate-LVs-in-shared-mode.patch new file mode 100644 index 0000000..bbf10c7 --- /dev/null +++ b/SOURCES/0004-lvm-Add-a-function-to-activate-LVs-in-shared-mode.patch @@ -0,0 +1,300 @@ +From ee9c3afec5ef2fe1e9fd50718cd732e267b235ed Mon Sep 17 00:00:00 2001 +From: Vojtech Trefny +Date: Mon, 24 Apr 2023 11:57:18 +0200 +Subject: [PATCH] lvm: Add a function to activate LVs in shared mode + +Needed by the new blivet feature to support shared LVM setups. +--- + src/lib/plugin_apis/lvm.api | 16 +++++++++ + src/plugins/lvm-dbus.c | 51 ++++++++++++++++++++------- + src/plugins/lvm.c | 53 ++++++++++++++++++++++------- + src/plugins/lvm.h | 1 + + src/python/gi/overrides/BlockDev.py | 5 ++- + tests/lvm_dbus_tests.py | 18 +++++++--- + tests/lvm_test.py | 18 +++++++--- + 7 files changed, 124 insertions(+), 38 deletions(-) + +diff --git a/src/lib/plugin_apis/lvm.api b/src/lib/plugin_apis/lvm.api +index dc8c1348..bac70a75 100644 +--- a/src/lib/plugin_apis/lvm.api ++++ b/src/lib/plugin_apis/lvm.api +@@ -1055,6 +1055,22 @@ gboolean bd_lvm_lvresize (const gchar *vg_name, const gchar *lv_name, guint64 si + */ + gboolean bd_lvm_lvactivate (const gchar *vg_name, const gchar *lv_name, gboolean ignore_skip, const BDExtraArg **extra, GError **error); + ++/** ++ * bd_lvm_lvactivate_shared: ++ * @vg_name: name of the VG containing the to-be-activated LV ++ * @lv_name: name of the to-be-activated LV ++ * @ignore_skip: whether to ignore the skip flag or not ++ * @shared: whether to activate the LV in shared mode ++ * @extra: (allow-none) (array zero-terminated=1): extra options for the LV activation ++ * (just passed to LVM as is) ++ * @error: (out): place to store error (if any) ++ * ++ * Returns: whether the @vg_name/@lv_name LV was successfully activated or not ++ * ++ * Tech category: %BD_LVM_TECH_BASIC-%BD_LVM_TECH_MODE_MODIFY ++ */ ++gboolean bd_lvm_lvactivate_shared (const gchar *vg_name, const gchar *lv_name, gboolean ignore_skip, gboolean shared, const BDExtraArg **extra, GError **error); ++ + /** + * bd_lvm_lvdeactivate: + * @vg_name: name of the VG containing the to-be-deactivated LV +diff --git a/src/plugins/lvm-dbus.c b/src/plugins/lvm-dbus.c +index b7b4480e..d8e997f9 100644 +--- a/src/plugins/lvm-dbus.c ++++ b/src/plugins/lvm-dbus.c +@@ -2115,6 +2115,27 @@ gboolean bd_lvm_lvresize (const gchar *vg_name, const gchar *lv_name, guint64 si + return (*error == NULL); + } + ++static gboolean _lvm_lvactivate (const gchar *vg_name, const gchar *lv_name, gboolean ignore_skip, gboolean shared, const BDExtraArg **extra, GError **error) { ++ GVariant *params = NULL; ++ GVariantBuilder builder; ++ GVariant *extra_params = NULL; ++ ++ if (shared) ++ params = g_variant_new ("(t)", (guint64) 1 << 6); ++ else ++ params = g_variant_new ("(t)", (guint64) 0); ++ ++ if (ignore_skip) { ++ g_variant_builder_init (&builder, G_VARIANT_TYPE_DICTIONARY); ++ g_variant_builder_add (&builder, "{sv}", "-K", g_variant_new ("s", "")); ++ extra_params = g_variant_builder_end (&builder); ++ g_variant_builder_clear (&builder); ++ } ++ call_lv_method_sync (vg_name, lv_name, "Activate", params, extra_params, extra, TRUE, error); ++ ++ return (*error == NULL); ++} ++ + /** + * bd_lvm_lvactivate: + * @vg_name: name of the VG containing the to-be-activated LV +@@ -2129,19 +2150,25 @@ gboolean bd_lvm_lvresize (const gchar *vg_name, const gchar *lv_name, guint64 si + * Tech category: %BD_LVM_TECH_BASIC-%BD_LVM_TECH_MODE_MODIFY + */ + gboolean bd_lvm_lvactivate (const gchar *vg_name, const gchar *lv_name, gboolean ignore_skip, const BDExtraArg **extra, GError **error) { +- GVariant *params = g_variant_new ("(t)", (guint64) 0); +- GVariantBuilder builder; +- GVariant *extra_params = NULL; +- +- if (ignore_skip) { +- g_variant_builder_init (&builder, G_VARIANT_TYPE_DICTIONARY); +- g_variant_builder_add (&builder, "{sv}", "-K", g_variant_new ("s", "")); +- extra_params = g_variant_builder_end (&builder); +- g_variant_builder_clear (&builder); +- } +- call_lv_method_sync (vg_name, lv_name, "Activate", params, extra_params, extra, TRUE, error); ++ return _lvm_lvactivate (vg_name, lv_name, ignore_skip, FALSE, extra, error); ++} + +- return (*error == NULL); ++/** ++ * bd_lvm_lvactivate_shared: ++ * @vg_name: name of the VG containing the to-be-activated LV ++ * @lv_name: name of the to-be-activated LV ++ * @ignore_skip: whether to ignore the skip flag or not ++ * @shared: whether to activate the LV in shared mode ++ * @extra: (allow-none) (array zero-terminated=1): extra options for the LV activation ++ * (just passed to LVM as is) ++ * @error: (out): place to store error (if any) ++ * ++ * Returns: whether the @vg_name/@lv_name LV was successfully activated or not ++ * ++ * Tech category: %BD_LVM_TECH_BASIC-%BD_LVM_TECH_MODE_MODIFY ++ */ ++gboolean bd_lvm_lvactivate_shared (const gchar *vg_name, const gchar *lv_name, gboolean ignore_skip, gboolean shared, const BDExtraArg **extra, GError **error) { ++ return _lvm_lvactivate (vg_name, lv_name, ignore_skip, shared, extra, error); + } + + /** +diff --git a/src/plugins/lvm.c b/src/plugins/lvm.c +index 50da656c..d7281339 100644 +--- a/src/plugins/lvm.c ++++ b/src/plugins/lvm.c +@@ -1594,6 +1594,28 @@ gboolean bd_lvm_lvresize (const gchar *vg_name, const gchar *lv_name, guint64 si + return success; + } + ++static gboolean _lvm_lvactivate (const gchar *vg_name, const gchar *lv_name, gboolean ignore_skip, gboolean shared, const BDExtraArg **extra, GError **error) { ++ const gchar *args[5] = {"lvchange", NULL, NULL, NULL, NULL}; ++ guint8 next_arg = 2; ++ gboolean success = FALSE; ++ ++ if (shared) ++ args[1] = "-asy"; ++ else ++ args[1] = "-ay"; ++ ++ if (ignore_skip) { ++ args[next_arg] = "-K"; ++ next_arg++; ++ } ++ args[next_arg] = g_strdup_printf ("%s/%s", vg_name, lv_name); ++ ++ success = call_lvm_and_report_error (args, extra, TRUE, error); ++ g_free ((gchar *) args[next_arg]); ++ ++ return success; ++} ++ + /** + * bd_lvm_lvactivate: + * @vg_name: name of the VG containing the to-be-activated LV +@@ -1608,20 +1630,25 @@ gboolean bd_lvm_lvresize (const gchar *vg_name, const gchar *lv_name, guint64 si + * Tech category: %BD_LVM_TECH_BASIC-%BD_LVM_TECH_MODE_MODIFY + */ + gboolean bd_lvm_lvactivate (const gchar *vg_name, const gchar *lv_name, gboolean ignore_skip, const BDExtraArg **extra, GError **error) { +- const gchar *args[5] = {"lvchange", "-ay", NULL, NULL, NULL}; +- guint8 next_arg = 2; +- gboolean success = FALSE; +- +- if (ignore_skip) { +- args[next_arg] = "-K"; +- next_arg++; +- } +- args[next_arg] = g_strdup_printf ("%s/%s", vg_name, lv_name); +- +- success = call_lvm_and_report_error (args, extra, TRUE, error); +- g_free ((gchar *) args[next_arg]); ++ return _lvm_lvactivate (vg_name, lv_name, ignore_skip, FALSE, extra, error); ++} + +- return success; ++/** ++ * bd_lvm_lvactivate_shared: ++ * @vg_name: name of the VG containing the to-be-activated LV ++ * @lv_name: name of the to-be-activated LV ++ * @ignore_skip: whether to ignore the skip flag or not ++ * @shared: whether to activate the LV in shared mode ++ * @extra: (allow-none) (array zero-terminated=1): extra options for the LV activation ++ * (just passed to LVM as is) ++ * @error: (out): place to store error (if any) ++ * ++ * Returns: whether the @vg_name/@lv_name LV was successfully activated or not ++ * ++ * Tech category: %BD_LVM_TECH_BASIC-%BD_LVM_TECH_MODE_MODIFY ++ */ ++gboolean bd_lvm_lvactivate_shared (const gchar *vg_name, const gchar *lv_name, gboolean ignore_skip, gboolean shared, const BDExtraArg **extra, GError **error) { ++ return _lvm_lvactivate (vg_name, lv_name, ignore_skip, shared, extra, error); + } + + /** +diff --git a/src/plugins/lvm.h b/src/plugins/lvm.h +index 2162d769..244663a4 100644 +--- a/src/plugins/lvm.h ++++ b/src/plugins/lvm.h +@@ -275,6 +275,7 @@ gboolean bd_lvm_lvremove (const gchar *vg_name, const gchar *lv_name, gboolean f + gboolean bd_lvm_lvrename (const gchar *vg_name, const gchar *lv_name, const gchar *new_name, const BDExtraArg **extra, GError **error); + gboolean bd_lvm_lvresize (const gchar *vg_name, const gchar *lv_name, guint64 size, const BDExtraArg **extra, GError **error); + gboolean bd_lvm_lvactivate (const gchar *vg_name, const gchar *lv_name, gboolean ignore_skip, const BDExtraArg **extra, GError **error); ++gboolean bd_lvm_lvactivate_shared (const gchar *vg_name, const gchar *lv_name, gboolean ignore_skip, gboolean shared, const BDExtraArg **extra, GError **error); + gboolean bd_lvm_lvdeactivate (const gchar *vg_name, const gchar *lv_name, const BDExtraArg **extra, GError **error); + gboolean bd_lvm_lvsnapshotcreate (const gchar *vg_name, const gchar *origin_name, const gchar *snapshot_name, guint64 size, const BDExtraArg **extra, GError **error); + gboolean bd_lvm_lvsnapshotmerge (const gchar *vg_name, const gchar *snapshot_name, const BDExtraArg **extra, GError **error); +diff --git a/src/python/gi/overrides/BlockDev.py b/src/python/gi/overrides/BlockDev.py +index f768c8bd..c7d72f4b 100644 +--- a/src/python/gi/overrides/BlockDev.py ++++ b/src/python/gi/overrides/BlockDev.py +@@ -580,11 +580,10 @@ def lvm_lvresize(vg_name, lv_name, size, extra=None, **kwargs): + return _lvm_lvresize(vg_name, lv_name, size, extra) + __all__.append("lvm_lvresize") + +-_lvm_lvactivate = BlockDev.lvm_lvactivate + @override(BlockDev.lvm_lvactivate) +-def lvm_lvactivate(vg_name, lv_name, ignore_skip=False, extra=None, **kwargs): ++def lvm_lvactivate(vg_name, lv_name, ignore_skip=False, shared=False, extra=None, **kwargs): + extra = _get_extra(extra, kwargs) +- return _lvm_lvactivate(vg_name, lv_name, ignore_skip, extra) ++ return BlockDev.lvm_lvactivate_shared(vg_name, lv_name, ignore_skip, shared, extra) + __all__.append("lvm_lvactivate") + + _lvm_lvdeactivate = BlockDev.lvm_lvdeactivate +diff --git a/tests/lvm_dbus_tests.py b/tests/lvm_dbus_tests.py +index 4882da88..67eaccd1 100644 +--- a/tests/lvm_dbus_tests.py ++++ b/tests/lvm_dbus_tests.py +@@ -799,15 +799,15 @@ class LvmTestLVactivateDeactivate(LvmPVVGLVTestCase): + self.assertTrue(succ) + + with self.assertRaises(GLib.GError): +- BlockDev.lvm_lvactivate("nonexistingVG", "testLV", True, None) ++ BlockDev.lvm_lvactivate("nonexistingVG", "testLV", True) + + with self.assertRaises(GLib.GError): +- BlockDev.lvm_lvactivate("testVG", "nonexistingLV", True, None) ++ BlockDev.lvm_lvactivate("testVG", "nonexistingLV", True) + + with self.assertRaises(GLib.GError): +- BlockDev.lvm_lvactivate("nonexistingVG", "nonexistingLV", True, None) ++ BlockDev.lvm_lvactivate("nonexistingVG", "nonexistingLV", True) + +- succ = BlockDev.lvm_lvactivate("testVG", "testLV", True, None) ++ succ = BlockDev.lvm_lvactivate("testVG", "testLV", True) + self.assertTrue(succ) + + with self.assertRaises(GLib.GError): +@@ -822,7 +822,15 @@ class LvmTestLVactivateDeactivate(LvmPVVGLVTestCase): + succ = BlockDev.lvm_lvdeactivate("testVG", "testLV", None) + self.assertTrue(succ) + +- succ = BlockDev.lvm_lvactivate("testVG", "testLV", True, None) ++ succ = BlockDev.lvm_lvactivate("testVG", "testLV", True) ++ self.assertTrue(succ) ++ ++ succ = BlockDev.lvm_lvdeactivate("testVG", "testLV", None) ++ self.assertTrue(succ) ++ ++ # try activating in shared mode, unfortunately no way to check whether it really ++ # works or not ++ succ = BlockDev.lvm_lvactivate("testVG", "testLV", True, True) + self.assertTrue(succ) + + succ = BlockDev.lvm_lvdeactivate("testVG", "testLV", None) +diff --git a/tests/lvm_test.py b/tests/lvm_test.py +index eb94c917..25e2f109 100644 +--- a/tests/lvm_test.py ++++ b/tests/lvm_test.py +@@ -730,15 +730,15 @@ class LvmTestLVactivateDeactivate(LvmPVVGLVTestCase): + self.assertTrue(succ) + + with self.assertRaises(GLib.GError): +- BlockDev.lvm_lvactivate("nonexistingVG", "testLV", True, None) ++ BlockDev.lvm_lvactivate("nonexistingVG", "testLV", True) + + with self.assertRaises(GLib.GError): +- BlockDev.lvm_lvactivate("testVG", "nonexistingLV", True, None) ++ BlockDev.lvm_lvactivate("testVG", "nonexistingLV", True) + + with self.assertRaises(GLib.GError): +- BlockDev.lvm_lvactivate("nonexistingVG", "nonexistingLV", True, None) ++ BlockDev.lvm_lvactivate("nonexistingVG", "nonexistingLV", True) + +- succ = BlockDev.lvm_lvactivate("testVG", "testLV", True, None) ++ succ = BlockDev.lvm_lvactivate("testVG", "testLV", True) + self.assertTrue(succ) + + with self.assertRaises(GLib.GError): +@@ -753,7 +753,15 @@ class LvmTestLVactivateDeactivate(LvmPVVGLVTestCase): + succ = BlockDev.lvm_lvdeactivate("testVG", "testLV", None) + self.assertTrue(succ) + +- succ = BlockDev.lvm_lvactivate("testVG", "testLV", True, None) ++ succ = BlockDev.lvm_lvactivate("testVG", "testLV", True) ++ self.assertTrue(succ) ++ ++ succ = BlockDev.lvm_lvdeactivate("testVG", "testLV", None) ++ self.assertTrue(succ) ++ ++ # try activating in shared mode, unfortunately no way to check whether it really ++ # works or not ++ succ = BlockDev.lvm_lvactivate("testVG", "testLV", True, True) + self.assertTrue(succ) + + succ = BlockDev.lvm_lvdeactivate("testVG", "testLV", None) +-- +2.41.0 + diff --git a/SOURCES/0005-lvm-Add-support-for-starting-and-stopping-VG-locking.patch b/SOURCES/0005-lvm-Add-support-for-starting-and-stopping-VG-locking.patch new file mode 100644 index 0000000..a2d9eac --- /dev/null +++ b/SOURCES/0005-lvm-Add-support-for-starting-and-stopping-VG-locking.patch @@ -0,0 +1,299 @@ +From 5e8429d004445c6f6e6f16cab67cf14cb4d32a65 Mon Sep 17 00:00:00 2001 +From: Vojtech Trefny +Date: Tue, 18 Apr 2023 12:05:35 +0200 +Subject: [PATCH] lvm: Add support for starting and stopping VG locking + +--- + docs/libblockdev-sections.txt | 2 ++ + src/lib/plugin_apis/lvm.api | 27 +++++++++++++++++++ + src/plugins/lvm-dbus.c | 49 ++++++++++++++++++++++++++++++++++- + src/plugins/lvm.c | 41 +++++++++++++++++++++++++++++ + src/plugins/lvm.h | 3 +++ + tests/lvm_dbus_tests.py | 33 +++++++++++++++++++++++ + tests/lvm_test.py | 32 +++++++++++++++++++++++ + 7 files changed, 186 insertions(+), 1 deletion(-) + +diff --git a/docs/libblockdev-sections.txt b/docs/libblockdev-sections.txt +index 512820c2..7377dd17 100644 +--- a/docs/libblockdev-sections.txt ++++ b/docs/libblockdev-sections.txt +@@ -286,6 +286,8 @@ bd_lvm_vgactivate + bd_lvm_vgdeactivate + bd_lvm_vgextend + bd_lvm_vgreduce ++bd_lvm_vglock_start ++bd_lvm_vglock_stop + bd_lvm_vginfo + bd_lvm_vgs + bd_lvm_lvorigin +diff --git a/src/lib/plugin_apis/lvm.api b/src/lib/plugin_apis/lvm.api +index 54c47a93..14f2620a 100644 +--- a/src/lib/plugin_apis/lvm.api ++++ b/src/lib/plugin_apis/lvm.api +@@ -601,6 +601,7 @@ typedef enum { + BD_LVM_TECH_CACHE_CALCS, + BD_LVM_TECH_GLOB_CONF, + BD_LVM_TECH_VDO, ++ BD_LVM_TECH_SHARED, + } BDLVMTech; + + typedef enum { +@@ -941,6 +942,32 @@ gboolean bd_lvm_vgextend (const gchar *vg_name, const gchar *device, const BDExt + */ + gboolean bd_lvm_vgreduce (const gchar *vg_name, const gchar *device, const BDExtraArg **extra, GError **error); + ++/** ++ * bd_lvm_vglock_start: ++ * @vg_name: a shared VG to start the lockspace in lvmlockd ++ * @extra: (nullable) (array zero-terminated=1): extra options for the vgchange command ++ * (just passed to LVM as is) ++ * @error: (out): place to store error (if any) ++ * ++ * Returns: whether the lock was successfully started for @vg_name or not ++ * ++ * Tech category: %BD_LVM_TECH_SHARED-%BD_LVM_TECH_MODE_MODIFY ++ */ ++gboolean bd_lvm_vglock_start (const gchar *vg_name, const BDExtraArg **extra, GError **error); ++ ++/** ++ * bd_lvm_vglock_stop: ++ * @vg_name: a shared VG to stop the lockspace in lvmlockd ++ * @extra: (nullable) (array zero-terminated=1): extra options for the vgchange command ++ * (just passed to LVM as is) ++ * @error: (out): place to store error (if any) ++ * ++ * Returns: whether the lock was successfully stopped for @vg_name or not ++ * ++ * Tech category: %BD_LVM_TECH_SHARED-%BD_LVM_TECH_MODE_MODIFY ++ */ ++gboolean bd_lvm_vglock_stop (const gchar *vg_name, const BDExtraArg **extra, GError **error); ++ + /** + * bd_lvm_vginfo: + * @vg_name: a VG to get information about +diff --git a/src/plugins/lvm-dbus.c b/src/plugins/lvm-dbus.c +index e1f946fe..ad44dfb3 100644 +--- a/src/plugins/lvm-dbus.c ++++ b/src/plugins/lvm-dbus.c +@@ -1848,10 +1848,57 @@ gboolean bd_lvm_vgreduce (const gchar *vg_name, const gchar *device, const BDExt + return ((*error) == NULL); + } + ++gboolean _vglock_start_stop (const gchar *vg_name, gboolean start, const BDExtraArg **extra, GError **error) { ++ GVariantBuilder builder; ++ GVariant *params = NULL; ++ ++ g_variant_builder_init (&builder, G_VARIANT_TYPE_DICTIONARY); ++ if (start) ++ g_variant_builder_add (&builder, "{sv}", "--lockstart", g_variant_new ("s", "")); ++ else ++ g_variant_builder_add (&builder, "{sv}", "--lockstop", g_variant_new ("s", "")); ++ params = g_variant_builder_end (&builder); ++ g_variant_builder_clear (&builder); ++ ++ call_lvm_obj_method_sync (vg_name, VG_INTF, "Change", NULL, params, extra, TRUE, error); ++ ++ return ((*error) == NULL); ++} ++ ++/** ++ * bd_lvm_vglock_start: ++ * @vg_name: a shared VG to start the lockspace in lvmlockd ++ * @extra: (nullable) (array zero-terminated=1): extra options for the vgchange command ++ * (just passed to LVM as is) ++ * @error: (out): place to store error (if any) ++ * ++ * Returns: whether the lock was successfully started for @vg_name or not ++ * ++ * Tech category: %BD_LVM_TECH_BASIC-%BD_LVM_TECH_MODE_MODIFY ++ */ ++gboolean bd_lvm_vglock_start (const gchar *vg_name, const BDExtraArg **extra, GError **error) { ++ return _vglock_start_stop (vg_name, TRUE, extra, error); ++} ++ ++/** ++ * bd_lvm_vglock_stop: ++ * @vg_name: a shared VG to stop the lockspace in lvmlockd ++ * @extra: (nullable) (array zero-terminated=1): extra options for the vgchange command ++ * (just passed to LVM as is) ++ * @error: (out): place to store error (if any) ++ * ++ * Returns: whether the lock was successfully stopped for @vg_name or not ++ * ++ * Tech category: %BD_LVM_TECH_BASIC-%BD_LVM_TECH_MODE_MODIFY ++ */ ++gboolean bd_lvm_vglock_stop (const gchar *vg_name, const BDExtraArg **extra, GError **error) { ++ return _vglock_start_stop (vg_name, FALSE, extra, error); ++} ++ + /** + * bd_lvm_vginfo: + * @vg_name: a VG to get information about +- * @error: (out): place to store error (if any) ++ * @error: (out) (optional): place to store error (if any) + * + * Returns: (transfer full): information about the @vg_name VG or %NULL in case + * of error (the @error) gets populated in those cases) +diff --git a/src/plugins/lvm.c b/src/plugins/lvm.c +index 8bb3ae24..1aaf6747 100644 +--- a/src/plugins/lvm.c ++++ b/src/plugins/lvm.c +@@ -1316,6 +1316,47 @@ gboolean bd_lvm_vgreduce (const gchar *vg_name, const gchar *device, const BDExt + return call_lvm_and_report_error (args, extra, TRUE, error); + } + ++gboolean _vglock_start_stop (const gchar *vg_name, gboolean start, const BDExtraArg **extra, GError **error) { ++ const gchar *args[4] = {"vgchange", NULL, vg_name, NULL}; ++ ++ if (start) ++ args[1] = "--lockstart"; ++ else ++ args[1] = "--lockstop"; ++ ++ return call_lvm_and_report_error (args, extra, TRUE, error); ++} ++ ++/** ++ * bd_lvm_vglock_start: ++ * @vg_name: a shared VG to start the lockspace in lvmlockd ++ * @extra: (nullable) (array zero-terminated=1): extra options for the vgchange command ++ * (just passed to LVM as is) ++ * @error: (out): place to store error (if any) ++ * ++ * Returns: whether the lock was successfully started for @vg_name or not ++ * ++ * Tech category: %BD_LVM_TECH_SHARED-%BD_LVM_TECH_MODE_MODIFY ++ */ ++gboolean bd_lvm_vglock_start (const gchar *vg_name, const BDExtraArg **extra, GError **error) { ++ return _vglock_start_stop (vg_name, TRUE, extra, error); ++} ++ ++/** ++ * bd_lvm_vglock_stop: ++ * @vg_name: a shared VG to stop the lockspace in lvmlockd ++ * @extra: (nullable) (array zero-terminated=1): extra options for the vgchange command ++ * (just passed to LVM as is) ++ * @error: (out): place to store error (if any) ++ * ++ * Returns: whether the lock was successfully stopped for @vg_name or not ++ * ++ * Tech category: %BD_LVM_TECH_SHARED-%BD_LVM_TECH_MODE_MODIFY ++ */ ++gboolean bd_lvm_vglock_stop (const gchar *vg_name, const BDExtraArg **extra, GError **error) { ++ return _vglock_start_stop (vg_name, FALSE, extra, error); ++} ++ + /** + * bd_lvm_vginfo: + * @vg_name: a VG to get information about +diff --git a/src/plugins/lvm.h b/src/plugins/lvm.h +index 244663a4..da14cc1a 100644 +--- a/src/plugins/lvm.h ++++ b/src/plugins/lvm.h +@@ -216,6 +216,7 @@ typedef enum { + BD_LVM_TECH_CACHE_CALCS, + BD_LVM_TECH_GLOB_CONF, + BD_LVM_TECH_VDO, ++ BD_LVM_TECH_SHARED, + } BDLVMTech; + + typedef enum { +@@ -266,6 +267,8 @@ gboolean bd_lvm_vgactivate (const gchar *vg_name, const BDExtraArg **extra, GErr + gboolean bd_lvm_vgdeactivate (const gchar *vg_name, const BDExtraArg **extra, GError **error); + gboolean bd_lvm_vgextend (const gchar *vg_name, const gchar *device, const BDExtraArg **extra, GError **error); + gboolean bd_lvm_vgreduce (const gchar *vg_name, const gchar *device, const BDExtraArg **extra, GError **error); ++gboolean bd_lvm_vglock_start (const gchar *vg_name, const BDExtraArg **extra, GError **error); ++gboolean bd_lvm_vglock_stop (const gchar *vg_name, const BDExtraArg **extra, GError **error); + BDLVMVGdata* bd_lvm_vginfo (const gchar *vg_name, GError **error); + BDLVMVGdata** bd_lvm_vgs (GError **error); + +diff --git a/tests/lvm_dbus_tests.py b/tests/lvm_dbus_tests.py +index 862a44cf..2a92c7c1 100644 +--- a/tests/lvm_dbus_tests.py ++++ b/tests/lvm_dbus_tests.py +@@ -612,6 +612,39 @@ class LvmTestVGs(LvmPVVGTestCase): + succ = BlockDev.lvm_pvremove(self.loop_dev, None) + self.assertTrue(succ) + ++@unittest.skipUnless(lvm_dbus_running, "LVM DBus not running") ++class LvmTestVGLocking(LvmPVVGTestCase): ++ @tag_test(TestTags.UNSAFE) ++ def test_vglock_stop_start(self): ++ """Verify that it is possible to start and stop locking on a VG""" ++ ++ # better not do anything if lvmlockd is running, shared VGs have ++ # a tendency to wreak havoc on your system if you look at them wrong ++ ret, _out, _err = run_command("systemctl is-active lvmlockd") ++ if ret == 0: ++ self.skipTest("lvmlockd is running, skipping") ++ ++ _ret, out, _err = run_command("lvm config 'global/use_lvmlockd'") ++ if "use_lvmlockd=0" not in out: ++ self.skipTest("lvmlockd is enabled, skipping") ++ ++ succ = BlockDev.lvm_pvcreate(self.loop_dev, 0, 0, None) ++ self.assertTrue(succ) ++ ++ succ = BlockDev.lvm_pvcreate(self.loop_dev2, 0, 0, None) ++ self.assertTrue(succ) ++ ++ succ = BlockDev.lvm_vgcreate("testVG", [self.loop_dev, self.loop_dev2], 0, None) ++ self.assertTrue(succ) ++ ++ # this actually doesn't "test" anything, the commands will just say lvmlockd is not ++ # running and return 0, but that's good enough for us ++ succ = BlockDev.lvm_vglock_start("testVG") ++ self.assertTrue(succ) ++ ++ succ = BlockDev.lvm_vglock_stop("testVG") ++ self.assertTrue(succ) ++ + @unittest.skipUnless(lvm_dbus_running, "LVM DBus not running") + class LvmPVVGLVTestCase(LvmPVVGTestCase): + def _clean_up(self): +diff --git a/tests/lvm_test.py b/tests/lvm_test.py +index 96f1670d..3ab11f04 100644 +--- a/tests/lvm_test.py ++++ b/tests/lvm_test.py +@@ -585,6 +585,38 @@ class LvmTestVGs(LvmPVVGTestCase): + succ = BlockDev.lvm_pvremove(self.loop_dev, None) + self.assertTrue(succ) + ++class LvmTestVGLocking(LvmPVVGTestCase): ++ @tag_test(TestTags.UNSAFE) ++ def test_vglock_stop_start(self): ++ """Verify that it is possible to start and stop locking on a VG""" ++ ++ # better not do anything if lvmlockd is running, shared VGs have ++ # a tendency to wreak havoc on your system if you look at them wrong ++ ret, _out, _err = run_command("systemctl is-active lvmlockd") ++ if ret == 0: ++ self.skipTest("lvmlockd is running, skipping") ++ ++ _ret, out, _err = run_command("lvm config 'global/use_lvmlockd'") ++ if "use_lvmlockd=0" not in out: ++ self.skipTest("lvmlockd is enabled, skipping") ++ ++ succ = BlockDev.lvm_pvcreate(self.loop_dev, 0, 0, None) ++ self.assertTrue(succ) ++ ++ succ = BlockDev.lvm_pvcreate(self.loop_dev2, 0, 0, None) ++ self.assertTrue(succ) ++ ++ succ = BlockDev.lvm_vgcreate("testVG", [self.loop_dev, self.loop_dev2], 0, None) ++ self.assertTrue(succ) ++ ++ # this actually doesn't "test" anything, the commands will just say lvmlockd is not ++ # running and return 0, but that's good enough for us ++ succ = BlockDev.lvm_vglock_start("testVG") ++ self.assertTrue(succ) ++ ++ succ = BlockDev.lvm_vglock_stop("testVG") ++ self.assertTrue(succ) ++ + class LvmPVVGLVTestCase(LvmPVVGTestCase): + def _clean_up(self): + try: +-- +2.41.0 + diff --git a/SPECS/libblockdev.spec b/SPECS/libblockdev.spec index 3134bf8..8143b0e 100644 --- a/SPECS/libblockdev.spec +++ b/SPECS/libblockdev.spec @@ -125,7 +125,7 @@ Name: libblockdev Version: 2.28 -Release: 4%{?dist} +Release: 6%{?dist} Summary: A library for low-level manipulation with block devices License: LGPLv2+ URL: https://github.com/storaged-project/libblockdev @@ -133,6 +133,8 @@ Source0: https://github.com/storaged-project/libblockdev/releases/download/% Patch0: 0001-crypto-Fix-GError-overwrite-from-libvolume_key.patch Patch1: 0002-tests-Fix-test_swapon_pagesize-on-systems-with-64k-p.patch Patch2: 0003-part-Fix-segfault-when-adding-a-partition-too-big-fo.patch +Patch3: 0004-lvm-Add-a-function-to-activate-LVs-in-shared-mode.patch +Patch4: 0005-lvm-Add-support-for-starting-and-stopping-VG-locking.patch BuildRequires: make BuildRequires: glib2-devel @@ -685,10 +687,7 @@ A meta-package that pulls all the libblockdev plugins as dependencies. %prep -%setup -q -n %{name}-%{version} -%patch0 -p1 -%patch1 -p1 -%patch2 -p1 +%autosetup -n %{name}-%{version} -p1 %build autoreconf -ivf @@ -992,6 +991,14 @@ find %{buildroot} -type f -name "*.la" | xargs %{__rm} %files plugins-all %changelog +* Wed Nov 08 2023 Vojtech Trefny - 2.28-10 +- lvm: Add support for starting and stopping VG locking + Resolves: RHEL-15923 + +* Thu Oct 19 2023 Vojtech Trefny - 2.28-5 +- lvm: Add a function to activate LVs in shared mode + Resolves: RHEL-14023 + * Tue May 16 2023 Vojtech Trefny - 2.28-4 - Fix segfault when adding a partition too big for MSDOS Resolves: rhbz#2207500