[lvm-devel] [PATCH 5 of 5] LVM RAID: Add ability to merge back LV split from RAID1
Jonathan Brassow
jbrassow at redhat.com
Tue Aug 16 14:20:58 UTC 2011
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.
Index: LVM2/lib/metadata/metadata-exported.h
===================================================================
--- LVM2.orig/lib/metadata/metadata-exported.h
+++ LVM2/lib/metadata/metadata-exported.h
@@ -746,6 +746,7 @@ int lv_raid_split(struct logical_volume
uint32_t new_count, struct dm_list *splittable_pvs);
int lv_raid_split_and_track(struct logical_volume *lv,
struct dm_list *splittable_pvs);
+int lv_raid_merge(struct logical_volume *lv);
/* -- metadata/raid_manip.c */
Index: LVM2/lib/metadata/raid_manip.c
===================================================================
--- LVM2.orig/lib/metadata/raid_manip.c
+++ LVM2/lib/metadata/raid_manip.c
@@ -1016,3 +1016,89 @@ int lv_raid_split_and_track(struct logic
lv->vg->name, seg_lv(seg, s)->name, lv->name);
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;
+}
Index: LVM2/tools/lvconvert.c
===================================================================
--- LVM2.orig/tools/lvconvert.c
+++ LVM2/tools/lvconvert.c
@@ -20,6 +20,7 @@
struct lvconvert_params {
int snapshot;
int merge;
+ int merge_mirror;
int zero;
const char *origin;
@@ -107,7 +108,7 @@ static int _lvconvert_name_params(struct
if ((ptr = strrchr(lp->lv_name_full, '/')))
lp->lv_name = ptr + 1;
- if (!apply_lvname_restrictions(lp->lv_name))
+ if (!lp->merge_mirror && !apply_lvname_restrictions(lp->lv_name))
return_0;
if (*pargc && lp->snapshot) {
@@ -178,8 +179,12 @@ static int _read_params(struct lvconvert
return 0;
}
- if (arg_count(cmd, merge_ARG))
- lp->merge = 1;
+ if (arg_count(cmd, merge_ARG)) {
+ if ((argc == 1) && strstr(argv[0], "_rimage_"))
+ lp->merge_mirror = 1;
+ else
+ lp->merge = 1;
+ }
if (arg_count(cmd, mirrors_ARG)) {
/*
@@ -1339,6 +1344,12 @@ static int _lvconvert_mirrors(struct cmd
uint32_t new_mimage_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 */
if (!_lvconvert_mirrors_parse_params(cmd, lv, lp,
&old_mimage_count, &old_log_count,
@@ -1423,17 +1434,21 @@ static int lvconvert_raid(struct logical
"split" : "reduce");
return 0;
}
-
- if (arg_count(cmd, trackchanges_ARG))
- return lv_raid_split_and_track(lv, lp->pvh);
- else if (arg_count(cmd, splitmirrors_ARG))
- return lv_raid_split(lv, lp->lv_split_name,
- image_count, lp->pvh);
- else
- return lv_raid_change_image_count(lv, image_count,
- lp->pvh);
}
+ if (lp->merge_mirror)
+ return lv_raid_merge(lv);
+
+ if (arg_count(cmd, trackchanges_ARG))
+ return lv_raid_split_and_track(lv, lp->pvh);
+
+ if (arg_count(cmd, splitmirrors_ARG))
+ return lv_raid_split(lv, lp->lv_split_name,
+ image_count, lp->pvh);
+
+ if (arg_count(cmd, mirrors_ARG))
+ return lv_raid_change_image_count(lv, image_count, lp->pvh);
+
log_error("Conversion operation not yet supported.");
return 0;
}
@@ -1652,7 +1667,8 @@ static int _lvconvert_single(struct cmd_
stack;
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)) {
stack;
return ECMD_FAILED;
Index: LVM2/libdm/ioctl/libdm-iface.c
===================================================================
--- LVM2.orig/libdm/ioctl/libdm-iface.c
+++ LVM2/libdm/ioctl/libdm-iface.c
@@ -1639,9 +1639,10 @@ static struct dm_ioctl *_do_dm_ioctl(str
_cmd_data_v4[dmt->type].name,
strerror(errno));
else
- log_error("device-mapper: %s ioctl "
+ log_error("device-mapper: %s ioctl for %s "
"failed: %s",
- _cmd_data_v4[dmt->type].name,
+ _cmd_data_v4[dmt->type].name,
+ dmi->name ? dmi->name : dmi->uuid,
strerror(errno));
_dm_zfree_dmi(dmi);
return NULL;
More information about the lvm-devel
mailing list