mrc0mmand / rpms / lvm2

Forked from rpms/lvm2 2 years ago
Clone

Blame SOURCES/lvm2-2_02_106-various-thin-fixes.patch

4c7ee1
commit 85fc38d398d1bc8acb4027da7acc376af2be0cc1
4c7ee1
Author: Peter Rajnoha <prajnoha@redhat.com>
4c7ee1
Date:   Wed Mar 12 14:37:59 2014 +0100
4c7ee1
4c7ee1
    thin fixes
4c7ee1
---
4c7ee1
 WHATS_NEW                   |  3 ++
4c7ee1
 lib/activate/activate.c     |  2 +-
4c7ee1
 lib/activate/dev_manager.c  | 72 +++++++++++++++++++++++++--------------------
4c7ee1
 lib/cache_segtype/cache.c   |  6 ++--
4c7ee1
 lib/metadata/lv_manip.c     | 63 +++------------------------------------
4c7ee1
 lib/metadata/pool_manip.c   |  3 ++
4c7ee1
 lib/metadata/thin_manip.c   |  2 +-
4c7ee1
 lib/mirror/mirrored.c       |  4 +--
4c7ee1
 lib/misc/lvm-string.c       |  8 ++++-
4c7ee1
 lib/misc/lvm-string.h       |  3 +-
4c7ee1
 lib/thin/thin.c             |  8 ++---
4c7ee1
 test/shell/lvcreate-thin.sh |  4 ++-
4c7ee1
 test/shell/pvremove-thin.sh | 28 ++++++++++++++++++
4c7ee1
 13 files changed, 101 insertions(+), 105 deletions(-)
4c7ee1
4c7ee1
diff --git a/WHATS_NEW b/WHATS_NEW
4c7ee1
index 3ee9585..a3d48f3 100644
4c7ee1
--- a/WHATS_NEW
4c7ee1
+++ b/WHATS_NEW
4c7ee1
@@ -1,5 +1,8 @@
4c7ee1
 Version 2.02.106 - 
4c7ee1
 ====================================
4c7ee1
+  Update API for internal function build_dm_uuid().
4c7ee1
+  Do not try to check empty pool with scheduled messages.
4c7ee1
+  Fix return value in pool_has_message() when quering for any message.
4c7ee1
   Fix cache consistency in lvmetad when PV moves around.
4c7ee1
   Fix memleak when lvmetad discovers PV to appear on another device.
4c7ee1
   Fix invalid memory read in lvmetad that could cause a deadlock.
4c7ee1
diff --git a/lib/activate/activate.c b/lib/activate/activate.c
4c7ee1
index 26dc0e1..565634f 100644
4c7ee1
--- a/lib/activate/activate.c
4c7ee1
+++ b/lib/activate/activate.c
4c7ee1
@@ -1546,7 +1546,7 @@ static char *_build_target_uuid(struct cmd_context *cmd, struct logical_volume *
4c7ee1
 	else
4c7ee1
 		layer = NULL;
4c7ee1
 
4c7ee1
-	return build_dm_uuid(cmd->mem, lv->lvid.s, layer);
4c7ee1
+	return build_dm_uuid(cmd->mem, lv, layer);
4c7ee1
 }
4c7ee1
 
4c7ee1
 int target_registered_with_dmeventd(struct cmd_context *cmd, const char *dso,
4c7ee1
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
4c7ee1
index 6b5f8c2..c723a61 100644
4c7ee1
--- a/lib/activate/dev_manager.c
4c7ee1
+++ b/lib/activate/dev_manager.c
4c7ee1
@@ -446,6 +446,12 @@ static int _device_is_usable(struct device *dev, int check_lv_names)
4c7ee1
 		    !dm_split_lvm_name(NULL, NULL, &vgname, &lvname, &layer))
4c7ee1
 			goto_out;
4c7ee1
 
4c7ee1
+		if (strlen(uuid) > 68) {
4c7ee1
+			log_debug_activation("%s: Reserved uuid %s on internal LV device %s/%s%s%s not usable.",
4c7ee1
+					     dev_name(dev), uuid, vgname, lvname, *layer ? "-" : "", layer);
4c7ee1
+			goto out;
4c7ee1
+		}
4c7ee1
+
4c7ee1
 		if (lvname && (is_reserved_lvname(lvname) || *layer)) {
4c7ee1
 			log_debug_activation("%s: Reserved internal LV device %s/%s%s%s not usable.",
4c7ee1
 					     dev_name(dev), vgname, lvname, *layer ? "-" : "", layer);
4c7ee1
@@ -505,7 +511,7 @@ int dev_manager_info(struct dm_pool *mem, const struct logical_volume *lv,
4c7ee1
 		return 0;
4c7ee1
 	}
4c7ee1
 
4c7ee1
-	if (!(dlid = build_dm_uuid(mem, lv->lvid.s, layer))) {
4c7ee1
+	if (!(dlid = build_dm_uuid(mem, lv, layer))) {
4c7ee1
 		log_error("dlid build failed for %s", name);
4c7ee1
 		r = 0;
4c7ee1
 		goto out;
4c7ee1
@@ -528,7 +534,7 @@ static const struct dm_info *_cached_info(struct dm_pool *mem,
4c7ee1
 	const struct dm_tree_node *dnode;
4c7ee1
 	const struct dm_info *dinfo = NULL;
4c7ee1
 
4c7ee1
-	if (!(dlid = build_dm_uuid(mem, lv->lvid.s, layer))) {
4c7ee1
+	if (!(dlid = build_dm_uuid(mem, lv, layer))) {
4c7ee1
 		log_error("Failed to build dlid for %s.", lv->name);
4c7ee1
 		return NULL;
4c7ee1
 	}
4c7ee1
@@ -641,7 +647,7 @@ int lv_has_target_type(struct dm_pool *mem, struct logical_volume *lv,
4c7ee1
 	char *type = NULL;
4c7ee1
 	char *params = NULL;
4c7ee1
 
4c7ee1
-	if (!(dlid = build_dm_uuid(mem, lv->lvid.s, layer)))
4c7ee1
+	if (!(dlid = build_dm_uuid(mem, lv, layer)))
4c7ee1
 		return_0;
4c7ee1
 
4c7ee1
 	if (!(dmt = _setup_task(NULL, dlid, 0,
4c7ee1
@@ -872,7 +878,7 @@ int dev_manager_transient(struct dev_manager *dm, struct logical_volume *lv)
4c7ee1
 	const struct dm_list *segh = &lv->segments;
4c7ee1
 	struct lv_segment *seg = NULL;
4c7ee1
 
4c7ee1
-	if (!(dlid = build_dm_uuid(dm->mem, lv->lvid.s, layer)))
4c7ee1
+	if (!(dlid = build_dm_uuid(dm->mem, lv, layer)))
4c7ee1
 		return_0;
4c7ee1
 
4c7ee1
 	if (!(dmt = _setup_task(0, dlid, NULL, DM_DEVICE_STATUS, 0, 0)))
4c7ee1
@@ -1015,7 +1021,7 @@ int dev_manager_snapshot_percent(struct dev_manager *dm,
4c7ee1
 	if (!(name = dm_build_dm_name(dm->mem, snap_lv->vg->name, snap_lv->name, NULL)))
4c7ee1
 		return_0;
4c7ee1
 
4c7ee1
-	if (!(dlid = build_dm_uuid(dm->mem, snap_lv->lvid.s, NULL)))
4c7ee1
+	if (!(dlid = build_dm_uuid(dm->mem, snap_lv, NULL)))
4c7ee1
 		return_0;
4c7ee1
 
4c7ee1
 	/*
4c7ee1
@@ -1047,7 +1053,7 @@ int dev_manager_mirror_percent(struct dev_manager *dm,
4c7ee1
 	if (!(name = dm_build_dm_name(dm->mem, lv->vg->name, lv->name, layer)))
4c7ee1
 		return_0;
4c7ee1
 
4c7ee1
-	if (!(dlid = build_dm_uuid(dm->mem, lv->lvid.s, layer))) {
4c7ee1
+	if (!(dlid = build_dm_uuid(dm->mem, lv, layer))) {
4c7ee1
 		log_error("dlid build failed for %s", lv->name);
4c7ee1
 		return 0;
4c7ee1
 	}
4c7ee1
@@ -1074,7 +1080,7 @@ int dev_manager_raid_status(struct dev_manager *dm,
4c7ee1
 	char *params = NULL;
4c7ee1
 	const char *layer = lv_layer(lv);
4c7ee1
 
4c7ee1
-	if (!(dlid = build_dm_uuid(dm->mem, lv->lvid.s, layer)))
4c7ee1
+	if (!(dlid = build_dm_uuid(dm->mem, lv, layer)))
4c7ee1
 		return_0;
4c7ee1
 
4c7ee1
 	log_debug_activation("Getting raid device status for %s.", lv->name);
4c7ee1
@@ -1138,7 +1144,7 @@ int dev_manager_raid_message(struct dev_manager *dm,
4c7ee1
 		return 0;
4c7ee1
 	}
4c7ee1
 
4c7ee1
-	if (!(dlid = build_dm_uuid(dm->mem, lv->lvid.s, layer)))
4c7ee1
+	if (!(dlid = build_dm_uuid(dm->mem, lv, layer)))
4c7ee1
 		return_0;
4c7ee1
 
4c7ee1
 	if (!(dmt = _setup_task(NULL, dlid, 0, DM_DEVICE_TARGET_MSG, 0, 0)))
4c7ee1
@@ -1173,7 +1179,7 @@ int dev_manager_cache_status(struct dev_manager *dm,
4c7ee1
 	char *params = NULL;
4c7ee1
 	const char *layer = lv_layer(lv);
4c7ee1
 
4c7ee1
-	if (!(dlid = build_dm_uuid(dm->mem, lv->lvid.s, layer)))
4c7ee1
+	if (!(dlid = build_dm_uuid(dm->mem, lv, layer)))
4c7ee1
 		return_0;
4c7ee1
 
4c7ee1
 	log_debug_activation("Getting cache device status for %s.", lv->name);
4c7ee1
@@ -1282,7 +1288,7 @@ int dev_manager_thin_pool_status(struct dev_manager *dm,
4c7ee1
 	int r = 0;
4c7ee1
 
4c7ee1
 	/* Build dlid for the thin pool layer */
4c7ee1
-	if (!(dlid = build_dm_uuid(dm->mem, lv->lvid.s, lv_layer(lv))))
4c7ee1
+	if (!(dlid = build_dm_uuid(dm->mem, lv, lv_layer(lv))))
4c7ee1
 		return_0;
4c7ee1
 
4c7ee1
 	log_debug_activation("Getting thin pool device status for %s.", lv->name);
4c7ee1
@@ -1328,7 +1334,7 @@ int dev_manager_thin_pool_percent(struct dev_manager *dm,
4c7ee1
 				      lv_layer(lv))))
4c7ee1
 		return_0;
4c7ee1
 
4c7ee1
-	if (!(dlid = build_dm_uuid(dm->mem, lv->lvid.s, lv_layer(lv))))
4c7ee1
+	if (!(dlid = build_dm_uuid(dm->mem, lv, lv_layer(lv))))
4c7ee1
 		return_0;
4c7ee1
 
4c7ee1
 	log_debug_activation("Getting device status percentage for %s", name);
4c7ee1
@@ -1351,7 +1357,7 @@ int dev_manager_thin_percent(struct dev_manager *dm,
4c7ee1
 	if (!(name = dm_build_dm_name(dm->mem, lv->vg->name, lv->name, layer)))
4c7ee1
 		return_0;
4c7ee1
 
4c7ee1
-	if (!(dlid = build_dm_uuid(dm->mem, lv->lvid.s, layer)))
4c7ee1
+	if (!(dlid = build_dm_uuid(dm->mem, lv, layer)))
4c7ee1
 		return_0;
4c7ee1
 
4c7ee1
 	log_debug_activation("Getting device status percentage for %s", name);
4c7ee1
@@ -1374,7 +1380,7 @@ int dev_manager_thin_device_id(struct dev_manager *dm,
4c7ee1
 	int r = 0;
4c7ee1
 
4c7ee1
 	/* Build dlid for the thin layer */
4c7ee1
-	if (!(dlid = build_dm_uuid(dm->mem, lv->lvid.s, lv_layer(lv))))
4c7ee1
+	if (!(dlid = build_dm_uuid(dm->mem, lv, lv_layer(lv))))
4c7ee1
 		return_0;
4c7ee1
 
4c7ee1
 	log_debug_activation("Getting device id for %s.", dlid);
4c7ee1
@@ -1575,7 +1581,7 @@ static int _add_dev_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
4c7ee1
 	if (!(name = dm_build_dm_name(dm->mem, lv->vg->name, lv->name, layer)))
4c7ee1
 		return_0;
4c7ee1
 
4c7ee1
-	if (!(dlid = build_dm_uuid(dm->mem, lv->lvid.s, layer)))
4c7ee1
+	if (!(dlid = build_dm_uuid(dm->mem, lv, layer)))
4c7ee1
 		return_0;
4c7ee1
 
4c7ee1
 	log_debug_activation("Getting device info for %s [%s]", name, dlid);
4c7ee1
@@ -1648,7 +1654,7 @@ static int _add_partial_replicator_to_dtree(struct dev_manager *dm,
4c7ee1
 	if (!_add_dev_to_dtree(dm, dtree, rlv, NULL))
4c7ee1
 		return_0;
4c7ee1
 
4c7ee1
-	if (!(uuid = build_dm_uuid(dm->mem, rlv->lvid.s, NULL)))
4c7ee1
+	if (!(uuid = build_dm_uuid(dm->mem, rlv, NULL)))
4c7ee1
 		return_0;
4c7ee1
 
4c7ee1
 	rep_node = dm_tree_find_node_by_uuid(dtree, uuid);
4c7ee1
@@ -1670,7 +1676,7 @@ static int _add_partial_replicator_to_dtree(struct dev_manager *dm,
4c7ee1
 				/* If replicator exists - try connect existing heads */
4c7ee1
 				if (rep_node) {
4c7ee1
 					uuid = build_dm_uuid(dm->mem,
4c7ee1
-							     rdev->replicator_dev->lv->lvid.s,
4c7ee1
+							     rdev->replicator_dev->lv,
4c7ee1
 							     NULL);
4c7ee1
 					if (!uuid)
4c7ee1
 						return_0;
4c7ee1
@@ -1790,7 +1796,9 @@ static int _thin_pool_register_callback(struct dev_manager *dm,
4c7ee1
 	struct thin_cb_data *data;
4c7ee1
 
4c7ee1
 	/* Skip metadata testing for unused pool. */
4c7ee1
-	if (!first_seg(lv)->transaction_id)
4c7ee1
+	if (!first_seg(lv)->transaction_id ||
4c7ee1
+	    ((first_seg(lv)->transaction_id == 1) &&
4c7ee1
+	     pool_has_message(first_seg(lv), NULL, 0)))
4c7ee1
 		return 1;
4c7ee1
 
4c7ee1
 	if (!(data = dm_pool_alloc(dm->mem, sizeof(*data)))) {
4c7ee1
@@ -1836,7 +1844,7 @@ static int _add_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
4c7ee1
 #if 0
4c7ee1
 		/* ? Use origin_only to avoid 'deep' thin pool suspend ? */
4c7ee1
 		/* FIXME Implement dm_tree_node_skip_childrens optimisation */
4c7ee1
-		if (!(uuid = build_dm_uuid(dm->mem, lv->lvid.s, lv_layer(lv))))
4c7ee1
+		if (!(uuid = build_dm_uuid(dm->mem, lv, lv_layer(lv))))
4c7ee1
 			return_0;
4c7ee1
 		if ((thin_node = dm_tree_find_node_by_uuid(dtree, uuid)))
4c7ee1
 			dm_tree_node_skip_childrens(thin_node, 1);
4c7ee1
@@ -1866,7 +1874,7 @@ static int _add_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
4c7ee1
 			/* Setup callback for non-activation partial tree */
4c7ee1
 			/* Activation gets own callback when needed */
4c7ee1
 			/* TODO: extend _cached_info() to return dnode */
4c7ee1
-			if (!(uuid = build_dm_uuid(dm->mem, lv->lvid.s, lv_layer(lv))))
4c7ee1
+			if (!(uuid = build_dm_uuid(dm->mem, lv, lv_layer(lv))))
4c7ee1
 				return_0;
4c7ee1
 			if ((thin_node = dm_tree_find_node_by_uuid(dtree, uuid)) &&
4c7ee1
 			    !_thin_pool_register_callback(dm, thin_node, lv))
4c7ee1
@@ -1977,7 +1985,7 @@ static char *_add_error_device(struct dev_manager *dm, struct dm_tree *dtree,
4c7ee1
 
4c7ee1
 	sprintf(errid, "missing_%d_%d", segno, s);
4c7ee1
 
4c7ee1
-	if (!(dlid = build_dm_uuid(dm->mem, seg->lv->lvid.s, errid)))
4c7ee1
+	if (!(dlid = build_dm_uuid(dm->mem, seg->lv, errid)))
4c7ee1
 		return_NULL;
4c7ee1
 
4c7ee1
 	if (!(name = dm_build_dm_name(dm->mem, seg->lv->vg->name,
4c7ee1
@@ -2085,18 +2093,18 @@ int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
4c7ee1
 					return_0;
4c7ee1
 				continue;
4c7ee1
 			}
4c7ee1
-			if (!(dlid = build_dm_uuid(dm->mem, seg_metalv(seg, s)->lvid.s, NULL)))
4c7ee1
+			if (!(dlid = build_dm_uuid(dm->mem, seg_metalv(seg, s), NULL)))
4c7ee1
 				return_0;
4c7ee1
 			if (!dm_tree_node_add_target_area(node, NULL, dlid, extent_size * seg_metale(seg, s)))
4c7ee1
 				return_0;
4c7ee1
 
4c7ee1
-			if (!(dlid = build_dm_uuid(dm->mem, seg_lv(seg, s)->lvid.s, NULL)))
4c7ee1
+			if (!(dlid = build_dm_uuid(dm->mem, seg_lv(seg, s), NULL)))
4c7ee1
 				return_0;
4c7ee1
 			if (!dm_tree_node_add_target_area(node, NULL, dlid, extent_size * seg_le(seg, s)))
4c7ee1
 				return_0;
4c7ee1
 		} else if (seg_type(seg, s) == AREA_LV) {
4c7ee1
 
4c7ee1
-			if (!(dlid = build_dm_uuid(dm->mem, seg_lv(seg, s)->lvid.s, NULL)))
4c7ee1
+			if (!(dlid = build_dm_uuid(dm->mem, seg_lv(seg, s), NULL)))
4c7ee1
 				return_0;
4c7ee1
 			if (!dm_tree_node_add_target_area(node, NULL, dlid, extent_size * seg_le(seg, s)))
4c7ee1
 				return_0;
4c7ee1
@@ -2125,7 +2133,7 @@ static int _add_layer_target_to_dtree(struct dev_manager *dm,
4c7ee1
 {
4c7ee1
 	const char *layer_dlid;
4c7ee1
 
4c7ee1
-	if (!(layer_dlid = build_dm_uuid(dm->mem, lv->lvid.s, lv_layer(lv))))
4c7ee1
+	if (!(layer_dlid = build_dm_uuid(dm->mem, lv, lv_layer(lv))))
4c7ee1
 		return_0;
4c7ee1
 
4c7ee1
 	/* Add linear mapping over layered LV */
4c7ee1
@@ -2144,7 +2152,7 @@ static int _add_origin_target_to_dtree(struct dev_manager *dm,
4c7ee1
 {
4c7ee1
 	const char *real_dlid;
4c7ee1
 
4c7ee1
-	if (!(real_dlid = build_dm_uuid(dm->mem, lv->lvid.s, "real")))
4c7ee1
+	if (!(real_dlid = build_dm_uuid(dm->mem, lv, "real")))
4c7ee1
 		return_0;
4c7ee1
 
4c7ee1
 	if (!dm_tree_node_add_snapshot_origin_target(dnode, lv->size, real_dlid))
4c7ee1
@@ -2165,13 +2173,13 @@ static int _add_snapshot_merge_target_to_dtree(struct dev_manager *dm,
4c7ee1
 		return 0;
4c7ee1
 	}
4c7ee1
 
4c7ee1
-	if (!(origin_dlid = build_dm_uuid(dm->mem, lv->lvid.s, "real")))
4c7ee1
+	if (!(origin_dlid = build_dm_uuid(dm->mem, lv, "real")))
4c7ee1
 		return_0;
4c7ee1
 
4c7ee1
-	if (!(cow_dlid = build_dm_uuid(dm->mem, merging_snap_seg->cow->lvid.s, "cow")))
4c7ee1
+	if (!(cow_dlid = build_dm_uuid(dm->mem, merging_snap_seg->cow, "cow")))
4c7ee1
 		return_0;
4c7ee1
 
4c7ee1
-	if (!(merge_dlid = build_dm_uuid(dm->mem, merging_snap_seg->cow->lvid.s, NULL)))
4c7ee1
+	if (!(merge_dlid = build_dm_uuid(dm->mem, merging_snap_seg->cow, NULL)))
4c7ee1
 		return_0;
4c7ee1
 
4c7ee1
 	if (!dm_tree_node_add_snapshot_merge_target(dnode, lv->size, origin_dlid,
4c7ee1
@@ -2197,10 +2205,10 @@ static int _add_snapshot_target_to_dtree(struct dev_manager *dm,
4c7ee1
 		return 0;
4c7ee1
 	}
4c7ee1
 
4c7ee1
-	if (!(origin_dlid = build_dm_uuid(dm->mem, snap_seg->origin->lvid.s, "real")))
4c7ee1
+	if (!(origin_dlid = build_dm_uuid(dm->mem, snap_seg->origin, "real")))
4c7ee1
 		return_0;
4c7ee1
 
4c7ee1
-	if (!(cow_dlid = build_dm_uuid(dm->mem, snap_seg->cow->lvid.s, "cow")))
4c7ee1
+	if (!(cow_dlid = build_dm_uuid(dm->mem, snap_seg->cow, "cow")))
4c7ee1
 		return_0;
4c7ee1
 
4c7ee1
 	size = (uint64_t) snap_seg->len * snap_seg->origin->vg->extent_size;
4c7ee1
@@ -2514,7 +2522,7 @@ static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
4c7ee1
 	if (!(name = dm_build_dm_name(dm->mem, lv->vg->name, lv->name, layer)))
4c7ee1
 		return_0;
4c7ee1
 
4c7ee1
-	if (!(dlid = build_dm_uuid(dm->mem, lv->lvid.s, layer)))
4c7ee1
+	if (!(dlid = build_dm_uuid(dm->mem, lv, layer)))
4c7ee1
 		return_0;
4c7ee1
 
4c7ee1
 	/* We've already processed this node if it already has a context ptr */
4c7ee1
@@ -2774,7 +2782,7 @@ static int _tree_action(struct dev_manager *dm, struct logical_volume *lv,
4c7ee1
 	/* Restore fs cookie */
4c7ee1
 	dm_tree_set_cookie(root, fs_get_cookie());
4c7ee1
 
4c7ee1
-	if (!(dlid = build_dm_uuid(dm->mem, lv->lvid.s, laopts->origin_only ? lv_layer(lv) : NULL)))
4c7ee1
+	if (!(dlid = build_dm_uuid(dm->mem, lv, laopts->origin_only ? lv_layer(lv) : NULL)))
4c7ee1
 		goto_out;
4c7ee1
 
4c7ee1
 	/* Only process nodes with uuid of "LVM-" plus VG id. */
4c7ee1
diff --git a/lib/cache_segtype/cache.c b/lib/cache_segtype/cache.c
4c7ee1
index 57c7a5c..df521c4 100644
4c7ee1
--- a/lib/cache_segtype/cache.c
4c7ee1
+++ b/lib/cache_segtype/cache.c
4c7ee1
@@ -360,13 +360,13 @@ static int _cache_add_target_line(struct dev_manager *dm,
4c7ee1
 	struct lv_segment *cache_pool_seg = first_seg(seg->pool_lv);
4c7ee1
 	char *metadata_uuid, *data_uuid, *origin_uuid;
4c7ee1
 
4c7ee1
-	if (!(metadata_uuid = build_dm_uuid(mem, cache_pool_seg->metadata_lv->lvid.s, NULL)))
4c7ee1
+	if (!(metadata_uuid = build_dm_uuid(mem, cache_pool_seg->metadata_lv, NULL)))
4c7ee1
 		return_0;
4c7ee1
 
4c7ee1
-	if (!(data_uuid = build_dm_uuid(mem, seg_lv(cache_pool_seg, 0)->lvid.s, NULL)))
4c7ee1
+	if (!(data_uuid = build_dm_uuid(mem, seg_lv(cache_pool_seg, 0), NULL)))
4c7ee1
 		return_0;
4c7ee1
 
4c7ee1
-	if (!(origin_uuid = build_dm_uuid(mem, seg_lv(seg, 0)->lvid.s, NULL)))
4c7ee1
+	if (!(origin_uuid = build_dm_uuid(mem, seg_lv(seg, 0), NULL)))
4c7ee1
 		return_0;
4c7ee1
 
4c7ee1
 	if (!dm_tree_node_add_cache_target(node, len,
4c7ee1
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
4c7ee1
index 57ce2d9..abbcbf8 100644
4c7ee1
--- a/lib/metadata/lv_manip.c
4c7ee1
+++ b/lib/metadata/lv_manip.c
4c7ee1
@@ -6291,19 +6291,6 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
4c7ee1
 	if (lv_activation_skip(lv, lp->activate, lp->activation_skip & ACTIVATION_SKIP_IGNORE))
4c7ee1
 		lp->activate = CHANGE_AN;
4c7ee1
 
4c7ee1
-	/*
4c7ee1
-	 * For thin pools - deactivate when inactive pool is requested or
4c7ee1
-	 * for cluster give-up local lock and take proper exlusive lock
4c7ee1
-	 */
4c7ee1
-	if (lv_is_thin_pool(lv) &&
4c7ee1
-	    (!is_change_activating(lp->activate) ||
4c7ee1
-	     vg_is_clustered(lv->vg)) &&
4c7ee1
-	    /* Deactivates cleared metadata LV */
4c7ee1
-	    !deactivate_lv(lv->vg->cmd, lv)) {
4c7ee1
-		stack;
4c7ee1
-		goto deactivate_failed;
4c7ee1
-	}
4c7ee1
-
4c7ee1
 	/* store vg on disk(s) */
4c7ee1
 	if (!vg_write(vg) || !vg_commit(vg))
4c7ee1
 		return_NULL;
4c7ee1
@@ -6322,50 +6309,7 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
4c7ee1
 	if (lp->temporary)
4c7ee1
 		lv->status |= LV_TEMPORARY;
4c7ee1
 
4c7ee1
-	if (lv_is_cache_type(lv)) {
4c7ee1
-		if (!lv_is_active(lv)) {
4c7ee1
-			if (!activate_lv_excl(cmd, lv)) {
4c7ee1
-				log_error("Failed to activate pool %s.",
4c7ee1
-					  lv->name);
4c7ee1
-				goto deactivate_and_revert_new_lv;
4c7ee1
-			}
4c7ee1
-		} else {
4c7ee1
-			if (!suspend_lv(cmd, lv)) {
4c7ee1
-				log_error("Failed to suspend pool %s.",
4c7ee1
-					  lv->name);
4c7ee1
-				goto deactivate_and_revert_new_lv;
4c7ee1
-			}
4c7ee1
-			if (!resume_lv(cmd, lv)) {
4c7ee1
-				log_error("Failed to resume pool %s.", lv->name);
4c7ee1
-				goto deactivate_and_revert_new_lv;
4c7ee1
-			}
4c7ee1
-		}
4c7ee1
-	} else if (lv_is_thin_pool(lv)) {
4c7ee1
-		if (is_change_activating(lp->activate)) {
4c7ee1
-			if (vg_is_clustered(lv->vg)) {
4c7ee1
-				if (!activate_lv_excl(cmd, lv)) {
4c7ee1
-					log_error("Failed to activate pool %s.", lv->name);
4c7ee1
-					goto deactivate_and_revert_new_lv;
4c7ee1
-				}
4c7ee1
-			} else {
4c7ee1
-				/*
4c7ee1
-				 * Suspend cleared plain metadata LV
4c7ee1
-				 * but now already commited as pool LV
4c7ee1
-				 * and resume it as a pool LV.
4c7ee1
-				 *
4c7ee1
-				 * This trick avoids collision with udev watch rule.
4c7ee1
-				 */
4c7ee1
-				if (!suspend_lv(cmd, lv)) {
4c7ee1
-					log_error("Failed to suspend pool %s.", lv->name);
4c7ee1
-					goto deactivate_and_revert_new_lv;
4c7ee1
-				}
4c7ee1
-				if (!resume_lv(cmd, lv)) {
4c7ee1
-					log_error("Failed to resume pool %s.", lv->name);
4c7ee1
-					goto deactivate_and_revert_new_lv;
4c7ee1
-				}
4c7ee1
-			}
4c7ee1
-		}
4c7ee1
-	} else if (lv_is_thin_volume(lv)) {
4c7ee1
+	if (lv_is_thin_volume(lv)) {
4c7ee1
 		/* For snapshot, suspend active thin origin first */
4c7ee1
 		if (org && lv_is_active(org) && lv_is_thin_volume(org)) {
4c7ee1
 			if (!suspend_lv_origin(cmd, org)) {
4c7ee1
@@ -6403,7 +6347,9 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
4c7ee1
 		}
4c7ee1
 	} else if (!lv_active_change(cmd, lv, lp->activate)) {
4c7ee1
 		log_error("Failed to activate new LV.");
4c7ee1
-		if (lp->zero || lp->wipe_signatures)
4c7ee1
+		if (lp->zero || lp->wipe_signatures ||
4c7ee1
+		    lv_is_thin_pool(lv) ||
4c7ee1
+		    lv_is_cache_type(lv))
4c7ee1
 			goto deactivate_and_revert_new_lv;
4c7ee1
 		return NULL;
4c7ee1
 	}
4c7ee1
@@ -6497,7 +6443,6 @@ out:
4c7ee1
 
4c7ee1
 deactivate_and_revert_new_lv:
4c7ee1
 	if (!deactivate_lv(cmd, lv)) {
4c7ee1
-deactivate_failed:
4c7ee1
 		log_error("Unable to deactivate failed new LV \"%s/%s\". "
4c7ee1
 			  "Manual intervention required.", lv->vg->name, lv->name);
4c7ee1
 		return NULL;
4c7ee1
diff --git a/lib/metadata/pool_manip.c b/lib/metadata/pool_manip.c
4c7ee1
index 0c7bf96..f414f3f 100644
4c7ee1
--- a/lib/metadata/pool_manip.c
4c7ee1
+++ b/lib/metadata/pool_manip.c
4c7ee1
@@ -267,6 +267,9 @@ int create_pool(struct logical_volume *pool_lv,
4c7ee1
 			goto bad;
4c7ee1
 		}
4c7ee1
 		pool_lv->status &= ~LV_TEMPORARY;
4c7ee1
+		/* Deactivates cleared metadata LV */
4c7ee1
+		if (!deactivate_lv_local(pool_lv->vg->cmd, pool_lv))
4c7ee1
+			goto_bad;
4c7ee1
 	}
4c7ee1
 
4c7ee1
 	if (dm_snprintf(name, sizeof(name), "%s_%s", pool_lv->name,
4c7ee1
diff --git a/lib/metadata/thin_manip.c b/lib/metadata/thin_manip.c
4c7ee1
index b28f5a0..b94a4a8 100644
4c7ee1
--- a/lib/metadata/thin_manip.c
4c7ee1
+++ b/lib/metadata/thin_manip.c
4c7ee1
@@ -160,7 +160,7 @@ int pool_has_message(const struct lv_segment *seg,
4c7ee1
 	}
4c7ee1
 
4c7ee1
 	if (!lv && !device_id)
4c7ee1
-		return dm_list_empty(&seg->thin_messages);
4c7ee1
+		return !dm_list_empty(&seg->thin_messages);
4c7ee1
 
4c7ee1
 	dm_list_iterate_items(tmsg, &seg->thin_messages) {
4c7ee1
 		switch (tmsg->type) {
4c7ee1
diff --git a/lib/mirror/mirrored.c b/lib/mirror/mirrored.c
4c7ee1
index 5088173..e35a372 100644
4c7ee1
--- a/lib/mirror/mirrored.c
4c7ee1
+++ b/lib/mirror/mirrored.c
4c7ee1
@@ -356,14 +356,14 @@ static int _add_log(struct dm_pool *mem, struct lv_segment *seg,
4c7ee1
 
4c7ee1
 	if (seg->log_lv) {
4c7ee1
 		/* If disk log, use its UUID */
4c7ee1
-		if (!(log_dlid = build_dm_uuid(mem, seg->log_lv->lvid.s, NULL))) {
4c7ee1
+		if (!(log_dlid = build_dm_uuid(mem, seg->log_lv, NULL))) {
4c7ee1
 			log_error("Failed to build uuid for log LV %s.",
4c7ee1
 				  seg->log_lv->name);
4c7ee1
 			return 0;
4c7ee1
 		}
4c7ee1
 	} else {
4c7ee1
 		/* If core log, use mirror's UUID and set DM_CORELOG flag */
4c7ee1
-		if (!(log_dlid = build_dm_uuid(mem, seg->lv->lvid.s, NULL))) {
4c7ee1
+		if (!(log_dlid = build_dm_uuid(mem, seg->lv, NULL))) {
4c7ee1
 			log_error("Failed to build uuid for mirror LV %s.",
4c7ee1
 				  seg->lv->name);
4c7ee1
 			return 0;
4c7ee1
diff --git a/lib/misc/lvm-string.c b/lib/misc/lvm-string.c
4c7ee1
index 380fe81..b96b5cc 100644
4c7ee1
--- a/lib/misc/lvm-string.c
4c7ee1
+++ b/lib/misc/lvm-string.c
4c7ee1
@@ -15,6 +15,7 @@
4c7ee1
 
4c7ee1
 #include "lib.h"
4c7ee1
 #include "lvm-string.h"
4c7ee1
+#include "metadata-exported.h"
4c7ee1
 
4c7ee1
 #include <ctype.h>
4c7ee1
 
4c7ee1
@@ -160,8 +161,13 @@ int is_reserved_lvname(const char *name)
4c7ee1
 	return rc;
4c7ee1
 }
4c7ee1
 
4c7ee1
-char *build_dm_uuid(struct dm_pool *mem, const char *lvid,
4c7ee1
+char *build_dm_uuid(struct dm_pool *mem, const struct logical_volume *lv,
4c7ee1
 		    const char *layer)
4c7ee1
 {
4c7ee1
+	const char *lvid = lv->lvid.s;
4c7ee1
+
4c7ee1
+	if (!layer && lv_is_thin_pool(lv))
4c7ee1
+		layer = "pool";
4c7ee1
+
4c7ee1
 	return dm_build_dm_uuid(mem, UUID_PREFIX, lvid, layer);
4c7ee1
 }
4c7ee1
diff --git a/lib/misc/lvm-string.h b/lib/misc/lvm-string.h
4c7ee1
index 13aacf8..82ebb12 100644
4c7ee1
--- a/lib/misc/lvm-string.h
4c7ee1
+++ b/lib/misc/lvm-string.h
4c7ee1
@@ -23,6 +23,7 @@
4c7ee1
 #define UUID_PREFIX "LVM-"
4c7ee1
 
4c7ee1
 struct pool;
4c7ee1
+struct logical_volume;
4c7ee1
 
4c7ee1
 typedef enum name_error { NAME_VALID = 0, NAME_INVALID_EMPTY = -1,
4c7ee1
 					NAME_INVALID_HYPEN = -2, NAME_INVALID_DOTS = -3,
4c7ee1
@@ -32,7 +33,7 @@ typedef enum name_error { NAME_VALID = 0, NAME_INVALID_EMPTY = -1,
4c7ee1
 int emit_to_buffer(char **buffer, size_t *size, const char *fmt, ...)
4c7ee1
   __attribute__ ((format(printf, 3, 4)));
4c7ee1
 
4c7ee1
-char *build_dm_uuid(struct dm_pool *mem, const char *lvid,
4c7ee1
+char *build_dm_uuid(struct dm_pool *mem, const struct logical_volume *lvid,
4c7ee1
 		    const char *layer);
4c7ee1
 
4c7ee1
 int validate_name(const char *n);
4c7ee1
diff --git a/lib/thin/thin.c b/lib/thin/thin.c
4c7ee1
index 7c989f8..494fa92 100644
4c7ee1
--- a/lib/thin/thin.c
4c7ee1
+++ b/lib/thin/thin.c
4c7ee1
@@ -277,13 +277,13 @@ static int _thin_pool_add_target_line(struct dev_manager *dm,
4c7ee1
 		return 0;
4c7ee1
 	}
4c7ee1
 
4c7ee1
-	if (!(metadata_dlid = build_dm_uuid(mem, seg->metadata_lv->lvid.s, NULL))) {
4c7ee1
+	if (!(metadata_dlid = build_dm_uuid(mem, seg->metadata_lv, NULL))) {
4c7ee1
 		log_error("Failed to build uuid for metadata LV %s.",
4c7ee1
 			  seg->metadata_lv->name);
4c7ee1
 		return 0;
4c7ee1
 	}
4c7ee1
 
4c7ee1
-	if (!(pool_dlid = build_dm_uuid(mem, seg_lv(seg, 0)->lvid.s, NULL))) {
4c7ee1
+	if (!(pool_dlid = build_dm_uuid(mem, seg_lv(seg, 0), NULL))) {
4c7ee1
 		log_error("Failed to build uuid for pool LV %s.",
4c7ee1
 			  seg_lv(seg, 0)->name);
4c7ee1
 		return 0;
4c7ee1
@@ -535,7 +535,7 @@ static int _thin_add_target_line(struct dev_manager *dm,
4c7ee1
 			  seg->lv->name);
4c7ee1
 		return 0;
4c7ee1
 	}
4c7ee1
-	if (!(pool_dlid = build_dm_uuid(mem, seg->pool_lv->lvid.s, lv_layer(seg->pool_lv)))) {
4c7ee1
+	if (!(pool_dlid = build_dm_uuid(mem, seg->pool_lv, lv_layer(seg->pool_lv)))) {
4c7ee1
 		log_error("Failed to build uuid for pool LV %s.",
4c7ee1
 			  seg->pool_lv->name);
4c7ee1
 		return 0;
4c7ee1
@@ -573,7 +573,7 @@ static int _thin_add_target_line(struct dev_manager *dm,
4c7ee1
 				return 0;
4c7ee1
 			}
4c7ee1
 		}
4c7ee1
-		if (!(external_dlid = build_dm_uuid(mem, seg->external_lv->lvid.s,
4c7ee1
+		if (!(external_dlid = build_dm_uuid(mem, seg->external_lv,
4c7ee1
 						    lv_layer(seg->external_lv)))) {
4c7ee1
 			log_error("Failed to build uuid for external origin LV %s.",
4c7ee1
 				  seg->external_lv->name);
4c7ee1
diff --git a/test/shell/lvcreate-thin.sh b/test/shell/lvcreate-thin.sh
4c7ee1
index a2811d2..ab27dfb 100644
4c7ee1
--- a/test/shell/lvcreate-thin.sh
4c7ee1
+++ b/test/shell/lvcreate-thin.sh
4c7ee1
@@ -173,7 +173,9 @@ not lvcreate --chunksize 32 -l1 -T $vg/pool1
4c7ee1
 # Too large chunk size (max is 1GB)
4c7ee1
 not lvcreate -L4M --chunksize 2G -T $vg/pool1
4c7ee1
 
4c7ee1
-lvcreate -L4M -V2G --name lv1 -T $vg/pool1
4c7ee1
+# Test creation of inactive pool
4c7ee1
+lvcreate -an -L4M -T $vg/pool1
4c7ee1
+lvcreate -V2G --name lv1 -T $vg/pool1
4c7ee1
 # Origin name is not accepted
4c7ee1
 not lvcreate -s $vg/lv1 -L4M -V2G --name $vg/lv4
4c7ee1
 
4c7ee1
diff --git a/test/shell/pvremove-thin.sh b/test/shell/pvremove-thin.sh
4c7ee1
new file mode 100644
4c7ee1
index 0000000..03e6ca3
4c7ee1
--- /dev/null
4c7ee1
+++ b/test/shell/pvremove-thin.sh
4c7ee1
@@ -0,0 +1,28 @@
4c7ee1
+#!/bin/sh
4c7ee1
+# Copyright (C) 2014 Red Hat, Inc. All rights reserved.
4c7ee1
+#
4c7ee1
+# This copyrighted material is made available to anyone wishing to use,
4c7ee1
+# modify, copy, or redistribute it subject to the terms and conditions
4c7ee1
+# of the GNU General Public License v.2.
4c7ee1
+#
4c7ee1
+# You should have received a copy of the GNU General Public License
4c7ee1
+# along with this program; if not, write to the Free Software Foundation,
4c7ee1
+# Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
4c7ee1
+
4c7ee1
+# Checks we are not reading our own devices
4c7ee1
+# https://bugzilla.redhat.com/show_bug.cgi?id=1064374
4c7ee1
+
4c7ee1
+. lib/test
4c7ee1
+
4c7ee1
+aux prepare_vg
4c7ee1
+
4c7ee1
+aux target_at_least dm-thin-pool 1 8 0 || skip
4c7ee1
+
4c7ee1
+aux extend_filter_LVMTEST
4c7ee1
+
4c7ee1
+lvcreate -L10 -V10 -n $lv1 -T $vg/pool1
4c7ee1
+
4c7ee1
+pvcreate "$DM_DEV_DIR/$vg/$lv1"
4c7ee1
+pvremove "$DM_DEV_DIR/$vg/$lv1"
4c7ee1
+
4c7ee1
+vgremove -ff $vg