404507
From fbecdf5ed4345a15d1ffc30922d44272a3d60368 Mon Sep 17 00:00:00 2001
404507
Message-Id: <fbecdf5ed4345a15d1ffc30922d44272a3d60368@dist-git>
404507
From: Martin Kletzander <mkletzan@redhat.com>
404507
Date: Fri, 2 Feb 2018 15:21:27 +0100
404507
Subject: [PATCH] util: Clear unused part of the map in virBitmapShrink
404507
404507
Some of the other functions depend on the fact that unused bits and longs are
404507
always zero and it's less error-prone to clear it than fix the other functions.
404507
It's enough to zero out one piece of the map since we're calling realloc() to
404507
get rid of the rest (and updating map_len).
404507
404507
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1540817
404507
404507
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
404507
(cherry picked from commit d6e582da80d07a90f154dc27aca239d44fc2b7b7)
404507
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
404507
---
404507
 src/conf/domain_conf.c |  4 +++-
404507
 src/util/virbitmap.c   | 30 ++++++++++++++++++++++--------
404507
 src/util/virbitmap.h   |  2 +-
404507
 src/util/virresctrl.c  |  3 ++-
404507
 tests/virbitmaptest.c  |  8 ++++++++
404507
 5 files changed, 36 insertions(+), 11 deletions(-)
404507
404507
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
404507
index 181b035647..0af3dd5ab6 100644
404507
--- a/src/conf/domain_conf.c
404507
+++ b/src/conf/domain_conf.c
404507
@@ -18365,7 +18365,9 @@ virDomainCachetuneDefParse(virDomainDefPtr def,
404507
 
404507
     /* We need to limit the bitmap to number of vCPUs.  If there's nothing left,
404507
      * then we can just clean up and return 0 immediately */
404507
-    virBitmapShrink(vcpus, def->maxvcpus);
404507
+    if (virBitmapShrink(vcpus, def->maxvcpus) < 0)
404507
+        goto cleanup;
404507
+
404507
     if (virBitmapIsAllClear(vcpus)) {
404507
         ret = 0;
404507
         goto cleanup;
404507
diff --git a/src/util/virbitmap.c b/src/util/virbitmap.c
404507
index b2c5c7a6a5..33cae2f305 100644
404507
--- a/src/util/virbitmap.c
404507
+++ b/src/util/virbitmap.c
404507
@@ -1201,21 +1201,35 @@ virBitmapSubtract(virBitmapPtr a,
404507
 /**
404507
  * virBitmapShrink:
404507
  * @map: Pointer to bitmap
404507
- * @b: last bit position to be excluded from bitmap
404507
+ * @b: Size to reduce the bitmap to
404507
  *
404507
- * Resizes the bitmap so that no more than @b bits will fit into it.  Nothing
404507
- * will change if the size is already smaller than @b.
404507
- *
404507
- * NB: Does not adjust the map->map_len so that a subsequent virBitmapExpand
404507
- * doesn't necessarily need to reallocate.
404507
+ * Reduces the bitmap to size @b.  Nothing will change if the size is already
404507
+ * smaller than or equal to @b.
404507
  */
404507
-void
404507
+int
404507
 virBitmapShrink(virBitmapPtr map,
404507
                 size_t b)
404507
 {
404507
+    size_t nl = 0;
404507
+    size_t nb = 0;
404507
+
404507
     if (!map)
404507
-        return;
404507
+        return 0;
404507
 
404507
     if (map->max_bit >= b)
404507
         map->max_bit = b;
404507
+
404507
+    nl = map->max_bit / VIR_BITMAP_BITS_PER_UNIT;
404507
+    nb = map->max_bit % VIR_BITMAP_BITS_PER_UNIT;
404507
+    map->map[nl] &= ((1UL << nb) - 1);
404507
+
404507
+    nl++;
404507
+    if (nl == map->map_len)
404507
+        return 0;
404507
+
404507
+    if (VIR_REALLOC_N(map->map, nl) < 0)
404507
+        return -1;
404507
+
404507
+    map->map_len = nl;
404507
+    return 0;
404507
 }
404507
diff --git a/src/util/virbitmap.h b/src/util/virbitmap.h
404507
index 2464814055..5a3362a19f 100644
404507
--- a/src/util/virbitmap.h
404507
+++ b/src/util/virbitmap.h
404507
@@ -153,6 +153,6 @@ void virBitmapIntersect(virBitmapPtr a, virBitmapPtr b)
404507
 void virBitmapSubtract(virBitmapPtr a, virBitmapPtr b)
404507
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
404507
 
404507
-void virBitmapShrink(virBitmapPtr map, size_t b);
404507
+int virBitmapShrink(virBitmapPtr map, size_t b);
404507
 
404507
 #endif
404507
diff --git a/src/util/virresctrl.c b/src/util/virresctrl.c
404507
index 70426199ce..ef388757a7 100644
404507
--- a/src/util/virresctrl.c
404507
+++ b/src/util/virresctrl.c
404507
@@ -941,7 +941,8 @@ virResctrlAllocParseProcessCache(virResctrlInfoPtr resctrl,
404507
     if (!mask)
404507
         return -1;
404507
 
404507
-    virBitmapShrink(mask, resctrl->levels[level]->types[type]->bits);
404507
+    if (virBitmapShrink(mask, resctrl->levels[level]->types[type]->bits) < 0)
404507
+        goto cleanup;
404507
 
404507
     if (virResctrlAllocUpdateMask(alloc, level, type, cache_id, mask) < 0)
404507
         goto cleanup;
404507
diff --git a/tests/virbitmaptest.c b/tests/virbitmaptest.c
404507
index 5bf30b2b1c..a78e4da723 100644
404507
--- a/tests/virbitmaptest.c
404507
+++ b/tests/virbitmaptest.c
404507
@@ -656,6 +656,14 @@ test12(const void *opaque ATTRIBUTE_UNUSED)
404507
 
404507
     TEST_MAP(1024, "34,1023");
404507
 
404507
+    if (virBitmapShrink(map, 35) < 0)
404507
+        goto cleanup;
404507
+    TEST_MAP(35, "34");
404507
+
404507
+    if (virBitmapShrink(map, 34) < 0)
404507
+        goto cleanup;
404507
+    TEST_MAP(34, "");
404507
+
404507
     ret = 0;
404507
 
404507
  cleanup:
404507
-- 
404507
2.16.1
404507