mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
lvconvert: enhance external origin conversion
This commit is contained in:
parent
7ae9662b4e
commit
3b9787d4ee
@ -2696,7 +2696,7 @@ static int _lvconvert_to_thin_with_external(struct cmd_context *cmd,
|
|||||||
struct volume_group *vg = lv->vg;
|
struct volume_group *vg = lv->vg;
|
||||||
struct logical_volume *thin_lv;
|
struct logical_volume *thin_lv;
|
||||||
const char *origin_name;
|
const char *origin_name;
|
||||||
|
int lv_was_active;
|
||||||
struct lvcreate_params lvc = {
|
struct lvcreate_params lvc = {
|
||||||
.activate = CHANGE_AEY,
|
.activate = CHANGE_AEY,
|
||||||
.alloc = ALLOC_INHERIT,
|
.alloc = ALLOC_INHERIT,
|
||||||
@ -2709,6 +2709,7 @@ static int _lvconvert_to_thin_with_external(struct cmd_context *cmd,
|
|||||||
.read_ahead = DM_READ_AHEAD_AUTO,
|
.read_ahead = DM_READ_AHEAD_AUTO,
|
||||||
.stripes = 1,
|
.stripes = 1,
|
||||||
.virtual_extents = lv->le_count,
|
.virtual_extents = lv->le_count,
|
||||||
|
.tags = DM_LIST_HEAD_INIT(lvc.tags),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!_raid_split_image_conversion(lv))
|
if (!_raid_split_image_conversion(lv))
|
||||||
@ -2746,14 +2747,23 @@ static int _lvconvert_to_thin_with_external(struct cmd_context *cmd,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
dm_list_init(&lvc.tags);
|
|
||||||
|
|
||||||
if (!thin_pool_supports_external_origin(first_seg(thinpool_lv), lv))
|
if (!thin_pool_supports_external_origin(first_seg(thinpool_lv), lv))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
if (!(lvc.segtype = get_segtype_from_string(cmd, SEG_TYPE_NAME_THIN)))
|
if (!(lvc.segtype = get_segtype_from_string(cmd, SEG_TYPE_NAME_THIN)))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
|
lv_was_active = lv_is_active(lv);
|
||||||
|
|
||||||
|
/* When converted LV is not holding lock, but some other LV keeps it
|
||||||
|
* 'active' i.e. being an external origin for such LV, activate this LV
|
||||||
|
* so the reload of table can properly update device tree. */
|
||||||
|
if (!lv_was_active && (lv != lv_lock_holder(lv)) && !activate_lv(cmd, lv)) {
|
||||||
|
log_error("Failed to activate %s. Conversion cannot proceed.",
|
||||||
|
display_lvname(lv));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* New thin LV needs to be created (all messages sent to pool) In this
|
* New thin LV needs to be created (all messages sent to pool) In this
|
||||||
* case thin volume is created READ-ONLY and also warn about not
|
* case thin volume is created READ-ONLY and also warn about not
|
||||||
@ -2769,28 +2779,42 @@ static int _lvconvert_to_thin_with_external(struct cmd_context *cmd,
|
|||||||
if (!(thin_lv = lv_create_single(vg, &lvc)))
|
if (!(thin_lv = lv_create_single(vg, &lvc)))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Only for converted active thick snapshot origin leave
|
||||||
|
* created thin LV active (locked) so it can be converted to new
|
||||||
|
* read-only 'snapshot-origin' with the consequent update and reload.
|
||||||
|
*
|
||||||
|
* Note: New thin LV is read-only so it can't be written.
|
||||||
|
*/
|
||||||
|
if (!lv_is_origin(lv) || !lv_was_active) {
|
||||||
if (!deactivate_lv(cmd, thin_lv)) {
|
if (!deactivate_lv(cmd, thin_lv)) {
|
||||||
log_error("Aborting. Unable to deactivate new LV. "
|
log_error("Aborting. Failed to deactivate new thin LV. "
|
||||||
"Manual intervention required.");
|
"Manual intervention required.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (!sync_local_dev_names(cmd)) {
|
||||||
|
log_error("Failed to sync local devices before conversion.");
|
||||||
|
goto revert_new_lv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Crashing till this point will leave plain thin volume
|
* Crashing till this point will leave plain thin volume
|
||||||
* which could be easily removed by the user after i.e. power-off
|
* which could be easily removed by the user after i.e. power-off
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!swap_lv_identifiers(cmd, thin_lv, lv)) {
|
if (!swap_lv_identifiers(cmd, thin_lv, lv)) {
|
||||||
stack;
|
log_error("Aborting. Failed to swap identifiers. "
|
||||||
goto revert_new_lv;
|
"Manual intervention required.");
|
||||||
|
return 0; /* runtime corruption */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Preserve read-write status of original LV here */
|
/* Preserve read-write status of original LV here */
|
||||||
thin_lv->status |= (lv->status & LVM_WRITE);
|
thin_lv->status |= (lv->status & LVM_WRITE);
|
||||||
|
|
||||||
if (!attach_thin_external_origin(first_seg(thin_lv), lv)) {
|
if (!attach_thin_external_origin(first_seg(thin_lv), lv)) {
|
||||||
stack;
|
log_error("Aborting. Failed to attach external origin. "
|
||||||
goto revert_new_lv;
|
"Manual intervention required.");
|
||||||
|
return 0; /* runtime corruption */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!lv_update_and_reload(thin_lv)) {
|
if (!lv_update_and_reload(thin_lv)) {
|
||||||
@ -2801,21 +2825,27 @@ static int _lvconvert_to_thin_with_external(struct cmd_context *cmd,
|
|||||||
log_print_unless_silent("Converted %s to thin volume with external origin %s.",
|
log_print_unless_silent("Converted %s to thin volume with external origin %s.",
|
||||||
display_lvname(thin_lv), display_lvname(lv));
|
display_lvname(thin_lv), display_lvname(lv));
|
||||||
|
|
||||||
return 1;
|
/* Restore previous state */
|
||||||
|
if (!lv_was_active && !deactivate_lv(cmd, thin_lv)) {
|
||||||
deactivate_and_revert_new_lv:
|
log_error("Failed to deactivate thin LV %s.", display_lvname(thin_lv));
|
||||||
if (!swap_lv_identifiers(cmd, thin_lv, lv))
|
|
||||||
stack;
|
|
||||||
|
|
||||||
if (!deactivate_lv(cmd, thin_lv)) {
|
|
||||||
log_error("Unable to deactivate failed new LV. "
|
|
||||||
"Manual intervention required.");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
deactivate_and_revert_new_lv:
|
||||||
if (!detach_thin_external_origin(first_seg(thin_lv)))
|
if (!detach_thin_external_origin(first_seg(thin_lv)))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
|
if (!swap_lv_identifiers(cmd, thin_lv, lv))
|
||||||
|
return_0;
|
||||||
|
|
||||||
|
if (!deactivate_lv(cmd, thin_lv)) {
|
||||||
|
log_error("Failed to deactivate thin LV. "
|
||||||
|
"Manual intervention required.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
revert_new_lv:
|
revert_new_lv:
|
||||||
/* FIXME Better to revert to backup of metadata? */
|
/* FIXME Better to revert to backup of metadata? */
|
||||||
if (!lv_remove(thin_lv) || !vg_write(vg) || !vg_commit(vg))
|
if (!lv_remove(thin_lv) || !vg_write(vg) || !vg_commit(vg))
|
||||||
|
Loading…
Reference in New Issue
Block a user