mirror of
git://sourceware.org/git/lvm2.git
synced 2025-01-03 05:18:29 +03:00
metadata: add historical_glv_remove
This commit is contained in:
parent
ccebf3100d
commit
f833a6d074
@ -788,7 +788,7 @@ static int _read_historical_lvnames_interconnections(struct format_instance *fid
|
||||
historical_lv_name = hlvn->key;
|
||||
hlvn = hlvn->child;
|
||||
|
||||
if (!(glv = find_historical_glv(vg, historical_lv_name, NULL))) {
|
||||
if (!(glv = find_historical_glv(vg, historical_lv_name, 0, NULL))) {
|
||||
log_error("Unknown historical logical volume %s/%s%s",
|
||||
vg->name, HISTORICAL_LV_PREFIX, historical_lv_name);
|
||||
goto bad;
|
||||
@ -828,7 +828,7 @@ static int _read_historical_lvnames_interconnections(struct format_instance *fid
|
||||
glvl->glv = glv;
|
||||
|
||||
if (!strncmp(origin_name, HISTORICAL_LV_PREFIX, strlen(HISTORICAL_LV_PREFIX))) {
|
||||
if (!(origin_glv = find_historical_glv(vg, origin_name + strlen(HISTORICAL_LV_PREFIX), NULL))) {
|
||||
if (!(origin_glv = find_historical_glv(vg, origin_name + strlen(HISTORICAL_LV_PREFIX), 0, NULL))) {
|
||||
log_error("Unknown origin %s for historical logical volume %s/%s%s",
|
||||
origin_name, vg->name, HISTORICAL_LV_PREFIX, historical_lv_name);
|
||||
goto bad;
|
||||
|
@ -1398,11 +1398,75 @@ int lv_reduce(struct logical_volume *lv, uint32_t extents)
|
||||
return _lv_reduce(lv, extents, 1);
|
||||
}
|
||||
|
||||
int historical_glv_remove(struct generic_logical_volume *glv)
|
||||
{
|
||||
struct generic_logical_volume *origin_glv;
|
||||
struct glv_list *glvl, *user_glvl;
|
||||
struct historical_logical_volume *hlv;
|
||||
int reconnected;
|
||||
|
||||
if (!glv || !glv->is_historical)
|
||||
return_0;
|
||||
|
||||
hlv = glv->historical;
|
||||
|
||||
if (!(glv = find_historical_glv(hlv->vg, hlv->name, 0, &glvl))) {
|
||||
if (!(find_historical_glv(hlv->vg, hlv->name, 1, NULL))) {
|
||||
log_error(INTERNAL_ERROR "historical_glv_remove: historical LV %s/-%s not found ",
|
||||
hlv->vg->name, hlv->name);
|
||||
return 0;
|
||||
} else {
|
||||
log_verbose("Historical LV %s/-%s already on removed list ",
|
||||
hlv->vg->name, hlv->name);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ((origin_glv = hlv->indirect_origin) &&
|
||||
!remove_glv_from_indirect_glvs(origin_glv, glv))
|
||||
return_0;
|
||||
|
||||
dm_list_iterate_items(user_glvl, &hlv->indirect_glvs) {
|
||||
reconnected = 0;
|
||||
if ((origin_glv && !origin_glv->is_historical) && !user_glvl->glv->is_historical)
|
||||
log_verbose("Removing historical connection between %s and %s.",
|
||||
origin_glv->live->name, user_glvl->glv->live->name);
|
||||
else if (hlv->vg->cmd->record_historical_lvs) {
|
||||
if (!add_glv_to_indirect_glvs(hlv->vg->vgmem, origin_glv, user_glvl->glv))
|
||||
return_0;
|
||||
reconnected = 1;
|
||||
}
|
||||
|
||||
if (!reconnected) {
|
||||
/*
|
||||
* Break ancestry chain if we're removing historical LV and tracking
|
||||
* historical LVs is switched off either via:
|
||||
* - "metadata/record_lvs_history=0" config
|
||||
* - "--nohistory" cmd line option
|
||||
*
|
||||
* Also, break the chain if we're unable to store such connection at all
|
||||
* because we're removing the very last historical LV that was in between
|
||||
* live LVs - pure live LVs can't store any indirect origin relation in
|
||||
* metadata - we need at least one historical LV to do that!
|
||||
*/
|
||||
if (user_glvl->glv->is_historical)
|
||||
user_glvl->glv->historical->indirect_origin = NULL;
|
||||
else
|
||||
first_seg(user_glvl->glv->live)->indirect_origin = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
dm_list_move(&hlv->vg->removed_historical_lvs, &glvl->list);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Completely remove an LV.
|
||||
*/
|
||||
int lv_remove(struct logical_volume *lv)
|
||||
{
|
||||
if (lv_is_historical(lv))
|
||||
return historical_glv_remove(lv->this_glv);
|
||||
|
||||
if (!lv_reduce(lv, lv->le_count))
|
||||
return_0;
|
||||
@ -5740,9 +5804,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 historical 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_historical(lv) &&
|
||||
!deactivate_lv(cmd, lv)) {
|
||||
/* FIXME Review and fix the snapshot error paths! */
|
||||
log_error("Unable to deactivate logical volume %s.",
|
||||
|
@ -807,6 +807,9 @@ int lv_extend(struct logical_volume *lv,
|
||||
/* lv must be part of lv->vg->lvs */
|
||||
int lv_remove(struct logical_volume *lv);
|
||||
|
||||
/* historical_glv must be part of lv->vg->historical_lvs */
|
||||
int historical_glv_remove(struct generic_logical_volume *historical_glv);
|
||||
|
||||
int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
force_t force, int suppress_remove_message);
|
||||
|
||||
@ -1029,6 +1032,7 @@ struct logical_volume *find_lv(const struct volume_group *vg,
|
||||
|
||||
struct generic_logical_volume *find_historical_glv(const struct volume_group *vg,
|
||||
const char *historical_lv_name,
|
||||
int check_removed_list,
|
||||
struct glv_list **glvl_found);
|
||||
|
||||
struct physical_volume *find_pv_by_name(struct cmd_context *cmd,
|
||||
|
@ -2122,10 +2122,13 @@ struct logical_volume *find_lv(const struct volume_group *vg,
|
||||
|
||||
struct generic_logical_volume *find_historical_glv(const struct volume_group *vg,
|
||||
const char *historical_lv_name,
|
||||
int check_removed_list,
|
||||
struct glv_list **glvl_found)
|
||||
{
|
||||
struct glv_list *glvl;
|
||||
const char *ptr;
|
||||
const struct dm_list *list = check_removed_list ? &vg->removed_historical_lvs
|
||||
: &vg->historical_lvs;
|
||||
|
||||
/* Use last component */
|
||||
if ((ptr = strrchr(historical_lv_name, '/')))
|
||||
@ -2133,7 +2136,7 @@ struct generic_logical_volume *find_historical_glv(const struct volume_group *vg
|
||||
else
|
||||
ptr = historical_lv_name;
|
||||
|
||||
dm_list_iterate_items(glvl, &vg->historical_lvs) {
|
||||
dm_list_iterate_items(glvl, list) {
|
||||
if (!strcmp(glvl->glv->historical->name, ptr)) {
|
||||
if (glvl_found)
|
||||
*glvl_found = glvl;
|
||||
|
@ -67,6 +67,7 @@ struct volume_group *alloc_vg(const char *pool_name, struct cmd_context *cmd,
|
||||
dm_list_init(&vg->historical_lvs);
|
||||
dm_list_init(&vg->tags);
|
||||
dm_list_init(&vg->removed_lvs);
|
||||
dm_list_init(&vg->removed_historical_lvs);
|
||||
dm_list_init(&vg->removed_pvs);
|
||||
|
||||
log_debug_mem("Allocated VG %s at %p.", vg->name, vg);
|
||||
|
@ -141,6 +141,11 @@ struct volume_group {
|
||||
*/
|
||||
struct dm_list removed_lvs;
|
||||
|
||||
/*
|
||||
* List of removed historical logical volumes by historical_glv_remove.
|
||||
*/
|
||||
struct dm_list removed_historical_lvs;
|
||||
|
||||
/*
|
||||
* List of removed physical volumes by pvreduce.
|
||||
* They have to get cleared on vg_commit.
|
||||
|
Loading…
Reference in New Issue
Block a user