96 lines
3.4 KiB
Diff
96 lines
3.4 KiB
Diff
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
|
|
|