[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[lvm-devel] [PATCH mirror 1/13] Enable mirror-addition to lvconvert



This patch allows lvconvert to add mirror to mirrored LV.

If mirrors are added to mirrored LV, a temporary layer will
be inserted for resync new mirrors.
The temporary LV is under the same naming rule with mirror images.

Thanks,
-- 
Jun'ichi Nomura, NEC Corporation of America

Allow lvconvert to add mirror.

  - Even if the LV is already mirrored, create_mirror_layers()
    do the same thing as when the LV is not mirrored.
    That is:
      1. Create (new mirrors + 1) of empty sub LVs with "_mimage_<n>"
      2. Attach allocated extents for each sub LVs, except for the first one.
      3. Move the current top-level LV segments to the first sub LV.
      4. Add mirror segment to mirror those (new mirrors + 1) sub LVs.

FIXME: Can't create multiple mlogs.

Index: LVM2.work/tools/lvconvert.c
===================================================================
--- LVM2.work.orig/tools/lvconvert.c
+++ LVM2.work/tools/lvconvert.c
@@ -227,6 +227,43 @@ static int _read_params(struct lvconvert
 	return 1;
 }
 
+static int _add_mirror(struct cmd_context *cmd,
+		       struct logical_volume *lv,
+		       uint32_t new_mirrors, unsigned corelog,
+		       struct lvconvert_params *lp)
+{
+	struct alloc_handle *ah = NULL;
+	struct logical_volume *log_lv;
+	struct list *parallel_areas;
+
+	if (!(parallel_areas = build_parallel_areas_from_lv(cmd, lv)))
+		return_0;
+
+	if (!(ah = allocate_extents(lv->vg, NULL, lp->segtype, 1,
+				    new_mirrors, corelog ? 0U : 1U,
+				    lv->le_count,
+				    lp->pvh, lp->alloc, parallel_areas)))
+		return_0;
+
+	lp->region_size = adjusted_mirror_region_size(lv->vg->extent_size,
+						      lv->le_count,
+						      lp->region_size);
+
+	log_lv = NULL;
+	if (!corelog &&
+	    !(log_lv = create_mirror_log(cmd, lv->vg, ah, lp->alloc,
+					 lv->name, 0, &lv->tags))) {
+		log_error("Failed to create mirror log.");
+		return 0;
+	}
+
+	if (!create_mirror_layers(ah, 1, new_mirrors + 1, lv,
+				  lp->segtype, 0, lp->region_size, log_lv))
+		return_0;
+
+	return 1;
+}
+
 static int lvconvert_mirrors(struct cmd_context * cmd, struct logical_volume * lv,
 			     struct lvconvert_params *lp)
 {
@@ -332,36 +369,9 @@ static int lvconvert_mirrors(struct cmd_
 			}
 		}
 
-		if (!(parallel_areas = build_parallel_areas_from_lv(cmd, lv)))
+		if (!_add_mirror(cmd, lv, lp->mirrors - 1, corelog, lp))
 			return_0;
 
-		if (!(ah = allocate_extents(lv->vg, NULL, lp->segtype,
-					    1, lp->mirrors - 1,
-					    corelog ? 0U : 1U,
-					    lv->le_count,
-					    lp->pvh,
-					    lp->alloc,
-					    parallel_areas)))
-			return_0;
-
-		lp->region_size = adjusted_mirror_region_size(lv->vg->extent_size,
-							      lv->le_count,
-							      lp->region_size);
-
-		log_lv = NULL;
-		if (!corelog &&
-		    !(log_lv = create_mirror_log(cmd, lv->vg, ah,
-						 lp->alloc,
-						 lv->name, 0, &lv->tags))) {
-			log_error("Failed to create mirror log.");
-			return 0;
-		}
-
-		if (!create_mirror_layers(ah, 1, lp->mirrors, lv,
-					  lp->segtype, 0,
-					  lp->region_size,
-					  log_lv))
-			return_0;
 		goto commit_changes;
 	}
 
@@ -436,14 +446,11 @@ static int lvconvert_mirrors(struct cmd_
 			return 1;
 		}
 	} else if (lp->mirrors > existing_mirrors) {
-		/* FIXME Unless anywhere, remove PV of log_lv
-		 * from allocatable_pvs & allocate
-		 * (mirrors - existing_mirrors) new areas
-		 */
-		/* FIXME Create mirror hierarchy to sync */
-		log_error("Adding mirror images is not "
-			  "supported yet.");
-		return 0;
+		/* FIXME: can't have multiple mlogs. force corelog. */
+		corelog = 1;
+		if (!_add_mirror(cmd, lv, lp->mirrors - existing_mirrors,
+				 corelog, lp))
+			return_0;
 	} else {
 		/* Reduce number of mirrors */
 		if (!remove_mirror_images(seg, lp->mirrors,
Index: LVM2.work/lib/metadata/mirror.c
===================================================================
--- LVM2.work.orig/lib/metadata/mirror.c
+++ LVM2.work/lib/metadata/mirror.c
@@ -487,11 +487,6 @@ int create_mirror_layers(struct alloc_ha
 		return 0;
 	}
 
-	/* Already got the parent mirror segment? */
-	if (lv->status & MIRRORED)
-		return lv_add_more_mirrored_areas(lv, img_lvs, num_mirrors,
-						  MIRROR_IMAGE);
-
 	/* Already got a non-mirrored area to be converted? */
 	if (first_area)
 		_move_lv_segments(img_lvs[0], lv);

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]