summaryrefslogtreecommitdiff
path: root/tools/lvconvert.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/lvconvert.c')
-rw-r--r--tools/lvconvert.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 213b0da95..e3a4ae635 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -2689,6 +2689,12 @@ static int _lvconvert_thin(struct cmd_context *cmd,
return 0;
}
+ if (is_lockd_type(lv->vg->lock_type)) {
+ log_error("Can't use lock_type %s LV as external origin.",
+ lv->vg->lock_type);
+ return 0;
+ }
+
dm_list_init(&lvc.tags);
if (!pool_supports_external_origin(first_seg(pool_lv), lv))
@@ -2801,6 +2807,8 @@ static int _lvconvert_pool(struct cmd_context *cmd,
{
int r = 0;
const char *old_name;
+ const char *lock_free_meta_name = NULL;
+ const char *lock_free_data_name = NULL;
struct lv_segment *seg;
struct volume_group *vg = pool_lv->vg;
struct logical_volume *data_lv;
@@ -3138,6 +3146,36 @@ static int _lvconvert_pool(struct cmd_context *cmd,
if (!attach_pool_data_lv(seg, data_lv))
return_0;
+ /*
+ * A thin pool lv adopts the lock from the data lv, and the lock for
+ * the meta lv is unlocked and freed. A cache pool lv has no lock, and
+ * the existing lock for both data and meta lvs are unlocked and freed.
+ */
+ if (is_lockd_type(pool_lv->vg->lock_type)) {
+ if (lp->pool_metadata_name) {
+ char *c;
+ if ((c = strchr(lp->pool_metadata_name, '/')))
+ lock_free_meta_name = c + 1;
+ else
+ lock_free_meta_name = lp->pool_metadata_name;
+ }
+
+ if (segtype_is_cache_pool(lp->segtype)) {
+ lock_free_data_name = pool_lv->name;
+ pool_lv->lock_type = NULL;
+ pool_lv->lock_args = NULL;
+ } else {
+ if (data_lv->lock_type)
+ pool_lv->lock_type = dm_pool_strdup(cmd->mem, data_lv->lock_type);
+ if (data_lv->lock_args)
+ pool_lv->lock_args = dm_pool_strdup(cmd->mem, data_lv->lock_args);
+ }
+ data_lv->lock_type = NULL;
+ data_lv->lock_args = NULL;
+ metadata_lv->lock_type = NULL;
+ metadata_lv->lock_args = NULL;
+ }
+
/* FIXME: revert renamed LVs in fail path? */
/* FIXME: any common code with metadata/thin_manip.c extend_pool() ? */
@@ -3195,6 +3233,22 @@ out:
(segtype_is_cache_pool(lp->segtype)) ?
"cache" : "thin");
+ if (lock_free_meta_name) {
+ if (!lockd_lv_name(cmd, pool_lv->vg, lock_free_meta_name, NULL, "un", LDLV_PERSISTENT)) {
+ log_error("Failed to unlock pool metadata LV %s/%s",
+ pool_lv->vg->name, lock_free_meta_name);
+ }
+ lockd_free_lv(cmd, pool_lv->vg, lock_free_meta_name, NULL);
+ }
+
+ if (lock_free_data_name) {
+ if (!lockd_lv_name(cmd, pool_lv->vg, lock_free_data_name, NULL, "un", LDLV_PERSISTENT)) {
+ log_error("Failed to unlock pool data LV %s/%s",
+ pool_lv->vg->name, lock_free_data_name);
+ }
+ lockd_free_lv(cmd, pool_lv->vg, lock_free_data_name, NULL);
+ }
+
return r;
#if 0
revert_new_lv:
@@ -3457,6 +3511,17 @@ static int lvconvert_single(struct cmd_context *cmd, struct lvconvert_params *lp
goto_out;
/*
+ * If the lv is inactive before and after the command, the
+ * use of PERSISTENT here means the lv will remain locked as
+ * an effect of running the lvconvert.
+ * To unlock it, it would need to be activated+deactivated.
+ * Or, we could identify the commands for which the lv remains
+ * inactive, and not use PERSISTENT here for those cases.
+ */
+ if (!lockd_lv(cmd, lv, "ex", LDLV_PERSISTENT))
+ goto_out;
+
+ /*
* lp->pvh holds the list of PVs available for allocation or removal
*/
if (lp->pv_count) {