diff options
author | David Teigland <teigland@redhat.com> | 2015-06-02 14:42:53 -0500 |
---|---|---|
committer | David Teigland <teigland@redhat.com> | 2015-06-02 14:42:53 -0500 |
commit | 7df810cadec2d1533bc0a7431437d6764e69f4bb (patch) | |
tree | 1dc62083fefd31a9fe8fcb0fda3bd0a86f48f545 | |
parent | 756302f9c6b322ae569e446776abcfb5cd141fd3 (diff) | |
download | lvm2-dev-dct-lvmlockd-AK.tar.gz |
lvmlockd: move sanlock lease allocationdev-dct-lvmlockd-AK
The lockd_init_lv() function no longer calls lvmlockd
to ask for the sanlock lease to be allocated for the LV,
i.e. lockd_init_lv_args().
Instead, it waits until vg_write() to do that, so the sanlock
lease does not need to be freed in all the cases where lvcreate
may quit before actually finishing.
-rw-r--r-- | lib/locking/lvmlockd.c | 28 | ||||
-rw-r--r-- | lib/metadata/lv.h | 1 | ||||
-rw-r--r-- | lib/metadata/metadata.c | 20 |
3 files changed, 44 insertions, 5 deletions
diff --git a/lib/locking/lvmlockd.c b/lib/locking/lvmlockd.c index be894cb2e..103558bc2 100644 --- a/lib/locking/lvmlockd.c +++ b/lib/locking/lvmlockd.c @@ -2085,7 +2085,6 @@ int lockd_init_lv(struct cmd_context *cmd, struct volume_group *vg, const char *lv_name, struct id *lv_id, struct lvcreate_params *lp) { - 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")) @@ -2164,7 +2163,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_lock = lp->pool_name; + /* lv_name_lock = lp->pool_name; */ } else { log_error("Unknown thin options for lock init."); @@ -2173,11 +2172,30 @@ int lockd_init_lv(struct cmd_context *cmd, struct volume_group *vg, } else { /* Creating a normal lv. */ - lv_name_lock = lv_name; + /* lv_name_lock = lv_name; */ } - return lockd_init_lv_args(cmd, vg, lv_name_lock, lv_id, - lp->lock_type, &lp->lock_args); + /* + * lockd_init_lv_args() will be called during vg_write() + * to complete the sanlock LV lock initialization, where + * actual space on disk is allocated. Waiting to do this + * last step until vg_write() avoids the need to revert + * the sanlock allocation if the lvcreate function isn't + * completed. + * + * This works, but would leave the sanlock lease allocated + * unless the lease was freed on each early exit path from + * lvcreate: + * + * return lockd_init_lv_args(cmd, vg, lv_name_lock, lv_id, + * lp->lock_type, &lp->lock_args); + */ + + if (!strcmp(lp->lock_type, "sanlock")) + lp->lock_args = "pending"; + + return 1; + } /* lvremove */ diff --git a/lib/metadata/lv.h b/lib/metadata/lv.h index ad17da5d5..5523b133f 100644 --- a/lib/metadata/lv.h +++ b/lib/metadata/lv.h @@ -51,6 +51,7 @@ struct logical_volume { struct dm_list segs_using_this_lv; uint64_t timestamp; + unsigned new_lock_args:1; const char *hostname; const char *lock_type; const char *lock_args; diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c index 508f5bb19..7c68ab630 100644 --- a/lib/metadata/metadata.c +++ b/lib/metadata/metadata.c @@ -2817,8 +2817,20 @@ int vg_write(struct volume_group *vg) struct dm_list *mdah; struct pv_to_create *pv_to_create; struct metadata_area *mda; + struct lv_list *lvl; int revert = 0, wrote = 0; + dm_list_iterate_items(lvl, &vg->lvs) { + if (lvl->lv->lock_args && !strcmp(lvl->lv->lock_args, "pending")) { + if (!lockd_init_lv_args(vg->cmd, vg, lvl->lv->name, &lvl->lv->lvid.id[1], + lvl->lv->lock_type, &lvl->lv->lock_args)) { + log_error("Cannot allocate lock for new LV."); + return 0; + } + lvl->lv->new_lock_args = 1; + } + } + if (!vg_validate(vg)) return_0; @@ -3020,6 +3032,14 @@ int vg_commit(struct volume_group *vg) void vg_revert(struct volume_group *vg) { struct metadata_area *mda; + struct lv_list *lvl; + + dm_list_iterate_items(lvl, &vg->lvs) { + if (lvl->lv->new_lock_args) { + lockd_free_lv(vg->cmd, vg, lvl->lv->name, &lvl->lv->lvid.id[1], lvl->lv->lock_args); + lvl->lv->new_lock_args = 0; + } + } release_vg(vg->vg_precommitted); /* VG is no longer needed */ vg->vg_precommitted = NULL; |