]> sourceware.org Git - lvm2.git/commitdiff
Allow mirror images to be resized.
authorAlasdair Kergon <agk@redhat.com>
Fri, 3 Jun 2005 19:48:19 +0000 (19:48 +0000)
committerAlasdair Kergon <agk@redhat.com>
Fri, 3 Jun 2005 19:48:19 +0000 (19:48 +0000)
WHATS_NEW
lib/metadata/lv_manip.c
tools/commands.h
tools/lvcreate.c
tools/lvresize.c

index 264a0b9ad10f27d69385b6962e30382771b98ba4..5c8f49c2fb31ce0b5def2db648e81e756acfdf01 100644 (file)
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
 Version 2.01.11 - 
 ==============================
+  Allow mirror images to be resized.
   Allow mirror images to have more than one segment.
   Centralise restrictions on LV names.
   Always insert an intermediate layer for mirrors.
index 3dab5dc46f314c7b1bc5c0fcc0aa4e5d30bf5a38..4b33cb1bf22877f47d465e90eac95fb52c29e503 100644 (file)
@@ -300,7 +300,7 @@ static struct alloc_handle *_alloc_init(struct pool *mem,
        uint32_t s, area_count;
 
        if (stripes > 1 && mirrors > 1) {
-               log_error("striped mirrors are not supported yet");
+               log_error("Striped mirrors are not supported yet");
                return NULL;
        }
 
@@ -980,7 +980,9 @@ int lv_extend(struct logical_volume *lv,
              alloc_policy_t alloc)
 {
        int r = 1;
+       uint32_t m;
        struct alloc_handle *ah;
+       struct lv_segment *first_seg;
 
        if (segtype_is_virtual(segtype))
                return lv_add_virtual_segment(lv, status, extents, segtype);
@@ -992,10 +994,29 @@ int lv_extend(struct logical_volume *lv,
                return 0;
        }
 
-       if (!lv_add_segment(ah, 0, ah->area_count, lv, segtype, stripe_size,
+       if (!mirrors) {
+               if (!lv_add_segment(ah, 0, ah->area_count, lv, segtype, stripe_size,
                            mirrored_pv, mirrored_pe, status, 0, NULL)) {
-               stack;
-               goto out;
+                       stack;
+                       goto out;
+               }
+       } else {
+               list_iterate_items(first_seg, &lv->segments)
+                       break;
+               for (m = 0; m < mirrors; m++) {
+                       if (!lv_add_segment(ah, m, 1, seg_lv(first_seg, m),
+                                           get_segtype_from_string(lv->vg->cmd,
+                                                                   "striped"),
+                                           0, NULL, 0, 0, 0, NULL)) {
+                               log_error("Aborting. Failed to extend %s.",
+                                         seg_lv(first_seg, m)->name);
+                               return 0;
+                       }
+               }
+               first_seg->area_len += extents;
+               first_seg->len += extents;
+               lv->le_count += extents;
+               lv->size += (uint64_t) extents *lv->vg->extent_size;
        }
 
       out:
index 6b22464948fd7761d5ab497099ad49cbf4249fea..42d591822d3076108273cfecc2d78d946bc04f4f 100644 (file)
@@ -178,6 +178,7 @@ xx(lvextend,
    "\t[-i|--stripes Stripes [-I|--stripesize StripeSize]]\n"
    "\t{-l|--extents [+]LogicalExtentsNumber |\n"
    "\t -L|--size [+]LogicalVolumeSize[kKmMgGtT]}\n"
+   "\t[-m|--mirrors Mirrors]\n"
    "\t[-n|--nofsck]\n"
    "\t[-r|--resizefs]\n"
    "\t[-t|--test]\n"
@@ -186,8 +187,9 @@ xx(lvextend,
    "\t[--version]" "\n"
    "\tLogicalVolume[Path] [ PhysicalVolumePath... ]\n",
 
-   alloc_ARG, autobackup_ARG, extents_ARG, nofsck_ARG, resizefs_ARG,
-   size_ARG, stripes_ARG, stripesize_ARG, test_ARG, type_ARG)
+   alloc_ARG, autobackup_ARG, extents_ARG, mirrors_ARG, nofsck_ARG,
+   resizefs_ARG, size_ARG, stripes_ARG, stripesize_ARG, test_ARG,
+   type_ARG)
 
 xx(lvmchange,
    "With the device mapper, this is obsolete and does nothing.",
index b495060bab5581f35a3a82e3520ed526b4243555..17e2bf68ecffb5c32ca9f8ba3dbadb3e2074ff8e 100644 (file)
@@ -497,6 +497,11 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp)
                return 0;
        }
 
+       if (lp->mirrors && !(vg->fid->fmt->features & FMT_SEGMENTS)) {
+               log_error("Metadata does not support mirroring.");
+               return 0;
+       }
+
        /*
         * Create the pv list.
         */
index ad3c29c000f9f95e4582e1c0254e2d4b6f159417..e2eb15c7a2f62518b7e0783f983d9147d609bc58 100644 (file)
@@ -23,6 +23,7 @@ struct lvresize_params {
 
        uint32_t stripes;
        uint32_t stripe_size;
+       uint32_t mirrors;
 
        struct segment_type *segtype;
 
@@ -119,6 +120,7 @@ static int _lvresize(struct cmd_context *cmd, struct lvresize_params *lp)
        struct lvinfo info;
        uint32_t stripesize_extents = 0;
        uint32_t seg_stripes = 0, seg_stripesize = 0, seg_size = 0;
+       uint32_t seg_mirrors = 0;
        uint32_t extents_used = 0;
        uint32_t size_rest;
        alloc_policy_t alloc;
@@ -161,6 +163,13 @@ static int _lvresize(struct cmd_context *cmd, struct lvresize_params *lp)
                        log_print("Varied striping not supported. Ignoring.");
        }
 
+       if (arg_count(cmd, mirrors_ARG)) {
+               if (vg->fid->fmt->features & FMT_SEGMENTS)
+                       lp->mirrors = arg_uint_value(cmd, mirrors_ARG, 1) + 1;
+               else
+                       log_print("Mirrors not supported. Ignoring.");
+       }
+
        if (arg_count(cmd, stripesize_ARG)) {
                if (arg_sign_value(cmd, stripesize_ARG, 0) == SIGN_MINUS) {
                        log_error("Stripesize may not be negative.");
@@ -171,6 +180,10 @@ static int _lvresize(struct cmd_context *cmd, struct lvresize_params *lp)
                                                             stripesize_ARG, 0);
                else
                        log_print("Varied stripesize not supported. Ignoring.");
+               if (lp->mirrors) {
+                       log_error("Mirrors and striping cannot be combined yet.");
+                       return ECMD_FAILED;
+               }
        }
 
        lv = lvl->lv;
@@ -277,13 +290,34 @@ static int _lvresize(struct cmd_context *cmd, struct lvresize_params *lp)
                }
        }
 
+       /* If extending, find mirrors of last segment */
+       if ((lp->extents > lv->le_count)) {
+               list_iterate_back_items(seg, &lv->segments) {
+                       if (seg_is_mirrored(seg))
+                               seg_mirrors = seg->area_count;
+                       else
+                               seg_mirrors = 0;
+                       break;
+               }
+               if (!arg_count(cmd, mirrors_ARG) && seg_mirrors) {
+                       log_print("Extending %" PRIu32 " mirror images.",
+                                 seg_mirrors);
+                       lp->mirrors = seg_mirrors;
+               }
+               if ((arg_count(cmd, mirrors_ARG) || seg_mirrors) &&
+                   (lp->mirrors != seg_mirrors)) {
+                       log_error("Cannot vary number of mirrors in LV yet.");
+                       return EINVALID_CMD_LINE;
+               }
+       }
+
        /* If reducing, find stripes, stripesize & size of last segment */
        if (lp->extents < lv->le_count) {
                extents_used = 0;
 
-               if (lp->stripes || lp->stripe_size)
-                       log_error("Ignoring stripes and stripesize arguments "
-                                 "when reducing");
+               if (lp->stripes || lp->stripe_size || lp->mirrors)
+                       log_error("Ignoring stripes, stripesize and mirrors "
+                                 "arguments when reducing");
 
                list_iterate_items(seg, &lv->segments) {
                        seg_extents = seg->len;
@@ -293,6 +327,11 @@ static int _lvresize(struct cmd_context *cmd, struct lvresize_params *lp)
                                seg_stripes = seg->area_count;
                        }
 
+                       if (seg_is_mirrored(seg))
+                               seg_mirrors = seg->area_count;
+                       else
+                               seg_mirrors = 0;
+
                        if (lp->extents <= extents_used + seg_extents)
                                break;
 
@@ -302,6 +341,7 @@ static int _lvresize(struct cmd_context *cmd, struct lvresize_params *lp)
                seg_size = lp->extents - extents_used;
                lp->stripe_size = seg_stripesize;
                lp->stripes = seg_stripes;
+               lp->mirrors = seg_mirrors;
        }
 
        if (lp->stripes > 1 && !lp->stripe_size) {
@@ -456,7 +496,7 @@ static int _lvresize(struct cmd_context *cmd, struct lvresize_params *lp)
                        return ECMD_FAILED;
                }
        } else if (!lv_extend(lv, lp->segtype, lp->stripes,
-                             lp->stripe_size, 0u,
+                             lp->stripe_size, lp->mirrors,
                              lp->extents - lv->le_count,
                              NULL, 0u, 0u, pvh, alloc)) {
                stack;
This page took 0.099411 seconds and 5 git commands to generate.