mirror of
git://sourceware.org/git/lvm2.git
synced 2025-01-11 09:18:25 +03:00
Add ability to merge back a RAID1 image that has been split w/ --trackchanges
Argument layout is very similar to the merge command for snapshots.
This commit is contained in:
parent
4fad401cd2
commit
b87604e649
@ -1,5 +1,6 @@
|
|||||||
Version 2.02.88 -
|
Version 2.02.88 -
|
||||||
==================================
|
==================================
|
||||||
|
Add --merge support for RAID1 images that were split with --trackchanges
|
||||||
Add support for m-way to n-way up-convert in RAID1 (no linear to n-way yet)
|
Add support for m-way to n-way up-convert in RAID1 (no linear to n-way yet)
|
||||||
Add --trackchanges support to --splitmirrors option for RAID1
|
Add --trackchanges support to --splitmirrors option for RAID1
|
||||||
Add --splitmirrors support for RAID1 (1 image only)
|
Add --splitmirrors support for RAID1 (1 image only)
|
||||||
|
@ -746,6 +746,7 @@ int lv_raid_split(struct logical_volume *lv, const char *split_name,
|
|||||||
uint32_t new_count, struct dm_list *splittable_pvs);
|
uint32_t new_count, struct dm_list *splittable_pvs);
|
||||||
int lv_raid_split_and_track(struct logical_volume *lv,
|
int lv_raid_split_and_track(struct logical_volume *lv,
|
||||||
struct dm_list *splittable_pvs);
|
struct dm_list *splittable_pvs);
|
||||||
|
int lv_raid_merge(struct logical_volume *lv);
|
||||||
|
|
||||||
/* -- metadata/raid_manip.c */
|
/* -- metadata/raid_manip.c */
|
||||||
|
|
||||||
|
@ -1016,3 +1016,89 @@ int lv_raid_split_and_track(struct logical_volume *lv,
|
|||||||
lv->vg->name, seg_lv(seg, s)->name, lv->name);
|
lv->vg->name, seg_lv(seg, s)->name, lv->name);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int lv_raid_merge(struct logical_volume *image_lv)
|
||||||
|
{
|
||||||
|
uint32_t s;
|
||||||
|
char *p, *lv_name;
|
||||||
|
struct lv_list *lvl;
|
||||||
|
struct logical_volume *lv;
|
||||||
|
struct logical_volume *meta_lv = NULL;
|
||||||
|
struct lv_segment *seg;
|
||||||
|
struct volume_group *vg = image_lv->vg;
|
||||||
|
|
||||||
|
lv_name = dm_pool_strdup(vg->vgmem, image_lv->name);
|
||||||
|
if (!lv_name)
|
||||||
|
return_0;
|
||||||
|
|
||||||
|
if (!(p = strstr(lv_name, "_rimage_"))) {
|
||||||
|
log_error("Unable to merge non-mirror image %s/%s",
|
||||||
|
vg->name, image_lv->name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
*p = '\0'; /* lv_name is now that of top-level RAID */
|
||||||
|
|
||||||
|
if (image_lv->status & LVM_WRITE) {
|
||||||
|
log_error("%s/%s is not read-only - refusing to merge",
|
||||||
|
vg->name, image_lv->name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(lvl = find_lv_in_vg(vg, lv_name))) {
|
||||||
|
log_error("Unable to find containing RAID array for %s/%s",
|
||||||
|
vg->name, image_lv->name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
lv = lvl->lv;
|
||||||
|
seg = first_seg(lv);
|
||||||
|
for (s = 0; s < seg->area_count; s++) {
|
||||||
|
if (seg_lv(seg, s) == image_lv) {
|
||||||
|
meta_lv = seg_metalv(seg, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!meta_lv)
|
||||||
|
return_0;
|
||||||
|
|
||||||
|
if (!deactivate_lv(vg->cmd, meta_lv)) {
|
||||||
|
log_error("Failed to deactivate %s", meta_lv->name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!deactivate_lv(vg->cmd, image_lv)) {
|
||||||
|
log_error("Failed to deactivate %s/%s before merging",
|
||||||
|
vg->name, image_lv->name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
lv_set_hidden(image_lv);
|
||||||
|
image_lv->status |= (lv->status & LVM_WRITE);
|
||||||
|
image_lv->status |= RAID_IMAGE;
|
||||||
|
|
||||||
|
if (!vg_write(vg)) {
|
||||||
|
log_error("Failed to write changes to %s in %s",
|
||||||
|
lv->name, vg->name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!suspend_lv(vg->cmd, lv)) {
|
||||||
|
log_error("Failed to suspend %s/%s before committing changes",
|
||||||
|
vg->name, lv->name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!vg_commit(vg)) {
|
||||||
|
log_error("Failed to commit changes to %s in %s",
|
||||||
|
lv->name, vg->name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!resume_lv(vg->cmd, lv)) {
|
||||||
|
log_error("Failed to resume %s/%s after committing changes",
|
||||||
|
vg->name, lv->name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_print("%s/%s successfully merged back into %s/%s",
|
||||||
|
vg->name, image_lv->name,
|
||||||
|
vg->name, lv->name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
@ -1639,9 +1639,10 @@ static struct dm_ioctl *_do_dm_ioctl(struct dm_task *dmt, unsigned command,
|
|||||||
_cmd_data_v4[dmt->type].name,
|
_cmd_data_v4[dmt->type].name,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
else
|
else
|
||||||
log_error("device-mapper: %s ioctl "
|
log_error("device-mapper: %s ioctl for %s "
|
||||||
"failed: %s",
|
"failed: %s",
|
||||||
_cmd_data_v4[dmt->type].name,
|
_cmd_data_v4[dmt->type].name,
|
||||||
|
dmi->name ? dmi->name : dmi->uuid,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
_dm_zfree_dmi(dmi);
|
_dm_zfree_dmi(dmi);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -40,7 +40,7 @@ OriginalLogicalVolume[Path] SnapshotLogicalVolume[Path]
|
|||||||
[\-h|\-?|\-\-help]
|
[\-h|\-?|\-\-help]
|
||||||
[\-v|\-\-verbose]
|
[\-v|\-\-verbose]
|
||||||
[\-\-version]
|
[\-\-version]
|
||||||
SnapshotLogicalVolume[Path]...
|
LogicalVolume[Path]...
|
||||||
.br
|
.br
|
||||||
|
|
||||||
.br
|
.br
|
||||||
@ -146,8 +146,11 @@ Controls zeroing of the first KB of data in the snapshot.
|
|||||||
If the volume is read-only the snapshot will not be zeroed.
|
If the volume is read-only the snapshot will not be zeroed.
|
||||||
.TP
|
.TP
|
||||||
.I \-\-merge
|
.I \-\-merge
|
||||||
Merges a snapshot into its origin volume. To check if your kernel
|
Merges a snapshot into its origin volume or merges a RAID1 image that has
|
||||||
supports this feature, look for 'snapshot-merge' in the output
|
been split from its mirror with \-\-trackchanges back into its mirror.
|
||||||
|
|
||||||
|
To check if your kernel supports the snapshot merge feature, look
|
||||||
|
for 'snapshot-merge' in the output
|
||||||
of 'dmsetup targets'. If both the origin and snapshot volume are not
|
of 'dmsetup targets'. If both the origin and snapshot volume are not
|
||||||
open the merge will start immediately. Otherwise, the merge will start
|
open the merge will start immediately. Otherwise, the merge will start
|
||||||
the first time either the origin or snapshot are activated and both are closed.
|
the first time either the origin or snapshot are activated and both are closed.
|
||||||
@ -206,7 +209,7 @@ converts linear logical volume "vg00/lvol1" to a two-way mirror, using physical
|
|||||||
extents /dev/sda:0-15 and /dev/sdb:0-15 for allocation of new extents.
|
extents /dev/sda:0-15 and /dev/sdb:0-15 for allocation of new extents.
|
||||||
|
|
||||||
.br
|
.br
|
||||||
"lvconvert -m0 vg00/lvmirror1 /dev/sda
|
"lvconvert -m0 vg00/lvmirror1 /dev/sda"
|
||||||
.br
|
.br
|
||||||
converts mirror logical volume "vg00/lvmirror1" to linear, freeing physical
|
converts mirror logical volume "vg00/lvmirror1" to linear, freeing physical
|
||||||
extents from /dev/sda.
|
extents from /dev/sda.
|
||||||
@ -224,6 +227,32 @@ each snapshot logical volume will be merged serially, e.g.: vg00/lvol1,
|
|||||||
then vg00/lvol2, then vg00/lvol3. If --background were used it would start
|
then vg00/lvol2, then vg00/lvol3. If --background were used it would start
|
||||||
all snapshot logical volume merges in parallel.
|
all snapshot logical volume merges in parallel.
|
||||||
|
|
||||||
|
.br
|
||||||
|
"lvconvert --splitmirrors 1 --name lv_split vg00/lvmirror1"
|
||||||
|
.br
|
||||||
|
Extract one image from the mirror, making it a new logical volume named
|
||||||
|
"lv_split". The mirror the image is extracted from is reduced accordingly.
|
||||||
|
If it was a 2-way mirror (created with '-m 1'), then the resulting original
|
||||||
|
volume will be linear.
|
||||||
|
|
||||||
|
.br
|
||||||
|
"lvconvert --splitmirrors 1 --trackchanges vg00/lv_raid1"
|
||||||
|
.br
|
||||||
|
A mirrored logical volume that uses the "raid1" segment type (i.e. created
|
||||||
|
with '--type raid1') can use the '\-\-trackchanges' argument when splitting
|
||||||
|
off an image. The split-off image cannot be given a new name, as it is still
|
||||||
|
part of the original RAID1 logical volume in the sense that changes between
|
||||||
|
the two are being tracked for future integration upon merging. The device that
|
||||||
|
results from the split will be read-only and will be named similarly to the
|
||||||
|
original - in this case "lv_raid1_rimage_N", where 'N' is the index of the
|
||||||
|
image that has been split.
|
||||||
|
|
||||||
|
.br
|
||||||
|
"lvconvert --merge vg00/lv_raid1_rimage_1"
|
||||||
|
.br
|
||||||
|
Merge an image back into the mirror it was split from when the '\-\-trackchanges'
|
||||||
|
argument was used.
|
||||||
|
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
.BR lvm (8),
|
.BR lvm (8),
|
||||||
.BR vgcreate (8),
|
.BR vgcreate (8),
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
struct lvconvert_params {
|
struct lvconvert_params {
|
||||||
int snapshot;
|
int snapshot;
|
||||||
int merge;
|
int merge;
|
||||||
|
int merge_mirror;
|
||||||
int zero;
|
int zero;
|
||||||
|
|
||||||
const char *origin;
|
const char *origin;
|
||||||
@ -107,7 +108,7 @@ static int _lvconvert_name_params(struct lvconvert_params *lp,
|
|||||||
if ((ptr = strrchr(lp->lv_name_full, '/')))
|
if ((ptr = strrchr(lp->lv_name_full, '/')))
|
||||||
lp->lv_name = ptr + 1;
|
lp->lv_name = ptr + 1;
|
||||||
|
|
||||||
if (!apply_lvname_restrictions(lp->lv_name))
|
if (!lp->merge_mirror && !apply_lvname_restrictions(lp->lv_name))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
if (*pargc && lp->snapshot) {
|
if (*pargc && lp->snapshot) {
|
||||||
@ -178,8 +179,12 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arg_count(cmd, merge_ARG))
|
if (arg_count(cmd, merge_ARG)) {
|
||||||
|
if ((argc == 1) && strstr(argv[0], "_rimage_"))
|
||||||
|
lp->merge_mirror = 1;
|
||||||
|
else
|
||||||
lp->merge = 1;
|
lp->merge = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (arg_count(cmd, mirrors_ARG)) {
|
if (arg_count(cmd, mirrors_ARG)) {
|
||||||
/*
|
/*
|
||||||
@ -1339,6 +1344,12 @@ static int _lvconvert_mirrors(struct cmd_context *cmd,
|
|||||||
uint32_t new_mimage_count;
|
uint32_t new_mimage_count;
|
||||||
uint32_t new_log_count;
|
uint32_t new_log_count;
|
||||||
|
|
||||||
|
if (lp->merge_mirror) {
|
||||||
|
log_error("Unable to merge mirror images"
|
||||||
|
"of segment type 'mirror'");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Adjust mimage and/or log count */
|
/* Adjust mimage and/or log count */
|
||||||
if (!_lvconvert_mirrors_parse_params(cmd, lv, lp,
|
if (!_lvconvert_mirrors_parse_params(cmd, lv, lp,
|
||||||
&old_mimage_count, &old_log_count,
|
&old_mimage_count, &old_log_count,
|
||||||
@ -1423,16 +1434,20 @@ static int lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *lp
|
|||||||
"split" : "reduce");
|
"split" : "reduce");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lp->merge_mirror)
|
||||||
|
return lv_raid_merge(lv);
|
||||||
|
|
||||||
if (arg_count(cmd, trackchanges_ARG))
|
if (arg_count(cmd, trackchanges_ARG))
|
||||||
return lv_raid_split_and_track(lv, lp->pvh);
|
return lv_raid_split_and_track(lv, lp->pvh);
|
||||||
else if (arg_count(cmd, splitmirrors_ARG))
|
|
||||||
|
if (arg_count(cmd, splitmirrors_ARG))
|
||||||
return lv_raid_split(lv, lp->lv_split_name,
|
return lv_raid_split(lv, lp->lv_split_name,
|
||||||
image_count, lp->pvh);
|
image_count, lp->pvh);
|
||||||
else
|
|
||||||
return lv_raid_change_image_count(lv, image_count,
|
if (arg_count(cmd, mirrors_ARG))
|
||||||
lp->pvh);
|
return lv_raid_change_image_count(lv, image_count, lp->pvh);
|
||||||
}
|
|
||||||
|
|
||||||
log_error("Conversion operation not yet supported.");
|
log_error("Conversion operation not yet supported.");
|
||||||
return 0;
|
return 0;
|
||||||
@ -1652,7 +1667,8 @@ static int _lvconvert_single(struct cmd_context *cmd, struct logical_volume *lv,
|
|||||||
stack;
|
stack;
|
||||||
return ECMD_FAILED;
|
return ECMD_FAILED;
|
||||||
}
|
}
|
||||||
} else if (segtype_is_raid(lp->segtype) || (lv->status & RAID)) {
|
} else if (segtype_is_raid(lp->segtype) ||
|
||||||
|
(lv->status & RAID) || lp->merge_mirror) {
|
||||||
if (!archive(lv->vg)) {
|
if (!archive(lv->vg)) {
|
||||||
stack;
|
stack;
|
||||||
return ECMD_FAILED;
|
return ECMD_FAILED;
|
||||||
|
Loading…
Reference in New Issue
Block a user