import CS lvm2-2.03.33-4.el9
This commit is contained in:
parent
14d381d8bb
commit
b5e43fdc08
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1 @@
|
||||
SOURCES/LVM2.2.03.32.tgz
|
||||
SOURCES/LVM2.2.03.33.tgz
|
||||
|
||||
@ -1 +1 @@
|
||||
6b0df2dddc2ee883380969362f5e5d1e89a6960d SOURCES/LVM2.2.03.32.tgz
|
||||
63bb26807fa2dc9b8df29525bd854335a278eed5 SOURCES/LVM2.2.03.33.tgz
|
||||
|
||||
@ -1,27 +1,28 @@
|
||||
From 4487d3c0b4e9e1bbb966a40876b2e481b90865a8 Mon Sep 17 00:00:00 2001
|
||||
From 826517119e31658ac9f91940816281a44b0af4e9 Mon Sep 17 00:00:00 2001
|
||||
From: Marian Csontos <mcsontos@redhat.com>
|
||||
Date: Thu, 3 Oct 2024 16:14:11 +0200
|
||||
Subject: [PATCH 1/7] RHEL9
|
||||
Subject: [PATCH 01/47] RHEL9
|
||||
|
||||
(cherry picked from commit 4ed40e67197778b28e4b822558614a517242e3e1)
|
||||
---
|
||||
VERSION | 2 +-
|
||||
VERSION_DM | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/VERSION b/VERSION
|
||||
index e1934c88c..e4e055d17 100644
|
||||
index 2d35b7660..4993d445a 100644
|
||||
--- a/VERSION
|
||||
+++ b/VERSION
|
||||
@@ -1 +1 @@
|
||||
-2.03.32(2) (2025-05-05)
|
||||
+2.03.32(2)-RHEL9 (2025-05-05)
|
||||
-2.03.33(2) (2025-06-27)
|
||||
+2.03.33(2)-RHEL9 (2025-09-25)
|
||||
diff --git a/VERSION_DM b/VERSION_DM
|
||||
index 9016990a1..ea3811ba7 100644
|
||||
index 0e8dcd346..c0564e0ea 100644
|
||||
--- a/VERSION_DM
|
||||
+++ b/VERSION_DM
|
||||
@@ -1 +1 @@
|
||||
-1.02.206 (2025-05-05)
|
||||
+1.02.206-RHEL9 (2025-05-05)
|
||||
-1.02.207 (2025-06-27)
|
||||
+1.02.207-RHEL9 (2025-09-25)
|
||||
--
|
||||
2.49.0
|
||||
2.51.0
|
||||
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
From 408a80fdd46d3854c92dfce1bff3a376aea611d1 Mon Sep 17 00:00:00 2001
|
||||
From c7b8367ebd23acbc63d657d3be822069cdb22e29 Mon Sep 17 00:00:00 2001
|
||||
From: Marian Csontos <mcsontos@redhat.com>
|
||||
Date: Thu, 16 May 2024 15:30:02 +0200
|
||||
Subject: [PATCH 2/7] Revert "10-dm.rules: bump DM_UDEV_RULES_VSN to 3"
|
||||
Subject: [PATCH 02/47] Revert "10-dm.rules: bump DM_UDEV_RULES_VSN to 3"
|
||||
|
||||
This reverts commit 038f9254d9554654197b59c160e3f775af27cdb1.
|
||||
|
||||
(cherry picked from commit 408a80fdd46d3854c92dfce1bff3a376aea611d1)
|
||||
---
|
||||
udev/10-dm.rules.in | 12 +-----------
|
||||
1 file changed, 1 insertion(+), 11 deletions(-)
|
||||
@ -46,5 +48,5 @@ index db4ee771d..ca255c793 100644
|
||||
ENV{DM_UDEV_DISABLE_DM_RULES_FLAG}!="1", ENV{DM_NAME}=="?*", SYMLINK+="(DM_DIR)/$env{DM_NAME}"
|
||||
|
||||
--
|
||||
2.49.0
|
||||
2.51.0
|
||||
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
From 6a15577cb02603512afce0f13a591183105c8f73 Mon Sep 17 00:00:00 2001
|
||||
From e7afa38ae6a12cb0ac0d4c7b923ec46c254df553 Mon Sep 17 00:00:00 2001
|
||||
From: Marian Csontos <mcsontos@redhat.com>
|
||||
Date: Thu, 16 May 2024 15:30:15 +0200
|
||||
Subject: [PATCH 3/7] Revert "dm udev rules: don't export and save DM_NOSCAN"
|
||||
Subject: [PATCH 03/47] Revert "dm udev rules: don't export and save DM_NOSCAN"
|
||||
|
||||
This reverts commit a196752969320cfc34a97cc97afa1978fa57da73.
|
||||
|
||||
(cherry picked from commit 6a15577cb02603512afce0f13a591183105c8f73)
|
||||
---
|
||||
udev/11-dm-lvm.rules.in | 2 +-
|
||||
udev/13-dm-disk.rules.in | 4 ++--
|
||||
@ -39,5 +41,5 @@ index 9bfeebe13..a9ad67e9f 100644
|
||||
(BLKID_RULE)
|
||||
GOTO="dm_link"
|
||||
--
|
||||
2.49.0
|
||||
2.51.0
|
||||
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
From 2280f85310b82c03b43dfd88e0712c5921a36ffc Mon Sep 17 00:00:00 2001
|
||||
From c58cdd59d2028c5eca83cdf5df16948b4277a21f Mon Sep 17 00:00:00 2001
|
||||
From: Marian Csontos <mcsontos@redhat.com>
|
||||
Date: Thu, 16 May 2024 15:30:24 +0200
|
||||
Subject: [PATCH 4/7] Revert "dm udev rules: don't export and save
|
||||
Subject: [PATCH 04/47] Revert "dm udev rules: don't export and save
|
||||
DM_SUSPENDED"
|
||||
|
||||
This reverts commit 21ca92c4325b6b161fb1e1f10942ad9f8d23c144.
|
||||
|
||||
(cherry picked from commit 2280f85310b82c03b43dfd88e0712c5921a36ffc)
|
||||
---
|
||||
udev/10-dm.rules.in | 14 ++++++--------
|
||||
udev/12-dm-permissions.rules | 1 +
|
||||
@ -84,5 +86,5 @@ index a9ad67e9f..e136ee441 100644
|
||||
|
||||
(BLKID_RULE)
|
||||
--
|
||||
2.49.0
|
||||
2.51.0
|
||||
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
From 4316c786f25f8b01b831458f8baf1f77faad79ba Mon Sep 17 00:00:00 2001
|
||||
From 1ab5db0e811306dafabcd7281ce84ffbe32b2566 Mon Sep 17 00:00:00 2001
|
||||
From: Marian Csontos <mcsontos@redhat.com>
|
||||
Date: Thu, 16 May 2024 15:30:37 +0200
|
||||
Subject: [PATCH 5/7] Revert "11-dm-lvm.rules: don't restore
|
||||
Subject: [PATCH 05/47] Revert "11-dm-lvm.rules: don't restore
|
||||
DM_UDEV_DISABLE_OTHER_RULES_FLAG from db"
|
||||
|
||||
This reverts commit 2b2f11a74cd5cc05f266fd0c65f0e55eb8bafd9f.
|
||||
|
||||
(cherry picked from commit 4316c786f25f8b01b831458f8baf1f77faad79ba)
|
||||
---
|
||||
udev/11-dm-lvm.rules.in | 13 ++++++++-----
|
||||
1 file changed, 8 insertions(+), 5 deletions(-)
|
||||
@ -34,5 +36,5 @@ index 6dd556aa9..9836f41ca 100644
|
||||
ENV{DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG}=="1", GOTO="lvm_end"
|
||||
|
||||
--
|
||||
2.49.0
|
||||
2.51.0
|
||||
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
From ebd5feaca2779c9379a14ba6f74a47214d03d94b Mon Sep 17 00:00:00 2001
|
||||
From 2d8f649144bd95cf2df65f1d4bd99c96a8c5f786 Mon Sep 17 00:00:00 2001
|
||||
From: Marian Csontos <mcsontos@redhat.com>
|
||||
Date: Thu, 16 May 2024 15:30:48 +0200
|
||||
Subject: [PATCH 6/7] Revert "10-dm-rules: don't restore
|
||||
Subject: [PATCH 06/47] Revert "10-dm-rules: don't restore
|
||||
DM_UDEV_DISABLE_OTHER_RULES_FLAG from db"
|
||||
|
||||
This reverts commit f98d020eadafe7d8db7bec1f5a26915615e5a6a9.
|
||||
|
||||
(cherry picked from commit ebd5feaca2779c9379a14ba6f74a47214d03d94b)
|
||||
---
|
||||
udev/10-dm.rules.in | 12 ++----------
|
||||
1 file changed, 2 insertions(+), 10 deletions(-)
|
||||
@ -45,5 +47,5 @@ index 29fe71527..2c6903da7 100644
|
||||
|
||||
# If DISK_RO is set, it's an uevent that changes the ro attribute of the device.
|
||||
--
|
||||
2.49.0
|
||||
2.51.0
|
||||
|
||||
|
||||
@ -1,30 +1,28 @@
|
||||
From 72f203a02d7f30d5afdaa853a082b2b1d1f56297 Mon Sep 17 00:00:00 2001
|
||||
From 50a4afb468ffa1219ee2d315a29808697e2d14c1 Mon Sep 17 00:00:00 2001
|
||||
From: Marian Csontos <mcsontos@redhat.com>
|
||||
Date: Mon, 5 May 2025 17:36:05 +0200
|
||||
Subject: [PATCH 7/7] WHATS_NEW_DM: update
|
||||
Subject: [PATCH 07/47] WHATS_NEW_DM: update
|
||||
|
||||
(cherry picked from commit 72f203a02d7f30d5afdaa853a082b2b1d1f56297)
|
||||
---
|
||||
WHATS_NEW_DM | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
WHATS_NEW_DM | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
|
||||
index 62ad0a055..0b167ec36 100644
|
||||
index 0bbdd1867..d4282ef20 100644
|
||||
--- a/WHATS_NEW_DM
|
||||
+++ b/WHATS_NEW_DM
|
||||
@@ -1,3 +1,13 @@
|
||||
+Version 1.02.207 -
|
||||
+================================
|
||||
+
|
||||
+RHEL9 - 05th May 2025
|
||||
+=====================
|
||||
@@ -1,3 +1,10 @@
|
||||
+RHEL9 - 30th September 2025
|
||||
+===========================
|
||||
+ Revert Increase DM_UDEV_RULES_VSN to 3 to indicate changed udev rules.
|
||||
+ Revert Rename DM_NOSCAN to .DM_NOSCAN so it's not stored in udev db.
|
||||
+ Revert Rename DM_SUSPENDED to .DM_SUSPENDED so it's not stored in udev db.
|
||||
+ Revert Do not import DM_UDEV_DISABLE_OTHER_RULES_FLAG from db in 10-dm-disk.rules.
|
||||
+
|
||||
Version 1.02.206 - 05th May 2025
|
||||
================================
|
||||
Add support for using regex in selection criteria for string lists.
|
||||
Version 1.02.207 - 27th June 2025
|
||||
=================================
|
||||
Escape the escape character itself on JSON report format output.
|
||||
--
|
||||
2.49.0
|
||||
2.51.0
|
||||
|
||||
|
||||
@ -1,143 +0,0 @@
|
||||
From 54d5564f0fc375278c940635c449bdeb24334b71 Mon Sep 17 00:00:00 2001
|
||||
From: David Teigland <teigland@redhat.com>
|
||||
Date: Wed, 7 May 2025 17:51:01 -0500
|
||||
Subject: [PATCH 08/14] lvmlockd: fix hosts check for vgremove
|
||||
|
||||
errors from lock manager were not being considered.
|
||||
EAGAIN from sanlock should be considered EBUSY.
|
||||
|
||||
(cherry picked from commit 53752ef851d3210e52297ebb4744fdd766c060c6)
|
||||
---
|
||||
daemons/lvmlockd/lvmlockd-core.c | 11 ++++++++---
|
||||
daemons/lvmlockd/lvmlockd-dlm.c | 8 ++++++++
|
||||
daemons/lvmlockd/lvmlockd-sanlock.c | 26 ++++++++++++++++++++++----
|
||||
3 files changed, 38 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/daemons/lvmlockd/lvmlockd-core.c b/daemons/lvmlockd/lvmlockd-core.c
|
||||
index c65a3cc39..e4aa91216 100644
|
||||
--- a/daemons/lvmlockd/lvmlockd-core.c
|
||||
+++ b/daemons/lvmlockd/lvmlockd-core.c
|
||||
@@ -2708,13 +2708,16 @@ static void *lockspace_thread_main(void *arg_in)
|
||||
rv = lm_hosts(ls, 1);
|
||||
if (rv) {
|
||||
/*
|
||||
+ * rv < 0: error (don't remove)
|
||||
+ * rv > 0: other hosts in lockspace (cannot remove)
|
||||
+ * rv = 0: only local host in lockspace (can remove)
|
||||
* Checking for hosts here in addition to after the
|
||||
* main loop allows vgremove to fail and be rerun
|
||||
* after the ls is stopped on other hosts.
|
||||
*/
|
||||
log_error("S %s lockspace hosts %d", ls->name, rv);
|
||||
list_del(&act->list);
|
||||
- act->result = -EBUSY;
|
||||
+ act->result = (rv < 0) ? rv : -EBUSY;
|
||||
add_client_result(act);
|
||||
continue;
|
||||
}
|
||||
@@ -2727,7 +2730,9 @@ static void *lockspace_thread_main(void *arg_in)
|
||||
if (act->op == LD_OP_BUSY && act->rt == LD_RT_VG) {
|
||||
log_debug("S %s checking if lockspace is busy", ls->name);
|
||||
rv = lm_hosts(ls, 0);
|
||||
- if (rv)
|
||||
+ if (rv < 0)
|
||||
+ act->result = rv;
|
||||
+ else if (rv)
|
||||
act->result = -EBUSY;
|
||||
else
|
||||
act->result = 0;
|
||||
@@ -2743,7 +2748,7 @@ static void *lockspace_thread_main(void *arg_in)
|
||||
if (rv) {
|
||||
log_error("S %s lockspace hosts %d", ls->name, rv);
|
||||
list_del(&act->list);
|
||||
- act->result = -EBUSY;
|
||||
+ act->result = (rv < 0) ? rv : -EBUSY;
|
||||
add_client_result(act);
|
||||
continue;
|
||||
}
|
||||
diff --git a/daemons/lvmlockd/lvmlockd-dlm.c b/daemons/lvmlockd/lvmlockd-dlm.c
|
||||
index 72b139170..7529ad327 100644
|
||||
--- a/daemons/lvmlockd/lvmlockd-dlm.c
|
||||
+++ b/daemons/lvmlockd/lvmlockd-dlm.c
|
||||
@@ -799,6 +799,14 @@ int lm_unlock_dlm(struct lockspace *ls, struct resource *r,
|
||||
* the stale lockspaces on the others eventually.)
|
||||
*/
|
||||
|
||||
+/*
|
||||
+ * On error, returns < 0
|
||||
+ *
|
||||
+ * On success:
|
||||
+ * If other hosts are found, returns the number.
|
||||
+ * If no other hosts are found (only ourself), returns 0.
|
||||
+ */
|
||||
+
|
||||
int lm_hosts_dlm(struct lockspace *ls, int notify)
|
||||
{
|
||||
char ls_nodes_path[PATH_MAX];
|
||||
diff --git a/daemons/lvmlockd/lvmlockd-sanlock.c b/daemons/lvmlockd/lvmlockd-sanlock.c
|
||||
index 1a3982071..d50d0ce4b 100644
|
||||
--- a/daemons/lvmlockd/lvmlockd-sanlock.c
|
||||
+++ b/daemons/lvmlockd/lvmlockd-sanlock.c
|
||||
@@ -2296,6 +2296,13 @@ int lm_unlock_sanlock(struct lockspace *ls, struct resource *r,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * On error, returns < 0
|
||||
+ * Else:
|
||||
+ * If other hosts are found, returns the number.
|
||||
+ * If no other hosts are found (only ourself), returns 0.
|
||||
+ */
|
||||
+
|
||||
int lm_hosts_sanlock(struct lockspace *ls, int notify)
|
||||
{
|
||||
struct sanlk_host *hss = NULL;
|
||||
@@ -2310,14 +2317,25 @@ int lm_hosts_sanlock(struct lockspace *ls, int notify)
|
||||
return 0;
|
||||
|
||||
rv = sanlock_get_hosts(ls->name, 0, &hss, &hss_count, 0);
|
||||
+
|
||||
+ if (rv == -EAGAIN) {
|
||||
+ /*
|
||||
+ * No host info is available yet (perhaps lockspace was
|
||||
+ * just started so other host state is unknown.) Pretend
|
||||
+ * there is one other host (busy).
|
||||
+ */
|
||||
+ log_debug("S %s hosts_san no info, retry later", ls->name);
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
if (rv < 0) {
|
||||
log_error("S %s hosts_san get_hosts error %d", ls->name, rv);
|
||||
- return 0;
|
||||
+ return -1;
|
||||
}
|
||||
|
||||
if (!hss || !hss_count) {
|
||||
log_error("S %s hosts_san zero hosts", ls->name);
|
||||
- return 0;
|
||||
+ return -1;
|
||||
}
|
||||
|
||||
hs = hss;
|
||||
@@ -2336,7 +2354,7 @@ int lm_hosts_sanlock(struct lockspace *ls, int notify)
|
||||
}
|
||||
|
||||
state = hs->flags & SANLK_HOST_MASK;
|
||||
- if (state == SANLK_HOST_LIVE)
|
||||
+ if ((state == SANLK_HOST_LIVE) || (state == SANLK_HOST_UNKNOWN))
|
||||
found_others++;
|
||||
hs++;
|
||||
}
|
||||
@@ -2358,7 +2376,7 @@ int lm_hosts_sanlock(struct lockspace *ls, int notify)
|
||||
|
||||
if (!found_self) {
|
||||
log_error("S %s hosts_san self not found others %d", ls->name, found_others);
|
||||
- return 0;
|
||||
+ return -1;
|
||||
}
|
||||
|
||||
return found_others;
|
||||
--
|
||||
2.49.0
|
||||
|
||||
50
SOURCES/0008-lvmlockd-fix-missing-free-in-vg_status.patch
Normal file
50
SOURCES/0008-lvmlockd-fix-missing-free-in-vg_status.patch
Normal file
@ -0,0 +1,50 @@
|
||||
From 8920f236abae6a9e7b15a0b11c1b9d5bad370aae Mon Sep 17 00:00:00 2001
|
||||
From: David Teigland <teigland@redhat.com>
|
||||
Date: Thu, 26 Jun 2025 13:42:38 -0500
|
||||
Subject: [PATCH 08/47] lvmlockd: fix missing free in vg_status
|
||||
|
||||
and add more checking of get_hosts result.
|
||||
|
||||
used by lockd_vg_is_started() for the PR feature.
|
||||
|
||||
(cherry picked from commit 5f0ddd0fd891e769577f6cd3546326f18dbc3bca)
|
||||
---
|
||||
daemons/lvmlockd/lvmlockd-sanlock.c | 8 +++++++-
|
||||
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/daemons/lvmlockd/lvmlockd-sanlock.c b/daemons/lvmlockd/lvmlockd-sanlock.c
|
||||
index 1af3c368f..97f06d115 100644
|
||||
--- a/daemons/lvmlockd/lvmlockd-sanlock.c
|
||||
+++ b/daemons/lvmlockd/lvmlockd-sanlock.c
|
||||
@@ -2352,7 +2352,7 @@ int lm_unlock_sanlock(struct lockspace *ls, struct resource *r,
|
||||
|
||||
int lm_vg_status_sanlock(struct lockspace *ls, struct action *act)
|
||||
{
|
||||
- struct sanlk_host *hs;
|
||||
+ struct sanlk_host *hs = NULL;
|
||||
const char *host_state;
|
||||
int count = 0;
|
||||
int rv;
|
||||
@@ -2366,6 +2366,11 @@ int lm_vg_status_sanlock(struct lockspace *ls, struct action *act)
|
||||
return rv;
|
||||
}
|
||||
|
||||
+ if (!count || !hs) {
|
||||
+ log_error("S %s vg_status_san get_hosts empty", ls->name);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
act->owner.host_id = (uint32_t)hs->host_id;
|
||||
act->owner.generation = (uint32_t)hs->generation;
|
||||
act->owner.timestamp = (uint32_t)hs->timestamp;
|
||||
@@ -2373,6 +2378,7 @@ int lm_vg_status_sanlock(struct lockspace *ls, struct action *act)
|
||||
if ((host_state = _host_flags_to_str(hs->flags)))
|
||||
dm_strncpy(act->owner.state, host_state, OWNER_STATE_SIZE-1);
|
||||
|
||||
+ free(hs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@ -0,0 +1,686 @@
|
||||
From 5878a6dc3167e4f9fc4c1dcb04c3dd41e3d4db19 Mon Sep 17 00:00:00 2001
|
||||
From: David Teigland <teigland@redhat.com>
|
||||
Date: Mon, 30 Jun 2025 12:59:49 -0500
|
||||
Subject: [PATCH 09/47] lvmlockd: add repair option to reinitialize sanlock
|
||||
leases
|
||||
|
||||
If sanlock leases become corrupted, adding --lockopt repair
|
||||
to the command will let lvmlockd reinitialize them.
|
||||
|
||||
(cherry picked from commit 4bc52d2dc5dee3c57f88d58c3143e8a2f4d44d9f)
|
||||
---
|
||||
configure.ac | 1 +
|
||||
daemons/lvmlockd/lvmlockd-core.c | 24 +--
|
||||
daemons/lvmlockd/lvmlockd-internal.h | 8 +-
|
||||
daemons/lvmlockd/lvmlockd-sanlock.c | 212 ++++++++++++++++++++++++---
|
||||
lib/locking/lvmlockd.c | 69 +++++++--
|
||||
lib/locking/lvmlockd.h | 4 +
|
||||
6 files changed, 277 insertions(+), 41 deletions(-)
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 6fcf6f2b5..11a735af5 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -936,6 +936,7 @@ dnl -- Look for sanlock libraries
|
||||
AS_IF([test "$BUILD_LOCKDSANLOCK" = "yes"], [
|
||||
LOCKDSANLOCK_SUPPORT=370
|
||||
PKG_CHECK_EXISTS(libsanlock_client >= 4.0.0, [LOCKDSANLOCK_SUPPORT=400])
|
||||
+ PKG_CHECK_EXISTS(libsanlock_client >= 4.1.0, [LOCKDSANLOCK_SUPPORT=410])
|
||||
PKG_CHECK_MODULES(LIBSANLOCKCLIENT, libsanlock_client >= 3.7.0, [BUILD_LVMLOCKD="yes"])
|
||||
AC_DEFINE_UNQUOTED([LOCKDSANLOCK_SUPPORT], [$LOCKDSANLOCK_SUPPORT], [Define version of sanlock.])
|
||||
])
|
||||
diff --git a/daemons/lvmlockd/lvmlockd-core.c b/daemons/lvmlockd/lvmlockd-core.c
|
||||
index 66a5d5e20..0cb10369a 100644
|
||||
--- a/daemons/lvmlockd/lvmlockd-core.c
|
||||
+++ b/daemons/lvmlockd/lvmlockd-core.c
|
||||
@@ -1057,7 +1057,7 @@ static void lm_vg_status(struct lockspace *ls, struct action *act)
|
||||
act->lm_rv = rv;
|
||||
}
|
||||
|
||||
-static int lm_prepare_lockspace(struct lockspace *ls, struct action *act)
|
||||
+static int lm_prepare_lockspace(struct lockspace *ls, struct action *act, int repair)
|
||||
{
|
||||
uint64_t prev_generation = 0;
|
||||
int rv = -1;
|
||||
@@ -1065,7 +1065,7 @@ static int lm_prepare_lockspace(struct lockspace *ls, struct action *act)
|
||||
if (ls->lm_type == LD_LM_DLM) {
|
||||
rv = lm_prepare_lockspace_dlm(ls);
|
||||
} else if (ls->lm_type == LD_LM_SANLOCK) {
|
||||
- rv = lm_prepare_lockspace_sanlock(ls, &prev_generation);
|
||||
+ rv = lm_prepare_lockspace_sanlock(ls, &prev_generation, repair);
|
||||
/* borrowing action.owner to avoid adding another action field */
|
||||
if (!rv)
|
||||
act->owner.generation = (uint32_t)prev_generation;
|
||||
@@ -1126,14 +1126,14 @@ static int lm_add_resource(struct lockspace *ls, struct resource *r)
|
||||
|
||||
static int lm_lock(struct lockspace *ls, struct resource *r, int mode, struct action *act,
|
||||
struct val_blk *vb_out, int *retry, struct owner *owner,
|
||||
- int adopt_only, int adopt_ok)
|
||||
+ int adopt_only, int adopt_ok, int repair)
|
||||
{
|
||||
int rv = -1;
|
||||
|
||||
if (ls->lm_type == LD_LM_DLM)
|
||||
rv = lm_lock_dlm(ls, r, mode, vb_out, adopt_only, adopt_ok);
|
||||
else if (ls->lm_type == LD_LM_SANLOCK)
|
||||
- rv = lm_lock_sanlock(ls, r, mode, vb_out, retry, owner, adopt_only, adopt_ok);
|
||||
+ rv = lm_lock_sanlock(ls, r, mode, vb_out, retry, owner, adopt_only, adopt_ok, repair);
|
||||
else if (ls->lm_type == LD_LM_IDM)
|
||||
rv = lm_lock_idm(ls, r, mode, vb_out, act->lv_uuid,
|
||||
&act->pvs, adopt_only, adopt_ok);
|
||||
@@ -1309,7 +1309,8 @@ static int res_lock(struct lockspace *ls, struct resource *r, struct action *act
|
||||
|
||||
rv = lm_lock(ls, r, act->mode, act, &vb, retry, owner,
|
||||
act->flags & LD_AF_ADOPT_ONLY ? 1 : 0,
|
||||
- act->flags & LD_AF_ADOPT ? 1 : 0);
|
||||
+ act->flags & LD_AF_ADOPT ? 1 : 0,
|
||||
+ act->flags & LD_AF_REPAIR ? 1 : 0);
|
||||
|
||||
if (rv && r->use_vb)
|
||||
log_debug("%s:%s res_lock rv %d read vb %x %x %u",
|
||||
@@ -2577,6 +2578,7 @@ static void *lockspace_thread_main(void *arg_in)
|
||||
int error = 0;
|
||||
int adopt_only = 0;
|
||||
int adopt_ok = 0;
|
||||
+ int repair = 0;
|
||||
int wait_flag = 0;
|
||||
int nodelay = 0;
|
||||
int nocreate;
|
||||
@@ -2604,6 +2606,8 @@ static void *lockspace_thread_main(void *arg_in)
|
||||
adopt_ok = 1;
|
||||
if (add_act->flags & LD_AF_NODELAY)
|
||||
nodelay = 1;
|
||||
+ if (add_act->flags & LD_AF_REPAIR)
|
||||
+ repair = 1;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&ls->mutex);
|
||||
@@ -2613,14 +2617,14 @@ static void *lockspace_thread_main(void *arg_in)
|
||||
adopt_ok = 1;
|
||||
}
|
||||
|
||||
- log_debug("S %s lm_add_lockspace %s wait %d adopt_only %d adopt_ok %d",
|
||||
- ls->name, lm_str(ls->lm_type), wait_flag, adopt_only, adopt_ok);
|
||||
+ log_debug("S %s lm_add_lockspace %s act %d wait %d adopt_only %d adopt_ok %d repair %d",
|
||||
+ ls->name, lm_str(ls->lm_type), add_act ? 1 : 0, wait_flag, adopt_only, adopt_ok, repair);
|
||||
|
||||
/*
|
||||
* The prepare step does not wait for anything and is quick;
|
||||
* it tells us if the parameters are valid and the lm is running.
|
||||
*/
|
||||
- error = lm_prepare_lockspace(ls, add_act);
|
||||
+ error = lm_prepare_lockspace(ls, add_act, repair);
|
||||
|
||||
if (add_act && (!wait_flag || error)) {
|
||||
/* send initial join result back to client */
|
||||
@@ -4789,6 +4793,8 @@ static uint32_t str_to_opts(const char *str)
|
||||
flags |= LD_AF_DISABLE;
|
||||
if (strstr(str, "nodelay"))
|
||||
flags |= LD_AF_NODELAY;
|
||||
+ if (strstr(str, "repair"))
|
||||
+ flags |= LD_AF_REPAIR;
|
||||
|
||||
/* FIXME: parse the flag values properly */
|
||||
if (strstr(str, "adopt_only"))
|
||||
@@ -5310,7 +5316,7 @@ skip_pvs_path:
|
||||
dm_config_destroy(req.cft);
|
||||
buffer_destroy(&req.buffer);
|
||||
|
||||
- log_debug("recv %s[%d][%u] %s%s%s %s%s %s%s%s%s opts=%x",
|
||||
+ log_debug("recv %s[%d][%u] %s%s%s %s%s %s%s%s%s opts=0x%x",
|
||||
cl->name[0] ? cl->name : "client", cl->pid, cl->id,
|
||||
op_mode_str(act->op, act->mode), act->rt ? "_" : "", rt_str(act->rt),
|
||||
act->vg_name[0] ? "vg=" : "",
|
||||
diff --git a/daemons/lvmlockd/lvmlockd-internal.h b/daemons/lvmlockd/lvmlockd-internal.h
|
||||
index bf40c77f2..7999c2a03 100644
|
||||
--- a/daemons/lvmlockd/lvmlockd-internal.h
|
||||
+++ b/daemons/lvmlockd/lvmlockd-internal.h
|
||||
@@ -118,6 +118,7 @@ struct client {
|
||||
#define LD_AF_SH_EXISTS 0x00100000
|
||||
#define LD_AF_ADOPT_ONLY 0x00200000 /* adopt orphan or fail */
|
||||
#define LD_AF_NODELAY 0x00400000
|
||||
+#define LD_AF_REPAIR 0x00800000
|
||||
|
||||
/*
|
||||
* Number of times to repeat a lock request after
|
||||
@@ -209,6 +210,7 @@ struct lockspace {
|
||||
int8_t lm_type; /* lock manager: LM_DLM, LM_SANLOCK */
|
||||
void *lm_data;
|
||||
uint32_t host_id;
|
||||
+ uint64_t generation;
|
||||
uint64_t free_lock_offset; /* for sanlock, start search for free lock here */
|
||||
struct pvs pvs; /* for idm: PV list */
|
||||
|
||||
@@ -561,13 +563,13 @@ int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_ar
|
||||
int lm_init_lv_sanlock(struct lockspace *ls, char *ls_name, char *vg_name, char *lv_name, char *vg_args, char *lv_args, char *prev_args);
|
||||
int lm_free_lv_sanlock(struct lockspace *ls, struct resource *r);
|
||||
int lm_rename_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_args);
|
||||
-int lm_prepare_lockspace_sanlock(struct lockspace *ls, uint64_t *prev_generation);
|
||||
+int lm_prepare_lockspace_sanlock(struct lockspace *ls, uint64_t *prev_generation, int repair);
|
||||
int lm_add_lockspace_sanlock(struct lockspace *ls, int adopt_only, int adopt_ok, int nodelay);
|
||||
int lm_rem_lockspace_sanlock(struct lockspace *ls, int free_vg);
|
||||
int lm_add_resource_sanlock(struct lockspace *ls, struct resource *r);
|
||||
int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||
struct val_blk *vb_out, int *retry, struct owner *owner,
|
||||
- int adopt_only, int adopt_ok);
|
||||
+ int adopt_only, int adopt_ok, int repair);
|
||||
int lm_convert_sanlock(struct lockspace *ls, struct resource *r,
|
||||
int ld_mode, uint32_t r_version);
|
||||
int lm_unlock_sanlock(struct lockspace *ls, struct resource *r,
|
||||
@@ -610,7 +612,7 @@ static inline int lm_rename_vg_sanlock(char *ls_name, char *vg_name, uint32_t fl
|
||||
return -1;
|
||||
}
|
||||
|
||||
-static inline int lm_prepare_lockspace_sanlock(struct lockspace *ls, uint64_t *prev_generation)
|
||||
+static inline int lm_prepare_lockspace_sanlock(struct lockspace *ls, uint64_t *prev_generation, int repair)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
diff --git a/daemons/lvmlockd/lvmlockd-sanlock.c b/daemons/lvmlockd/lvmlockd-sanlock.c
|
||||
index 97f06d115..ce5953faf 100644
|
||||
--- a/daemons/lvmlockd/lvmlockd-sanlock.c
|
||||
+++ b/daemons/lvmlockd/lvmlockd-sanlock.c
|
||||
@@ -218,6 +218,18 @@ int lm_data_size_sanlock(void)
|
||||
|
||||
static uint64_t daemon_test_lv_count;
|
||||
|
||||
+static void _fclose(FILE *fp, char *name)
|
||||
+{
|
||||
+ if (fclose(fp))
|
||||
+ log_warn("fclose error %d %s", errno, name ?: "");
|
||||
+}
|
||||
+
|
||||
+static void _close(int fd)
|
||||
+{
|
||||
+ if (close(fd))
|
||||
+ log_warn("close error %d fd %d", errno, fd);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Copy a null-terminated string "str" into a fixed
|
||||
* size struct field "buf" which is not null terminated.
|
||||
@@ -308,14 +320,74 @@ static int read_host_id_file(void)
|
||||
break;
|
||||
}
|
||||
}
|
||||
- if (fclose(file))
|
||||
- log_debug("Failed to fclose host id file %s (%s).",
|
||||
- daemon_host_id_file, strerror(errno));
|
||||
+ _fclose(file, (char *)daemon_host_id_file);
|
||||
out:
|
||||
log_debug("host_id %d from %s", host_id, daemon_host_id_file);
|
||||
return host_id;
|
||||
}
|
||||
|
||||
+static int read_info_file(struct lockspace *ls, uint32_t *host_id, uint64_t *generation, int *sector_size, int *align_size)
|
||||
+{
|
||||
+ char line[MAX_LINE];
|
||||
+ char path[PATH_MAX] = { 0 };
|
||||
+ FILE *fp;
|
||||
+
|
||||
+ if (dm_snprintf(path, PATH_MAX-1, "/var/lib/lvm/lvmlockd_info_%s", ls->vg_name) < 0)
|
||||
+ return -1;
|
||||
+
|
||||
+ if (!(fp = fopen(path, "r"))) {
|
||||
+ log_debug("Failed to open info file");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ while (fgets(line, sizeof(line), fp)) {
|
||||
+ if (line[0] == '#')
|
||||
+ continue;
|
||||
+ if (!strncmp(line, "host_id ", 8)) {
|
||||
+ sscanf(line, "host_id %u", host_id);
|
||||
+ } else if (!strncmp(line, "generation ", 11)) {
|
||||
+ sscanf(line, "generation %llu", (unsigned long long *)generation);
|
||||
+ } else if (!strncmp(line, "sector_size ", 12)) {
|
||||
+ sscanf(line, "sector_size %d", sector_size);
|
||||
+ } else if (!strncmp(line, "align_size ", 11)) {
|
||||
+ sscanf(line, "align_size %d", align_size);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ _fclose(fp, path);
|
||||
+ log_debug("info file: read %u %llu %d %d", *host_id, (unsigned long long)*generation, *sector_size, *align_size);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int write_info_file(struct lockspace *ls)
|
||||
+{
|
||||
+ struct lm_sanlock *lms = (struct lm_sanlock *)ls->lm_data;
|
||||
+ char path[PATH_MAX] = { 0 };
|
||||
+ FILE *fp;
|
||||
+ time_t t;
|
||||
+
|
||||
+ if (dm_snprintf(path, PATH_MAX-1, "/var/lib/lvm/lvmlockd_info_%s", ls->vg_name) < 0)
|
||||
+ return -1;
|
||||
+
|
||||
+ if (!(fp = fopen(path, "w"))) {
|
||||
+ log_debug("Failed to create info file");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ fprintf(fp, "# vg %s %s created %s", ls->vg_name, ls->vg_uuid, ctime(&t));
|
||||
+ fprintf(fp, "host_id %u\n", ls->host_id);
|
||||
+ fprintf(fp, "generation %llu\n", (unsigned long long)ls->generation);
|
||||
+ fprintf(fp, "sector_size %d\n", lms->sector_size);
|
||||
+ fprintf(fp, "align_size %d\n", lms->align_size);
|
||||
+
|
||||
+ if (fflush(fp))
|
||||
+ log_warn("Failed to write/flush %s", path);
|
||||
+ _fclose(fp, path);
|
||||
+
|
||||
+ log_debug("info file: wrote %u %llu %d %d", ls->host_id, (unsigned long long)ls->generation, lms->sector_size, lms->align_size);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/* Prepare valid /dev/mapper/vgname-lvname with all the mangling */
|
||||
static int build_dm_path(char *path, size_t path_len,
|
||||
const char *vg_name, const char *lv_name)
|
||||
@@ -370,7 +442,7 @@ static void _read_sysfs_size(dev_t devno, const char *name, uint64_t *val)
|
||||
if (strlen(buf))
|
||||
*val = strtoull(buf, NULL, 0);
|
||||
out:
|
||||
- (void)fclose(fp);
|
||||
+ _fclose(fp, path);
|
||||
}
|
||||
|
||||
/* Select sector/align size for a new VG based on what the device reports for
|
||||
@@ -479,6 +551,7 @@ static int _lease_corrupt_error(int rv)
|
||||
{
|
||||
if (rv == SANLK_LEADER_MAGIC ||
|
||||
rv == SANLK_LEADER_VERSION ||
|
||||
+ rv == SANLK_LEADER_DIFF ||
|
||||
rv == SANLK_LEADER_LOCKSPACE ||
|
||||
rv == SANLK_LEADER_RESOURCE ||
|
||||
rv == SANLK_LEADER_CHECKSUM ||
|
||||
@@ -509,8 +582,10 @@ static int read_lockspace_info(char *path, uint32_t host_id, int *sector_size, i
|
||||
#endif
|
||||
rv = sanlock_read_lockspace(&ss, 0, &io_timeout);
|
||||
|
||||
- if (_lease_corrupt_error(rv))
|
||||
+ if (_lease_corrupt_error(rv)) {
|
||||
+ log_error("read_lockspace_info %s %u corrupt lease error %d", path, host_id, rv);
|
||||
return -ELOCKREPAIR;
|
||||
+ }
|
||||
|
||||
if (rv < 0) {
|
||||
log_error("read_lockspace_info %s %u error %d", path, host_id, rv);
|
||||
@@ -1471,7 +1546,7 @@ int lm_find_free_lock_sanlock(struct lockspace *ls, uint64_t lv_size_bytes)
|
||||
* This should also not create any major problems.
|
||||
*/
|
||||
|
||||
-int lm_prepare_lockspace_sanlock(struct lockspace *ls, uint64_t *prev_generation)
|
||||
+int lm_prepare_lockspace_sanlock(struct lockspace *ls, uint64_t *prev_generation, int repair)
|
||||
{
|
||||
struct stat st;
|
||||
struct lm_sanlock *lms = NULL;
|
||||
@@ -1486,6 +1561,7 @@ int lm_prepare_lockspace_sanlock(struct lockspace *ls, uint64_t *prev_generation
|
||||
int sector_size = 0;
|
||||
int align_size = 0;
|
||||
int align_mb = 0;
|
||||
+ int retries = 0;
|
||||
int gl_found;
|
||||
int ret, rv;
|
||||
|
||||
@@ -1502,6 +1578,8 @@ int lm_prepare_lockspace_sanlock(struct lockspace *ls, uint64_t *prev_generation
|
||||
memset(killargs, 0, sizeof(killargs));
|
||||
snprintf(killargs, SANLK_PATH_LEN, "--kill %s", ls->vg_name);
|
||||
|
||||
+ log_debug("S %s prepare_lockspace_san host_id %u repair %d", ls->name, ls->host_id, repair);
|
||||
+
|
||||
rv = check_args_version(ls->vg_args, VG_LOCK_ARGS_MAJOR);
|
||||
if (rv < 0) {
|
||||
ret = -EARGS;
|
||||
@@ -1602,7 +1680,63 @@ int lm_prepare_lockspace_sanlock(struct lockspace *ls, uint64_t *prev_generation
|
||||
goto fail;
|
||||
}
|
||||
|
||||
+ repair_retry:
|
||||
+ sector_size = 0;
|
||||
+ align_size = 0;
|
||||
+
|
||||
rv = read_lockspace_info(disk_path, lms->ss.host_id, §or_size, &align_size, &align_mb, &ss_flags, &rs_flags, &hs);
|
||||
+
|
||||
+#if LOCKDSANLOCK_SUPPORT >= 410
|
||||
+ if ((rv == -ELOCKREPAIR) && repair && !retries) {
|
||||
+ uint64_t generation = 0;
|
||||
+ uint32_t host_id = 0;
|
||||
+
|
||||
+ rv = read_info_file(ls, &host_id, &generation, §or_size, &align_size);
|
||||
+ if (rv < 0) {
|
||||
+ log_error("S %s prepare_lockspace_san cannot repair lockspace no info file", lsname);
|
||||
+ ret = -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if (host_id != lms->ss.host_id) {
|
||||
+ log_error("S %s prepare_lockspace_san cannot repair lockspace other info host_id", lsname);
|
||||
+ ret = -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ hs.generation = generation;
|
||||
+
|
||||
+ if (sector_size == 512) {
|
||||
+ lms->ss.flags |= SANLK_LSF_SECTOR512;
|
||||
+ lms->ss.flags |= SANLK_LSF_ALIGN1M;
|
||||
+ } else if (sector_size == 4096) {
|
||||
+ lms->ss.flags |= SANLK_LSF_SECTOR4K;
|
||||
+ if (align_size == ONE_MB)
|
||||
+ lms->ss.flags |= SANLK_LSF_ALIGN1M;
|
||||
+ else if (align_size == 2 * ONE_MB)
|
||||
+ lms->ss.flags |= SANLK_LSF_ALIGN2M;
|
||||
+ else if (align_size == 4 * ONE_MB)
|
||||
+ lms->ss.flags |= SANLK_LSF_ALIGN4M;
|
||||
+ else if (align_size == 8 * ONE_MB)
|
||||
+ lms->ss.flags |= SANLK_LSF_ALIGN8M;
|
||||
+ } else {
|
||||
+ log_error("S %s prepare_lockspace_san cannot repair lockspace invalid sector_size", lsname);
|
||||
+ ret = -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ log_debug("S %s prepare_lockspace_san repair host %u lease", lsname, host_id);
|
||||
+
|
||||
+ rv = sanlock_init_lockspace_host(&lms->ss, NULL, generation, 0, 0, 0);
|
||||
+ if (rv < 0) {
|
||||
+ log_error("S %s prepare_lockspace_san repair host %u lease error %d", lsname, host_id, rv);
|
||||
+ ret = -EMANAGER;
|
||||
+ }
|
||||
+ retries = 1;
|
||||
+ goto repair_retry;
|
||||
+ }
|
||||
+#else
|
||||
+ if ((rv == -ELOCKREPAIR) && repair && !retries)
|
||||
+ log_debug("S %s prepare_lockspace_san sanlock does not support repair.", lsname);
|
||||
+#endif
|
||||
+
|
||||
if (rv < 0) {
|
||||
log_error("S %s prepare_lockspace_san cannot read lockspace info %d", lsname, rv);
|
||||
ret = -EMANAGER;
|
||||
@@ -1675,7 +1809,7 @@ out:
|
||||
|
||||
fail:
|
||||
if (lms && lms->sock)
|
||||
- close(lms->sock);
|
||||
+ _close(lms->sock);
|
||||
free(lms);
|
||||
return ret;
|
||||
}
|
||||
@@ -1683,7 +1817,9 @@ fail:
|
||||
int lm_add_lockspace_sanlock(struct lockspace *ls, int adopt_only, int adopt_ok, int nodelay)
|
||||
{
|
||||
struct lm_sanlock *lms = (struct lm_sanlock *)ls->lm_data;
|
||||
+ struct sanlk_host *hs = NULL;
|
||||
uint32_t flags = 0;
|
||||
+ int count = 0;
|
||||
int rv;
|
||||
|
||||
if (daemon_test) {
|
||||
@@ -1710,6 +1846,33 @@ int lm_add_lockspace_sanlock(struct lockspace *ls, int adopt_only, int adopt_ok,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
+ rv = sanlock_get_hosts(ls->name, 0, &hs, &count, SANLK_GET_HOST_LOCAL);
|
||||
+ if (rv < 0) {
|
||||
+ log_error("S %s add_lockspace_san add_lockspace get_host error %d", ls->name, rv);
|
||||
+ goto fail_rem;
|
||||
+ }
|
||||
+
|
||||
+ if (!count || !hs) {
|
||||
+ log_error("S %s add_lockspace_san add_lockspace get_host empty", ls->name);
|
||||
+ goto fail_rem;
|
||||
+ }
|
||||
+
|
||||
+ if ((uint32_t)hs->host_id != ls->host_id) {
|
||||
+ log_error("S %s add_lockspace_san add_lockspace get_host invalid host_id", ls->name);
|
||||
+ goto fail_rem;
|
||||
+ }
|
||||
+
|
||||
+ if (!hs->generation) {
|
||||
+ log_error("S %s add_lockspace_san add_lockspace get_host zero generation", ls->name);
|
||||
+ goto fail_rem;
|
||||
+ }
|
||||
+
|
||||
+ ls->generation = hs->generation;
|
||||
+
|
||||
+ free(hs);
|
||||
+
|
||||
+ write_info_file(ls);
|
||||
+
|
||||
/*
|
||||
* Don't let the lockspace be cleanly released if orphan locks
|
||||
* exist, because the orphan locks are still protecting resources
|
||||
@@ -1721,17 +1884,17 @@ int lm_add_lockspace_sanlock(struct lockspace *ls, int adopt_only, int adopt_ok,
|
||||
rv = sanlock_set_config(ls->name, 0, SANLK_CONFIG_USED_BY_ORPHANS, NULL);
|
||||
if (rv < 0) {
|
||||
log_error("S %s add_lockspace_san set_config error %d", ls->name, rv);
|
||||
- sanlock_rem_lockspace(&lms->ss, 0);
|
||||
- goto fail;
|
||||
+ goto fail_rem;
|
||||
}
|
||||
|
||||
out:
|
||||
log_debug("S %s add_lockspace_san done", ls->name);
|
||||
return 0;
|
||||
|
||||
+fail_rem:
|
||||
+ sanlock_rem_lockspace(&lms->ss, 0);
|
||||
fail:
|
||||
- if (close(lms->sock))
|
||||
- log_error("failed to close sanlock daemon socket connection");
|
||||
+ _close(lms->sock);
|
||||
free(lms);
|
||||
ls->lm_data = NULL;
|
||||
return rv;
|
||||
@@ -1767,8 +1930,7 @@ int lm_rem_lockspace_sanlock(struct lockspace *ls, int free_vg)
|
||||
}
|
||||
}
|
||||
|
||||
- if (close(lms->sock))
|
||||
- log_error("failed to close sanlock daemon socket connection");
|
||||
+ _close(lms->sock);
|
||||
out:
|
||||
free(lms);
|
||||
ls->lm_data = NULL;
|
||||
@@ -1845,7 +2007,7 @@ static const char *_host_flags_to_str(uint32_t flags)
|
||||
|
||||
int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||
struct val_blk *vb_out, int *retry, struct owner *owner,
|
||||
- int adopt_only, int adopt_ok)
|
||||
+ int adopt_only, int adopt_ok, int repair)
|
||||
{
|
||||
struct lm_sanlock *lms = (struct lm_sanlock *)ls->lm_data;
|
||||
struct rd_sanlock *rds = (struct rd_sanlock *)r->lm_data;
|
||||
@@ -1857,6 +2019,7 @@ int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||
uint32_t flags = 0;
|
||||
struct val_blk vb = { 0 };
|
||||
int added = 0;
|
||||
+ int retries = 0;
|
||||
int rv;
|
||||
|
||||
if (!r->lm_init) {
|
||||
@@ -1956,6 +2119,8 @@ int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||
memset(&opt, 0, sizeof(opt));
|
||||
sprintf(opt.owner_name, "%s", "lvmlockd");
|
||||
|
||||
+ repair_retry:
|
||||
+
|
||||
#if LOCKDSANLOCK_SUPPORT >= 400
|
||||
rv = sanlock_acquire2(lms->sock, -1, flags, rs, &opt, &owner_host, &owner_name);
|
||||
#else
|
||||
@@ -2068,9 +2233,20 @@ int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||
return -EIOTIMEOUT;
|
||||
}
|
||||
|
||||
+ if (_lease_corrupt_error(rv) && repair && !retries) {
|
||||
+ log_debug("%s:%s lock_san acquire lease_corrupt %d repair", ls->name, r->name, rv);
|
||||
+
|
||||
+ rv = sanlock_write_resource(rs, 0, 0, 0);
|
||||
+ if (rv < 0) {
|
||||
+ log_error("%s:%s lock_san acquire lease repair write_resource error %d", ls->name, r->name, rv);
|
||||
+ return rv;
|
||||
+ }
|
||||
+ retries = 1;
|
||||
+ goto repair_retry;
|
||||
+ }
|
||||
+
|
||||
if (rv < 0) {
|
||||
- log_error("%s:%s lock_san acquire error %d",
|
||||
- ls->name, r->name, rv);
|
||||
+ log_error("%s:%s lock_san acquire error %d", ls->name, r->name, rv);
|
||||
|
||||
/* if the gl has been disabled, remove and free the gl resource */
|
||||
if ((rv == SANLK_LEADER_RESOURCE) && (r->type == LD_RT_GL)) {
|
||||
@@ -2094,8 +2270,10 @@ int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||
rv == SANLK_DBLOCK_WRITE)
|
||||
return -ELOCKIO;
|
||||
|
||||
- if (_lease_corrupt_error(rv))
|
||||
+ if (_lease_corrupt_error(rv)) {
|
||||
+ log_debug("%s:%s lock_san lease corrupt repair %d retries %d", ls->name, r->name, repair, retries);
|
||||
return -ELOCKREPAIR;
|
||||
+ }
|
||||
|
||||
/*
|
||||
* The sanlock lockspace can disappear if the lease storage fails,
|
||||
diff --git a/lib/locking/lvmlockd.c b/lib/locking/lvmlockd.c
|
||||
index f86007858..68dea52e0 100644
|
||||
--- a/lib/locking/lvmlockd.c
|
||||
+++ b/lib/locking/lvmlockd.c
|
||||
@@ -1466,11 +1466,17 @@ int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg, int *exists
|
||||
|
||||
if ((cmd->lockopt & LOCKOPT_NODELAY) ||
|
||||
(cmd->lockopt & LOCKOPT_ADOPTLS) ||
|
||||
- (cmd->lockopt & LOCKOPT_ADOPT)) {
|
||||
- (void) dm_snprintf(opt_buf, sizeof(opt_buf), "%s%s%s",
|
||||
- (cmd->lockopt & LOCKOPT_NODELAY) ? "nodelay," : "",
|
||||
- (cmd->lockopt & LOCKOPT_ADOPTLS) ? "adopt_only" : "",
|
||||
- (cmd->lockopt & LOCKOPT_ADOPT) ? "adopt" : "");
|
||||
+ (cmd->lockopt & LOCKOPT_ADOPT) ||
|
||||
+ (cmd->lockopt & LOCKOPT_REPAIRVG) ||
|
||||
+ (cmd->lockopt & LOCKOPT_REPAIR)) {
|
||||
+ if (dm_snprintf(opt_buf, sizeof(opt_buf), "%s%s%s%s",
|
||||
+ (cmd->lockopt & LOCKOPT_NODELAY) ? "nodelay," : "",
|
||||
+ (cmd->lockopt & LOCKOPT_ADOPTLS) ? "adopt_only," : "",
|
||||
+ (cmd->lockopt & LOCKOPT_ADOPT) ? "adopt," : "",
|
||||
+ (cmd->lockopt & (LOCKOPT_REPAIR|LOCKOPT_REPAIRVG)) ? "repair" : "") < 0) {
|
||||
+ log_error("Options string too long %x", cmd->lockopt);
|
||||
+ return 0;
|
||||
+ }
|
||||
opts = opt_buf;
|
||||
}
|
||||
|
||||
@@ -1967,6 +1973,7 @@ out:
|
||||
int lockd_global(struct cmd_context *cmd, const char *def_mode)
|
||||
{
|
||||
struct owner owner = { 0 };
|
||||
+ char opt_buf[64] = {};
|
||||
const char *mode = NULL;
|
||||
const char *opts = NULL;
|
||||
uint32_t lockd_flags;
|
||||
@@ -1996,10 +2003,19 @@ int lockd_global(struct cmd_context *cmd, const char *def_mode)
|
||||
return 0;
|
||||
}
|
||||
|
||||
- if (cmd->lockopt & LOCKOPT_ADOPTGL)
|
||||
- opts = "adopt_only";
|
||||
- else if (cmd->lockopt & LOCKOPT_ADOPT)
|
||||
- opts = "adopt";
|
||||
+ if ((cmd->lockopt & LOCKOPT_ADOPTGL) ||
|
||||
+ (cmd->lockopt & LOCKOPT_ADOPT) ||
|
||||
+ (cmd->lockopt & LOCKOPT_REPAIRGL) ||
|
||||
+ (cmd->lockopt & LOCKOPT_REPAIR)) {
|
||||
+ if (dm_snprintf(opt_buf, sizeof(opt_buf), "%s%s%s",
|
||||
+ (cmd->lockopt & LOCKOPT_ADOPTGL) ? "adopt_only" : "",
|
||||
+ (cmd->lockopt & LOCKOPT_ADOPT) ? "adopt" : "",
|
||||
+ (cmd->lockopt & (LOCKOPT_REPAIR|LOCKOPT_REPAIRGL)) ? "repair" : "") < 0) {
|
||||
+ log_error("Options string too long %x", cmd->lockopt);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ opts = opt_buf;
|
||||
+ }
|
||||
|
||||
if (!strcmp(mode, "sh") && cmd->lockd_global_ex)
|
||||
return 1;
|
||||
@@ -2255,6 +2271,7 @@ int lockd_vg(struct cmd_context *cmd, const char *vg_name, const char *def_mode,
|
||||
uint32_t flags, uint32_t *lockd_state)
|
||||
{
|
||||
struct owner owner = { 0 };
|
||||
+ char opt_buf[64] = {};
|
||||
const char *mode = NULL;
|
||||
const char *opts = NULL;
|
||||
uint32_t lockd_flags;
|
||||
@@ -2332,6 +2349,20 @@ int lockd_vg(struct cmd_context *cmd, const char *vg_name, const char *def_mode,
|
||||
else if (cmd->lockopt & LOCKOPT_ADOPT)
|
||||
opts = "adopt";
|
||||
|
||||
+ if ((cmd->lockopt & LOCKOPT_ADOPTVG) ||
|
||||
+ (cmd->lockopt & LOCKOPT_ADOPT) ||
|
||||
+ (cmd->lockopt & LOCKOPT_REPAIRVG) ||
|
||||
+ (cmd->lockopt & LOCKOPT_REPAIR)) {
|
||||
+ if (dm_snprintf(opt_buf, sizeof(opt_buf), "%s%s%s",
|
||||
+ (cmd->lockopt & LOCKOPT_ADOPTVG) ? "adopt_only" : "",
|
||||
+ (cmd->lockopt & LOCKOPT_ADOPT) ? "adopt" : "",
|
||||
+ (cmd->lockopt & (LOCKOPT_REPAIR|LOCKOPT_REPAIRVG)) ? "repair" : "") < 0) {
|
||||
+ log_error("Options string too long %x.", cmd->lockopt);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ opts = opt_buf;
|
||||
+ }
|
||||
+
|
||||
if (!strcmp(mode, "ex"))
|
||||
*lockd_state |= LDST_EX;
|
||||
|
||||
@@ -2792,11 +2823,17 @@ int lockd_lv_name(struct cmd_context *cmd, struct volume_group *vg,
|
||||
|
||||
if ((flags & LDLV_PERSISTENT) ||
|
||||
(cmd->lockopt & LOCKOPT_ADOPTLV) ||
|
||||
- (cmd->lockopt & LOCKOPT_ADOPT)) {
|
||||
- (void) dm_snprintf(opt_buf, sizeof(opt_buf), "%s%s%s",
|
||||
+ (cmd->lockopt & LOCKOPT_ADOPT) ||
|
||||
+ (cmd->lockopt & LOCKOPT_REPAIRLV) ||
|
||||
+ (cmd->lockopt & LOCKOPT_REPAIR)) {
|
||||
+ if (dm_snprintf(opt_buf, sizeof(opt_buf), "%s%s%s%s",
|
||||
(flags & LDLV_PERSISTENT) ? "persistent," : "",
|
||||
(cmd->lockopt & LOCKOPT_ADOPTLV) ? "adopt_only" : "",
|
||||
- (cmd->lockopt & LOCKOPT_ADOPT) ? "adopt" : "");
|
||||
+ (cmd->lockopt & LOCKOPT_ADOPT) ? "adopt" : "",
|
||||
+ (cmd->lockopt & (LOCKOPT_REPAIR|LOCKOPT_REPAIRLV)) ? "repair" : "") < 0) {
|
||||
+ log_error("Options string too long %x.", cmd->lockopt);
|
||||
+ return 0;
|
||||
+ }
|
||||
opts = opt_buf;
|
||||
}
|
||||
|
||||
@@ -4397,6 +4434,14 @@ void lockd_lockopt_get_flags(const char *str, uint32_t *flags)
|
||||
*flags |= LOCKOPT_ADOPT;
|
||||
else if (!strcmp(argv[i], "nodelay"))
|
||||
*flags |= LOCKOPT_NODELAY;
|
||||
+ else if (!strcmp(argv[i], "repair"))
|
||||
+ *flags |= LOCKOPT_REPAIR;
|
||||
+ else if (!strcmp(argv[i], "repairgl"))
|
||||
+ *flags |= LOCKOPT_REPAIRGL;
|
||||
+ else if (!strcmp(argv[i], "repairvg"))
|
||||
+ *flags |= LOCKOPT_REPAIRVG;
|
||||
+ else if (!strcmp(argv[i], "repairlv"))
|
||||
+ *flags |= LOCKOPT_REPAIRLV;
|
||||
else
|
||||
log_warn("Ignoring unknown lockopt value: %s", argv[i]);
|
||||
}
|
||||
diff --git a/lib/locking/lvmlockd.h b/lib/locking/lvmlockd.h
|
||||
index 85295852c..18f01cd23 100644
|
||||
--- a/lib/locking/lvmlockd.h
|
||||
+++ b/lib/locking/lvmlockd.h
|
||||
@@ -58,6 +58,10 @@
|
||||
#define LOCKOPT_ADOPTLV 0x00001000
|
||||
#define LOCKOPT_ADOPT 0x00002000
|
||||
#define LOCKOPT_NODELAY 0x00004000
|
||||
+#define LOCKOPT_REPAIR 0x00008000
|
||||
+#define LOCKOPT_REPAIRGL 0x00010000
|
||||
+#define LOCKOPT_REPAIRVG 0x00020000
|
||||
+#define LOCKOPT_REPAIRLV 0x00040000
|
||||
|
||||
#ifdef LVMLOCKD_SUPPORT
|
||||
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@ -1,38 +0,0 @@
|
||||
From 0b375ab5f49c4eea0c705ef8e27e94a366b0f6d6 Mon Sep 17 00:00:00 2001
|
||||
From: David Teigland <teigland@redhat.com>
|
||||
Date: Thu, 8 May 2025 10:54:50 -0500
|
||||
Subject: [PATCH 09/14] lvmlockd: fix sanlock_release for vgremove
|
||||
|
||||
incorrect data was being copied to lease structs passed
|
||||
to sanlock_release(), making the lease removal fail.
|
||||
|
||||
(cherry picked from commit 88910c200f9e24a454dc9fcbf39c2df1d4887f3b)
|
||||
---
|
||||
daemons/lvmlockd/lvmlockd-sanlock.c | 7 +++++--
|
||||
1 file changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/daemons/lvmlockd/lvmlockd-sanlock.c b/daemons/lvmlockd/lvmlockd-sanlock.c
|
||||
index d50d0ce4b..b17cbad7e 100644
|
||||
--- a/daemons/lvmlockd/lvmlockd-sanlock.c
|
||||
+++ b/daemons/lvmlockd/lvmlockd-sanlock.c
|
||||
@@ -2192,12 +2192,15 @@ static int release_rename(struct lockspace *ls, struct resource *r)
|
||||
if (!res_args)
|
||||
return -ENOMEM;
|
||||
|
||||
- memcpy(&rd1, rds, sizeof(struct rd_sanlock));
|
||||
- memcpy(&rd2, rds, sizeof(struct rd_sanlock));
|
||||
+ memcpy(&rd1, &rds->rs, sizeof(struct rd_sanlock));
|
||||
+ memcpy(&rd2, &rds->rs, sizeof(struct rd_sanlock));
|
||||
|
||||
res1 = (struct sanlk_resource *)&rd1;
|
||||
res2 = (struct sanlk_resource *)&rd2;
|
||||
|
||||
+ if (memcmp(res1->name, r->name, SANLK_NAME_LEN))
|
||||
+ log_error("%s:%s unlock_san release rename bad name %.48s", ls->name, r->name, res1->name);
|
||||
+
|
||||
strcpy_name_len(res2->name, "invalid_removed", SANLK_NAME_LEN);
|
||||
|
||||
res_args[0] = res1;
|
||||
--
|
||||
2.49.0
|
||||
|
||||
@ -1,460 +0,0 @@
|
||||
From ad632cf9f19f3b8efbcf087cbf60527160ba5fec Mon Sep 17 00:00:00 2001
|
||||
From: Heinz Mauelshagen <heinzm@redhat.com>
|
||||
Date: Tue, 5 Nov 2024 18:33:19 +0100
|
||||
Subject: [PATCH 10/14] raid: count or clear transiently failed devices
|
||||
|
||||
Count or clear transiently failed devices as of dm-raid superblocks.
|
||||
Updated debuging.
|
||||
Use lvconvert --repair to repair transiently failed legs.
|
||||
Activating all 'meta' LVs with single sync_local_dev_names().
|
||||
Using proper DM path for meta LV.
|
||||
|
||||
Modified-by: zkabelac@redhat.com
|
||||
(cherry picked from commit 03d8661657bb3d1cb5dd764f3a450a8211f892e6)
|
||||
---
|
||||
device_mapper/Makefile | 1 +
|
||||
device_mapper/all.h | 1 +
|
||||
device_mapper/raid/raid_parser.c | 164 ++++++++++++++++++++++++++++
|
||||
device_mapper/raid/target.h | 23 ++++
|
||||
lib/activate/activate.h | 2 +
|
||||
lib/metadata/raid_manip.c | 179 ++++++++++++++++++++++++++++++-
|
||||
6 files changed, 369 insertions(+), 1 deletion(-)
|
||||
create mode 100644 device_mapper/raid/raid_parser.c
|
||||
create mode 100644 device_mapper/raid/target.h
|
||||
|
||||
diff --git a/device_mapper/Makefile b/device_mapper/Makefile
|
||||
index b1aa53c36..4dfcd4f12 100644
|
||||
--- a/device_mapper/Makefile
|
||||
+++ b/device_mapper/Makefile
|
||||
@@ -25,6 +25,7 @@ DEVICE_MAPPER_SOURCE=\
|
||||
device_mapper/libdm-targets.c \
|
||||
device_mapper/libdm-timestamp.c \
|
||||
device_mapper/mm/pool.c \
|
||||
+ device_mapper/raid/raid_parser.c \
|
||||
device_mapper/regex/matcher.c \
|
||||
device_mapper/regex/parse_rx.c \
|
||||
device_mapper/regex/ttree.c \
|
||||
diff --git a/device_mapper/all.h b/device_mapper/all.h
|
||||
index 91c085e76..97279c10b 100644
|
||||
--- a/device_mapper/all.h
|
||||
+++ b/device_mapper/all.h
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include "base/data-struct/list.h"
|
||||
#include "base/data-struct/hash.h"
|
||||
+#include "raid/target.h"
|
||||
#include "vdo/target.h"
|
||||
|
||||
#include <inttypes.h>
|
||||
diff --git a/device_mapper/raid/raid_parser.c b/device_mapper/raid/raid_parser.c
|
||||
new file mode 100644
|
||||
index 000000000..adef7bb6c
|
||||
--- /dev/null
|
||||
+++ b/device_mapper/raid/raid_parser.c
|
||||
@@ -0,0 +1,164 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2024 Red Hat, Inc. All rights reserved.
|
||||
+ *
|
||||
+ * This file is part of the device-mapper userspace tools.
|
||||
+ *
|
||||
+ * This copyrighted material is made available to anyone wishing to use,
|
||||
+ * modify, copy, or redistribute it subject to the terms and conditions
|
||||
+ * of the GNU Lesser General Public License v.2.1.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU Lesser General Public License
|
||||
+ * along with this program; if not, write to the Free Software Foundation,
|
||||
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
+ */
|
||||
+
|
||||
+/*
|
||||
+ * Support counting number of failed device bits in dm-raid superblock bit arrays or clear them out.
|
||||
+ */
|
||||
+
|
||||
+#include "device_mapper/misc/dmlib.h"
|
||||
+#include "device_mapper/all.h"
|
||||
+#include "device_mapper/raid/target.h"
|
||||
+#include <fcntl.h>
|
||||
+#include <unistd.h>
|
||||
+
|
||||
+/* Copied/derived from kernel's drivers/md/dm-raid.c so this is prone to out-of-sync (factor out to header file?). */
|
||||
+#define MAX_RAID_DEVICES 253 /* md-raid kernel limit? */
|
||||
+#define UINT64_BITS (sizeof(uint64_t) * 8)
|
||||
+#define DISKS_ARRAY_ELEMS ((MAX_RAID_DEVICES + (UINT64_BITS - 1)) / UINT64_BITS)
|
||||
+#define DM_RAID_SB_MAGIC 0x446D5264 /* "DmRd" */
|
||||
+#define FEATURE_FLAG_SUPPORTS_V190 0x1 /* Supports extended superblock */
|
||||
+
|
||||
+/* RAID superblock at beginning of rmeta SubLVs trimmed down to mandatory members. */
|
||||
+struct dm_raid_superblock {
|
||||
+ __le32 magic; /* "DmRd" */
|
||||
+ __le32 compat_features; /* Used to indicate compatible features (like 1.9.0 ondisk metadata extension) */
|
||||
+ __le32 dummy[4];
|
||||
+ __le64 failed_devices; /* Pre 1.9.0 part of bit field of devices to */
|
||||
+ /* indicate device failures (see extension below) */
|
||||
+ __le32 dummy1[7];
|
||||
+
|
||||
+ /********************************************************************
|
||||
+ * BELOW FOLLOW V1.9.0 EXTENSIONS TO THE PRISTINE SUPERBLOCK FORMAT!!!
|
||||
+ *
|
||||
+ * FEATURE_FLAG_SUPPORTS_V190 in the compat_features member indicates that those exist
|
||||
+ */
|
||||
+ __le32 flags; /* Flags defining array states for reshaping */
|
||||
+ __le32 dummy2[14];
|
||||
+ __le64 extended_failed_devices[DISKS_ARRAY_ELEMS - 1];
|
||||
+
|
||||
+ __le32 dummy3;
|
||||
+ /* Always set rest up to logical block size to 0 when writing ... */
|
||||
+} __packed;
|
||||
+/* END: Copied from ... */
|
||||
+
|
||||
+/* Superblock I/O buffer size to be able to Cope with 4K native devices... */
|
||||
+#define SB_BUFSZ 4096
|
||||
+
|
||||
+static size_t _get_sb_size(const struct dm_raid_superblock *sb)
|
||||
+{
|
||||
+ return (FEATURE_FLAG_SUPPORTS_V190 & le32toh(sb->compat_features)) ?
|
||||
+ sizeof(*sb) : ((char *) &sb->flags - (char *) sb);
|
||||
+}
|
||||
+
|
||||
+static uint32_t _hweight64(__le64 v)
|
||||
+{
|
||||
+ uint32_t r = 0;
|
||||
+
|
||||
+ while (v) {
|
||||
+ r += v & 1;
|
||||
+ v >>= 1;
|
||||
+ }
|
||||
+
|
||||
+ return r;
|
||||
+}
|
||||
+
|
||||
+static uint32_t _hweight_failed(struct dm_raid_superblock *sb)
|
||||
+{
|
||||
+ uint32_t r = _hweight64(sb->failed_devices);
|
||||
+
|
||||
+ if (_get_sb_size(sb) == sizeof(*sb)) {
|
||||
+ size_t i = DM_ARRAY_SIZE(sb->extended_failed_devices);
|
||||
+
|
||||
+ while (i--)
|
||||
+ r = max(r, _hweight64(sb->extended_failed_devices[i]));
|
||||
+ }
|
||||
+
|
||||
+ return r;
|
||||
+}
|
||||
+
|
||||
+static void _clear_failed_devices(struct dm_raid_superblock *sb)
|
||||
+{
|
||||
+
|
||||
+ sb->failed_devices = 0;
|
||||
+
|
||||
+ if (_get_sb_size(sb) == sizeof(*sb))
|
||||
+ memset(sb->extended_failed_devices, 0, sizeof(sb->extended_failed_devices));
|
||||
+}
|
||||
+
|
||||
+static int _count_or_clear_failed_devices(const char *dev_path, bool clear, uint32_t *nr_failed)
|
||||
+{
|
||||
+ struct dm_raid_superblock *sb = NULL;
|
||||
+ size_t sz;
|
||||
+ int fd, r = 0;
|
||||
+
|
||||
+ if (posix_memalign((void *) &sb, SB_BUFSZ, SB_BUFSZ)) {
|
||||
+ log_sys_error("Failed to allocate RAID superblock buffer", dev_path);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ fd = open(dev_path, O_EXCL | ((clear) ? O_RDWR : O_RDONLY) | O_DIRECT);
|
||||
+ if (fd < 0) {
|
||||
+ log_sys_error("Failed to open RAID metadata volume", dev_path);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (read(fd, sb, SB_BUFSZ) != SB_BUFSZ) {
|
||||
+ log_sys_error("Failed to read RAID metadata volume", dev_path);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ /* FIXME: big endian??? */
|
||||
+ if (sb->magic != htobe32(DM_RAID_SB_MAGIC)) {
|
||||
+ log_error("No RAID signature on %s.", dev_path);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (nr_failed)
|
||||
+ *nr_failed = _hweight_failed(sb);
|
||||
+
|
||||
+ if (clear) {
|
||||
+ if (lseek(fd, 0, SEEK_SET) < 0) {
|
||||
+ log_sys_error("Failed to seek RAID metadata volume", dev_path);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ sz = _get_sb_size(sb);
|
||||
+ memset((void *)((char *) sb + sz), 0, SB_BUFSZ - sz);
|
||||
+ _clear_failed_devices(sb);
|
||||
+ if (write(fd, sb, SB_BUFSZ) != SB_BUFSZ) {
|
||||
+ log_sys_error("Failed to clear RAID metadata volume", dev_path);
|
||||
+ goto out;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ r = 1;
|
||||
+
|
||||
+out:
|
||||
+ if ((fd >= 0) && close(fd))
|
||||
+ log_sys_debug("close", dev_path);
|
||||
+
|
||||
+ free(sb);
|
||||
+
|
||||
+ return r;
|
||||
+}
|
||||
+
|
||||
+int dm_raid_count_failed_devices(const char *dev_path, uint32_t *nr_failed)
|
||||
+{
|
||||
+ return _count_or_clear_failed_devices(dev_path, false, nr_failed);
|
||||
+}
|
||||
+
|
||||
+int dm_raid_clear_failed_devices(const char *dev_path, uint32_t *nr_failed)
|
||||
+{
|
||||
+ return _count_or_clear_failed_devices(dev_path, true, nr_failed);
|
||||
+}
|
||||
diff --git a/device_mapper/raid/target.h b/device_mapper/raid/target.h
|
||||
new file mode 100644
|
||||
index 000000000..3e3ec024c
|
||||
--- /dev/null
|
||||
+++ b/device_mapper/raid/target.h
|
||||
@@ -0,0 +1,23 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2024 Red Hat, Inc. All rights reserved.
|
||||
+ *
|
||||
+ * This file is part of the device-mapper userspace tools.
|
||||
+ *
|
||||
+ * This copyrighted material is made available to anyone wishing to use,
|
||||
+ * modify, copy, or redistribute it subject to the terms and conditions
|
||||
+ * of the GNU Lesser General Public License v.2.1.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU Lesser General Public License
|
||||
+ * along with this program; if not, write to the Free Software Foundation,
|
||||
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
+ */
|
||||
+
|
||||
+#ifndef DEVICE_MAPPER_RAID_TARGET_H
|
||||
+#define DEVICE_MAPPER_RAID_TARGET_H
|
||||
+
|
||||
+#include <stdint.h>
|
||||
+
|
||||
+int dm_raid_count_failed_devices(const char *dev_path, uint32_t *nr_failed);
|
||||
+int dm_raid_clear_failed_devices(const char *dev_path, uint32_t *nr_failed);
|
||||
+
|
||||
+#endif
|
||||
diff --git a/lib/activate/activate.h b/lib/activate/activate.h
|
||||
index bd30e2655..155936135 100644
|
||||
--- a/lib/activate/activate.h
|
||||
+++ b/lib/activate/activate.h
|
||||
@@ -197,6 +197,8 @@ int lv_raid_mismatch_count(const struct logical_volume *lv, uint64_t *cnt);
|
||||
int lv_raid_sync_action(const struct logical_volume *lv, char **sync_action);
|
||||
int lv_raid_message(const struct logical_volume *lv, const char *msg);
|
||||
int lv_raid_status(const struct logical_volume *lv, struct lv_status_raid **status);
|
||||
+int lv_raid_clear_failed_devices(const struct logical_volume *lv);
|
||||
+int lv_raid_count_failed_devices(const struct logical_volume *lv, uint32_t *failed_cnt);
|
||||
int lv_writecache_message(const struct logical_volume *lv, const char *msg);
|
||||
int lv_cache_status(const struct logical_volume *cache_lv,
|
||||
struct lv_status_cache **status);
|
||||
diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c
|
||||
index eb4a2eb45..2a78a0bec 100644
|
||||
--- a/lib/metadata/raid_manip.c
|
||||
+++ b/lib/metadata/raid_manip.c
|
||||
@@ -3242,7 +3242,7 @@ static int _raid_leg_degraded(struct lv_segment *raid_seg, uint32_t s)
|
||||
_sublv_is_degraded(seg_metalv(raid_seg, s))));
|
||||
}
|
||||
|
||||
-/* Return failed component SubLV count for @lv. */
|
||||
+/* Return failed component SubLV pair count for @lv. */
|
||||
static uint32_t _lv_get_nr_failed_components(const struct logical_volume *lv)
|
||||
{
|
||||
uint32_t r = 0, s;
|
||||
@@ -7328,6 +7328,183 @@ int lv_raid_remove_missing(struct logical_volume *lv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Count number of failed device bits in dm-raid superblock bit arrays -or- clear them out.
|
||||
+ *
|
||||
+ * If any failed devices, return != 0 maximum of failed SubLVs and parity_devs so that the
|
||||
+ * caller will ask to clear and try activation of the RaidLV unless more than parity_devs
|
||||
+ * component device pairs (rmeta and rimage) are still failed. This'll allow early exit
|
||||
+ * in the caller preventing MD kernel rejection to activate the RAID array with > parity_devs
|
||||
+ * failed component device pairs.
|
||||
+ */
|
||||
+static int _count_or_clear_failed_devices_bits(struct logical_volume *meta_lv,
|
||||
+ bool clear, uint32_t *nr_failed)
|
||||
+{
|
||||
+ char *meta_path = lv_dmpath_dup(meta_lv->vg->cmd->mem, meta_lv);
|
||||
+
|
||||
+ if (!meta_path) {
|
||||
+ log_error("Failed to build device path for %s.",
|
||||
+ display_lvname(meta_lv));
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (!clear) /* only counting */
|
||||
+ return dm_raid_count_failed_devices(meta_path, nr_failed);
|
||||
+
|
||||
+ return dm_raid_clear_failed_devices(meta_path, nr_failed);
|
||||
+}
|
||||
+
|
||||
+/* Count or clear failed devices bits in RAID superblocks for
|
||||
+ * recurred transiently failed component SubLV pairs. */
|
||||
+static int _raid_count_or_clear_failed_devices(const struct logical_volume *lv,
|
||||
+ bool clear, uint32_t *failed_devices)
|
||||
+{
|
||||
+ uint32_t nr_failed = 0, nr_failed_tmp = 0, failed_sublvs = 0, s;
|
||||
+ struct lv_segment *raid_seg = first_seg(lv);
|
||||
+ struct logical_volume *meta_lv;
|
||||
+ const char *str;
|
||||
+ int r = 1, cleared_devs = 0;
|
||||
+
|
||||
+ /* Prevent bogus use. */
|
||||
+ if (!seg_is_raid_with_meta(raid_seg)) {
|
||||
+ log_error("%s is not a RaidLV with metadata.", display_lvname(lv));
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ failed_sublvs = _lv_get_nr_failed_components(lv);
|
||||
+
|
||||
+ if (clear && (failed_sublvs > raid_seg->segtype->parity_devs)) {
|
||||
+ log_error("Can't clear transiently failed devices on still failed %s.",
|
||||
+ display_lvname(lv));
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (!raid_seg->meta_areas) {
|
||||
+ log_error(INTERNAL_ERROR "Missing metadata areas on %s!", display_lvname(lv));
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ /* Check if there isn't any meta LV already active */
|
||||
+ for (s = 0; s < raid_seg->area_count; s++) {
|
||||
+ if (_raid_leg_degraded(raid_seg, s))
|
||||
+ continue;
|
||||
+
|
||||
+ meta_lv = seg_metalv(raid_seg, s);
|
||||
+
|
||||
+ if (lv_is_active(meta_lv)) {
|
||||
+ /* DM table is in some unknown condition, aborting... */
|
||||
+ log_error("Can't %s failed devices with active %s metadata volume %s.",
|
||||
+ clear ? "clear" : "count",
|
||||
+ lvseg_name(raid_seg), display_lvname(meta_lv));
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Activate all non degraded meta LVs before count or clear */
|
||||
+ for (s = 0; s < raid_seg->area_count; s++) {
|
||||
+ meta_lv = seg_metalv(raid_seg, s);
|
||||
+
|
||||
+ if (_raid_leg_degraded(raid_seg, s)) {
|
||||
+ log_debug("Skipping activation of failed devices for degraded %s metadata volume %s.",
|
||||
+ lvseg_name(raid_seg), display_lvname(meta_lv));
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (!activate_lv(lv->vg->cmd, meta_lv)) {
|
||||
+ log_error("Failed to activate %s metadata volume %s.",
|
||||
+ lvseg_name(raid_seg), display_lvname(meta_lv));
|
||||
+ r = 0; /* how many can be counted... */
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Wait for meta activation. */
|
||||
+ if (!sync_local_dev_names(lv->vg->cmd))
|
||||
+ stack;
|
||||
+
|
||||
+ for (s = 0; s < raid_seg->area_count; s++) {
|
||||
+ meta_lv = seg_metalv(raid_seg, s);
|
||||
+
|
||||
+ if (_raid_leg_degraded(raid_seg, s)) {
|
||||
+ if (clear)
|
||||
+ log_debug("Skipping clear of failed devices for degraded %s metadata volume %s.",
|
||||
+ lvseg_name(raid_seg), display_lvname(meta_lv));
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (lv_is_active(meta_lv) &&
|
||||
+ !_count_or_clear_failed_devices_bits(meta_lv, clear,
|
||||
+ &nr_failed_tmp)) {
|
||||
+ log_error("Failed to %s failed device(s) in superblock of %s metadata volume %s.",
|
||||
+ clear ? "clear" : "count",
|
||||
+ lvseg_name(raid_seg), display_lvname(meta_lv));
|
||||
+ r = 0;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (nr_failed_tmp) {
|
||||
+ log_verbose("%s %u failed device(s) in superblock of %s metadata volume %s.",
|
||||
+ clear ? "Cleared" : "Counted", nr_failed_tmp,
|
||||
+ lvseg_name(raid_seg), display_lvname(meta_lv));
|
||||
+ cleared_devs++;
|
||||
+ }
|
||||
+
|
||||
+ if (nr_failed_tmp > nr_failed)
|
||||
+ nr_failed = nr_failed_tmp;
|
||||
+ }
|
||||
+
|
||||
+ /* Deactivate meta LVs */
|
||||
+ for (s = 0; s < raid_seg->area_count; s++) {
|
||||
+ if (_raid_leg_degraded(raid_seg, s))
|
||||
+ continue;
|
||||
+
|
||||
+ if (!deactivate_lv(lv->vg->cmd, seg_metalv(raid_seg, s))) {
|
||||
+ stack;
|
||||
+ r = 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (clear) {
|
||||
+ if (!failed_sublvs)
|
||||
+ str = "fully operational";
|
||||
+ else if (failed_sublvs <= raid_seg->segtype->parity_devs)
|
||||
+ str = "degraded";
|
||||
+ else
|
||||
+ str = "still failed";
|
||||
+
|
||||
+ log_print_unless_silent("The %s volume %s is %s with %u transiently failed device(s).",
|
||||
+ lvseg_name(raid_seg), display_lvname(lv), str,
|
||||
+ nr_failed - failed_sublvs);
|
||||
+
|
||||
+ if (r && cleared_devs &&
|
||||
+ (failed_sublvs <= raid_seg->segtype->parity_devs))
|
||||
+ /* TODO: maybe we want to activate RAID volume here ? */
|
||||
+ log_print_unless_silent("Volume has been restored after clearing %u superblocks(s). Once online please check its content.",
|
||||
+ cleared_devs);
|
||||
+ }
|
||||
+
|
||||
+ if (failed_devices)
|
||||
+ *failed_devices = max(failed_sublvs, raid_seg->segtype->parity_devs);
|
||||
+
|
||||
+ return r;
|
||||
+}
|
||||
+
|
||||
+/* Clear failed device bits in RAID superblocks for recurred
|
||||
+ * transiently failed component SubLV pairs. */
|
||||
+int lv_raid_clear_failed_devices(const struct logical_volume *lv)
|
||||
+{
|
||||
+ return _raid_count_or_clear_failed_devices(lv, true, NULL);
|
||||
+}
|
||||
+
|
||||
+/* Count failed device bits in RAID superblocks for recurred
|
||||
+ * transiently failed component SubLV pairs.
|
||||
+ *
|
||||
+ * On success, @failed_cnt contains the current number.
|
||||
+ */
|
||||
+int lv_raid_count_failed_devices(const struct logical_volume *lv, uint32_t *failed_cnt)
|
||||
+{
|
||||
+ return _raid_count_or_clear_failed_devices(lv, false, failed_cnt);
|
||||
+}
|
||||
+
|
||||
/* Return 1 if a partial raid LV can be activated redundantly */
|
||||
static int _partial_raid_lv_is_redundant(const struct logical_volume *lv)
|
||||
{
|
||||
--
|
||||
2.49.0
|
||||
|
||||
@ -0,0 +1,54 @@
|
||||
From 4659eb9d2a7b58a9b199d7cf2ccaaf32d6605a76 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Rajnoha <prajnoha@redhat.com>
|
||||
Date: Wed, 9 Jul 2025 12:48:48 +0200
|
||||
Subject: [PATCH 10/47] udev: fix autoactivation on top of loop dev PVs
|
||||
|
||||
We already check loop devices for LVM_LOOP_PV_ACTIVATED="1" in udev
|
||||
rules to see if have executed pvscan before. If that is the case, we
|
||||
don't want to execute it again to avoid VG reactivation.
|
||||
|
||||
However, the rules missed the IMPORT{db}="LVM_LOOP_PV_ACTIVATED" rule
|
||||
to actually get the value already stored in udev db from previous event.
|
||||
As a result, the pvscan executed on each CHANGE udev event, hence the
|
||||
VG autoactivation triggered each time as well.
|
||||
|
||||
Fix this by adding the missing IMPORT{db}="LVM_LOOP_PV_ACTIVATED" rule
|
||||
(just like we already do for MD devices).
|
||||
|
||||
Note: Keep the behavior for ADD events. That is, we still want the
|
||||
autoactivation to trigger each time, otherwise coldplug will not work
|
||||
(again, we have the same principle used for MD devices).
|
||||
|
||||
(cherry picked from commit bd26e768efa534ba95f801c411a2a9581992a993)
|
||||
---
|
||||
WHATS_NEW | 4 ++++
|
||||
udev/69-dm-lvm.rules.in | 1 +
|
||||
2 files changed, 5 insertions(+)
|
||||
|
||||
diff --git a/WHATS_NEW b/WHATS_NEW
|
||||
index 635651863..e8db60d53 100644
|
||||
--- a/WHATS_NEW
|
||||
+++ b/WHATS_NEW
|
||||
@@ -1,3 +1,7 @@
|
||||
+Version 2.03.34 -
|
||||
+==================
|
||||
+ Fix autoactivation on top of loop dev PVs to trigger once for change uevents.
|
||||
+
|
||||
Version 2.03.33 - 27th June 2025
|
||||
================================
|
||||
Various spelling, grammar, formatting, test, and build script improvements.
|
||||
diff --git a/udev/69-dm-lvm.rules.in b/udev/69-dm-lvm.rules.in
|
||||
index f7a6eef8f..adcf63453 100644
|
||||
--- a/udev/69-dm-lvm.rules.in
|
||||
+++ b/udev/69-dm-lvm.rules.in
|
||||
@@ -52,6 +52,7 @@ GOTO="lvm_end"
|
||||
# Loop device:
|
||||
LABEL="next"
|
||||
KERNEL!="loop[0-9]*", GOTO="next"
|
||||
+IMPORT{db}="LVM_LOOP_PV_ACTIVATED"
|
||||
ACTION=="add", ENV{LVM_LOOP_PV_ACTIVATED}=="1", GOTO="lvm_scan"
|
||||
ACTION=="change", ENV{LVM_LOOP_PV_ACTIVATED}!="1", TEST=="loop/backing_file", ENV{LVM_LOOP_PV_ACTIVATED}="1", GOTO="lvm_scan"
|
||||
GOTO="lvm_end"
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@ -0,0 +1,81 @@
|
||||
From 6ca7cd60fd6afcc0f95dfe20d33044a319621b6d Mon Sep 17 00:00:00 2001
|
||||
From: Peter Rajnoha <prajnoha@redhat.com>
|
||||
Date: Fri, 18 Jul 2025 15:06:36 +0200
|
||||
Subject: [PATCH 11/47] lv_manip.c: fix lvresize corruption in LV->crypt->FS
|
||||
stack if near crypt min size limit
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
If we have LV->crypt->FS stack, check that the adjustment for the crypt
|
||||
data offset will left space for the crypt data itself. Fix possible underflow.
|
||||
|
||||
Example:
|
||||
|
||||
❯ lvs -o name,size vg/lvol0
|
||||
lv_name lv_size
|
||||
lvol0 124.00m
|
||||
|
||||
❯ lsblk /dev/vg/lvol0
|
||||
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
|
||||
vg-lvol0 252:2 0 124M 0 lvm
|
||||
└─a 252:4 0 108M 0 crypt
|
||||
|
||||
Before this patch (the incorrect resulting underflowed file system size after adjustment
|
||||
for crypt data offset, crypt data then severed by the LV resize without proper
|
||||
crypt resize beforehand):
|
||||
|
||||
❯ lvreduce --yes --resizefs -L -123M vg/lvol0
|
||||
Rounding size to boundary between physical extents: 120.00 MiB.
|
||||
Checking crypt device /dev/dm-4 on LV vg/lvol0.
|
||||
File system size 18446744073696968704b is adjusted for crypt data offset 16777216b.
|
||||
File system ext4+crypto_LUKS found on vg/lvol0.
|
||||
File system size (108.00 MiB) is smaller than the requested size (<16.00 EiB).
|
||||
File system reduce is not needed, skipping.
|
||||
crypt device is already reduced to 113246208 bytes.
|
||||
Size of logical volume vg/lvol0 changed from 124.00 MiB (31 extents) to 4.00 MiB (1 extents).
|
||||
Logical volume vg/lvol0 successfully resized.
|
||||
|
||||
With this patch applied:
|
||||
|
||||
❯ lvreduce --yes --resizefs -L -123M vg/lvol0
|
||||
Rounding size to boundary between physical extents: 120.00 MiB.
|
||||
Checking crypt device /dev/dm-4 on LV vg/lvol0.
|
||||
Crypt header requires 16.00 MiB, not enough space left for crypt data.
|
||||
|
||||
(cherry picked from commit 5da3676ff3901fd099dcdd2bd7478fa9ea4f54dc)
|
||||
---
|
||||
WHATS_NEW | 1 +
|
||||
lib/metadata/lv_manip.c | 5 +++++
|
||||
2 files changed, 6 insertions(+)
|
||||
|
||||
diff --git a/WHATS_NEW b/WHATS_NEW
|
||||
index e8db60d53..723638042 100644
|
||||
--- a/WHATS_NEW
|
||||
+++ b/WHATS_NEW
|
||||
@@ -1,5 +1,6 @@
|
||||
Version 2.03.34 -
|
||||
==================
|
||||
+ Fix lvresize corruption in LV->crypt->FS stack if near crypt min size limit.
|
||||
Fix autoactivation on top of loop dev PVs to trigger once for change uevents.
|
||||
|
||||
Version 2.03.33 - 27th June 2025
|
||||
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
|
||||
index 193b1f403..577ffd0b3 100644
|
||||
--- a/lib/metadata/lv_manip.c
|
||||
+++ b/lib/metadata/lv_manip.c
|
||||
@@ -6478,6 +6478,11 @@ static int _fs_reduce(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
* 2MB for LUKS1 and 16MB for LUKS2.)
|
||||
*/
|
||||
if (fsinfo.needs_crypt) {
|
||||
+ if (fsinfo.crypt_offset_bytes >= fsinfo.new_size_bytes) {
|
||||
+ log_error("Crypt header requires %s, not enough space left for crypt data.",
|
||||
+ display_size(cmd, fsinfo.crypt_offset_bytes >> SECTOR_SHIFT));
|
||||
+ goto out;
|
||||
+ }
|
||||
fsinfo.new_size_bytes -= fsinfo.crypt_offset_bytes;
|
||||
log_print_unless_silent("File system size %llub is adjusted for crypt data offset %ub.",
|
||||
(unsigned long long)fsinfo.new_size_bytes, fsinfo.crypt_offset_bytes);
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@ -1,64 +0,0 @@
|
||||
From 4fbda3d36dc02bb682dd8579c8a4ebfc692cbfe3 Mon Sep 17 00:00:00 2001
|
||||
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||
Date: Fri, 31 Jan 2025 21:45:57 +0100
|
||||
Subject: [PATCH 11/14] lvconvert: allow clearing superblocks
|
||||
|
||||
(cherry picked from commit 0a8f560c759de0f3335213896c2a3383009c7206)
|
||||
---
|
||||
tools/lvconvert.c | 38 ++++++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 36 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
|
||||
index 72ef74cef..270bae7d0 100644
|
||||
--- a/tools/lvconvert.c
|
||||
+++ b/tools/lvconvert.c
|
||||
@@ -3874,10 +3874,44 @@ static int _lvconvert_repair_pvs_raid(struct cmd_context *cmd, struct logical_vo
|
||||
{
|
||||
struct dm_list *failed_pvs;
|
||||
int do_it;
|
||||
+ uint32_t failed_cnt = 0;
|
||||
+ struct lv_segment *raid_seg;
|
||||
|
||||
if (!lv_is_active(lv_lock_holder(lv))) {
|
||||
- log_error("%s must be active to perform this operation.", display_lvname(lv));
|
||||
- return 0;
|
||||
+ if (!lv_raid_count_failed_devices(lv, &failed_cnt))
|
||||
+ return_0;
|
||||
+
|
||||
+ if (!failed_cnt) {
|
||||
+ log_error("Logical volume %s must be active to perform this operation.",
|
||||
+ display_lvname(lv));
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ raid_seg = first_seg(lv);
|
||||
+
|
||||
+ if (failed_cnt > raid_seg->segtype->parity_devs) {
|
||||
+ log_error("Can't clear %u failed superblock(s) in %s volume %s.",
|
||||
+ failed_cnt, lvseg_name(raid_seg), display_lvname(lv));
|
||||
+ log_print_unless_silent("The maximum number of degraded devices allowed is %u.",
|
||||
+ raid_seg->segtype->parity_devs);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (!arg_count(cmd, yes_ARG) &&
|
||||
+ yes_no_prompt("Attempt to clear %u transiently failed %s superblock(s) in %s? [y/n]: ",
|
||||
+ failed_cnt, lvseg_name(raid_seg), display_lvname(lv)) == 'n') {
|
||||
+ log_error("Logical volume %s with %u transiently failed %s superblock(s) NOT repaired.",
|
||||
+ display_lvname(lv), failed_cnt, lvseg_name(raid_seg));
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ log_verbose("Clearing %u transiently failed %s superblock(s) in %s.",
|
||||
+ failed_cnt, lvseg_name(raid_seg), display_lvname(lv));
|
||||
+
|
||||
+ if (!lv_raid_clear_failed_devices(lv))
|
||||
+ return_0;
|
||||
+
|
||||
+ return 1;
|
||||
}
|
||||
|
||||
lv_check_transient(lv); /* TODO check this in lib for all commands? */
|
||||
--
|
||||
2.49.0
|
||||
|
||||
@ -0,0 +1,32 @@
|
||||
From 6d7837dc2b93a51bfdad7c796d2b8e3f7fe9f938 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Rajnoha <prajnoha@redhat.com>
|
||||
Date: Mon, 21 Jul 2025 13:40:30 +0200
|
||||
Subject: [PATCH 12/47] device_id: always log_error on device ids write error
|
||||
|
||||
(cherry picked from commit 03e3b27ba094cc6e58113713a0d36a8b3190a2f3)
|
||||
---
|
||||
lib/device/device_id.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
|
||||
index a3f341bfc..76165559f 100644
|
||||
--- a/lib/device/device_id.c
|
||||
+++ b/lib/device/device_id.c
|
||||
@@ -1730,12 +1730,12 @@ int device_ids_write(struct cmd_context *cmd)
|
||||
log_sys_debug("unlink", tmppath);
|
||||
|
||||
if (!(fp = fopen(tmppath, "w+"))) {
|
||||
- log_warn("Cannot open to write %s.", tmppath);
|
||||
+ log_error("Cannot open to write %s.", tmppath);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((dir_fd = open(dirpath, O_RDONLY)) < 0) {
|
||||
- log_sys_debug("open", dirpath);
|
||||
+ log_sys_error("open", dirpath);
|
||||
goto out;
|
||||
}
|
||||
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@ -1,107 +0,0 @@
|
||||
From 7ef2e32ab91194abfcacb96eae2577cf19e66123 Mon Sep 17 00:00:00 2001
|
||||
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||
Date: Sun, 2 Feb 2025 19:21:05 +0100
|
||||
Subject: [PATCH 12/14] test: check raid superblock clearing
|
||||
|
||||
(cherry picked from commit 0cafb18978d4a720845c2830fcff129ce9b79327)
|
||||
---
|
||||
test/shell/lvconvert-repair-raid5.sh | 62 +++++++++++++++++++++-------
|
||||
1 file changed, 47 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/test/shell/lvconvert-repair-raid5.sh b/test/shell/lvconvert-repair-raid5.sh
|
||||
index a14d90be9..66485c536 100644
|
||||
--- a/test/shell/lvconvert-repair-raid5.sh
|
||||
+++ b/test/shell/lvconvert-repair-raid5.sh
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
-# Copyright (C) 2024 Red Hat, Inc. All rights reserved.
|
||||
+# Copyright (C) 2024-2025 Red Hat, Inc. All rights reserved.
|
||||
#
|
||||
# This copyrighted material is made available to anyone wishing to use,
|
||||
# modify, copy, or redistribute it subject to the terms and conditions
|
||||
@@ -24,17 +24,31 @@ SKIP_WITH_LVMPOLLD=1
|
||||
#
|
||||
aux have_raid 1 8 0 || skip
|
||||
|
||||
-aux prepare_vg 4
|
||||
-get_devs
|
||||
+aux prepare_vg 6
|
||||
|
||||
-#offset=$(get first_extent_sector "$dev1")
|
||||
|
||||
-# It's possible small raid arrays do have problems with reporting in-sync.
|
||||
-# So try bigger size
|
||||
-RAID_SIZE=8
|
||||
+lvcreate --type raid5 -i 5 -L8 -n $lv1 $vg
|
||||
+aux wait_for_sync $vg $lv1
|
||||
+
|
||||
+lvs -ao+devices $vg
|
||||
+
|
||||
+# fail 2 drives out of 4
|
||||
+aux error_dev "$dev2"
|
||||
+aux error_dev "$dev3"
|
||||
+
|
||||
+lvchange -an $vg
|
||||
+
|
||||
+aux enable_dev "$dev2"
|
||||
+aux enable_dev "$dev3"
|
||||
+
|
||||
+lvconvert --yes --repair $vg/$lv1 -v
|
||||
+
|
||||
+lvremove -f $vg
|
||||
|
||||
-# RAID1 transient failure check
|
||||
-lvcreate --type raid5 -i 3 -L $RAID_SIZE -n $lv1 $vg
|
||||
+
|
||||
+# Raid5 transient failure check
|
||||
+
|
||||
+lvcreate --type raid5 -i 3 -L8 -n $lv1 $vg
|
||||
aux wait_for_sync $vg $lv1
|
||||
|
||||
lvs -ao+devices $vg
|
||||
@@ -43,17 +57,35 @@ lvs -ao+devices $vg
|
||||
aux error_dev "$dev2"
|
||||
aux error_dev "$dev3"
|
||||
|
||||
+not lvconvert --yes --repair $vg/$lv1
|
||||
+
|
||||
# deactivate immediately
|
||||
lvchange -an $vg
|
||||
|
||||
+# Raid5 cannot activate with only 2 disks
|
||||
+not lvchange -ay $vg
|
||||
+
|
||||
+# also it cannot be repaired
|
||||
+not lvconvert --yes --repair $vg/$lv1
|
||||
+
|
||||
+# restore 1st. failed drive
|
||||
aux enable_dev "$dev2"
|
||||
+
|
||||
+# Raid5 should be now repairable
|
||||
+lvconvert --yes --repair $vg/$lv1
|
||||
+
|
||||
+# Raid5 volume is working now
|
||||
+lvchange -ay $vg
|
||||
+
|
||||
+# again deactivate
|
||||
+lvchange -an $vg
|
||||
+
|
||||
+# restore 2nd. missing drive
|
||||
aux enable_dev "$dev3"
|
||||
|
||||
-# ATM we are failing here with this kernel message:
|
||||
-#
|
||||
-# md/raid:mdX: Cannot continue operation (2/4 failed).
|
||||
-#
|
||||
-# Raid5 LV cannot be started any more
|
||||
-should lvchange -ay $vg
|
||||
+# still repairable
|
||||
+lvconvert --yes --repair $vg/$lv1
|
||||
+
|
||||
+lvchange -ay $vg
|
||||
|
||||
vgremove -ff $vg
|
||||
--
|
||||
2.49.0
|
||||
|
||||
@ -0,0 +1,48 @@
|
||||
From f697518550298ec4a571b72f0f6395b42e6fc85d Mon Sep 17 00:00:00 2001
|
||||
From: Peter Rajnoha <prajnoha@redhat.com>
|
||||
Date: Mon, 21 Jul 2025 13:41:32 +0200
|
||||
Subject: [PATCH 13/47] lvmdevices: return error if writing device ids fail for
|
||||
--delldev
|
||||
|
||||
(cherry picked from commit 1cd2f35655e79d880d28914998b738baa0be5c07)
|
||||
---
|
||||
tools/lvmdevices.c | 9 ++++++---
|
||||
1 file changed, 6 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/tools/lvmdevices.c b/tools/lvmdevices.c
|
||||
index fd766e102..d7d3af59b 100644
|
||||
--- a/tools/lvmdevices.c
|
||||
+++ b/tools/lvmdevices.c
|
||||
@@ -925,7 +925,8 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv)
|
||||
dev_del:
|
||||
dm_list_del(&du->list);
|
||||
free_du(du);
|
||||
- device_ids_write(cmd);
|
||||
+ if (!device_ids_write(cmd))
|
||||
+ goto_bad;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -967,7 +968,8 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv)
|
||||
|
||||
dm_list_del(&du->list);
|
||||
free_du(du);
|
||||
- device_ids_write(cmd);
|
||||
+ if (!device_ids_write(cmd))
|
||||
+ goto_bad;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1008,7 +1010,8 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv)
|
||||
}
|
||||
|
||||
free_du(du);
|
||||
- device_ids_write(cmd);
|
||||
+ if (!device_ids_write(cmd))
|
||||
+ goto_bad;
|
||||
goto out;
|
||||
}
|
||||
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@ -1,50 +0,0 @@
|
||||
From 63312cb3343d6370c89ab0ff4e93aa39aab25fa5 Mon Sep 17 00:00:00 2001
|
||||
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||
Date: Mon, 12 May 2025 15:05:46 +0200
|
||||
Subject: [PATCH 13/14] man: update raid man
|
||||
|
||||
Mention repair of transiently lost devices.
|
||||
|
||||
(cherry picked from commit 22364ce9b68b3a2e03819bfd8fdc569df584b7e2)
|
||||
---
|
||||
man/lvmraid.7_main | 17 ++++++++++++++++-
|
||||
1 file changed, 16 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/man/lvmraid.7_main b/man/lvmraid.7_main
|
||||
index 5b429a410..db8009d46 100644
|
||||
--- a/man/lvmraid.7_main
|
||||
+++ b/man/lvmraid.7_main
|
||||
@@ -434,7 +434,7 @@ found, run:
|
||||
# lvs -o name,raid_mismatch_count
|
||||
.EE
|
||||
.P
|
||||
-Also, if mismatches were found, the
|
||||
+Also, if mismatches were found, the
|
||||
.BR lvs (8)
|
||||
attr field will display the letter
|
||||
"m" (mismatch) in the 9th position, e.g.
|
||||
@@ -862,6 +862,21 @@ those PVs can be reconstructed with:
|
||||
The rebuild option can be repeated with different PVs to replace the data
|
||||
on multiple PVs.
|
||||
.
|
||||
+.SS Reactivating arrays after temporary device loss
|
||||
+
|
||||
+When a RAID array loses a critical number of devices,
|
||||
+causing it to lose its ability to function reliably,
|
||||
+the array will stop and require repair.
|
||||
+
|
||||
+Initiate repair process with this command:
|
||||
+.P
|
||||
+.B lvconvert --repair
|
||||
+.I LV
|
||||
+.P
|
||||
+If the previously unavailable devices become accessible again,
|
||||
+this repair process will update their metadata and
|
||||
+the RAID array can be reactivated.
|
||||
+.
|
||||
.SH DATA INTEGRITY
|
||||
.
|
||||
The device mapper integrity target can be used in combination with RAID
|
||||
--
|
||||
2.49.0
|
||||
|
||||
@ -1,25 +1,24 @@
|
||||
From 14f920c81c9499bcfcc0414c494f7abc0b9f3d58 Mon Sep 17 00:00:00 2001
|
||||
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||
Date: Mon, 12 May 2025 15:07:15 +0200
|
||||
Subject: [PATCH 14/14] WHATS_NEW: update
|
||||
From 7f6e08eb6d9dfdf82c50151b832c3f5663ea5b9b Mon Sep 17 00:00:00 2001
|
||||
From: Peter Rajnoha <prajnoha@redhat.com>
|
||||
Date: Tue, 22 Jul 2025 09:46:39 +0200
|
||||
Subject: [PATCH 14/47] WHATS_NEW: update
|
||||
|
||||
(cherry picked from commit 759d1bfe113ca7a80248821808d13ed9e011201c)
|
||||
(cherry picked from commit 986ff7b9cdd6a4af1d79706c80e9660c4ccbf423)
|
||||
---
|
||||
WHATS_NEW | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
WHATS_NEW | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/WHATS_NEW b/WHATS_NEW
|
||||
index 4d8b59681..c9af7be6e 100644
|
||||
index 723638042..41fea1a7a 100644
|
||||
--- a/WHATS_NEW
|
||||
+++ b/WHATS_NEW
|
||||
@@ -1,3 +1,7 @@
|
||||
+Version 2.03.33 -
|
||||
+==================
|
||||
+ Repair raid arrays with transiently lost devices.
|
||||
+
|
||||
Version 2.03.32 - 05th May 2025
|
||||
===============================
|
||||
Lvconvert vdopool conversion propperly validates acceptable LVs.
|
||||
@@ -1,5 +1,6 @@
|
||||
Version 2.03.34 -
|
||||
==================
|
||||
+ Fix lvmdevices --deldev/--delpvid to error out if devices file not writeable.
|
||||
Fix lvresize corruption in LV->crypt->FS stack if near crypt min size limit.
|
||||
Fix autoactivation on top of loop dev PVs to trigger once for change uevents.
|
||||
|
||||
--
|
||||
2.49.0
|
||||
2.51.0
|
||||
|
||||
|
||||
@ -0,0 +1,103 @@
|
||||
From cc809a01ac3059fa613473ce45bc75426ab000ad Mon Sep 17 00:00:00 2001
|
||||
From: Peter Rajnoha <prajnoha@redhat.com>
|
||||
Date: Wed, 23 Jul 2025 09:17:36 +0200
|
||||
Subject: [PATCH 15/47] device_id: log_warn instead of log_error in
|
||||
device_ids_write
|
||||
|
||||
It is not always the case that the whole command fails if
|
||||
device_ids_write fail so change all log_error to log_warn and let the
|
||||
caller decide.
|
||||
|
||||
(cherry picked from commit 80144223e700703f76267b8d033e2d7d04156ee9)
|
||||
---
|
||||
lib/device/device_id.c | 20 ++++++++++----------
|
||||
1 file changed, 10 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/lib/device/device_id.c b/lib/device/device_id.c
|
||||
index 76165559f..4bb92cb09 100644
|
||||
--- a/lib/device/device_id.c
|
||||
+++ b/lib/device/device_id.c
|
||||
@@ -1730,12 +1730,12 @@ int device_ids_write(struct cmd_context *cmd)
|
||||
log_sys_debug("unlink", tmppath);
|
||||
|
||||
if (!(fp = fopen(tmppath, "w+"))) {
|
||||
- log_error("Cannot open to write %s.", tmppath);
|
||||
+ log_warn("WARNING: %s: cannot open for writing: %s.", tmppath, strerror(errno));
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((dir_fd = open(dirpath, O_RDONLY)) < 0) {
|
||||
- log_sys_error("open", dirpath);
|
||||
+ log_warn("WARNING: %s: cannot open directory: %s.", dirpath, strerror(errno));
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1748,7 +1748,7 @@ int device_ids_write(struct cmd_context *cmd)
|
||||
fb_size = names_len + 256 + (128 * dm_list_size(&cmd->use_devices));
|
||||
|
||||
if (!(fb = malloc(fb_size))) {
|
||||
- log_error("Failed to allocate buffer size %d for devices file.", fb_size);
|
||||
+ log_warn("Failed to allocate buffer size %d for devices file.", fb_size);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1762,7 +1762,7 @@ int device_ids_write(struct cmd_context *cmd)
|
||||
num = snprintf(fb + pos, len - pos, "HOSTNAME=%s\n", cmd->hostname);
|
||||
|
||||
if (num >= len - pos) {
|
||||
- log_error("Failed to write buffer for devices file content.");
|
||||
+ log_warn("Failed to write buffer for devices file content.");
|
||||
goto out;
|
||||
}
|
||||
pos += num;
|
||||
@@ -1772,7 +1772,7 @@ int device_ids_write(struct cmd_context *cmd)
|
||||
|
||||
num = snprintf(fb + pos, len - pos, "%s\n", version_buf);
|
||||
if (num >= len - pos) {
|
||||
- log_error("Failed to write buffer for devices file content.");
|
||||
+ log_warn("Failed to write buffer for devices file content.");
|
||||
goto out;
|
||||
}
|
||||
pos += num;
|
||||
@@ -1801,7 +1801,7 @@ int device_ids_write(struct cmd_context *cmd)
|
||||
du->idname ?: ".", devname, pvid);
|
||||
}
|
||||
if (num >= len - pos) {
|
||||
- log_error("Failed to write buffer for devices file content.");
|
||||
+ log_warn("Failed to write buffer for devices file content.");
|
||||
goto out;
|
||||
}
|
||||
pos += num;
|
||||
@@ -1820,17 +1820,17 @@ int device_ids_write(struct cmd_context *cmd)
|
||||
"# HASH=%u\n",
|
||||
cmd->name, cmd->device_ids_auto_import ? " (auto)" : "",
|
||||
getpid(), ctime(&t), hash)) < 0) {
|
||||
- log_error("Failed to write buffer for devices file content.");
|
||||
+ log_warn("Failed to write buffer for devices file content.");
|
||||
goto out;
|
||||
}
|
||||
fc[fc_bytes] = '\0';
|
||||
|
||||
if (fputs(fc, fp) < 0) {
|
||||
- log_error("Failed to write devices file header.");
|
||||
+ log_warn("Failed to write devices file header.");
|
||||
goto out;
|
||||
}
|
||||
if (fputs(fb, fp) < 0) {
|
||||
- log_error("Failed to write devices file.");
|
||||
+ log_warn("Failed to write devices file.");
|
||||
goto out;
|
||||
}
|
||||
if (fflush(fp) < 0)
|
||||
@@ -1845,7 +1845,7 @@ int device_ids_write(struct cmd_context *cmd)
|
||||
fp = NULL;
|
||||
|
||||
if (rename(tmppath, cmd->devices_file_path) < 0) {
|
||||
- log_error("Failed to replace devices file.");
|
||||
+ log_warn("WARNING: %s: failed to replace devices file: %s", cmd->devices_file_path, strerror(errno));
|
||||
goto out;
|
||||
}
|
||||
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@ -0,0 +1,97 @@
|
||||
From e845c1a99d660295735d6fd0dd5a048f3980fce7 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Rajnoha <prajnoha@redhat.com>
|
||||
Date: Wed, 23 Jul 2025 09:24:07 +0200
|
||||
Subject: [PATCH 16/47] lvmdevices: log_error when writing devices file fails
|
||||
|
||||
(cherry picked from commit d5abc55fcf31dbd8b52036340e085c9f7e8d61b2)
|
||||
---
|
||||
tools/lvmdevices.c | 25 +++++++++++++++++++------
|
||||
1 file changed, 19 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/tools/lvmdevices.c b/tools/lvmdevices.c
|
||||
index d7d3af59b..7f10038d4 100644
|
||||
--- a/tools/lvmdevices.c
|
||||
+++ b/tools/lvmdevices.c
|
||||
@@ -560,6 +560,7 @@ restart4:
|
||||
|
||||
int lvmdevices(struct cmd_context *cmd, int argc, char **argv)
|
||||
{
|
||||
+ static const char failed_to_write_devices_file_msg[] = "Failed to write devices file.";
|
||||
struct dm_list search_pvids;
|
||||
struct dm_list found_devs;
|
||||
struct dm_list scan_devs;
|
||||
@@ -752,8 +753,10 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv)
|
||||
|
||||
if (arg_is_set(cmd, update_ARG)) {
|
||||
if (update_needed || !dm_list_empty(&found_devs) || cmd->devices_file_hash_mismatch) {
|
||||
- if (!device_ids_write(cmd))
|
||||
+ if (!device_ids_write(cmd)) {
|
||||
+ log_error(failed_to_write_devices_file_msg);
|
||||
goto_bad;
|
||||
+ }
|
||||
log_print("Updated devices file to version %s", devices_file_version());
|
||||
} else {
|
||||
log_print("No update for devices file is needed.");
|
||||
@@ -835,8 +838,10 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv)
|
||||
|
||||
if (!device_id_add(cmd, dev, dev->pvid, deviceidtype, NULL, 1))
|
||||
goto_bad;
|
||||
- if (!device_ids_write(cmd))
|
||||
+ if (!device_ids_write(cmd)) {
|
||||
+ log_error(failed_to_write_devices_file_msg);
|
||||
goto_bad;
|
||||
+ }
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -884,8 +889,10 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv)
|
||||
if (!device_id_add(cmd, devl->dev, devl->dev->pvid, deviceidtype, NULL, 1))
|
||||
goto_bad;
|
||||
}
|
||||
- if (!device_ids_write(cmd))
|
||||
+ if (!device_ids_write(cmd)) {
|
||||
+ log_error(failed_to_write_devices_file_msg);
|
||||
goto_bad;
|
||||
+ }
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -925,8 +932,10 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv)
|
||||
dev_del:
|
||||
dm_list_del(&du->list);
|
||||
free_du(du);
|
||||
- if (!device_ids_write(cmd))
|
||||
+ if (!device_ids_write(cmd)) {
|
||||
+ log_error(failed_to_write_devices_file_msg);
|
||||
goto_bad;
|
||||
+ }
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -968,8 +977,10 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv)
|
||||
|
||||
dm_list_del(&du->list);
|
||||
free_du(du);
|
||||
- if (!device_ids_write(cmd))
|
||||
+ if (!device_ids_write(cmd)) {
|
||||
+ log_error(failed_to_write_devices_file_msg);
|
||||
goto_bad;
|
||||
+ }
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1010,8 +1021,10 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv)
|
||||
}
|
||||
|
||||
free_du(du);
|
||||
- if (!device_ids_write(cmd))
|
||||
+ if (!device_ids_write(cmd)) {
|
||||
+ log_error(failed_to_write_devices_file_msg);
|
||||
goto_bad;
|
||||
+ }
|
||||
goto out;
|
||||
}
|
||||
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@ -0,0 +1,56 @@
|
||||
From 5653b3e38962d81264dd45db1aad356f6f59dd6c Mon Sep 17 00:00:00 2001
|
||||
From: David Teigland <teigland@redhat.com>
|
||||
Date: Fri, 8 Aug 2025 14:06:24 -0500
|
||||
Subject: [PATCH 17/47] lvmlockd: --lockopt was mistakenly ignored when
|
||||
--nolocking was set
|
||||
|
||||
(cherry picked from commit 3dc5c3fc9e1dcbca8f74fa5e7df3e0750d66975a)
|
||||
---
|
||||
tools/lvmcmdline.c | 24 +++++++++++++-----------
|
||||
1 file changed, 13 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
|
||||
index 22ae1e3bb..ebb1b87c9 100644
|
||||
--- a/tools/lvmcmdline.c
|
||||
+++ b/tools/lvmcmdline.c
|
||||
@@ -2969,6 +2969,19 @@ static int _init_lvmlockd(struct cmd_context *cmd)
|
||||
if (use_lvmlockd)
|
||||
cmd->enable_hints = 0;
|
||||
|
||||
+ if (arg_is_set(cmd, lockopt_ARG)) {
|
||||
+ lockd_lockopt_get_flags(arg_str_value(cmd, lockopt_ARG, ""), &cmd->lockopt);
|
||||
+
|
||||
+ if (use_lvmlockd) {
|
||||
+ if (cmd->lockopt & LOCKOPT_SKIPLV)
|
||||
+ cmd->lockd_lv_disable = 1;
|
||||
+ if (cmd->lockopt & LOCKOPT_SKIPVG)
|
||||
+ cmd->lockd_vg_disable = 1;
|
||||
+ if (cmd->lockopt & LOCKOPT_SKIPGL)
|
||||
+ cmd->lockd_gl_disable = 1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (use_lvmlockd && arg_is_set(cmd, nolocking_ARG)) {
|
||||
/* --nolocking is only allowed with vgs/lvs/pvs commands */
|
||||
cmd->lockd_gl_disable = 1;
|
||||
@@ -2977,17 +2990,6 @@ static int _init_lvmlockd(struct cmd_context *cmd)
|
||||
return 1;
|
||||
}
|
||||
|
||||
- if (use_lvmlockd && arg_is_set(cmd, lockopt_ARG)) {
|
||||
- lockd_lockopt_get_flags(arg_str_value(cmd, lockopt_ARG, ""), &cmd->lockopt);
|
||||
-
|
||||
- if (cmd->lockopt & LOCKOPT_SKIPLV)
|
||||
- cmd->lockd_lv_disable = 1;
|
||||
- if (cmd->lockopt & LOCKOPT_SKIPVG)
|
||||
- cmd->lockd_vg_disable = 1;
|
||||
- if (cmd->lockopt & LOCKOPT_SKIPGL)
|
||||
- cmd->lockd_gl_disable = 1;
|
||||
- }
|
||||
-
|
||||
lvmlockd_disconnect(); /* start over when tool context is refreshed */
|
||||
lvmlockd_socket = getenv("LVM_LVMLOCKD_SOCKET");
|
||||
if (!lvmlockd_socket)
|
||||
--
|
||||
2.51.0
|
||||
|
||||
26
SOURCES/0018-sanlock-match-lm_lock_sanlock-prototype.patch
Normal file
26
SOURCES/0018-sanlock-match-lm_lock_sanlock-prototype.patch
Normal file
@ -0,0 +1,26 @@
|
||||
From a70dd84cfdd897a8b9d8cdddd98caaacaa1dff72 Mon Sep 17 00:00:00 2001
|
||||
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||
Date: Wed, 2 Jul 2025 11:46:20 +0200
|
||||
Subject: [PATCH 18/47] sanlock: match lm_lock_sanlock prototype
|
||||
|
||||
(cherry picked from commit 95c77bc922ec9867764ddd95df635444804c12ba)
|
||||
---
|
||||
daemons/lvmlockd/lvmlockd-internal.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/daemons/lvmlockd/lvmlockd-internal.h b/daemons/lvmlockd/lvmlockd-internal.h
|
||||
index 7999c2a03..df69824b6 100644
|
||||
--- a/daemons/lvmlockd/lvmlockd-internal.h
|
||||
+++ b/daemons/lvmlockd/lvmlockd-internal.h
|
||||
@@ -634,7 +634,7 @@ static inline int lm_add_resource_sanlock(struct lockspace *ls, struct resource
|
||||
|
||||
static inline int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||
struct val_blk *vb_out, int *retry, struct owner *owner,
|
||||
- int adopt_only, int adopt_ok)
|
||||
+ int adopt_only, int adopt_ok, int repair)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
From de5bc8c70577b3d7483c43ce373d233d9089a990 Mon Sep 17 00:00:00 2001
|
||||
From: David Teigland <teigland@redhat.com>
|
||||
Date: Tue, 1 Jul 2025 10:22:50 -0500
|
||||
Subject: [PATCH 19/47] lvmlockd-sanlock: fix struct pointer in release_rename
|
||||
|
||||
(cherry picked from commit 03a343dc9e49b164fe0d153b0b0dc815f18edd6e)
|
||||
---
|
||||
daemons/lvmlockd/lvmlockd-sanlock.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/daemons/lvmlockd/lvmlockd-sanlock.c b/daemons/lvmlockd/lvmlockd-sanlock.c
|
||||
index ce5953faf..80def0449 100644
|
||||
--- a/daemons/lvmlockd/lvmlockd-sanlock.c
|
||||
+++ b/daemons/lvmlockd/lvmlockd-sanlock.c
|
||||
@@ -2424,8 +2424,8 @@ static int release_rename(struct lockspace *ls, struct resource *r)
|
||||
memcpy(&rd1, &rds->rs, sizeof(struct rd_sanlock));
|
||||
memcpy(&rd2, &rds->rs, sizeof(struct rd_sanlock));
|
||||
|
||||
- res1 = (struct sanlk_resource *)&rd1;
|
||||
- res2 = (struct sanlk_resource *)&rd2;
|
||||
+ res1 = &rd1.rs;
|
||||
+ res2 = &rd2.rs;
|
||||
|
||||
if (memcmp(res1->name, r->name, SANLK_NAME_LEN))
|
||||
log_error("%s:%s unlock_san release rename bad name %.48s", ls->name, r->name, res1->name);
|
||||
--
|
||||
2.51.0
|
||||
|
||||
33
SOURCES/0020-lvmlockd-free-structs-in-adopt-error-path.patch
Normal file
33
SOURCES/0020-lvmlockd-free-structs-in-adopt-error-path.patch
Normal file
@ -0,0 +1,33 @@
|
||||
From 20b81f31c29f416a9c397e41d6998b10fc379228 Mon Sep 17 00:00:00 2001
|
||||
From: David Teigland <teigland@redhat.com>
|
||||
Date: Tue, 1 Jul 2025 10:53:33 -0500
|
||||
Subject: [PATCH 20/47] lvmlockd: free structs in adopt error path
|
||||
|
||||
(cherry picked from commit fcca60fda61b5a545c936e61380e047deb887779)
|
||||
---
|
||||
daemons/lvmlockd/lvmlockd-core.c | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
diff --git a/daemons/lvmlockd/lvmlockd-core.c b/daemons/lvmlockd/lvmlockd-core.c
|
||||
index 0cb10369a..369755ac7 100644
|
||||
--- a/daemons/lvmlockd/lvmlockd-core.c
|
||||
+++ b/daemons/lvmlockd/lvmlockd-core.c
|
||||
@@ -6331,6 +6331,15 @@ static void adopt_locks(void)
|
||||
return;
|
||||
|
||||
fail:
|
||||
+ list_for_each_entry_safe(ls, lsafe, &vg_lockd, list) {
|
||||
+ list_for_each_entry_safe(r, rsafe, &ls->resources, list) {
|
||||
+ list_del(&r->list);
|
||||
+ free_resource(r);
|
||||
+ }
|
||||
+ list_del(&ls->list);
|
||||
+ free(ls);
|
||||
+ }
|
||||
+
|
||||
(void) unlink(adopt_file);
|
||||
log_error("adopt_locks failed, reset host");
|
||||
}
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@ -0,0 +1,27 @@
|
||||
From d4406030d3fcaa9286fa9ef86fe4ebed04303bbf Mon Sep 17 00:00:00 2001
|
||||
From: David Teigland <teigland@redhat.com>
|
||||
Date: Tue, 1 Jul 2025 11:23:16 -0500
|
||||
Subject: [PATCH 21/47] lvmlockd-sanlock: check lock_lv_offset_from_args result
|
||||
|
||||
(cherry picked from commit f35f074afdaa52b0db098911d97202b478a33085)
|
||||
---
|
||||
daemons/lvmlockd/lvmlockd-sanlock.c | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
diff --git a/daemons/lvmlockd/lvmlockd-sanlock.c b/daemons/lvmlockd/lvmlockd-sanlock.c
|
||||
index 80def0449..89df4ec44 100644
|
||||
--- a/daemons/lvmlockd/lvmlockd-sanlock.c
|
||||
+++ b/daemons/lvmlockd/lvmlockd-sanlock.c
|
||||
@@ -1212,8 +1212,7 @@ int lm_free_lv_sanlock(struct lockspace *ls, struct resource *r)
|
||||
|
||||
strcpy_name_len(rs->name, "#unused", SANLK_NAME_LEN);
|
||||
|
||||
- if (!offset) {
|
||||
- lock_lv_offset_from_args(r->lv_args, &offset);
|
||||
+ if (!offset && !lock_lv_offset_from_args(r->lv_args, &offset)) {
|
||||
rds->rs.disks[0].offset = offset;
|
||||
log_debug("%s:%s free_lv_san lock_args offset %llu", ls->name, r->name, (unsigned long long)offset);
|
||||
}
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@ -0,0 +1,57 @@
|
||||
From 2477a95fe1a47ff4e8c4c8afda7c4b95dddfaeda Mon Sep 17 00:00:00 2001
|
||||
From: David Teigland <teigland@redhat.com>
|
||||
Date: Fri, 5 Sep 2025 12:21:12 -0500
|
||||
Subject: [PATCH 22/47] lvmlockd: always free ls struct after ls thread exits
|
||||
|
||||
The ls struct was being freed after ls thread exit for common stop,
|
||||
but was missing when the ls thread was stopped for drop and rename.
|
||||
Also free ls->actions structs in case any still exist.
|
||||
|
||||
(cherry picked from commit 5b410e589c75d0d540e4ebe4f44cc71b5624cbc6)
|
||||
---
|
||||
daemons/lvmlockd/lvmlockd-core.c | 20 +++++++++-----------
|
||||
1 file changed, 9 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/daemons/lvmlockd/lvmlockd-core.c b/daemons/lvmlockd/lvmlockd-core.c
|
||||
index 369755ac7..f7340ff3e 100644
|
||||
--- a/daemons/lvmlockd/lvmlockd-core.c
|
||||
+++ b/daemons/lvmlockd/lvmlockd-core.c
|
||||
@@ -3553,6 +3553,7 @@ static int count_lockspace_starting(uint32_t client_id)
|
||||
static int for_each_lockspace(int do_stop, int do_free, int do_force)
|
||||
{
|
||||
struct lockspace *ls, *safe;
|
||||
+ struct action *act, *act2;
|
||||
int need_stop = 0;
|
||||
int need_free = 0;
|
||||
int stop_count = 0;
|
||||
@@ -3605,19 +3606,16 @@ static int for_each_lockspace(int do_stop, int do_free, int do_force)
|
||||
if ((perrno = pthread_join(ls->thread, NULL)))
|
||||
log_error("pthread_join error %d", perrno);
|
||||
|
||||
+ log_debug("free ls struct %s", ls->name);
|
||||
list_del(&ls->list);
|
||||
-
|
||||
- /* FIXME: will free_vg ever not be set? */
|
||||
-
|
||||
- log_debug("free ls %s", ls->name);
|
||||
-
|
||||
- if (ls->free_vg) {
|
||||
- /* In future we may need to free ls->actions here */
|
||||
- free_ls_resources(ls);
|
||||
- free_pvs_path(&ls->pvs);
|
||||
- free(ls);
|
||||
- free_count++;
|
||||
+ list_for_each_entry_safe(act, act2, &ls->actions, list) {
|
||||
+ list_del(&act->list);
|
||||
+ free_action(act);
|
||||
}
|
||||
+ free_ls_resources(ls);
|
||||
+ free_pvs_path(&ls->pvs);
|
||||
+ free(ls);
|
||||
+ free_count++;
|
||||
} else {
|
||||
need_free++;
|
||||
}
|
||||
--
|
||||
2.51.0
|
||||
|
||||
582
SOURCES/0023-man-lvmlockd-updates.patch
Normal file
582
SOURCES/0023-man-lvmlockd-updates.patch
Normal file
@ -0,0 +1,582 @@
|
||||
From e193db35a368dcd9ac8c9737d774d3552d4cf877 Mon Sep 17 00:00:00 2001
|
||||
From: David Teigland <teigland@redhat.com>
|
||||
Date: Tue, 23 Sep 2025 11:09:08 -0500
|
||||
Subject: [PATCH 23/47] man lvmlockd: updates
|
||||
|
||||
Major rewrite of the beginning description/setup/introduction.
|
||||
|
||||
(cherry picked from commit f15d948720b4a8b52b7929856ee52e20ab0da798)
|
||||
---
|
||||
man/lvmlockd.8_main | 470 +++++++++++++++++++++-----------------------
|
||||
1 file changed, 219 insertions(+), 251 deletions(-)
|
||||
|
||||
diff --git a/man/lvmlockd.8_main b/man/lvmlockd.8_main
|
||||
index 0c0c88ddd..621224df7 100644
|
||||
--- a/man/lvmlockd.8_main
|
||||
+++ b/man/lvmlockd.8_main
|
||||
@@ -20,33 +20,44 @@ lvmlockd \(em LVM locking daemon
|
||||
.
|
||||
.SH DESCRIPTION
|
||||
.
|
||||
-LVM commands use lvmlockd to coordinate access to shared storage.
|
||||
+
|
||||
+A shared Volume Group is a VG placed on shared storage devices, e.g. from a
|
||||
+SAN, that can be used by all the hosts that can access the devices. A
|
||||
+shared VG requires the use of lvmlockd, and an external lock manager.
|
||||
+.
|
||||
+.P
|
||||
+Different hosts may activate and use LVs in the same shared VG, and
|
||||
+different hosts can create, extend, or remove LVs in the VG. Locking,
|
||||
+through lvmlockd, ensures this is all done safely and consistently.
|
||||
+LVM commands request locks from lvmlockd, which passes the lock requests
|
||||
+to an external lock manager. Each shared VG has a
|
||||
+.B locktype
|
||||
+attribute, specifying the external lock manager to use for the VG.
|
||||
+.
|
||||
.P
|
||||
-When LVM is used on devices shared by multiple hosts, locks will:
|
||||
+The lock manager options are:
|
||||
+.B sanlock
|
||||
+which places locks on storage space reserved within the VG, and
|
||||
+.B dlm
|
||||
+which uses a network locking protocol, and has additional clustering
|
||||
+requirements.
|
||||
+.
|
||||
+.P
|
||||
+There are three types of locking performed through lvmlockd:
|
||||
.PD 0
|
||||
.IP \[bu] 2
|
||||
-coordinate reading and writing of LVM metadata
|
||||
+per-VG locks protect changes to the VG metadata.
|
||||
.IP \[bu]
|
||||
-validate caching of LVM metadata
|
||||
+LV locks limit LV activation to one host at a time.
|
||||
.IP \[bu]
|
||||
-prevent conflicting activation of logical volumes
|
||||
-.PD
|
||||
-.P
|
||||
-lvmlockd uses an external lock manager to perform basic locking.
|
||||
-.P
|
||||
-Lock manager (lock type) options are:
|
||||
-.
|
||||
-.TP 8
|
||||
-.B sanlock
|
||||
-\(en places locks on disk within LVM storage.
|
||||
-.
|
||||
-.TP
|
||||
-.B dlm
|
||||
-\(en uses network communication and a cluster manager.
|
||||
+A Global lock protects unused PVs and the VG namespace.
|
||||
.PD
|
||||
.
|
||||
.SH OPTIONS
|
||||
.
|
||||
+lvmlockd daemon command line options:
|
||||
+.P
|
||||
+.
|
||||
.TP
|
||||
.BR -h | --help
|
||||
Show this help information.
|
||||
@@ -108,193 +119,212 @@ Override the default sanlock I/O timeout.
|
||||
.BR -A | --adopt " " 0 | 1
|
||||
Enable (1) or disable (0) lock adoption.
|
||||
.
|
||||
-.SH USAGE
|
||||
-.
|
||||
-.SS Initial set up
|
||||
+.SH SETUP
|
||||
.
|
||||
-Setting up LVM to use lvmlockd and a shared VG for the first time includes
|
||||
-some one time set up steps:
|
||||
-.
|
||||
-.SS 1. choose a lock manager
|
||||
-.
|
||||
-.TP 8
|
||||
-.B sanlock
|
||||
-Choose sanlock if dlm/corosync are not otherwise required.
|
||||
-sanlock does not depend on any clustering software or configuration.
|
||||
-.
|
||||
-.TP
|
||||
-.B dlm
|
||||
-If dlm (or corosync) are already being used by other cluster
|
||||
-software, then select dlm. dlm uses corosync which requires additional
|
||||
-configuration beyond the scope of this document. See corosync and dlm
|
||||
-documentation for instructions on configuration, set up and usage.
|
||||
-.
|
||||
-.SS 2. configure hosts to use lvmlockd
|
||||
-.
|
||||
-On all hosts running lvmlockd, configure
|
||||
-.BR lvm.conf (5):
|
||||
+The following steps provide a quick overview of how to use shared VGs.
|
||||
+More details can be found under SETUP DETAILS.
|
||||
.P
|
||||
-.EX
|
||||
-use_lvmlockd = 1
|
||||
-.EE
|
||||
-.
|
||||
-.TP 8
|
||||
-.B sanlock
|
||||
-Assign each host a unique host_id in the range 1-2000 by setting
|
||||
+.I Devices
|
||||
+.P
|
||||
+Identify the shared device(s) that will be used in the shared VG,
|
||||
+and add them to each host's devices file (local device names often
|
||||
+differ, unless a WWN-based name from /dev/disk/by-id is used.)
|
||||
.br
|
||||
-.I #DEFAULT_SYS_DIR#/lvmlocal.conf
|
||||
-local/host_id
|
||||
-.
|
||||
-.SS 3. start lvmlockd
|
||||
-.
|
||||
-Start the lvmlockd daemon.
|
||||
+.B $ lvmdevices --adddev
|
||||
+.I device
|
||||
+.P
|
||||
+.I Configuration
|
||||
+.P
|
||||
+Edit lvm.conf, setting
|
||||
+.B use_lvmlockd=1
|
||||
+on each host using a shared VG.
|
||||
+.P
|
||||
+Edit lvmlocal.conf, setting
|
||||
+.B host_id
|
||||
+on each host (only required when using sanlock.)
|
||||
+The host_id is a unique integer for each host between 1 and 2000.
|
||||
+.P
|
||||
+.I Locking
|
||||
+.P
|
||||
+Start lvmlockd and the external lock manager (sanlock or dlm) on
|
||||
+each host.
|
||||
+.P
|
||||
+.I VG
|
||||
+.P
|
||||
+Create a shared VG from one host (uses the running lock manager):
|
||||
.br
|
||||
-Use systemctl, a cluster resource agent, or run directly, e.g.
|
||||
+.B $ vgcreate --shared
|
||||
+.I VG
|
||||
+.I devices
|
||||
.P
|
||||
-.EX
|
||||
-systemctl start lvmlockd
|
||||
-.EE
|
||||
-.
|
||||
-.SS 4. start lock manager
|
||||
-.
|
||||
-.TP 8
|
||||
-.B sanlock
|
||||
-Start the sanlock and wdmd daemons.
|
||||
+Start the lockspace for the shared VG on all hosts:
|
||||
.br
|
||||
-Use systemctl or run directly, e.g.
|
||||
-.sp
|
||||
-.EX
|
||||
-systemctl start wdmd sanlock
|
||||
-.EE
|
||||
-.
|
||||
-.TP
|
||||
-.B dlm
|
||||
-Start the dlm and corosync daemons.
|
||||
+.B $ vgchange --lockstart
|
||||
+.I VG
|
||||
+.P
|
||||
+.I Usage
|
||||
+.P
|
||||
+Begin using the VG, e.g. creating LVs.
|
||||
+.P
|
||||
+Regular shutdown steps:
|
||||
+.br
|
||||
+ $ vgchange -an VG
|
||||
+.br
|
||||
+ $ vgchange --lockstop VG
|
||||
+.br
|
||||
+ $ stop lvmlockd and lock manager
|
||||
.br
|
||||
-Use systemctl, a cluster resource agent, or run directly, e.g.
|
||||
-.sp
|
||||
-.EX
|
||||
-systemctl start corosync dlm
|
||||
-.EE
|
||||
-.
|
||||
-.SS 5. create VG on shared devices
|
||||
-.
|
||||
-vgcreate --shared <vgname> <devices>
|
||||
.P
|
||||
-The shared option sets the VG lock type to sanlock or dlm depending on
|
||||
-which lock manager is running. LVM commands acquire locks from lvmlockd,
|
||||
-and lvmlockd uses the chosen lock manager.
|
||||
-.
|
||||
-.SS 6. start VG on all hosts
|
||||
-.
|
||||
-.EX
|
||||
-vgchange --lockstart
|
||||
-.EE
|
||||
+Regular startup steps:
|
||||
+.br
|
||||
+ $ start lvmlockd and lock manager
|
||||
+.br
|
||||
+ $ vgchange --lockstart VG
|
||||
.P
|
||||
-Shared VGs must be started before they are used. Starting the VG performs
|
||||
-lock manager initialization that is necessary to begin using locks (i.e.
|
||||
-creating and joining a lockspace). Starting the VG may take some time,
|
||||
-and until the start completes the VG may not be modified or activated.
|
||||
.
|
||||
-.SS 7. create and activate LVs
|
||||
-.
|
||||
-Standard lvcreate and lvchange commands are used to create and activate
|
||||
-LVs in a shared VG.
|
||||
+.SH SETUP DETAILS
|
||||
+.P
|
||||
+.B Identifying devices
|
||||
+.br
|
||||
+Devices often have different local names on each host, e.g. /dev/sda
|
||||
+on one host is named /dev/sdb on another. One method to identify the
|
||||
+same device on each host is to run the command lsblk -o+WWN on each
|
||||
+host, looking for the same WWN, and its corresponding local device name.
|
||||
+Or, the WWN-based device symlinks under /dev/disk/by-id/ can be a
|
||||
+useful way to consistently identify a device across multiple hosts.
|
||||
+.P
|
||||
+.B Device access
|
||||
+.br
|
||||
+On each host, LVM needs to be given access to the shared devices by
|
||||
+adding them to the local system.devices file (unless the devices file
|
||||
+feature has been disabled.) Use the local device name identified
|
||||
+in the previous step, or a WWN-based device symlink, and run the
|
||||
+command lvmdevices --adddev device_path to add each of the shared
|
||||
+devices to the local system.devices file.
|
||||
+Alternatively, after the shared VG has been created from one host,
|
||||
+other hosts can run the command vgimportdevices VG to add devices
|
||||
+from VG to system.devices.
|
||||
+See
|
||||
+.BR lvmdevices (8)
|
||||
+for more information.
|
||||
+.P
|
||||
+.B Config files
|
||||
+.br
|
||||
+After #DEFAULT_SYS_DIR#/lvm.conf use_lvmlockd has been set to 1,
|
||||
+lvm commands will begin attempting to acquire locks from lvmlockd.
|
||||
+Failures to acquire the global lock from lvmlockd may appear until
|
||||
+the first shared VG is operational. These warnings won't interfere
|
||||
+with lvm commands doing read operations, but lvm commands attempting
|
||||
+to write may fail with a global lock error.
|
||||
+.P
|
||||
+The #DEFAULT_SYS_DIR#/lvmlocal.conf host_id setting is only required
|
||||
+when using VGs with lock type sanlock. Each host using sanlock VGs
|
||||
+must be configured with a unique host_id value. Valid host_ids are
|
||||
+integers in the range 1-2000. (The lvmlocal.conf descriptions of
|
||||
+host_id and sanlock_align_size mention special cases with 4K disks
|
||||
+in which the valid host_id range can be smaller, e.g. 1-250.)
|
||||
+.P
|
||||
+.B Lock managers
|
||||
+.br
|
||||
+A specific build of LVM may exclude support for sanlock or dlm
|
||||
+lock managers. To check this, run the command "lvm version" and
|
||||
+look for "--enable-lvmlockd-sanlock" or "--enable-lvmlockd-dlm".
|
||||
+.P
|
||||
+With the --shared option, vgcreate searches for a running lock manager
|
||||
+(dlm or sanlock), and uses the result for the VG lock type.
|
||||
+In place of --shared, vgcreate --locktype sanlock|dlm can be specified
|
||||
+directly.
|
||||
.P
|
||||
-An LV activated exclusively on one host cannot be activated on another.
|
||||
-When multiple hosts need to use the same LV concurrently, the LV can be
|
||||
-activated with a shared lock (see lvchange options -aey vs -asy.)
|
||||
-(Shared locks are disallowed for certain LV types that cannot be used from
|
||||
-multiple hosts.)
|
||||
+When using lvmlockd in a cluster which already uses corosync and
|
||||
+dlm, then the dlm lock type should be used for shared VGs. Otherwise,
|
||||
+using sanlock is usually more straight forward.
|
||||
+.P
|
||||
+Details on starting or setting up each lock manager are outside the
|
||||
+scope of LVM. sanlock can usually be started with a simple
|
||||
+"systemctl start wdmd sanlock". Steps for setting up and starting
|
||||
+corosync and dlm can be more complicated.
|
||||
+.P
|
||||
+.B Lock start
|
||||
+.br
|
||||
+Shared VGs must be started before they are used via vgchange --lockstart
|
||||
+VG. Starting the VG performs lock manager initialization that is necessary
|
||||
+to begin using locks (i.e. creating and joining a lockspace). Starting the
|
||||
+VG may take some time, and until the start completes the VG may not be
|
||||
+modified or activated. When shutting down, the lockspace is stopped with
|
||||
+vgchange --lockstop VG.
|
||||
.
|
||||
-.SS Normal start up and shut down
|
||||
+.SH TOPICS
|
||||
.
|
||||
-After initial set up, start up and shut down include the following steps.
|
||||
-They can be performed directly or may be automated using systemd or a
|
||||
-cluster resource manager/agents. When using lvmlockd.service, daemon
|
||||
-options can be set in
|
||||
-.I /etc/sysconfig/lvmlockd
|
||||
-as OPTIONS='-x1 -y2'.
|
||||
+.SS Displaying shared VGs
|
||||
+.P
|
||||
+The
|
||||
+.B vgs
|
||||
+command shows the letter
|
||||
+.B s
|
||||
+in the last (sixth) attr position for a shared VG:
|
||||
.
|
||||
-.IP \[bu] 2
|
||||
-start lvmlockd
|
||||
+.nf
|
||||
.
|
||||
-.IP \[bu]
|
||||
-start lock manager
|
||||
+.P
|
||||
+$ vgs
|
||||
+ VG #PV #LV #SN Attr VSize VFree
|
||||
+ vgfoo 1 0 0 wz--ns 992.00m 736.00m
|
||||
+.fi
|
||||
.
|
||||
-.IP \[bu]
|
||||
-vgchange --lockstart
|
||||
+.P
|
||||
.
|
||||
-.IP \[bu]
|
||||
-activate LVs in shared VGs
|
||||
+Or, the shared attribute can be displayed as a
|
||||
+.B vgs
|
||||
+reporting field:
|
||||
+.P
|
||||
+.nf
|
||||
+$ vgs -o+shared
|
||||
+ VG #PV #LV #SN Attr VSize VFree Shared
|
||||
+ vgfoo 1 0 0 wz--ns 992.00m 736.00m shared
|
||||
+.fi
|
||||
.P
|
||||
-The shut down sequence is the reverse:
|
||||
-.IP \[bu] 2
|
||||
-deactivate LVs in shared VGs
|
||||
-.IP \[bu]
|
||||
-vgchange --lockstop
|
||||
-.IP \[bu]
|
||||
-stop lock manager
|
||||
-.IP \[bu]
|
||||
-stop lvmlockd
|
||||
.
|
||||
-.SH TOPICS
|
||||
+The
|
||||
+.B vgs
|
||||
+command can also display the lock type:
|
||||
.
|
||||
-.SS Protecting VGs on shared devices
|
||||
+.P
|
||||
+.nf
|
||||
+$ vgs -o+locktype
|
||||
+ VG #PV #LV #SN Attr VSize VFree LockType
|
||||
+ vgfoo 1 0 0 wz--ns 992.00m 736.00m sanlock
|
||||
+.fi
|
||||
+.P
|
||||
.
|
||||
-The following terms are used to describe the different ways of accessing
|
||||
-VGs on shared devices.
|
||||
+On hosts that are attached to the shared devices, but do not have
|
||||
+lvmlockd enabled, the
|
||||
+.B vgs
|
||||
+command will not display shared VGs unless the
|
||||
+.B --shared
|
||||
+option is added:
|
||||
.
|
||||
-.TP
|
||||
-.I shared VG
|
||||
-A shared VG exists on shared storage that is visible to multiple hosts.
|
||||
-LVM acquires locks through lvmlockd to coordinate access to shared VGs.
|
||||
-A shared VG has lock_type "dlm" or "sanlock", which specifies the lock
|
||||
-manager lvmlockd will use.
|
||||
-.sp
|
||||
-When the lock manager for the lock type is not available (e.g. not started
|
||||
-or failed), lvmlockd is unable to acquire locks for LVM commands. In this
|
||||
-situation, LVM commands are only allowed to read and display the VG;
|
||||
-changes and activation will fail.
|
||||
+.P
|
||||
+.nf
|
||||
+$ vgs --shared
|
||||
+ VG #PV #LV #SN Attr VSize VFree
|
||||
+ vgfoo 1 0 0 wz--ns 992.00m 736.00m
|
||||
+.fi
|
||||
.
|
||||
-.TP
|
||||
-.I local VG
|
||||
-A local VG is meant to be used by a single host. It has no lock type or
|
||||
-lock type "none". A local VG typically exists on local (non-shared)
|
||||
-devices and cannot be used concurrently from different hosts.
|
||||
-.sp
|
||||
-If a local VG does exist on shared devices, it should be owned by a single
|
||||
-host by having the system ID set, see
|
||||
+.SS System ID
|
||||
+.br
|
||||
+In contrast to a shared VG, a local VG can only be used by one host
|
||||
+at a time, and does not use lvmlockd or a lock manager. If a local VG
|
||||
+is located on shared devices, then the LVM system ID feature should be
|
||||
+used to assign one host ownership of the VG. See
|
||||
.BR lvmsystemid (7).
|
||||
-The host with a matching system ID can use the local VG and other hosts
|
||||
-will ignore it. A VG with no lock type and no system ID should be
|
||||
-excluded from all but one host using
|
||||
-.BR lvm.conf (5)
|
||||
-filters.
|
||||
-Without any of these protections, a local VG on shared devices
|
||||
-can be easily damaged or destroyed.
|
||||
-.
|
||||
-.TP
|
||||
-.I clvm VG
|
||||
-A clvm VG (or clustered VG) is a VG on shared storage (like a shared VG)
|
||||
-that requires clvmd for clustering and locking. See below for converting
|
||||
-a clvm/clustered VG to a shared VG.
|
||||
-.
|
||||
-.SS Shared VGs from hosts not using lvmlockd
|
||||
-.
|
||||
-Hosts that do not use shared VGs will not be running lvmlockd. In this
|
||||
-case, shared VGs that are still visible to the host will be ignored
|
||||
-(like foreign VGs, see
|
||||
-.BR lvmsystemid (7)).
|
||||
.P
|
||||
-The --shared option for reporting and display commands causes shared VGs
|
||||
-to be displayed on a host not using lvmlockd, like the --foreign option
|
||||
-does for foreign VGs.
|
||||
+For additional protection, the shared devices in a local VG can be
|
||||
+excluded from the devices file (system.devices) on all hosts except
|
||||
+for the host that owns the VG.
|
||||
.
|
||||
.SS Creating the first sanlock VG
|
||||
.
|
||||
-When use_lvmlockd is first enabled in
|
||||
-.BR lvm.conf (5),
|
||||
+When use_lvmlockd is first enabled in lvm.conf,
|
||||
and before the first sanlock VG is created, no global lock will exist.
|
||||
In this initial state, LVM commands try
|
||||
and fail to acquire the global lock, producing a warning,
|
||||
@@ -327,27 +357,12 @@ from concurrent use by another vgcreate on another host.
|
||||
.P
|
||||
See below for more information about managing the sanlock global lock.
|
||||
.
|
||||
-.SS Using shared VGs
|
||||
+.SS Removing a shared VG
|
||||
.
|
||||
-In the
|
||||
-.BR vgs (8)
|
||||
-command, shared VGs are indicated by "s" (for shared)
|
||||
-in the sixth attr field,
|
||||
-and by "shared" in the "--options shared" report field.
|
||||
-The specific lock type and lock args for a shared VG can be
|
||||
-displayed with:
|
||||
-.P
|
||||
-.EX
|
||||
-# vgs -o+locktype,lockargs
|
||||
-.EE
|
||||
-.P
|
||||
-Shared VGs need to be "started" and "stopped", unlike other types of VGs.
|
||||
-See the following section for a full description of starting and stopping.
|
||||
-.P
|
||||
-Removing a shared VG will fail if other hosts have the VG started. Run
|
||||
-vgchange --lockstop <vgname> on all other hosts before vgremove. (It may
|
||||
-take several seconds before vgremove recognizes that all hosts have
|
||||
-stopped a sanlock VG.)
|
||||
+Removing a shared VG will fail if other hosts have the VG started (it must
|
||||
+be started on the host running vgremove.) Run vgchange --lockstop <vgname>
|
||||
+on all other hosts before vgremove. (It may take several seconds before
|
||||
+vgremove recognizes that all hosts have stopped a sanlock VG.)
|
||||
.
|
||||
.SS Starting and stopping VGs
|
||||
.
|
||||
@@ -366,32 +381,6 @@ When using the lock type sanlock, starting a VG can take a long time
|
||||
(potentially minutes if the host was previously shut down without cleanly
|
||||
stopping the VG.)
|
||||
.P
|
||||
-A shared VG can be started after all the following are true:
|
||||
-.P
|
||||
-\[bu]
|
||||
-lvmlockd is running
|
||||
-.br
|
||||
-\[bu]
|
||||
-the lock manager is running
|
||||
-.br
|
||||
-\[bu]
|
||||
-the VG's devices are visible on the system
|
||||
-.P
|
||||
-A shared VG can be stopped if all LVs are deactivated.
|
||||
-.P
|
||||
-All shared VGs can be started/stopped using:
|
||||
-.P
|
||||
-.EX
|
||||
-# vgchange --lockstart
|
||||
-# vgchange --lockstop
|
||||
-.EE
|
||||
-.P
|
||||
-Individual VGs can be started/stopped using:
|
||||
-.br
|
||||
-vgchange --lockstart <vgname> \&.\|.\|.
|
||||
-.br
|
||||
-vgchange --lockstop <vgname> \&.\|.\|.
|
||||
-.P
|
||||
To make vgchange not wait for start to complete:
|
||||
.br
|
||||
vgchange --lockstart --lockopt nowait \&.\|.\|.
|
||||
@@ -400,21 +389,6 @@ lvmlockd can be asked directly to stop all lockspaces:
|
||||
.br
|
||||
lvmlockctl -S|--stop-lockspaces
|
||||
.P
|
||||
-To start only selected shared VGs, use the
|
||||
-.BR lvm.conf (5)
|
||||
-\fBactivation/lock_start_list\fP.
|
||||
-When defined, only VG names in this list are
|
||||
-started by vgchange. If the list is not defined (the default), all
|
||||
-visible shared VGs are started. To start only "vg1", use the following
|
||||
-.BR lvm.conf (5)
|
||||
-configuration:
|
||||
-.P
|
||||
-.EX
|
||||
-activation {
|
||||
-\ lock_start_list = [ "vg1" ]
|
||||
-\ \&...
|
||||
-}
|
||||
-.EE
|
||||
.
|
||||
.SS Internal command locking
|
||||
.
|
||||
@@ -664,7 +638,7 @@ dmsetup wipe_table -S "uuid=~LVM && vgname=$VG && lv_layer=\\"\\""
|
||||
# check that the error target is in place
|
||||
dmsetup table -c -S "uuid=~LVM && vgname=$VG && lv_layer=\\"\\"" |grep -vw error
|
||||
if [[ $? -ne 0 ]] ; then
|
||||
-\ exit 0
|
||||
+exit 0
|
||||
fi
|
||||
exit 1
|
||||
.EE
|
||||
@@ -868,14 +842,11 @@ vgmerge
|
||||
.
|
||||
.SS lvmlockd changes from clvmd
|
||||
.
|
||||
-(See above for converting an existing clvm VG to a shared VG.)
|
||||
.P
|
||||
-While lvmlockd and clvmd are entirely different systems, LVM command usage
|
||||
-remains similar. Differences are more notable when using lvmlockd's
|
||||
-sanlock option.
|
||||
-.P
|
||||
-Visible usage differences between shared VGs (using lvmlockd) and
|
||||
-clvm/clustered VGs (using clvmd):
|
||||
+Prior to the introduction of lvmlockd, clvmd (CLVM) existed with similar
|
||||
+capabilities, but a very different design.
|
||||
+Some of the visible usage differences between shared VGs (using lvmlockd)
|
||||
+and cluster VGs (using clvmd):
|
||||
.
|
||||
.IP \[bu] 2
|
||||
.BR lvm.conf (5)
|
||||
@@ -945,9 +916,6 @@ unable to passively check the remote active or lock state of an LV.
|
||||
.
|
||||
.nh
|
||||
.na
|
||||
-.BR lvm (8),
|
||||
.BR lvmlockctl (8),
|
||||
-.BR lvchange (8),
|
||||
-.BR lvgs (8),
|
||||
-.BR vgs (8),
|
||||
-.BR lvm.conf (5)
|
||||
+.BR sanlock (8),
|
||||
+.BR dlm_controld (8)
|
||||
--
|
||||
2.51.0
|
||||
|
||||
44
SOURCES/0024-lvmlockd-allow-1-more-extra-character.patch
Normal file
44
SOURCES/0024-lvmlockd-allow-1-more-extra-character.patch
Normal file
@ -0,0 +1,44 @@
|
||||
From 1fee1b03564bb807e7adedefb27180babcd861d0 Mon Sep 17 00:00:00 2001
|
||||
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||
Date: Fri, 27 Jun 2025 11:15:05 +0200
|
||||
Subject: [PATCH 24/47] lvmlockd: allow 1 more extra character
|
||||
|
||||
Function dm_strncpy() ensures the last character is \0,
|
||||
so pass whole array size for buffer size.
|
||||
|
||||
This give 1 extra character for use to store owner state and name.
|
||||
|
||||
(cherry picked from commit 879fb36f0a6c4fda783efbc02b4bf6477f18a4af)
|
||||
---
|
||||
daemons/lvmlockd/lvmlockd-sanlock.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/daemons/lvmlockd/lvmlockd-sanlock.c b/daemons/lvmlockd/lvmlockd-sanlock.c
|
||||
index 89df4ec44..6ef59b591 100644
|
||||
--- a/daemons/lvmlockd/lvmlockd-sanlock.c
|
||||
+++ b/daemons/lvmlockd/lvmlockd-sanlock.c
|
||||
@@ -2208,10 +2208,10 @@ int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||
owner->timestamp = (uint32_t)owner_host.timestamp;
|
||||
|
||||
if ((host_state = _host_flags_to_str(owner_host.flags)))
|
||||
- dm_strncpy(owner->state, host_state, OWNER_STATE_SIZE-1);
|
||||
+ dm_strncpy(owner->state, host_state, sizeof(owner->state));
|
||||
|
||||
if (owner_name) {
|
||||
- dm_strncpy(owner->name, owner_name, OWNER_NAME_SIZE-1);
|
||||
+ dm_strncpy(owner->name, owner_name, sizeof(owner->name));
|
||||
free(owner_name);
|
||||
}
|
||||
|
||||
@@ -2553,7 +2553,7 @@ int lm_vg_status_sanlock(struct lockspace *ls, struct action *act)
|
||||
act->owner.timestamp = (uint32_t)hs->timestamp;
|
||||
|
||||
if ((host_state = _host_flags_to_str(hs->flags)))
|
||||
- dm_strncpy(act->owner.state, host_state, OWNER_STATE_SIZE-1);
|
||||
+ dm_strncpy(act->owner.state, host_state, sizeof(act->owner.state));
|
||||
|
||||
free(hs);
|
||||
return 0;
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@ -0,0 +1,113 @@
|
||||
From 20a049ac3267240de7ffcfb55cf58c08fe7d88a6 Mon Sep 17 00:00:00 2001
|
||||
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||
Date: Fri, 27 Jun 2025 11:38:24 +0200
|
||||
Subject: [PATCH 25/47] libdm-stats: fix type mismatch in bit operations
|
||||
|
||||
The stats implementation was using uint64_t for group_id and loop variables
|
||||
while calling dm_bit_* functions that return int types. This created a
|
||||
potential issue where large values could be incorrectly handled due to
|
||||
implicit casting between signed and unsigned types.
|
||||
|
||||
Changes:
|
||||
- Change loop variables from uint64_t to int in _stats_group_tag_len()
|
||||
- Change loop variable from uint64_t to int in _stats_clear_group_regions()
|
||||
- Change loop variables from uint64_t to int in dm_stats_get_counter()
|
||||
- Change loop variable from uint64_t to int in dm_stats_get_region_len()
|
||||
- Fix _stats_create_group() to properly handle dm_bit_get_first() return value
|
||||
|
||||
This ensures consistent type usage and prevents potential issues with
|
||||
values exceeding INT_MAX (2^31 - 1). Also this limitats group_id to 31 bits
|
||||
as a constraint that may need addressing in the future.
|
||||
|
||||
FIXME: Maybe consider implementing 64-bit variants of dm_bit functions or
|
||||
documenting this limitation more prominently is this ever become an
|
||||
issue...
|
||||
|
||||
(cherry picked from commit 2dec6f5493e573b7a4012708931226bcbc9af32f)
|
||||
---
|
||||
libdm/libdm-stats.c | 25 +++++++++++++++----------
|
||||
1 file changed, 15 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/libdm/libdm-stats.c b/libdm/libdm-stats.c
|
||||
index c1b1cc466..cbcbb6754 100644
|
||||
--- a/libdm/libdm-stats.c
|
||||
+++ b/libdm/libdm-stats.c
|
||||
@@ -1859,7 +1859,8 @@ bad:
|
||||
static size_t _stats_group_tag_len(const struct dm_stats *dms,
|
||||
dm_bitset_t regions)
|
||||
{
|
||||
- int64_t i, j, next, nr_regions = 0;
|
||||
+ int i, j, next;
|
||||
+ int64_t nr_regions = 0;
|
||||
size_t buflen = 0, id_len = 0;
|
||||
|
||||
/* check region ids and find last set bit */
|
||||
@@ -2124,7 +2125,7 @@ out:
|
||||
static void _stats_clear_group_regions(struct dm_stats *dms, uint64_t group_id)
|
||||
{
|
||||
struct dm_stats_group *group;
|
||||
- uint64_t i;
|
||||
+ int i;
|
||||
|
||||
group = &dms->groups[group_id];
|
||||
for (i = dm_bit_get_first(group->regions);
|
||||
@@ -2499,7 +2500,7 @@ void dm_stats_destroy(struct dm_stats *dms)
|
||||
* i is a variable of type int that holds the current area_id.
|
||||
*/
|
||||
#define _foreach_region_area(dms, rid, i) \
|
||||
-for ((i) = 0; (i) < _nr_areas_region(&dms->regions[(rid)]); (i)++) \
|
||||
+for ((i) = 0; (int)(i) < (int)_nr_areas_region(&dms->regions[(rid)]); (i)++) \
|
||||
|
||||
/*
|
||||
* Walk each region that is a member of group_id gid.
|
||||
@@ -2507,7 +2508,7 @@ for ((i) = 0; (i) < _nr_areas_region(&dms->regions[(rid)]); (i)++) \
|
||||
*/
|
||||
#define _foreach_group_region(dms, gid, i) \
|
||||
for ((i) = dm_bit_get_first((dms)->groups[(gid)].regions); \
|
||||
- (i) != DM_STATS_GROUP_NOT_PRESENT; \
|
||||
+ (int)(i) != (int)DM_STATS_GROUP_NOT_PRESENT; \
|
||||
(i) = dm_bit_get_next((dms)->groups[(gid)].regions, (i))) \
|
||||
|
||||
/*
|
||||
@@ -2562,8 +2563,8 @@ uint64_t dm_stats_get_counter(const struct dm_stats *dms,
|
||||
dm_stats_counter_t counter,
|
||||
uint64_t region_id, uint64_t area_id)
|
||||
{
|
||||
- uint64_t i, j, sum = 0; /* aggregation */
|
||||
- int sum_regions = 0;
|
||||
+ uint64_t sum = 0; /* aggregation */
|
||||
+ int i, j, sum_regions = 0;
|
||||
struct dm_stats_region *region;
|
||||
struct dm_stats_counters *area;
|
||||
|
||||
@@ -3129,7 +3130,7 @@ int dm_stats_get_region_start(const struct dm_stats *dms, uint64_t *start,
|
||||
int dm_stats_get_region_len(const struct dm_stats *dms, uint64_t *len,
|
||||
uint64_t region_id)
|
||||
{
|
||||
- uint64_t i;
|
||||
+ int i;
|
||||
if (!dms || !dms->regions)
|
||||
return_0;
|
||||
|
||||
@@ -3970,11 +3971,15 @@ static int _stats_create_group(struct dm_stats *dms, dm_bitset_t regions,
|
||||
const char *alias, uint64_t *group_id)
|
||||
{
|
||||
struct dm_stats_group *group;
|
||||
- *group_id = dm_bit_get_first(regions);
|
||||
+ int i = dm_bit_get_first(regions);
|
||||
|
||||
- /* group has no regions? */
|
||||
- if (*group_id == DM_STATS_GROUP_NOT_PRESENT)
|
||||
+ if (i < 0) {
|
||||
+ /* group has no regions? */
|
||||
+ *group_id = DM_STATS_GROUP_NOT_PRESENT;
|
||||
return_0;
|
||||
+ }
|
||||
+
|
||||
+ *group_id = (uint64_t)i;
|
||||
|
||||
group = &dms->groups[*group_id];
|
||||
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@ -0,0 +1,41 @@
|
||||
From c25e62f4e0532dfb55e2c81a6e236edfeffa8c11 Mon Sep 17 00:00:00 2001
|
||||
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||
Date: Sun, 29 Jun 2025 20:47:13 +0200
|
||||
Subject: [PATCH 26/47] cov: prevent potential negative array index
|
||||
|
||||
The _stats_map_extents() function processes file extents returned
|
||||
by FIEMAP ioctl calls. When handling the case where a file has
|
||||
only a single extent, the code accesses fm_ext[i - 1] to check
|
||||
if the logical offset is 0.
|
||||
|
||||
However, when i is 0 (no extents processed yet), this results in a negative
|
||||
array index access which can cause undefined behavior or crashes.
|
||||
|
||||
So check early whether there are fm_mapped_extents to process.
|
||||
This avoids using negative index array.
|
||||
|
||||
Existing code already checks fm_mapped_extents == 0 before calling
|
||||
this function so the patch is not fixing any real bug.
|
||||
|
||||
(cherry picked from commit 2a2ad7317f19f15982045d847aacd74922a28572)
|
||||
---
|
||||
libdm/libdm-stats.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/libdm/libdm-stats.c b/libdm/libdm-stats.c
|
||||
index cbcbb6754..53c3c5480 100644
|
||||
--- a/libdm/libdm-stats.c
|
||||
+++ b/libdm/libdm-stats.c
|
||||
@@ -4411,6 +4411,9 @@ static uint64_t _stats_map_extents(int fd, struct dm_pool *mem,
|
||||
uint64_t expected = 0, nr_extents = next_extent;
|
||||
unsigned int i;
|
||||
|
||||
+ if (!fiemap->fm_mapped_extents)
|
||||
+ return 0;
|
||||
+
|
||||
/*
|
||||
* Loop over the returned extents adding the fm_pending extent
|
||||
* to the table of extents each time a discontinuity (or eof)
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@ -0,0 +1,65 @@
|
||||
From fa4c75d8e20019a11c722d1cc7f3923b3e4b5324 Mon Sep 17 00:00:00 2001
|
||||
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||
Date: Fri, 27 Jun 2025 13:46:01 +0200
|
||||
Subject: [PATCH 27/47] cov: fix integer underflow in _count handling
|
||||
|
||||
The _count variable was declared as uint64_t but used in arithmetic operations
|
||||
that could result in underflow when subtracting from smaller values. This
|
||||
could cause issues when calculating interval numbers or handling count-based
|
||||
reporting.
|
||||
|
||||
Changes:
|
||||
- Change _count variable type from uint64_t to int64_t
|
||||
- Update _interval_num() to use proper casting for arithmetic
|
||||
- Change UINT64_MAX to INT64_MAX for default count value
|
||||
- Remove unnecessary casting in count assignment
|
||||
|
||||
This prevents potential underflow issues when _count is decremented or used
|
||||
in subtraction operations, ensuring proper behavior for interval-based
|
||||
reporting and count tracking in dmsetup commands.
|
||||
|
||||
The fix maintains compatibility while providing safer integer arithmetic
|
||||
for the reporting loop logic.
|
||||
|
||||
(cherry picked from commit 8873599b66612852136b3dbcb4ebefe0164271dd)
|
||||
---
|
||||
libdm/dm-tools/dmsetup.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/libdm/dm-tools/dmsetup.c b/libdm/dm-tools/dmsetup.c
|
||||
index bf8449e35..2d6ed0a71 100644
|
||||
--- a/libdm/dm-tools/dmsetup.c
|
||||
+++ b/libdm/dm-tools/dmsetup.c
|
||||
@@ -268,7 +268,7 @@ static struct dm_tree *_dtree;
|
||||
static struct dm_report *_report;
|
||||
static report_type_t _report_type;
|
||||
static dev_name_t _dev_name_type;
|
||||
-static uint64_t _count = 1; /* count of repeating reports */
|
||||
+static int64_t _count = 1; /* count of repeating reports */
|
||||
static struct dm_timestamp *_initial_timestamp = NULL;
|
||||
static uint64_t _disp_factor = 512; /* display sizes in sectors */
|
||||
static char _disp_units = 's';
|
||||
@@ -593,7 +593,7 @@ static struct dm_split_name *_get_split_name(const char *uuid, const char *name,
|
||||
static uint64_t _interval_num(void)
|
||||
{
|
||||
uint64_t count_arg = _int_args[COUNT_ARG];
|
||||
- return ((uint64_t) _int_args[COUNT_ARG] - _count) + !!count_arg;
|
||||
+ return (uint64_t)(_int_args[COUNT_ARG] - _count) + !!count_arg;
|
||||
}
|
||||
|
||||
#ifdef HAVE_SYS_TIMERFD_H
|
||||
@@ -7342,9 +7342,9 @@ unknown:
|
||||
}
|
||||
|
||||
if (_switches[COUNT_ARG] && _int_args[COUNT_ARG])
|
||||
- _count = (uint64_t)_int_args[COUNT_ARG];
|
||||
+ _count = _int_args[COUNT_ARG];
|
||||
else if (_switches[COUNT_ARG] || _switches[INTERVAL_ARG])
|
||||
- _count = UINT64_MAX;
|
||||
+ _count = INT64_MAX;
|
||||
|
||||
if (_switches[UNITS_ARG]) {
|
||||
_disp_factor = _factor_from_units(_string_args[UNITS_ARG],
|
||||
--
|
||||
2.51.0
|
||||
|
||||
39
SOURCES/0028-cov-fix-va_end-resource-leak-in-szscanf.patch
Normal file
39
SOURCES/0028-cov-fix-va_end-resource-leak-in-szscanf.patch
Normal file
@ -0,0 +1,39 @@
|
||||
From 15164d1c1f84cd583e93b13e277f4cbae310b03b Mon Sep 17 00:00:00 2001
|
||||
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||
Date: Sat, 28 Jun 2025 22:42:17 +0200
|
||||
Subject: [PATCH 28/47] cov: fix va_end resource leak in szscanf()
|
||||
|
||||
- Fix potential resource leak by ensuring va_end() is called on error path
|
||||
- Set matched = -1 and break from while loop instead of immediate return
|
||||
- This ensures proper cleanup of va_list when unsupported format
|
||||
specifiers are encountered in lvmlockctl.
|
||||
|
||||
The szscanf function is a custom string scanner used for parsing lvmlockd
|
||||
status information. Previously, encountering an unsupported format
|
||||
specifier would cause an immediate return without calling va_end(),
|
||||
leading to undefined behavior and potential resource leaks.
|
||||
|
||||
This fix ensures proper cleanup of variable argument lists in all code paths.
|
||||
|
||||
(cherry picked from commit a53352b4aaa9277cec96f61c50b05d6334320bfe)
|
||||
---
|
||||
daemons/lvmlockd/lvmlockctl.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/daemons/lvmlockd/lvmlockctl.c b/daemons/lvmlockd/lvmlockctl.c
|
||||
index 5a4512095..4623e349d 100644
|
||||
--- a/daemons/lvmlockd/lvmlockctl.c
|
||||
+++ b/daemons/lvmlockd/lvmlockctl.c
|
||||
@@ -181,7 +181,8 @@ static int szscanf(const char *input, const char *format, ...)
|
||||
|
||||
} else {
|
||||
/* unsupported format specifier */
|
||||
- return -1;
|
||||
+ matched = -1;
|
||||
+ break;
|
||||
}
|
||||
|
||||
/* advance past 'd', 'u', or 's' character */
|
||||
--
|
||||
2.51.0
|
||||
|
||||
44
SOURCES/0029-cov-add-explicit-check-for-0-size.patch
Normal file
44
SOURCES/0029-cov-add-explicit-check-for-0-size.patch
Normal file
@ -0,0 +1,44 @@
|
||||
From b2814746de3fac6809c07dbd74ca606388a57aa8 Mon Sep 17 00:00:00 2001
|
||||
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||
Date: Mon, 30 Jun 2025 13:55:11 +0200
|
||||
Subject: [PATCH 29/47] cov: add explicit check for 0 size
|
||||
|
||||
(cherry picked from commit ae407d2f3cb1d607463d6d5964e44f11857cdb1f)
|
||||
---
|
||||
device_mapper/libdm-report.c | 4 +++-
|
||||
libdm/libdm-report.c | 4 +++-
|
||||
2 files changed, 6 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/device_mapper/libdm-report.c b/device_mapper/libdm-report.c
|
||||
index b2dc1b70c..1521708ed 100644
|
||||
--- a/device_mapper/libdm-report.c
|
||||
+++ b/device_mapper/libdm-report.c
|
||||
@@ -3832,7 +3832,9 @@ static struct field_selection *_create_field_selection(struct dm_report *rh,
|
||||
goto bad;
|
||||
fs->value->v.l = *((struct selection_str_list **) custom);
|
||||
|
||||
- s_arr_size = dm_list_size(&fs->value->v.l->str_list.list);
|
||||
+ if (!(s_arr_size = dm_list_size(&fs->value->v.l->str_list.list)))
|
||||
+ break;
|
||||
+
|
||||
if (!(s_arr = malloc(sizeof(char *) * s_arr_size))) {
|
||||
log_error("dm_report: malloc failed for regex array "
|
||||
"for selection field %s", field_id);
|
||||
diff --git a/libdm/libdm-report.c b/libdm/libdm-report.c
|
||||
index 18f7b6eb8..b8686901f 100644
|
||||
--- a/libdm/libdm-report.c
|
||||
+++ b/libdm/libdm-report.c
|
||||
@@ -3829,7 +3829,9 @@ static struct field_selection *_create_field_selection(struct dm_report *rh,
|
||||
goto bad;
|
||||
fs->value->v.l = *((struct selection_str_list **) custom);
|
||||
|
||||
- s_arr_size = dm_list_size(&fs->value->v.l->str_list.list);
|
||||
+ if (!(s_arr_size = dm_list_size(&fs->value->v.l->str_list.list)))
|
||||
+ break;
|
||||
+
|
||||
if (!(s_arr = malloc(sizeof(char *) * s_arr_size))) {
|
||||
log_error("dm_report: malloc failed for regex array "
|
||||
"for selection field %s", field_id);
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@ -0,0 +1,47 @@
|
||||
From 51f6e02a458f763d4066782549f0b3873317119d Mon Sep 17 00:00:00 2001
|
||||
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||
Date: Mon, 30 Jun 2025 14:32:10 +0200
|
||||
Subject: [PATCH 30/47] cov: explicitly zero allocated mem for array
|
||||
|
||||
Replace malloc() with calloc() when allocating the string pointer array
|
||||
for regex pattern matching in _create_field_selection(). This ensures
|
||||
all array elements are initialized to NULL pointers, preventing potential
|
||||
use of uninitialized memory objected by Coverity.
|
||||
|
||||
Existing code sets all elements in the follow up loop.
|
||||
|
||||
(cherry picked from commit 2c5489dd13045624e9597d11a85a29c8408cc0e8)
|
||||
---
|
||||
device_mapper/libdm-report.c | 2 +-
|
||||
libdm/libdm-report.c | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/device_mapper/libdm-report.c b/device_mapper/libdm-report.c
|
||||
index 1521708ed..4c3f3266a 100644
|
||||
--- a/device_mapper/libdm-report.c
|
||||
+++ b/device_mapper/libdm-report.c
|
||||
@@ -3835,7 +3835,7 @@ static struct field_selection *_create_field_selection(struct dm_report *rh,
|
||||
if (!(s_arr_size = dm_list_size(&fs->value->v.l->str_list.list)))
|
||||
break;
|
||||
|
||||
- if (!(s_arr = malloc(sizeof(char *) * s_arr_size))) {
|
||||
+ if (!(s_arr = calloc(s_arr_size, sizeof(char *)))) {
|
||||
log_error("dm_report: malloc failed for regex array "
|
||||
"for selection field %s", field_id);
|
||||
goto error;
|
||||
diff --git a/libdm/libdm-report.c b/libdm/libdm-report.c
|
||||
index b8686901f..36d99f7d7 100644
|
||||
--- a/libdm/libdm-report.c
|
||||
+++ b/libdm/libdm-report.c
|
||||
@@ -3832,7 +3832,7 @@ static struct field_selection *_create_field_selection(struct dm_report *rh,
|
||||
if (!(s_arr_size = dm_list_size(&fs->value->v.l->str_list.list)))
|
||||
break;
|
||||
|
||||
- if (!(s_arr = malloc(sizeof(char *) * s_arr_size))) {
|
||||
+ if (!(s_arr = calloc(s_arr_size, sizeof(char *)))) {
|
||||
log_error("dm_report: malloc failed for regex array "
|
||||
"for selection field %s", field_id);
|
||||
goto error;
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@ -0,0 +1,34 @@
|
||||
From 940d475e612a8ae2e3fe48213e7ed2a5c2a40705 Mon Sep 17 00:00:00 2001
|
||||
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||
Date: Mon, 30 Jun 2025 14:11:16 +0200
|
||||
Subject: [PATCH 31/47] cov: check for potential empty registry list
|
||||
|
||||
Check early for empty thread_registry list and return EINVAL
|
||||
instead of doing zero length allocation.
|
||||
|
||||
(cherry picked from commit bf580fcc2f17a0c7c732b929ed08acaf9dd831d7)
|
||||
---
|
||||
daemons/dmeventd/dmeventd.c | 7 ++++++-
|
||||
1 file changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/daemons/dmeventd/dmeventd.c b/daemons/dmeventd/dmeventd.c
|
||||
index b823a0476..2224ba23e 100644
|
||||
--- a/daemons/dmeventd/dmeventd.c
|
||||
+++ b/daemons/dmeventd/dmeventd.c
|
||||
@@ -680,7 +680,12 @@ static int _get_status(struct message_data *message_data)
|
||||
return -EINVAL;
|
||||
|
||||
_lock_mutex();
|
||||
- count = dm_list_size(&_thread_registry);
|
||||
+ if (!(count = dm_list_size(&_thread_registry))) {
|
||||
+ _unlock_mutex();
|
||||
+ ret = -EINVAL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
buffers = alloca(sizeof(char*) * count);
|
||||
dm_list_iterate_items(thread, &_thread_registry) {
|
||||
if ((current = dm_asprintf(buffers + i, "0:%d %s %s %u %" PRIu32 ";",
|
||||
--
|
||||
2.51.0
|
||||
|
||||
54
SOURCES/0032-cov-check-for-potential-empty-row-list.patch
Normal file
54
SOURCES/0032-cov-check-for-potential-empty-row-list.patch
Normal file
@ -0,0 +1,54 @@
|
||||
From ceb2cbb8a9252222e24d919977b149a5f455c11c Mon Sep 17 00:00:00 2001
|
||||
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||
Date: Mon, 30 Jun 2025 14:14:01 +0200
|
||||
Subject: [PATCH 32/47] cov: check for potential empty row list
|
||||
|
||||
Skip potential 0 length allocation and return early for empty list.
|
||||
|
||||
(cherry picked from commit 9fcc66316cd5f4b78b78ab1e0d50fafad362d499)
|
||||
---
|
||||
device_mapper/libdm-report.c | 7 +++++--
|
||||
libdm/libdm-report.c | 7 +++++--
|
||||
2 files changed, 10 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/device_mapper/libdm-report.c b/device_mapper/libdm-report.c
|
||||
index 4c3f3266a..343a7edbc 100644
|
||||
--- a/device_mapper/libdm-report.c
|
||||
+++ b/device_mapper/libdm-report.c
|
||||
@@ -4668,9 +4668,12 @@ static int _sort_rows(struct dm_report *rh)
|
||||
struct row *(*rows)[];
|
||||
uint32_t count = 0;
|
||||
struct row *row;
|
||||
+ size_t cnt_rows;
|
||||
|
||||
- if (!(rows = dm_pool_alloc(rh->mem, sizeof(**rows) *
|
||||
- dm_list_size(&rh->rows)))) {
|
||||
+ if (!(cnt_rows = dm_list_size(&rh->rows)))
|
||||
+ return 1; /* nothing to sort */
|
||||
+
|
||||
+ if (!(rows = dm_pool_alloc(rh->mem, sizeof(**rows) * cnt_rows))) {
|
||||
log_error("dm_report: sort array allocation failed");
|
||||
return 0;
|
||||
}
|
||||
diff --git a/libdm/libdm-report.c b/libdm/libdm-report.c
|
||||
index 36d99f7d7..87c588c3c 100644
|
||||
--- a/libdm/libdm-report.c
|
||||
+++ b/libdm/libdm-report.c
|
||||
@@ -4665,9 +4665,12 @@ static int _sort_rows(struct dm_report *rh)
|
||||
struct row *(*rows)[];
|
||||
uint32_t count = 0;
|
||||
struct row *row;
|
||||
+ size_t cnt_rows;
|
||||
|
||||
- if (!(rows = dm_pool_alloc(rh->mem, sizeof(**rows) *
|
||||
- dm_list_size(&rh->rows)))) {
|
||||
+ if (!(cnt_rows = dm_list_size(&rh->rows)))
|
||||
+ return 1; /* nothing to sort */
|
||||
+
|
||||
+ if (!(rows = dm_pool_alloc(rh->mem, sizeof(**rows) * cnt_rows))) {
|
||||
log_error("dm_report: sort array allocation failed");
|
||||
return 0;
|
||||
}
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@ -0,0 +1,61 @@
|
||||
From 659e03ed04eff50f12d56baff949d1e7e7b3168b Mon Sep 17 00:00:00 2001
|
||||
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||
Date: Sun, 29 Jun 2025 16:45:49 +0200
|
||||
Subject: [PATCH 33/47] gcc: for C90 don't mix declaration and code
|
||||
|
||||
This commit fixes C90 compatibility issues by ensuring variable declarations
|
||||
are placed at the beginning of code blocks before any executable statements.
|
||||
|
||||
(cherry picked from commit 0be635934c9cb4ac56e53d95adc7d7800d15e11f)
|
||||
---
|
||||
daemons/lvmlockd/lvmlockctl.c | 9 ++++++---
|
||||
tools/reporter.c | 3 ++-
|
||||
2 files changed, 8 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/daemons/lvmlockd/lvmlockctl.c b/daemons/lvmlockd/lvmlockctl.c
|
||||
index 4623e349d..e36293260 100644
|
||||
--- a/daemons/lvmlockd/lvmlockctl.c
|
||||
+++ b/daemons/lvmlockd/lvmlockctl.c
|
||||
@@ -87,12 +87,15 @@ do { \
|
||||
static int szscanf(const char *input, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
- va_start(args, format);
|
||||
- const char *fm = format;
|
||||
- const char *in = input;
|
||||
+ const char *fm;
|
||||
+ const char *in;
|
||||
int matched = 0;
|
||||
int n;
|
||||
|
||||
+ va_start(args, format);
|
||||
+ fm = format;
|
||||
+ in = input;
|
||||
+
|
||||
while (*fm != '\0') {
|
||||
|
||||
/*
|
||||
diff --git a/tools/reporter.c b/tools/reporter.c
|
||||
index 5cc6a2487..e88b8fa72 100644
|
||||
--- a/tools/reporter.c
|
||||
+++ b/tools/reporter.c
|
||||
@@ -1498,6 +1498,7 @@ int report_format_init(struct cmd_context *cmd)
|
||||
struct single_report_args *single_args;
|
||||
struct dm_report_group *new_report_group;
|
||||
struct dm_report *tmp_log_rh = NULL;
|
||||
+ const char * radixchar;
|
||||
|
||||
args.log_only = arg_is_set(cmd, logonly_ARG);
|
||||
report_command_log = args.log_only || find_config_tree_bool(cmd, log_report_command_log_CFG, NULL);
|
||||
@@ -1522,7 +1523,7 @@ int report_format_init(struct cmd_context *cmd)
|
||||
cmd->report_strict_type_mode = 1;
|
||||
|
||||
/* For json_std, the radix character must be '.'. */
|
||||
- const char * radixchar = nl_langinfo(RADIXCHAR);
|
||||
+ radixchar = nl_langinfo(RADIXCHAR);
|
||||
if (radixchar && strcmp(radixchar, ".")) {
|
||||
log_debug("Radix character for current locale is '%s', json_std requires '.', "
|
||||
"overriding LC_NUMERIC locale to 'C'", radixchar);
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@ -0,0 +1,35 @@
|
||||
From 6596b120d33f33286f37ba8b2f486fa01978b82e Mon Sep 17 00:00:00 2001
|
||||
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||
Date: Thu, 10 Jul 2025 15:11:30 +0200
|
||||
Subject: [PATCH 34/47] sanlock: fix struct copy to avoid aliasing issues
|
||||
|
||||
Replace direct structure assignment with explicit copying to prevent
|
||||
potential undefined behavior from structure aliasing. This ensures
|
||||
proper memory handling when working with sanlock structures.
|
||||
|
||||
This possibly fixes regression introduced with commit: e9640e5178769
|
||||
as unintended side effect.
|
||||
|
||||
(cherry picked from commit b86b1da80acfa97ee6cc18e3d3a44809d4083a1b)
|
||||
---
|
||||
daemons/lvmlockd/lvmlockd-sanlock.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/daemons/lvmlockd/lvmlockd-sanlock.c b/daemons/lvmlockd/lvmlockd-sanlock.c
|
||||
index 6ef59b591..93cb3ab17 100644
|
||||
--- a/daemons/lvmlockd/lvmlockd-sanlock.c
|
||||
+++ b/daemons/lvmlockd/lvmlockd-sanlock.c
|
||||
@@ -2420,8 +2420,8 @@ static int release_rename(struct lockspace *ls, struct resource *r)
|
||||
if (!res_args)
|
||||
return -ENOMEM;
|
||||
|
||||
- memcpy(&rd1, &rds->rs, sizeof(struct rd_sanlock));
|
||||
- memcpy(&rd2, &rds->rs, sizeof(struct rd_sanlock));
|
||||
+ rd1.rs = rds->rs;
|
||||
+ rd2.rs = rds->rs;
|
||||
|
||||
res1 = &rd1.rs;
|
||||
res2 = &rd2.rs;
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@ -0,0 +1,33 @@
|
||||
From e10a604ae404ff6a87eced54743d5a539a06a030 Mon Sep 17 00:00:00 2001
|
||||
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||
Date: Thu, 10 Jul 2025 15:13:18 +0200
|
||||
Subject: [PATCH 35/47] sanlock: fix file descriptor leak in error path
|
||||
|
||||
Add proper cleanup of file descriptor in the error handling path
|
||||
to prevent resource leaks when sanlock operations fail.
|
||||
|
||||
(cherry picked from commit f82c46e6735ce123da27fb576371e660697b0bb7)
|
||||
---
|
||||
daemons/lvmlockd/lvmlockd-sanlock.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/daemons/lvmlockd/lvmlockd-sanlock.c b/daemons/lvmlockd/lvmlockd-sanlock.c
|
||||
index 93cb3ab17..17820b91d 100644
|
||||
--- a/daemons/lvmlockd/lvmlockd-sanlock.c
|
||||
+++ b/daemons/lvmlockd/lvmlockd-sanlock.c
|
||||
@@ -320,8 +320,11 @@ static int read_host_id_file(void)
|
||||
break;
|
||||
}
|
||||
}
|
||||
- _fclose(file, (char *)daemon_host_id_file);
|
||||
+
|
||||
out:
|
||||
+ if (file)
|
||||
+ _fclose(file, (char *)daemon_host_id_file);
|
||||
+
|
||||
log_debug("host_id %d from %s", host_id, daemon_host_id_file);
|
||||
return host_id;
|
||||
}
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@ -0,0 +1,30 @@
|
||||
From bf48c1541291aeda537520b664f59249fc85f95b Mon Sep 17 00:00:00 2001
|
||||
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||
Date: Fri, 11 Jul 2025 14:29:41 +0200
|
||||
Subject: [PATCH 36/47] command-lines: fix typo in configurable name
|
||||
|
||||
Fix type in lvm.conf option name used for lvcreate
|
||||
and replace global/mirror_segfault_default with correct
|
||||
name global/mirror_segtype_default.
|
||||
|
||||
(cherry picked from commit 0b7b6ccd79929611131549a70bcb339f0c67530e)
|
||||
---
|
||||
tools/command-lines.in | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tools/command-lines.in b/tools/command-lines.in
|
||||
index d85df7bbd..3d38b1ce7 100644
|
||||
--- a/tools/command-lines.in
|
||||
+++ b/tools/command-lines.in
|
||||
@@ -973,7 +973,7 @@ OP: PV ...
|
||||
IO: --stripes 1
|
||||
ID: lvcreate_mirror_or_raid1
|
||||
DESC: Create a raid1 or mirror LV.
|
||||
-DESC: Implicit type is defined by lvm.conf global/mirror_segfault_default.
|
||||
+DESC: Implicit type is defined by lvm.conf global/mirror_segtype_default.
|
||||
AUTOTYPE: raid1
|
||||
AUTOTYPE: mirror
|
||||
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@ -0,0 +1,30 @@
|
||||
From 7f5a4a9de4aab40f2c243f0f657008da839cb75f Mon Sep 17 00:00:00 2001
|
||||
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||
Date: Thu, 10 Jul 2025 21:40:14 +0200
|
||||
Subject: [PATCH 37/47] tools: simplify LVM_DID_EXEC environment variable
|
||||
|
||||
Set LVM_DID_EXEC to "1" instead of using the command name string,
|
||||
avoiding potential issues with unusual command names and improving
|
||||
consistency in environment variable handling.
|
||||
|
||||
(cherry picked from commit 5d16b1d7348aad816424b2a8e95fd31a59c3e2e2)
|
||||
---
|
||||
tools/lvmcmdline.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
|
||||
index ebb1b87c9..2ecdbd164 100644
|
||||
--- a/tools/lvmcmdline.c
|
||||
+++ b/tools/lvmcmdline.c
|
||||
@@ -3608,7 +3608,7 @@ int lvm2_main(int argc, char **argv)
|
||||
if (is_static() && strcmp(base, "lvm.static") &&
|
||||
path_exists(LVM_PATH) &&
|
||||
!getenv("LVM_DID_EXEC")) {
|
||||
- if (setenv("LVM_DID_EXEC", base, 1))
|
||||
+ if (setenv("LVM_DID_EXEC", "1", 1))
|
||||
log_sys_error("setenv", "LVM_DID_EXEC");
|
||||
if (execvp(LVM_PATH, argv) == -1)
|
||||
log_sys_error("execvp", LVM_PATH);
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@ -0,0 +1,39 @@
|
||||
From 89300351f254ce1fe499f6bae609c16a0b1ef60a Mon Sep 17 00:00:00 2001
|
||||
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||
Date: Wed, 9 Jul 2025 23:26:03 +0200
|
||||
Subject: [PATCH 38/47] gcc: ensure pointer is properly initialized
|
||||
|
||||
Fix gcc warning by ensuring pointers are properly defined and
|
||||
initialized before use in man-generator code to prevent potential
|
||||
undefined behavior.
|
||||
|
||||
(cherry picked from commit a23ef8e26f5468c37d676da15d0125bff6de7095)
|
||||
---
|
||||
tools/man-generator.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/tools/man-generator.c b/tools/man-generator.c
|
||||
index bd161796a..7a60d4327 100644
|
||||
--- a/tools/man-generator.c
|
||||
+++ b/tools/man-generator.c
|
||||
@@ -1219,7 +1219,7 @@ static void _print_cmd_usage_option(const struct command_name *cname,
|
||||
static int _print_man(char *name, char *des_file, int secondary)
|
||||
{
|
||||
const struct command_name *cname;
|
||||
- const struct command_name_args *cna;
|
||||
+ const struct command_name_args *cna = NULL;
|
||||
struct command *cmd, *prev_cmd = NULL;
|
||||
char *lvmname = name;
|
||||
int i, sep = 0;
|
||||
@@ -1363,7 +1363,7 @@ static int _print_man(char *name, char *des_file, int secondary)
|
||||
if (cname && (i == (COMMAND_COUNT - 1))) {
|
||||
_print_cmd_usage_option(cname, cmd);
|
||||
} else {
|
||||
- if (cna->variants > 1)
|
||||
+ if (cna && cna->variants > 1)
|
||||
sep = 1;
|
||||
}
|
||||
}
|
||||
--
|
||||
2.51.0
|
||||
|
||||
40
SOURCES/0039-dmeventd-check-device-exists.patch
Normal file
40
SOURCES/0039-dmeventd-check-device-exists.patch
Normal file
@ -0,0 +1,40 @@
|
||||
From 4ed321be7a9dcd3df99f3175f03bc45d65989c98 Mon Sep 17 00:00:00 2001
|
||||
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||
Date: Tue, 22 Jul 2025 20:34:38 +0200
|
||||
Subject: [PATCH 39/47] dmeventd: check device exists
|
||||
|
||||
Check first whether the monitored device actually really exists,
|
||||
before resolving its device name.
|
||||
|
||||
In the case device is not present in DM table, fail _fill_device_data().
|
||||
|
||||
(cherry picked from commit 175a80157a2116a64f72e912c04b4a45a03c50f6)
|
||||
---
|
||||
daemons/dmeventd/dmeventd.c | 9 ++++++---
|
||||
1 file changed, 6 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/daemons/dmeventd/dmeventd.c b/daemons/dmeventd/dmeventd.c
|
||||
index 2224ba23e..93dfb9bc0 100644
|
||||
--- a/daemons/dmeventd/dmeventd.c
|
||||
+++ b/daemons/dmeventd/dmeventd.c
|
||||
@@ -606,11 +606,14 @@ static int _fill_device_data(struct thread_status *ts)
|
||||
if (!dm_task_run(dmt))
|
||||
goto fail;
|
||||
|
||||
- free(ts->device.name);
|
||||
- if (!(ts->device.name = strdup(dm_task_get_name(dmt))))
|
||||
+ if (!dm_task_get_info(dmt, &dmi))
|
||||
goto fail;
|
||||
|
||||
- if (!dm_task_get_info(dmt, &dmi))
|
||||
+ if (!dmi.exists)
|
||||
+ goto fail;
|
||||
+
|
||||
+ free(ts->device.name);
|
||||
+ if (!(ts->device.name = strdup(dm_task_get_name(dmt))))
|
||||
goto fail;
|
||||
|
||||
ts->device.major = dmi.major;
|
||||
--
|
||||
2.51.0
|
||||
|
||||
53
SOURCES/0040-dmeventd-add-device-existence-check.patch
Normal file
53
SOURCES/0040-dmeventd-add-device-existence-check.patch
Normal file
@ -0,0 +1,53 @@
|
||||
From a7c707334f3b2d571f8fa80db75e631b11e4b09b Mon Sep 17 00:00:00 2001
|
||||
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||
Date: Tue, 22 Jul 2025 20:35:24 +0200
|
||||
Subject: [PATCH 40/47] dmeventd: add device existence check
|
||||
|
||||
Add device existence check after successful wait ioctl to prevent
|
||||
processing events on removed devices.
|
||||
|
||||
When dm_task_run() succeeds on a WAITEVENT ioctl, the success might
|
||||
actually indicate that the device was removed rather than a genuine
|
||||
device event. Without this check, dmeventd would attempt to process
|
||||
ERROR events on non-existent devices, leading to unnecessary error
|
||||
commands and log noise.
|
||||
|
||||
This fix adds a _fill_device_data() call immediately after successful
|
||||
wait completion to verify the device still exists. If the device is
|
||||
gone, execution jumps to the existing ENXIO error path which properly
|
||||
handles device disappearance.
|
||||
|
||||
Note: Future kernel versions may return ENXIO directly from the wait
|
||||
ioctl when devices are removed, making this workaround unnecessary.
|
||||
Until then, this extra INFO ioctl provides the needed verification.
|
||||
|
||||
(cherry picked from commit fa2ec32c4eaab7f6c7e85dd71fba455a0022dc38)
|
||||
---
|
||||
daemons/dmeventd/dmeventd.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/daemons/dmeventd/dmeventd.c b/daemons/dmeventd/dmeventd.c
|
||||
index 93dfb9bc0..b696cc77a 100644
|
||||
--- a/daemons/dmeventd/dmeventd.c
|
||||
+++ b/daemons/dmeventd/dmeventd.c
|
||||
@@ -902,6 +902,9 @@ static int _event_wait(struct thread_status *thread)
|
||||
}
|
||||
|
||||
if (dm_task_run(thread->wait_task)) {
|
||||
+ /* Recheck device info whether is still exists */
|
||||
+ if (!_fill_device_data(thread))
|
||||
+ goto disappeared; /* device is gone... */
|
||||
thread->current_events |= DM_EVENT_DEVICE_ERROR;
|
||||
ret = DM_WAIT_INTR;
|
||||
/* Update event_nr */
|
||||
@@ -910,6 +913,7 @@ static int _event_wait(struct thread_status *thread)
|
||||
} else {
|
||||
switch (dm_task_get_errno(thread->wait_task)) {
|
||||
case ENXIO:
|
||||
+disappeared:
|
||||
log_error("%s disappeared, detaching.",
|
||||
thread->device.name);
|
||||
ret = DM_WAIT_FATAL;
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@ -0,0 +1,37 @@
|
||||
From d825680fd9fae523f166a1ff1a833e5157ccce79 Mon Sep 17 00:00:00 2001
|
||||
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||
Date: Tue, 29 Jul 2025 16:00:39 +0200
|
||||
Subject: [PATCH 41/47] dmeventd: _get_status returns success for non
|
||||
monitoring
|
||||
|
||||
No longer returning EINVAL when the dmeventd is not monitoring
|
||||
any device (there are no registered devices).
|
||||
|
||||
This makes usable i.e. 'dmeventd -R' for the case, the dmeventd
|
||||
was not monnitoring anything during this call.
|
||||
|
||||
Previously this actually cause refuse of 'restart' - since
|
||||
restarting 'dmeventd' has seen failing resutl of a call:
|
||||
DM_EVENT_CMD_GET_STATUS
|
||||
|
||||
(cherry picked from commit 6a31246bdd50ee8619d58704d83e4e916e0608d8)
|
||||
---
|
||||
daemons/dmeventd/dmeventd.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/daemons/dmeventd/dmeventd.c b/daemons/dmeventd/dmeventd.c
|
||||
index b696cc77a..22a713b9a 100644
|
||||
--- a/daemons/dmeventd/dmeventd.c
|
||||
+++ b/daemons/dmeventd/dmeventd.c
|
||||
@@ -685,7 +685,7 @@ static int _get_status(struct message_data *message_data)
|
||||
_lock_mutex();
|
||||
if (!(count = dm_list_size(&_thread_registry))) {
|
||||
_unlock_mutex();
|
||||
- ret = -EINVAL;
|
||||
+ ret = 0; /* no monitored devices */
|
||||
goto out;
|
||||
}
|
||||
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@ -0,0 +1,58 @@
|
||||
From 5af9f7beca2c30815707c412dcbe31a109fd0d62 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Rajnoha <prajnoha@redhat.com>
|
||||
Date: Fri, 25 Jul 2025 10:45:07 +0200
|
||||
Subject: [PATCH 42/47] vgsplit: fix check for not splitting an LV between two
|
||||
VGs
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Fix check for not splitting an LV between two VGs in case
|
||||
where the LVs contains an internal layer.
|
||||
|
||||
For example, integrity layer for RAIDs and splitting a PV that
|
||||
is not part of the RAID LV at all (sdc here):
|
||||
|
||||
❯ vgcreate vg /dev/sda /dev/sdb /dev/sdc
|
||||
Volume group "vg" successfully created
|
||||
|
||||
❯ lvcreate -l1 -m1 --type raid1 --raidintegrity y vg /dev/sda /dev/sdb
|
||||
Logical volume "lvol0" created.
|
||||
|
||||
Before this patch:
|
||||
|
||||
❯ vgsplit vg vg2 /dev/sdc
|
||||
Logical volume vg/lvol0_rimage_0 (part of lvol0) must be inactive.
|
||||
|
||||
❯ vgchange -an vg
|
||||
0 logical volume(s) in volume group "vg" now active
|
||||
|
||||
❯ vgsplit vg vg2 /dev/sdc
|
||||
Can't split LV lvol0_rimage_0 between two Volume Groups
|
||||
|
||||
With this patch applied:
|
||||
|
||||
❯ vgsplit vg vg2 /dev/sdc
|
||||
New volume group "vg2" successfully split from "vg"
|
||||
|
||||
(cherry picked from commit 185455659347722a5eab26f1cc9f189076847e45)
|
||||
---
|
||||
tools/vgsplit.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tools/vgsplit.c b/tools/vgsplit.c
|
||||
index e79195019..aa89835d3 100644
|
||||
--- a/tools/vgsplit.c
|
||||
+++ b/tools/vgsplit.c
|
||||
@@ -170,7 +170,7 @@ static int _move_lvs(struct volume_group *vg_from, struct volume_group *vg_to)
|
||||
|
||||
}
|
||||
|
||||
- if (vg_with == vg_from)
|
||||
+ if (!vg_with || vg_with == vg_from)
|
||||
continue;
|
||||
|
||||
/* Move this LV */
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@ -0,0 +1,88 @@
|
||||
From 147d05c177c39d298f02fc6f786e476308413133 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Rajnoha <prajnoha@redhat.com>
|
||||
Date: Tue, 12 Aug 2025 11:32:18 +0200
|
||||
Subject: [PATCH 43/47] vgsplit: fix check for not splitting an LV between two
|
||||
VGs for cachevol
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
When cachevol was used for the cache LV, the check for not splitting an
|
||||
LV between two VGs was incorrect, not allowing to split the VG in cases
|
||||
it should have been possible.
|
||||
|
||||
For example, splitting a VG which contains the cache LV with cachevol
|
||||
only on two devices (sda and sdb here) and leaving third device completely
|
||||
unused (sdc here) should clearly allow us to split it into a new VG:
|
||||
|
||||
❯ vgcreate vg /dev/sd{a..c}
|
||||
Physical volume "/dev/sda" successfully created.
|
||||
Physical volume "/dev/sdb" successfully created.
|
||||
Physical volume "/dev/sdc" successfully created.
|
||||
Volume group "vg" successfully created
|
||||
|
||||
❯ lvcreate -l2 -n main vg /dev/sda
|
||||
Logical volume "main" created.
|
||||
|
||||
❯ lvcreate -l2 -n fast vg /dev/sdb
|
||||
Logical volume "fast" created.
|
||||
|
||||
❯ lvconvert -y --type cache --cachevol fast vg/main
|
||||
Logical volume vg/main is now cached.
|
||||
|
||||
❯ lvs -a -o name,devices vg
|
||||
lv_name devices
|
||||
[fast_cvol] /dev/sdb(0)
|
||||
main main_corig(0)
|
||||
[main_corig] /dev/sda(0)
|
||||
|
||||
❯ lsblk -o name /dev/sd{a..c}
|
||||
NAME
|
||||
sda
|
||||
└─vg-main_corig
|
||||
└─vg-main
|
||||
sdb
|
||||
└─vg-fast_cvol
|
||||
├─vg-fast_cvol-cdata
|
||||
│ └─vg-main
|
||||
└─vg-fast_cvol-cmeta
|
||||
└─vg-main
|
||||
sdc
|
||||
|
||||
Before this patch:
|
||||
|
||||
❯ vgsplit vg vg2 /dev/sdc
|
||||
Logical volume vg/main must be inactive.
|
||||
|
||||
❯ vgchange -an vg
|
||||
0 logical volume(s) in volume group "vg" now active
|
||||
|
||||
❯ vgsplit vg vg2 /dev/sdc
|
||||
Can't split LV main between two Volume Groups
|
||||
|
||||
With this patch applied:
|
||||
|
||||
❯ vgsplit vg vg2 /dev/sdc
|
||||
New volume group "vg2" successfully split from "vg"
|
||||
|
||||
(cherry picked from commit 3fe57cc892fc984c30fb14c866a109ef17772ed4)
|
||||
---
|
||||
tools/vgsplit.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/tools/vgsplit.c b/tools/vgsplit.c
|
||||
index aa89835d3..5d6c0a06c 100644
|
||||
--- a/tools/vgsplit.c
|
||||
+++ b/tools/vgsplit.c
|
||||
@@ -450,6 +450,8 @@ static int _move_cache(struct volume_group *vg_from,
|
||||
|
||||
if (lv_is_cache_vol(lv)) {
|
||||
fast = lv;
|
||||
+ } else if (lv_is_cache_vol(seg->lv)) {
|
||||
+ fast = seg->lv;
|
||||
} else {
|
||||
data = seg_lv(seg, 0);
|
||||
meta = seg->metadata_lv;
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@ -0,0 +1,51 @@
|
||||
From c370fe563dd095a09f6e070afb8a5c8e4915ec47 Mon Sep 17 00:00:00 2001
|
||||
From: David Teigland <teigland@redhat.com>
|
||||
Date: Fri, 8 Aug 2025 12:36:11 -0500
|
||||
Subject: [PATCH 44/47] lvmdevices: do not create system.devices when deleting
|
||||
entries
|
||||
|
||||
When using "lvmdevices --deldev" or "lvmdevices --delpvid" and no
|
||||
system.devices file exists, the commands should not create the file.
|
||||
|
||||
(cherry picked from commit e61aab70498a887557c133fcba21fcc41345d272)
|
||||
---
|
||||
test/shell/devicesfile-edit.sh | 7 +++++++
|
||||
tools/lvmdevices.c | 4 ++++
|
||||
2 files changed, 11 insertions(+)
|
||||
|
||||
diff --git a/test/shell/devicesfile-edit.sh b/test/shell/devicesfile-edit.sh
|
||||
index 5f8eb90ee..4b8f9c008 100644
|
||||
--- a/test/shell/devicesfile-edit.sh
|
||||
+++ b/test/shell/devicesfile-edit.sh
|
||||
@@ -249,6 +249,13 @@ lvmdevices --update --delnotfound
|
||||
not grep PVID=aaa $DF
|
||||
not grep PVID=bbb $DF
|
||||
|
||||
+# test that deldev does not create devices file when it doesn't exist
|
||||
+rm -f $DF
|
||||
+test ! -e $DF
|
||||
+not lvmdevices --deldev "$LOOP1"
|
||||
+test ! -e $DF
|
||||
+not lvmdevices --delpvid "$PVID1"
|
||||
+test ! -e $DF
|
||||
|
||||
# TODO: add/rem of partitions of same device
|
||||
|
||||
diff --git a/tools/lvmdevices.c b/tools/lvmdevices.c
|
||||
index 7f10038d4..65399c96c 100644
|
||||
--- a/tools/lvmdevices.c
|
||||
+++ b/tools/lvmdevices.c
|
||||
@@ -590,6 +590,10 @@ int lvmdevices(struct cmd_context *cmd, int argc, char **argv)
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
if (!devices_file_exists(cmd)) {
|
||||
+ if (arg_is_set(cmd, deldev_ARG) || arg_is_set(cmd, delpvid_ARG) || arg_is_set(cmd, update_ARG)) {
|
||||
+ log_error("Devices file does not exist.");
|
||||
+ return ECMD_FAILED;
|
||||
+ }
|
||||
if (!devices_file_touch(cmd)) {
|
||||
log_error("Failed to create the devices file.");
|
||||
return ECMD_FAILED;
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@ -0,0 +1,51 @@
|
||||
From 85a712e95a5c0127d27ca3bbbe7019d54393cc33 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Rajnoha <prajnoha@redhat.com>
|
||||
Date: Fri, 29 Aug 2025 13:43:20 +0200
|
||||
Subject: [PATCH 45/47] tools: pvchange: unlock devices file at the end of cmd
|
||||
processing
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Unlock devices file at the end of cmd processing, after all the PVs are
|
||||
processed, not after the first processed PV.
|
||||
|
||||
Before this patch:
|
||||
|
||||
❯ pvchange -u /dev/sda /dev/sdb
|
||||
Physical volume "/dev/sda" changed
|
||||
WARNING: Devices file unlock no fd.
|
||||
Physical volume "/dev/sdb" changed
|
||||
2 physical volumes changed / 0 physical volumes not changed
|
||||
|
||||
With this patch applied:
|
||||
|
||||
❯ pvchange -u /dev/sda /dev/sdb
|
||||
Physical volume "/dev/sda" changed
|
||||
Physical volume "/dev/sdb" changed
|
||||
2 physical volumes changed / 0 physical volumes not changed
|
||||
|
||||
The lvm_run_command/devices_file_exit/unlock_devices_file will
|
||||
do the unlock at the very end of cmd processing.
|
||||
|
||||
(cherry picked from commit 16d3195a69fbe15d9fad4a16cceec468ea542e5a)
|
||||
---
|
||||
tools/pvchange.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tools/pvchange.c b/tools/pvchange.c
|
||||
index 339d990ca..d7376c499 100644
|
||||
--- a/tools/pvchange.c
|
||||
+++ b/tools/pvchange.c
|
||||
@@ -194,7 +194,7 @@ static int _pvchange_single(struct cmd_context *cmd, struct volume_group *vg,
|
||||
log_error("Failed to set pvid for devices file.");
|
||||
if (!device_ids_write(cmd))
|
||||
log_warn("Failed to update devices file.");
|
||||
- unlock_devices_file(cmd);
|
||||
+ //unlock_devices_file(cmd);
|
||||
}
|
||||
|
||||
log_print_unless_silent("Physical volume \"%s\" changed", pv_name);
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
From dcae883b382f03a58a04d72f6a3bb446e4814ae9 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Rajnoha <prajnoha@redhat.com>
|
||||
Date: Fri, 29 Aug 2025 13:50:20 +0200
|
||||
Subject: [PATCH 46/47] tools: pvchange: unlock devices file at the end of cmd
|
||||
processing
|
||||
|
||||
Remove the line, not just comment out.
|
||||
|
||||
(cherry picked from commit d89869f17ec217ee758918047b7edba6c9aa017a)
|
||||
---
|
||||
tools/pvchange.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/tools/pvchange.c b/tools/pvchange.c
|
||||
index d7376c499..1b43b0154 100644
|
||||
--- a/tools/pvchange.c
|
||||
+++ b/tools/pvchange.c
|
||||
@@ -194,7 +194,6 @@ static int _pvchange_single(struct cmd_context *cmd, struct volume_group *vg,
|
||||
log_error("Failed to set pvid for devices file.");
|
||||
if (!device_ids_write(cmd))
|
||||
log_warn("Failed to update devices file.");
|
||||
- //unlock_devices_file(cmd);
|
||||
}
|
||||
|
||||
log_print_unless_silent("Physical volume \"%s\" changed", pv_name);
|
||||
--
|
||||
2.51.0
|
||||
|
||||
162
SOURCES/0047-make-generate.patch
Normal file
162
SOURCES/0047-make-generate.patch
Normal file
@ -0,0 +1,162 @@
|
||||
From 3a6c6366c0605fbb7b0001d920da6bd801bff689 Mon Sep 17 00:00:00 2001
|
||||
From: Marian Csontos <mcsontos@redhat.com>
|
||||
Date: Mon, 29 Sep 2025 15:44:24 +0200
|
||||
Subject: [PATCH 47/47] make: generate
|
||||
|
||||
---
|
||||
man/lvchange.8_pregen | 6 +++---
|
||||
man/lvconvert.8_pregen | 8 ++++----
|
||||
man/lvcreate.8_pregen | 10 +++++-----
|
||||
man/lvextend.8_pregen | 2 +-
|
||||
man/lvresize.8_pregen | 2 +-
|
||||
5 files changed, 14 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/man/lvchange.8_pregen b/man/lvchange.8_pregen
|
||||
index f45d8001c..1e87db1b8 100644
|
||||
--- a/man/lvchange.8_pregen
|
||||
+++ b/man/lvchange.8_pregen
|
||||
@@ -891,7 +891,7 @@ See \fBvgcfgbackup\fP(8) for more information.
|
||||
Specifies when writes to a cache LV should be considered complete.
|
||||
\fBwriteback\fP considers a write complete as soon as it is
|
||||
stored in the cache pool.
|
||||
-\fBwritethough\fP considers a write complete only when it has
|
||||
+\fBwritethrough\fP considers a write complete only when it has
|
||||
been stored in both the cache pool and on the origin LV.
|
||||
While writethrough may be slower for writes, it is more
|
||||
resilient if something should happen to a device associated with the
|
||||
@@ -923,7 +923,7 @@ See \fBlvm.conf\fP(5) for more information about profiles.
|
||||
.
|
||||
.TP
|
||||
.O_compression
|
||||
-Controls whether compression is enabled or disable for VDO volume.
|
||||
+Controls whether compression is enabled or disabled for VDO volume.
|
||||
See \fBlvmvdo\fP(7) for more information about VDO usage.
|
||||
.
|
||||
.TP
|
||||
@@ -948,7 +948,7 @@ messages sent to the log file and/or syslog (if configured).
|
||||
.
|
||||
.TP
|
||||
.O_deduplication
|
||||
-Controls whether deduplication is enabled or disable for VDO volume.
|
||||
+Controls whether deduplication is enabled or disabled for VDO volume.
|
||||
See \fBlvmvdo\fP(7) for more information about VDO usage.
|
||||
.
|
||||
.TP
|
||||
diff --git a/man/lvconvert.8_pregen b/man/lvconvert.8_pregen
|
||||
index 7ff0d1d79..d5173a651 100644
|
||||
--- a/man/lvconvert.8_pregen
|
||||
+++ b/man/lvconvert.8_pregen
|
||||
@@ -1750,7 +1750,7 @@ Specifies the cache metadata format used by cache target.
|
||||
Specifies when writes to a cache LV should be considered complete.
|
||||
\fBwriteback\fP considers a write complete as soon as it is
|
||||
stored in the cache pool.
|
||||
-\fBwritethough\fP considers a write complete only when it has
|
||||
+\fBwritethrough\fP considers a write complete only when it has
|
||||
been stored in both the cache pool and on the origin LV.
|
||||
While writethrough may be slower for writes, it is more
|
||||
resilient if something should happen to a device associated with the
|
||||
@@ -1807,7 +1807,7 @@ See \fBlvm.conf\fP(5) for more information about profiles.
|
||||
.
|
||||
.TP
|
||||
.O_compression
|
||||
-Controls whether compression is enabled or disable for VDO volume.
|
||||
+Controls whether compression is enabled or disabled for VDO volume.
|
||||
See \fBlvmvdo\fP(7) for more information about VDO usage.
|
||||
.
|
||||
.TP
|
||||
@@ -1824,7 +1824,7 @@ messages sent to the log file and/or syslog (if configured).
|
||||
.
|
||||
.TP
|
||||
.O_deduplication
|
||||
-Controls whether deduplication is enabled or disable for VDO volume.
|
||||
+Controls whether deduplication is enabled or disabled for VDO volume.
|
||||
See \fBlvmvdo\fP(7) for more information about VDO usage.
|
||||
.
|
||||
.TP
|
||||
@@ -2009,7 +2009,7 @@ Use VDO type volume for pool data volume.
|
||||
.
|
||||
.TP
|
||||
.O_poolmetadata
|
||||
-The name of a an LV to use for storing pool metadata.
|
||||
+The name of an LV to use for storing pool metadata.
|
||||
.
|
||||
.TP
|
||||
.O_poolmetadatasize
|
||||
diff --git a/man/lvcreate.8_pregen b/man/lvcreate.8_pregen
|
||||
index 5a8c9cc2e..8fc5b34d2 100644
|
||||
--- a/man/lvcreate.8_pregen
|
||||
+++ b/man/lvcreate.8_pregen
|
||||
@@ -633,7 +633,7 @@ Create a striped LV.
|
||||
.P
|
||||
.
|
||||
Create a raid1 or mirror LV.
|
||||
-Implicit type is defined by lvm.conf global/mirror_segfault_default.
|
||||
+Implicit type is defined by lvm.conf global/mirror_segtype_default.
|
||||
.P
|
||||
.B lvcreate
|
||||
.O_mirrors
|
||||
@@ -1575,7 +1575,7 @@ Specifies the cache metadata format used by cache target.
|
||||
Specifies when writes to a cache LV should be considered complete.
|
||||
\fBwriteback\fP considers a write complete as soon as it is
|
||||
stored in the cache pool.
|
||||
-\fBwritethough\fP considers a write complete only when it has
|
||||
+\fBwritethrough\fP considers a write complete only when it has
|
||||
been stored in both the cache pool and on the origin LV.
|
||||
While writethrough may be slower for writes, it is more
|
||||
resilient if something should happen to a device associated with the
|
||||
@@ -1632,7 +1632,7 @@ See \fBlvm.conf\fP(5) for more information about profiles.
|
||||
.
|
||||
.TP
|
||||
.O_compression
|
||||
-Controls whether compression is enabled or disable for VDO volume.
|
||||
+Controls whether compression is enabled or disabled for VDO volume.
|
||||
See \fBlvmvdo\fP(7) for more information about VDO usage.
|
||||
.
|
||||
.TP
|
||||
@@ -1657,7 +1657,7 @@ messages sent to the log file and/or syslog (if configured).
|
||||
.
|
||||
.TP
|
||||
.O_deduplication
|
||||
-Controls whether deduplication is enabled or disable for VDO volume.
|
||||
+Controls whether deduplication is enabled or disabled for VDO volume.
|
||||
See \fBlvmvdo\fP(7) for more information about VDO usage.
|
||||
.
|
||||
.TP
|
||||
@@ -1847,7 +1847,7 @@ This is useful for skipping a potentially long and resource intensive initial
|
||||
sync of an empty mirror/raid1/raid4/raid5 and raid10 LV.
|
||||
This option is not valid for raid6, because raid6 relies on proper parity
|
||||
(P and Q Syndromes) being created during initial synchronization in order
|
||||
-to reconstruct proper user date in case of device failures.
|
||||
+to reconstruct proper user data in case of device failures.
|
||||
raid0 and raid0_meta do not provide any data copies or parity support
|
||||
and thus do not support initial synchronization.
|
||||
.
|
||||
diff --git a/man/lvextend.8_pregen b/man/lvextend.8_pregen
|
||||
index e52d46fd4..2729d6eda 100644
|
||||
--- a/man/lvextend.8_pregen
|
||||
+++ b/man/lvextend.8_pregen
|
||||
@@ -713,7 +713,7 @@ This is useful for skipping a potentially long and resource intensive initial
|
||||
sync of an empty mirror/raid1/raid4/raid5 and raid10 LV.
|
||||
This option is not valid for raid6, because raid6 relies on proper parity
|
||||
(P and Q Syndromes) being created during initial synchronization in order
|
||||
-to reconstruct proper user date in case of device failures.
|
||||
+to reconstruct proper user data in case of device failures.
|
||||
raid0 and raid0_meta do not provide any data copies or parity support
|
||||
and thus do not support initial synchronization.
|
||||
.
|
||||
diff --git a/man/lvresize.8_pregen b/man/lvresize.8_pregen
|
||||
index a1f127a1e..8c1ff4dfd 100644
|
||||
--- a/man/lvresize.8_pregen
|
||||
+++ b/man/lvresize.8_pregen
|
||||
@@ -639,7 +639,7 @@ This is useful for skipping a potentially long and resource intensive initial
|
||||
sync of an empty mirror/raid1/raid4/raid5 and raid10 LV.
|
||||
This option is not valid for raid6, because raid6 relies on proper parity
|
||||
(P and Q Syndromes) being created during initial synchronization in order
|
||||
-to reconstruct proper user date in case of device failures.
|
||||
+to reconstruct proper user data in case of device failures.
|
||||
raid0 and raid0_meta do not provide any data copies or parity support
|
||||
and thus do not support initial synchronization.
|
||||
.
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@ -0,0 +1,48 @@
|
||||
From 52efa6f5a1a5a9057130d0b3c8acfdb8feff2e22 Mon Sep 17 00:00:00 2001
|
||||
From: David Teigland <teigland@redhat.com>
|
||||
Date: Mon, 27 Oct 2025 11:01:16 -0500
|
||||
Subject: [PATCH] activating raid LV with partial snapshot is an error
|
||||
|
||||
Detect and report this error early in the command, with
|
||||
a clear message, including a possible remedy. Previously,
|
||||
the command failed at a lower level, where the message is
|
||||
confusing or even misleading.
|
||||
|
||||
Old error message:
|
||||
"Aborting. LV vg/snap1 is incomplete and --activationmode partial was not specified."
|
||||
|
||||
New error message:
|
||||
"Activating raid LV vg/main requires the removal of partial snapshot vg/snap1."
|
||||
|
||||
(cherry picked from commit 2760e804630a36bab2c3938ce9ac0b08c5e75395)
|
||||
---
|
||||
tools/toollib.c | 13 +++++++++++++
|
||||
1 file changed, 13 insertions(+)
|
||||
|
||||
diff --git a/tools/toollib.c b/tools/toollib.c
|
||||
index a7384dd60..b9fa67446 100644
|
||||
--- a/tools/toollib.c
|
||||
+++ b/tools/toollib.c
|
||||
@@ -781,6 +781,19 @@ int lv_change_activate(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
}
|
||||
}
|
||||
|
||||
+ if (lv_is_raid(lv) && lv_is_origin(lv) && lv_is_partial(lv)) {
|
||||
+ struct lv_list *lvl;
|
||||
+ dm_list_iterate_items(lvl, &lv->vg->lvs) {
|
||||
+ if (lv_is_cow(lvl->lv) &&
|
||||
+ (lv_origin_lv(lvl->lv) == lv) &&
|
||||
+ lv_is_partial(lvl->lv)) {
|
||||
+ log_error("Activating raid LV %s requires the removal of partial snapshot %s.",
|
||||
+ display_lvname(lv), display_lvname(lvl->lv));
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (is_change_activating(activate) &&
|
||||
lvmcache_has_duplicate_devs() &&
|
||||
vg_has_duplicate_pvs(lv->vg) &&
|
||||
--
|
||||
2.51.1
|
||||
|
||||
@ -0,0 +1,34 @@
|
||||
From a71342640ddf81b73625e55149f1077245ee7412 Mon Sep 17 00:00:00 2001
|
||||
From: Heinz Mauelshagen <heinzm@redhat.com>
|
||||
Date: Mon, 27 Oct 2025 17:37:09 +0100
|
||||
Subject: [PATCH 49/51] lv_manip: show a warning during classic snapshot
|
||||
creation on a RaidLV.
|
||||
|
||||
The RaidLV will fail to activate in case of the loss of any of its snapshots.
|
||||
Once created, commit 2760e804630a36bab2c3938ce9ac0b08c5e75395 will
|
||||
catch any loss of such snapshots and provide remedy information.
|
||||
|
||||
(cherry picked from commit ae81b41811ede78b77f6badf0c65c88fa56cc951)
|
||||
---
|
||||
lib/metadata/lv_manip.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
|
||||
index 577ffd0b3..e7405f1dc 100644
|
||||
--- a/lib/metadata/lv_manip.c
|
||||
+++ b/lib/metadata/lv_manip.c
|
||||
@@ -9654,6 +9654,11 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
|
||||
goto revert_new_lv;
|
||||
}
|
||||
|
||||
+ if (lp->snapshot && origin_lv && lv_is_raid(origin_lv)) {
|
||||
+ log_warn("WARNING: Loss of snapshot %s will cause the activation of the %s LV %s to fail!",
|
||||
+ lp->lv_name, lvseg_name(first_seg(origin_lv)), display_lvname(origin_lv));
|
||||
+ }
|
||||
+
|
||||
/* Do not scan this LV until properly zeroed/wiped. */
|
||||
if (_should_wipe_lv(lp, lv, 0))
|
||||
lv->status |= LV_NOSCAN;
|
||||
--
|
||||
2.51.1
|
||||
|
||||
@ -0,0 +1,67 @@
|
||||
From 4ad6776b11103a864b98963c3540e87e13db2450 Mon Sep 17 00:00:00 2001
|
||||
From: Heinz Mauelshagen <heinzm@redhat.com>
|
||||
Date: Mon, 27 Oct 2025 19:12:25 +0100
|
||||
Subject: [PATCH 50/51] test: add new test for snapshot on raid
|
||||
creation/activation warning/error
|
||||
|
||||
(cherry picked from commit 6704ef4012e8c187deaeadb1275e2d80661c3941)
|
||||
---
|
||||
...shot-create-warning-activate-error-raid.sh | 46 +++++++++++++++++++
|
||||
1 file changed, 46 insertions(+)
|
||||
create mode 100644 test/shell/snapshot-create-warning-activate-error-raid.sh
|
||||
|
||||
diff --git a/test/shell/snapshot-create-warning-activate-error-raid.sh b/test/shell/snapshot-create-warning-activate-error-raid.sh
|
||||
new file mode 100644
|
||||
index 000000000..c5b65d018
|
||||
--- /dev/null
|
||||
+++ b/test/shell/snapshot-create-warning-activate-error-raid.sh
|
||||
@@ -0,0 +1,46 @@
|
||||
+#!/usr/bin/env bash
|
||||
+
|
||||
+# Copyright (C) 2025 Red Hat, Inc. All rights reserved.
|
||||
+#
|
||||
+# This copyrighted material is made available to anyone wishing to use,
|
||||
+# modify, copy, or redistribute it subject to the terms and conditions
|
||||
+# of the GNU General Public License v.2.
|
||||
+#
|
||||
+# You should have received a copy of the GNU General Public License
|
||||
+# along with this program; if not, write to the Free Software Foundation,
|
||||
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
+
|
||||
+# Test for classic snapshots of raid throwing warning/error on creation/activation
|
||||
+
|
||||
+
|
||||
+. lib/inittest --skip-with-lvmpolld
|
||||
+
|
||||
+aux have_raid 1 3 0 || skip
|
||||
+
|
||||
+aux prepare_devs 2 50
|
||||
+
|
||||
+# Create Raid1LV and wait for initial sync to finish.
|
||||
+vgcreate $SHARED $vg "$dev1" "$dev2"
|
||||
+lvcreate -y --type raid1 -m1 -n $lv1 -L32M $vg
|
||||
+aux wait_for_sync $vg $lv1
|
||||
+
|
||||
+# Create classic snapshot of Raid1LV and check for warning message.
|
||||
+lvcreate -y -s -n snap -L12M $vg/$lv1 "$dev1" 2>&1 | grep 'WARNING: Loss of snapshot ' >/dev/null 2>&1
|
||||
+
|
||||
+# Disable all LVs and the first PV with the snapshot allocated on.
|
||||
+vgchange -an $vg
|
||||
+aux disable_dev "$dev1"
|
||||
+
|
||||
+# Active vg and check for warning message.
|
||||
+not vgchange -ay $vg 2>&1 | grep -E 'Activating raid LV .* requires the removal of partial snapshot' >/dev/null 2>&1
|
||||
+
|
||||
+# Remove the snapshot having lost its backing PV.
|
||||
+lvremove -y $vg/snap
|
||||
+
|
||||
+# Active vg and check for warning message not being displayed.
|
||||
+vgchange -ay $vg 2>&1 | not grep -E 'Activating raid LV .* requires the removal of partial snapshot' >/dev/null 2>&1
|
||||
+
|
||||
+ls $DM_DEV_DIR/$vg/$lv1
|
||||
+
|
||||
+lvremove -y $vg/$lv1
|
||||
+vgremove -ff $vg
|
||||
--
|
||||
2.51.1
|
||||
|
||||
36
SOURCES/0051-WHATS_NEW-update.patch
Normal file
36
SOURCES/0051-WHATS_NEW-update.patch
Normal file
@ -0,0 +1,36 @@
|
||||
From 8af5d6dda5a1e29e0fa9e573ca6f6cf69d07aa9b Mon Sep 17 00:00:00 2001
|
||||
From: Heinz Mauelshagen <heinzm@redhat.com>
|
||||
Date: Mon, 27 Oct 2025 19:15:06 +0100
|
||||
Subject: [PATCH 51/51] WHATS_NEW: update
|
||||
|
||||
---
|
||||
WHATS_NEW | 11 +++++++++++
|
||||
1 file changed, 11 insertions(+)
|
||||
|
||||
diff --git a/WHATS_NEW b/WHATS_NEW
|
||||
index 41fea1a7a..19442f8c5 100644
|
||||
--- a/WHATS_NEW
|
||||
+++ b/WHATS_NEW
|
||||
@@ -1,8 +1,19 @@
|
||||
+Version 2.03.37 -
|
||||
+==================
|
||||
+ Warn on classic snapshot on raid creation and error on activation + test.
|
||||
+
|
||||
+Version 2.03.35 -
|
||||
+==================
|
||||
+ Fix unlocking devices file only after all PVs are processed.
|
||||
+ Avoid creating system.devices when deleting entries.
|
||||
+ Fix --lockopt handling in lvmlockd when --nolocking is used.
|
||||
+
|
||||
Version 2.03.34 -
|
||||
==================
|
||||
Fix lvmdevices --deldev/--delpvid to error out if devices file not writeable.
|
||||
Fix lvresize corruption in LV->crypt->FS stack if near crypt min size limit.
|
||||
Fix autoactivation on top of loop dev PVs to trigger once for change uevents.
|
||||
+ Add lvmlockd --lockopt repair to reinitialize corrupted sanlock leases.
|
||||
|
||||
Version 2.03.33 - 27th June 2025
|
||||
================================
|
||||
--
|
||||
2.51.1
|
||||
|
||||
@ -0,0 +1,240 @@
|
||||
From 48c68c0cc2cef75f6aa1c6a3e68c44b3a806f60a Mon Sep 17 00:00:00 2001
|
||||
From: David Teigland <teigland@redhat.com>
|
||||
Date: Mon, 13 Oct 2025 14:36:58 -0500
|
||||
Subject: [PATCH] integrity: allow creating imeta with more than one segment
|
||||
|
||||
The imeta LV is already permitted to have more than one segment when
|
||||
extending, so there's no reason to prevent this in the initial state.
|
||||
|
||||
(cherry picked from commit 724747d7729c38133c4d71f96edd6e2be9dd44a0)
|
||||
---
|
||||
lib/metadata/integrity_manip.c | 5 -
|
||||
test/shell/integrity-imeta-segs.sh | 200 +++++++++++++++++++++++++++++
|
||||
2 files changed, 200 insertions(+), 5 deletions(-)
|
||||
create mode 100755 test/shell/integrity-imeta-segs.sh
|
||||
|
||||
diff --git a/lib/metadata/integrity_manip.c b/lib/metadata/integrity_manip.c
|
||||
index 43a9143a5..be2d458b3 100644
|
||||
--- a/lib/metadata/integrity_manip.c
|
||||
+++ b/lib/metadata/integrity_manip.c
|
||||
@@ -151,11 +151,6 @@ static int _lv_create_integrity_metadata(struct cmd_context *cmd,
|
||||
return 0;
|
||||
}
|
||||
|
||||
- if (dm_list_size(&lv->segments) > 1) {
|
||||
- log_error("Integrity metadata uses more than one segment.");
|
||||
- return 0;
|
||||
- }
|
||||
-
|
||||
*meta_lv = lv;
|
||||
return 1;
|
||||
}
|
||||
diff --git a/test/shell/integrity-imeta-segs.sh b/test/shell/integrity-imeta-segs.sh
|
||||
new file mode 100755
|
||||
index 000000000..4df1a7dda
|
||||
--- /dev/null
|
||||
+++ b/test/shell/integrity-imeta-segs.sh
|
||||
@@ -0,0 +1,200 @@
|
||||
+#!/usr/bin/env bash
|
||||
+
|
||||
+# Copyright (C) 2025 Red Hat, Inc. All rights reserved.
|
||||
+#
|
||||
+# This copyrighted material is made available to anyone wishing to use,
|
||||
+# modify, copy, or redistribute it subject to the terms and conditions
|
||||
+# of the GNU General Public License v.2.
|
||||
+#
|
||||
+# You should have received a copy of the GNU General Public License
|
||||
+# along with this program; if not, write to the Free Software Foundation,
|
||||
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
+
|
||||
+# Test creating integrity metadata LV requiring multiple LV segments
|
||||
+
|
||||
+SKIP_WITH_LOW_SPACE=256
|
||||
+
|
||||
+. lib/inittest
|
||||
+
|
||||
+aux have_integrity 1 5 0 || skip
|
||||
+
|
||||
+which mkfs.xfs || skip
|
||||
+mnt="mnt"
|
||||
+mkdir -p $mnt
|
||||
+
|
||||
+# Use awk instead of anoyingly long log out from printf
|
||||
+#printf "%0.sA" {1..16384} >> fileA
|
||||
+awk 'BEGIN { while (z++ < 16384) printf "A" }' > fileA
|
||||
+awk 'BEGIN { while (z++ < 16384) printf "B" }' > fileB
|
||||
+awk 'BEGIN { while (z++ < 16384) printf "C" }' > fileC
|
||||
+
|
||||
+# generate random data
|
||||
+dd if=/dev/urandom of=randA bs=512K count=2
|
||||
+dd if=/dev/urandom of=randB bs=512K count=3
|
||||
+dd if=/dev/urandom of=randC bs=512K count=4
|
||||
+
|
||||
+_prepare_vg() {
|
||||
+ vgcreate $SHARED $vg "$dev1" "$dev2"
|
||||
+ pvs
|
||||
+}
|
||||
+
|
||||
+_add_data_to_lv() {
|
||||
+ mkfs.xfs -f "$DM_DEV_DIR/$vg/$lv1"
|
||||
+
|
||||
+ mount "$DM_DEV_DIR/$vg/$lv1" $mnt
|
||||
+
|
||||
+ # add original data
|
||||
+ cp randA $mnt
|
||||
+ cp randB $mnt
|
||||
+ cp randC $mnt
|
||||
+ mkdir $mnt/1
|
||||
+ cp fileA $mnt/1
|
||||
+ cp fileB $mnt/1
|
||||
+ cp fileC $mnt/1
|
||||
+ mkdir $mnt/2
|
||||
+ cp fileA $mnt/2
|
||||
+ cp fileB $mnt/2
|
||||
+ cp fileC $mnt/2
|
||||
+
|
||||
+ umount $mnt
|
||||
+}
|
||||
+
|
||||
+_verify_data_on_lv() {
|
||||
+ mount "$DM_DEV_DIR/$vg/$lv1" $mnt
|
||||
+
|
||||
+ diff randA $mnt/randA
|
||||
+ diff randB $mnt/randB
|
||||
+ diff randC $mnt/randC
|
||||
+ diff fileA $mnt/1/fileA
|
||||
+ diff fileB $mnt/1/fileB
|
||||
+ diff fileC $mnt/1/fileC
|
||||
+ diff fileA $mnt/2/fileA
|
||||
+ diff fileB $mnt/2/fileB
|
||||
+ diff fileC $mnt/2/fileC
|
||||
+
|
||||
+ umount $mnt
|
||||
+}
|
||||
+
|
||||
+_replace_data_on_lv() {
|
||||
+ mount "$DM_DEV_DIR/$vg/$lv1" $mnt
|
||||
+
|
||||
+ rm $mnt/randA
|
||||
+ rm $mnt/randB
|
||||
+ rm $mnt/randC
|
||||
+ rm $mnt/1/fileA
|
||||
+ rm $mnt/1/fileB
|
||||
+ rm $mnt/1/fileC
|
||||
+ rm $mnt/2/fileA
|
||||
+ rm $mnt/2/fileB
|
||||
+ rm $mnt/2/fileC
|
||||
+
|
||||
+ cp randA $mnt
|
||||
+ cp randB $mnt
|
||||
+ cp randC $mnt
|
||||
+ cp fileA $mnt/1
|
||||
+ cp fileB $mnt/1
|
||||
+ cp fileC $mnt/1
|
||||
+ cp fileA $mnt/2
|
||||
+ cp fileB $mnt/2
|
||||
+ cp fileC $mnt/2
|
||||
+
|
||||
+ umount $mnt
|
||||
+}
|
||||
+
|
||||
+# Create a raid LV with multi-segment images (based on an example of vg metadata)
|
||||
+# Strategy: Fragment the PV by creating/removing temporary LVs, causing the raid
|
||||
+# images to be allocated in multiple non-contiguous segments. When adding integrity,
|
||||
+# the imeta will likely also need multiple segments due to the fragmented free space.
|
||||
+
|
||||
+# Use smaller extent size to reduce total device size needed
|
||||
+# With 2MB extents, a 400MB raid LV can have multi-segment images with smaller devices
|
||||
+aux prepare_devs 2 256
|
||||
+vgcreate -s 2m $SHARED $vg "$dev1" "$dev2"
|
||||
+
|
||||
+# Two-phase fragmentation strategy:
|
||||
+# Phase 1: Create some larger LVs, then create the raid LV which will consume the gaps
|
||||
+# Phase 2: Create small fragments in the remaining space where imeta will allocate
|
||||
+
|
||||
+# Phase 1: Create large fragments so the raid LV will have 2-3 segments
|
||||
+lvcreate -n frag1 -L 60M -an $vg "$dev1"
|
||||
+lvcreate -n frag2 -L 60M -an $vg "$dev2"
|
||||
+
|
||||
+lvcreate -n temp1 -L 80M -an $vg "$dev1"
|
||||
+lvcreate -n temp2 -L 80M -an $vg "$dev2"
|
||||
+
|
||||
+lvcreate -n frag3 -L 40M -an $vg "$dev1"
|
||||
+lvcreate -n frag4 -L 40M -an $vg "$dev2"
|
||||
+
|
||||
+# Remove temp1 and temp2, leaving large gaps for the raid LV
|
||||
+lvremove -y $vg/temp1 $vg/temp2
|
||||
+
|
||||
+pvs -o+pv_free,pv_used
|
||||
+
|
||||
+# Now create a raid1 LV that will use the large fragmented gaps
|
||||
+# This will result in raid images with 2 segments
|
||||
+lvcreate --type raid1 -m1 -n $lv1 -L 120M -an $vg
|
||||
+
|
||||
+lvchange -ay $vg/$lv1
|
||||
+_add_data_to_lv
|
||||
+lvchange -an $vg/$lv1
|
||||
+
|
||||
+lvs -a -o+devices,seg_count $vg
|
||||
+
|
||||
+# Check if the rimage has multiple segments (should be 2)
|
||||
+check lv_field $vg/${lv1}_rimage_0 seg_count 2
|
||||
+check lv_field $vg/${lv1}_rimage_1 seg_count 2
|
||||
+
|
||||
+# Phase 2: Now fragment the remaining free space into small gaps for imeta
|
||||
+# The remaining free space should be ~70MB on each device
|
||||
+# Create 6MB fragments leaving 6MB gaps
|
||||
+for i in {1..6}; do
|
||||
+ lvcreate -n perm${i} -L 6M -an $vg "$dev1" 2>/dev/null || break
|
||||
+ lvcreate -n temp${i} -L 6M -an $vg "$dev1" 2>/dev/null || break
|
||||
+done
|
||||
+
|
||||
+for i in {1..6}; do
|
||||
+ lvcreate -n perm${i}_2 -L 6M -an $vg "$dev2" 2>/dev/null || break
|
||||
+ lvcreate -n temp${i}_2 -L 6M -an $vg "$dev2" 2>/dev/null || break
|
||||
+done
|
||||
+
|
||||
+# Remove temp LVs, leaving 6MB (3-extent) gaps
|
||||
+for i in {1..6}; do
|
||||
+ lvremove -y $vg/temp${i} 2>/dev/null || true
|
||||
+ lvremove -y $vg/temp${i}_2 2>/dev/null || true
|
||||
+done
|
||||
+
|
||||
+pvs -o+pv_free,pv_used
|
||||
+lvs -a -o+devices,seg_count $vg
|
||||
+
|
||||
+# Now try to add integrity
|
||||
+# With a 120MB LV, imeta needs ~8MB (4 extents with 2MB extent size)
|
||||
+# The fragmented free space (only 6MB/3-extent gaps) should cause imeta allocation
|
||||
+# to require multiple segments.
|
||||
+lvchange -an $vg/$lv1
|
||||
+lvconvert --raidintegrity y $vg/$lv1
|
||||
+
|
||||
+lvs -a -o+devices $vg
|
||||
+
|
||||
+lvchange -ay $vg/$lv1
|
||||
+aux wait_recalc $vg/${lv1}_rimage_0
|
||||
+aux wait_recalc $vg/${lv1}_rimage_1
|
||||
+_verify_data_on_lv
|
||||
+lvextend -L+4M $vg/$lv1
|
||||
+_verify_data_on_lv
|
||||
+_replace_data_on_lv
|
||||
+lvconvert --raidintegrity n $vg/$lv1
|
||||
+_verify_data_on_lv
|
||||
+
|
||||
+# Clean up
|
||||
+lvremove -y $vg/$lv1 || true
|
||||
+
|
||||
+# Remove all fragment LVs
|
||||
+lvremove -y $vg/frag1 $vg/frag2 $vg/frag3 $vg/frag4 || true
|
||||
+
|
||||
+# Remove all perm LVs
|
||||
+for i in {1..6}; do
|
||||
+ lvremove -y $vg/perm${i} 2>/dev/null || true
|
||||
+ lvremove -y $vg/perm${i}_2 2>/dev/null || true
|
||||
+done
|
||||
+
|
||||
+vgremove -ff $vg
|
||||
--
|
||||
2.52.0
|
||||
|
||||
350
SOURCES/0053-lvresize-fix-xfs-size-checks.patch
Normal file
350
SOURCES/0053-lvresize-fix-xfs-size-checks.patch
Normal file
@ -0,0 +1,350 @@
|
||||
From dcda3b48c2f6ca9841d53911d10fe8825f4e1d19 Mon Sep 17 00:00:00 2001
|
||||
From: David Teigland <teigland@redhat.com>
|
||||
Date: Thu, 11 Dec 2025 14:48:42 -0600
|
||||
Subject: [PATCH 53/57] lvresize: fix xfs size checks
|
||||
|
||||
After lvextend with xfs_growfs on a mounted xfs file system,
|
||||
libblkid FSLASTBLOCK continues to return the original value,
|
||||
and does not reflect the grown size of the fs.
|
||||
|
||||
If that was followed by lvreduce back to the original LV size,
|
||||
lvm saw the original fs size in FSLASTBLOCK, and allowed the LV
|
||||
to shrink back to the original size, even though xfs had grown
|
||||
and was now using the space.
|
||||
|
||||
Fix this by using the XFS_IOC_FSGEOMETRY ioctl to get the
|
||||
correct size value for mounted xfs.
|
||||
|
||||
(cherry picked from commit 0b231e3f4e3e60b8ec7bb7e4443583a06f42614e)
|
||||
---
|
||||
lib/device/filesystem.c | 53 +++++++++++++++++++++++---
|
||||
lib/device/filesystem.h | 3 +-
|
||||
lib/metadata/lv_manip.c | 6 +--
|
||||
test/shell/lvresize-fs-crypt.sh | 18 +++++++++
|
||||
test/shell/lvresize-fs.sh | 67 +++++++++++++++++++++++++++++++++
|
||||
test/shell/lvresize-xfs.sh | 67 ++++++++++++++++++++++++++++++++-
|
||||
6 files changed, 203 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/lib/device/filesystem.c b/lib/device/filesystem.c
|
||||
index 6d53ebd24..64e1d9422 100644
|
||||
--- a/lib/device/filesystem.c
|
||||
+++ b/lib/device/filesystem.c
|
||||
@@ -22,7 +22,21 @@
|
||||
|
||||
#include <dirent.h>
|
||||
#include <mntent.h>
|
||||
+#include <uuid/uuid.h>
|
||||
#include <sys/ioctl.h>
|
||||
+#include <linux/types.h>
|
||||
+/* including xfs/linux.h causes uuid_t conflicts, so define some types that are needed */
|
||||
+/* #include <xfs/linux.h> */
|
||||
+typedef off_t xfs_off_t;
|
||||
+typedef uint64_t xfs_ino_t;
|
||||
+typedef uint32_t xfs_dev_t;
|
||||
+typedef int64_t xfs_daddr_t;
|
||||
+typedef __u32 xfs_nlink_t;
|
||||
+#include <xfs/xfs_types.h>
|
||||
+#ifndef __user
|
||||
+#define __user
|
||||
+#endif
|
||||
+#include <xfs/xfs_fs.h>
|
||||
|
||||
static const char *_lvresize_fs_helper_path;
|
||||
|
||||
@@ -253,8 +267,36 @@ static int _btrfs_get_mnt(struct fs_info *fsi, dev_t lv_devt)
|
||||
return ret;
|
||||
}
|
||||
|
||||
-int fs_get_info(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
- struct fs_info *fsi, int include_mount)
|
||||
+static int _xfs_update_size_mounted(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
+ char *lv_path, struct fs_info *fsi)
|
||||
+{
|
||||
+ struct xfs_fsop_geom geo = { 0 };
|
||||
+ int fd;
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ if ((fd = open(fsi->mount_dir, O_RDONLY)) < 0) {
|
||||
+ log_error("XFS geometry open error %d for %s %s", errno, lv_path, fsi->mount_dir);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (ioctl(fd, XFS_IOC_FSGEOMETRY, &geo)) {
|
||||
+ log_error("XFS geometry ioctl error %d for %s %s", errno, lv_path, fsi->mount_dir);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ /* replace the potentially wrong value from blkid_probe_lookup_value FSLASTBLOCK */
|
||||
+ fsi->fs_last_byte = geo.blocksize * geo.datablocks;
|
||||
+ ret = 1;
|
||||
+
|
||||
+ log_debug("xfs geometry blocksize %llu datablocks %llu fs_last_byte %llu from %s %s",
|
||||
+ (unsigned long long)geo.blocksize, (unsigned long long)geo.datablocks,
|
||||
+ (unsigned long long)fsi->fs_last_byte, lv_path, fsi->mount_dir);
|
||||
+out:
|
||||
+ (void)close(fd);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+int fs_get_info(struct cmd_context *cmd, struct logical_volume *lv, struct fs_info *fsi)
|
||||
{
|
||||
char lv_path[PATH_MAX];
|
||||
char crypt_path[PATH_MAX] = { 0 };
|
||||
@@ -340,14 +382,15 @@ int fs_get_info(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
st_top = st_lv;
|
||||
}
|
||||
|
||||
- if (!include_mount)
|
||||
- return 1;
|
||||
-
|
||||
if (!strcmp(fsi->fstype, "btrfs"))
|
||||
ret = _btrfs_get_mnt(fsi, st_lv.st_rdev);
|
||||
else
|
||||
ret = _fs_get_mnt(fsi, st_top.st_rdev);
|
||||
|
||||
+ /* blkid FSLASTBLOCK may be incorrect for mounted xfs */
|
||||
+ if (fsi->mounted && !strcmp(fsi->fstype, "xfs"))
|
||||
+ ret = _xfs_update_size_mounted(cmd, lv, lv_path, fsi);
|
||||
+
|
||||
fsi->unmounted = !fsi->mounted;
|
||||
return ret;
|
||||
}
|
||||
diff --git a/lib/device/filesystem.h b/lib/device/filesystem.h
|
||||
index 4ba6f0db9..bb43f9a96 100644
|
||||
--- a/lib/device/filesystem.h
|
||||
+++ b/lib/device/filesystem.h
|
||||
@@ -45,8 +45,7 @@ struct fs_info {
|
||||
unsigned needs_crypt:1;
|
||||
};
|
||||
|
||||
-int fs_get_info(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
- struct fs_info *fsi, int include_mount);
|
||||
+int fs_get_info(struct cmd_context *cmd, struct logical_volume *lv, struct fs_info *fsi);
|
||||
|
||||
int fs_extend_script(struct cmd_context *cmd, struct logical_volume *lv, struct fs_info *fsi, char *fsmode);
|
||||
int fs_reduce_script(struct cmd_context *cmd, struct logical_volume *lv, struct fs_info *fsi, char *fsmode);
|
||||
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
|
||||
index e7405f1dc..7296f5e66 100644
|
||||
--- a/lib/metadata/lv_manip.c
|
||||
+++ b/lib/metadata/lv_manip.c
|
||||
@@ -6459,7 +6459,7 @@ static int _fs_reduce(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
memset(&fsinfo, 0, sizeof(fsinfo));
|
||||
memset(&fsinfo2, 0, sizeof(fsinfo));
|
||||
|
||||
- if (!fs_get_info(cmd, lv, &fsinfo, 1))
|
||||
+ if (!fs_get_info(cmd, lv, &fsinfo))
|
||||
goto_out;
|
||||
|
||||
if (fsinfo.nofs) {
|
||||
@@ -6578,7 +6578,7 @@ static int _fs_reduce(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
* Re-check the fs last block which should now be less than the
|
||||
* requested (reduced) LV size.
|
||||
*/
|
||||
- if (!fs_get_info(cmd, lv, &fsinfo2, 0))
|
||||
+ if (!fs_get_info(cmd, lv, &fsinfo2))
|
||||
goto_out;
|
||||
|
||||
if (fsinfo.fs_last_byte && (fsinfo2.fs_last_byte > fsinfo.new_size_bytes)) {
|
||||
@@ -6600,7 +6600,7 @@ static int _fs_extend_check_fsinfo(struct cmd_context *cmd, struct logical_volum
|
||||
|
||||
memset(fsinfo, 0, sizeof(*fsinfo));
|
||||
|
||||
- if (!fs_get_info(cmd, lv, fsinfo, 1))
|
||||
+ if (!fs_get_info(cmd, lv, fsinfo))
|
||||
return 0;
|
||||
|
||||
if (fsinfo->nofs)
|
||||
diff --git a/test/shell/lvresize-fs-crypt.sh b/test/shell/lvresize-fs-crypt.sh
|
||||
index a56bf6a3e..d4f9de1e0 100644
|
||||
--- a/test/shell/lvresize-fs-crypt.sh
|
||||
+++ b/test/shell/lvresize-fs-crypt.sh
|
||||
@@ -97,6 +97,24 @@ umount "$mount_dir"
|
||||
cryptsetup close $cr
|
||||
lvremove -f $vg/$lv
|
||||
|
||||
+# lvextend+lvreduce xfs on LUKS1
|
||||
+lvcreate -n $lv -L 320M $vg
|
||||
+echo 93R4P4pIqAH8 | cryptsetup luksFormat -i1 --type luks1 "$DM_DEV_DIR/$vg/$lv"
|
||||
+echo 93R4P4pIqAH8 | cryptsetup luksOpen "$DM_DEV_DIR/$vg/$lv" $cr
|
||||
+mkfs.xfs /dev/mapper/$cr
|
||||
+mount /dev/mapper/$cr "$mount_dir"
|
||||
+dd if=/dev/zero of="$mount_dir/zeros1" bs=1M count=20 oflag=direct
|
||||
+df --output=size "$mount_dir" |tee df1
|
||||
+lvextend -L+136M --fs resize $vg/$lv
|
||||
+check lv_field $vg/$lv lv_size "456.00m"
|
||||
+df --output=size "$mount_dir" |tee df2
|
||||
+not diff df1 df2
|
||||
+not lvresize -L 320M $vg/$lv
|
||||
+not lvresize -r -L 320M $vg/$lv
|
||||
+umount "$mount_dir"
|
||||
+cryptsetup close $cr
|
||||
+lvremove -f $vg/$lv
|
||||
+
|
||||
# lvextend ext4 on plain crypt (no header)
|
||||
lvcreate -n $lv -L 256M $vg
|
||||
echo 93R4P4pIqAH8 | cryptsetup create $cr "$DM_DEV_DIR/$vg/$lv"
|
||||
diff --git a/test/shell/lvresize-fs.sh b/test/shell/lvresize-fs.sh
|
||||
index 4bcbb9ca2..266f18bc1 100644
|
||||
--- a/test/shell/lvresize-fs.sh
|
||||
+++ b/test/shell/lvresize-fs.sh
|
||||
@@ -700,5 +700,72 @@ blkid -p "$DM_DEV_DIR/$vg/$lv" | grep FSSIZE && {
|
||||
lvreduce -L16m $vg/$lv
|
||||
check lv_field $vg/$lv lv_size "16.00m"
|
||||
}
|
||||
+lvremove -y $vg/$lv
|
||||
+
|
||||
+###############################
|
||||
+#
|
||||
+# lvextend followed by lvreduce
|
||||
+#
|
||||
+###############################
|
||||
+
|
||||
+# mounted, fs resized
|
||||
+lvcreate -n $lv -L 40M $vg
|
||||
+mkfs.ext4 "$DM_DEV_DIR/$vg/$lv"
|
||||
+mount "$DM_DEV_DIR/$vg/$lv" "$mount_dir"
|
||||
+dd if=/dev/zero of="$mount_dir/zeros1" bs=1M count=10 oflag=direct
|
||||
+lvresize --yes -r -L 50M $vg/$lv
|
||||
+not lvresize --yes -L 40M $vg/$lv
|
||||
+lvresize --yes -r -L 40M $vg/$lv
|
||||
+umount "$mount_dir"
|
||||
+lvchange -an $vg/$lv
|
||||
+lvremove $vg/$lv
|
||||
+
|
||||
+# unmounted, fs resized
|
||||
+lvcreate -n $lv -L 40M $vg
|
||||
+mkfs.ext4 "$DM_DEV_DIR/$vg/$lv"
|
||||
+mount "$DM_DEV_DIR/$vg/$lv" "$mount_dir"
|
||||
+dd if=/dev/zero of="$mount_dir/zeros1" bs=1M count=10 oflag=direct
|
||||
+umount "$mount_dir"
|
||||
+lvresize --yes -r -L 50M $vg/$lv
|
||||
+not lvresize --yes -L 40M $vg/$lv
|
||||
+lvresize --yes -r -L 40M $vg/$lv
|
||||
+lvchange -an $vg/$lv
|
||||
+lvremove $vg/$lv
|
||||
+
|
||||
+# mounted, fs not resized
|
||||
+lvcreate -n $lv -L 40M $vg
|
||||
+mkfs.ext4 "$DM_DEV_DIR/$vg/$lv"
|
||||
+mount "$DM_DEV_DIR/$vg/$lv" "$mount_dir"
|
||||
+dd if=/dev/zero of="$mount_dir/zeros1" bs=1M count=10 oflag=direct
|
||||
+df --output=size "$mount_dir" |tee df1
|
||||
+lvresize --yes -L 50M $vg/$lv
|
||||
+check lv_field $vg/$lv lv_size "50.00m"
|
||||
+lvresize --yes -L 40M $vg/$lv
|
||||
+check lv_field $vg/$lv lv_size "40.00m"
|
||||
+df --output=size "$mount_dir" |tee df2
|
||||
+# fs size unchanged
|
||||
+diff df1 df2
|
||||
+umount "$mount_dir"
|
||||
+lvchange -an $vg/$lv
|
||||
+lvremove $vg/$lv
|
||||
+
|
||||
+# unmounted, fs not resized
|
||||
+lvcreate -n $lv -L 40M $vg
|
||||
+mkfs.ext4 "$DM_DEV_DIR/$vg/$lv"
|
||||
+mount "$DM_DEV_DIR/$vg/$lv" "$mount_dir"
|
||||
+dd if=/dev/zero of="$mount_dir/zeros1" bs=1M count=10 oflag=direct
|
||||
+df --output=size "$mount_dir" |tee df1
|
||||
+umount "$mount_dir"
|
||||
+lvresize --yes -L 50M $vg/$lv
|
||||
+check lv_field $vg/$lv lv_size "50.00m"
|
||||
+lvresize --yes -L 40M $vg/$lv
|
||||
+check lv_field $vg/$lv lv_size "40.00m"
|
||||
+# fs size unchanged
|
||||
+mount "$DM_DEV_DIR/$vg/$lv" "$mount_dir"
|
||||
+df --output=size "$mount_dir" |tee df2
|
||||
+diff df1 df2
|
||||
+umount "$mount_dir"
|
||||
+lvchange -an $vg/$lv
|
||||
+lvremove $vg/$lv
|
||||
|
||||
vgremove -ff $vg
|
||||
diff --git a/test/shell/lvresize-xfs.sh b/test/shell/lvresize-xfs.sh
|
||||
index 4c4ed15e7..ef87b1b3a 100644
|
||||
--- a/test/shell/lvresize-xfs.sh
|
||||
+++ b/test/shell/lvresize-xfs.sh
|
||||
@@ -19,7 +19,7 @@ which xfs_growfs || skip
|
||||
|
||||
aux have_fsinfo || skip "Test needs --fs checksize support"
|
||||
|
||||
-aux prepare_vg 1 500
|
||||
+aux prepare_vg 1 600
|
||||
|
||||
mount_dir="mnt_lvresize_fs"
|
||||
mkdir -p "$mount_dir"
|
||||
@@ -242,6 +242,71 @@ umount "$mount_dir"
|
||||
|
||||
lvremove -f $vg/$lv
|
||||
|
||||
+###############################
|
||||
+#
|
||||
+# lvextend followed by lvreduce
|
||||
+#
|
||||
+###############################
|
||||
+
|
||||
+# mounted, fs resized
|
||||
+lvcreate -n $lv -L 400M $vg
|
||||
+mkfs.xfs "$DM_DEV_DIR/$vg/$lv"
|
||||
+mount "$DM_DEV_DIR/$vg/$lv" "$mount_dir"
|
||||
+dd if=/dev/zero of="$mount_dir/zeros1" bs=1M count=20 oflag=direct
|
||||
+lvresize --yes -r -L 500M $vg/$lv
|
||||
+not lvresize --yes -r -L 400M $vg/$lv
|
||||
+not lvresize --yes -L 400M $vg/$lv
|
||||
+umount "$mount_dir"
|
||||
+lvchange -an $vg/$lv
|
||||
+lvremove $vg/$lv
|
||||
+
|
||||
+# unmounted, fs resized
|
||||
+lvcreate -n $lv -L 400M $vg
|
||||
+mkfs.xfs "$DM_DEV_DIR/$vg/$lv"
|
||||
+mount "$DM_DEV_DIR/$vg/$lv" "$mount_dir"
|
||||
+dd if=/dev/zero of="$mount_dir/zeros1" bs=1M count=20 oflag=direct
|
||||
+umount "$mount_dir"
|
||||
+lvresize --yes -r -L 500M $vg/$lv
|
||||
+not lvresize --yes -r -L 400M $vg/$lv
|
||||
+not lvresize --yes -L 400M $vg/$lv
|
||||
+lvchange -an $vg/$lv
|
||||
+lvremove $vg/$lv
|
||||
+
|
||||
+# mounted, fs not resized
|
||||
+lvcreate -n $lv -L 400M $vg
|
||||
+mkfs.xfs "$DM_DEV_DIR/$vg/$lv"
|
||||
+mount "$DM_DEV_DIR/$vg/$lv" "$mount_dir"
|
||||
+dd if=/dev/zero of="$mount_dir/zeros1" bs=1M count=20 oflag=direct
|
||||
+df --output=size "$mount_dir" |tee df1
|
||||
+lvresize --yes -L 500M $vg/$lv
|
||||
+check lv_field $vg/$lv lv_size "500.00m"
|
||||
+lvresize --yes -L 400M $vg/$lv
|
||||
+check lv_field $vg/$lv lv_size "400.00m"
|
||||
+df --output=size "$mount_dir" |tee df2
|
||||
+# fs size unchanged
|
||||
+diff df1 df2
|
||||
+umount "$mount_dir"
|
||||
+lvchange -an $vg/$lv
|
||||
+lvremove $vg/$lv
|
||||
+
|
||||
+# unmounted, fs not resized
|
||||
+lvcreate -n $lv -L 400M $vg
|
||||
+mkfs.xfs "$DM_DEV_DIR/$vg/$lv"
|
||||
+mount "$DM_DEV_DIR/$vg/$lv" "$mount_dir"
|
||||
+dd if=/dev/zero of="$mount_dir/zeros1" bs=1M count=20 oflag=direct
|
||||
+df --output=size "$mount_dir" |tee df1
|
||||
+umount "$mount_dir"
|
||||
+lvresize --yes -L 500M $vg/$lv
|
||||
+check lv_field $vg/$lv lv_size "500.00m"
|
||||
+lvresize --yes -L 400M $vg/$lv
|
||||
+check lv_field $vg/$lv lv_size "400.00m"
|
||||
+# fs size unchanged
|
||||
+mount "$DM_DEV_DIR/$vg/$lv" "$mount_dir"
|
||||
+df --output=size "$mount_dir" |tee df2
|
||||
+diff df1 df2
|
||||
+umount "$mount_dir"
|
||||
+lvchange -an $vg/$lv
|
||||
+lvremove $vg/$lv
|
||||
|
||||
##########################################################
|
||||
#
|
||||
--
|
||||
2.52.0
|
||||
|
||||
37
SOURCES/0054-configure-check-for-xfs-header-file.patch
Normal file
37
SOURCES/0054-configure-check-for-xfs-header-file.patch
Normal file
@ -0,0 +1,37 @@
|
||||
From f533eab471f78f27c86d9b88cf2ba66df924f3ea Mon Sep 17 00:00:00 2001
|
||||
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||
Date: Sun, 14 Dec 2025 17:15:37 +0100
|
||||
Subject: [PATCH 54/57] configure: check for xfs header file
|
||||
|
||||
Check if xfs/xfs.h is available.
|
||||
|
||||
(cherry picked from commit 127774ff1bf1a471017b1ae91786eb4e1c2edd82)
|
||||
---
|
||||
configure.ac | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 11a735af5..89ec0ea9c 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -101,6 +101,7 @@ AC_CHECK_HEADERS([assert.h ctype.h dirent.h errno.h fcntl.h float.h \
|
||||
unistd.h], , [AC_MSG_ERROR(bailing out)])
|
||||
|
||||
AC_CHECK_HEADERS(termios.h sys/statvfs.h sys/timerfd.h sys/vfs.h linux/magic.h linux/fiemap.h)
|
||||
+AC_CHECK_HEADERS(xfs/xfs.h, LVM_NO_XFS_WARN=, LVM_NO_XFS_WARN=y, [#define _GNU_SOURCE 1])
|
||||
AC_CHECK_HEADERS(libaio.h,LVM_NEEDS_LIBAIO_WARN=,LVM_NEEDS_LIBAIO_WARN=y)
|
||||
AS_CASE(["$host_os"],
|
||||
[linux*], [AC_CHECK_HEADERS([asm/byteorder.h linux/fs.h malloc.h], [], [AC_MSG_ERROR(bailing out)])],
|
||||
@@ -2126,6 +2127,9 @@ AS_IF([test -n "$VDO_CONFIGURE_WARN"],
|
||||
AS_IF([test -n "$LVM_NEEDS_LIBAIO_WARN"],
|
||||
[AC_MSG_WARN([Only libdm part can be build without libaio: make [[install_]]device-mapper])])
|
||||
|
||||
+AS_IF([test -n "$LVM_NO_XFS_WARN"],
|
||||
+ [AC_MSG_WARN(['lvextend --resizefs' is less capable without xfs/xfs.h (see package: xfsprogs devel)])])
|
||||
+
|
||||
AS_IF([test "$ODIRECT" != "yes"],
|
||||
[AC_MSG_WARN([O_DIRECT disabled: low-memory pvmove may lock up])])
|
||||
|
||||
--
|
||||
2.52.0
|
||||
|
||||
27
SOURCES/0055-log-add-string.h.patch
Normal file
27
SOURCES/0055-log-add-string.h.patch
Normal file
@ -0,0 +1,27 @@
|
||||
From 9248e4fa05534a0865a7fad4b0bb76ca85c4dd55 Mon Sep 17 00:00:00 2001
|
||||
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||
Date: Sun, 14 Dec 2025 21:54:29 +0100
|
||||
Subject: [PATCH 55/57] log: add string.h
|
||||
|
||||
Header file is using strerror() from <string.h>.
|
||||
|
||||
(cherry picked from commit e8d744e8bdb8386ab5754015e6511d0431d76f04)
|
||||
---
|
||||
lib/log/log.h | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/lib/log/log.h b/lib/log/log.h
|
||||
index 6efe5a66b..287db00e5 100644
|
||||
--- a/lib/log/log.h
|
||||
+++ b/lib/log/log.h
|
||||
@@ -38,6 +38,7 @@
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
+#include <string.h>
|
||||
|
||||
#define EUNCLASSIFIED -1 /* Generic error code */
|
||||
|
||||
--
|
||||
2.52.0
|
||||
|
||||
208
SOURCES/0056-filesystem-refactor-code-working-with-xfs.patch
Normal file
208
SOURCES/0056-filesystem-refactor-code-working-with-xfs.patch
Normal file
@ -0,0 +1,208 @@
|
||||
From 077eaef48b2d257e94feb1caa3825fa5a5da14e6 Mon Sep 17 00:00:00 2001
|
||||
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||
Date: Sun, 14 Dec 2025 17:14:08 +0100
|
||||
Subject: [PATCH 56/57] filesystem: refactor code working with xfs
|
||||
|
||||
Move XFS ioctl code to separate filesystem_xfs.c file.
|
||||
Remove hackish way of including xfs headers.
|
||||
|
||||
When xfs/xfs.h is missing, continue running without checking
|
||||
mounted filesystem size.
|
||||
|
||||
(cherry picked from commit 1e9efc72cfed277e6885e201affbc47a2edbf576)
|
||||
---
|
||||
lib/Makefile.in | 1 +
|
||||
lib/device/filesystem.c | 48 +++--------------------------
|
||||
lib/device/filesystem.h | 10 +++++-
|
||||
lib/device/filesystem_xfs.c | 61 +++++++++++++++++++++++++++++++++++++
|
||||
4 files changed, 76 insertions(+), 44 deletions(-)
|
||||
create mode 100644 lib/device/filesystem_xfs.c
|
||||
|
||||
diff --git a/lib/Makefile.in b/lib/Makefile.in
|
||||
index 8424ac952..8620eaaff 100644
|
||||
--- a/lib/Makefile.in
|
||||
+++ b/lib/Makefile.in
|
||||
@@ -40,6 +40,7 @@ SOURCES =\
|
||||
device/dev-luks.c \
|
||||
device/dev-dasd.c \
|
||||
device/dev-lvm1-pool.c \
|
||||
+ device/filesystem_xfs.c \
|
||||
device/filesystem.c \
|
||||
device/online.c \
|
||||
device/parse_vpd.c \
|
||||
diff --git a/lib/device/filesystem.c b/lib/device/filesystem.c
|
||||
index 64e1d9422..f1add62f9 100644
|
||||
--- a/lib/device/filesystem.c
|
||||
+++ b/lib/device/filesystem.c
|
||||
@@ -19,24 +19,12 @@
|
||||
#include "lib/display/display.h"
|
||||
#include "lib/misc/lvm-exec.h"
|
||||
#include "lib/activate/dev_manager.h"
|
||||
+#include "lib/commands/toolcontext.h"
|
||||
|
||||
#include <dirent.h>
|
||||
#include <mntent.h>
|
||||
-#include <uuid/uuid.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/types.h>
|
||||
-/* including xfs/linux.h causes uuid_t conflicts, so define some types that are needed */
|
||||
-/* #include <xfs/linux.h> */
|
||||
-typedef off_t xfs_off_t;
|
||||
-typedef uint64_t xfs_ino_t;
|
||||
-typedef uint32_t xfs_dev_t;
|
||||
-typedef int64_t xfs_daddr_t;
|
||||
-typedef __u32 xfs_nlink_t;
|
||||
-#include <xfs/xfs_types.h>
|
||||
-#ifndef __user
|
||||
-#define __user
|
||||
-#endif
|
||||
-#include <xfs/xfs_fs.h>
|
||||
|
||||
static const char *_lvresize_fs_helper_path;
|
||||
|
||||
@@ -267,34 +255,6 @@ static int _btrfs_get_mnt(struct fs_info *fsi, dev_t lv_devt)
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static int _xfs_update_size_mounted(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
- char *lv_path, struct fs_info *fsi)
|
||||
-{
|
||||
- struct xfs_fsop_geom geo = { 0 };
|
||||
- int fd;
|
||||
- int ret = 0;
|
||||
-
|
||||
- if ((fd = open(fsi->mount_dir, O_RDONLY)) < 0) {
|
||||
- log_error("XFS geometry open error %d for %s %s", errno, lv_path, fsi->mount_dir);
|
||||
- return 0;
|
||||
- }
|
||||
-
|
||||
- if (ioctl(fd, XFS_IOC_FSGEOMETRY, &geo)) {
|
||||
- log_error("XFS geometry ioctl error %d for %s %s", errno, lv_path, fsi->mount_dir);
|
||||
- goto out;
|
||||
- }
|
||||
-
|
||||
- /* replace the potentially wrong value from blkid_probe_lookup_value FSLASTBLOCK */
|
||||
- fsi->fs_last_byte = geo.blocksize * geo.datablocks;
|
||||
- ret = 1;
|
||||
-
|
||||
- log_debug("xfs geometry blocksize %llu datablocks %llu fs_last_byte %llu from %s %s",
|
||||
- (unsigned long long)geo.blocksize, (unsigned long long)geo.datablocks,
|
||||
- (unsigned long long)fsi->fs_last_byte, lv_path, fsi->mount_dir);
|
||||
-out:
|
||||
- (void)close(fd);
|
||||
- return ret;
|
||||
-}
|
||||
|
||||
int fs_get_info(struct cmd_context *cmd, struct logical_volume *lv, struct fs_info *fsi)
|
||||
{
|
||||
@@ -388,8 +348,10 @@ int fs_get_info(struct cmd_context *cmd, struct logical_volume *lv, struct fs_in
|
||||
ret = _fs_get_mnt(fsi, st_top.st_rdev);
|
||||
|
||||
/* blkid FSLASTBLOCK may be incorrect for mounted xfs */
|
||||
- if (fsi->mounted && !strcmp(fsi->fstype, "xfs"))
|
||||
- ret = _xfs_update_size_mounted(cmd, lv, lv_path, fsi);
|
||||
+ if (fsi->mounted && !strcmp(fsi->fstype, "xfs")) {
|
||||
+ if (!(ret = fs_xfs_update_size_mounted(cmd, lv, lv_path, fsi)))
|
||||
+ stack;
|
||||
+ }
|
||||
|
||||
fsi->unmounted = !fsi->mounted;
|
||||
return ret;
|
||||
diff --git a/lib/device/filesystem.h b/lib/device/filesystem.h
|
||||
index bb43f9a96..c66b47995 100644
|
||||
--- a/lib/device/filesystem.h
|
||||
+++ b/lib/device/filesystem.h
|
||||
@@ -15,9 +15,13 @@
|
||||
#ifndef _FILESYSTEM_H
|
||||
#define _FILESYSTEM_H
|
||||
|
||||
-#include "lib/commands/toolcontext.h"
|
||||
#include "lib/device/device.h"
|
||||
|
||||
+#include <linux/limits.h> /* PATH_MAX */
|
||||
+
|
||||
+struct cmd_context;
|
||||
+struct logical_volume;
|
||||
+
|
||||
#define FSTYPE_MAX 16
|
||||
#define UUID_LEN 37
|
||||
|
||||
@@ -54,4 +58,8 @@ int crypt_resize_script(struct cmd_context *cmd, struct logical_volume *lv, stru
|
||||
int fs_mount_state_is_misnamed(struct cmd_context *cmd, struct logical_volume *lv, char *lv_path, char *fstype);
|
||||
int lv_crypt_is_active(struct cmd_context *cmd, char *lv_path);
|
||||
|
||||
+/* filesystem_xfs.c */
|
||||
+int fs_xfs_update_size_mounted(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
+ char *lv_path, struct fs_info *fsi);
|
||||
+
|
||||
#endif
|
||||
diff --git a/lib/device/filesystem_xfs.c b/lib/device/filesystem_xfs.c
|
||||
new file mode 100644
|
||||
index 000000000..61252fe16
|
||||
--- /dev/null
|
||||
+++ b/lib/device/filesystem_xfs.c
|
||||
@@ -0,0 +1,61 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2025 Red Hat, Inc. All rights reserved.
|
||||
+ *
|
||||
+ * This file is part of LVM2.
|
||||
+ *
|
||||
+ * This copyrighted material is made available to anyone wishing to use,
|
||||
+ * modify, copy, or redistribute it subject to the terms and conditions
|
||||
+ * of the GNU Lesser General Public License v.2.1.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU Lesser General Public License
|
||||
+ * along with this program; if not, write to the Free Software Foundation,
|
||||
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
+ */
|
||||
+
|
||||
+#include "filesystem.h"
|
||||
+#include "lib/log/lvm-logging.h"
|
||||
+
|
||||
+#ifdef HAVE_XFS_XFS_H
|
||||
+
|
||||
+#include <xfs/xfs.h>
|
||||
+
|
||||
+int fs_xfs_update_size_mounted(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
+ char *lv_path, struct fs_info *fsi)
|
||||
+{
|
||||
+ struct xfs_fsop_geom geo = { 0 };
|
||||
+ int ret = 0;
|
||||
+ int fd;
|
||||
+
|
||||
+ if ((fd = open(fsi->mount_dir, O_RDONLY)) < 0) {
|
||||
+ log_sys_error("XFS geometry open", fsi->mount_dir);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (ioctl(fd, XFS_IOC_FSGEOMETRY, &geo)) {
|
||||
+ log_sys_error("XFS geometry ioctl", fsi->mount_dir);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ /* replace the potentially wrong value from blkid_probe_lookup_value FSLASTBLOCK */
|
||||
+ fsi->fs_last_byte = geo.blocksize * geo.datablocks;
|
||||
+ ret = 1;
|
||||
+
|
||||
+ log_debug("xfs geometry blocksize %llu datablocks %llu fs_last_byte %llu from %s %s",
|
||||
+ (unsigned long long)geo.blocksize, (unsigned long long)geo.datablocks,
|
||||
+ (unsigned long long)fsi->fs_last_byte, lv_path, fsi->mount_dir);
|
||||
+out:
|
||||
+ (void)close(fd);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+#else /* !HAVE_XFS_XFS_H */
|
||||
+
|
||||
+int fs_xfs_update_size_mounted(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
+ char *lv_path, struct fs_info *fsi)
|
||||
+{
|
||||
+ log_debug("No XFS support, continuing WITHOUT reading XFS geometry.");
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+#endif
|
||||
--
|
||||
2.52.0
|
||||
|
||||
210
SOURCES/0057-lib-rename-uuid.c-to-id.c.patch
Normal file
210
SOURCES/0057-lib-rename-uuid.c-to-id.c.patch
Normal file
@ -0,0 +1,210 @@
|
||||
From 86812cc39d76f615af43d165c0117cae0c844129 Mon Sep 17 00:00:00 2001
|
||||
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||
Date: Sun, 14 Dec 2025 17:13:54 +0100
|
||||
Subject: [PATCH 1/2] lib: rename uuid.c to id.c
|
||||
|
||||
Use id.c to better match function naming in id.h.
|
||||
uuid/uuid.h is public header file, so using lib/id/id.c
|
||||
avoids potential naming collision with system uuid.h file.
|
||||
|
||||
(cherry picked from commit fe90043412f010957b6c09352a64e56a64c9b2c5)
|
||||
---
|
||||
lib/Makefile.in | 2 +-
|
||||
lib/cache/lvmcache.h | 2 +-
|
||||
lib/device/device.h | 2 +-
|
||||
lib/format_text/format-text.c | 2 +-
|
||||
lib/format_text/layout.h | 2 +-
|
||||
lib/{uuid/uuid.c => id/id.c} | 2 +-
|
||||
lib/{uuid/uuid.h => id/id.h} | 6 +++---
|
||||
lib/label/label.h | 2 +-
|
||||
lib/locking/locking.h | 2 +-
|
||||
lib/metadata/metadata-exported.h | 2 +-
|
||||
lib/metadata/pv.h | 2 +-
|
||||
lib/metadata/vg.h | 2 +-
|
||||
12 files changed, 14 insertions(+), 14 deletions(-)
|
||||
rename lib/{uuid/uuid.c => id/id.c} (99%)
|
||||
rename lib/{uuid/uuid.h => id/id.h} (93%)
|
||||
|
||||
diff --git a/lib/Makefile.in b/lib/Makefile.in
|
||||
index 8620eaaff..002a9ec46 100644
|
||||
--- a/lib/Makefile.in
|
||||
+++ b/lib/Makefile.in
|
||||
@@ -70,6 +70,7 @@ SOURCES =\
|
||||
format_text/import_vsn1.c \
|
||||
format_text/text_label.c \
|
||||
freeseg/freeseg.c \
|
||||
+ id/id.c \
|
||||
label/label.c \
|
||||
label/hints.c \
|
||||
locking/file_locking.c \
|
||||
@@ -115,7 +116,6 @@ SOURCES =\
|
||||
snapshot/snapshot.c \
|
||||
striped/striped.c \
|
||||
thin/thin.c \
|
||||
- uuid/uuid.c \
|
||||
zero/zero.c
|
||||
|
||||
ifeq ("@DEVMAPPER@", "yes")
|
||||
diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h
|
||||
index 9db5268dd..0468a6318 100644
|
||||
--- a/lib/cache/lvmcache.h
|
||||
+++ b/lib/cache/lvmcache.h
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
#include "lib/device/dev-cache.h"
|
||||
#include "lib/device/dev-type.h"
|
||||
-#include "lib/uuid/uuid.h"
|
||||
+#include "lib/id/id.h"
|
||||
#include "lib/label/label.h"
|
||||
#include "lib/locking/locking.h"
|
||||
|
||||
diff --git a/lib/device/device.h b/lib/device/device.h
|
||||
index 8c3cb53b0..35ec3712c 100644
|
||||
--- a/lib/device/device.h
|
||||
+++ b/lib/device/device.h
|
||||
@@ -17,7 +17,7 @@
|
||||
#define _LVM_DEVICE_H
|
||||
|
||||
#include "base/data-struct/list.h"
|
||||
-#include "lib/uuid/uuid.h"
|
||||
+#include "lib/id/id.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <fcntl.h>
|
||||
diff --git a/lib/format_text/format-text.c b/lib/format_text/format-text.c
|
||||
index d2c99f6bb..615b92df9 100644
|
||||
--- a/lib/format_text/format-text.c
|
||||
+++ b/lib/format_text/format-text.c
|
||||
@@ -23,7 +23,7 @@
|
||||
#include "lib/display/display.h"
|
||||
#include "lib/commands/toolcontext.h"
|
||||
#include "lib/misc/lvm-string.h"
|
||||
-#include "lib/uuid/uuid.h"
|
||||
+#include "lib/id/id.h"
|
||||
#include "lib/misc/crc.h"
|
||||
#include "lib/mm/xlate.h"
|
||||
#include "lib/label/label.h"
|
||||
diff --git a/lib/format_text/layout.h b/lib/format_text/layout.h
|
||||
index 2ef35b3af..2858f39c2 100644
|
||||
--- a/lib/format_text/layout.h
|
||||
+++ b/lib/format_text/layout.h
|
||||
@@ -20,7 +20,7 @@
|
||||
#include "lib/metadata/metadata.h"
|
||||
#include "lib/format_text/format-text.h"
|
||||
#include "lib/cache/lvmcache.h"
|
||||
-#include "lib/uuid/uuid.h"
|
||||
+#include "lib/id/id.h"
|
||||
|
||||
/*
|
||||
* PV header extension versions:
|
||||
diff --git a/lib/uuid/uuid.c b/lib/id/id.c
|
||||
similarity index 99%
|
||||
rename from lib/uuid/uuid.c
|
||||
rename to lib/id/id.c
|
||||
index 6f7acd2bd..b52121cd9 100644
|
||||
--- a/lib/uuid/uuid.c
|
||||
+++ b/lib/id/id.c
|
||||
@@ -13,8 +13,8 @@
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
+#include "lib/id/id.h"
|
||||
#include "lib/misc/lib.h"
|
||||
-#include "lib/uuid/uuid.h"
|
||||
#include "lib/misc/lvm-wrappers.h"
|
||||
|
||||
#include <assert.h>
|
||||
diff --git a/lib/uuid/uuid.h b/lib/id/id.h
|
||||
similarity index 93%
|
||||
rename from lib/uuid/uuid.h
|
||||
rename to lib/id/id.h
|
||||
index 5dad2548a..8e19dff0f 100644
|
||||
--- a/lib/uuid/uuid.h
|
||||
+++ b/lib/id/id.h
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
- * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
|
||||
+ * Copyright (C) 2004-2025 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
*
|
||||
@@ -13,8 +13,8 @@
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
-#ifndef _LVM_UUID_H
|
||||
-#define _LVM_UUID_H
|
||||
+#ifndef _LVM_ID_H
|
||||
+#define _LVM_ID_H
|
||||
|
||||
#define ID_LEN 32
|
||||
|
||||
diff --git a/lib/label/label.h b/lib/label/label.h
|
||||
index 4c224dc50..e17f8c8ed 100644
|
||||
--- a/lib/label/label.h
|
||||
+++ b/lib/label/label.h
|
||||
@@ -16,7 +16,7 @@
|
||||
#ifndef _LVM_LABEL_H
|
||||
#define _LVM_LABEL_H
|
||||
|
||||
-#include "lib/uuid/uuid.h"
|
||||
+#include "lib/id/id.h"
|
||||
#include "lib/device/device.h"
|
||||
#include "lib/device/bcache.h"
|
||||
|
||||
diff --git a/lib/locking/locking.h b/lib/locking/locking.h
|
||||
index a60935d52..487139a06 100644
|
||||
--- a/lib/locking/locking.h
|
||||
+++ b/lib/locking/locking.h
|
||||
@@ -16,7 +16,7 @@
|
||||
#ifndef _LVM_LOCKING_H
|
||||
#define _LVM_LOCKING_H
|
||||
|
||||
-#include "lib/uuid/uuid.h"
|
||||
+#include "lib/id/id.h"
|
||||
#include "lib/config/config.h"
|
||||
|
||||
struct logical_volume;
|
||||
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
|
||||
index 3752caf1e..7ec81f27d 100644
|
||||
--- a/lib/metadata/metadata-exported.h
|
||||
+++ b/lib/metadata/metadata-exported.h
|
||||
@@ -21,7 +21,7 @@
|
||||
#ifndef _LVM_METADATA_EXPORTED_H
|
||||
#define _LVM_METADATA_EXPORTED_H
|
||||
|
||||
-#include "lib/uuid/uuid.h"
|
||||
+#include "lib/id/id.h"
|
||||
#include "lib/metadata/pv.h"
|
||||
#include "lib/metadata/vg.h"
|
||||
#include "lib/metadata/lv.h"
|
||||
diff --git a/lib/metadata/pv.h b/lib/metadata/pv.h
|
||||
index ee2bd853b..7195f9a2d 100644
|
||||
--- a/lib/metadata/pv.h
|
||||
+++ b/lib/metadata/pv.h
|
||||
@@ -15,7 +15,7 @@
|
||||
#ifndef _LVM_PV_H
|
||||
#define _LVM_PV_H
|
||||
|
||||
-#include "lib/uuid/uuid.h"
|
||||
+#include "lib/id/id.h"
|
||||
#include "device_mapper/all.h"
|
||||
|
||||
struct device;
|
||||
diff --git a/lib/metadata/vg.h b/lib/metadata/vg.h
|
||||
index 92a15ef2f..0f5adb6ee 100644
|
||||
--- a/lib/metadata/vg.h
|
||||
+++ b/lib/metadata/vg.h
|
||||
@@ -15,7 +15,7 @@
|
||||
#ifndef _LVM_VG_H
|
||||
#define _LVM_VG_H
|
||||
|
||||
-#include "lib/uuid/uuid.h"
|
||||
+#include "lib/id/id.h"
|
||||
#include "device_mapper/all.h"
|
||||
|
||||
struct cmd_context;
|
||||
--
|
||||
2.52.0
|
||||
|
||||
113
SOURCES/0058-autoreconf-reconfigure.patch
Normal file
113
SOURCES/0058-autoreconf-reconfigure.patch
Normal file
@ -0,0 +1,113 @@
|
||||
From 5c44e8301451e0bace56c5f1400f11f4758d2aed Mon Sep 17 00:00:00 2001
|
||||
From: Zdenek Kabelac <zkabelac@redhat.com>
|
||||
Date: Sun, 14 Dec 2025 17:16:22 +0100
|
||||
Subject: [PATCH 2/2] autoreconf: reconfigure
|
||||
|
||||
Regenerate configure and configure.h.in after adding XFS header check.
|
||||
---
|
||||
aclocal.m4 | 8 ++++----
|
||||
configure | 28 ++++++++++++++++++++++++++++
|
||||
include/configure.h.in | 3 +++
|
||||
3 files changed, 35 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/aclocal.m4 b/aclocal.m4
|
||||
index 5f3a3e9c4..fa488e1f8 100644
|
||||
--- a/aclocal.m4
|
||||
+++ b/aclocal.m4
|
||||
@@ -1,6 +1,6 @@
|
||||
-# generated automatically by aclocal 1.17 -*- Autoconf -*-
|
||||
+# generated automatically by aclocal 1.18.1 -*- Autoconf -*-
|
||||
|
||||
-# Copyright (C) 1996-2024 Free Software Foundation, Inc.
|
||||
+# Copyright (C) 1996-2025 Free Software Foundation, Inc.
|
||||
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@@ -422,7 +422,7 @@ AS_IF([test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"],
|
||||
[AC_DEFINE([HAVE_][$1], 1, [Enable ]m4_tolower([$1])[ support])])
|
||||
])dnl PKG_HAVE_DEFINE_WITH_MODULES
|
||||
|
||||
-# Copyright (C) 1999-2024 Free Software Foundation, Inc.
|
||||
+# Copyright (C) 1999-2025 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@@ -792,7 +792,7 @@ for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[[i]]
|
||||
sys.exit(sys.hexversion < minverhex)"
|
||||
AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])])
|
||||
|
||||
-# Copyright (C) 2001-2024 Free Software Foundation, Inc.
|
||||
+# Copyright (C) 2001-2025 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
diff --git a/configure b/configure
|
||||
index 342bd0047..e3eb37ff6 100755
|
||||
--- a/configure
|
||||
+++ b/configure
|
||||
@@ -6921,6 +6921,20 @@ then :
|
||||
|
||||
fi
|
||||
|
||||
+ for ac_header in xfs/xfs.h
|
||||
+do :
|
||||
+ ac_fn_c_check_header_compile "$LINENO" "xfs/xfs.h" "ac_cv_header_xfs_xfs_h" "#define _GNU_SOURCE 1
|
||||
+"
|
||||
+if test "x$ac_cv_header_xfs_xfs_h" = xyes
|
||||
+then :
|
||||
+ printf "%s\n" "#define HAVE_XFS_XFS_H 1" >>confdefs.h
|
||||
+ LVM_NO_XFS_WARN=
|
||||
+else case e in #(
|
||||
+ e) LVM_NO_XFS_WARN=y ;;
|
||||
+esac
|
||||
+fi
|
||||
+
|
||||
+done
|
||||
for ac_header in libaio.h
|
||||
do :
|
||||
ac_fn_c_check_header_compile "$LINENO" "libaio.h" "ac_cv_header_libaio_h" "$ac_includes_default"
|
||||
@@ -12183,6 +12197,14 @@ then :
|
||||
test $ac_status = 0; }; then
|
||||
LOCKDSANLOCK_SUPPORT=400
|
||||
fi
|
||||
+ if test -n "$PKG_CONFIG" && \
|
||||
+ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsanlock_client >= 4.1.0\""; } >&5
|
||||
+ ($PKG_CONFIG --exists --print-errors "libsanlock_client >= 4.1.0") 2>&5
|
||||
+ ac_status=$?
|
||||
+ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||
+ test $ac_status = 0; }; then
|
||||
+ LOCKDSANLOCK_SUPPORT=410
|
||||
+fi
|
||||
|
||||
pkg_failed=no
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libsanlock_client >= 3.7.0" >&5
|
||||
@@ -18224,6 +18246,12 @@ then :
|
||||
printf "%s\n" "$as_me: WARNING: Only libdm part can be build without libaio: make [install_]device-mapper" >&2;}
|
||||
fi
|
||||
|
||||
+if test -n "$LVM_NO_XFS_WARN"
|
||||
+then :
|
||||
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: 'lvextend --resizefs' is less capable without xfs/xfs.h (see package: xfsprogs devel)" >&5
|
||||
+printf "%s\n" "$as_me: WARNING: 'lvextend --resizefs' is less capable without xfs/xfs.h (see package: xfsprogs devel)" >&2;}
|
||||
+fi
|
||||
+
|
||||
if test "$ODIRECT" != "yes"
|
||||
then :
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: O_DIRECT disabled: low-memory pvmove may lock up" >&5
|
||||
diff --git a/include/configure.h.in b/include/configure.h.in
|
||||
index 3fe1dc85b..eee47a36d 100644
|
||||
--- a/include/configure.h.in
|
||||
+++ b/include/configure.h.in
|
||||
@@ -549,6 +549,9 @@
|
||||
/* Define to 1 if 'vfork' works. */
|
||||
#undef HAVE_WORKING_VFORK
|
||||
|
||||
+/* Define to 1 if you have the <xfs/xfs.h> header file. */
|
||||
+#undef HAVE_XFS_XFS_H
|
||||
+
|
||||
/* Define to 1 if the system has the type '_Bool'. */
|
||||
#undef HAVE__BOOL
|
||||
|
||||
--
|
||||
2.52.0
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
%global device_mapper_version 1.02.206
|
||||
%global device_mapper_version 1.02.207
|
||||
|
||||
%global enable_cache 1
|
||||
%global enable_lvmdbusd 1
|
||||
@ -50,11 +50,11 @@ Name: lvm2
|
||||
%if 0%{?rhel}
|
||||
Epoch: %{rhel}
|
||||
%endif
|
||||
Version: 2.03.32
|
||||
Version: 2.03.33
|
||||
%if 0%{?from_snapshot}
|
||||
Release: 0.1.20211115git%{shortcommit}%{?dist}%{?rel_suffix}
|
||||
%else
|
||||
Release: 2%{?dist}%{?rel_suffix}
|
||||
Release: 4%{?dist}%{?rel_suffix}
|
||||
%endif
|
||||
License: GPL-2.0-only
|
||||
URL: https://sourceware.org/lvm2
|
||||
@ -70,15 +70,59 @@ Patch4: 0004-Revert-dm-udev-rules-don-t-export-and-save-DM_SUSPEN.patch
|
||||
Patch5: 0005-Revert-11-dm-lvm.rules-don-t-restore-DM_UDEV_DISABLE.patch
|
||||
Patch6: 0006-Revert-10-dm-rules-don-t-restore-DM_UDEV_DISABLE_OTH.patch
|
||||
Patch7: 0007-WHATS_NEW_DM-update.patch
|
||||
# RHEL-94577:
|
||||
Patch8: 0008-lvmlockd-fix-hosts-check-for-vgremove.patch
|
||||
Patch9: 0009-lvmlockd-fix-sanlock_release-for-vgremove.patch
|
||||
# RHEL-67039:
|
||||
Patch10: 0010-raid-count-or-clear-transiently-failed-devices.patch
|
||||
Patch11: 0011-lvconvert-allow-clearing-superblocks.patch
|
||||
Patch12: 0012-test-check-raid-superblock-clearing.patch
|
||||
Patch13: 0013-man-update-raid-man.patch
|
||||
Patch8: 0008-lvmlockd-fix-missing-free-in-vg_status.patch
|
||||
Patch9: 0009-lvmlockd-add-repair-option-to-reinitialize-sanlock-l.patch
|
||||
Patch10: 0010-udev-fix-autoactivation-on-top-of-loop-dev-PVs.patch
|
||||
Patch11: 0011-lv_manip.c-fix-lvresize-corruption-in-LV-crypt-FS-st.patch
|
||||
Patch12: 0012-device_id-always-log_error-on-device-ids-write-error.patch
|
||||
Patch13: 0013-lvmdevices-return-error-if-writing-device-ids-fail-f.patch
|
||||
Patch14: 0014-WHATS_NEW-update.patch
|
||||
Patch15: 0015-device_id-log_warn-instead-of-log_error-in-device_id.patch
|
||||
Patch16: 0016-lvmdevices-log_error-when-writing-devices-file-fails.patch
|
||||
Patch17: 0017-lvmlockd-lockopt-was-mistakenly-ignored-when-nolocki.patch
|
||||
Patch18: 0018-sanlock-match-lm_lock_sanlock-prototype.patch
|
||||
Patch19: 0019-lvmlockd-sanlock-fix-struct-pointer-in-release_renam.patch
|
||||
Patch20: 0020-lvmlockd-free-structs-in-adopt-error-path.patch
|
||||
Patch21: 0021-lvmlockd-sanlock-check-lock_lv_offset_from_args-resu.patch
|
||||
Patch22: 0022-lvmlockd-always-free-ls-struct-after-ls-thread-exits.patch
|
||||
Patch23: 0023-man-lvmlockd-updates.patch
|
||||
Patch24: 0024-lvmlockd-allow-1-more-extra-character.patch
|
||||
Patch25: 0025-libdm-stats-fix-type-mismatch-in-bit-operations.patch
|
||||
Patch26: 0026-cov-prevent-potential-negative-array-index.patch
|
||||
Patch27: 0027-cov-fix-integer-underflow-in-_count-handling.patch
|
||||
Patch28: 0028-cov-fix-va_end-resource-leak-in-szscanf.patch
|
||||
Patch29: 0029-cov-add-explicit-check-for-0-size.patch
|
||||
Patch30: 0030-cov-explicitly-zero-allocated-mem-for-array.patch
|
||||
Patch31: 0031-cov-check-for-potential-empty-registry-list.patch
|
||||
Patch32: 0032-cov-check-for-potential-empty-row-list.patch
|
||||
Patch33: 0033-gcc-for-C90-don-t-mix-declaration-and-code.patch
|
||||
Patch34: 0034-sanlock-fix-struct-copy-to-avoid-aliasing-issues.patch
|
||||
Patch35: 0035-sanlock-fix-file-descriptor-leak-in-error-path.patch
|
||||
Patch36: 0036-command-lines-fix-typo-in-configurable-name.patch
|
||||
Patch37: 0037-tools-simplify-LVM_DID_EXEC-environment-variable.patch
|
||||
Patch38: 0038-gcc-ensure-pointer-is-properly-initialized.patch
|
||||
Patch39: 0039-dmeventd-check-device-exists.patch
|
||||
Patch40: 0040-dmeventd-add-device-existence-check.patch
|
||||
Patch41: 0041-dmeventd-_get_status-returns-success-for-non-monitor.patch
|
||||
Patch42: 0042-vgsplit-fix-check-for-not-splitting-an-LV-between-tw.patch
|
||||
Patch43: 0043-vgsplit-fix-check-for-not-splitting-an-LV-between-tw.patch
|
||||
Patch44: 0044-lvmdevices-do-not-create-system.devices-when-deletin.patch
|
||||
Patch45: 0045-tools-pvchange-unlock-devices-file-at-the-end-of-cmd.patch
|
||||
Patch46: 0046-tools-pvchange-unlock-devices-file-at-the-end-of-cmd.patch
|
||||
Patch47: 0047-make-generate.patch
|
||||
Patch48: 0048-activating-raid-LV-with-partial-snapshot-is-an-error.patch
|
||||
Patch49: 0049-lv_manip-show-a-warning-during-classic-snapshot-crea.patch
|
||||
Patch50: 0050-test-add-new-test-for-snapshot-on-raid-creation-acti.patch
|
||||
Patch51: 0051-WHATS_NEW-update.patch
|
||||
# RHEL-135072:
|
||||
Patch52: 0052-integrity-allow-creating-imeta-with-more-than-one-se.patch
|
||||
# RHEL-116883:
|
||||
Patch53: 0053-lvresize-fix-xfs-size-checks.patch
|
||||
Patch54: 0054-configure-check-for-xfs-header-file.patch
|
||||
Patch55: 0055-log-add-string.h.patch
|
||||
Patch56: 0056-filesystem-refactor-code-working-with-xfs.patch
|
||||
Patch57: 0057-lib-rename-uuid.c-to-id.c.patch
|
||||
Patch58: 0058-autoreconf-reconfigure.patch
|
||||
|
||||
BuildRequires: make
|
||||
BuildRequires: gcc
|
||||
@ -91,6 +135,8 @@ BuildRequires: ncurses-devel
|
||||
BuildRequires: libedit-devel
|
||||
BuildRequires: libaio-devel
|
||||
BuildRequires: libnvme-devel
|
||||
BuildRequires: xfsprogs-devel
|
||||
#BuildRequires: libuuid-devel
|
||||
%if %{enable_lockd_dlm}
|
||||
BuildRequires: dlm-devel >= %{dlm_version}
|
||||
%endif
|
||||
@ -710,6 +756,19 @@ An extensive functional testsuite for LVM2.
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Thu Jan 15 2026 Marian Csontos <mcsontos@redhat.com> - 2.03.33-4
|
||||
- Handle wrong XFS reported size when shrinking LV immediately after growing.
|
||||
|
||||
* Tue Jan 06 2026 Marian Csontos <mcsontos@redhat.com> - 2.03.33-3
|
||||
- Allow integrity to use multiple segments for metadata.
|
||||
|
||||
* Mon Nov 10 2025 Marian Csontos <mcsontos@redhat.com> - 2.03.33-2
|
||||
- Add message when activating RAID volumes with snapshots.
|
||||
|
||||
* Mon Sep 29 2025 Marian Csontos <mcsontos@redhat.com> - 2.03.33-1
|
||||
- Update to upstream version 2.03.33.
|
||||
- See WHATS_NEW and WHATS_NEW_DM for more information.
|
||||
|
||||
* Tue Jun 03 2025 Marian Csontos <mcsontos@redhat.com> - 2.03.32-2
|
||||
- Fix vgremove hanging immediately after lockstart.
|
||||
- Add repair option for RAID volumes with too many transiently failed devices.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user