diff options
-rw-r--r-- | lib/locking/lvmlockd.c | 13 | ||||
-rw-r--r-- | lib/locking/lvmlockd.h | 4 | ||||
-rw-r--r-- | lib/metadata/lv_manip.c | 21 |
3 files changed, 23 insertions, 15 deletions
diff --git a/lib/locking/lvmlockd.c b/lib/locking/lvmlockd.c index 66ab3e18f..576fb529a 100644 --- a/lib/locking/lvmlockd.c +++ b/lib/locking/lvmlockd.c @@ -1821,6 +1821,9 @@ int lockd_init_lv_args(struct cmd_context *cmd, struct volume_group *vg, } dm_list_iterate_items(lvl, &vg->lvs) { + /* An exact match is the lv itself. */ + if (!strcmp(lvl->lv->name, lv_name)) + continue; if (!strncmp(lvl->lv->name, lv_name, maxname)) { log_error("LV name %s matches existing LV %s within %s character limit %d", lv_name, lvl->lv->name, vg->lock_type, maxname); @@ -1853,9 +1856,9 @@ int lockd_init_lv_args(struct cmd_context *cmd, struct volume_group *vg, */ int lockd_init_lv(struct cmd_context *cmd, struct volume_group *vg, - struct lvcreate_params *lp) + const char *lv_name, struct lvcreate_params *lp) { - const char *lv_name; + const char *lv_name_lock; int lock_type_num = lock_type_to_num(lp->lock_type); if (cmd->lock_lv_mode && !strcmp(cmd->lock_lv_mode, "na")) @@ -1934,7 +1937,7 @@ int lockd_init_lv(struct cmd_context *cmd, struct volume_group *vg, } else if (!seg_is_thin_volume(lp) && lp->create_pool) { /* Creating a thin pool only. */ - lv_name = lp->pool_name; + lv_name_lock = lp->pool_name; } else { log_error("Unknown thin options for lock init."); @@ -1943,10 +1946,10 @@ int lockd_init_lv(struct cmd_context *cmd, struct volume_group *vg, } else { /* Creating a normal lv. */ - lv_name = lp->lv_name; + lv_name_lock = lv_name; } - return lockd_init_lv_args(cmd, vg, lv_name, lp->lock_type, &lp->lock_args); + return lockd_init_lv_args(cmd, vg, lv_name_lock, lp->lock_type, &lp->lock_args); } /* lvremove */ diff --git a/lib/locking/lvmlockd.h b/lib/locking/lvmlockd.h index 5374204e5..ac66bbfd2 100644 --- a/lib/locking/lvmlockd.h +++ b/lib/locking/lvmlockd.h @@ -129,7 +129,7 @@ int lockd_lv(struct cmd_context *cmd, struct logical_volume *lv, /* lvcreate/lvremove use init/free */ int lockd_init_lv(struct cmd_context *cmd, struct volume_group *vg, - struct lvcreate_params *lp); + const char *lv_name, struct lvcreate_params *lp); int lockd_free_lv(struct cmd_context *cmd, struct volume_group *vg, const char *lv_name, const char *lock_args); @@ -166,7 +166,7 @@ int lockd_init_lv_args(struct cmd_context *cmd, struct volume_group *vg, #define lockd_lv_name(cmd, vg, lv_name, lock_args, def_mode, flags) (1) #define lockd_lv(cmd, lv, def_mode, flags) (1) -#define lockd_init_lv(cmd, vg, lp) (1) +#define lockd_init_lv(cmd, vg, lv_name, lp) (1) #define lockd_free_lv(cmd, vg, lv_name, lock_args) (1) #define lockd_init_lv_args(cmd, vg, lv_name, lock_type, lock_args) (1) diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c index 37e2c3880..f577ec06a 100644 --- a/lib/metadata/lv_manip.c +++ b/lib/metadata/lv_manip.c @@ -7034,13 +7034,22 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg, lv->major, lv->minor); } + /* + * lockd_init_lv clears lp lock_type if this LV does not use its own lock. + * TODO: use lockd_free_lv if lv_extend fails below. + */ + if (lp->lock_type && !lockd_init_lv(vg->cmd, vg, lv->name, lp)) + return_NULL; + if (lp->lock_type && !(lv->lock_type = dm_pool_strdup(cmd->mem, lp->lock_type))) { log_error("Failed to allocate lock_type"); + lockd_free_lv(vg->cmd, vg, lp->lv_name, lp->lock_args); return NULL; } if (lp->lock_args && !(lv->lock_args = dm_pool_strdup(cmd->mem, lp->lock_args))) { log_error("Failed to allocate lock_args"); + lockd_free_lv(vg->cmd, vg, lp->lv_name, lp->lock_args); return NULL; } @@ -7351,6 +7360,9 @@ deactivate_and_revert_new_lv: } revert_new_lv: + if (lp->lock_type) + lockd_free_lv(vg->cmd, vg, lp->lv_name, lp->lock_args); + /* FIXME Better to revert to backup of metadata? */ if (!lv_remove(lv) || !vg_write(vg) || !vg_commit(vg)) log_error("Manual intervention may be required to remove " @@ -7367,10 +7379,6 @@ struct logical_volume *lv_create_single(struct volume_group *vg, const struct segment_type *segtype; struct logical_volume *lv; - /* lockd_init_lv clears lock_type if this LV does not use its own lock. */ - if (lp->lock_type && !lockd_init_lv(vg->cmd, vg, lp)) - return_NULL; - /* Create pool first if necessary */ if (lp->create_pool && !seg_is_pool(lp)) { segtype = lp->segtype; @@ -7412,11 +7420,8 @@ struct logical_volume *lv_create_single(struct volume_group *vg, lp->segtype = segtype; } - if (!(lv = _lv_create_an_lv(vg, lp, lp->lv_name))) { - if (lp->lock_type) - lockd_free_lv(vg->cmd, vg, lp->lv_name, lp->lock_args); + if (!(lv = _lv_create_an_lv(vg, lp, lp->lv_name))) return_NULL; - } if (lp->temporary) log_verbose("Temporary logical volume \"%s\" created.", lv->name); |