File 0001-lvconvert-swapmetadata-fix-lvmlockd-locking.patch of Package lvm2.38362

From ff0a8d7b6734c745e52652fc5e7dd3a0f2efb518 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Tue, 8 Aug 2023 16:57:22 -0500
Subject: [PATCH 01/24] lvconvert swapmetadata: fix lvmlockd locking

The lockd lock needs to be freed for the LV that is becoming
the new metadata LV, and a new lockd lock needs to be created
for the old metadata LV that is becoming an independent LV.
Fixes b3e45219c2f4
---
 tools/lvconvert.c | 45 +++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 43 insertions(+), 2 deletions(-)

diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 0004422f2..49047abb0 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -2818,6 +2818,9 @@ static int _lvconvert_swap_pool_metadata(struct cmd_context *cmd,
 	struct lv_type *lvtype;
 	char meta_name[NAME_LEN];
 	const char *swap_name;
+	char *lockd_meta_args = NULL;
+	char *lockd_meta_name = NULL;
+	struct id lockd_meta_id;
 	uint32_t chunk_size;
 	int is_thinpool;
 	int is_cachepool;
@@ -2872,6 +2875,12 @@ static int _lvconvert_swap_pool_metadata(struct cmd_context *cmd,
 	if (!lockd_lv(cmd, lv, "ex", 0))
 		return 0;
 
+	/* If new metadata LV is inactive here, ensure it's not active elsewhere */
+	if (!lockd_lv(cmd, metadata_lv, "ex", 0)) {
+		log_error("New pool metadata LV %s cannot be locked.", display_lvname(metadata_lv));
+		return 0;
+	}
+
 	if (!deactivate_lv(cmd, metadata_lv)) {
 		log_error("Aborting. Failed to deactivate %s.",
 			  display_lvname(metadata_lv));
@@ -2883,8 +2892,22 @@ static int _lvconvert_swap_pool_metadata(struct cmd_context *cmd,
 		return 0;
 	}
 
-        metadata_lv->lock_args = NULL;
-
+	/*
+	 * metadata_lv is currently an independent LV with its own lockd lock allocated.
+	 * A pool metadata LV does not have its own lockd lock (only the pool LV does.)
+	 * So, when metadata_lv is added to the thin pool, it's lock needs to be freed.
+	 * Save info about the metadata_lv here that will be used to free the lock.
+	 * The current pool metadata LV does not currently have its own lockd lock
+	 * allocated, and once it becomes an independent LV it will need its own lock.
+	 * (see setting prev_metadata_lv->lock_args below.)
+	 */
+	if (vg_is_shared(vg) && metadata_lv->lock_args) {
+		lockd_meta_args = dm_pool_strdup(cmd->mem, metadata_lv->lock_args);
+		lockd_meta_name = dm_pool_strdup(cmd->mem, metadata_lv->name);
+		memcpy(&lockd_meta_id, &metadata_lv->lvid.id[1], sizeof(struct id));
+		/* Without lock_args, a lock will no longer be acquired for this LV. */
+		metadata_lv->lock_args = NULL;
+	}
 
 	seg = first_seg(lv);
 
@@ -2950,9 +2973,27 @@ static int _lvconvert_swap_pool_metadata(struct cmd_context *cmd,
 	if (!attach_pool_metadata_lv(seg, metadata_lv))
 		return_0;
 
+	/*
+	 * The previous metadata LV will now be an independent LV so it now
+	 * requires a lockd lock.  We could call lockd_init_lv_args() directly
+	 * here, but reuse the existing code in vg_write() to be consistent
+	 * with the way lvcreate allocates locks.
+	 */
+	if (is_lockd_type(vg->lock_type)) {
+		if (!strcmp(vg->lock_type, "sanlock"))
+			prev_metadata_lv->lock_args = "pending";
+		else if (!strcmp(vg->lock_type, "dlm"))
+			prev_metadata_lv->lock_args = "dlm";
+		else if (!strcmp(vg->lock_type, "idm"))
+			prev_metadata_lv->lock_args = "idm";
+	}
+
 	if (!vg_write(vg) || !vg_commit(vg))
 		return_0;
 
+	if (lockd_meta_name)
+		lockd_free_lv(cmd, vg, lockd_meta_name, &lockd_meta_id, lockd_meta_args);
+
 	return 1;
 }
 
-- 
2.35.3

openSUSE Build Service is sponsored by