Gitweb:
http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=13c07c685ade35...
Commit: 13c07c685ade35192348a6b60a6c19077976b089
Parent: cd3345a5b06ee1626101619f94b346a77295ca03
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Sep 22 14:15:13 2014 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Wed Sep 24 10:53:44 2014 +0200
thin and cache: improve conversion validation
More validations before any thin or cache related conversion begins.
We allow to use and stack:
pool data: cache or raid
pool metadata: raid
pool: linear, striped
cache: linear, striped, raid
thin(extorig): linear, origin, cow, virtual, thin
---
tools/lvconvert.c | 145 +++++++++++++++++++++++++++++------------------------
1 files changed, 79 insertions(+), 66 deletions(-)
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 62e560c..57975d1 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -2662,30 +2662,48 @@ static int _lvconvert_pool(struct cmd_context *cmd,
return 0;
}
- /*
- * Only linear, striped and raid supported.
- * FIXME Tidy up all these type restrictions.
- */
- if (!lv_is_pool(pool_lv) &&
- (lv_is_external_origin(pool_lv) || lv_is_origin(pool_lv) || lv_is_thin_type(pool_lv)
||
- lv_is_mirror_type(pool_lv) || lv_is_cache_type(pool_lv) || lv_is_virtual(pool_lv)
||
- lv_is_cache_origin(pool_lv) || lv_is_merging_origin(pool_lv) ||
lv_is_merging_cow(pool_lv))) {
- log_error("Pool data LV %s is of an unsupported type.",
display_lvname(pool_lv));
+ if (!lv_is_visible(pool_lv)) {
+ log_error("Can't convert internal LV %s.", display_lvname(pool_lv));
+ return 0;
+ }
+
+ if (lv_is_locked(pool_lv)) {
+ log_error("Can't convert locked LV %s.", display_lvname(pool_lv));
return 0;
}
- if (arg_is_set(cmd, cachepool_ARG) && lv_is_thin_pool(pool_lv)) {
- log_error("--cachepool requires a cache pool. %s is a thin pool.",
+ if (lv_is_thin_pool(pool_lv) && (segtype_is_cache_pool(lp->segtype) ||
lp->cache)) {
+ log_error("Cannot convert thin pool volume %s as cache pool data volume.",
display_lvname(pool_lv));
return 0;
}
- if (arg_is_set(cmd, thinpool_ARG) && lv_is_cache_pool(pool_lv)) {
- log_error("--thinpool requires a thin pool. %s is a cache pool.",
+ if (lv_is_cache_pool(pool_lv) && (segtype_is_thin_pool(lp->segtype) ||
lp->thin)) {
+ log_error("Cannot convert cache pool %s as thin pool data volume.",
display_lvname(pool_lv));
return 0;
}
+ if (lv_is_mirror(pool_lv)) {
+ log_error("Mirror logical volumes cannot be used as pools.");
+ log_print_unless_silent("Try \"raid1\" segment type instead.");
+ return 0;
+ }
+
+ /*
+ * Only linear, striped and raid supported.
+ * FIXME Tidy up all these type restrictions.
+ */
+ if (!lv_is_pool(pool_lv) &&
+ (lv_is_thin_type(pool_lv) ||
+ lv_is_cow(pool_lv) || lv_is_merging_cow(pool_lv) ||
+ lv_is_origin(pool_lv) ||lv_is_merging_origin(pool_lv) ||
+ lv_is_external_origin(pool_lv) ||
+ lv_is_virtual(pool_lv))) {
+ log_error("Pool data LV %s is of an unsupported type.",
display_lvname(pool_lv));
+ return 0;
+ }
+
if (lp->pool_metadata_lv_name) {
if (!(lp->pool_metadata_lv = find_lv(vg, lp->pool_metadata_lv_name))) {
log_error("Unknown pool metadata LV %s.", lp->pool_metadata_lv_name);
@@ -2694,16 +2712,15 @@ static int _lvconvert_pool(struct cmd_context *cmd,
lp->pool_metadata_size = lp->pool_metadata_lv->size;
metadata_lv = lp->pool_metadata_lv;
- if (!lv_is_visible(metadata_lv)) {
- log_error("Can't convert internal LV %s.",
+ if (metadata_lv == pool_lv) {
+ log_error("Can't use same LV for pool data and metadata LV %s.",
display_lvname(metadata_lv));
return 0;
}
- if (lv_is_mirror(metadata_lv)) {
- log_error("Mirror logical volumes cannot be used "
- "for pool metadata.");
- log_error("Try \"raid1\" segment type instead.");
+ if (!lv_is_visible(metadata_lv)) {
+ log_error("Can't convert internal LV %s.",
+ display_lvname(metadata_lv));
return 0;
}
@@ -2713,24 +2730,19 @@ static int _lvconvert_pool(struct cmd_context *cmd,
return 0;
}
- if (metadata_lv == pool_lv) {
- log_error("Can't use same LV for pool data and metadata LV %s.",
- display_lvname(metadata_lv));
- return 0;
- }
-
- if (lv_is_thin_type(metadata_lv) ||
- lv_is_cache_type(metadata_lv)) {
- log_error("Can't use thin or cache type LV %s for pool metadata.",
- display_lvname(metadata_lv));
+ if (lv_is_mirror(metadata_lv)) {
+ log_error("Mirror logical volumes cannot be used for pool metadata.");
+ log_print_unless_silent("Try \"raid1\" segment type instead.");
return 0;
}
/* FIXME Tidy up all these type restrictions. */
- if (lv_is_external_origin(metadata_lv) || lv_is_virtual(metadata_lv) ||
- lv_is_origin(metadata_lv) || lv_is_thin_origin(metadata_lv, NULL) ||
- lv_is_cache_origin(metadata_lv) || lv_is_cow(metadata_lv) ||
- lv_is_merging_origin(metadata_lv) || lv_is_merging_cow(metadata_lv)) {
+ if (lv_is_cache_type(metadata_lv) ||
+ lv_is_thin_type(metadata_lv) ||
+ lv_is_cow(metadata_lv) || lv_is_merging_cow(metadata_lv) ||
+ lv_is_origin(metadata_lv) || lv_is_merging_origin(metadata_lv) ||
+ lv_is_external_origin(metadata_lv) ||
+ lv_is_virtual(metadata_lv)) {
log_error("Pool metadata LV %s is of an unsupported type.",
display_lvname(metadata_lv));
return 0;
@@ -2748,39 +2760,21 @@ static int _lvconvert_pool(struct cmd_context *cmd,
}
}
- if (!lv_is_visible(pool_lv)) {
- log_error("Can't convert internal LV %s.", display_lvname(pool_lv));
- return 0;
- }
-
- if (lv_is_mirror(pool_lv)) {
- log_error("Mirror logical volumes cannot be used as pools.\n"
- "Try \"raid1\" segment type instead.");
- return 0;
- }
-
- if ((dm_snprintf(metadata_name, sizeof(metadata_name), "%s%s",
- pool_lv->name,
- (segtype_is_cache_pool(lp->segtype)) ?
- "_cmeta" : "_tmeta") < 0) ||
- (dm_snprintf(data_name, sizeof(data_name), "%s%s",
- pool_lv->name,
- (segtype_is_cache_pool(lp->segtype)) ?
- "_cdata" : "_tdata") < 0)) {
- log_error("Failed to create internal lv names, "
- "pool name is too long.");
- return 0;
- }
-
if (lv_is_pool(pool_lv)) {
lp->pool_data_lv = pool_lv;
if (!metadata_lv) {
if (arg_from_list_is_set(cmd, "is invalid with existing pool",
- cachemode_ARG,chunksize_ARG, discards_ARG,
+ cachemode_ARG, chunksize_ARG, discards_ARG,
zero_ARG, poolmetadatasize_ARG, -1))
return_0;
- return 1;
+
+ if (lp->thin || lp->cache)
+ /* already pool, can continue converting volume */
+ return 1;
+
+ log_error("LV %s is already pool.", display_lvname(pool_lv));
+ return 0;
}
if (lp->thin || lp->cache) {
@@ -2841,10 +2835,6 @@ static int _lvconvert_pool(struct cmd_context *cmd,
log_error("Conversion aborted.");
return 0;
}
- } else if (lv_is_thin_type(pool_lv)) {
- log_error("Can't use thin type logical volume %s for thin pool data.",
- display_lvname(pool_lv));
- return 0;
} else {
log_warn("WARNING: Converting logical volume %s%s%s to pool's data%s.",
display_lvname(pool_lv),
@@ -2869,6 +2859,19 @@ static int _lvconvert_pool(struct cmd_context *cmd,
/* Allow to have only thinpool active and restore it's active state */
activate_pool = lv_is_active(pool_lv);
+ if ((dm_snprintf(metadata_name, sizeof(metadata_name), "%s%s",
+ pool_lv->name,
+ (segtype_is_cache_pool(lp->segtype)) ?
+ "_cmeta" : "_tmeta") < 0) ||
+ (dm_snprintf(data_name, sizeof(data_name), "%s%s",
+ pool_lv->name,
+ (segtype_is_cache_pool(lp->segtype)) ?
+ "_cdata" : "_tdata") < 0)) {
+ log_error("Failed to create internal lv names, "
+ "pool name is too long.");
+ return 0;
+ }
+
if (!metadata_lv) {
if (!_lvconvert_update_pool_params(pool_lv, lp))
return_0;
@@ -3068,13 +3071,23 @@ static int _lvconvert_cache(struct cmd_context *cmd,
return 0;
}
+ /* We support conversion of _tdata */
+ if (!lv_is_visible(origin) && !lv_is_thin_pool_data(origin)) {
+ log_error("Can't convert internal LV %s.", display_lvname(origin));
+ return 0;
+ }
+
/*
* Only linear, striped or raid supported.
* FIXME Tidy up all these type restrictions.
*/
- if (lv_is_external_origin(origin) || lv_is_origin(origin) || lv_is_thin_type(origin) ||
- lv_is_mirror_type(origin) || lv_is_cache_origin(origin) || lv_is_virtual(origin) ||
- lv_is_cow(origin) || lv_is_merging_origin(origin) || lv_is_merging_cow(origin)) {
+ if (lv_is_cache_origin(origin) ||
+ lv_is_mirror_type(origin) ||
+ lv_is_thin_volume(origin) || lv_is_thin_pool_metadata(origin) ||
+ lv_is_origin(origin) || lv_is_merging_origin(origin) ||
+ lv_is_cow(origin) || lv_is_merging_cow(origin) ||
+ lv_is_external_origin(origin) ||
+ lv_is_virtual(origin)) {
log_error("Cache is not supported with origin LV %s type.",
display_lvname(origin));
return 0;