]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
util: Clear unused part of the map in virBitmapShrink
authorMartin Kletzander <mkletzan@redhat.com>
Thu, 1 Feb 2018 13:33:02 +0000 (14:33 +0100)
committerMartin Kletzander <mkletzan@redhat.com>
Fri, 2 Feb 2018 13:51:32 +0000 (14:51 +0100)
Some of the other functions depend on the fact that unused bits and longs are
always zero and it's less error-prone to clear it than fix the other functions.
It's enough to zero out one piece of the map since we're calling realloc() to
get rid of the rest (and updating map_len).

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1540817

Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
src/conf/domain_conf.c
src/util/virbitmap.c
src/util/virbitmap.h
src/util/virresctrl.c
tests/virbitmaptest.c

index 01d168eb875b7d1bcda31039fece5cc911526c1f..e827b2a810f7ba0619591e59a3ddfccca4055862 100644 (file)
@@ -18453,7 +18453,9 @@ virDomainCachetuneDefParse(virDomainDefPtr def,
 
     /* We need to limit the bitmap to number of vCPUs.  If there's nothing left,
      * then we can just clean up and return 0 immediately */
-    virBitmapShrink(vcpus, def->maxvcpus);
+    if (virBitmapShrink(vcpus, def->maxvcpus) < 0)
+        goto cleanup;
+
     if (virBitmapIsAllClear(vcpus)) {
         ret = 0;
         goto cleanup;
index b2c5c7a6a5ac7fe2c21d79a910524aa9170d799f..33cae2f305691caf7c873b5a7eae139a8ff51d8c 100644 (file)
@@ -1201,21 +1201,35 @@ virBitmapSubtract(virBitmapPtr a,
 /**
  * virBitmapShrink:
  * @map: Pointer to bitmap
- * @b: last bit position to be excluded from bitmap
+ * @b: Size to reduce the bitmap to
  *
- * Resizes the bitmap so that no more than @b bits will fit into it.  Nothing
- * will change if the size is already smaller than @b.
- *
- * NB: Does not adjust the map->map_len so that a subsequent virBitmapExpand
- * doesn't necessarily need to reallocate.
+ * Reduces the bitmap to size @b.  Nothing will change if the size is already
+ * smaller than or equal to @b.
  */
-void
+int
 virBitmapShrink(virBitmapPtr map,
                 size_t b)
 {
+    size_t nl = 0;
+    size_t nb = 0;
+
     if (!map)
-        return;
+        return 0;
 
     if (map->max_bit >= b)
         map->max_bit = b;
+
+    nl = map->max_bit / VIR_BITMAP_BITS_PER_UNIT;
+    nb = map->max_bit % VIR_BITMAP_BITS_PER_UNIT;
+    map->map[nl] &= ((1UL << nb) - 1);
+
+    nl++;
+    if (nl == map->map_len)
+        return 0;
+
+    if (VIR_REALLOC_N(map->map, nl) < 0)
+        return -1;
+
+    map->map_len = nl;
+    return 0;
 }
index 2464814055de9d74edc7b834a7817d5ae5d3901a..5a3362a19f9f8acb599a727c015c509e1c6c973d 100644 (file)
@@ -153,6 +153,6 @@ void virBitmapIntersect(virBitmapPtr a, virBitmapPtr b)
 void virBitmapSubtract(virBitmapPtr a, virBitmapPtr b)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
 
-void virBitmapShrink(virBitmapPtr map, size_t b);
+int virBitmapShrink(virBitmapPtr map, size_t b);
 
 #endif
index 70426199ce2041079fbe06ba576801208dc9d5fe..ef388757a704cd0d96550ef67abc6d0fae491dcf 100644 (file)
@@ -941,7 +941,8 @@ virResctrlAllocParseProcessCache(virResctrlInfoPtr resctrl,
     if (!mask)
         return -1;
 
-    virBitmapShrink(mask, resctrl->levels[level]->types[type]->bits);
+    if (virBitmapShrink(mask, resctrl->levels[level]->types[type]->bits) < 0)
+        goto cleanup;
 
     if (virResctrlAllocUpdateMask(alloc, level, type, cache_id, mask) < 0)
         goto cleanup;
index 9c0ffe70cb49c5749d999ef108cd0635e199ceaf..fffecdf1f6edbdfd6237e459e095ce185e6e82cf 100644 (file)
@@ -656,6 +656,14 @@ test12(const void *opaque ATTRIBUTE_UNUSED)
 
     TEST_MAP(1024, "34,1023");
 
+    if (virBitmapShrink(map, 35) < 0)
+        goto cleanup;
+    TEST_MAP(35, "34");
+
+    if (virBitmapShrink(map, 34) < 0)
+        goto cleanup;
+    TEST_MAP(34, "");
+
     ret = 0;
 
  cleanup: