Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=2272a32e6f9b99f98514e…
Commit: 2272a32e6f9b99f98514e58de82f8a3baa8b46da
Parent: 82e270c18a76d68e2efc28a194bca2e428c18fae
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Tue Sep 29 14:33:44 2020 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Tue Sep 29 14:43:27 2020 -0500
lvmlockd vdo: add support
lvmlockd handling for vdo lv and vdo pool is like
thin lv and thin pool.
---
lib/locking/lvmlockd.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++
lib/metadata/lv_manip.c | 21 ++++++++++++--
2 files changed, 92 insertions(+), 2 deletions(-)
diff --git a/lib/locking/lvmlockd.c b/lib/locking/lvmlockd.c
index 9d11077e3..24b7ff6f7 100644
--- a/lib/locking/lvmlockd.c
+++ b/lib/locking/lvmlockd.c
@@ -2311,6 +2311,49 @@ static int _lockd_lv_thin(struct cmd_context *cmd, struct logical_volume *lv,
pool_lv->lock_args, def_mode, flags);
}
+static int _lockd_lv_vdo(struct cmd_context *cmd, struct logical_volume *lv,
+ const char *def_mode, uint32_t flags)
+{
+ struct logical_volume *pool_lv = NULL;
+
+ if (lv_is_vdo(lv)) {
+ if (first_seg(lv))
+ pool_lv = seg_lv(first_seg(lv), 0);
+
+ } else if (lv_is_vdo_pool(lv)) {
+ pool_lv = lv;
+
+ } else if (lv_is_vdo_pool_data(lv)) {
+ return 1;
+
+ } else {
+ /* This should not happen AFAIK. */
+ log_error("Lock on incorrect vdo lv type %s/%s",
+ lv->vg->name, lv->name);
+ return 0;
+ }
+
+ if (!pool_lv) {
+ /* This happens in lvremove where it's harmless. */
+ log_debug("No vdo pool for %s/%s", lv->vg->name, lv->name);
+ return 0;
+ }
+
+ /*
+ * Locking a locked lv (pool in this case) is a no-op.
+ * Unlock when the pool is no longer active.
+ */
+
+ if (def_mode && !strcmp(def_mode, "un") &&
+ lv_is_vdo_pool(pool_lv) && lv_is_active(lv_lock_holder(pool_lv)))
+ return 1;
+
+ flags |= LDLV_MODE_NO_SH;
+
+ return lockd_lv_name(cmd, pool_lv->vg, pool_lv->name, &pool_lv->lvid.id[1],
+ pool_lv->lock_args, def_mode, flags);
+}
+
/*
* If the VG has no lock_type, then this function can return immediately.
* The LV itself may have no lock (NULL lv->lock_args), but the lock request
@@ -2352,6 +2395,9 @@ int lockd_lv(struct cmd_context *cmd, struct logical_volume *lv,
if (lv_is_thin_type(lv))
return _lockd_lv_thin(cmd, lv, def_mode, flags);
+ if (lv_is_vdo_type(lv))
+ return _lockd_lv_vdo(cmd, lv, def_mode, flags);
+
/*
* An LV with NULL lock_args does not have a lock of its own.
*/
@@ -2724,6 +2770,27 @@ int lockd_init_lv(struct cmd_context *cmd, struct volume_group *vg, struct logic
return 0;
}
+ } else if (seg_is_vdo(lp)) {
+ struct lv_list *lvl;
+
+ /*
+ * A vdo lv is being created in a vdo pool. The vdo lv does
+ * not have its own lock, the lock of the vdo pool is used, and
+ * the vdo pool needs to be locked to create a vdo lv in it.
+ */
+
+ if (!(lvl = find_lv_in_vg(vg, lp->pool_name))) {
+ log_error("Failed to find vdo pool %s/%s", vg->name, lp->pool_name);
+ return 0;
+ }
+
+ if (!lockd_lv(cmd, lvl->lv, "ex", LDLV_PERSISTENT)) {
+ log_error("Failed to lock vdo pool %s/%s", vg->name, lp->pool_name);
+ return 0;
+ }
+ lv->lock_args = NULL;
+ return 1;
+
} else {
/* Creating a normal lv. */
/* lv_name_lock = lv_name; */
@@ -2963,6 +3030,12 @@ int lockd_lv_uses_lock(struct logical_volume *lv)
if (lv_is_pool_metadata_spare(lv))
return 0;
+ if (lv_is_vdo(lv))
+ return 0;
+
+ if (lv_is_vdo_pool_data(lv))
+ return 0;
+
if (lv_is_cache_vol(lv))
return 0;
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 9dbb6e1b5..a907130ff 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -1222,8 +1222,19 @@ static int _release_and_discard_lv_segment_area(struct lv_segment *seg, uint32_t
}
/* When removed last VDO user automatically removes VDO pool */
- if (lv_is_vdo_pool(lv) && dm_list_empty(&(lv->segs_using_this_lv)))
- return lv_remove(lv); /* FIXME: any upper level reporting */
+ if (lv_is_vdo_pool(lv) && dm_list_empty(&(lv->segs_using_this_lv))) {
+ struct volume_group *vg = lv->vg;
+
+ if (!lv_remove(lv)) /* FIXME: any upper level reporting */
+ return_0;
+
+ if (vg_is_shared(vg)) {
+ if (!lockd_lv_name(vg->cmd, vg, lv->name, &lv->lvid.id[1], lv->lock_args, "un", LDLV_PERSISTENT))
+ log_error("Failed to unlock vdo pool in lvmlockd.");
+ lockd_free_lv(vg->cmd, vg, lv->name, &lv->lvid.id[1], lv->lock_args);
+ }
+ return 1;
+ }
return 1;
}
@@ -8730,9 +8741,15 @@ struct logical_volume *lv_create_single(struct volume_group *vg,
/* The VDO segment needs VDO pool which is layer above created striped data LV */
if (!(lp->segtype = get_segtype_from_string(vg->cmd, SEG_TYPE_NAME_VDO_POOL)))
return_NULL;
+
+ /* We want a lockd lock for the new vdo pool, but not the vdo lv. */
+ lp->needs_lockd_init = 1;
+
/* Use vpool names for vdo-pool */
if (!(lv = _lv_create_an_lv(vg, lp, lp->pool_name ? : "vpool%d")))
return_NULL;
+
+ lp->needs_lockd_init = 0;
} else {
log_error(INTERNAL_ERROR "Creation of pool for unsupported segment type %s.",
lp->segtype->name);
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=4cd356b26b85e075490be…
Commit: 4cd356b26b85e075490be29b9e1e40b3aafe2d5b
Parent: 18c74666ee668c5d4569c868f38c3d8ae950dda1
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Sun Sep 27 02:20:50 2020 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Sep 29 10:43:56 2020 +0200
thin: remove unneeded code test
Since we detect already transaction if before starting
to build dm tree - this extra check is a duplicate
that would only capture very tiny 'race' and we later
validate transaction_id with suspended snapshot origin.
---
lib/thin/thin.c | 20 --------------------
1 file changed, 20 deletions(-)
diff --git a/lib/thin/thin.c b/lib/thin/thin.c
index 9c4bfb39c..ba0da712d 100644
--- a/lib/thin/thin.c
+++ b/lib/thin/thin.c
@@ -265,8 +265,6 @@ static int _thin_pool_add_target_line(struct dev_manager *dm,
char *metadata_dlid, *pool_dlid;
const struct lv_thin_message *lmsg;
const struct logical_volume *origin;
- struct lvinfo info;
- uint64_t transaction_id = 0;
unsigned attr;
uint64_t low_water_mark;
int threshold;
@@ -351,24 +349,6 @@ static int _thin_pool_add_target_line(struct dev_manager *dm,
case DM_THIN_MESSAGE_CREATE_THIN:
origin = first_seg(lmsg->u.lv)->origin;
/* Check if the origin is suspended */
- if (origin && lv_info(cmd, origin, 1, &info, 0, 0) &&
- info.exists && !info.suspended) {
- /* Origin is not suspended, but the transaction may have been
- * already transfered, so test for transaction_id and
- * allow to pass in the message for dmtree processing
- * so it will skip all messages later.
- */
- if (!lv_thin_pool_transaction_id(seg->lv, &transaction_id))
- return_0; /* Thin pool should exist and work */
- if ((transaction_id + 1) != seg->transaction_id) {
- log_error("Omitting suspend of thin snapshot origin %s with expected "
- "transaction_id " FMTu64 ", but active pool has " FMTu64 ".",
- display_lvname(origin),
- !seg->transaction_id ? 0 : seg->transaction_id - 1,
- transaction_id);
- return 0;
- }
- }
log_debug_activation("Thin pool create_%s %s.", (!origin) ? "thin" : "snap", lmsg->u.lv->name);
if (!dm_tree_node_add_thin_pool_message(node,
(!origin) ? lmsg->type : DM_THIN_MESSAGE_CREATE_SNAP,