]> sourceware.org Git - lvm2.git/commitdiff
lvconvert: improve validation thin and cache pool conversion
authorZdenek Kabelac <zkabelac@redhat.com>
Fri, 6 Sep 2019 16:09:40 +0000 (18:09 +0200)
committerZdenek Kabelac <zkabelac@redhat.com>
Tue, 17 Sep 2019 11:13:49 +0000 (13:13 +0200)
Limit convertible LVs to thin-pool and cache-pools.
Also fix return code on  interal error path to return ECMD_FAILED.

WHATS_NEW
tools/lvconvert.c

index cb93bbef15114f727d5a4a4e34df650aeddb4b73..518b9443e7b8c27c78a67a32e81150cb937eb8a7 100644 (file)
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
 Version 2.03.06 - 
 ================================
+  Enhance validation for thin and cache pool conversion and swapping.
   Improve internal removal of cached devices.
   Synchronize with udev when dropping snapshot.
   Add missing device synchronization point before removing pvmove node.
index 31f9296769ac275542b064dfb77f13b2d09c105b..d64ab224aab3e66b7da9bb1e6fedae018781fab2 100644 (file)
@@ -4455,24 +4455,66 @@ static int _lvconvert_to_pool_or_swap_metadata_single(struct cmd_context *cmd,
        struct dm_list *use_pvh = NULL;
        int to_thinpool = 0;
        int to_cachepool = 0;
+       int lvt_enum = get_lvt_enum(lv);
+       struct lv_type *lvtype;
 
        switch (cmd->command->command_enum) {
        case lvconvert_to_thinpool_or_swap_metadata_CMD:
+               if (lv_is_cache(lv))
+                       /* For cached LV check the cache origin LV type */
+                       lvt_enum = get_lvt_enum(seg_lv(first_seg(lv), 0));
                to_thinpool = 1;
                break;
        case lvconvert_to_cachepool_or_swap_metadata_CMD:
+               if (lv_is_cache(lv))
+                       goto_bad; /* Cache over cache is not supported */
                to_cachepool = 1;
                break;
        default:
-               log_error(INTERNAL_ERROR "Invalid lvconvert pool command");
-               return 0;
-       };
+               log_error(INTERNAL_ERROR "Invalid lvconvert pool command.");
+               return ECMD_FAILED;
+       }
+
+       switch (lvt_enum) {
+       case thinpool_LVT:
+               if (!to_thinpool)
+                       goto_bad; /* can't accept cache-pool */
+               break; /* swap thin-pool */
+       case cachepool_LVT:
+               if (!to_cachepool)
+                       goto_bad; /* can't accept thin-pool */
+               break; /* swap cache-pool */
+       case linear_LVT:
+       case raid_LVT:
+       case striped_LVT:
+       case zero_LVT:
+               break;
+       default:
+bad:
+               lvtype = get_lv_type(lvt_enum);
+               log_error("LV %s with type %s cannot be used as a %s pool LV.",
+                         display_lvname(lv), lvtype ? lvtype->name : "unknown",
+                         to_thinpool ? "thin" : "cache");
+               return ECMD_FAILED;
+       }
 
        if (lv_is_origin(lv)) {
                log_error("Cannot convert logical volume %s under snapshot.",
                          display_lvname(lv));
-               return 0;
-       };
+               return ECMD_FAILED;
+       }
+
+       if (!lv_is_visible(lv)) {
+               log_error("Can't convert internal LV %s.",
+                         display_lvname(lv));
+               return ECMD_FAILED;
+       }
+
+       if (lv_is_locked(lv)) {
+               log_error("Can't convert locked LV %s.",
+                         display_lvname(lv));
+               return ECMD_FAILED;
+       }
 
        if (cmd->position_argc > 1) {
                /* First pos arg is required LV, remaining are optional PVs. */
This page took 0.056825 seconds and 5 git commands to generate.