]> sourceware.org Git - lvm2.git/commitdiff
thin: fix volume_list support
authorZdenek Kabelac <zkabelac@redhat.com>
Tue, 26 Aug 2014 10:10:29 +0000 (12:10 +0200)
committerZdenek Kabelac <zkabelac@redhat.com>
Tue, 26 Aug 2014 12:10:18 +0000 (14:10 +0200)
Fixing problem, when user sets volume_list and excludes thin pools
from activation. In this case pool return 'success' for skipped activation.

We need to really check the volume it is actually active to properly
to remove queued pool messages. Otherwise the lvm2 and kernel
metadata started to go async since lvm2 believed, messages were submitted.

Add also better check for threshold when create a new thin volume.
In this case we require local activation of thin pool so we are able
to check pool fullness.

WHATS_NEW
lib/metadata/lv_manip.c
lib/metadata/thin_manip.c

index 13e61292deac48648aef2f5bfa2c685382bdfe48..9ddb232021e6ccbc16a465bdc1e6cb8cdc7fafe9 100644 (file)
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
 Version 2.02.110 -
 ==================================
+  Fix manipulation with thin-pools which are excluded via volume_list.
   Support lv/vgremove -ff to remove thin vols from broken/inactive thin pools.
   Fix typo breaking configure --with-lvm1=shared.
   Modify lvresize code to handle raid/mirrors and physical extents.
index 5cc00797223687e6defa2b3103e020c9fbdeb74d..e57e7b370e510b94be7ad545762d868c11f577d2 100644 (file)
@@ -6816,15 +6816,7 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
                        return NULL;
                }
 
-               if (lv_is_active_locally(lvl->lv) &&
-                   !pool_below_threshold(first_seg(lvl->lv))) {
-                       log_error("Cannot create thin volume. Pool \"%s/%s\" "
-                                 "is filled over the autoextend threshold.",
-                                 lvl->lv->vg->name, lvl->lv->name);
-                       return NULL;
-               }
-
-               if ((lv_is_active(lvl->lv) || is_change_activating(lp->activate)) &&
+               if ((pool_is_active(lvl->lv) || is_change_activating(lp->activate)) &&
                    !update_pool_lv(lvl->lv, 1))
                        return_NULL;
 
index ae42da1693ddc24a18d64efaf4d5188e5a8b2a11..61e9c6ecb356b12e583d34cdac12ba907896f129 100644 (file)
@@ -307,9 +307,36 @@ uint32_t get_free_pool_device_id(struct lv_segment *thin_pool_seg)
        return max_id;
 }
 
+static int _check_pool_create(const struct logical_volume *lv)
+{
+       const struct lv_thin_message *lmsg;
+       struct lvinfo info;
+
+       dm_list_iterate_items(lmsg, &first_seg(lv)->thin_messages) {
+               if (lmsg->type != DM_THIN_MESSAGE_CREATE_THIN)
+                       continue;
+               /* When creating new thin LV, check for size would be needed */
+               if (!lv_info(lv->vg->cmd, lv, 1, &info, 0, 0) ||
+                   !info.exists) {
+                       log_error("Pool %s needs to be locally active for threshold check.",
+                                 display_lvname(lv));
+                       return 0;
+               }
+               if (!pool_below_threshold(first_seg(lv))) {
+                       log_error("Free space in pool %s is above threshold, new volumes are not allowed.",
+                                 display_lvname(lv));
+                       return 0;
+               }
+               break;
+       }
+
+       return 1;
+}
+
 int update_pool_lv(struct logical_volume *lv, int activate)
 {
        int monitored;
+       int ret = 1;
 
        if (!lv_is_thin_pool(lv)) {
                log_error(INTERNAL_ERROR "Updated LV %s is not pool.", lv->name);
@@ -324,10 +351,24 @@ int update_pool_lv(struct logical_volume *lv, int activate)
                if (!lv_is_active(lv)) {
                        monitored = dmeventd_monitor_mode();
                        init_dmeventd_monitor(DMEVENTD_MONITOR_IGNORE);
-                       if (!activate_lv_excl(lv->vg->cmd, lv))
+                       if (!activate_lv_excl(lv->vg->cmd, lv)) {
+                               init_dmeventd_monitor(monitored);
                                return_0;
-                       if (!deactivate_lv(lv->vg->cmd, lv))
+                       }
+                       if (!lv_is_active(lv)) {
+                               init_dmeventd_monitor(monitored);
+                               log_error("Cannot activate thin pool %s, perhaps skipped in lvm.conf volume_list?",
+                                         display_lvname(lv));
+                               return 0;
+                       }
+
+                       if (!(ret = _check_pool_create(lv)))
+                               stack;
+
+                       if (!deactivate_lv(lv->vg->cmd, lv)) {
+                               init_dmeventd_monitor(monitored);
                                return_0;
+                       }
                        init_dmeventd_monitor(monitored);
                }
                /*
@@ -337,7 +378,8 @@ int update_pool_lv(struct logical_volume *lv, int activate)
                else if (!resume_lv_origin(lv->vg->cmd, lv)) {
                        log_error("Failed to resume %s.", lv->name);
                        return 0;
-               }
+               } else if (!(ret = _check_pool_create(lv)))
+                       stack;
        }
 
        dm_list_init(&(first_seg(lv)->thin_messages));
@@ -345,7 +387,7 @@ int update_pool_lv(struct logical_volume *lv, int activate)
        if (!vg_write(lv->vg) || !vg_commit(lv->vg))
                return_0;
 
-       return 1;
+       return ret;
 }
 
 int update_thin_pool_params(struct volume_group *vg,
This page took 0.053724 seconds and 5 git commands to generate.