summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2015-06-02 14:42:53 -0500
committerDavid Teigland <teigland@redhat.com>2015-06-02 14:42:53 -0500
commit7df810cadec2d1533bc0a7431437d6764e69f4bb (patch)
tree1dc62083fefd31a9fe8fcb0fda3bd0a86f48f545
parent756302f9c6b322ae569e446776abcfb5cd141fd3 (diff)
downloadlvm2-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.c28
-rw-r--r--lib/metadata/lv.h1
-rw-r--r--lib/metadata/metadata.c20
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;