From 762751ddd7893666689414c2171fcb81266d5d8b Mon Sep 17 00:00:00 2001 From: Vojtech Trefny Date: Fri, 19 Jul 2024 14:48:46 +0200 Subject: [PATCH] Bugfix update for C10S - Fix passing size for pvresize over DBus Resolves: RHEL-45872 - Upstream kernel VDO support Resolves: RHEL-31953 --- ...-passing-size-for-pvresize-over-DBus.patch | 65 ++ 0004-Upstream-kernel-VDO-support.patch | 571 ++++++++++++++++++ 0005-libext2fs-unused-parameters-fix.patch | 86 +++ libblockdev.spec | 13 +- tests/tests.yml | 1 + 5 files changed, 735 insertions(+), 1 deletion(-) create mode 100644 0003-Fix-passing-size-for-pvresize-over-DBus.patch create mode 100644 0004-Upstream-kernel-VDO-support.patch create mode 100644 0005-libext2fs-unused-parameters-fix.patch diff --git a/0003-Fix-passing-size-for-pvresize-over-DBus.patch b/0003-Fix-passing-size-for-pvresize-over-DBus.patch new file mode 100644 index 0000000..5d19946 --- /dev/null +++ b/0003-Fix-passing-size-for-pvresize-over-DBus.patch @@ -0,0 +1,65 @@ +From 7afe64265c9fc6ac67bfc412e43d00e5a21c867a Mon Sep 17 00:00:00 2001 +From: Vojtech Trefny +Date: Fri, 22 Mar 2024 14:54:15 +0100 +Subject: [PATCH] lvm-dbus: Fix passing size for pvresize over DBus + +"u" is UINT32, we need to use "t" for UINT64 +--- + src/plugins/lvm-dbus.c | 2 +- + tests/lvm_dbus_tests.py | 6 ++++++ + tests/lvm_test.py | 6 ++++++ + 3 files changed, 13 insertions(+), 1 deletion(-) + +diff --git a/src/plugins/lvm-dbus.c b/src/plugins/lvm-dbus.c +index 5ecf47f6..ff9eb24b 100644 +--- a/src/plugins/lvm-dbus.c ++++ b/src/plugins/lvm-dbus.c +@@ -1776,7 +1776,7 @@ gboolean bd_lvm_pvresize (const gchar *device, guint64 size, const BDExtraArg ** + if (!obj_path) + return FALSE; + +- params = g_variant_new ("(u)", size); ++ params = g_variant_new ("(t)", size); + return call_lvm_method_sync (obj_path, PV_INTF, "ReSize", params, NULL, extra, TRUE, error); + } + +diff --git a/tests/lvm_dbus_tests.py b/tests/lvm_dbus_tests.py +index 013a29c3..c179a82c 100644 +--- a/tests/lvm_dbus_tests.py ++++ b/tests/lvm_dbus_tests.py +@@ -431,9 +431,15 @@ def test_pvresize(self): + succ = BlockDev.lvm_pvresize(self.loop_dev, 200 * 1024**2, None) + self.assertTrue(succ) + ++ info = BlockDev.lvm_pvinfo(self.loop_dev) ++ self.assertEqual(info.pv_size, 200 * 1024**2) ++ + succ = BlockDev.lvm_pvresize(self.loop_dev, 200 * 1024**3, None) + self.assertTrue(succ) + ++ info = BlockDev.lvm_pvinfo(self.loop_dev) ++ self.assertEqual(info.pv_size, 200 * 1024**3) ++ + @unittest.skipUnless(lvm_dbus_running, "LVM DBus not running") + class LvmTestPVscan(LvmPVonlyTestCase): + def test_pvscan(self): +diff --git a/tests/lvm_test.py b/tests/lvm_test.py +index e7800d8f..261615e9 100644 +--- a/tests/lvm_test.py ++++ b/tests/lvm_test.py +@@ -434,9 +434,15 @@ def test_pvresize(self): + succ = BlockDev.lvm_pvresize(self.loop_dev, 200 * 1024**2, None) + self.assertTrue(succ) + ++ info = BlockDev.lvm_pvinfo(self.loop_dev) ++ self.assertEqual(info.pv_size, 200 * 1024**2) ++ + succ = BlockDev.lvm_pvresize(self.loop_dev, 200 * 1024**3, None) + self.assertTrue(succ) + ++ info = BlockDev.lvm_pvinfo(self.loop_dev) ++ self.assertEqual(info.pv_size, 200 * 1024**3) ++ + class LvmTestPVscan(LvmPVonlyTestCase): + def test_pvscan(self): + """Verify that pvscan runs without issues with cache or without""" diff --git a/0004-Upstream-kernel-VDO-support.patch b/0004-Upstream-kernel-VDO-support.patch new file mode 100644 index 0000000..6a01f76 --- /dev/null +++ b/0004-Upstream-kernel-VDO-support.patch @@ -0,0 +1,571 @@ +From 5db24c0542a6c7ee44e2d487969ef71170d9cb33 Mon Sep 17 00:00:00 2001 +From: Vojtech Trefny +Date: Tue, 2 Jul 2024 12:30:42 +0200 +Subject: [PATCH 1/2] lvm: Check for dm-vdo instead of kvdo module for VDO + support + +VDO is available in the upstream kernel since 6.9 as dm-vdo so we +should check for it instead of the out-of-tree kvdo module. +--- + src/plugins/lvm-dbus.c | 2 +- + src/plugins/lvm.c | 2 +- + tests/lvm_dbus_tests.py | 4 ++-- + tests/lvm_test.py | 4 ++-- + 4 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/plugins/lvm-dbus.c b/src/plugins/lvm-dbus.c +index d080b389..0c017306 100644 +--- a/src/plugins/lvm-dbus.c ++++ b/src/plugins/lvm-dbus.c +@@ -321,7 +321,7 @@ static const UtilFeatureDep features[FEATURES_LAST] = { + #define MODULE_DEPS_VDO_MASK (1 << MODULE_DEPS_VDO) + #define MODULE_DEPS_LAST 1 + +-static const gchar*const module_deps[MODULE_DEPS_LAST] = { "kvdo" }; ++static const gchar*const module_deps[MODULE_DEPS_LAST] = { "dm-vdo" }; + + /** + * bd_lvm_init: +diff --git a/src/plugins/lvm.c b/src/plugins/lvm.c +index 361a084b..dc7491a7 100644 +--- a/src/plugins/lvm.c ++++ b/src/plugins/lvm.c +@@ -329,7 +329,7 @@ static const UtilFeatureDep features[FEATURES_LAST] = { + #define MODULE_DEPS_VDO_MASK (1 << MODULE_DEPS_VDO) + #define MODULE_DEPS_LAST 1 + +-static const gchar*const module_deps[MODULE_DEPS_LAST] = { "kvdo" }; ++static const gchar*const module_deps[MODULE_DEPS_LAST] = { "dm-vdo" }; + + #define UNUSED __attribute__((unused)) + +diff --git a/tests/lvm_dbus_tests.py b/tests/lvm_dbus_tests.py +index fc270cb5..9f302611 100644 +--- a/tests/lvm_dbus_tests.py ++++ b/tests/lvm_dbus_tests.py +@@ -2029,11 +2029,11 @@ class LVMVDOTest(LVMTestCase): + + @classmethod + def setUpClass(cls): +- if not BlockDev.utils_have_kernel_module("kvdo"): ++ if not BlockDev.utils_have_kernel_module("dm-vdo"): + raise unittest.SkipTest("VDO kernel module not available, skipping.") + + try: +- BlockDev.utils_load_kernel_module("kvdo") ++ BlockDev.utils_load_kernel_module("dm-vdo") + except GLib.GError as e: + if "File exists" not in e.message: + raise unittest.SkipTest("cannot load VDO kernel module, skipping.") +diff --git a/tests/lvm_test.py b/tests/lvm_test.py +index a4c90172..b1d65baf 100644 +--- a/tests/lvm_test.py ++++ b/tests/lvm_test.py +@@ -1933,11 +1933,11 @@ class LVMVDOTest(LVMTestCase): + + @classmethod + def setUpClass(cls): +- if not BlockDev.utils_have_kernel_module("kvdo"): ++ if not BlockDev.utils_have_kernel_module("dm-vdo"): + raise unittest.SkipTest("VDO kernel module not available, skipping.") + + try: +- BlockDev.utils_load_kernel_module("kvdo") ++ BlockDev.utils_load_kernel_module("dm-vdo") + except GLib.GError as e: + if "File exists" not in e.message: + raise unittest.SkipTest("cannot load VDO kernel module, skipping.") +-- +2.45.2 + + +From 6cf4de50d385d801c1936fc67ee2902f9c60e04e Mon Sep 17 00:00:00 2001 +From: Vojtech Trefny +Date: Tue, 2 Jul 2024 12:32:46 +0200 +Subject: [PATCH 2/2] lvm: Get VDO stats from device mapper instead of + /sys/kvdo + +The /sys/kvdo API has been removed so we need to get the full +statistics using libdevmapper now. +--- + configure.ac | 4 + + dist/libblockdev.spec.in | 2 + + src/lib/plugin_apis/lvm.api | 6 +- + src/plugins/Makefile.am | 8 +- + src/plugins/lvm-dbus.c | 18 +-- + src/plugins/lvm.c | 18 +-- + src/plugins/vdo_stats.c | 213 ++++++++++++++++++++++-------------- + tests/lvm_dbus_tests.py | 4 +- + tests/lvm_test.py | 10 +- + 9 files changed, 175 insertions(+), 108 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 02b26e3e..cc875bb4 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -193,6 +193,10 @@ AS_IF([test "x$with_dm" != "xno" -o "x$with_lvm" != "xno" -o "x$with_lvm_dbus" ! + [LIBBLOCKDEV_PKG_CHECK_MODULES([DEVMAPPER], [devmapper >= 1.02.93])], + []) + ++AS_IF([test "x$with_lvm" != "xno" -o "x$with_lvm_dbus" != "xno"], ++ [LIBBLOCKDEV_PKG_CHECK_MODULES([YAML], [yaml-0.1])], ++ []) ++ + AS_IF([test "x$with_part" != "xno"], + [LIBBLOCKDEV_PKG_CHECK_MODULES([FDISK], [fdisk >= 2.31.0])], + []) +diff --git a/dist/libblockdev.spec.in b/dist/libblockdev.spec.in +index 768aa0c0..e8703411 100644 +--- a/dist/libblockdev.spec.in ++++ b/dist/libblockdev.spec.in +@@ -290,6 +290,7 @@ with the libblockdev-loop plugin/library. + %if %{with_lvm} + %package lvm + BuildRequires: device-mapper-devel ++BuildRequires: libyaml-devel + Summary: The LVM plugin for the libblockdev library + Requires: %{name}-utils%{?_isa} = %{version}-%{release} + Requires: lvm2 +@@ -312,6 +313,7 @@ with the libblockdev-lvm plugin/library. + %if %{with_lvm_dbus} + %package lvm-dbus + BuildRequires: device-mapper-devel ++BuildRequires: libyaml-devel + Summary: The LVM plugin for the libblockdev library + Requires: %{name}-utils%{?_isa} = %{version}-%{release} + Requires: lvm2-dbusd >= 2.02.156 +diff --git a/src/lib/plugin_apis/lvm.api b/src/lib/plugin_apis/lvm.api +index 2152aa79..3dd5ea4a 100644 +--- a/src/lib/plugin_apis/lvm.api ++++ b/src/lib/plugin_apis/lvm.api +@@ -1965,10 +1965,10 @@ BDLVMVDOWritePolicy bd_lvm_get_vdo_write_policy_from_str (const gchar *policy_st + * statistics or %NULL in case of error + * (@error gets populated in those cases) + * +- * Statistics are collected from the values exposed by the kernel `kvdo` module +- * at the `/sys/kvdo//statistics/` path. ++ * Statistics are collected from the values exposed by the kernel `dm-vdo` module. ++ * + * Some of the keys are computed to mimic the information produced by the vdo tools. +- * Please note the contents of the hashtable may vary depending on the actual kvdo module version. ++ * Please note the contents of the hashtable may vary depending on the actual dm-vdo module version. + * + * Tech category: %BD_LVM_TECH_VDO-%BD_LVM_TECH_MODE_QUERY + */ +diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am +index 0195e9e1..71bacb7c 100644 +--- a/src/plugins/Makefile.am ++++ b/src/plugins/Makefile.am +@@ -97,16 +97,16 @@ libbd_loop_la_SOURCES = loop.c loop.h + endif + + if WITH_LVM +-libbd_lvm_la_CFLAGS = $(GLIB_CFLAGS) $(GIO_CFLAGS) $(DEVMAPPER_CFLAGS) -Wall -Wextra -Werror +-libbd_lvm_la_LIBADD = ${builddir}/../utils/libbd_utils.la -lm $(GLIB_LIBS) $(GIO_LIBS) $(DEVMAPPER_LIBS) ++libbd_lvm_la_CFLAGS = $(GLIB_CFLAGS) $(GIO_CFLAGS) $(DEVMAPPER_CFLAGS) $(YAML_CFLAGS) -Wall -Wextra -Werror ++libbd_lvm_la_LIBADD = ${builddir}/../utils/libbd_utils.la -lm $(GLIB_LIBS) $(GIO_LIBS) $(DEVMAPPER_LIBS) $(YAML_LIBS) + libbd_lvm_la_LDFLAGS = -L${srcdir}/../utils/ -version-info 3:0:0 -Wl,--no-undefined -export-symbols-regex '^bd_.*' + libbd_lvm_la_CPPFLAGS = -I${builddir}/../../include/ + libbd_lvm_la_SOURCES = lvm.c lvm.h check_deps.c check_deps.h dm_logging.c dm_logging.h vdo_stats.c vdo_stats.h + endif + + if WITH_LVM_DBUS +-libbd_lvm_dbus_la_CFLAGS = $(GLIB_CFLAGS) $(GIO_CFLAGS) $(DEVMAPPER_CFLAGS) -Wall -Wextra -Werror +-libbd_lvm_dbus_la_LIBADD = ${builddir}/../utils/libbd_utils.la -lm $(GLIB_LIBS) $(GIO_LIBS) $(DEVMAPPER_LIBS) ++libbd_lvm_dbus_la_CFLAGS = $(GLIB_CFLAGS) $(GIO_CFLAGS) $(DEVMAPPER_CFLAGS) $(YAML_CFLAGS) -Wall -Wextra -Werror ++libbd_lvm_dbus_la_LIBADD = ${builddir}/../utils/libbd_utils.la -lm $(GLIB_LIBS) $(GIO_LIBS) $(DEVMAPPER_LIBS) $(YAML_LIBS) + libbd_lvm_dbus_la_LDFLAGS = -L${srcdir}/../utils/ -version-info 3:0:0 -Wl,--no-undefined -export-symbols-regex '^bd_.*' + libbd_lvm_dbus_la_CPPFLAGS = -I${builddir}/../../include/ + libbd_lvm_dbus_la_SOURCES = lvm-dbus.c lvm.h check_deps.c check_deps.h dm_logging.c dm_logging.h vdo_stats.c vdo_stats.h +diff --git a/src/plugins/lvm-dbus.c b/src/plugins/lvm-dbus.c +index 0c017306..92d90718 100644 +--- a/src/plugins/lvm-dbus.c ++++ b/src/plugins/lvm-dbus.c +@@ -4701,10 +4701,10 @@ BDLVMVDOWritePolicy bd_lvm_get_vdo_write_policy_from_str (const gchar *policy_st + * statistics or %NULL in case of error + * (@error gets populated in those cases) + * +- * Statistics are collected from the values exposed by the kernel `kvdo` module +- * at the `/sys/kvdo//statistics/` path. ++ * Statistics are collected from the values exposed by the kernel `dm-vdo` module. ++ * + * Some of the keys are computed to mimic the information produced by the vdo tools. +- * Please note the contents of the hashtable may vary depending on the actual kvdo module version. ++ * Please note the contents of the hashtable may vary depending on the actual dm-vdo module version. + * + * Tech category: %BD_LVM_TECH_VDO-%BD_LVM_TECH_MODE_QUERY + */ +@@ -4736,12 +4736,12 @@ BDLVMVDOStats* bd_lvm_vdo_get_stats (const gchar *vg_name, const gchar *pool_nam + return NULL; + + stats = g_new0 (BDLVMVDOStats, 1); +- get_stat_val64_default (full_stats, "block_size", &stats->block_size, -1); +- get_stat_val64_default (full_stats, "logical_block_size", &stats->logical_block_size, -1); +- get_stat_val64_default (full_stats, "physical_blocks", &stats->physical_blocks, -1); +- get_stat_val64_default (full_stats, "data_blocks_used", &stats->data_blocks_used, -1); +- get_stat_val64_default (full_stats, "overhead_blocks_used", &stats->overhead_blocks_used, -1); +- get_stat_val64_default (full_stats, "logical_blocks_used", &stats->logical_blocks_used, -1); ++ get_stat_val64_default (full_stats, "blockSize", &stats->block_size, -1); ++ get_stat_val64_default (full_stats, "logicalBlockSize", &stats->logical_block_size, -1); ++ get_stat_val64_default (full_stats, "physicalBlocks", &stats->physical_blocks, -1); ++ get_stat_val64_default (full_stats, "dataBlocksUsed", &stats->data_blocks_used, -1); ++ get_stat_val64_default (full_stats, "overheadBlocksUsed", &stats->overhead_blocks_used, -1); ++ get_stat_val64_default (full_stats, "logicalBlocksUsed", &stats->logical_blocks_used, -1); + get_stat_val64_default (full_stats, "usedPercent", &stats->used_percent, -1); + get_stat_val64_default (full_stats, "savingPercent", &stats->saving_percent, -1); + if (!get_stat_val_double (full_stats, "writeAmplificationRatio", &stats->write_amplification_ratio)) +diff --git a/src/plugins/lvm.c b/src/plugins/lvm.c +index dc7491a7..0af9a382 100644 +--- a/src/plugins/lvm.c ++++ b/src/plugins/lvm.c +@@ -3799,10 +3799,10 @@ BDLVMVDOWritePolicy bd_lvm_get_vdo_write_policy_from_str (const gchar *policy_st + * statistics or %NULL in case of error + * (@error gets populated in those cases) + * +- * Statistics are collected from the values exposed by the kernel `kvdo` module +- * at the `/sys/kvdo//statistics/` path. ++ * Statistics are collected from the values exposed by the kernel `dm-vdo` module. ++ * + * Some of the keys are computed to mimic the information produced by the vdo tools. +- * Please note the contents of the hashtable may vary depending on the actual kvdo module version. ++ * Please note the contents of the hashtable may vary depending on the actual dm-vdo module version. + * + * Tech category: %BD_LVM_TECH_VDO-%BD_LVM_TECH_MODE_QUERY + */ +@@ -3834,12 +3834,12 @@ BDLVMVDOStats* bd_lvm_vdo_get_stats (const gchar *vg_name, const gchar *pool_nam + return NULL; + + stats = g_new0 (BDLVMVDOStats, 1); +- get_stat_val64_default (full_stats, "block_size", &stats->block_size, -1); +- get_stat_val64_default (full_stats, "logical_block_size", &stats->logical_block_size, -1); +- get_stat_val64_default (full_stats, "physical_blocks", &stats->physical_blocks, -1); +- get_stat_val64_default (full_stats, "data_blocks_used", &stats->data_blocks_used, -1); +- get_stat_val64_default (full_stats, "overhead_blocks_used", &stats->overhead_blocks_used, -1); +- get_stat_val64_default (full_stats, "logical_blocks_used", &stats->logical_blocks_used, -1); ++ get_stat_val64_default (full_stats, "blockSize", &stats->block_size, -1); ++ get_stat_val64_default (full_stats, "logicalBlockSize", &stats->logical_block_size, -1); ++ get_stat_val64_default (full_stats, "physicalBlocks", &stats->physical_blocks, -1); ++ get_stat_val64_default (full_stats, "dataBlocksUsed", &stats->data_blocks_used, -1); ++ get_stat_val64_default (full_stats, "overheadBlocksUsed", &stats->overhead_blocks_used, -1); ++ get_stat_val64_default (full_stats, "logicalBlocksUsed", &stats->logical_blocks_used, -1); + get_stat_val64_default (full_stats, "usedPercent", &stats->used_percent, -1); + get_stat_val64_default (full_stats, "savingPercent", &stats->saving_percent, -1); + if (!get_stat_val_double (full_stats, "writeAmplificationRatio", &stats->write_amplification_ratio)) +diff --git a/src/plugins/vdo_stats.c b/src/plugins/vdo_stats.c +index 620e972f..ab914821 100644 +--- a/src/plugins/vdo_stats.c ++++ b/src/plugins/vdo_stats.c +@@ -19,10 +19,11 @@ + + #include + #include ++#include ++#include + + #include "vdo_stats.h" +- +-#define VDO_SYS_PATH "/sys/kvdo" ++#include "lvm.h" + + + gboolean __attribute__ ((visibility ("hidden"))) +@@ -67,9 +68,9 @@ get_stat_val_double (GHashTable *stats, const gchar *key, gdouble *val) { + static void add_write_ampl_r_stats (GHashTable *stats) { + gint64 bios_meta_write, bios_out_write, bios_in_write; + +- if (! get_stat_val64 (stats, "bios_meta_write", &bios_meta_write) || +- ! get_stat_val64 (stats, "bios_out_write", &bios_out_write) || +- ! get_stat_val64 (stats, "bios_in_write", &bios_in_write)) ++ if (! get_stat_val64 (stats, "biosMetaWrite", &bios_meta_write) || ++ ! get_stat_val64 (stats, "biosOutWrite", &bios_out_write) || ++ ! get_stat_val64 (stats, "biosInWrite", &bios_in_write)) + return; + + if (bios_in_write <= 0) +@@ -84,11 +85,11 @@ static void add_block_stats (GHashTable *stats) { + gint64 physical_blocks, block_size, data_blocks_used, overhead_blocks_used, logical_blocks_used; + gint64 savings; + +- if (! get_stat_val64 (stats, "physical_blocks", &physical_blocks) || +- ! get_stat_val64 (stats, "block_size", &block_size) || +- ! get_stat_val64 (stats, "data_blocks_used", &data_blocks_used) || +- ! get_stat_val64 (stats, "overhead_blocks_used", &overhead_blocks_used) || +- ! get_stat_val64 (stats, "logical_blocks_used", &logical_blocks_used)) ++ if (! get_stat_val64 (stats, "physicalBlocks", &physical_blocks) || ++ ! get_stat_val64 (stats, "blockSize", &block_size) || ++ ! get_stat_val64 (stats, "dataBlocksUsed", &data_blocks_used) || ++ ! get_stat_val64 (stats, "overheadBlocksUsed", &overhead_blocks_used) || ++ ! get_stat_val64 (stats, "logicalBlocksUsed", &logical_blocks_used)) + return; + + g_hash_table_replace (stats, g_strdup ("oneKBlocks"), g_strdup_printf ("%"G_GINT64_FORMAT, physical_blocks * block_size / 1024)); +@@ -105,24 +106,24 @@ static void add_journal_stats (GHashTable *stats) { + gint64 journal_entries_committed, journal_entries_started, journal_entries_written; + gint64 journal_blocks_committed, journal_blocks_started, journal_blocks_written; + +- if (! get_stat_val64 (stats, "journal_entries_committed", &journal_entries_committed) || +- ! get_stat_val64 (stats, "journal_entries_started", &journal_entries_started) || +- ! get_stat_val64 (stats, "journal_entries_written", &journal_entries_written) || +- ! get_stat_val64 (stats, "journal_blocks_committed", &journal_blocks_committed) || +- ! get_stat_val64 (stats, "journal_blocks_started", &journal_blocks_started) || +- ! get_stat_val64 (stats, "journal_blocks_written", &journal_blocks_written)) ++ if (! get_stat_val64 (stats, "journalEntriesCommitted", &journal_entries_committed) || ++ ! get_stat_val64 (stats, "journalEntriesStarted", &journal_entries_started) || ++ ! get_stat_val64 (stats, "journalEntriesWritten", &journal_entries_written) || ++ ! get_stat_val64 (stats, "journalBlocksCommitted", &journal_blocks_committed) || ++ ! get_stat_val64 (stats, "journalBlocksStarted", &journal_blocks_started) || ++ ! get_stat_val64 (stats, "journalBlocksWritten", &journal_blocks_written)) + return; + +- g_hash_table_replace (stats, g_strdup ("journal_entries_batching"), g_strdup_printf ("%"G_GINT64_FORMAT, journal_entries_started - journal_entries_written)); +- g_hash_table_replace (stats, g_strdup ("journal_entries_writing"), g_strdup_printf ("%"G_GINT64_FORMAT, journal_entries_written - journal_entries_committed)); +- g_hash_table_replace (stats, g_strdup ("journal_blocks_batching"), g_strdup_printf ("%"G_GINT64_FORMAT, journal_blocks_started - journal_blocks_written)); +- g_hash_table_replace (stats, g_strdup ("journal_blocks_writing"), g_strdup_printf ("%"G_GINT64_FORMAT, journal_blocks_written - journal_blocks_committed)); ++ g_hash_table_replace (stats, g_strdup ("journalEntriesBatching"), g_strdup_printf ("%"G_GINT64_FORMAT, journal_entries_started - journal_entries_written)); ++ g_hash_table_replace (stats, g_strdup ("journalEntriesWriting"), g_strdup_printf ("%"G_GINT64_FORMAT, journal_entries_written - journal_entries_committed)); ++ g_hash_table_replace (stats, g_strdup ("journalBlocksBatching"), g_strdup_printf ("%"G_GINT64_FORMAT, journal_blocks_started - journal_blocks_written)); ++ g_hash_table_replace (stats, g_strdup ("journalBlocksWriting"), g_strdup_printf ("%"G_GINT64_FORMAT, journal_blocks_written - journal_blocks_committed)); + } + + static void add_computed_stats (GHashTable *stats) { + const gchar *s; + +- s = g_hash_table_lookup (stats, "logical_block_size"); ++ s = g_hash_table_lookup (stats, "logicalBlockSize"); + g_hash_table_replace (stats, + g_strdup ("fiveTwelveByteEmulation"), + g_strdup ((g_strcmp0 (s, "512") == 0) ? "true" : "false")); +@@ -132,76 +133,128 @@ static void add_computed_stats (GHashTable *stats) { + add_journal_stats (stats); + } + +-static gchar* _dm_node_from_name (const gchar *map_name, GError **error) { +- gchar *dev_path = NULL; +- gchar *ret = NULL; +- gchar *dev_mapper_path = g_strdup_printf ("/dev/mapper/%s", map_name); ++enum parse_flags { ++ PARSE_NEXT_KEY, ++ PARSE_NEXT_VAL, ++ PARSE_NEXT_IGN, ++}; + +- dev_path = bd_utils_resolve_device (dev_mapper_path, error); +- g_free (dev_mapper_path); +- if (!dev_path) +- /* error is already populated */ ++GHashTable __attribute__ ((visibility ("hidden"))) ++*vdo_get_stats_full (const gchar *name, GError **error) { ++ struct dm_task *dmt = NULL; ++ const gchar *response = NULL; ++ yaml_parser_t parser; ++ yaml_token_t token; ++ GHashTable *stats = NULL; ++ gchar *key = NULL; ++ gsize len = 0; ++ int next_token = PARSE_NEXT_IGN; ++ gchar *prefix = NULL; ++ ++ dmt = dm_task_create (DM_DEVICE_TARGET_MSG); ++ if (!dmt) { ++ g_set_error (error, BD_LVM_ERROR, BD_LVM_ERROR_DM_ERROR, ++ "Failed to create DM task"); + return NULL; ++ } + +- ret = g_path_get_basename (dev_path); +- g_free (dev_path); ++ if (!dm_task_set_name (dmt, name)) { ++ g_set_error (error, BD_LVM_ERROR, BD_LVM_ERROR_DM_ERROR, ++ "Failed to set name for DM task"); ++ dm_task_destroy (dmt); ++ return NULL; ++ } + +- return ret; +-} ++ if (!dm_task_set_message (dmt, "stats")) { ++ g_set_error (error, BD_LVM_ERROR, BD_LVM_ERROR_DM_ERROR, ++ "Failed to set message for DM task"); ++ dm_task_destroy (dmt); ++ return NULL; ++ } + +-GHashTable __attribute__ ((visibility ("hidden"))) +-*vdo_get_stats_full (const gchar *name, GError **error) { +- GHashTable *stats; +- GDir *dir; +- gchar *stats_dir; +- const gchar *direntry; +- gchar *s; +- gchar *val = NULL; +- g_autofree gchar *dm_node = NULL; +- GError *l_error = NULL; +- +- /* try "new" (kvdo >= 8) path first -- /sys/block/dm-X/vdo/statistics */ +- dm_node = _dm_node_from_name (name, error); +- if (dm_node == NULL) { +- g_prefix_error (error, "Failed to get DM node for %s: ", name); ++ if (!dm_task_run (dmt)) { ++ g_set_error (error, BD_LVM_ERROR, BD_LVM_ERROR_DM_ERROR, ++ "Failed to run DM task"); ++ dm_task_destroy (dmt); ++ return NULL; ++ } ++ ++ response = dm_task_get_message_response (dmt); ++ if (!response) { ++ g_set_error (error, BD_LVM_ERROR, BD_LVM_ERROR_DM_ERROR, ++ "Failed to get response from the DM task"); ++ dm_task_destroy (dmt); + return NULL; + } + +- stats_dir = g_build_path (G_DIR_SEPARATOR_S, "/sys/block", dm_node, "vdo/statistics", NULL); +- dir = g_dir_open (stats_dir, 0, &l_error); +- if (dir == NULL) { +- bd_utils_log_format (BD_UTILS_LOG_INFO, +- "Failed to read VDO stats using the new API, falling back to %s: %s", +- VDO_SYS_PATH, l_error->message); +- g_free (stats_dir); +- g_clear_error (&l_error); +- +- /* lets try /sys/kvdo */ +- stats_dir = g_build_path (G_DIR_SEPARATOR_S, VDO_SYS_PATH, name, "statistics", NULL); +- dir = g_dir_open (stats_dir, 0, error); +- if (dir == NULL) { +- g_prefix_error (error, "Error reading statistics from %s: ", stats_dir); +- g_free (stats_dir); +- return NULL; +- } ++ if (!yaml_parser_initialize (&parser)) { ++ g_set_error (error, BD_LVM_ERROR, BD_LVM_ERROR_DM_ERROR, ++ "Failed to get initialize YAML parser"); ++ dm_task_destroy (dmt); ++ return NULL; + } + + stats = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); +- while ((direntry = g_dir_read_name (dir))) { +- s = g_build_filename (stats_dir, direntry, NULL); +- if (! g_file_get_contents (s, &val, NULL, error)) { +- g_prefix_error (error, "Error reading statistics from %s: ", s); +- g_free (s); +- g_hash_table_destroy (stats); +- stats = NULL; +- break; +- } +- g_hash_table_replace (stats, g_strdup (direntry), g_strdup (g_strstrip (val))); +- g_free (val); +- g_free (s); +- } +- g_dir_close (dir); +- g_free (stats_dir); ++ yaml_parser_set_input_string (&parser, (guchar *) response, strlen (response)); ++ ++ do { ++ yaml_parser_scan (&parser, &token); ++ switch (token.type) { ++ /* key */ ++ case YAML_KEY_TOKEN: ++ next_token = PARSE_NEXT_KEY; ++ break; ++ /* value */ ++ case YAML_VALUE_TOKEN: ++ next_token = PARSE_NEXT_VAL; ++ break; ++ /* block mapping */ ++ case YAML_BLOCK_MAPPING_START_TOKEN: ++ if (next_token == PARSE_NEXT_VAL) ++ /* we were expecting to read a key-value pair but this is actually ++ a block start, so we need to free the key we're not going to use */ ++ g_free (key); ++ break; ++ /* mapping */ ++ case YAML_FLOW_MAPPING_START_TOKEN: ++ /* start of flow mapping -> previously read key will be used as prefix ++ for all keys in the mapping: ++ previous key: biosInProgress ++ keys in the mapping: Read, Write... ++ with prefix: biosInProgressRead, biosInProgressWrite... ++ */ ++ prefix = key; ++ break; ++ case YAML_FLOW_MAPPING_END_TOKEN: ++ /* end of flow mapping, discard the prefix used */ ++ g_free (prefix); ++ prefix = NULL; ++ break; ++ /* actual data */ ++ case YAML_SCALAR_TOKEN: ++ if (next_token == PARSE_NEXT_KEY) { ++ if (prefix) { ++ key = g_strdup_printf ("%s%s", prefix, (const gchar *) token.data.scalar.value); ++ len = strlen (prefix); ++ /* make sure the key with the prefix is still camelCase */ ++ key[len] = g_ascii_toupper (key[len]); ++ } else ++ key = g_strdup ((const gchar *) token.data.scalar.value); ++ } else if (next_token == PARSE_NEXT_VAL) { ++ gchar *val = g_strdup ((const gchar *) token.data.scalar.value); ++ g_hash_table_insert (stats, key, val); ++ } ++ break; ++ default: ++ break; ++ } ++ ++ if (token.type != YAML_STREAM_END_TOKEN) ++ yaml_token_delete (&token); ++ } while (token.type != YAML_STREAM_END_TOKEN); ++ ++ yaml_parser_delete (&parser); ++ dm_task_destroy (dmt); + + if (stats != NULL) + add_computed_stats (stats); +diff --git a/tests/lvm_dbus_tests.py b/tests/lvm_dbus_tests.py +index 9f302611..db0d5c90 100644 +--- a/tests/lvm_dbus_tests.py ++++ b/tests/lvm_dbus_tests.py +@@ -2090,7 +2090,9 @@ class LVMVDOTest(LVMTestCase): + pool_info = BlockDev.lvm_lvinfo("testVDOVG", "vdoPool") + self.assertEqual(pool_info.segtype, "vdo-pool") + self.assertEqual(pool_info.data_lv, "vdoPool_vdata") +- self.assertGreater(pool_info.data_percent, 0) ++ lvm_version = self._get_lvm_version() ++ if lvm_version >= Version("2.03.24"): ++ self.assertGreater(pool_info.data_percent, 0) + + pool = BlockDev.lvm_vdolvpoolname("testVDOVG", "vdoLV") + self.assertEqual(pool, lv_info.pool_lv) +diff --git a/tests/lvm_test.py b/tests/lvm_test.py +index b1d65baf..96aa352a 100644 +--- a/tests/lvm_test.py ++++ b/tests/lvm_test.py +@@ -1994,7 +1994,9 @@ class LVMVDOTest(LVMTestCase): + pool_info = BlockDev.lvm_lvinfo("testVDOVG", "vdoPool") + self.assertEqual(pool_info.segtype, "vdo-pool") + self.assertEqual(pool_info.data_lv, "vdoPool_vdata") +- self.assertGreater(pool_info.data_percent, 0) ++ lvm_version = self._get_lvm_version() ++ if lvm_version >= Version("2.03.24"): ++ self.assertGreater(pool_info.data_percent, 0) + + pool = BlockDev.lvm_vdolvpoolname("testVDOVG", "vdoLV") + self.assertEqual(pool, lv_info.pool_lv) +@@ -2155,7 +2157,11 @@ class LVMVDOTest(LVMTestCase): + self.assertTrue(vdo_info.deduplication) + + vdo_stats = BlockDev.lvm_vdo_get_stats("testVDOVG", "vdoPool") +- self.assertEqual(vdo_info.saving_percent, vdo_stats.saving_percent) ++ ++ lvm_version = self._get_lvm_version() ++ if lvm_version >= Version("2.03.24"): ++ # saving_percent is incorrect with LVM < 2.03.24 ++ self.assertEqual(vdo_info.saving_percent, vdo_stats.saving_percent) + + # just sanity check + self.assertNotEqual(vdo_stats.used_percent, -1) +-- +2.45.2 + diff --git a/0005-libext2fs-unused-parameters-fix.patch b/0005-libext2fs-unused-parameters-fix.patch new file mode 100644 index 0000000..cfeb97c --- /dev/null +++ b/0005-libext2fs-unused-parameters-fix.patch @@ -0,0 +1,86 @@ +From e1c3c3e3555963104a8de00b510b69375eee5ced Mon Sep 17 00:00:00 2001 +From: Vojtech Trefny +Date: Fri, 7 Jun 2024 10:06:22 +0200 +Subject: [PATCH 1/3] fs: Ignore unused-parameter warning in the FS plugin + +There are some unused parameters in the libext2fs header which +together with Wall and Werror means the plugin compilation fails. +As a workaround we'll disable the unused-parameter warning for +now. + +Fixes: #1026 +--- + src/plugins/fs/Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/plugins/fs/Makefile.am b/src/plugins/fs/Makefile.am +index 7d4849c0..00474d5a 100644 +--- a/src/plugins/fs/Makefile.am ++++ b/src/plugins/fs/Makefile.am +@@ -2,7 +2,7 @@ AUTOMAKE_OPTIONS = subdir-objects + + lib_LTLIBRARIES = libbd_fs.la + +-libbd_fs_la_CFLAGS = $(GLIB_CFLAGS) $(GIO_CFLAGS) $(BLKID_CFLAGS) $(MOUNT_CFLAGS) $(UUID_CFLAGS) $(EXT2FS_CFLAGS) -Wall -Wextra -Werror ++libbd_fs_la_CFLAGS = $(GLIB_CFLAGS) $(GIO_CFLAGS) $(BLKID_CFLAGS) $(MOUNT_CFLAGS) $(UUID_CFLAGS) $(EXT2FS_CFLAGS) -Wall -Wextra -Werror -Wno-unused-parameter + libbd_fs_la_LIBADD = ${builddir}/../../utils/libbd_utils.la $(GLIB_LIBS) $(GIO_LIBS) $(BLKID_LIBS) $(MOUNT_LIBS) $(UUID_LIBS) $(EXT2FS_LIBS) + libbd_fs_la_LDFLAGS = -L${srcdir}/../../utils/ -version-info 3:0:0 -Wl,--no-undefined -export-symbols-regex '^bd_.*' + libbd_fs_la_CPPFLAGS = -I${builddir}/../../../include/ -I${srcdir}/../ +-- +2.45.2 + + +From 30e7d0bd7b78b5d9a2ddd031d0cdf9f45187a717 Mon Sep 17 00:00:00 2001 +From: Vojtech Trefny +Date: Fri, 7 Jun 2024 15:21:09 +0200 +Subject: [PATCH 2/3] fs: Ignore shift-count-overflow warning in FS plugin + +The warning happens in the libext2fs header. +--- + src/plugins/fs/Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/plugins/fs/Makefile.am b/src/plugins/fs/Makefile.am +index 00474d5a..42e1c777 100644 +--- a/src/plugins/fs/Makefile.am ++++ b/src/plugins/fs/Makefile.am +@@ -2,7 +2,7 @@ AUTOMAKE_OPTIONS = subdir-objects + + lib_LTLIBRARIES = libbd_fs.la + +-libbd_fs_la_CFLAGS = $(GLIB_CFLAGS) $(GIO_CFLAGS) $(BLKID_CFLAGS) $(MOUNT_CFLAGS) $(UUID_CFLAGS) $(EXT2FS_CFLAGS) -Wall -Wextra -Werror -Wno-unused-parameter ++libbd_fs_la_CFLAGS = $(GLIB_CFLAGS) $(GIO_CFLAGS) $(BLKID_CFLAGS) $(MOUNT_CFLAGS) $(UUID_CFLAGS) $(EXT2FS_CFLAGS) -Wall -Wextra -Werror -Wno-unused-parameter -Wno-shift-count-overflow + libbd_fs_la_LIBADD = ${builddir}/../../utils/libbd_utils.la $(GLIB_LIBS) $(GIO_LIBS) $(BLKID_LIBS) $(MOUNT_LIBS) $(UUID_LIBS) $(EXT2FS_LIBS) + libbd_fs_la_LDFLAGS = -L${srcdir}/../../utils/ -version-info 3:0:0 -Wl,--no-undefined -export-symbols-regex '^bd_.*' + libbd_fs_la_CPPFLAGS = -I${builddir}/../../../include/ -I${srcdir}/../ +-- +2.45.2 + + +From b40ce052f98c9afb3e5bd0f91e7eb8bf6cbacd90 Mon Sep 17 00:00:00 2001 +From: Vojtech Trefny +Date: Wed, 12 Jun 2024 15:34:02 +0200 +Subject: [PATCH 3/3] fs: Fix ignoring errors from libext2fs + +Follow-up for #1028, we still want to show the warning and not +completely supress it. +--- + src/plugins/fs/Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/plugins/fs/Makefile.am b/src/plugins/fs/Makefile.am +index 42e1c777..1ee256f0 100644 +--- a/src/plugins/fs/Makefile.am ++++ b/src/plugins/fs/Makefile.am +@@ -2,7 +2,7 @@ AUTOMAKE_OPTIONS = subdir-objects + + lib_LTLIBRARIES = libbd_fs.la + +-libbd_fs_la_CFLAGS = $(GLIB_CFLAGS) $(GIO_CFLAGS) $(BLKID_CFLAGS) $(MOUNT_CFLAGS) $(UUID_CFLAGS) $(EXT2FS_CFLAGS) -Wall -Wextra -Werror -Wno-unused-parameter -Wno-shift-count-overflow ++libbd_fs_la_CFLAGS = $(GLIB_CFLAGS) $(GIO_CFLAGS) $(BLKID_CFLAGS) $(MOUNT_CFLAGS) $(UUID_CFLAGS) $(EXT2FS_CFLAGS) -Wall -Wextra -Werror -Wno-error=unused-parameter -Wno-error=shift-count-overflow + libbd_fs_la_LIBADD = ${builddir}/../../utils/libbd_utils.la $(GLIB_LIBS) $(GIO_LIBS) $(BLKID_LIBS) $(MOUNT_LIBS) $(UUID_LIBS) $(EXT2FS_LIBS) + libbd_fs_la_LDFLAGS = -L${srcdir}/../../utils/ -version-info 3:0:0 -Wl,--no-undefined -export-symbols-regex '^bd_.*' + libbd_fs_la_CPPFLAGS = -I${builddir}/../../../include/ -I${srcdir}/../ +-- +2.45.2 + diff --git a/libblockdev.spec b/libblockdev.spec index 20dff4b..d114a7c 100644 --- a/libblockdev.spec +++ b/libblockdev.spec @@ -78,7 +78,7 @@ Name: libblockdev Version: 3.1.0 -Release: 5%{?dist} +Release: 6%{?dist} Summary: A library for low-level manipulation with block devices License: LGPL-2.1-or-later URL: https://github.com/storaged-project/libblockdev @@ -86,6 +86,9 @@ Source0: https://github.com/storaged-project/libblockdev/releases/download/% Patch0: 0001-misc-RHEL-10-beta-backport.patch Patch1: 0002-Check-also-for-aliases-in-bd_utils_have_kernel_module.patch +Patch2: 0003-Fix-passing-size-for-pvresize-over-DBus.patch +Patch3: 0004-Upstream-kernel-VDO-support.patch +Patch4: 0005-libext2fs-unused-parameters-fix.patch BuildRequires: make BuildRequires: glib2-devel @@ -293,6 +296,7 @@ with the libblockdev-loop plugin/library. %if %{with_lvm} %package lvm BuildRequires: device-mapper-devel +BuildRequires: libyaml-devel Summary: The LVM plugin for the libblockdev library Requires: %{name}-utils%{?_isa} = %{version}-%{release} Requires: lvm2 @@ -315,6 +319,7 @@ with the libblockdev-lvm plugin/library. %if %{with_lvm_dbus} %package lvm-dbus BuildRequires: device-mapper-devel +BuildRequires: libyaml-devel Summary: The LVM plugin for the libblockdev library Requires: %{name}-utils%{?_isa} = %{version}-%{release} Requires: lvm2-dbusd >= 2.02.156 @@ -854,6 +859,12 @@ find %{buildroot} -type f -name "*.la" | xargs %{__rm} %files plugins-all %changelog +* Fri Jul 19 2024 Vojtech Trefny - 3.1.0-6 +- Fix passing size for pvresize over DBus + Resolves: RHEL-45872 +- Upstream kernel VDO support + Resolves: RHEL-31953 + * Mon Jun 24 2024 Troy Dawson - 3.1.0-5 - Bump release for June 2024 mass rebuild diff --git a/tests/tests.yml b/tests/tests.yml index d938ac9..eadbcb8 100644 --- a/tests/tests.yml +++ b/tests/tests.yml @@ -33,5 +33,6 @@ - python3-packaging - python3-yaml - targetcli + - vdo - volume_key - xfsprogs