neil / rpms / python-blivet

Forked from rpms/python-blivet a year ago
Clone

Blame SOURCES/0025-Check-for-PV-sector-size-when-creating-new-VG.patch

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