All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/6] Thin external origin support
@ 2013-02-05 13:56 Zdenek Kabelac
  2013-02-05 13:56 ` [PATCH 1/6] thin: add support for external origin Zdenek Kabelac
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Zdenek Kabelac @ 2013-02-05 13:56 UTC (permalink / raw)
  To: lvm-devel

Pach set adds support for external origin usage for thin volumes.
Usage might be observed in the 'tests:' patch 6.

I've tried to combine as many usage patterns as I could think of,
but if someone sees still some missing behavior, report please.

Patch set does not provide yet for 'lvcreate -s' usage.

Zdenek Kabelac (6):
  thin: add support for external origin
  thin: external origin cannot be changed
  thin: report external origin
  thin: removal of external origin
  thin: lvconvert support for external origin
  tests: lvconvert external origin

 lib/activate/activate.c               |   6 +-
 lib/activate/dev_manager.c            |  40 ++++++++
 lib/format_text/flags.c               |   3 +-
 lib/metadata/lv.c                     |   9 +-
 lib/metadata/lv_manip.c               |  62 ++++++++----
 lib/metadata/merge.c                  |   7 +-
 lib/metadata/metadata-exported.h      |   5 +-
 lib/metadata/metadata.h               |   5 +-
 lib/metadata/thin_manip.c             |  50 ++++++++++
 lib/report/report.c                   |   3 +
 lib/thin/thin.c                       |  33 ++++++-
 man/lvconvert.8.in                    |  32 +++++++
 test/shell/lvconvert-thin-external.sh |  82 ++++++++++++++++
 tools/args.h                          |   3 +-
 tools/commands.h                      |   7 +-
 tools/lvchange.c                      |   6 ++
 tools/lvconvert.c                     | 173 ++++++++++++++++++++++++++++++++--
 tools/lvresize.c                      |   9 ++
 18 files changed, 497 insertions(+), 38 deletions(-)
 create mode 100644 test/shell/lvconvert-thin-external.sh

-- 
1.8.1.2



^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/6] thin: add support for external origin
  2013-02-05 13:56 [PATCH 0/6] Thin external origin support Zdenek Kabelac
@ 2013-02-05 13:56 ` Zdenek Kabelac
  2013-02-05 13:56 ` [PATCH 2/6] thin: external origin cannot be changed Zdenek Kabelac
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Zdenek Kabelac @ 2013-02-05 13:56 UTC (permalink / raw)
  To: lvm-devel

Add internal support for thin volume's external origin.

Signed-off-by: Zdenek Kabelac <zkabelac@redhat.com>
---
 lib/activate/dev_manager.c       | 40 ++++++++++++++++++++++++++++++++
 lib/format_text/flags.c          |  3 ++-
 lib/metadata/lv.c                |  2 +-
 lib/metadata/lv_manip.c          |  5 +++-
 lib/metadata/merge.c             |  7 +++++-
 lib/metadata/metadata-exported.h |  5 +++-
 lib/metadata/metadata.h          |  5 +++-
 lib/metadata/thin_manip.c        | 50 ++++++++++++++++++++++++++++++++++++++++
 lib/thin/thin.c                  | 33 ++++++++++++++++++++++----
 9 files changed, 140 insertions(+), 10 deletions(-)

diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index e8f449c..db64f26 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -1565,6 +1565,7 @@ static int _add_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
 		return_0;
 
 	/* FIXME Can we avoid doing this every time? */
+	/* Reused also for lv_is_external_origin(lv) */
 	if (!_add_dev_to_dtree(dm, dtree, lv, "real"))
 		return_0;
 
@@ -1605,6 +1606,11 @@ static int _add_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
 				dm_tree_node_skip_children(thin_node, 1);
 #endif
 		} else {
+			/* Add external origin */
+			if (seg->external_lv &&
+			    !_add_dev_to_dtree(dm, dtree, seg->external_lv,
+					       lv_layer(seg->external_lv)))
+				return_0;
 			/* Add thin pool LV layer */
 			lv = seg->pool_lv;
 			seg = first_seg(lv);
@@ -1832,6 +1838,28 @@ int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
 	return 1;
 }
 
+static int _add_external_origin_target_to_dtree(struct dev_manager *dm,
+						struct dm_tree_node *dnode,
+						struct logical_volume *lv)
+{
+	const char *layer_dlid;
+
+	if (!(layer_dlid = build_dm_uuid(dm->mem, lv->lvid.s, lv_layer(lv))))
+		return_0;
+
+	/* Add linear mapping to layered external origin */
+	if (!add_linear_area_to_dtree(dnode,
+				      (uint64_t)lv->vg->extent_size * lv->le_count,
+				      lv->vg->extent_size,
+				      lv->vg->cmd->use_linear_target,
+				      lv->vg->name, lv->name) ||
+	    !dm_tree_node_add_target_area(dnode, NULL, layer_dlid, 0))
+		return_0;
+
+	return 1;
+}
+
+
 static int _add_origin_target_to_dtree(struct dev_manager *dm,
 					 struct dm_tree_node *dnode,
 					 struct logical_volume *lv)
@@ -2020,6 +2048,18 @@ static int _add_segment_to_dtree(struct dev_manager *dm,
 		return 0;
 	}
 
+	/* Add external origin */
+	if (seg->external_lv &&
+	    !_add_new_lv_to_dtree(dm, dtree, seg->external_lv, laopts,
+				  lv_layer(seg->external_lv)))
+		return_0;
+	else if (!layer && lv_is_external_origin(seg->lv)) {
+		if (!_add_new_lv_to_dtree(dm, dtree, seg->lv, laopts,
+					  lv_layer(seg->lv)))
+			return_0;
+		return _add_external_origin_target_to_dtree(dm, dnode, seg->lv);
+	}
+
 	/* Add mirror log */
 	if (seg->log_lv &&
 	    !_add_new_lv_to_dtree(dm, dtree, seg->log_lv, laopts, NULL))
diff --git a/lib/format_text/flags.c b/lib/format_text/flags.c
index a3a3d0e..66e4bde 100644
--- a/lib/format_text/flags.c
+++ b/lib/format_text/flags.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004-2013 Red Hat, Inc. All rights reserved.
  *
  * This file is part of LVM2.
  *
@@ -58,6 +58,7 @@ static const struct flag _lv_flags[] = {
 	{LOCKED, "LOCKED", STATUS_FLAG},
 	{LV_NOTSYNCED, "NOTSYNCED", STATUS_FLAG},
 	{LV_REBUILD, "REBUILD", STATUS_FLAG},
+	{EXTERNAL_ORIGIN, NULL, 0},
 	{RAID, NULL, 0},
 	{RAID_META, NULL, 0},
 	{RAID_IMAGE, NULL, 0},
diff --git a/lib/metadata/lv.c b/lib/metadata/lv.c
index c27ef08..9f6b327 100644
--- a/lib/metadata/lv.c
+++ b/lib/metadata/lv.c
@@ -229,7 +229,7 @@ const char *lv_layer(const struct logical_volume *lv)
 {
 	if (lv_is_thin_pool(lv))
 		return "tpool";
-	else if (lv_is_origin(lv))
+	else if (lv_is_origin(lv) || lv_is_external_origin(lv))
 		return "real";
 
 	return NULL;
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 50e42dc..07d3fd7 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2012 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004-2013 Red Hat, Inc. All rights reserved.
  *
  * This file is part of LVM2.
  *
@@ -278,6 +278,9 @@ struct lv_segment *alloc_lv_segment(const struct segment_type *segtype,
 			seg->transaction_id = first_seg(first_seg(thin_pool_lv)->pool_lv)->transaction_id;
 			if (!attach_pool_lv(seg, first_seg(thin_pool_lv)->pool_lv, thin_pool_lv))
 				return_NULL;
+			/* Use the same external origin */
+			if (!attach_thin_external_origin(seg, first_seg(thin_pool_lv)->external_lv))
+				return_NULL;
 		} else {
 			seg->transaction_id = first_seg(thin_pool_lv)->transaction_id;
 			if (!attach_pool_lv(seg, thin_pool_lv, NULL))
diff --git a/lib/metadata/merge.c b/lib/metadata/merge.c
index a4563f8..477d7bb 100644
--- a/lib/metadata/merge.c
+++ b/lib/metadata/merge.c
@@ -243,6 +243,11 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
 						  lv->name, seg_count, seg->device_id);
 					inc_error_count;
 				}
+				if (seg->external_lv && (seg->external_lv->status & LVM_WRITE)) {
+					log_error("LV %s: external origin %s is writable.",
+						  lv->name, seg->external_lv->name);
+					inc_error_count;
+				}
 			} else {
 				if (seg->pool_lv) {
 					log_error("LV %s: segment %u must not have thin pool LV set",
@@ -372,7 +377,7 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
 			seg_found++;
 		if (seg->metadata_lv == lv || seg->pool_lv == lv)
 			seg_found++;
-		if (seg_is_thin_volume(seg) && seg->origin == lv)
+		if (seg_is_thin_volume(seg) && (seg->origin == lv || seg->external_lv == lv))
 			seg_found++;
 		if (!seg_found) {
 			log_error("LV %s is used by LV %s:%" PRIu32 "-%" PRIu32
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index ffec129..202ab2d 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004-2013 Red Hat, Inc. All rights reserved.
  *
  * This file is part of LVM2.
  *
@@ -89,6 +89,7 @@
 #define THIN_POOL		UINT64_C(0x0000002000000000)	/* LV */
 #define THIN_POOL_DATA		UINT64_C(0x0000004000000000)	/* LV */
 #define THIN_POOL_METADATA	UINT64_C(0x0000008000000000)	/* LV */
+#define EXTERNAL_ORIGIN		UINT64_C(0x0000010000000000)	/* LV */
 
 #define LVM_READ		UINT64_C(0x00000100)	/* LV, VG */
 #define LVM_WRITE		UINT64_C(0x00000200)	/* LV, VG */
@@ -141,6 +142,7 @@
 #define lv_is_used_thin_pool(lv)	(lv_is_thin_pool(lv) && !dm_list_empty(&(lv)->segs_using_this_lv))
 #define lv_is_thin_pool_data(lv)	((lv)->status & THIN_POOL_DATA ? 1 : 0)
 #define lv_is_thin_pool_metadata(lv)	((lv)->status & THIN_POOL_METADATA ? 1 : 0)
+#define lv_is_external_origin(lv)	((lv)->status & EXTERNAL_ORIGIN ? 1 : 0)
 #define lv_is_mirrored(lv)	((lv)->status & MIRRORED ? 1 : 0)
 #define lv_is_rlog(lv)		((lv)->status & REPLICATOR_LOG ? 1 : 0)
 
@@ -355,6 +357,7 @@ struct lv_segment {
 	unsigned zero_new_blocks;		/* For thin_pool */
 	thin_discards_t discards;		/* For thin_pool */
 	struct dm_list thin_messages;		/* For thin_pool */
+	struct logical_volume *external_lv;	/* For thin */
 	struct logical_volume *pool_lv;		/* For thin */
 	uint32_t device_id;			/* For thin, 24bit */
 
diff --git a/lib/metadata/metadata.h b/lib/metadata/metadata.h
index 8a80147..9ee455c 100644
--- a/lib/metadata/metadata.h
+++ b/lib/metadata/metadata.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.  
- * Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004-2013 Red Hat, Inc. All rights reserved.
  *
  * This file is part of LVM2.
  *
@@ -476,6 +476,9 @@ int pool_is_active(const struct lv_segment *pool_seg);
 int pool_below_threshold(const struct lv_segment *pool_seg);
 int extend_pool(struct logical_volume *lv, const struct segment_type *segtype,
 		struct alloc_handle *ah, uint32_t stripes, uint32_t stripe_size);
+int attach_thin_external_origin(struct lv_segment *seg,
+				struct logical_volume *external_lv);
+int detach_thin_external_origin(struct lv_segment *seg);
 
 /*
  * Begin skeleton for external LVM library
diff --git a/lib/metadata/thin_manip.c b/lib/metadata/thin_manip.c
index 6ec97d4..3eca06b 100644
--- a/lib/metadata/thin_manip.c
+++ b/lib/metadata/thin_manip.c
@@ -108,6 +108,9 @@ int detach_pool_lv(struct lv_segment *seg)
 		}
 	}
 
+	if (!detach_thin_external_origin(seg))
+		return_0;
+
 	if (!attach_pool_message(first_seg(seg->pool_lv),
 				 DM_THIN_MESSAGE_DELETE,
 				 NULL, seg->device_id, no_update))
@@ -198,6 +201,53 @@ int attach_pool_message(struct lv_segment *pool_seg, dm_thin_message_t type,
 	return 1;
 }
 
+int attach_thin_external_origin(struct lv_segment *seg,
+				struct logical_volume *external_lv)
+{
+	seg->external_lv = external_lv;
+
+	if (external_lv) {
+		if (!add_seg_to_segs_using_this_lv(external_lv, seg))
+			return_0;
+
+		external_lv->status |= EXTERNAL_ORIGIN;
+
+		if (external_lv->status & LVM_WRITE) {
+			log_verbose("Setting logical volume \"%s\" read-only.",
+				    external_lv->name);
+			external_lv->status &= ~LVM_WRITE;
+		}
+	}
+
+	return 1;
+}
+
+int detach_thin_external_origin(struct lv_segment *seg)
+{
+	if (seg->external_lv) {
+		if (!lv_is_external_origin(seg->external_lv)) {
+			log_error(INTERNAL_ERROR "Inconsitent external origin.");
+			return 0;
+		}
+
+		if (!remove_seg_from_segs_using_this_lv(seg->external_lv, seg))
+			return_0;
+
+		if (dm_list_empty(&seg->external_lv->segs_using_this_lv)) {
+			seg->external_lv->status &= ~EXTERNAL_ORIGIN;
+
+			/* FIXME -  we do not keep original state */
+			//log_verbose("Setting logical volume \"%s\" writable",
+			//	    seg->external_lv->name);
+			//seg->external_lv->status |= LVM_WRITE;
+		}
+
+		seg->external_lv = NULL;
+	}
+
+	return 1;
+}
+
 /*
  * Check whether pool has some message queued for LV or for device_id
  * When LV is NULL and device_id is 0 it just checks for any message.
diff --git a/lib/thin/thin.c b/lib/thin/thin.c
index 8c0ec82..807e0ee 100644
--- a/lib/thin/thin.c
+++ b/lib/thin/thin.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2012 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2011-2013 Red Hat, Inc. All rights reserved.
  *
  * This file is part of LVM2.
  *
@@ -439,7 +439,7 @@ static int _thin_text_import(struct lv_segment *seg,
 			     struct dm_hash_table *pv_hash __attribute__((unused)))
 {
 	const char *lv_name;
-	struct logical_volume *pool_lv, *origin = NULL;
+	struct logical_volume *pool_lv, *origin = NULL, *external_lv = NULL;
 
 	if (!dm_config_get_str(sn, "thin_pool", &lv_name))
 		return SEG_LOG_ERROR("Thin pool must be a string in");
@@ -465,9 +465,20 @@ static int _thin_text_import(struct lv_segment *seg,
 		return SEG_LOG_ERROR("Unsupported value %u for device_id",
 				     seg->device_id);
 
+	if (dm_config_has_node(sn, "external_origin")) {
+		if (!dm_config_get_str(sn, "external_origin", &lv_name))
+			return SEG_LOG_ERROR("External origin must be a string in");
+
+		if (!(external_lv = find_lv(seg->lv->vg, lv_name)))
+			return SEG_LOG_ERROR("Unknown external origin %s in", lv_name);
+	}
+
 	if (!attach_pool_lv(seg, pool_lv, origin))
 		return_0;
 
+	if (!attach_thin_external_origin(seg, external_lv))
+		return_0;
+
 	return 1;
 }
 
@@ -477,6 +488,8 @@ static int _thin_text_export(const struct lv_segment *seg, struct formatter *f)
 	outf(f, "transaction_id = %" PRIu64, seg->transaction_id);
 	outf(f, "device_id = %d", seg->device_id);
 
+	if (seg->external_lv)
+		outf(f, "external_origin = \"%s\"", seg->external_lv->name);
 	if (seg->origin)
 		outf(f, "origin = \"%s\"", seg->origin->name);
 
@@ -493,10 +506,10 @@ static int _thin_add_target_line(struct dev_manager *dm,
 				 struct dm_tree_node *node, uint64_t len,
 				 uint32_t *pvmove_mirror_count __attribute__((unused)))
 {
-	char *pool_dlid;
+	char *pool_dlid, *external_dlid;
 	uint32_t device_id = seg->device_id;
 
-	if (!(pool_dlid = build_dm_uuid(mem, seg->pool_lv->lvid.s, "tpool"))) {
+	if (!(pool_dlid = build_dm_uuid(mem, seg->pool_lv->lvid.s, lv_layer(seg->pool_lv)))) {
 		log_error("Failed to build uuid for pool LV %s.",
 			  seg->pool_lv->name);
 		return 0;
@@ -505,6 +518,18 @@ static int _thin_add_target_line(struct dev_manager *dm,
 	if (!dm_tree_node_add_thin_target(node, len, pool_dlid, device_id))
 		return_0;
 
+	/* Add external origin LV */
+	if (seg->external_lv) {
+		if (!(external_dlid = build_dm_uuid(mem, seg->external_lv->lvid.s,
+						    lv_layer(seg->external_lv)))) {
+			log_error("Failed to build uuid for external origin LV %s.",
+				  seg->external_lv->name);
+			return 0;
+		}
+		if (!dm_tree_node_set_thin_external_origin(node, external_dlid))
+			return_0;
+	}
+
 	return 1;
 }
 
-- 
1.8.1.2



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/6] thin: external origin cannot be changed
  2013-02-05 13:56 [PATCH 0/6] Thin external origin support Zdenek Kabelac
  2013-02-05 13:56 ` [PATCH 1/6] thin: add support for external origin Zdenek Kabelac
@ 2013-02-05 13:56 ` Zdenek Kabelac
  2013-02-05 13:56 ` [PATCH 3/6] thin: report external origin Zdenek Kabelac
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Zdenek Kabelac @ 2013-02-05 13:56 UTC (permalink / raw)
  To: lvm-devel

Do not allow conversion of external origin into writeable LV,
and prohibit changing the external origin size.

Signed-off-by: Zdenek Kabelac <zkabelac@redhat.com>
---
 tools/lvchange.c | 6 ++++++
 tools/lvresize.c | 9 +++++++++
 2 files changed, 15 insertions(+)

diff --git a/tools/lvchange.c b/tools/lvchange.c
index 0ea2e78..7ac4a39 100644
--- a/tools/lvchange.c
+++ b/tools/lvchange.c
@@ -36,6 +36,12 @@ static int lvchange_permission(struct cmd_context *cmd,
 		return 0;
 	}
 
+	if (lv_is_external_origin(lv)) {
+		log_error("Cannot change permissions of external origin "
+			  "\"%s\".", lv->name);
+		return 0;
+	}
+
 	if ((lv->status & MIRRORED) && (vg_is_clustered(lv->vg)) &&
 	    lv_info(cmd, lv, 0, &info, 0, 0) && info.exists) {
 		log_error("Cannot change permissions of mirror \"%s\" "
diff --git a/tools/lvresize.c b/tools/lvresize.c
index 4c9580d..d49da8a 100644
--- a/tools/lvresize.c
+++ b/tools/lvresize.c
@@ -390,6 +390,15 @@ static int _lvresize(struct cmd_context *cmd, struct volume_group *vg,
 		return ECMD_FAILED;
 	}
 
+	if (lv_is_external_origin(lvl->lv)) {
+		/*
+		 * Since external-origin can be activated read-only,
+		 * there is no way to use extended areas.
+		 */
+		log_error("Cannot resize external origin \"%s\".", lvl->lv->name);
+		return EINVALID_CMD_LINE;
+	}
+
 	if (lvl->lv->status & (RAID_IMAGE | RAID_META)) {
 		log_error("Cannot resize a RAID %s directly",
 			  (lvl->lv->status & RAID_IMAGE) ? "image" :
-- 
1.8.1.2



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 3/6] thin: report external origin
  2013-02-05 13:56 [PATCH 0/6] Thin external origin support Zdenek Kabelac
  2013-02-05 13:56 ` [PATCH 1/6] thin: add support for external origin Zdenek Kabelac
  2013-02-05 13:56 ` [PATCH 2/6] thin: external origin cannot be changed Zdenek Kabelac
@ 2013-02-05 13:56 ` Zdenek Kabelac
  2013-02-05 13:56 ` [PATCH 4/6] thin: removal of " Zdenek Kabelac
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Zdenek Kabelac @ 2013-02-05 13:56 UTC (permalink / raw)
  To: lvm-devel

Use the field 'origin' for reporting external origin lv name.

For thin volumes with external origin, report the size of
external origin size via:

  lvs -o+origin_size

Signed-off-by: Zdenek Kabelac <zkabelac@redhat.com>
---
 lib/metadata/lv.c   | 7 ++++++-
 lib/report/report.c | 3 +++
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/lib/metadata/lv.c b/lib/metadata/lv.c
index 9f6b327..f1c79be 100644
--- a/lib/metadata/lv.c
+++ b/lib/metadata/lv.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2012 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004-2013 Red Hat, Inc. All rights reserved.
  *
  * This file is part of LVM2.
  *
@@ -169,6 +169,9 @@ char *lv_origin_dup(struct dm_pool *mem, const struct logical_volume *lv)
 	if (lv_is_thin_volume(lv) && first_seg(lv)->origin)
 		return lv_name_dup(mem, first_seg(lv)->origin);
 
+	if (lv_is_thin_volume(lv) && first_seg(lv)->external_lv)
+		return lv_name_dup(mem, first_seg(lv)->external_lv);
+
 	return NULL;
 }
 
@@ -282,6 +285,8 @@ uint64_t lv_origin_size(const struct logical_volume *lv)
 {
 	if (lv_is_cow(lv))
 		return (uint64_t) find_cow(lv)->len * lv->vg->extent_size;
+	if (lv_is_thin_volume(lv) && first_seg(lv)->external_lv)
+		return first_seg(lv)->external_lv->size;
 	if (lv_is_origin(lv))
 		return lv->size;
 	return 0;
diff --git a/lib/report/report.c b/lib/report/report.c
index 5a4e4df..633dfe4 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -343,6 +343,9 @@ static int _origin_disp(struct dm_report *rh, struct dm_pool *mem,
 	if (lv_is_thin_volume(lv) && first_seg(lv)->origin)
 		return _lvname_disp(rh, mem, field, first_seg(lv)->origin, private);
 
+	if (lv_is_thin_volume(lv) && first_seg(lv)->external_lv)
+		return _lvname_disp(rh, mem, field, first_seg(lv)->external_lv, private);
+
 	dm_report_field_set_value(field, "", NULL);
 	return 1;
 }
-- 
1.8.1.2



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 4/6] thin: removal of external origin
  2013-02-05 13:56 [PATCH 0/6] Thin external origin support Zdenek Kabelac
                   ` (2 preceding siblings ...)
  2013-02-05 13:56 ` [PATCH 3/6] thin: report external origin Zdenek Kabelac
@ 2013-02-05 13:56 ` Zdenek Kabelac
  2013-02-05 13:56 ` [PATCH 5/6] thin: lvconvert support for " Zdenek Kabelac
  2013-02-05 13:56 ` [PATCH 6/6] tests: lvconvert " Zdenek Kabelac
  5 siblings, 0 replies; 7+ messages in thread
From: Zdenek Kabelac @ 2013-02-05 13:56 UTC (permalink / raw)
  To: lvm-devel

If the removal of external origin is requested,
query if the user also want to remove all its users.

Create common static function _lv_remove_segs_using_this_lv()
so the same code can be shared with thin pool removal.

Note: the function cannot use dm_list_iterate_items_safe()

Signed-off-by: Zdenek Kabelac <zkabelac@redhat.com>
---
 lib/metadata/lv_manip.c | 57 +++++++++++++++++++++++++++++++++++--------------
 1 file changed, 41 insertions(+), 16 deletions(-)

diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 07d3fd7..11bd3a4 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -3309,6 +3309,12 @@ int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv,
 		return 0;
 	}
 
+	if (lv_is_external_origin(lv)) {
+		log_error("Can't remove external origin logical volume \"%s\".",
+			  lv->name);
+		return 0;
+	}
+
 	if (lv->status & MIRROR_IMAGE) {
 		log_error("Can't remove logical volume %s used by a mirror",
 			  lv->name);
@@ -3448,6 +3454,35 @@ int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv,
 	return 1;
 }
 
+static int _lv_remove_segs_using_this_lv(struct cmd_context *cmd, struct logical_volume *lv,
+					 const force_t force, unsigned level,
+					 const char *lv_type)
+{
+	struct seg_list *sl;
+
+	if ((force == PROMPT) &&
+	    yes_no_prompt("Removing %s \"%s\" will remove %u dependent volume(s). "
+			  "Proceed? [y/n]: ", lv_type, lv->name,
+			  dm_list_size(&lv->segs_using_this_lv)) == 'n') {
+			log_error("Logical volume \"%s\" not removed.", lv->name);
+			return 0;
+		}
+	/*
+	 * Not using _safe iterator here - since we may delete whole subtree
+	 * (similar as process_each_lv_in_vg())
+	 * the code is roughly equivalent to this:
+	 *
+	 * while (!dm_list_empty(&lv->segs_using_this_lv))
+	 * 	dm_list_iterate_items(sl, &lv->segs_using_this_lv)
+	 * 		break;
+	 */
+	dm_list_iterate_items(sl, &lv->segs_using_this_lv)
+		if (!lv_remove_with_dependencies(cmd, sl->seg->lv,
+						 force, level + 1))
+			return_0;
+
+	return 1;
+}
 /*
  * remove LVs with its dependencies - LV leaf nodes should be removed first
  */
@@ -3456,7 +3491,6 @@ int lv_remove_with_dependencies(struct cmd_context *cmd, struct logical_volume *
 {
 	percent_t snap_percent;
 	struct dm_list *snh, *snht;
-	struct seg_list *sl, *tsl;
 	struct lvinfo info;
 
 	if (lv_is_cow(lv)) {
@@ -3507,22 +3541,13 @@ int lv_remove_with_dependencies(struct cmd_context *cmd, struct logical_volume *
 				return_0;
 	}
 
-	if (lv_is_used_thin_pool(lv)) {
-		/* Remove thin LVs first */
-		if ((force == PROMPT) &&
-		    yes_no_prompt("Removing pool %s will also remove %u "
-				  "thin volume(s). OK? [y/n]: ", lv->name,
-				  /* Note: Snaphosts not included */
-				  dm_list_size(&lv->segs_using_this_lv)) == 'n') {
-			log_error("Logical volume %s not removed.", lv->name);
-			return 0;
-		}
+	if (lv_is_external_origin(lv) &&
+	    !_lv_remove_segs_using_this_lv(cmd, lv, force, level, "external origin"))
+		return_0;
 
-		dm_list_iterate_items_safe(sl, tsl, &lv->segs_using_this_lv)
-			if (!lv_remove_with_dependencies(cmd, sl->seg->lv,
-							 force, level + 1))
-				return_0;
-	}
+	if (lv_is_used_thin_pool(lv) &&
+	    !_lv_remove_segs_using_this_lv(cmd, lv, force, level, "pool"))
+		return_0;
 
 	return lv_remove_single(cmd, lv, force);
 }
-- 
1.8.1.2



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 5/6] thin: lvconvert support for external origin
  2013-02-05 13:56 [PATCH 0/6] Thin external origin support Zdenek Kabelac
                   ` (3 preceding siblings ...)
  2013-02-05 13:56 ` [PATCH 4/6] thin: removal of " Zdenek Kabelac
@ 2013-02-05 13:56 ` Zdenek Kabelac
  2013-02-05 13:56 ` [PATCH 6/6] tests: lvconvert " Zdenek Kabelac
  5 siblings, 0 replies; 7+ messages in thread
From: Zdenek Kabelac @ 2013-02-05 13:56 UTC (permalink / raw)
  To: lvm-devel

Add basic support for converting LV into an external origin volume.

Syntax:

lvconvert --thinpool vg/pool  --originname renamed_origin -T origin

It will convert volume  'origin' into a thin volume, which will
use 'renamed_origin' as an external read-only origin.
All read/write into origin will go via 'pool'.

renamed_origin volume is read-only volume, that could be activated
only in read-only mode, and cannot be modified.

Signed-off-by: Zdenek Kabelac <zkabelac@redhat.com>
---
 lib/activate/activate.c |   6 +-
 man/lvconvert.8.in      |  32 +++++++++
 tools/args.h            |   3 +-
 tools/commands.h        |   7 +-
 tools/lvconvert.c       | 173 ++++++++++++++++++++++++++++++++++++++++++++++--
 5 files changed, 210 insertions(+), 11 deletions(-)

diff --git a/lib/activate/activate.c b/lib/activate/activate.c
index 6187828..f19dff7 100644
--- a/lib/activate/activate.c
+++ b/lib/activate/activate.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2012 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004-2013 Red Hat, Inc. All rights reserved.
  *
  * This file is part of LVM2.
  *
@@ -1580,6 +1580,10 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
 	    (lv_is_origin(lv_pre) || lv_is_cow(lv_pre)))
 		lockfs = 1;
 
+	/* Converting non-thin LV to thin external origin ? */
+	if (!lv_is_thin_volume(lv) && lv_is_thin_volume(lv_pre))
+		lockfs = 1; /* Sync before conversion */
+
 	if (laopts->origin_only && lv_is_thin_volume(lv) && lv_is_thin_volume(lv_pre))
 		lockfs = 1;
 
diff --git a/man/lvconvert.8.in b/man/lvconvert.8.in
index 578047b..c5929c2 100644
--- a/man/lvconvert.8.in
+++ b/man/lvconvert.8.in
@@ -99,6 +99,10 @@ lvconvert \- convert a logical volume from linear to mirror or snapshot
 .RB [ \-h | \-? | \-\-help ]
 .RB [ \-v | \-\-verbose ]
 .RB [ \-\-version ]
+.RB [ \-T | \-\-thin
+.IR ExternalOriginLogicalVolume { Name | Path }
+.RB [ \-\-originname
+.IR NewExternalOriginVolumeName ]]
 .RI [ PhysicalVolume [ Path ][ :PE [ -PE ]]...]
 .sp
 
@@ -230,6 +234,13 @@ merge finishes, the merged snapshot is removed.  Multiple snapshots may
 be specified on the commandline or a @tag may be used to specify
 multiple snapshots be merged to their respective origin.
 .TP
+.B \-\-originname \fINewExternalOriginVolumeName\fP
+The name for converted external origin volume.
+.br
+Without this option a default names of "lvol#" will be generated where
+# is the LVM internal number of the logical volume.
+Converted volume will be read-only.
+.TP
 .BR \-\-poolmetadata " " \fIThinPoolMetadataLogicalVolume { \fIName | \fIPath }
 Specifies thin pool metadata logical volume.
 The size should be in between 2MiB and 16GiB.
@@ -288,6 +299,13 @@ StripeSize must be 2^n (n = 2 to 9) for metadata in LVM1 format.
 For metadata in LVM2 format, the stripe size may be a larger
 power of 2 but must not exceed the physical extent size.
 .TP
+.IR \fB\-T ", " \fB\-\-thin " " ExternalOriginLogicalVolume { Name | Path }
+Changes the logical volume into a thin volume for the thin pool
+specified with the option \fB\-\-thinpool\fP. \fIExternalOriginLogicalVolume\fP
+is converted into a new read-only logical volume which will be used as an
+external origin volume for unprovisioned areas.
+The non-default name for this new volume can be specified with \fB\-\-originname\fP.
+.TP
 .IR \fB\-\-thinpool " " ThinPoolLogicalVolume { Name | Path }
 Changes logical volume into a thin pool volume. The volume
 will store the pool's data.
@@ -379,6 +397,20 @@ available in the volume group.
 .sp
 .B lvconvert \-\-replace /dev/sdb1 vg00/my_raid1 /dev/sdf1
 
+Convert the logical volume "vg00/lvpool" into a thin pool with chunk size 128KiB
+and convert "vg00/lv1" into a thin volume using this pool. Original "vg00/lv1"
+is used as an external read-only origin, where all writes to such volume
+are stored in the "vg00/lvpool".
+.sp
+.B lvconvert \-\-thinpool vg00/lvpool -c 128 -T lv1
+
+Convert the logical volume "vg00/origin" into a thin volume from the thin pool
+"vg00/lvpool". This thin volume will use "vg00/origin" as an external origin
+volume for unprovisioned areas in this volume.
+For the read-only external origin use the new name "vg00/external".
+.sp
+.B lvconvert \-\-thinpool vg00/lvpool \-\-originname external -T vg00/origin
+
 .SH SEE ALSO
 .BR lvm (8),
 .BR vgcreate (8),
diff --git a/tools/args.h b/tools/args.h
index d4d6c40..b140cdb 100644
--- a/tools/args.h
+++ b/tools/args.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.  
- * Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004-2013 Red Hat, Inc. All rights reserved.
  *
  * This file is part of LVM2.
  *
@@ -69,6 +69,7 @@ arg(dataalignment_ARG, '\0', "dataalignment", size_kb_arg, 0)
 arg(dataalignmentoffset_ARG, '\0', "dataalignmentoffset", size_kb_arg, 0)
 arg(virtualoriginsize_ARG, '\0', "virtualoriginsize", size_mb_arg, 0)
 arg(noudevsync_ARG, '\0', "noudevsync", NULL, 0)
+arg(originname_ARG, '\0', "originname", string_arg, 0)
 arg(poll_ARG, '\0', "poll", yes_no_arg, 0)
 arg(poolmetadata_ARG, '\0', "poolmetadata", string_arg, 0)
 arg(poolmetadatasize_ARG, '\0', "poolmetadatasize", size_mb_arg, 0)
diff --git a/tools/commands.h b/tools/commands.h
index 986539e..32d3c96 100644
--- a/tools/commands.h
+++ b/tools/commands.h
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2012 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004-2013 Red Hat, Inc. All rights reserved.
  *
  * This file is part of LVM2.
  *
@@ -151,6 +151,8 @@ xx(lvconvert,
    "\t [--poolmetadatasize size]\n"
    "\t [-r|--readahead ReadAheadSectors|auto|none]\n"
    "\t [--stripes Stripes [-I|--stripesize StripeSize]]]\n"
+   "\t[-T|--thin ExternalLogicalVolume[Path]\n"
+   "\t [--originname NewExternalOriginVolumeName]]\n"
    "\t[-Z|--zero {y|n}]\n"
    "\t[-d|--debug] [-h|-?|--help] [-v|--verbose]\n",
 
@@ -158,7 +160,8 @@ xx(lvconvert,
    merge_ARG, mirrorlog_ARG, mirrors_ARG, name_ARG, noudevsync_ARG,
    readahead_ARG, regionsize_ARG, repair_ARG, replace_ARG, snapshot_ARG, splitmirrors_ARG,
    trackchanges_ARG, type_ARG, stripes_long_ARG, stripesize_ARG, test_ARG,
-   chunksize_ARG, discards_ARG, poolmetadata_ARG, poolmetadatasize_ARG, thinpool_ARG,
+   chunksize_ARG, discards_ARG, poolmetadata_ARG, poolmetadatasize_ARG,
+   originname_ARG, thin_ARG, thinpool_ARG,
    use_policies_ARG, yes_ARG, force_ARG, zero_ARG)
 
 xx(lvcreate,
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 0e15888..133b456 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -57,6 +57,7 @@ struct lvconvert_params {
 	struct logical_volume *lv_to_poll;
 
 	uint64_t poolmetadata_size;
+	const char *origin_lv_name;
 	const char *pool_data_lv_name;
 	const char *pool_metadata_lv_name;
 	thin_discards_t discards;
@@ -68,6 +69,7 @@ static int _lvconvert_name_params(struct lvconvert_params *lp,
 {
 	char *ptr;
 	const char *vg_name = NULL;
+	const char *tmp_str;
 
 	if (lp->merge)
 		return 1;
@@ -94,16 +96,35 @@ static int _lvconvert_name_params(struct lvconvert_params *lp,
 
 	if (lp->pool_data_lv_name) {
 		if (*pargc) {
-			log_error("More then one logical volume name name specified.");
-			return 0;
+			if (!arg_count(cmd, thin_ARG)) {
+				log_error("More then one logical volume name specified.");
+				return 0;
+			}
+		} else {
+			if (arg_count(cmd, thin_ARG)) {
+				log_error("External thin volume name is missing.");
+				return 0;
+			}
+
+			if (!lp->vg_name || !validate_name(lp->vg_name)) {
+				log_error("Please provide a valid volume group name.");
+				return 0;
+			}
+
+			lp->lv_name = lp->pool_data_lv_name;
+			return 1;
 		}
+	}
 
-		if (!lp->vg_name || !validate_name(lp->vg_name)) {
-			log_error("Please provide a valid volume group name.");
-			return 0;
+	if (lp->origin_lv_name) {
+		/* FIXME: Using generic routine */
+		if (strchr(lp->origin_lv_name, '/')) {
+			if (!(lp->vg_name = extract_vgname(cmd, lp->origin_lv_name)))
+				return_0;
+			/* Strip VG from origin_lv_name */
+			if ((tmp_str = strrchr(lp->origin_lv_name, '/')))
+				lp->origin_lv_name = tmp_str + 1;
 		}
-		lp->lv_name = lp->pool_data_lv_name;
-		return 1; /* Create metadata LV on it's own */
 	}
 
 	if (!*pargc) {
@@ -219,6 +240,9 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
 			return 0;
 		}
 		lp->discards = (thin_discards_t) arg_uint_value(cmd, discards_ARG, THIN_DISCARDS_PASSDOWN);
+	} else if (arg_count(cmd, thin_ARG)) {
+		log_error("--thin is only valid with --thinpool.");
+		return 0;
 	} else if (arg_count(cmd, discards_ARG)) {
 		log_error("--discards is only valid with --thinpool.");
 		return 0;
@@ -376,6 +400,13 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
 			lp->pool_data_lv_name = tmp_str + 1;
 		}
 
+		if (arg_count(cmd, originname_ARG)) {
+			if (!(lp->origin_lv_name = arg_str_value(cmd, originname_ARG, NULL))) {
+				log_error("--originname is invalid.");
+				return 0;
+			}
+		}
+
 		lp->segtype = get_segtype_from_string(cmd, arg_str_value(cmd, type_ARG, "thin-pool"));
 		if (!lp->segtype)
 			return_0;
@@ -1827,6 +1858,115 @@ out:
 	return r;
 }
 
+/* Swap lvid and LV names */
+static int _swap_lv(struct cmd_context *cmd,
+		    struct logical_volume *a, struct logical_volume *b)
+{
+	union lvid lvid;
+	const char *name;
+
+	lvid = a->lvid;
+	a->lvid = b->lvid;
+	b->lvid = lvid;
+
+	name = a->name;
+	a->name = b->name;
+	if (!lv_rename_update(cmd, b, name, 0))
+		return_0;
+
+	return 1;
+}
+
+static int _lvconvert_thinpool_external(struct cmd_context *cmd,
+					struct logical_volume *pool_lv,
+					struct logical_volume *external_lv,
+					struct lvconvert_params *lp)
+{
+	struct logical_volume *torigin_lv;
+	struct volume_group *vg = pool_lv->vg;
+	struct lvcreate_params lvc = { 0 };
+
+	dm_list_init(&lvc.tags);
+
+	if (!(lvc.segtype = get_segtype_from_string(cmd, "thin")))
+		return_0;
+
+	lvc.activate = CHANGE_AE;
+	lvc.alloc = ALLOC_INHERIT;
+	lvc.lv_name = lp->origin_lv_name;
+	lvc.major = -1;
+	lvc.minor = -1;
+	lvc.permission = LVM_READ;
+	lvc.pool = pool_lv->name;
+	lvc.pvh = &vg->pvs;
+	lvc.read_ahead = DM_READ_AHEAD_AUTO;
+	lvc.stripes = 1;
+	lvc.vg_name = vg->name;
+	lvc.voriginextents = external_lv->le_count;
+	lvc.voriginsize = external_lv->size;
+
+	/* New thin LV needs to be created (all messages sent to pool) */
+	if (!(torigin_lv = lv_create_single(vg, &lvc)))
+		return_0;
+
+	/* Activate again via -torigin, so this active LV is not needed */
+	if (!deactivate_lv(cmd, torigin_lv)) {
+		log_error("Aborting. Unable to deactivate new LV. "
+			  "Manual intervention required.");
+		return 0;
+	}
+
+	/*
+	 * Crashing till this point will leave plain thin volume
+	 * which could be easily removed by the user after i.e. power-off
+	 */
+
+	if (!_swap_lv(cmd, torigin_lv, external_lv)) {
+		stack;
+		goto revert_new_lv;
+	}
+
+	/* FIXME: is that useful to preserve status here ? */
+	torigin_lv->status |= (external_lv->status & LVM_WRITE);
+
+	if (!attach_thin_external_origin(first_seg(torigin_lv), external_lv)) {
+		goto revert_new_lv;
+	}
+
+	if (!_reload_lv(cmd, vg, torigin_lv)) {
+		stack;
+		goto deactivate_and_revert_new_lv;
+	}
+
+	log_print_unless_silent("Converted %s/%s to thin external origin.",
+				vg->name, external_lv->name);
+
+	return 1;
+
+deactivate_and_revert_new_lv:
+	if (!_swap_lv(cmd, torigin_lv, external_lv))
+		stack;
+
+	if (!deactivate_lv(cmd, torigin_lv)) {
+		log_error("Unable to deactivate failed new LV. "
+			  "Manual intervention required.");
+		return 0;
+	}
+
+	if (!detach_thin_external_origin(first_seg(torigin_lv)))
+		return_0;
+
+revert_new_lv:
+	/* FIXME Better to revert to backup of metadata? */
+	if (!lv_remove(torigin_lv) || !vg_write(vg) || !vg_commit(vg))
+		log_error("Manual intervention may be required to remove "
+			  "abandoned LV(s) before retrying.");
+	else
+		backup(vg);
+
+	return 0;
+}
+
 /*
  * Thin lvconvert version which
  *  rename metadata
@@ -1845,6 +1985,7 @@ static int _lvconvert_thinpool(struct cmd_context *cmd,
 	struct logical_volume *data_lv;
 	struct logical_volume *metadata_lv;
 	struct logical_volume *pool_metadata_lv;
+	struct logical_volume *external_lv = NULL;
 
 	if (!lv_is_visible(pool_lv)) {
 		log_error("Can't convert internal LV %s/%s.",
@@ -1852,6 +1993,19 @@ static int _lvconvert_thinpool(struct cmd_context *cmd,
 		return 0;
 	}
 
+	if (arg_count(cmd, thin_ARG)) {
+		external_lv = pool_lv;
+		if (!(pool_lv = find_lv(external_lv->vg, lp->pool_data_lv_name))) {
+			log_error("Can't find pool LV %s/%s.",
+				  external_lv->vg->name, lp->pool_data_lv_name);
+			return 0;
+		}
+		if (lv_is_thin_pool(pool_lv)) {
+			r = 1; /* Already existing thin pool */
+			goto out;
+		}
+	}
+
 	if (lv_is_thin_type(pool_lv) && !lp->pool_metadata_lv_name) {
 		log_error("Can't use thin logical volume %s/%s for thin pool data.",
 			  pool_lv->vg->name, pool_lv->name);
@@ -2066,7 +2220,12 @@ mda_write:
 
 	r = 1;
 out:
+	if (r && external_lv &&
+	    !(r = _lvconvert_thinpool_external(cmd, pool_lv, external_lv, lp)))
+		stack;
+
 	backup(pool_lv->vg);
+
 	return r;
 }
 
-- 
1.8.1.2



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 6/6] tests: lvconvert external origin
  2013-02-05 13:56 [PATCH 0/6] Thin external origin support Zdenek Kabelac
                   ` (4 preceding siblings ...)
  2013-02-05 13:56 ` [PATCH 5/6] thin: lvconvert support for " Zdenek Kabelac
@ 2013-02-05 13:56 ` Zdenek Kabelac
  5 siblings, 0 replies; 7+ messages in thread
From: Zdenek Kabelac @ 2013-02-05 13:56 UTC (permalink / raw)
  To: lvm-devel


Signed-off-by: Zdenek Kabelac <zkabelac@redhat.com>
---
 test/shell/lvconvert-thin-external.sh | 82 +++++++++++++++++++++++++++++++++++
 1 file changed, 82 insertions(+)
 create mode 100644 test/shell/lvconvert-thin-external.sh

diff --git a/test/shell/lvconvert-thin-external.sh b/test/shell/lvconvert-thin-external.sh
new file mode 100644
index 0000000..06fc731
--- /dev/null
+++ b/test/shell/lvconvert-thin-external.sh
@@ -0,0 +1,82 @@
+#!/bin/sh
+
+# Copyright (C) 2013 Red Hat, Inc. All rights reserved.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions
+# of the GNU General Public License v.2.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+# test thin external origin behavior
+
+. lib/test
+
+#
+# Main
+#
+aux have_thin 1 5 0 || skip
+
+aux prepare_pvs 2 64
+
+vgcreate $vg -s 64K $(cat DEVICES)
+
+# create thin pool
+lvcreate -L8M -T $vg/pool
+
+# create plain LV
+lvcreate -L8M -n $lv1 $vg
+
+mkfs.ext4 $DM_DEV_DIR/$vg/$lv1
+mkdir mnt
+mount $DM_DEV_DIR/$vg/$lv1 mnt
+
+dd if=/dev/zero of=mnt/test1 bs=1M count=1
+
+# convert plain LV into thin external snapshot volume
+# during conversion dd above could be still flushed
+
+lvconvert -T --originname extorg --thinpool $vg/pool $vg/$lv1
+
+check active $vg $lv1
+check inactive $vg extorg
+
+touch mnt/test
+umount mnt
+
+fsck $DM_DEV_DIR/$vg/$lv1
+
+lvchange -ay $vg/extorg
+lvchange -an $vg/$lv1
+
+check active $vg extorg
+check inactive $vg $lv1
+
+# fsck in read-only mode
+fsck -n $DM_DEV_DIR/$vg/extorg
+
+not lvresize -l+8 $vg/extorg
+not lvresize -l-4 $vg/extorg
+not lvchange -p rw $vg/extorg
+
+lvresize -L+8M $vg/$lv1
+lvresize -L-4M $vg/$lv1
+lvchange -p r $vg/$lv1
+lvchange -p rw $vg/$lv1
+
+lvconvert --originname extorg1 --thinpool $vg/pool -T $vg/extorg
+lvconvert --originname extorglv1 --thinpool $vg/pool -T $vg/extorg1
+
+lvcreate -l10 -s $vg/$lv1
+
+# Remove all volumes dependent on external origin
+lvremove -f $vg/extorglv1
+
+#lvs -a -o+origin_size,seg_size $vg
+
+# Only pool is left
+check vg_field $vg lv_count 1
+
+vgremove -ff $vg
-- 
1.8.1.2



^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2013-02-05 13:56 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-02-05 13:56 [PATCH 0/6] Thin external origin support Zdenek Kabelac
2013-02-05 13:56 ` [PATCH 1/6] thin: add support for external origin Zdenek Kabelac
2013-02-05 13:56 ` [PATCH 2/6] thin: external origin cannot be changed Zdenek Kabelac
2013-02-05 13:56 ` [PATCH 3/6] thin: report external origin Zdenek Kabelac
2013-02-05 13:56 ` [PATCH 4/6] thin: removal of " Zdenek Kabelac
2013-02-05 13:56 ` [PATCH 5/6] thin: lvconvert support for " Zdenek Kabelac
2013-02-05 13:56 ` [PATCH 6/6] tests: lvconvert " Zdenek Kabelac

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.