|
|
b83e05 |
WHATS_NEW | 1 +
|
|
|
b83e05 |
tools/lvconvert.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++-----
|
|
|
b83e05 |
2 files changed, 48 insertions(+), 5 deletions(-)
|
|
|
b83e05 |
|
|
|
b83e05 |
diff --git a/WHATS_NEW b/WHATS_NEW
|
|
|
b83e05 |
index 399864d..d1f4530 100644
|
|
|
b83e05 |
--- a/WHATS_NEW
|
|
|
b83e05 |
+++ b/WHATS_NEW
|
|
|
b83e05 |
@@ -2,6 +2,7 @@ Version 2.02.187 -
|
|
|
b83e05 |
===================================
|
|
|
b83e05 |
Prevent creating VGs with PVs with different logical block sizes.
|
|
|
b83e05 |
Pvmove runs in exlusively activating mode for exclusively active LVs.
|
|
|
b83e05 |
+ Enhance validation for thin and cache pool conversion and swapping.
|
|
|
b83e05 |
|
|
|
b83e05 |
Version 2.02.186 - 27th August 2019
|
|
|
b83e05 |
===================================
|
|
|
b83e05 |
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
|
|
|
b83e05 |
index e66f063..799e746 100644
|
|
|
b83e05 |
--- a/tools/lvconvert.c
|
|
|
b83e05 |
+++ b/tools/lvconvert.c
|
|
|
b83e05 |
@@ -4309,24 +4309,66 @@ static int _lvconvert_to_pool_or_swap_metadata_single(struct cmd_context *cmd,
|
|
|
b83e05 |
struct dm_list *use_pvh = NULL;
|
|
|
b83e05 |
int to_thinpool = 0;
|
|
|
b83e05 |
int to_cachepool = 0;
|
|
|
b83e05 |
+ int lvt_enum = get_lvt_enum(lv);
|
|
|
b83e05 |
+ struct lv_type *lvtype;
|
|
|
b83e05 |
|
|
|
b83e05 |
switch (cmd->command->command_enum) {
|
|
|
b83e05 |
case lvconvert_to_thinpool_or_swap_metadata_CMD:
|
|
|
b83e05 |
+ if (lv_is_cache(lv))
|
|
|
b83e05 |
+ /* For cached LV check the cache origin LV type */
|
|
|
b83e05 |
+ lvt_enum = get_lvt_enum(seg_lv(first_seg(lv), 0));
|
|
|
b83e05 |
to_thinpool = 1;
|
|
|
b83e05 |
break;
|
|
|
b83e05 |
case lvconvert_to_cachepool_or_swap_metadata_CMD:
|
|
|
b83e05 |
+ if (lv_is_cache(lv))
|
|
|
b83e05 |
+ goto_bad; /* Cache over cache is not supported */
|
|
|
b83e05 |
to_cachepool = 1;
|
|
|
b83e05 |
break;
|
|
|
b83e05 |
default:
|
|
|
b83e05 |
- log_error(INTERNAL_ERROR "Invalid lvconvert pool command");
|
|
|
b83e05 |
- return 0;
|
|
|
b83e05 |
- };
|
|
|
b83e05 |
+ log_error(INTERNAL_ERROR "Invalid lvconvert pool command.");
|
|
|
b83e05 |
+ return ECMD_FAILED;
|
|
|
b83e05 |
+ }
|
|
|
b83e05 |
+
|
|
|
b83e05 |
+ switch (lvt_enum) {
|
|
|
b83e05 |
+ case thinpool_LVT:
|
|
|
b83e05 |
+ if (!to_thinpool)
|
|
|
b83e05 |
+ goto_bad; /* can't accept cache-pool */
|
|
|
b83e05 |
+ break; /* swap thin-pool */
|
|
|
b83e05 |
+ case cachepool_LVT:
|
|
|
b83e05 |
+ if (!to_cachepool)
|
|
|
b83e05 |
+ goto_bad; /* can't accept thin-pool */
|
|
|
b83e05 |
+ break; /* swap cache-pool */
|
|
|
b83e05 |
+ case linear_LVT:
|
|
|
b83e05 |
+ case raid_LVT:
|
|
|
b83e05 |
+ case striped_LVT:
|
|
|
b83e05 |
+ case zero_LVT:
|
|
|
b83e05 |
+ break;
|
|
|
b83e05 |
+ default:
|
|
|
b83e05 |
+bad:
|
|
|
b83e05 |
+ lvtype = get_lv_type(lvt_enum);
|
|
|
b83e05 |
+ log_error("LV %s with type %s cannot be used as a %s pool LV.",
|
|
|
b83e05 |
+ display_lvname(lv), lvtype ? lvtype->name : "unknown",
|
|
|
b83e05 |
+ to_thinpool ? "thin" : "cache");
|
|
|
b83e05 |
+ return ECMD_FAILED;
|
|
|
b83e05 |
+ }
|
|
|
b83e05 |
|
|
|
b83e05 |
if (lv_is_origin(lv)) {
|
|
|
b83e05 |
log_error("Cannot convert logical volume %s under snapshot.",
|
|
|
b83e05 |
display_lvname(lv));
|
|
|
b83e05 |
- return 0;
|
|
|
b83e05 |
- };
|
|
|
b83e05 |
+ return ECMD_FAILED;
|
|
|
b83e05 |
+ }
|
|
|
b83e05 |
+
|
|
|
b83e05 |
+ if (!lv_is_visible(lv)) {
|
|
|
b83e05 |
+ log_error("Can't convert internal LV %s.",
|
|
|
b83e05 |
+ display_lvname(lv));
|
|
|
b83e05 |
+ return ECMD_FAILED;
|
|
|
b83e05 |
+ }
|
|
|
b83e05 |
+
|
|
|
b83e05 |
+ if (lv_is_locked(lv)) {
|
|
|
b83e05 |
+ log_error("Can't convert locked LV %s.",
|
|
|
b83e05 |
+ display_lvname(lv));
|
|
|
b83e05 |
+ return ECMD_FAILED;
|
|
|
b83e05 |
+ }
|
|
|
b83e05 |
|
|
|
b83e05 |
if (cmd->position_argc > 1) {
|
|
|
b83e05 |
/* First pos arg is required LV, remaining are optional PVs. */
|