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