diff options
author | Peter Rajnoha <prajnoha@redhat.com> | 2015-08-26 14:34:30 +0200 |
---|---|---|
committer | Peter Rajnoha <prajnoha@redhat.com> | 2016-02-19 14:40:23 +0100 |
commit | 80f1fd60a502cf995e3ecf2d506c547f7df506cc (patch) | |
tree | d016f768ab63f06b6e412b8d2367fe679cd63e8e | |
parent | b91d8dabb7219f183ae5d102c28050711b2e41d8 (diff) | |
download | lvm2-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.c | 33 | ||||
-rw-r--r-- | lib/metadata/metadata-exported.h | 3 | ||||
-rw-r--r-- | lib/metadata/vg.c | 1 | ||||
-rw-r--r-- | lib/metadata/vg.h | 5 |
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. */ |