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

[lvm-devel] [PATCH pvmove 4/6] Change pvmove to use the generalized APIs



This patch changes pvmove to use the generic APIs added in
the previous patches.

Thanks,
-- 
Jun'ichi Nomura, NEC Corporation of America
Change pvmove to use the new generalized APIs for layer insertion and
mirror conversion.

Index: LVM2.work/lib/metadata/lv_manip.c
===================================================================
--- LVM2.work.orig/lib/metadata/lv_manip.c
+++ LVM2.work/lib/metadata/lv_manip.c
@@ -1501,7 +1501,8 @@ int lv_extend(struct logical_volume *lv,
 	      const struct segment_type *segtype,
 	      uint32_t stripes, uint32_t stripe_size,
 	      uint32_t mirrors, uint32_t extents,
-	      struct physical_volume *mirrored_pv, uint32_t mirrored_pe,
+	      struct physical_volume *mirrored_pv __attribute((unused)),
+	      uint32_t mirrored_pe __attribute((unused)),
 	      uint32_t status, struct list *allocatable_pvs,
 	      alloc_policy_t alloc)
 {
@@ -1514,10 +1515,6 @@ int lv_extend(struct logical_volume *lv,
 	if (segtype_is_virtual(segtype))
 		return lv_add_virtual_segment(lv, status, extents, segtype);
 
-	/* FIXME Temporary restriction during code reorganisation */
-	if (mirrored_pv)
-		can_split = 0;
-
 	if (!(ah = allocate_extents(lv->vg, lv, segtype, stripes, mirrors, 0,
 				    extents, allocatable_pvs, alloc, can_split,
 				    NULL)))
@@ -1525,7 +1522,7 @@ int lv_extend(struct logical_volume *lv,
 
 	if (mirrors < 2) {
 		if (!lv_add_segment(ah, 0, ah->area_count, lv, segtype, stripe_size,
-			    mirrored_pv, mirrored_pe, status, 0, NULL)) {
+			    NULL, 0, status, 0, NULL)) {
 			stack;
 			goto out;
 		}
Index: LVM2.work/lib/metadata/metadata-exported.h
===================================================================
--- LVM2.work.orig/lib/metadata/metadata-exported.h
+++ LVM2.work/lib/metadata/metadata-exported.h
@@ -455,13 +455,6 @@ int remove_mirror_images(struct lv_segme
 int reconfigure_mirror_images(struct lv_segment *mirrored_seg, uint32_t num_mirrors,
 			      struct list *removable_pvs, unsigned remove_log);
 
-int insert_pvmove_mirrors(struct cmd_context *cmd,
-			  struct logical_volume *lv_mirr,
-			  struct list *source_pvl,
-			  struct logical_volume *lv,
-			  struct list *allocatable_pvs,
-			  alloc_policy_t alloc,
-			  struct list *lvs_changed);
 int remove_pvmove_mirrors(struct volume_group *vg,
 			  struct logical_volume *lv_mirr);
 struct logical_volume *find_pvmove_lv(struct volume_group *vg,
Index: LVM2.work/lib/metadata/mirror.c
===================================================================
--- LVM2.work.orig/lib/metadata/mirror.c
+++ LVM2.work/lib/metadata/mirror.c
@@ -532,37 +532,6 @@ int add_mirror_layers(struct alloc_handl
 	return lv_add_more_mirrored_areas(lv, img_lvs, num_mirrors, 0);
 }
 
-static int _alloc_and_insert_pvmove_seg(struct logical_volume *lv_mirr,
-					struct lv_segment *seg, uint32_t s,
-					struct list *allocatable_pvs,
-					alloc_policy_t alloc,
-					const struct segment_type *segtype)
-{
-	struct physical_volume *pv = seg_pv(seg, s);
-	uint32_t start_le = lv_mirr->le_count;
-	uint32_t pe = seg_pe(seg, s);
-
-	log_very_verbose("Moving %s:%u-%u of %s/%s", pv_dev_name(pv),
-			 pe, pe + seg->area_len - 1,
-			 seg->lv->vg->name, seg->lv->name);
-
-	release_lv_segment_area(seg, s, seg->area_len);
-
-	if (!lv_extend(lv_mirr, segtype, 1,
-	       	seg->area_len, 0u, seg->area_len,
-	       	pv, pe,
-	       	PVMOVE, allocatable_pvs,
-	       	alloc)) {
-		log_error("Unable to allocate "
-			  "temporary LV for pvmove.");
-		return 0;
-	}
-
-	set_lv_segment_area_lv(seg, s, lv_mirr, start_le, 0);
-
-	return 1;
-}
-
 static int _split_parent_segment(struct logical_volume *layer_lv,
 				 struct lv_segment *seg, uint32_t s)
 {
@@ -632,140 +601,6 @@ int split_parent_segments(struct logical
 	return 1;
 }
 
-/* 
- * Replace any LV segments on given PV with temporary mirror.
- * Returns list of LVs changed.
- */
-int insert_pvmove_mirrors(struct cmd_context *cmd,
-			  struct logical_volume *lv_mirr,
-			  struct list *source_pvl,
-			  struct logical_volume *lv,
-			  struct list *allocatable_pvs,
-			  alloc_policy_t alloc,
-			  struct list *lvs_changed)
-{
-	struct lv_segment *seg;
-	struct lv_list *lvl;
-	struct pv_list *pvl;
-	int lv_used = 0;
-	uint32_t s, extent_count = 0u;
-	const struct segment_type *segtype;
-	struct pe_range *per;
-	uint32_t pe_start, pe_end, per_end, stripe_multiplier;
-
-	/* Only 1 PV may feature in source_pvl */
-	pvl = list_item(source_pvl->n, struct pv_list);
-
-	if (!(segtype = get_segtype_from_string(lv->vg->cmd, "mirror"))) {
-		stack;
-		return 0;
-	}
-
-        if (activation() && segtype->ops->target_present &&
-            !segtype->ops->target_present(NULL)) {
-                log_error("%s: Required device-mapper target(s) not "
-                          "detected in your kernel", segtype->name);
-                return 0;
-        }
-
-	/* Split LV segments to match PE ranges */
-	list_iterate_items(seg, &lv->segments) {
-		for (s = 0; s < seg->area_count; s++) {
-			if (seg_type(seg, s) != AREA_PV ||
-			    seg_dev(seg, s) != pvl->pv->dev)
-				continue;
-
-			/* Do these PEs need moving? */
-			list_iterate_items(per, pvl->pe_ranges) {
-				pe_start = seg_pe(seg, s);
-				pe_end = pe_start + seg->area_len - 1;
-				per_end = per->start + per->count - 1;
-
-				/* No overlap? */
-				if ((pe_end < per->start) ||
-				    (pe_start > per_end))
-					continue;
-
-				if (seg_is_striped(seg))
-					stripe_multiplier = seg->area_count;
-				else
-					stripe_multiplier = 1;
-
-				if ((per->start != pe_start &&
-				     per->start > pe_start) &&
-				    !lv_split_segment(lv, seg->le +
-						      (per->start - pe_start) *
-						      stripe_multiplier)) {
-					stack;
-					return 0;
-				}
-
-				if ((per_end != pe_end &&
-				     per_end < pe_end) &&
-				    !lv_split_segment(lv, seg->le +
-						      (per_end - pe_start + 1) *
-						      stripe_multiplier)) {
-					stack;
-					return 0;
-				}
-			}
-		}
-	}
-
-	/* Work through all segments on the supplied PV */
-	list_iterate_items(seg, &lv->segments) {
-		for (s = 0; s < seg->area_count; s++) {
-			if (seg_type(seg, s) != AREA_PV ||
-			    seg_dev(seg, s) != pvl->pv->dev)
-				continue;
-
-			pe_start = seg_pe(seg, s);
-
-			/* Do these PEs need moving? */
-			list_iterate_items(per, pvl->pe_ranges) {
-				per_end = per->start + per->count - 1;
-
-				if ((pe_start < per->start) ||
-				    (pe_start > per_end))
-					continue;
-
-				log_debug("Matched PE range %u-%u against "
-					  "%s %u len %u", per->start, per_end,
-					  dev_name(seg_dev(seg, s)),
-					  seg_pe(seg, s),
-					  seg->area_len);
-
-				/* First time, add LV to list of LVs affected */
-				if (!lv_used) {
-					if (!(lvl = dm_pool_alloc(cmd->mem, sizeof(*lvl)))) {
-						log_error("lv_list alloc failed");
-						return 0;
-					}
-					lvl->lv = lv;
-					list_add(lvs_changed, &lvl->list);
-					lv_used = 1;
-				}
-	
-				if (!_alloc_and_insert_pvmove_seg(lv_mirr, seg, s,
-								  allocatable_pvs,
-								  alloc, segtype))
-					return_0;
-
-				extent_count += seg->area_len;
-	
-				lv->status |= LOCKED;
-
-				break;
-			}
-		}
-	}
-
-	log_verbose("Moving %u extents of logical volume %s/%s", extent_count,
-		    lv->vg->name, lv->name);
-
-	return 1;
-}
-
 /* Remove a temporary mirror */
 int remove_pvmove_mirrors(struct volume_group *vg,
 			  struct logical_volume *lv_mirr)
Index: LVM2.work/tools/pvmove.c
===================================================================
--- LVM2.work.orig/tools/pvmove.c
+++ LVM2.work/tools/pvmove.c
@@ -106,6 +106,40 @@ static struct list *_get_allocatable_pvs
 	return allocatable_pvs;
 }
 
+/*
+ * Replace any LV segments on given PV with temporary mirror.
+ * Returns list of LVs changed.
+ */
+static int _insert_pvmove_mirrors(struct cmd_context *cmd,
+				  struct logical_volume *lv_mirr,
+				  struct list *source_pvl,
+				  struct logical_volume *lv,
+				  struct list *lvs_changed)
+
+{
+	struct pv_list *pvl;
+	uint32_t prev_le_count;
+
+	/* Only 1 PV may feature in source_pvl */
+	pvl = list_item(source_pvl->n, struct pv_list);
+
+	prev_le_count = lv_mirr->le_count;
+	if (!insert_layer_for_segments_on_pv(cmd, lv, lv_mirr, PVMOVE,
+					     pvl, lvs_changed))
+		return_0;
+
+	/* check if layer was inserted */
+	if (lv_mirr->le_count - prev_le_count) {
+		lv->status |= LOCKED;
+
+		log_verbose("Moving %u extents of logical volume %s/%s",
+			    lv_mirr->le_count - prev_le_count,
+			    lv->vg->name, lv->name);
+	}
+
+	return 1;
+}
+
 /* Create new LV with mirror segments for the required copies */
 static struct logical_volume *_set_up_pvmove_lv(struct cmd_context *cmd,
 						struct volume_group *vg,
@@ -166,9 +200,8 @@ static struct logical_volume *_set_up_pv
 		// insert_layer_for_segments_on_pv(cmd, lv, source_pvl, lv_mirr, *lvs_changed)
 		//   - for each lv segment using that pv
 		//     - call new fn insert_internal_layer()
-		if (!insert_pvmove_mirrors(cmd, lv_mirr, source_pvl, lv,
-					   allocatable_pvs, alloc,
-					   *lvs_changed)) {
+		if (!_insert_pvmove_mirrors(cmd, lv_mirr, source_pvl, lv,
+					    *lvs_changed)) {
 			stack;
 			return NULL;
 		}
@@ -184,6 +217,17 @@ static struct logical_volume *_set_up_pv
 	// again, this knows nothing about pvmove: it's a normal lvconvert lv_mirr to mirror with in-core log
 	// - a flag passed in requires that parent segs get split after the allocation (with failure if not possible)
 
+	if (!convert_segments_mirrored(cmd, lv_mirr, 1, 0,
+				       allocatable_pvs, alloc)) {
+		log_error("Failed to convert pvmove LV to mirrored");
+		return_NULL;
+	}
+
+	if (!split_parent_segments(lv_mirr)) {
+		log_error("Failed to split segments being moved");
+		return_NULL;
+	}
+
 	return lv_mirr;
 }
 
@@ -488,6 +532,17 @@ int pvmove(struct cmd_context *cmd, int 
 	char *pv_name = NULL;
 	char *colon;
 	int ret;
+	const struct segment_type *segtype;
+
+	if (!(segtype = get_segtype_from_string(cmd, "mirror")))
+		return_0;
+
+        if (activation() && segtype->ops->target_present &&
+            !segtype->ops->target_present(NULL)) {
+                log_error("%s: Required device-mapper target(s) not "
+                          "detected in your kernel", segtype->name);
+                return 0;
+        }
 
 	if (argc) {
 		pv_name = argv[0];

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