|
|
3709d2 |
From 06cafbbbbff0aae3634eb2908d25d0dc46c2048b Mon Sep 17 00:00:00 2001
|
|
|
3709d2 |
From: Vojtech Trefny <vtrefny@redhat.com>
|
|
|
3709d2 |
Date: Tue, 9 Nov 2021 15:52:48 +0100
|
|
|
3709d2 |
Subject: [PATCH] Use bigger chunk size for thinpools bigger than ~15.88 TiB
|
|
|
3709d2 |
|
|
|
3709d2 |
With our default chunk size of 64 KiB we cannot create bigger
|
|
|
3709d2 |
thin pools than 15.88 TiB. Unfortunately we need to specify chunk
|
|
|
3709d2 |
size to be able to calculate thin metadata properly so we can't
|
|
|
3709d2 |
simply leave this to LVM to determine the correct chunk size.
|
|
|
3709d2 |
---
|
|
|
3709d2 |
blivet/devicelibs/lvm.py | 11 +++++++++++
|
|
|
3709d2 |
blivet/devices/lvm.py | 6 +++---
|
|
|
3709d2 |
tests/devices_test/lvm_test.py | 11 +++++++++++
|
|
|
3709d2 |
3 files changed, 25 insertions(+), 3 deletions(-)
|
|
|
3709d2 |
|
|
|
3709d2 |
diff --git a/blivet/devicelibs/lvm.py b/blivet/devicelibs/lvm.py
|
|
|
3709d2 |
index d56a76ed..cb6f655e 100644
|
|
|
3709d2 |
--- a/blivet/devicelibs/lvm.py
|
|
|
3709d2 |
+++ b/blivet/devicelibs/lvm.py
|
|
|
3709d2 |
@@ -20,6 +20,7 @@
|
|
|
3709d2 |
# Author(s): Dave Lehman <dlehman@redhat.com>
|
|
|
3709d2 |
#
|
|
|
3709d2 |
|
|
|
3709d2 |
+import math
|
|
|
3709d2 |
import os
|
|
|
3709d2 |
import re
|
|
|
3709d2 |
|
|
|
3709d2 |
@@ -51,6 +52,7 @@ LVM_THINP_MIN_METADATA_SIZE = Size("2 MiB")
|
|
|
3709d2 |
LVM_THINP_MAX_METADATA_SIZE = Size("16 GiB")
|
|
|
3709d2 |
LVM_THINP_MIN_CHUNK_SIZE = Size("64 KiB")
|
|
|
3709d2 |
LVM_THINP_MAX_CHUNK_SIZE = Size("1 GiB")
|
|
|
3709d2 |
+LVM_THINP_ADDRESSABLE_CHUNK_SIZE = Size("17455015526400 B") # 15.88 TiB
|
|
|
3709d2 |
|
|
|
3709d2 |
raid_levels = raid.RAIDLevels(["linear", "striped", "raid1", "raid4", "raid5", "raid6", "raid10"])
|
|
|
3709d2 |
raid_seg_types = list(itertools.chain.from_iterable([level.names for level in raid_levels if level.name != "linear"]))
|
|
|
3709d2 |
@@ -225,3 +227,12 @@ def is_lvm_name_valid(name):
|
|
|
3709d2 |
return False
|
|
|
3709d2 |
|
|
|
3709d2 |
return True
|
|
|
3709d2 |
+
|
|
|
3709d2 |
+
|
|
|
3709d2 |
+def recommend_thpool_chunk_size(thpool_size):
|
|
|
3709d2 |
+ # calculation of the recommended chunk size by LVM is so complicated that we
|
|
|
3709d2 |
+ # can't really replicate it, but we know that 64 KiB chunk size gives us
|
|
|
3709d2 |
+ # upper limit of ~15.88 TiB so we will just add 64 KiB to the chunk size
|
|
|
3709d2 |
+ # for every ~15.88 TiB of thinpool data size
|
|
|
3709d2 |
+ return min(math.ceil(thpool_size / LVM_THINP_ADDRESSABLE_CHUNK_SIZE) * LVM_THINP_MIN_CHUNK_SIZE,
|
|
|
3709d2 |
+ LVM_THINP_MAX_CHUNK_SIZE)
|
|
|
3709d2 |
diff --git a/blivet/devices/lvm.py b/blivet/devices/lvm.py
|
|
|
3709d2 |
index 51d785d9..c61eeb4b 100644
|
|
|
3709d2 |
--- a/blivet/devices/lvm.py
|
|
|
3709d2 |
+++ b/blivet/devices/lvm.py
|
|
|
3709d2 |
@@ -1634,9 +1634,9 @@ class LVMThinPoolMixin(object):
|
|
|
3709d2 |
return
|
|
|
3709d2 |
|
|
|
3709d2 |
# we need to know chunk size to calculate recommended metadata size
|
|
|
3709d2 |
- if self._chunk_size == 0:
|
|
|
3709d2 |
- self._chunk_size = Size(blockdev.LVM_DEFAULT_CHUNK_SIZE)
|
|
|
3709d2 |
- log.debug("Using default chunk size: %s", self._chunk_size)
|
|
|
3709d2 |
+ if self._chunk_size == 0 or enforced:
|
|
|
3709d2 |
+ self._chunk_size = lvm.recommend_thpool_chunk_size(self._size)
|
|
|
3709d2 |
+ log.debug("Using recommended chunk size: %s", self._chunk_size)
|
|
|
3709d2 |
|
|
|
3709d2 |
old_md_size = self._metadata_size
|
|
|
3709d2 |
old_pmspare_size = self.vg.pmspare_size
|
|
|
3709d2 |
diff --git a/tests/devices_test/lvm_test.py b/tests/devices_test/lvm_test.py
|
|
|
3709d2 |
index 4156d0bf..336c5b99 100644
|
|
|
3709d2 |
--- a/tests/devices_test/lvm_test.py
|
|
|
3709d2 |
+++ b/tests/devices_test/lvm_test.py
|
|
|
3709d2 |
@@ -442,6 +442,17 @@ class LVMDeviceTest(unittest.TestCase):
|
|
|
3709d2 |
self.assertFalse(pool.exists)
|
|
|
3709d2 |
self.assertTrue(lvm.lvremove.called)
|
|
|
3709d2 |
|
|
|
3709d2 |
+ def test_lvmthinpool_chunk_size(self):
|
|
|
3709d2 |
+ pv = StorageDevice("pv1", fmt=blivet.formats.get_format("lvmpv"),
|
|
|
3709d2 |
+ size=Size("100 TiB"))
|
|
|
3709d2 |
+ vg = LVMVolumeGroupDevice("testvg", parents=[pv])
|
|
|
3709d2 |
+ pool = LVMLogicalVolumeDevice("pool1", parents=[vg], size=Size("500 MiB"), seg_type="thin-pool")
|
|
|
3709d2 |
+ self.assertEqual(pool.chunk_size, Size("64 KiB"))
|
|
|
3709d2 |
+
|
|
|
3709d2 |
+ pool.size = Size("16 TiB")
|
|
|
3709d2 |
+ pool.autoset_md_size(enforced=True)
|
|
|
3709d2 |
+ self.assertEqual(pool.chunk_size, Size("128 KiB"))
|
|
|
3709d2 |
+
|
|
|
3709d2 |
|
|
|
3709d2 |
class TypeSpecificCallsTest(unittest.TestCase):
|
|
|
3709d2 |
def test_type_specific_calls(self):
|
|
|
3709d2 |
--
|
|
|
3709d2 |
2.31.1
|
|
|
3709d2 |
|