diff options
author | David Teigland <teigland@redhat.com> | 2015-06-04 15:11:38 -0500 |
---|---|---|
committer | David Teigland <teigland@redhat.com> | 2015-06-23 17:08:53 -0500 |
commit | 802198ea90ed0ff07829737e0196eb3d85ff9ea5 (patch) | |
tree | c7d2d1ac444979becc631b6b9883625f1591e501 | |
parent | 543d157ab9f73b67d361f1a2cfcdd09cdf58531a (diff) | |
download | lvm2-802198ea90ed0ff07829737e0196eb3d85ff9ea5.tar.gz |
lvconvert: fixes for lvmlockd
A new thin pool LV gets a new lock in lvmlockd.
The locks from data and meta LVs are unlocked and freed.
-rw-r--r-- | tools/lvconvert.c | 95 |
1 files changed, 52 insertions, 43 deletions
diff --git a/tools/lvconvert.c b/tools/lvconvert.c index 0effd0d44..6161b71cf 100644 --- a/tools/lvconvert.c +++ b/tools/lvconvert.c @@ -2643,18 +2643,21 @@ 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 id *lock_free_meta_id; - struct id *lock_free_data_id; struct lv_segment *seg; struct volume_group *vg = pool_lv->vg; struct logical_volume *data_lv; struct logical_volume *metadata_lv = NULL; struct logical_volume *pool_metadata_lv; + char *free_data_name = NULL; + char *free_meta_name = NULL; + struct id free_data_id; + struct id free_meta_id; char metadata_name[NAME_LEN], data_name[NAME_LEN]; int activate_pool; + memset(&free_data_id, 0, sizeof(free_data_id)); + memset(&free_meta_id, 0, sizeof(free_meta_id)); + if (lp->pool_data_name) { if ((lp->thin || lp->cache) && !strcmp(lp->pool_data_name, pool_lv->name)) { @@ -2668,6 +2671,12 @@ static int _lvconvert_pool(struct cmd_context *cmd, } } + /* An existing LV needs to have its lock freed once it becomes a data LV. */ + if (!lv_is_pool(pool_lv)) { + free_data_name = dm_pool_strdup(cmd->mem, pool_lv->name); + memcpy(&free_data_id, &pool_lv->lvid.id[1], sizeof(struct id)); + } + if (!lv_is_visible(pool_lv)) { log_error("Can't convert internal LV %s.", display_lvname(pool_lv)); return 0; @@ -2723,6 +2732,10 @@ static int _lvconvert_pool(struct cmd_context *cmd, lp->pool_metadata_extents = lp->pool_metadata_lv->le_count; metadata_lv = lp->pool_metadata_lv; + /* An existing LV needs to have its lock freed once it becomes a meta LV. */ + free_meta_name = dm_pool_strdup(cmd->mem, metadata_lv->name); + memcpy(&free_meta_id, &metadata_lv->lvid.id[1], sizeof(struct id)); + if (metadata_lv == pool_lv) { log_error("Can't use same LV for pool data and metadata LV %s.", display_lvname(metadata_lv)); @@ -2986,36 +2999,27 @@ static int _lvconvert_pool(struct cmd_context *cmd, 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. + * Create a new lock for a thin pool LV. A cache pool LV has no lock. + * Locks are removed from existing LVs that are being converted to + * data and meta LVs (they are unlocked and deleted below.) */ - 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 (is_lockd_type(vg->lock_type)) { + if (segtype_is_cache_pool(lp->segtype)) { + data_lv->lock_type = NULL; + data_lv->lock_args = NULL; + metadata_lv->lock_type = NULL; + metadata_lv->lock_args = NULL; + } else { + data_lv->lock_type = NULL; + data_lv->lock_args = NULL; + metadata_lv->lock_type = NULL; + metadata_lv->lock_args = NULL; - lock_free_meta_id = &lp->pool_metadata_lv->lvid.id[1]; + pool_lv->lock_type = dm_pool_strdup(cmd->mem, vg->lock_type); + if (!strcmp(pool_lv->lock_type, "sanlock")) + pool_lv->lock_args = "pending"; + /* The lock_args will be set in vg_write(). */ } - - if (segtype_is_cache_pool(lp->segtype)) { - lock_free_data_name = pool_lv->name; - lock_free_data_id = &pool_lv->lvid.id[1]; - 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? */ @@ -3051,6 +3055,11 @@ mda_write: log_warn("WARNING: Pool zeroing and large %s chunk size slows down " "provisioning.", display_size(cmd, seg->chunk_size)); + if (activate_pool && !lockd_lv(cmd, pool_lv, "ex", LDLV_PERSISTENT)) { + log_error("Failed to lock pool LV %s/%s", vg->name, pool_lv->name); + goto out; + } + if (activate_pool && !activate_lv_excl(cmd, pool_lv)) { log_error("Failed to activate pool logical volume %s.", @@ -3075,20 +3084,20 @@ 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, lock_free_meta_id, 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, lock_free_meta_id, NULL); + /* + * Unlock and free the locks from existing LVs that became pool data + * and meta LVs. + */ + if (free_data_name) { + if (!lockd_lv_name(cmd, vg, free_data_name, &free_data_id, NULL, "un", LDLV_PERSISTENT)) + log_error("Failed to unlock pool data LV %s/%s", vg->name, free_data_name); + lockd_free_lv(cmd, vg, free_data_name, &free_data_id, NULL); } - if (lock_free_data_name) { - if (!lockd_lv_name(cmd, pool_lv->vg, lock_free_data_name, lock_free_data_id, 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, lock_free_data_id, NULL); + if (free_meta_name) { + if (!lockd_lv_name(cmd, vg, free_meta_name, &free_meta_id, NULL, "un", LDLV_PERSISTENT)) + log_error("Failed to unlock pool metadata LV %s/%s", vg->name, free_meta_name); + lockd_free_lv(cmd, vg, free_meta_name, &free_meta_id, NULL); } return r; |