summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2015-08-24 15:06:23 -0500
committerDavid Teigland <teigland@redhat.com>2015-08-27 10:27:24 -0500
commitde4db6a93b9e3be1968b1d1b7e2de8f1f88bacf0 (patch)
treed8b825a1c691833b9e291096129ef6b26341b360
parentd797f4d5903bf33618be38c543b8e7822a74b506 (diff)
downloadlvm2-de4db6a93b9e3be1968b1d1b7e2de8f1f88bacf0.tar.gz
lvmlockd: add full changing of lock type
Remove the existing lock type using the same functions used to remove the lockd components during vgremove. This results in a "clean" VG and lvmlockd state after the vgchange, i.e. no bits left over from previous lock type.
-rw-r--r--lib/locking/lvmlockd.c45
-rw-r--r--lib/locking/lvmlockd.h2
-rw-r--r--tools/vgchange.c41
-rw-r--r--tools/vgremove.c2
4 files changed, 59 insertions, 31 deletions
diff --git a/lib/locking/lvmlockd.c b/lib/locking/lvmlockd.c
index 5918de347..3f73cf3a2 100644
--- a/lib/locking/lvmlockd.c
+++ b/lib/locking/lvmlockd.c
@@ -868,10 +868,37 @@ int lockd_init_vg(struct cmd_context *cmd, struct volume_group *vg,
}
}
+static int _lockd_all_lvs(struct cmd_context *cmd, struct volume_group *vg)
+{
+ struct lv_list *lvl;
+
+ dm_list_iterate_items(lvl, &vg->lvs) {
+ if (!lockd_lv(cmd, lvl->lv, "ex", 0)) {
+ log_error("LV %s/%s must be inactive on all hosts.",
+ vg->name, lvl->lv->name);
+ return 0;
+ }
+
+ if (!lockd_lv(cmd, lvl->lv, "un", 0)) {
+ log_error("Failed to unlock LV %s/%s.", vg->name, lvl->lv->name);
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
/* vgremove before the vg is removed */
-int lockd_free_vg_before(struct cmd_context *cmd, struct volume_group *vg)
+int lockd_free_vg_before(struct cmd_context *cmd, struct volume_group *vg,
+ int changing)
{
+ /* Check that no LVs are active on other hosts. */
+ if (changing && !_lockd_all_lvs(cmd, vg)) {
+ log_error("Cannot change VG %s with active LVs", vg->name);
+ return 0;
+ }
+
switch (get_lock_type_from_string(vg->lock_type)) {
case LOCK_TYPE_NONE:
case LOCK_TYPE_CLVM:
@@ -2374,7 +2401,6 @@ int lockd_free_lv(struct cmd_context *cmd, struct volume_group *vg,
int lockd_rename_vg_before(struct cmd_context *cmd, struct volume_group *vg)
{
- struct lv_list *lvl;
daemon_reply reply;
int result;
int ret;
@@ -2392,18 +2418,9 @@ int lockd_rename_vg_before(struct cmd_context *cmd, struct volume_group *vg)
}
/* Check that no LVs are active on other hosts. */
-
- dm_list_iterate_items(lvl, &vg->lvs) {
- if (!lockd_lv(cmd, lvl->lv, "ex", 0)) {
- log_error("LV %s/%s must be inactive on all hosts before vgrename.",
- vg->name, lvl->lv->name);
- return 0;
- }
-
- if (!lockd_lv(cmd, lvl->lv, "un", 0)) {
- log_error("Failed to unlock LV %s/%s.", vg->name, lvl->lv->name);
- return 0;
- }
+ if (!_lockd_all_lvs(cmd, vg)) {
+ log_error("Cannot rename VG %s with active LVs", vg->name);
+ return 0;
}
/*
diff --git a/lib/locking/lvmlockd.h b/lib/locking/lvmlockd.h
index 64b3ce9aa..ec36ff81a 100644
--- a/lib/locking/lvmlockd.h
+++ b/lib/locking/lvmlockd.h
@@ -54,7 +54,7 @@ void lvmlockd_disconnect(void);
/* vgcreate/vgremove use init/free */
int lockd_init_vg(struct cmd_context *cmd, struct volume_group *vg, const char *lock_type, int lv_lock_count);
-int lockd_free_vg_before(struct cmd_context *cmd, struct volume_group *vg);
+int lockd_free_vg_before(struct cmd_context *cmd, struct volume_group *vg, int changing);
void lockd_free_vg_final(struct cmd_context *cmd, struct volume_group *vg);
/* vgrename */
diff --git a/tools/vgchange.c b/tools/vgchange.c
index cbdc29a3e..f57fa1555 100644
--- a/tools/vgchange.c
+++ b/tools/vgchange.c
@@ -568,11 +568,17 @@ static int _vgchange_locktype(struct cmd_context *cmd,
}
if (!strcmp(vg->lock_type, lock_type)) {
- log_warn("New lock_type %s matches the current lock_type %s.",
+ log_warn("New lock type %s matches the current lock type %s.",
lock_type, vg->lock_type);
return 1;
}
+ if (is_lockd_type(vg->lock_type) && is_lockd_type(lock_type)) {
+ log_error("First change from lock type %s to none, then to lock type %s",
+ vg->lock_type, lock_type);
+ return 0;
+ }
+
/*
* When lvm is currently using clvm, this function is just an alternative
* to vgchange -c{y,n}, and can:
@@ -627,17 +633,19 @@ static int _vgchange_locktype(struct cmd_context *cmd,
/*
* lockd type to ..., first undo lockd type
- *
- * To allow this, we need to do:
- * lockd_stop_vg();
- * lockd_free_vg_before();
- * lockd_free_vg_after();
*/
if (is_lockd_type(vg->lock_type)) {
- /* FIXME: implement full undoing of the lock_type */
- log_error("Changing VG %s from lock type %s not yet allowed.",
- vg->name, vg->lock_type);
- return 0;
+ if (!lockd_free_vg_before(cmd, vg, 1))
+ return 0;
+
+ lockd_free_vg_final(cmd, vg);
+
+ vg->status &= ~CLUSTERED;
+ vg->lock_type = "none";
+ vg->lock_args = NULL;
+
+ dm_list_iterate_items(lvl, &vg->lvs)
+ lvl->lv->lock_args = NULL;
}
/* ... to clvm */
@@ -716,7 +724,14 @@ static int _vgchange_locktype(struct cmd_context *cmd,
return 1;
}
- log_error("Unknown lock type");
+ /* ... to none */
+ if (!strcmp(lock_type, "none")) {
+ vg->lock_type = NULL;
+ vg->system_id = cmd->system_id ? dm_pool_strdup(vg->vgmem, cmd->system_id) : NULL;
+ return 1;
+ }
+
+ log_error("Cannot change to unknown lock type %s", lock_type);
return 0;
}
@@ -791,10 +806,6 @@ static int _vgchange_system_id(struct cmd_context *cmd, struct volume_group *vg)
if (vg->lvm1_system_id)
*vg->lvm1_system_id = '\0';
- /* update system_id in lvmlockd's record for this vg */
- if (!lockd_start_vg(cmd, vg))
- log_debug("Failed to update lvmlockd.");
-
return 1;
}
diff --git a/tools/vgremove.c b/tools/vgremove.c
index 692d11461..219149ee0 100644
--- a/tools/vgremove.c
+++ b/tools/vgremove.c
@@ -68,7 +68,7 @@ static int vgremove_single(struct cmd_context *cmd, const char *vg_name,
}
}
- if (!lockd_free_vg_before(cmd, vg))
+ if (!lockd_free_vg_before(cmd, vg, 0))
return_ECMD_FAILED;
if (!force && !vg_remove_check(vg))