1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-01-03 05:18:29 +03:00

snapshot: move code of old snapshot merge

Move code for merging old snapshot into its own function.
This commit is contained in:
Zdenek Kabelac 2013-11-26 12:09:41 +01:00
parent b3679590df
commit 8724c0fceb

View File

@ -1884,31 +1884,59 @@ static int lvconvert_snapshot(struct cmd_context *cmd,
return 1;
}
static int lvconvert_merge(struct cmd_context *cmd,
struct logical_volume *lv,
struct lvconvert_params *lp)
static int _lvconvert_merge_old_snapshot(struct cmd_context *cmd,
struct logical_volume *lv,
struct lvconvert_params *lp)
{
int r = 0;
int merge_on_activate = 0;
struct logical_volume *origin = origin_from_cow(lv);
struct lv_segment *snap_seg = find_snapshot(lv);
struct lvinfo info;
percent_t snap_percent;
/* Check if merge is possible */
if (lv_is_merging_cow(lv)) {
log_error("Snapshot %s is already merging", lv->name);
if (!lv_is_cow(lv)) {
log_error("\"%s\" is not a mergeable logical volume.",
lv->name);
return 0;
}
if (lv_is_merging_cow(lv)) {
log_error("Snapshot %s is already merging.", lv->name);
return 0;
}
if (lv_is_merging_origin(origin)) {
log_error("Snapshot %s is already merging into the origin.",
find_snapshot(origin)->cow->name);
return 0;
}
if (lv_is_virtual_origin(origin)) {
log_error("Snapshot %s has virtual origin.", lv->name);
return 0;
}
if (lv_is_external_origin(origin_from_cow(lv))) {
log_error("Cannot merge snapshot \"%s\" into "
"the read-only external origin \"%s\".",
lv->name, origin_from_cow(lv)->name);
return 0;
}
if (lv_info(lv->vg->cmd, lv, 0, &info, 1, 0)
&& info.exists && info.live_table &&
(!lv_snapshot_percent(lv, &snap_percent) ||
snap_percent == PERCENT_INVALID)) {
log_error("Unable to merge invalidated snapshot LV \"%s\".",
lv->name);
return 0;
}
if (!archive(lv->vg))
return_0;
/*
* Prevent merge with open device(s) as it would likely lead
* to application/filesystem failure. Merge on origin's next
@ -1955,7 +1983,7 @@ static int lvconvert_merge(struct cmd_context *cmd,
/* Perform merge */
if (!suspend_lv(cmd, origin)) {
log_error("Failed to suspend origin %s", origin->name);
log_error("Failed to suspend origin %s.", origin->name);
vg_revert(lv->vg);
goto out;
}
@ -1967,7 +1995,7 @@ static int lvconvert_merge(struct cmd_context *cmd,
}
if (!resume_lv(cmd, origin)) {
log_error("Failed to reactivate origin %s", origin->name);
log_error("Failed to reactivate origin %s.", origin->name);
goto out;
}
@ -1978,6 +2006,7 @@ static int lvconvert_merge(struct cmd_context *cmd,
log_print_unless_silent("Merging of volume %s started.", lv->name);
out:
backup(lv->vg);
return r;
}
@ -2588,8 +2617,6 @@ static int _lvconvert_single(struct cmd_context *cmd, struct logical_volume *lv,
{
struct lvconvert_params *lp = handle;
struct dm_list *failed_pvs;
struct lvinfo info;
percent_t snap_percent;
if (lv->status & LOCKED) {
log_error("Cannot convert locked LV %s", lv->name);
@ -2634,29 +2661,8 @@ static int _lvconvert_single(struct cmd_context *cmd, struct logical_volume *lv,
}
}
if (lp->merge) {
if (!lv_is_cow(lv)) {
log_error("\"%s\" is not a mergeable logical volume",
lv->name);
return ECMD_FAILED;
}
if (lv_is_external_origin(origin_from_cow(lv))) {
log_error("Cannot merge snapshot \"%s\" into "
"the read-only external origin \"%s\".",
lv->name, origin_from_cow(lv)->name);
return ECMD_FAILED;
}
if (lv_info(lv->vg->cmd, lv, 0, &info, 1, 0)
&& info.exists && info.live_table &&
(!lv_snapshot_percent(lv, &snap_percent) ||
snap_percent == PERCENT_INVALID)) {
log_error("Unable to merge invalidated snapshot LV \"%s\"", lv->name);
return ECMD_FAILED;
}
if (!archive(lv->vg))
return_ECMD_FAILED;
if (!lvconvert_merge(cmd, lv, lp)) {
log_error("Unable to merge LV \"%s\" into its origin.", lv->name);
if (!_lvconvert_merge_old_snapshot(cmd, lv, lp)) {
log_print_unless_silent("Unable to merge LV \"%s\" into its origin.", lv->name);
return ECMD_FAILED;
}
} else if (lp->snapshot) {