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

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):