From af2aeba737cca3f3d2f531099a2fde5929edef31 Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Wed, 11 Oct 2023 16:43:19 +0200 Subject: [PATCH] Add BDPluginSpec constructor and use it in plugin_specs_from_names Starting with Python 3.12 we got some weird complains when setting attributes of BlockDev.PluginSpec in plugin_specs_from_names, it's better to add a fully working constructor to create the struct correctly from the Python overrides. --- docs/libblockdev-sections.txt | 1 + src/lib/plugins.c | 18 ++++++++++++++++++ src/lib/plugins.h | 7 +++++++ src/python/gi/overrides/BlockDev.py | 13 ++++++++++--- tests/library_test.py | 16 ++++------------ tests/lvm_dbus_tests.py | 7 ++----- 6 files changed, 42 insertions(+), 20 deletions(-) diff --git a/docs/libblockdev-sections.txt b/docs/libblockdev-sections.txt index 8421e24..aa0b4b5 100644 --- a/docs/libblockdev-sections.txt +++ b/docs/libblockdev-sections.txt @@ -447,6 +447,7 @@ bd_mpath_is_tech_avail BDPlugin bd_plugin_spec_copy bd_plugin_spec_free +bd_plugin_spec_new bd_is_plugin_available bd_get_available_plugin_names bd_get_plugin_soname diff --git a/src/lib/plugins.c b/src/lib/plugins.c index 53f56b2..3cb6d0d 100644 --- a/src/lib/plugins.c +++ b/src/lib/plugins.c @@ -40,6 +40,24 @@ void bd_plugin_spec_free (BDPluginSpec *spec) { g_free (spec); } +/** + * bd_plugin_spec_new: (constructor) + * @name: %BDPlugin name, e.g. %BD_PLUGIN_LVM + * @so_name: (nullable): SO name of the plugin to load or %NULL for default + * + * Returns: (transfer full): a new plugin spec + */ +BDPluginSpec* bd_plugin_spec_new (BDPlugin name, const gchar *so_name) { + BDPluginSpec* ret = g_new0 (BDPluginSpec, 1); + ret->name = name; + /* FIXME: this should be const, but we are already allocating a new string in _copy + * and freeing it in _free + */ + ret->so_name = so_name ? g_strdup (so_name) : NULL; + + return ret; +} + GType bd_plugin_spec_get_type (void) { static GType type = 0; diff --git a/src/lib/plugins.h b/src/lib/plugins.h index 8b7c541..3574916 100644 --- a/src/lib/plugins.h +++ b/src/lib/plugins.h @@ -24,6 +24,12 @@ typedef enum { #define BD_TYPE_PLUGIN_SPEC (bd_plugin_spec_get_type ()) GType bd_plugin_spec_get_type(void); +/** + * BDPluginSpec: + * @name: %BDPlugin name, e.g. %BD_PLUGIN_LVM + * @so_name: (nullable): SO name of the plugin to load or %NULL for default + * + */ typedef struct BDPluginSpec { BDPlugin name; const gchar *so_name; @@ -31,6 +37,7 @@ typedef struct BDPluginSpec { BDPluginSpec* bd_plugin_spec_copy (BDPluginSpec *spec); void bd_plugin_spec_free (BDPluginSpec *spec); +BDPluginSpec* bd_plugin_spec_new (BDPlugin name, const gchar *so_name); gboolean bd_is_plugin_available (BDPlugin plugin); gchar** bd_get_available_plugin_names (void); diff --git a/src/python/gi/overrides/BlockDev.py b/src/python/gi/overrides/BlockDev.py index e2cb695..8aac896 100644 --- a/src/python/gi/overrides/BlockDev.py +++ b/src/python/gi/overrides/BlockDev.py @@ -85,6 +85,15 @@ for _cname, cls in all_boxed: cls.__repr__ = _default_repr +class PluginSpec(BlockDev.PluginSpec): + def __new__(cls, name=BlockDev.Plugin.UNDEF, so_name=None): + ret = BlockDev.PluginSpec.new(name, so_name) + ret.__class__ = cls + return ret +PluginSpec = override(PluginSpec) +__all__.append("PluginSpec") + + class ExtraArg(BlockDev.ExtraArg): def __new__(cls, opt, val=""): ret = BlockDev.ExtraArg.new(opt, val) @@ -1122,9 +1131,7 @@ __all__.append("nvme_connect") def plugin_specs_from_names(plugin_names): ret = [] for name in plugin_names: - plugin = BlockDev.PluginSpec() - plugin.name = bd_plugins[name.lower()] - plugin.so_name = None + plugin = PluginSpec(name=bd_plugins[name.lower()], so_name=None) ret.append(plugin) return ret diff --git a/tests/library_test.py b/tests/library_test.py index 1814d13..cb93da9 100644 --- a/tests/library_test.py +++ b/tests/library_test.py @@ -71,9 +71,7 @@ class LibraryOpsTestCase(unittest.TestCase): def test_require_plugins(self): """Verify that loading only required plugins works as expected""" - ps = BlockDev.PluginSpec() - ps.name = BlockDev.Plugin.SWAP - ps.so_name = "" + ps = BlockDev.PluginSpec(name=BlockDev.Plugin.SWAP, so_name="") self.assertTrue(BlockDev.reinit([ps], True, None)) self.assertEqual(BlockDev.get_available_plugin_names(), ["swap"]) self.assertTrue(BlockDev.reinit(self.requested_plugins, True, None)) @@ -85,9 +83,7 @@ class LibraryOpsTestCase(unittest.TestCase): # should be loaded and working self.assertTrue(BlockDev.md_canonicalize_uuid("3386ff85:f5012621:4a435f06:1eb47236")) - ps = BlockDev.PluginSpec() - ps.name = BlockDev.Plugin.SWAP - ps.so_name = "" + ps = BlockDev.PluginSpec(name=BlockDev.Plugin.SWAP, so_name="") self.assertTrue(BlockDev.reinit([ps], True, None)) self.assertEqual(BlockDev.get_available_plugin_names(), ["swap"]) @@ -237,9 +233,7 @@ class PluginsTestCase(unittest.TestCase): self.assertEqual(ret, 0, "Failed to recompile libblockdev for force plugin test") # force the new plugin to be used - ps = BlockDev.PluginSpec() - ps.name = BlockDev.Plugin.LVM - ps.so_name = "libbd_lvm2.so" + ps = BlockDev.PluginSpec(name=BlockDev.Plugin.LVM, so_name="libbd_lvm2.so") self.assertTrue(BlockDev.reinit([ps], True, None)) # new LVM plugin loaded, max LV size should be 1024 bytes @@ -249,9 +243,7 @@ class PluginsTestCase(unittest.TestCase): os.system ("rm -f src/plugins/.libs/libbd_lvm2.so") # force the old plugin to be used - ps = BlockDev.PluginSpec() - ps.name = BlockDev.Plugin.LVM - ps.so_name = "libbd_lvm.so" + ps = BlockDev.PluginSpec(name=BlockDev.Plugin.LVM, so_name="libbd_lvm.so") self.assertTrue(BlockDev.reinit([ps], True, None)) self.assertEqual(BlockDev.lvm_get_max_lv_size(), orig_max_size) diff --git a/tests/lvm_dbus_tests.py b/tests/lvm_dbus_tests.py index c0b36b2..327211d 100644 --- a/tests/lvm_dbus_tests.py +++ b/tests/lvm_dbus_tests.py @@ -43,11 +43,8 @@ class LVMTestCase(unittest.TestCase): def setUpClass(cls): if lvm_dbus_running: # force the new plugin to be used - cls.ps = BlockDev.PluginSpec() - cls.ps.name = BlockDev.Plugin.LVM - cls.ps.so_name = "libbd_lvm-dbus.so.3" - cls.ps2 = BlockDev.PluginSpec() - cls.ps2.name = BlockDev.Plugin.LOOP + cls.ps = BlockDev.PluginSpec(name=BlockDev.Plugin.LVM, so_name="libbd_lvm-dbus.so.3") + cls.ps2 = BlockDev.PluginSpec(name=BlockDev.Plugin.LOOP) if not BlockDev.is_initialized(): BlockDev.init([cls.ps, cls.ps2], None) else: