]> sourceware.org Git - lvm2.git/commitdiff
Add ability to merge back a RAID1 image that has been split w/ --trackchanges
authorJonathan Earl Brassow <jbrassow@redhat.com>
Thu, 18 Aug 2011 19:43:08 +0000 (19:43 +0000)
committerJonathan Earl Brassow <jbrassow@redhat.com>
Thu, 18 Aug 2011 19:43:08 +0000 (19:43 +0000)
Argument layout is very similar to the merge command for snapshots.

WHATS_NEW
lib/metadata/metadata-exported.h
lib/metadata/raid_manip.c
libdm/ioctl/libdm-iface.c
man/lvconvert.8.in
tools/lvconvert.c

index 5d8386e60aa9af8497d453da8118ce93348885c2..b145f174727e29e3fbe7f8ef2f70f93faeed2090 100644 (file)
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
 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 --trackchanges support to --splitmirrors option for RAID1
   Add --splitmirrors support for RAID1 (1 image only)
index d058ef691d86179bc0b3897cd1308b4cc0abfc8e..5b3ca63d6dccf02607a8314c46f240c4ba356c0a 100644 (file)
@@ -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);
 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 d9b1ecb6ee714e5399182d6df3a8b065ddbd162d..d0d0591266be7e5d82dbc599b174a5cadbf4edb5 100644 (file)
@@ -1016,3 +1016,89 @@ int lv_raid_split_and_track(struct logical_volume *lv,
                  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 767732a680a8ee813ebfecf47988725635c83651..d74fab463982b63f9e17d3af187e9f17aa7590bd 100644 (file)
@@ -1639,9 +1639,10 @@ static struct dm_ioctl *_do_dm_ioctl(struct dm_task *dmt, unsigned command,
                                            _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;
index 43261dacebc71254df6748c10369be6e968b9982..bd594687ad8f0db68714ed981e7bf4cdab4213c5 100644 (file)
@@ -40,7 +40,7 @@ OriginalLogicalVolume[Path] SnapshotLogicalVolume[Path]
 [\-h|\-?|\-\-help]
 [\-v|\-\-verbose]
 [\-\-version]
-SnapshotLogicalVolume[Path]...
+LogicalVolume[Path]...
 .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.
 .TP
 .I \-\-merge
-Merges a snapshot into its origin volume.  To check if your kernel
-supports this feature, look for 'snapshot-merge' in the output
+Merges a snapshot into its origin volume or merges a RAID1 image that has
+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
 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.
@@ -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.
 
 .br
-"lvconvert -m0 vg00/lvmirror1 /dev/sda
+"lvconvert -m0 vg00/lvmirror1 /dev/sda"
 .br
 converts mirror logical volume "vg00/lvmirror1" to linear, freeing physical
 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
 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
 .BR lvm (8),
 .BR vgcreate (8),
index a3788273967bf43c69dd497bc1b808c571cc20df..443c492e345f7238cd44073949f5d57dc26ebe1b 100644 (file)
@@ -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 lvconvert_params *lp,
        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_params *lp, struct cmd_context *cmd,
                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_context *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_volume *lv, struct lvconvert_params *lp
                                  "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_context *cmd, struct logical_volume *lv,
                        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;
This page took 0.099052 seconds and 5 git commands to generate.