import UBI lvm2-2.03.14-15.el8_10.2
This commit is contained in:
parent
48dfb805f0
commit
ea6214f636
196
SOURCES/0140-mirror-enhance-error-path-for-pvmove-finish.patch
Normal file
196
SOURCES/0140-mirror-enhance-error-path-for-pvmove-finish.patch
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
From ae515916c05218a49b40afaaf26f9c4c0bb55e53 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||||
|
Date: Sat, 8 Feb 2025 21:51:09 +0100
|
||||||
|
Subject: [PATCH] mirror: enhance error path for pvmove finish
|
||||||
|
|
||||||
|
When the pvmove operation is completing, it attempts to deactivate
|
||||||
|
the temporary mirror and remove its mirror legs. However,
|
||||||
|
if an external tool holds these volumes open, the operation would
|
||||||
|
previously abort entirely, leaving the LVM2 metadata in a partially
|
||||||
|
unusable state that required manual administrative fixes.
|
||||||
|
|
||||||
|
To improve this, the code has been enhanced to handle such scenarios
|
||||||
|
more gracefully. It will now complete the pvmove operation even
|
||||||
|
if some volumes cannot be deactivated, marking them in the metadata
|
||||||
|
with an error segment. While the command will report errors,
|
||||||
|
the metadata will remain in a usable state. The administrator
|
||||||
|
can then remove the orphaned volumes when they are no longer in use.
|
||||||
|
|
||||||
|
(cherry picked from commit ed9468153ec3d9cec8d6fbb9f6b8e09e10427416)
|
||||||
|
---
|
||||||
|
lib/metadata/mirror.c | 93 ++++++++++++++++++++++++++++++++++++++++---
|
||||||
|
tools/pvmove_poll.c | 13 ++++++
|
||||||
|
2 files changed, 101 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/metadata/mirror.c b/lib/metadata/mirror.c
|
||||||
|
index 46da57948..d5c988372 100644
|
||||||
|
--- a/lib/metadata/mirror.c
|
||||||
|
+++ b/lib/metadata/mirror.c
|
||||||
|
@@ -398,6 +398,59 @@ static int _activate_lv_like_model(struct logical_volume *model,
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * Inherit tags @from_lv to @to_lv, tags maybe needed for activation
|
||||||
|
+ */
|
||||||
|
+static int _inherit_lv_tags(const struct logical_volume *from_lv, struct logical_volume *to_lv)
|
||||||
|
+{
|
||||||
|
+ struct dm_str_list *sl;
|
||||||
|
+
|
||||||
|
+ if (to_lv && !str_list_match_list(&from_lv->tags, &to_lv->tags, NULL))
|
||||||
|
+ dm_list_iterate_items(sl, &from_lv->tags)
|
||||||
|
+ if (!str_list_add(from_lv->vg->cmd->mem, &to_lv->tags, sl->str)) {
|
||||||
|
+ log_error("Aborting. Unable to inherit tag.");
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Deactivates and removes an 'orphan' temporary @lv,
|
||||||
|
+ * which is expected to already have an 'error' segment.
|
||||||
|
+ * Sets @updated_mda (!NULL) to 1 when LV is removed.
|
||||||
|
+ * Sets @deactivation_failed (!NULL) to 1 when deactivation fails.
|
||||||
|
+ *
|
||||||
|
+ * Note: An external tool might still have the volume open, preventing
|
||||||
|
+ * immediate deactivation. If deactivation fails (even after retrying),
|
||||||
|
+ * it is safer to proceed with the command and leave the LV visible.
|
||||||
|
+ * This allows the user to manually remove it when it is no longer in use.
|
||||||
|
+ *
|
||||||
|
+ * Any errors will be detected later in the process, as there will be
|
||||||
|
+ * more visible LVs than expected.
|
||||||
|
+ */
|
||||||
|
+static int _deactivate_and_remove_lv(struct logical_volume *lv,
|
||||||
|
+ int *updated_mda,
|
||||||
|
+ int *deactivation_failed)
|
||||||
|
+{
|
||||||
|
+ if (lv) {
|
||||||
|
+ /* FIXME: convert to use lv_active_change() */
|
||||||
|
+ if (!deactivate_lv(lv->vg->cmd, lv)) {
|
||||||
|
+ /* Note: still returns success here and fails later */
|
||||||
|
+ log_warn("WARNING: Can't deactivate temporary volume %s.",
|
||||||
|
+ display_lvname(lv));
|
||||||
|
+ if (deactivation_failed)
|
||||||
|
+ *deactivation_failed = 1;
|
||||||
|
+ } else if (!lv_remove(lv)) {
|
||||||
|
+ /* Can't continue with internal metadata problems */
|
||||||
|
+ return_0;
|
||||||
|
+ } else if (updated_mda)
|
||||||
|
+ *updated_mda = 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Delete independent/orphan LV, it must acquire lock.
|
||||||
|
*/
|
||||||
|
@@ -803,7 +856,6 @@ static int _remove_mirror_images(struct logical_volume *lv,
|
||||||
|
struct lv_list *lvl;
|
||||||
|
struct dm_list tmp_orphan_lvs;
|
||||||
|
uint32_t orig_removed = num_removed;
|
||||||
|
- int reactivate;
|
||||||
|
|
||||||
|
if (removed)
|
||||||
|
*removed = 0;
|
||||||
|
@@ -967,6 +1019,19 @@ static int _remove_mirror_images(struct logical_volume *lv,
|
||||||
|
return_0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (!collapse) {
|
||||||
|
+ dm_list_iterate_items(lvl, &tmp_orphan_lvs) {
|
||||||
|
+ if (!_inherit_lv_tags(lv, lvl->lv))
|
||||||
|
+ return_0;
|
||||||
|
+ if (!replace_lv_with_error_segment(lvl->lv))
|
||||||
|
+ return_0;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!_inherit_lv_tags(lv, temp_layer_lv) ||
|
||||||
|
+ !_inherit_lv_tags(lv, detached_log_lv))
|
||||||
|
+ return_0;
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* To successfully remove these unwanted LVs we need to
|
||||||
|
* remove the LVs from the mirror set, commit that metadata
|
||||||
|
@@ -976,17 +1041,35 @@ static int _remove_mirror_images(struct logical_volume *lv,
|
||||||
|
return_0;
|
||||||
|
|
||||||
|
/* Save or delete the 'orphan' LVs */
|
||||||
|
- reactivate = lv_is_active(lv_lock_holder(lv));
|
||||||
|
+ if (lv_is_active(lv_lock_holder(lv))) {
|
||||||
|
+ if (!collapse) {
|
||||||
|
+ dm_list_iterate_items(lvl, &tmp_orphan_lvs)
|
||||||
|
+ if (!_activate_lv_like_model(lv, lvl->lv))
|
||||||
|
+ return_0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (temp_layer_lv &&
|
||||||
|
+ !_activate_lv_like_model(lv, temp_layer_lv))
|
||||||
|
+ return_0;
|
||||||
|
+
|
||||||
|
+ if (detached_log_lv &&
|
||||||
|
+ !_activate_lv_like_model(lv, detached_log_lv))
|
||||||
|
+ return_0;
|
||||||
|
+
|
||||||
|
+ if (!sync_local_dev_names(lv->vg->cmd))
|
||||||
|
+ stack;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (!collapse) {
|
||||||
|
dm_list_iterate_items(lvl, &tmp_orphan_lvs)
|
||||||
|
- if (!_delete_lv(lv, lvl->lv, reactivate))
|
||||||
|
+ if (!_deactivate_and_remove_lv(lvl->lv, NULL, NULL))
|
||||||
|
return_0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (temp_layer_lv && !_delete_lv(lv, temp_layer_lv, reactivate))
|
||||||
|
+ if (!_deactivate_and_remove_lv(temp_layer_lv, NULL, NULL))
|
||||||
|
return_0;
|
||||||
|
|
||||||
|
- if (detached_log_lv && !_delete_lv(lv, detached_log_lv, reactivate))
|
||||||
|
+ if (!_deactivate_and_remove_lv(detached_log_lv, NULL, NULL))
|
||||||
|
return_0;
|
||||||
|
|
||||||
|
/* Mirror with only 1 area is 'in sync'. */
|
||||||
|
diff --git a/tools/pvmove_poll.c b/tools/pvmove_poll.c
|
||||||
|
index 751313cd7..8b97905c0 100644
|
||||||
|
--- a/tools/pvmove_poll.c
|
||||||
|
+++ b/tools/pvmove_poll.c
|
||||||
|
@@ -87,6 +87,8 @@ int pvmove_update_metadata(struct cmd_context *cmd, struct volume_group *vg,
|
||||||
|
int pvmove_finish(struct cmd_context *cmd, struct volume_group *vg,
|
||||||
|
struct logical_volume *lv_mirr, struct dm_list *lvs_changed)
|
||||||
|
{
|
||||||
|
+ uint32_t visible = vg_visible_lvs(lv_mirr->vg);
|
||||||
|
+
|
||||||
|
if (!dm_list_empty(lvs_changed) &&
|
||||||
|
(!_detach_pvmove_mirror(cmd, lv_mirr) ||
|
||||||
|
!replace_lv_with_error_segment(lv_mirr))) {
|
||||||
|
@@ -94,6 +96,8 @@ int pvmove_finish(struct cmd_context *cmd, struct volume_group *vg,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ lv_set_visible(lv_mirr);
|
||||||
|
+
|
||||||
|
if (!lv_update_and_reload(lv_mirr))
|
||||||
|
return_0;
|
||||||
|
|
||||||
|
@@ -120,5 +124,14 @@ int pvmove_finish(struct cmd_context *cmd, struct volume_group *vg,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /* Allows the pvmove operation to complete even if 'orphaned' temporary volumes
|
||||||
|
+ * cannot be deactivated due to being held open by another process.
|
||||||
|
+ * The user can manually remove these volumes later when they are no longer in use. */
|
||||||
|
+ if (visible < vg_visible_lvs(lv_mirr->vg)) {
|
||||||
|
+ log_error("ABORTING: Failed to remove temporary logical volume(s).");
|
||||||
|
+ log_print_unless_silent("Please remove orphan temporary logical volume(s) when possible.");
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.48.1
|
||||||
|
|
@ -0,0 +1,42 @@
|
|||||||
|
From 97aa5f67547f150b5f8f511249b200a41561a3c9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Teigland <teigland@redhat.com>
|
||||||
|
Date: Thu, 27 Jun 2024 12:46:15 -0500
|
||||||
|
Subject: [PATCH 1/2] lvmlockd: vgchange systemid doen't need global lock
|
||||||
|
|
||||||
|
The comment explained that the ex global lock was just
|
||||||
|
used to trigger global cache invalidation, which is no
|
||||||
|
longer needed. This extra locking can cause problems
|
||||||
|
with LVM-activate when local and shared VGs are mixed
|
||||||
|
(and the incorrect exit code for errors was causing
|
||||||
|
problems.)
|
||||||
|
|
||||||
|
(cherry picked from commit 680f7bd676526771b7a26e35105af3bccb95e4a1)
|
||||||
|
---
|
||||||
|
tools/vgchange.c | 11 -----------
|
||||||
|
1 file changed, 11 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/tools/vgchange.c b/tools/vgchange.c
|
||||||
|
index e4b57dbd2..b0e2b2d2a 100644
|
||||||
|
--- a/tools/vgchange.c
|
||||||
|
+++ b/tools/vgchange.c
|
||||||
|
@@ -1231,17 +1231,6 @@ int vgchange_systemid_cmd(struct cmd_context *cmd, int argc, char **argv)
|
||||||
|
struct processing_handle *handle;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
- /*
|
||||||
|
- * This is a special case where taking the global lock is
|
||||||
|
- * not needed to protect global state, because the change is
|
||||||
|
- * only to an existing VG. But, taking the global lock ex is
|
||||||
|
- * helpful in this case to trigger a global cache validation
|
||||||
|
- * on other hosts, to cause them to see the new system_id or
|
||||||
|
- * lock_type.
|
||||||
|
- */
|
||||||
|
- if (!lockd_global(cmd, "ex"))
|
||||||
|
- return 0;
|
||||||
|
-
|
||||||
|
if (!(handle = init_processing_handle(cmd, NULL))) {
|
||||||
|
log_error("Failed to initialize processing handle.");
|
||||||
|
return ECMD_FAILED;
|
||||||
|
--
|
||||||
|
2.49.0
|
||||||
|
|
@ -55,7 +55,7 @@
|
|||||||
%global commit 4dc5d4ac7e7a9457ccc46ff04796b347e58bf4da
|
%global commit 4dc5d4ac7e7a9457ccc46ff04796b347e58bf4da
|
||||||
%global shortcommit %(c=%{commit}; echo ${c:0:7})
|
%global shortcommit %(c=%{commit}; echo ${c:0:7})
|
||||||
%endif
|
%endif
|
||||||
#%%global rel_suffix .bz2233901_1
|
%global rel_suffix .2
|
||||||
|
|
||||||
# Do not reset Release to 1 unless both lvm2 and device-mapper
|
# Do not reset Release to 1 unless both lvm2 and device-mapper
|
||||||
# versions are increased together.
|
# versions are increased together.
|
||||||
@ -237,6 +237,10 @@ Patch137: 0136-configure-autoreconf.patch
|
|||||||
Patch138: 0137-dmeventd-implement-exit_on-file-check.patch
|
Patch138: 0137-dmeventd-implement-exit_on-file-check.patch
|
||||||
Patch139: 0138-debug-correct-level.patch
|
Patch139: 0138-debug-correct-level.patch
|
||||||
Patch140: 0139-tests-check-exit_on-works.patch
|
Patch140: 0139-tests-check-exit_on-works.patch
|
||||||
|
# RHEL-62764:
|
||||||
|
Patch141: 0140-mirror-enhance-error-path-for-pvmove-finish.patch
|
||||||
|
# RHEL-66486:
|
||||||
|
Patch142: 0141-lvmlockd-vgchange-systemid-doen-t-need-global-lock.patch
|
||||||
|
|
||||||
BuildRequires: gcc
|
BuildRequires: gcc
|
||||||
%if %{enable_testsuite}
|
%if %{enable_testsuite}
|
||||||
@ -902,7 +906,7 @@ the device-mapper event library.
|
|||||||
%package testsuite
|
%package testsuite
|
||||||
Summary: LVM2 Testsuite
|
Summary: LVM2 Testsuite
|
||||||
# Most of the code is GPLv2, the harness in test/lib/{brick-shelltest.h,runner.cpp} is BSD, and C files in test/api are LGPLv2...
|
# Most of the code is GPLv2, the harness in test/lib/{brick-shelltest.h,runner.cpp} is BSD, and C files in test/api are LGPLv2...
|
||||||
License: LGPLv2 and GPLv2 and BSD-2-Clause
|
License: GPL-2.0-only AND LGPL-2.1-only AND BSD-2-Clause
|
||||||
|
|
||||||
%description testsuite
|
%description testsuite
|
||||||
An extensive functional testsuite for LVM2.
|
An extensive functional testsuite for LVM2.
|
||||||
@ -915,6 +919,12 @@ An extensive functional testsuite for LVM2.
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Mon Jun 02 2025 Marian Csontos <mcsontos@redhat.com> - 2.03.14-15.el8_10.2
|
||||||
|
- Fix vgchange exit code when lvmlockd is not running and no change is done.
|
||||||
|
|
||||||
|
* Wed Apr 30 2025 Marian Csontos <mcsontos@redhat.com> - 2.03.14-15.el8_10.1
|
||||||
|
- Fix incomplete pvmove write bad metadata requiring manual intervention.
|
||||||
|
|
||||||
* Wed Jan 22 2025 Marian Csontos <mcsontos@redhat.com> - 2.03.14-15
|
* Wed Jan 22 2025 Marian Csontos <mcsontos@redhat.com> - 2.03.14-15
|
||||||
- Fix dmeventd blocking on shutdown.
|
- Fix dmeventd blocking on shutdown.
|
||||||
- Force exit dmeventd when /run/nologin is present.
|
- Force exit dmeventd when /run/nologin is present.
|
||||||
|
Loading…
Reference in New Issue
Block a user