[lvm-devel] master - thin: check for overprovisioning

Zdenek Kabelac zkabelac at fedoraproject.org
Fri Jul 3 14:19:07 UTC 2015


Gitweb:        http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=622064f00fe41a02ab857ce02920a9e8818e610b
Commit:        622064f00fe41a02ab857ce02920a9e8818e610b
Parent:        9cee94372a7e45b6a40478ec17de1c142ed268d4
Author:        Zdenek Kabelac <zkabelac at redhat.com>
AuthorDate:    Fri Jul 3 15:31:31 2015 +0200
Committer:     Zdenek Kabelac <zkabelac at redhat.com>
CommitterDate: Fri Jul 3 16:13:14 2015 +0200

thin: check for overprovisioning

---
 WHATS_NEW                           |    1 +
 lib/metadata/lv_manip.c             |    5 ++
 lib/metadata/metadata.h             |    1 +
 lib/metadata/thin_manip.c           |   88 +++++++++++++++++++++++++++++++++++
 test/shell/thin-overprovisioning.sh |   71 ++++++++++++++++++++++++++++
 5 files changed, 166 insertions(+), 0 deletions(-)

diff --git a/WHATS_NEW b/WHATS_NEW
index 6a33e6d..22fc42a 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
 Version 2.02.124 -
 =================================
+  Report warning when pool is overprovisioned and not auto resized.
   Recognize free-form date/time values for lv_time field in selection criteria.
   Fix regression in select to match string fields if using synonyms (2.02.123).
   Fix regression when printing more lv names via display_lvname (2.02.122).
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 87888a7..d23dd62 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -5167,6 +5167,8 @@ static struct logical_volume *_lvresize_volume(struct cmd_context *cmd,
 			      lp->extents - lv->le_count,
 			      pvh, alloc, lp->approx_alloc))
 		return_NULL;
+	else if (!pool_check_overprovisioning(lv))
+		return_NULL;
 
 	if (old_extents == lv->le_count)
 		log_print_unless_silent("Size of logical volume %s unchanged from %s (%" PRIu32 " extents).",
@@ -7293,6 +7295,9 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
 			return_NULL;
 	}
 
+	if (!pool_check_overprovisioning(lv))
+		return_NULL;
+
 	/* FIXME Log allocation and attachment should have happened inside lv_extend. */
 	if (lp->log_count &&
 	    !seg_is_raid(first_seg(lv)) && seg_is_mirrored(first_seg(lv))) {
diff --git a/lib/metadata/metadata.h b/lib/metadata/metadata.h
index abf6072..1a5306b 100644
--- a/lib/metadata/metadata.h
+++ b/lib/metadata/metadata.h
@@ -485,6 +485,7 @@ int lv_is_merging_thin_snapshot(const struct logical_volume *lv);
 int pool_has_message(const struct lv_segment *seg,
 		     const struct logical_volume *lv, uint32_t device_id);
 int pool_below_threshold(const struct lv_segment *pool_seg);
+int pool_check_overprovisioning(const struct logical_volume *lv);
 int create_pool(struct logical_volume *lv, const struct segment_type *segtype,
 		struct alloc_handle *ah, uint32_t stripes, uint32_t stripe_size);
 
diff --git a/lib/metadata/thin_manip.c b/lib/metadata/thin_manip.c
index 1620d62..1453f88 100644
--- a/lib/metadata/thin_manip.c
+++ b/lib/metadata/thin_manip.c
@@ -237,6 +237,94 @@ int pool_below_threshold(const struct lv_segment *pool_seg)
 }
 
 /*
+ * Detect overprovisioning and check lvm2 is configured for auto resize.
+ *
+ * If passed LV is thin volume/pool, check first only this one for overprovisiong.
+ * Lots of test combined together.
+ * Test is not detecting status of dmeventd, too complex for now...
+ */
+int pool_check_overprovisioning(const struct logical_volume *lv)
+{
+	const struct lv_list *lvl;
+	const struct seg_list *sl;
+	const struct logical_volume *pool_lv = NULL;
+	struct cmd_context *cmd = lv->vg->cmd;
+	const char *txt = "";
+	uint64_t thinsum = 0, poolsum = 0, sz = ~0;
+	int threshold, max_threshold = 0;
+	int percent, min_percent = 100;
+	int more_pools = 0;
+
+	/* When passed thin volume, check related pool first */
+	if (lv_is_thin_volume(lv))
+		pool_lv = first_seg(lv)->pool_lv;
+	else if (lv_is_thin_pool(lv))
+		pool_lv = lv;
+
+	if (pool_lv) {
+		poolsum += pool_lv->size;
+		dm_list_iterate_items(sl, &pool_lv->segs_using_this_lv)
+			thinsum += sl->seg->lv->size;
+
+		if (thinsum <= poolsum)
+			return 1; /* All thins fit into this thin pool */
+	}
+
+	/* Sum all thins and all thin pools in VG */
+	dm_list_iterate_items(lvl, &lv->vg->lvs) {
+		if (!lv_is_thin_pool(lvl->lv))
+			continue;
+
+		threshold = find_config_tree_int(cmd, activation_thin_pool_autoextend_threshold_CFG,
+						 lv_config_profile(lvl->lv));
+		percent = find_config_tree_int(cmd, activation_thin_pool_autoextend_percent_CFG,
+					       lv_config_profile(lvl->lv));
+		if (threshold > max_threshold)
+			max_threshold = threshold;
+		if (percent < min_percent)
+			min_percent = percent;
+
+		if (lvl->lv == pool_lv)
+			continue; /* Skip iteration for already checked thin pool */
+
+		more_pools++;
+		poolsum += lvl->lv->size;
+		dm_list_iterate_items(sl, &lvl->lv->segs_using_this_lv)
+			thinsum += sl->seg->lv->size;
+	}
+
+	if (thinsum <= poolsum)
+		return 1; /* All fits for all pools */
+
+	if ((sz = vg_size(lv->vg)) < thinsum)
+		/* Thin sum size is above VG size */
+		txt = " and the size of whole volume group";
+	else if ((sz = vg_free(lv->vg)) < thinsum)
+		/* Thin sum size is more then free space in a VG */
+		txt = !sz ? "" : " and the amount of free space in volume group";
+	else if ((max_threshold > 99) || !min_percent)
+		/* There is some free space in VG, but it is not configured
+		 * for growing - threshold is 100% or percent is 0% */
+		sz = poolsum;
+
+	if (sz != ~0) {
+		log_warn("WARNING: Sum of all thin volume sizes (%s) exceeds the "
+			 "size of thin pool%s%s%s (%s)!",
+			 display_size(cmd, thinsum),
+			 more_pools ? "" : " ",
+			 more_pools ? "s" : display_lvname(pool_lv),
+			 txt,
+			 (sz > 0) ? display_size(cmd, sz) : "no free space in volume group");
+		if (max_threshold > 99)
+			log_print_unless_silent("For thin pool auto extension activation/thin_pool_autoextend_threshold should be bellow 100.");
+		if (!min_percent)
+			log_print_unless_silent("For thin pool auto extension activation/thin_pool_autoextend_percent should be above 0.");
+	}
+
+	return 1;
+}
+
+/*
  * Validate given external origin could be used with thin pool
  */
 int pool_supports_external_origin(const struct lv_segment *pool_seg, const struct logical_volume *external_lv)
diff --git a/test/shell/thin-overprovisioning.sh b/test/shell/thin-overprovisioning.sh
new file mode 100644
index 0000000..ac0b96c
--- /dev/null
+++ b/test/shell/thin-overprovisioning.sh
@@ -0,0 +1,71 @@
+#!/bin/sh
+# Copyright (C) 2015 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
+
+# Test warns when thin pool is overprovisiong
+
+export LVM_TEST_THIN_REPAIR_CMD=${LVM_TEST_THIN_REPAIR_CMD-/bin/false}
+
+. lib/inittest
+
+aux have_thin 1 3 0 || skip
+
+# 2PVs by 32M
+aux prepare_vg 2 33
+
+lvcreate -L32 -T $vg/pool
+
+# leave 12M free space
+lvcreate -an -n $lv1 -L16 $vg 2>&1 | tee out
+vgs $vg
+
+lvcreate -n thin1 -V30 $vg/pool 2>&1 | tee out
+not grep "WARNING: Sum" out
+
+# Pool gets overprovisioned
+lvcreate -an -n thin2 -V4 $vg/pool 2>&1 | tee out
+grep "WARNING: Sum" out
+grep "amount of free space in volume group (12.00 MiB)" out
+
+# Eat all space in VG
+lvcreate -an -n $lv2 -L12 $vg 2>&1 | tee out
+grep "WARNING: Sum" out
+grep "no free space in volume group" out
+
+lvcreate -an -n thin3 -V1G $vg/pool 2>&1 | tee out
+grep "WARNING: Sum" out
+grep "the size of whole volume group" out
+
+lvremove -ff $vg/thin2 $vg/thin3 $vg/$lv2
+
+# Create 2nd thin pool in a VG
+
+lvcreate -L4 -T $vg/pool2
+lvcreate -V4 -n thin2 $vg/pool2 2>&1 | tee out
+not grep "WARNING: Sum" out
+
+lvcreate -an -V4 -n thin3 $vg/pool2 2>&1 | tee out
+grep "WARNING: Sum of all thin volume sizes (38.00 MiB)" out
+grep "free space in volume group (6.00 MiB)" out
+
+lvcreate -an -L6 -n $lv3 $vg 2>&1 | tee out
+grep "no free space in volume group" out
+
+lvremove -ff $vg/thin2 $vg/thin3
+
+lvcreate -an -V4 -n thin2 $vg/pool2 2>&1 | tee out
+not grep "WARNING: Sum" out
+
+# Check if resize notices problem
+lvextend -L+8 $vg/thin2
+
+vgs $vg
+
+vgremove -ff $vg




More information about the lvm-devel mailing list