summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Rajnoha <prajnoha@redhat.com>2015-08-26 14:34:30 +0200
committerPeter Rajnoha <prajnoha@redhat.com>2016-02-19 14:40:23 +0100
commit80f1fd60a502cf995e3ecf2d506c547f7df506cc (patch)
treed016f768ab63f06b6e412b8d2367fe679cd63e8e
parentb91d8dabb7219f183ae5d102c28050711b2e41d8 (diff)
downloadlvm2-80f1fd60a502cf995e3ecf2d506c547f7df506cc.tar.gz
metadata: add former_glv_remove fn
Add former_glv_remove function to add support for removing former LVs from history.
-rw-r--r--lib/metadata/lv_manip.c33
-rw-r--r--lib/metadata/metadata-exported.h3
-rw-r--r--lib/metadata/vg.c1
-rw-r--r--lib/metadata/vg.h5
4 files changed, 40 insertions, 2 deletions
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index d517b157b..eb157d152 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -1398,11 +1398,40 @@ int lv_reduce(struct logical_volume *lv, uint32_t extents)
return _lv_reduce(lv, extents, 1);
}
+int former_glv_remove(struct generic_logical_volume *glv)
+{
+ struct generic_logical_volume *origin_glv;
+ struct glv_list *glvl, *user_glvl;
+
+ if (!glv || !glv->is_former)
+ return_0;
+
+ if (!(glv = find_former_glv(glv->former->vg, glv->former->name, &glvl))) {
+ log_error(INTERNAL_ERROR "former_glv_remove: former LV %s/-%s not found ",
+ glv->former->vg->name, glv->former->dname);
+ return 0;
+ }
+
+ if ((origin_glv = glv->former->indirect_origin) &&
+ !remove_glv_from_indirect_glvs(origin_glv, glv))
+ return_0;
+
+ dm_list_iterate_items(user_glvl, &glv->former->indirect_glvs) {
+ if (!add_glv_to_indirect_glvs(glv->former->vg->vgmem, origin_glv, user_glvl->glv))
+ return_0;
+ }
+
+ dm_list_move(&glv->former->vg->removed_former_lvs, &glvl->list);
+ return 1;
+}
+
/*
* Completely remove an LV.
*/
int lv_remove(struct logical_volume *lv)
{
+ if (lv_is_former(lv))
+ return former_glv_remove(lv->this_glv);
if (!lv_reduce(lv, lv->le_count))
return_0;
@@ -5738,9 +5767,9 @@ int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv,
is_last_pool = 1;
}
- /* Used cache pool or COW cannot be activated */
+ /* Used cache pool, COW or former LV cannot be activated */
if ((!lv_is_cache_pool(lv) || dm_list_empty(&lv->segs_using_this_lv)) &&
- !lv_is_cow(lv) &&
+ !lv_is_cow(lv) && !lv_is_former(lv) &&
!deactivate_lv(cmd, lv)) {
/* FIXME Review and fix the snapshot error paths! */
log_error("Unable to deactivate logical volume %s.",
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index 40e9572e1..9b7ead9c8 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -775,6 +775,9 @@ int lv_extend(struct logical_volume *lv,
/* lv must be part of lv->vg->lvs */
int lv_remove(struct logical_volume *lv);
+/* former_glv must be part of lv->vg->former_lvs */
+int former_glv_remove(struct generic_logical_volume *former_glv);
+
int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv,
force_t force, int suppress_remove_message);
diff --git a/lib/metadata/vg.c b/lib/metadata/vg.c
index 687d1aa28..0b0f08484 100644
--- a/lib/metadata/vg.c
+++ b/lib/metadata/vg.c
@@ -66,6 +66,7 @@ struct volume_group *alloc_vg(const char *pool_name, struct cmd_context *cmd,
dm_list_init(&vg->former_lvs);
dm_list_init(&vg->tags);
dm_list_init(&vg->removed_lvs);
+ dm_list_init(&vg->removed_former_lvs);
dm_list_init(&vg->removed_pvs);
log_debug_mem("Allocated VG %s at %p.", vg->name, vg);
diff --git a/lib/metadata/vg.h b/lib/metadata/vg.h
index 533a115ab..569970d6a 100644
--- a/lib/metadata/vg.h
+++ b/lib/metadata/vg.h
@@ -140,6 +140,11 @@ struct volume_group {
struct dm_list removed_lvs;
/*
+ * List of removed former logical volumes by former_glv_remove.
+ */
+ struct dm_list removed_former_lvs;
+
+ /*
* List of removed physical volumes by pvreduce.
* They have to get cleared on vg_commit.
*/