|
|
0b05ab |
From 83a42f3e232c7c4a02deb3539972c82b6dca284b Mon Sep 17 00:00:00 2001
|
|
|
0b05ab |
From: Vojtech Trefny <vtrefny@redhat.com>
|
|
|
0b05ab |
Date: Fri, 4 Oct 2019 12:30:03 +0200
|
|
|
0b05ab |
Subject: [PATCH 1/2] Add a new "sector_size" property to storage devices.
|
|
|
0b05ab |
|
|
|
0b05ab |
This represents the logical sector size of the device.
|
|
|
0b05ab |
|
|
|
0b05ab |
Related: rhbz#1754446
|
|
|
0b05ab |
---
|
|
|
0b05ab |
blivet/devices/disk.py | 6 +++++-
|
|
|
0b05ab |
blivet/devices/md.py | 11 +++++++++++
|
|
|
0b05ab |
blivet/devices/partition.py | 7 +++++++
|
|
|
0b05ab |
blivet/devices/storage.py | 15 +++++++++++++++
|
|
|
0b05ab |
4 files changed, 38 insertions(+), 1 deletion(-)
|
|
|
0b05ab |
|
|
|
0b05ab |
diff --git a/blivet/devices/disk.py b/blivet/devices/disk.py
|
|
|
0b05ab |
index bf2f7a4f..7dfeabf0 100644
|
|
|
0b05ab |
--- a/blivet/devices/disk.py
|
|
|
0b05ab |
+++ b/blivet/devices/disk.py
|
|
|
0b05ab |
@@ -687,7 +687,7 @@ def __init__(self, device, **kwargs):
|
|
|
0b05ab |
"""
|
|
|
0b05ab |
self.mode = kwargs.pop("mode")
|
|
|
0b05ab |
self.devname = kwargs.pop("devname")
|
|
|
0b05ab |
- self.sector_size = kwargs.pop("sector_size")
|
|
|
0b05ab |
+ self._sector_size = kwargs.pop("sector_size")
|
|
|
0b05ab |
|
|
|
0b05ab |
DiskDevice.__init__(self, device, **kwargs)
|
|
|
0b05ab |
|
|
|
0b05ab |
@@ -710,3 +710,7 @@ def description(self):
|
|
|
0b05ab |
% {'devname': self.devname,
|
|
|
0b05ab |
'mode': self.mode,
|
|
|
0b05ab |
'path': self.path}
|
|
|
0b05ab |
+
|
|
|
0b05ab |
+ @property
|
|
|
0b05ab |
+ def sector_size(self):
|
|
|
0b05ab |
+ return self._sector_size
|
|
|
0b05ab |
diff --git a/blivet/devices/md.py b/blivet/devices/md.py
|
|
|
0b05ab |
index 6a837df0..0b6da980 100644
|
|
|
0b05ab |
--- a/blivet/devices/md.py
|
|
|
0b05ab |
+++ b/blivet/devices/md.py
|
|
|
0b05ab |
@@ -19,10 +19,13 @@
|
|
|
0b05ab |
# Red Hat Author(s): David Lehman <dlehman@redhat.com>
|
|
|
0b05ab |
#
|
|
|
0b05ab |
|
|
|
0b05ab |
+import math
|
|
|
0b05ab |
import os
|
|
|
0b05ab |
import six
|
|
|
0b05ab |
import time
|
|
|
0b05ab |
|
|
|
0b05ab |
+from six.moves import reduce
|
|
|
0b05ab |
+
|
|
|
0b05ab |
import gi
|
|
|
0b05ab |
gi.require_version("BlockDev", "2.0")
|
|
|
0b05ab |
|
|
|
0b05ab |
@@ -195,6 +198,14 @@ def level(self, value):
|
|
|
0b05ab |
|
|
|
0b05ab |
self._level = level
|
|
|
0b05ab |
|
|
|
0b05ab |
+ @property
|
|
|
0b05ab |
+ def sector_size(self):
|
|
|
0b05ab |
+ if not self.exists:
|
|
|
0b05ab |
+ # Least common multiple of parents' sector sizes
|
|
|
0b05ab |
+ return reduce(lambda a, b: a * b // math.gcd(a, b), (int(p.sector_size) for p in self.parents))
|
|
|
0b05ab |
+
|
|
|
0b05ab |
+ return super(MDRaidArrayDevice, self).sector_size
|
|
|
0b05ab |
+
|
|
|
0b05ab |
@property
|
|
|
0b05ab |
def chunk_size(self):
|
|
|
0b05ab |
if self.exists and self._chunk_size == Size(0):
|
|
|
0b05ab |
diff --git a/blivet/devices/partition.py b/blivet/devices/partition.py
|
|
|
0b05ab |
index 623e1c9d..73daa76f 100644
|
|
|
0b05ab |
--- a/blivet/devices/partition.py
|
|
|
0b05ab |
+++ b/blivet/devices/partition.py
|
|
|
0b05ab |
@@ -729,6 +729,13 @@ def protected(self):
|
|
|
0b05ab |
def protected(self, value):
|
|
|
0b05ab |
self._protected = value
|
|
|
0b05ab |
|
|
|
0b05ab |
+ @property
|
|
|
0b05ab |
+ def sector_size(self):
|
|
|
0b05ab |
+ if self.disk:
|
|
|
0b05ab |
+ return self.disk.sector_size
|
|
|
0b05ab |
+
|
|
|
0b05ab |
+ return super(PartitionDevice, self).sector_size
|
|
|
0b05ab |
+
|
|
|
0b05ab |
def _pre_resize(self):
|
|
|
0b05ab |
if not self.exists:
|
|
|
0b05ab |
raise errors.DeviceError("device has not been created", self.name)
|
|
|
0b05ab |
diff --git a/blivet/devices/storage.py b/blivet/devices/storage.py
|
|
|
0b05ab |
index e087fa64..91c5e60e 100644
|
|
|
0b05ab |
--- a/blivet/devices/storage.py
|
|
|
0b05ab |
+++ b/blivet/devices/storage.py
|
|
|
0b05ab |
@@ -190,6 +190,21 @@ def raw_device(self):
|
|
|
0b05ab |
""" The device itself, or when encrypted, the backing device. """
|
|
|
0b05ab |
return self
|
|
|
0b05ab |
|
|
|
0b05ab |
+ @property
|
|
|
0b05ab |
+ def sector_size(self):
|
|
|
0b05ab |
+ """ Logical sector (block) size of this device """
|
|
|
0b05ab |
+ if not self.exists:
|
|
|
0b05ab |
+ if self.parents:
|
|
|
0b05ab |
+ return self.parents[0].sector_size
|
|
|
0b05ab |
+ else:
|
|
|
0b05ab |
+ return LINUX_SECTOR_SIZE
|
|
|
0b05ab |
+
|
|
|
0b05ab |
+ block_size = util.get_sysfs_attr(self.sysfs_path, "queue/logical_block_size")
|
|
|
0b05ab |
+ if block_size:
|
|
|
0b05ab |
+ return int(block_size)
|
|
|
0b05ab |
+ else:
|
|
|
0b05ab |
+ return LINUX_SECTOR_SIZE
|
|
|
0b05ab |
+
|
|
|
0b05ab |
@property
|
|
|
0b05ab |
def controllable(self):
|
|
|
0b05ab |
return self._controllable and not flags.testing and not self.unavailable_type_dependencies()
|
|
|
0b05ab |
|
|
|
0b05ab |
From 9f81bd1ffb877862760223ba88f2086deebd2d06 Mon Sep 17 00:00:00 2001
|
|
|
0b05ab |
From: Vojtech Trefny <vtrefny@redhat.com>
|
|
|
0b05ab |
Date: Fri, 4 Oct 2019 12:37:01 +0200
|
|
|
0b05ab |
Subject: [PATCH 2/2] Do not allow creating VGs with PVs with different sector
|
|
|
0b05ab |
size
|
|
|
0b05ab |
|
|
|
0b05ab |
New versions of LVM don't allow mixing PVs with different sector
|
|
|
0b05ab |
sizes in one VG.
|
|
|
0b05ab |
|
|
|
0b05ab |
Resolves: rhbz#1754446
|
|
|
0b05ab |
---
|
|
|
0b05ab |
blivet/devices/lvm.py | 12 ++++++++++++
|
|
|
0b05ab |
tests/devices_test/lvm_test.py | 13 ++++++++++++-
|
|
|
0b05ab |
2 files changed, 24 insertions(+), 1 deletion(-)
|
|
|
0b05ab |
|
|
|
0b05ab |
diff --git a/blivet/devices/lvm.py b/blivet/devices/lvm.py
|
|
|
0b05ab |
index 4347f483..b9da286a 100644
|
|
|
0b05ab |
--- a/blivet/devices/lvm.py
|
|
|
0b05ab |
+++ b/blivet/devices/lvm.py
|
|
|
0b05ab |
@@ -356,6 +356,18 @@ def _remove_log_vol(self, lv):
|
|
|
0b05ab |
def _add_parent(self, parent):
|
|
|
0b05ab |
super(LVMVolumeGroupDevice, self)._add_parent(parent)
|
|
|
0b05ab |
|
|
|
0b05ab |
+ # we are creating new VG or adding a new PV to an existing (complete) one
|
|
|
0b05ab |
+ if not self.exists or (self.exists and self._complete):
|
|
|
0b05ab |
+ parent_sectors = set([p.sector_size for p in self.pvs] + [parent.sector_size])
|
|
|
0b05ab |
+ if len(parent_sectors) != 1:
|
|
|
0b05ab |
+ if not self.exists:
|
|
|
0b05ab |
+ msg = "The volume group %s cannot be created. Selected disks have " \
|
|
|
0b05ab |
+ "inconsistent sector sizes (%s)." % (self.name, parent_sectors)
|
|
|
0b05ab |
+ else:
|
|
|
0b05ab |
+ msg = "Disk %s cannot be added to this volume group. LVM doesn't " \
|
|
|
0b05ab |
+ "allow using physical volumes with inconsistent (logical) sector sizes." % parent.name
|
|
|
0b05ab |
+ raise ValueError(msg)
|
|
|
0b05ab |
+
|
|
|
0b05ab |
if (self.exists and parent.format.exists and
|
|
|
0b05ab |
len(self.parents) + 1 == self.pv_count):
|
|
|
0b05ab |
self._complete = True
|
|
|
0b05ab |
diff --git a/tests/devices_test/lvm_test.py b/tests/devices_test/lvm_test.py
|
|
|
0b05ab |
index 8ed577f4..a32c1d83 100644
|
|
|
0b05ab |
--- a/tests/devices_test/lvm_test.py
|
|
|
0b05ab |
+++ b/tests/devices_test/lvm_test.py
|
|
|
0b05ab |
@@ -2,7 +2,7 @@
|
|
|
0b05ab |
import test_compat # pylint: disable=unused-import
|
|
|
0b05ab |
|
|
|
0b05ab |
import six
|
|
|
0b05ab |
-from six.moves.mock import patch # pylint: disable=no-name-in-module,import-error
|
|
|
0b05ab |
+from six.moves.mock import patch, PropertyMock # pylint: disable=no-name-in-module,import-error
|
|
|
0b05ab |
import unittest
|
|
|
0b05ab |
|
|
|
0b05ab |
import blivet
|
|
|
0b05ab |
@@ -352,6 +352,17 @@ def test_target_size(self):
|
|
|
0b05ab |
self.assertEqual(lv.target_size, orig_size)
|
|
|
0b05ab |
self.assertEqual(lv.size, orig_size)
|
|
|
0b05ab |
|
|
|
0b05ab |
+ def test_lvm_inconsistent_sector_size(self):
|
|
|
0b05ab |
+ pv = StorageDevice("pv1", fmt=blivet.formats.get_format("lvmpv"),
|
|
|
0b05ab |
+ size=Size("1024 MiB"))
|
|
|
0b05ab |
+ pv2 = StorageDevice("pv2", fmt=blivet.formats.get_format("lvmpv"),
|
|
|
0b05ab |
+ size=Size("1024 MiB"))
|
|
|
0b05ab |
+
|
|
|
0b05ab |
+ with patch("blivet.devices.StorageDevice.sector_size", new_callable=PropertyMock) as mock_property:
|
|
|
0b05ab |
+ mock_property.__get__ = lambda _mock, pv, _class: 512 if pv.name == "pv1" else 4096
|
|
|
0b05ab |
+ with six.assertRaisesRegex(self, ValueError, "The volume group testvg cannot be created."):
|
|
|
0b05ab |
+ LVMVolumeGroupDevice("testvg", parents=[pv, pv2])
|
|
|
0b05ab |
+
|
|
|
0b05ab |
|
|
|
0b05ab |
class TypeSpecificCallsTest(unittest.TestCase):
|
|
|
0b05ab |
def test_type_specific_calls(self):
|