- Improve error message printed for missing dependecies

Resolves: rhbz#2012121
- Use bigger chunk size for thinpools bigger than ~15.88 TiB
  Resolves: rhbz#1971516
This commit is contained in:
Vojtech Trefny 2021-11-26 12:36:14 +01:00
parent 4bf6a0b6da
commit 7f9bb703ff
3 changed files with 164 additions and 1 deletions

View File

@ -0,0 +1,65 @@
From 46335861073882b7162221fc0995dc1df3c67749 Mon Sep 17 00:00:00 2001
From: Vojtech Trefny <vtrefny@redhat.com>
Date: Fri, 6 Aug 2021 16:37:51 +0200
Subject: [PATCH] Improve error message printed for missing dependecies
The existing error message can be confusing for people that don't
know internals of blivet and libblockdev and the information what
is actually broken or not installed on the system is missing
completely. Example for LVM VDO with missing kvdo module:
Before:
device type lvmvdopool requires unavailable_dependencies:
libblockdev lvm plugin (vdo technology)
After:
device type lvmvdopool requires unavailable_dependencies:
libblockdev lvm plugin (vdo technology):
libblockdev plugin lvm is loaded but some required technologies
are not available (BD_LVM_TECH_VDO: Kernel module 'kvdo' not
available)
---
blivet/deviceaction.py | 2 +-
blivet/tasks/availability.py | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/blivet/deviceaction.py b/blivet/deviceaction.py
index 56e29215..0458e4be 100644
--- a/blivet/deviceaction.py
+++ b/blivet/deviceaction.py
@@ -173,7 +173,7 @@ class DeviceAction(util.ObjectID):
def _check_device_dependencies(self):
unavailable_dependencies = self.device.unavailable_dependencies
if unavailable_dependencies:
- dependencies_str = ", ".join(str(d) for d in unavailable_dependencies)
+ dependencies_str = ", ".join("%s:\n%s" % (str(d), ", ".join(d.availability_errors)) for d in unavailable_dependencies)
raise DependencyError("device type %s requires unavailable_dependencies: %s" % (self.device.type, dependencies_str))
def apply(self):
diff --git a/blivet/tasks/availability.py b/blivet/tasks/availability.py
index 1fd80590..1537f3f5 100644
--- a/blivet/tasks/availability.py
+++ b/blivet/tasks/availability.py
@@ -224,7 +224,7 @@ class BlockDevMethod(Method):
try:
self._tech_info.check_fn(tech, mode)
except GLib.GError as e:
- errors.append(str(e))
+ errors.append("%s: %s" % (tech.value_name, e.message))
return errors
def availability_errors(self, resource):
@@ -242,7 +242,7 @@ class BlockDevMethod(Method):
tech_missing = self._check_technologies()
if tech_missing:
return ["libblockdev plugin %s is loaded but some required "
- "technologies are not available:\n%s" % (self._tech_info.plugin_name, tech_missing)]
+ "technologies are not available (%s)" % (self._tech_info.plugin_name, "; ".join(tech_missing))]
else:
return []
--
2.31.1

View File

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

View File

@ -23,7 +23,7 @@ Version: 3.4.0
#%%global prerelease .b2
# prerelease, if defined, should be something like .a1, .b1, .b2.dev1, or .c2
Release: 7%{?prerelease}%{?dist}
Release: 8%{?prerelease}%{?dist}
Epoch: 1
License: LGPLv2+
%global realname blivet
@ -40,6 +40,8 @@ Patch6: 0008-Fix-resolving-devices-with-names-that-look-like-BIOS.patch
Patch7: 0009-Do-not-set-chunk-size-for-RAID1.patch
Patch8: 0010-Fix-running-tests-in-gating.patch
Patch9: 0011-Tell-LVM-to-ignore-the-new-devices-file-for-now.patch
Patch10: 0012-Improve-error-message-printed-for-missing-dependecie.patch
Patch11: 0013-Use-bigger-chunk-size-for-thinpools-bigger-than-15.8.patch
# Versions of required components (done so we make sure the buildrequires
# match the requires versions of things).
@ -202,6 +204,12 @@ configuration.
%endif
%changelog
* Fri Nov 26 2021 Vojtech Trefny <vtrefny@redhat.com> - 3.4.0-8
- Improve error message printed for missing dependecies
Resolves: rhbz#2012121
- Use bigger chunk size for thinpools bigger than ~15.88 TiB
Resolves: rhbz#1971516
* Tue Aug 17 2021 Vojtech Trefny <vtrefny@redhat.com> - 3.4.0-7
- Fix script for running tests in gating
Resolves: rhbz#1990237