import python-blivet-3.1.0-20.el8
This commit is contained in:
parent
495f7f954c
commit
70f10104b7
183
SOURCES/0025-Check-for-PV-sector-size-when-creating-new-VG.patch
Normal file
183
SOURCES/0025-Check-for-PV-sector-size-when-creating-new-VG.patch
Normal file
@ -0,0 +1,183 @@
|
||||
From 83a42f3e232c7c4a02deb3539972c82b6dca284b Mon Sep 17 00:00:00 2001
|
||||
From: Vojtech Trefny <vtrefny@redhat.com>
|
||||
Date: Fri, 4 Oct 2019 12:30:03 +0200
|
||||
Subject: [PATCH 1/2] Add a new "sector_size" property to storage devices.
|
||||
|
||||
This represents the logical sector size of the device.
|
||||
|
||||
Related: rhbz#1754446
|
||||
---
|
||||
blivet/devices/disk.py | 6 +++++-
|
||||
blivet/devices/md.py | 11 +++++++++++
|
||||
blivet/devices/partition.py | 7 +++++++
|
||||
blivet/devices/storage.py | 15 +++++++++++++++
|
||||
4 files changed, 38 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/blivet/devices/disk.py b/blivet/devices/disk.py
|
||||
index bf2f7a4f..7dfeabf0 100644
|
||||
--- a/blivet/devices/disk.py
|
||||
+++ b/blivet/devices/disk.py
|
||||
@@ -687,7 +687,7 @@ def __init__(self, device, **kwargs):
|
||||
"""
|
||||
self.mode = kwargs.pop("mode")
|
||||
self.devname = kwargs.pop("devname")
|
||||
- self.sector_size = kwargs.pop("sector_size")
|
||||
+ self._sector_size = kwargs.pop("sector_size")
|
||||
|
||||
DiskDevice.__init__(self, device, **kwargs)
|
||||
|
||||
@@ -710,3 +710,7 @@ def description(self):
|
||||
% {'devname': self.devname,
|
||||
'mode': self.mode,
|
||||
'path': self.path}
|
||||
+
|
||||
+ @property
|
||||
+ def sector_size(self):
|
||||
+ return self._sector_size
|
||||
diff --git a/blivet/devices/md.py b/blivet/devices/md.py
|
||||
index 6a837df0..0b6da980 100644
|
||||
--- a/blivet/devices/md.py
|
||||
+++ b/blivet/devices/md.py
|
||||
@@ -19,10 +19,13 @@
|
||||
# Red Hat Author(s): David Lehman <dlehman@redhat.com>
|
||||
#
|
||||
|
||||
+import math
|
||||
import os
|
||||
import six
|
||||
import time
|
||||
|
||||
+from six.moves import reduce
|
||||
+
|
||||
import gi
|
||||
gi.require_version("BlockDev", "2.0")
|
||||
|
||||
@@ -195,6 +198,14 @@ def level(self, value):
|
||||
|
||||
self._level = level
|
||||
|
||||
+ @property
|
||||
+ def sector_size(self):
|
||||
+ if not self.exists:
|
||||
+ # Least common multiple of parents' sector sizes
|
||||
+ return reduce(lambda a, b: a * b // math.gcd(a, b), (int(p.sector_size) for p in self.parents))
|
||||
+
|
||||
+ return super(MDRaidArrayDevice, self).sector_size
|
||||
+
|
||||
@property
|
||||
def chunk_size(self):
|
||||
if self.exists and self._chunk_size == Size(0):
|
||||
diff --git a/blivet/devices/partition.py b/blivet/devices/partition.py
|
||||
index 623e1c9d..73daa76f 100644
|
||||
--- a/blivet/devices/partition.py
|
||||
+++ b/blivet/devices/partition.py
|
||||
@@ -729,6 +729,13 @@ def protected(self):
|
||||
def protected(self, value):
|
||||
self._protected = value
|
||||
|
||||
+ @property
|
||||
+ def sector_size(self):
|
||||
+ if self.disk:
|
||||
+ return self.disk.sector_size
|
||||
+
|
||||
+ return super(PartitionDevice, self).sector_size
|
||||
+
|
||||
def _pre_resize(self):
|
||||
if not self.exists:
|
||||
raise errors.DeviceError("device has not been created", self.name)
|
||||
diff --git a/blivet/devices/storage.py b/blivet/devices/storage.py
|
||||
index e087fa64..91c5e60e 100644
|
||||
--- a/blivet/devices/storage.py
|
||||
+++ b/blivet/devices/storage.py
|
||||
@@ -190,6 +190,21 @@ def raw_device(self):
|
||||
""" The device itself, or when encrypted, the backing device. """
|
||||
return self
|
||||
|
||||
+ @property
|
||||
+ def sector_size(self):
|
||||
+ """ Logical sector (block) size of this device """
|
||||
+ if not self.exists:
|
||||
+ if self.parents:
|
||||
+ return self.parents[0].sector_size
|
||||
+ else:
|
||||
+ return LINUX_SECTOR_SIZE
|
||||
+
|
||||
+ block_size = util.get_sysfs_attr(self.sysfs_path, "queue/logical_block_size")
|
||||
+ if block_size:
|
||||
+ return int(block_size)
|
||||
+ else:
|
||||
+ return LINUX_SECTOR_SIZE
|
||||
+
|
||||
@property
|
||||
def controllable(self):
|
||||
return self._controllable and not flags.testing and not self.unavailable_type_dependencies()
|
||||
|
||||
From 9f81bd1ffb877862760223ba88f2086deebd2d06 Mon Sep 17 00:00:00 2001
|
||||
From: Vojtech Trefny <vtrefny@redhat.com>
|
||||
Date: Fri, 4 Oct 2019 12:37:01 +0200
|
||||
Subject: [PATCH 2/2] Do not allow creating VGs with PVs with different sector
|
||||
size
|
||||
|
||||
New versions of LVM don't allow mixing PVs with different sector
|
||||
sizes in one VG.
|
||||
|
||||
Resolves: rhbz#1754446
|
||||
---
|
||||
blivet/devices/lvm.py | 12 ++++++++++++
|
||||
tests/devices_test/lvm_test.py | 13 ++++++++++++-
|
||||
2 files changed, 24 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/blivet/devices/lvm.py b/blivet/devices/lvm.py
|
||||
index 4347f483..b9da286a 100644
|
||||
--- a/blivet/devices/lvm.py
|
||||
+++ b/blivet/devices/lvm.py
|
||||
@@ -356,6 +356,18 @@ def _remove_log_vol(self, lv):
|
||||
def _add_parent(self, parent):
|
||||
super(LVMVolumeGroupDevice, self)._add_parent(parent)
|
||||
|
||||
+ # we are creating new VG or adding a new PV to an existing (complete) one
|
||||
+ if not self.exists or (self.exists and self._complete):
|
||||
+ parent_sectors = set([p.sector_size for p in self.pvs] + [parent.sector_size])
|
||||
+ if len(parent_sectors) != 1:
|
||||
+ if not self.exists:
|
||||
+ msg = "The volume group %s cannot be created. Selected disks have " \
|
||||
+ "inconsistent sector sizes (%s)." % (self.name, parent_sectors)
|
||||
+ else:
|
||||
+ msg = "Disk %s cannot be added to this volume group. LVM doesn't " \
|
||||
+ "allow using physical volumes with inconsistent (logical) sector sizes." % parent.name
|
||||
+ raise ValueError(msg)
|
||||
+
|
||||
if (self.exists and parent.format.exists and
|
||||
len(self.parents) + 1 == self.pv_count):
|
||||
self._complete = True
|
||||
diff --git a/tests/devices_test/lvm_test.py b/tests/devices_test/lvm_test.py
|
||||
index 8ed577f4..a32c1d83 100644
|
||||
--- a/tests/devices_test/lvm_test.py
|
||||
+++ b/tests/devices_test/lvm_test.py
|
||||
@@ -2,7 +2,7 @@
|
||||
import test_compat # pylint: disable=unused-import
|
||||
|
||||
import six
|
||||
-from six.moves.mock import patch # pylint: disable=no-name-in-module,import-error
|
||||
+from six.moves.mock import patch, PropertyMock # pylint: disable=no-name-in-module,import-error
|
||||
import unittest
|
||||
|
||||
import blivet
|
||||
@@ -352,6 +352,17 @@ def test_target_size(self):
|
||||
self.assertEqual(lv.target_size, orig_size)
|
||||
self.assertEqual(lv.size, orig_size)
|
||||
|
||||
+ def test_lvm_inconsistent_sector_size(self):
|
||||
+ pv = StorageDevice("pv1", fmt=blivet.formats.get_format("lvmpv"),
|
||||
+ size=Size("1024 MiB"))
|
||||
+ pv2 = StorageDevice("pv2", fmt=blivet.formats.get_format("lvmpv"),
|
||||
+ size=Size("1024 MiB"))
|
||||
+
|
||||
+ with patch("blivet.devices.StorageDevice.sector_size", new_callable=PropertyMock) as mock_property:
|
||||
+ mock_property.__get__ = lambda _mock, pv, _class: 512 if pv.name == "pv1" else 4096
|
||||
+ with six.assertRaisesRegex(self, ValueError, "The volume group testvg cannot be created."):
|
||||
+ LVMVolumeGroupDevice("testvg", parents=[pv, pv2])
|
||||
+
|
||||
|
||||
class TypeSpecificCallsTest(unittest.TestCase):
|
||||
def test_type_specific_calls(self):
|
@ -0,0 +1,309 @@
|
||||
From c85a80ca54eabb1cf2458a3e17b3472ba2eb0914 Mon Sep 17 00:00:00 2001
|
||||
From: David Lehman <dlehman@redhat.com>
|
||||
Date: Fri, 1 Nov 2019 12:07:43 -0400
|
||||
Subject: [PATCH 1/2] Override LVM skip-activation to allow for thorough
|
||||
removal.
|
||||
|
||||
When we have been told to remove the LV or manage the formatting we
|
||||
must tell LVM to ignore the skip-activation bit. Otherwise we have
|
||||
no way to properly perform the requested management.
|
||||
|
||||
Resolves: rhbz#1766498
|
||||
---
|
||||
blivet/deviceaction.py | 35 ++++++++++++++++++++++++++++++++++
|
||||
blivet/devices/lvm.py | 12 ++++--------
|
||||
tests/action_test.py | 16 ++++++++++++++++
|
||||
tests/devices_test/lvm_test.py | 29 ++++++++++++++++++++++++++++
|
||||
4 files changed, 84 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/blivet/deviceaction.py b/blivet/deviceaction.py
|
||||
index 14a06ff0..57115662 100644
|
||||
--- a/blivet/deviceaction.py
|
||||
+++ b/blivet/deviceaction.py
|
||||
@@ -393,10 +393,29 @@ class ActionDestroyDevice(DeviceAction):
|
||||
|
||||
super(ActionDestroyDevice, self)._check_device_dependencies()
|
||||
|
||||
+ def apply(self):
|
||||
+ """ apply changes related to the action to the device(s) """
|
||||
+ if self._applied:
|
||||
+ return
|
||||
+
|
||||
+ if hasattr(self.device, 'ignore_skip_activation'):
|
||||
+ self.device.ignore_skip_activation += 1
|
||||
+
|
||||
+ super(ActionDestroyDevice, self).apply()
|
||||
+
|
||||
def execute(self, callbacks=None):
|
||||
super(ActionDestroyDevice, self).execute(callbacks=callbacks)
|
||||
self.device.destroy()
|
||||
|
||||
+ def cancel(self):
|
||||
+ if not self._applied:
|
||||
+ return
|
||||
+
|
||||
+ if hasattr(self.device, 'ignore_skip_activation'):
|
||||
+ self.device.ignore_skip_activation -= 1
|
||||
+
|
||||
+ super(ActionDestroyDevice, self).cancel()
|
||||
+
|
||||
def requires(self, action):
|
||||
""" Return True if self requires action.
|
||||
|
||||
@@ -715,6 +734,9 @@ class ActionDestroyFormat(DeviceAction):
|
||||
return
|
||||
|
||||
self.device.format = None
|
||||
+ if hasattr(self.device, 'ignore_skip_activation'):
|
||||
+ self.device.ignore_skip_activation += 1
|
||||
+
|
||||
super(ActionDestroyFormat, self).apply()
|
||||
|
||||
def execute(self, callbacks=None):
|
||||
@@ -739,6 +761,8 @@ class ActionDestroyFormat(DeviceAction):
|
||||
return
|
||||
|
||||
self.device.format = self.orig_format
|
||||
+ if hasattr(self.device, 'ignore_skip_activation'):
|
||||
+ self.device.ignore_skip_activation -= 1
|
||||
super(ActionDestroyFormat, self).cancel()
|
||||
|
||||
@property
|
||||
@@ -834,6 +858,9 @@ class ActionResizeFormat(DeviceAction):
|
||||
return
|
||||
|
||||
self.device.format.target_size = self._target_size
|
||||
+ if hasattr(self.device, 'ignore_skip_activation'):
|
||||
+ self.device.ignore_skip_activation += 1
|
||||
+
|
||||
super(ActionResizeFormat, self).apply()
|
||||
|
||||
def execute(self, callbacks=None):
|
||||
@@ -854,6 +881,9 @@ class ActionResizeFormat(DeviceAction):
|
||||
return
|
||||
|
||||
self.device.format.target_size = self.orig_size
|
||||
+ if hasattr(self.device, 'ignore_skip_activation'):
|
||||
+ self.device.ignore_skip_activation -= 1
|
||||
+
|
||||
super(ActionResizeFormat, self).cancel()
|
||||
|
||||
def requires(self, action):
|
||||
@@ -1056,6 +1086,9 @@ class ActionConfigureFormat(DeviceAction):
|
||||
return
|
||||
|
||||
setattr(self.device.format, self.attr, self.new_value)
|
||||
+ if hasattr(self.device, 'ignore_skip_activation'):
|
||||
+ self.device.ignore_skip_activation += 1
|
||||
+
|
||||
super(ActionConfigureFormat, self).apply()
|
||||
|
||||
def cancel(self):
|
||||
@@ -1063,6 +1096,8 @@ class ActionConfigureFormat(DeviceAction):
|
||||
return
|
||||
|
||||
setattr(self.device.format, self.attr, self.old_value)
|
||||
+ if hasattr(self.device, 'ignore_skip_activation'):
|
||||
+ self.device.ignore_skip_activation -= 1
|
||||
|
||||
def execute(self, callbacks=None):
|
||||
super(ActionConfigureFormat, self).execute(callbacks=callbacks)
|
||||
diff --git a/blivet/devices/lvm.py b/blivet/devices/lvm.py
|
||||
index 06191110..58adf5cf 100644
|
||||
--- a/blivet/devices/lvm.py
|
||||
+++ b/blivet/devices/lvm.py
|
||||
@@ -628,6 +628,8 @@ class LVMLogicalVolumeBase(DMDevice, RaidDevice):
|
||||
self.uuid = uuid
|
||||
self.seg_type = seg_type or "linear"
|
||||
self._raid_level = None
|
||||
+ self.ignore_skip_activation = 0
|
||||
+
|
||||
if self.seg_type in lvm.raid_seg_types:
|
||||
self._raid_level = lvm.raid_levels.raid_level(self.seg_type)
|
||||
else:
|
||||
@@ -1367,12 +1369,6 @@ class LVMSnapshotMixin(object):
|
||||
# the old snapshot cannot be setup and torn down
|
||||
pass
|
||||
|
||||
- def _setup(self, orig=False):
|
||||
- """ Open, or set up, a device. """
|
||||
- log_method_call(self, self.name, orig=orig, status=self.status,
|
||||
- controllable=self.controllable)
|
||||
- blockdev.lvm.lvactivate(self.vg.name, self._name, ignore_skip=True)
|
||||
-
|
||||
@old_snapshot_specific
|
||||
def teardown(self, recursive=False):
|
||||
# the old snapshot cannot be setup and torn down
|
||||
@@ -1969,12 +1965,12 @@ class LVMLogicalVolumeDevice(LVMLogicalVolumeBase, LVMInternalLogicalVolumeMixin
|
||||
def display_lv_name(self):
|
||||
return self.lvname
|
||||
|
||||
- @type_specific
|
||||
def _setup(self, orig=False):
|
||||
""" Open, or set up, a device. """
|
||||
log_method_call(self, self.name, orig=orig, status=self.status,
|
||||
controllable=self.controllable)
|
||||
- blockdev.lvm.lvactivate(self.vg.name, self._name)
|
||||
+ ignore_skip_activation = self.is_snapshot_lv or self.ignore_skip_activation > 0
|
||||
+ blockdev.lvm.lvactivate(self.vg.name, self._name, ignore_skip=ignore_skip_activation)
|
||||
|
||||
@type_specific
|
||||
def _pre_create(self):
|
||||
diff --git a/tests/action_test.py b/tests/action_test.py
|
||||
index 101d5a21..24ed10b2 100644
|
||||
--- a/tests/action_test.py
|
||||
+++ b/tests/action_test.py
|
||||
@@ -1025,12 +1025,28 @@ class DeviceActionTestCase(StorageTestCase):
|
||||
# ActionDestroyFormat
|
||||
original_format = lv_root.format
|
||||
action = ActionDestroyFormat(lv_root)
|
||||
+ orig_ignore_skip = lv_root.ignore_skip_activation
|
||||
self.assertEqual(lv_root.format, original_format)
|
||||
self.assertNotEqual(lv_root.format.type, None)
|
||||
action.apply()
|
||||
self.assertEqual(lv_root.format.type, None)
|
||||
+ self.assertEqual(lv_root.ignore_skip_activation, orig_ignore_skip + 1)
|
||||
action.cancel()
|
||||
self.assertEqual(lv_root.format, original_format)
|
||||
+ self.assertEqual(lv_root.ignore_skip_activation, orig_ignore_skip)
|
||||
+
|
||||
+ # ActionDestroyDevice
|
||||
+ action1 = ActionDestroyFormat(lv_root)
|
||||
+ orig_ignore_skip = lv_root.ignore_skip_activation
|
||||
+ action1.apply()
|
||||
+ self.assertEqual(lv_root.ignore_skip_activation, orig_ignore_skip + 1)
|
||||
+ action2 = ActionDestroyDevice(lv_root)
|
||||
+ action2.apply()
|
||||
+ self.assertEqual(lv_root.ignore_skip_activation, orig_ignore_skip + 2)
|
||||
+ action2.cancel()
|
||||
+ self.assertEqual(lv_root.ignore_skip_activation, orig_ignore_skip + 1)
|
||||
+ action1.cancel()
|
||||
+ self.assertEqual(lv_root.ignore_skip_activation, orig_ignore_skip)
|
||||
|
||||
sdc = self.storage.devicetree.get_device_by_name("sdc")
|
||||
sdc.format = None
|
||||
diff --git a/tests/devices_test/lvm_test.py b/tests/devices_test/lvm_test.py
|
||||
index 76a3a5db..c4c50748 100644
|
||||
--- a/tests/devices_test/lvm_test.py
|
||||
+++ b/tests/devices_test/lvm_test.py
|
||||
@@ -360,6 +360,35 @@ class LVMDeviceTest(unittest.TestCase):
|
||||
with six.assertRaisesRegex(self, ValueError, "The volume group testvg cannot be created."):
|
||||
LVMVolumeGroupDevice("testvg", parents=[pv, pv2])
|
||||
|
||||
+ def test_skip_activate(self):
|
||||
+ pv = StorageDevice("pv1", fmt=blivet.formats.get_format("lvmpv"),
|
||||
+ size=Size("1 GiB"), exists=True)
|
||||
+ vg = LVMVolumeGroupDevice("testvg", parents=[pv], exists=True)
|
||||
+ lv = LVMLogicalVolumeDevice("data_lv", parents=[vg], size=Size("500 MiB"), exists=True)
|
||||
+
|
||||
+ with patch("blivet.devices.lvm.blockdev.lvm") as lvm:
|
||||
+ with patch.object(lv, "_pre_setup"):
|
||||
+ lv.setup()
|
||||
+ self.assertTrue(lvm.lvactivate.called_with(vg.name, lv.lvname, ignore_skip=False))
|
||||
+
|
||||
+ lv.ignore_skip_activation += 1
|
||||
+ with patch("blivet.devices.lvm.blockdev.lvm") as lvm:
|
||||
+ with patch.object(lv, "_pre_setup"):
|
||||
+ lv.setup()
|
||||
+ self.assertTrue(lvm.lvactivate.called_with(vg.name, lv.lvname, ignore_skip=True))
|
||||
+
|
||||
+ lv.ignore_skip_activation += 1
|
||||
+ with patch("blivet.devices.lvm.blockdev.lvm") as lvm:
|
||||
+ with patch.object(lv, "_pre_setup"):
|
||||
+ lv.setup()
|
||||
+ self.assertTrue(lvm.lvactivate.called_with(vg.name, lv.lvname, ignore_skip=True))
|
||||
+
|
||||
+ lv.ignore_skip_activation -= 2
|
||||
+ with patch("blivet.devices.lvm.blockdev.lvm") as lvm:
|
||||
+ with patch.object(lv, "_pre_setup"):
|
||||
+ lv.setup()
|
||||
+ self.assertTrue(lvm.lvactivate.called_with(vg.name, lv.lvname, ignore_skip=False))
|
||||
+
|
||||
|
||||
class TypeSpecificCallsTest(unittest.TestCase):
|
||||
def test_type_specific_calls(self):
|
||||
--
|
||||
2.24.1
|
||||
|
||||
|
||||
From 0e19f91ff0917b7c498cdc2e6d5484847cf18cee Mon Sep 17 00:00:00 2001
|
||||
From: David Lehman <dlehman@redhat.com>
|
||||
Date: Tue, 17 Dec 2019 14:43:02 -0500
|
||||
Subject: [PATCH 2/2] Make sure LVs are writable before wiping.
|
||||
|
||||
Related: rhbz#1766498
|
||||
---
|
||||
blivet/deviceaction.py | 3 +++
|
||||
blivet/devicelibs/lvm.py | 18 ++++++++++++++++++
|
||||
blivet/devices/lvm.py | 4 ++++
|
||||
3 files changed, 25 insertions(+)
|
||||
|
||||
diff --git a/blivet/deviceaction.py b/blivet/deviceaction.py
|
||||
index 57115662..ac89365b 100644
|
||||
--- a/blivet/deviceaction.py
|
||||
+++ b/blivet/deviceaction.py
|
||||
@@ -745,6 +745,9 @@ class ActionDestroyFormat(DeviceAction):
|
||||
super(ActionDestroyFormat, self).execute(callbacks=callbacks)
|
||||
status = self.device.status
|
||||
self.device.setup(orig=True)
|
||||
+ if hasattr(self.device, 'set_rw'):
|
||||
+ self.device.set_rw()
|
||||
+
|
||||
self.format.destroy()
|
||||
udev.settle()
|
||||
if isinstance(self.device, PartitionDevice) and self.device.disklabel_supported:
|
||||
diff --git a/blivet/devicelibs/lvm.py b/blivet/devicelibs/lvm.py
|
||||
index 8eea9d19..65dc425e 100644
|
||||
--- a/blivet/devicelibs/lvm.py
|
||||
+++ b/blivet/devicelibs/lvm.py
|
||||
@@ -38,7 +38,9 @@ from . import raid
|
||||
from ..size import Size
|
||||
from ..i18n import N_
|
||||
from ..flags import flags
|
||||
+from ..static_data import lvs_info
|
||||
from ..tasks import availability
|
||||
+from ..util import run_program
|
||||
|
||||
# some of lvm's defaults that we have no way to ask it for
|
||||
LVM_PE_START = Size("1 MiB")
|
||||
@@ -187,6 +189,22 @@ def lvmetad_socket_exists():
|
||||
return os.path.exists(LVMETAD_SOCKET_PATH)
|
||||
|
||||
|
||||
+def ensure_lv_is_writable(vg_name, lv_name):
|
||||
+ lv_info = lvs_info.cache.get("%s-%s" % (vg_name, lv_name))
|
||||
+ if lv_info is None:
|
||||
+ return
|
||||
+
|
||||
+ if lv_info.attr[1] == 'w':
|
||||
+ return
|
||||
+
|
||||
+ try:
|
||||
+ rc = run_program(['lvchange', '-prw', "%s/%s" % (vg_name, lv_name)])
|
||||
+ except OSError:
|
||||
+ rc = -1
|
||||
+
|
||||
+ return rc == 0
|
||||
+
|
||||
+
|
||||
def is_lvm_name_valid(name):
|
||||
# No . or ..
|
||||
if name == '.' or name == '..':
|
||||
diff --git a/blivet/devices/lvm.py b/blivet/devices/lvm.py
|
||||
index 58adf5cf..dbecc1e5 100644
|
||||
--- a/blivet/devices/lvm.py
|
||||
+++ b/blivet/devices/lvm.py
|
||||
@@ -951,6 +951,10 @@ class LVMLogicalVolumeBase(DMDevice, RaidDevice):
|
||||
# set up the vg's pvs so lvm can remove the lv
|
||||
self.vg.setup_parents(orig=True)
|
||||
|
||||
+ def set_rw(self):
|
||||
+ """ Run lvchange as needed to ensure the lv is not read-only. """
|
||||
+ lvm.ensure_lv_is_writable(self.vg.name, self.lvname)
|
||||
+
|
||||
@property
|
||||
def lvname(self):
|
||||
""" The LV's name (not including VG name). """
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,195 @@
|
||||
From 16db72b7adc5e1a295ecd52c0a53ee5a12111878 Mon Sep 17 00:00:00 2001
|
||||
From: David Lehman <dlehman@redhat.com>
|
||||
Date: Tue, 7 Jan 2020 17:10:24 -0500
|
||||
Subject: [PATCH 1/2] Make minimal and optimal alignment getters public.
|
||||
|
||||
Related: rhbz#1781106
|
||||
---
|
||||
blivet/formats/disklabel.py | 10 +++++-----
|
||||
tests/formats_test/disklabel_test.py | 6 +++---
|
||||
2 files changed, 8 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/blivet/formats/disklabel.py b/blivet/formats/disklabel.py
|
||||
index a435bc59..a3f9d04b 100644
|
||||
--- a/blivet/formats/disklabel.py
|
||||
+++ b/blivet/formats/disklabel.py
|
||||
@@ -462,7 +462,7 @@ class DiskLabel(DeviceFormat):
|
||||
|
||||
return self._disk_label_alignment
|
||||
|
||||
- def _get_minimal_alignment(self):
|
||||
+ def get_minimal_alignment(self):
|
||||
""" Return the device's minimal alignment for new partitions.
|
||||
|
||||
:rtype: :class:`parted.Alignment`
|
||||
@@ -484,7 +484,7 @@ class DiskLabel(DeviceFormat):
|
||||
|
||||
return self._minimal_alignment
|
||||
|
||||
- def _get_optimal_alignment(self):
|
||||
+ def get_optimal_alignment(self):
|
||||
""" Return the device's optimal alignment for new partitions.
|
||||
|
||||
:rtype: :class:`parted.Alignment`
|
||||
@@ -502,7 +502,7 @@ class DiskLabel(DeviceFormat):
|
||||
# if there is no optimal alignment, use the minimal alignment,
|
||||
# which has already been intersected with the disklabel
|
||||
# alignment
|
||||
- alignment = self._get_minimal_alignment()
|
||||
+ alignment = self.get_minimal_alignment()
|
||||
else:
|
||||
try:
|
||||
alignment = optimal_alignment.intersect(disklabel_alignment)
|
||||
@@ -524,13 +524,13 @@ class DiskLabel(DeviceFormat):
|
||||
small to be aligned
|
||||
"""
|
||||
# default to the optimal alignment
|
||||
- alignment = self._get_optimal_alignment()
|
||||
+ alignment = self.get_optimal_alignment()
|
||||
if size is None:
|
||||
return alignment
|
||||
|
||||
# use the minimal alignment if the requested size is smaller than the
|
||||
# optimal io size
|
||||
- minimal_alignment = self._get_minimal_alignment()
|
||||
+ minimal_alignment = self.get_minimal_alignment()
|
||||
optimal_grain_size = Size(alignment.grainSize * self.sector_size)
|
||||
minimal_grain_size = Size(minimal_alignment.grainSize * self.sector_size)
|
||||
if size < minimal_grain_size:
|
||||
diff --git a/tests/formats_test/disklabel_test.py b/tests/formats_test/disklabel_test.py
|
||||
index 93ce8c4a..6a1187e1 100644
|
||||
--- a/tests/formats_test/disklabel_test.py
|
||||
+++ b/tests/formats_test/disklabel_test.py
|
||||
@@ -41,8 +41,8 @@ class DiskLabelTestCase(unittest.TestCase):
|
||||
|
||||
# make sure the private methods all return the expected values
|
||||
self.assertEqual(dl._get_disk_label_alignment(), disklabel_alignment)
|
||||
- self.assertEqual(dl._get_minimal_alignment(), minimal_alignment)
|
||||
- self.assertEqual(dl._get_optimal_alignment(), optimal_alignment)
|
||||
+ self.assertEqual(dl.get_minimal_alignment(), minimal_alignment)
|
||||
+ self.assertEqual(dl.get_optimal_alignment(), optimal_alignment)
|
||||
|
||||
# validate result when passing a start alignment to get_end_alignment
|
||||
self.assertEqual(dl.get_end_alignment(alignment=optimal_alignment),
|
||||
@@ -61,7 +61,7 @@ class DiskLabelTestCase(unittest.TestCase):
|
||||
minimal_end_alignment)
|
||||
|
||||
# test the old deprecated properties' values
|
||||
- self.assertEqual(dl.alignment, dl._get_optimal_alignment())
|
||||
+ self.assertEqual(dl.alignment, dl.get_optimal_alignment())
|
||||
self.assertEqual(dl.end_alignment, dl.get_end_alignment())
|
||||
|
||||
@patch("blivet.formats.disklabel.arch")
|
||||
--
|
||||
2.24.1
|
||||
|
||||
|
||||
From f5810a412048bd445dbed02ce0d01e50a1d083ec Mon Sep 17 00:00:00 2001
|
||||
From: David Lehman <dlehman@redhat.com>
|
||||
Date: Tue, 7 Jan 2020 17:11:43 -0500
|
||||
Subject: [PATCH 2/2] Align base sizes up if smaller than min I/O size.
|
||||
|
||||
Resolves: rhbz#1781106
|
||||
---
|
||||
blivet/partitioning.py | 18 +++++++++++++++---
|
||||
tests/partitioning_test.py | 34 ++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 49 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/blivet/partitioning.py b/blivet/partitioning.py
|
||||
index 026a3f8c..bc0fe237 100644
|
||||
--- a/blivet/partitioning.py
|
||||
+++ b/blivet/partitioning.py
|
||||
@@ -408,7 +408,11 @@ def add_partition(disklabel, free, part_type, size, start=None, end=None):
|
||||
else:
|
||||
_size = size
|
||||
|
||||
- alignment = disklabel.get_alignment(size=_size)
|
||||
+ try:
|
||||
+ alignment = disklabel.get_alignment(size=_size)
|
||||
+ except AlignmentError:
|
||||
+ alignment = disklabel.get_minimal_alignment()
|
||||
+
|
||||
end_alignment = disklabel.get_end_alignment(alignment=alignment)
|
||||
else:
|
||||
alignment = parted.Alignment(grainSize=1, offset=0)
|
||||
@@ -646,7 +650,12 @@ def do_partitioning(storage, boot_disk=None):
|
||||
|
||||
def align_size_for_disklabel(size, disklabel):
|
||||
# Align the base size to the disk's grain size.
|
||||
- grain_size = Size(disklabel.alignment.grainSize)
|
||||
+ try:
|
||||
+ alignment = disklabel.get_alignment(size=size)
|
||||
+ except AlignmentError:
|
||||
+ alignment = disklabel.get_minimal_alignment()
|
||||
+
|
||||
+ grain_size = Size(alignment.grainSize)
|
||||
grains, rem = divmod(size, grain_size)
|
||||
return (grains * grain_size) + (grain_size if rem else Size(0))
|
||||
|
||||
@@ -751,7 +760,10 @@ def allocate_partitions(storage, disks, partitions, freespace, boot_disk=None):
|
||||
disklabel = disklabels[_disk.path]
|
||||
best = None
|
||||
current_free = free
|
||||
- alignment = disklabel.get_alignment(size=_part.req_size)
|
||||
+ try:
|
||||
+ alignment = disklabel.get_alignment(size=_part.req_size)
|
||||
+ except AlignmentError:
|
||||
+ alignment = disklabel.get_minimal_alignment()
|
||||
|
||||
# for growable requests, we don't want to pass the current free
|
||||
# geometry to get_best_free_region -- this allows us to try the
|
||||
diff --git a/tests/partitioning_test.py b/tests/partitioning_test.py
|
||||
index ebd05260..4fe87ebe 100644
|
||||
--- a/tests/partitioning_test.py
|
||||
+++ b/tests/partitioning_test.py
|
||||
@@ -179,6 +179,8 @@ class PartitioningTestCase(unittest.TestCase):
|
||||
min_str = 'parted.Device.minimumAlignment'
|
||||
opt_al = parted.Alignment(offset=0, grainSize=8192) # 4 MiB
|
||||
min_al = parted.Alignment(offset=0, grainSize=2048) # 1 MiB
|
||||
+ disk.format._minimal_alignment = None # drop cache
|
||||
+ disk.format._optimal_alignment = None # drop cache
|
||||
with patch(opt_str, opt_al) as optimal, patch(min_str, min_al) as minimal:
|
||||
optimal_end = disk.format.get_end_alignment(alignment=optimal)
|
||||
minimal_end = disk.format.get_end_alignment(alignment=minimal)
|
||||
@@ -201,6 +203,38 @@ class PartitioningTestCase(unittest.TestCase):
|
||||
disk.format.remove_partition(part)
|
||||
self.assertEqual(len(disk.format.partitions), 0)
|
||||
|
||||
+ #
|
||||
+ # adding a partition smaller than the minimal io size should yield
|
||||
+ # a partition whose size is aligned up to the minimal io size
|
||||
+ #
|
||||
+ opt_str = 'parted.Device.optimumAlignment'
|
||||
+ min_str = 'parted.Device.minimumAlignment'
|
||||
+ opt_al = parted.Alignment(offset=0, grainSize=8192) # 4 MiB
|
||||
+ min_al = parted.Alignment(offset=0, grainSize=2048) # 1 MiB
|
||||
+ disk.format._minimal_alignment = None # drop cache
|
||||
+ disk.format._optimal_alignment = None # drop cache
|
||||
+ with patch(opt_str, opt_al) as optimal, patch(min_str, min_al) as minimal:
|
||||
+ optimal_end = disk.format.get_end_alignment(alignment=optimal)
|
||||
+ minimal_end = disk.format.get_end_alignment(alignment=minimal)
|
||||
+
|
||||
+ sector_size = Size(disk.format.sector_size)
|
||||
+ length = 1024 # 512 KiB
|
||||
+ size = Size(sector_size * length)
|
||||
+ part = add_partition(disk.format, free, parted.PARTITION_NORMAL,
|
||||
+ size)
|
||||
+ self.assertEqual(part.geometry.length, min_al.grainSize)
|
||||
+ self.assertEqual(optimal.isAligned(free, part.geometry.start),
|
||||
+ False)
|
||||
+ self.assertEqual(minimal.isAligned(free, part.geometry.start),
|
||||
+ True)
|
||||
+ self.assertEqual(optimal_end.isAligned(free, part.geometry.end),
|
||||
+ False)
|
||||
+ self.assertEqual(minimal_end.isAligned(free, part.geometry.end),
|
||||
+ True)
|
||||
+
|
||||
+ disk.format.remove_partition(part)
|
||||
+ self.assertEqual(len(disk.format.partitions), 0)
|
||||
+
|
||||
#
|
||||
# add a partition with an unaligned start sector
|
||||
#
|
||||
--
|
||||
2.24.1
|
||||
|
@ -0,0 +1,130 @@
|
||||
From 4e23e410bb5fcab5db931ad42a9b46af6be4fb3d Mon Sep 17 00:00:00 2001
|
||||
From: David Lehman <dlehman@redhat.com>
|
||||
Date: Thu, 16 Jan 2020 13:14:29 -0500
|
||||
Subject: [PATCH 1/2] Add recognition of Dell FW RAID to udev.device_is_disk.
|
||||
|
||||
Resolves: rhbz#1758102
|
||||
---
|
||||
blivet/udev.py | 16 +++++++++++++++-
|
||||
tests/udev_test.py | 42 ++++++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 57 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/blivet/udev.py b/blivet/udev.py
|
||||
index 53e7b7ca..df2b4e64 100644
|
||||
--- a/blivet/udev.py
|
||||
+++ b/blivet/udev.py
|
||||
@@ -353,7 +353,7 @@ def device_is_disk(info):
|
||||
device_is_dm_lvm(info) or
|
||||
device_is_dm_crypt(info) or
|
||||
(device_is_md(info) and
|
||||
- not device_get_md_container(info))))
|
||||
+ (not device_get_md_container(info) and not all(device_is_disk(d) for d in device_get_slaves(info))))))
|
||||
|
||||
|
||||
def device_is_partition(info):
|
||||
@@ -432,6 +432,20 @@ def device_get_devname(info):
|
||||
return info.get('DEVNAME')
|
||||
|
||||
|
||||
+def device_get_slaves(info):
|
||||
+ """ Return a list of udev device objects representing this device's slaves. """
|
||||
+ slaves_dir = device_get_sysfs_path(info) + "/slaves/"
|
||||
+ names = list()
|
||||
+ if os.path.isdir(slaves_dir):
|
||||
+ names = os.listdir(slaves_dir)
|
||||
+
|
||||
+ slaves = list()
|
||||
+ for name in names:
|
||||
+ slaves.append(get_device(device_node="/dev/" + name))
|
||||
+
|
||||
+ return slaves
|
||||
+
|
||||
+
|
||||
def device_get_md_level(info):
|
||||
""" Returns the RAID level of the array of which this device is a member.
|
||||
|
||||
diff --git a/tests/udev_test.py b/tests/udev_test.py
|
||||
index 5cc81a05..beb8109c 100644
|
||||
--- a/tests/udev_test.py
|
||||
+++ b/tests/udev_test.py
|
||||
@@ -35,3 +35,45 @@ class UdevTest(unittest.TestCase):
|
||||
import blivet.udev
|
||||
blivet.udev.trigger()
|
||||
self.assertTrue(blivet.udev.util.run_program.called)
|
||||
+
|
||||
+ @mock.patch('blivet.udev.device_is_cdrom', return_value=False)
|
||||
+ @mock.patch('blivet.udev.device_is_partition', return_value=False)
|
||||
+ @mock.patch('blivet.udev.device_is_dm_partition', return_value=False)
|
||||
+ @mock.patch('blivet.udev.device_is_dm_lvm', return_value=False)
|
||||
+ @mock.patch('blivet.udev.device_is_dm_crypt', return_value=False)
|
||||
+ @mock.patch('blivet.udev.device_is_md')
|
||||
+ @mock.patch('blivet.udev.device_get_md_container')
|
||||
+ @mock.patch('blivet.udev.device_get_slaves')
|
||||
+ def test_udev_device_is_disk_md(self, *args):
|
||||
+ import blivet.udev
|
||||
+ info = dict(DEVTYPE='disk', SYS_PATH=mock.sentinel.md_path)
|
||||
+ (device_get_slaves, device_get_md_container, device_is_md) = args[:3] # pylint: disable=unbalanced-tuple-unpacking
|
||||
+
|
||||
+ disk_parents = [dict(DEVTYPE="disk", SYS_PATH='/fake/path/2'),
|
||||
+ dict(DEVTYPE="disk", SYS_PATH='/fake/path/3')]
|
||||
+ partition_parents = [dict(DEVTYPE="partition", SYS_PATH='/fake/path/2'),
|
||||
+ dict(DEVTYPE="partition", SYS_PATH='/fake/path/3')]
|
||||
+ mixed_parents = [dict(DEVTYPE="partition", SYS_PATH='/fake/path/2'),
|
||||
+ dict(DEVTYPE="partition", SYS_PATH='/fake/path/3')]
|
||||
+
|
||||
+ blivet.udev.os.path.exists.return_value = False # has_range checked in device_is_disk
|
||||
+ device_is_md.return_value = True
|
||||
+
|
||||
+ # Intel FW RAID (MD RAID w/ container layer)
|
||||
+ # device_get_container will return some mock value which will evaluate to True
|
||||
+ device_get_md_container.return_value = mock.sentinel.md_container
|
||||
+ device_get_slaves.side_effect = lambda info: list()
|
||||
+ self.assertTrue(blivet.udev.device_is_disk(info))
|
||||
+
|
||||
+ # Normal MD RAID
|
||||
+ device_get_slaves.side_effect = lambda info: partition_parents if info['SYS_PATH'] == mock.sentinel.md_path else list()
|
||||
+ device_get_md_container.return_value = None
|
||||
+ self.assertFalse(blivet.udev.device_is_disk(info))
|
||||
+
|
||||
+ # Dell FW RAID (MD RAID whose members are all whole disks)
|
||||
+ device_get_slaves.side_effect = lambda info: disk_parents if info['SYS_PATH'] == mock.sentinel.md_path else list()
|
||||
+ self.assertTrue(blivet.udev.device_is_disk(info))
|
||||
+
|
||||
+ # Normal MD RAID (w/ at least one non-disk member)
|
||||
+ device_get_slaves.side_effect = lambda info: mixed_parents if info['SYS_PATH'] == mock.sentinel.md_path else list()
|
||||
+ self.assertFalse(blivet.udev.device_is_disk(info))
|
||||
--
|
||||
2.24.1
|
||||
|
||||
|
||||
From 1d75298702f55830a3d69858c3b0b7defa7bf6f2 Mon Sep 17 00:00:00 2001
|
||||
From: David Lehman <dlehman@redhat.com>
|
||||
Date: Tue, 21 Jan 2020 15:28:27 -0500
|
||||
Subject: [PATCH 2/2] Fix udev test names so they actually get run.
|
||||
|
||||
---
|
||||
tests/udev_test.py | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/tests/udev_test.py b/tests/udev_test.py
|
||||
index beb8109c..653eeb6d 100644
|
||||
--- a/tests/udev_test.py
|
||||
+++ b/tests/udev_test.py
|
||||
@@ -26,12 +26,12 @@ class UdevTest(unittest.TestCase):
|
||||
for device in devices:
|
||||
self.assertNotEqual(blivet.udev.get_device(device.sys_path), None)
|
||||
|
||||
- def udev_settle_test(self):
|
||||
+ def test_udev_settle(self):
|
||||
import blivet.udev
|
||||
blivet.udev.settle()
|
||||
self.assertTrue(blivet.udev.util.run_program.called)
|
||||
|
||||
- def udev_trigger_test(self):
|
||||
+ def test_udev_trigger(self):
|
||||
import blivet.udev
|
||||
blivet.udev.trigger()
|
||||
self.assertTrue(blivet.udev.util.run_program.called)
|
||||
--
|
||||
2.24.1
|
||||
|
71
SOURCES/0029-add-y-to-lvm.pvcreate.patch
Normal file
71
SOURCES/0029-add-y-to-lvm.pvcreate.patch
Normal file
@ -0,0 +1,71 @@
|
||||
From a873679b9440105740e7e34f5a3fc9ce0f2c2ace Mon Sep 17 00:00:00 2001
|
||||
From: Hongxu Jia <hongxu.jia@windriver.com>
|
||||
Date: Tue, 28 Aug 2018 09:41:38 +0800
|
||||
Subject: [PATCH 1/2] add `-y' to lvm.pvcreate
|
||||
|
||||
While reinstall a crypt fs, it occasionally failed
|
||||
[snip]
|
||||
|gi.overrides.BlockDev.LVMError: Process reported exit code 5:
|
||||
WARNING: atari signature detected on /dev/mapper/luks-0e5f891c
|
||||
-7701-48bc-a41e-8d626b6ef953 at offset 466. Wipe it? [y/n]:
|
||||
[snip]
|
||||
|
||||
Add `-y' to lvm.pvcreate
|
||||
|
||||
Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
|
||||
---
|
||||
blivet/formats/lvmpv.py | 5 ++---
|
||||
1 file changed, 2 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/blivet/formats/lvmpv.py b/blivet/formats/lvmpv.py
|
||||
index 260cc0bd..96d25394 100644
|
||||
--- a/blivet/formats/lvmpv.py
|
||||
+++ b/blivet/formats/lvmpv.py
|
||||
@@ -120,9 +120,8 @@ class LVMPhysicalVolume(DeviceFormat):
|
||||
log_method_call(self, device=self.device,
|
||||
type=self.type, status=self.status)
|
||||
|
||||
- # Consider use of -Z|--zero
|
||||
- # -f|--force or -y|--yes may be required
|
||||
- blockdev.lvm.pvcreate(self.device, data_alignment=self.data_alignment)
|
||||
+ ea_yes = blockdev.ExtraArg.new("-y", "")
|
||||
+ blockdev.lvm.pvcreate(self.device, data_alignment=self.data_alignment, extra=[ea_yes])
|
||||
|
||||
def _destroy(self, **kwargs):
|
||||
log_method_call(self, device=self.device,
|
||||
--
|
||||
2.24.1
|
||||
|
||||
|
||||
From d3d86ec2383bbd8e2797ebaaed551a3fbe8ee437 Mon Sep 17 00:00:00 2001
|
||||
From: Vojtech Trefny <vtrefny@redhat.com>
|
||||
Date: Wed, 29 Aug 2018 10:05:29 +0200
|
||||
Subject: [PATCH 2/2] Adjust LVMPhysicalVolumeMethodsTestCase to new pvcreate
|
||||
option
|
||||
|
||||
Adjust tests to changes in f8a7ee3dbd6617eb9a0add96b2c4d124d78a1b98
|
||||
---
|
||||
tests/formats_test/methods_test.py | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tests/formats_test/methods_test.py b/tests/formats_test/methods_test.py
|
||||
index 741c4f15..710fa1c5 100644
|
||||
--- a/tests/formats_test/methods_test.py
|
||||
+++ b/tests/formats_test/methods_test.py
|
||||
@@ -389,10 +389,12 @@ class LVMPhysicalVolumeMethodsTestCase(FormatMethodsTestCase):
|
||||
self.patches["blockdev"].lvm.pvremove.assert_called_with(self.format.device)
|
||||
|
||||
def _test_create_backend(self):
|
||||
+ self.patches["blockdev"].ExtraArg.new.return_value = sentinel.extra_arg
|
||||
self.format.exists = False
|
||||
self.format.create()
|
||||
self.patches["blockdev"].lvm.pvcreate.assert_called_with(self.format.device,
|
||||
- data_alignment=self.format.data_alignment) # pylint: disable=no-member
|
||||
+ data_alignment=self.format.data_alignment, # pylint: disable=no-member
|
||||
+ extra=[sentinel.extra_arg])
|
||||
|
||||
|
||||
class MDRaidMemberMethodsTestCase(FormatMethodsTestCase):
|
||||
--
|
||||
2.24.1
|
||||
|
@ -23,7 +23,7 @@ Version: 3.1.0
|
||||
|
||||
#%%global prerelease .b2
|
||||
# prerelease, if defined, should be something like .a1, .b1, .b2.dev1, or .c2
|
||||
Release: 17%{?prerelease}%{?dist}
|
||||
Release: 20%{?prerelease}%{?dist}
|
||||
Epoch: 1
|
||||
License: LGPLv2+
|
||||
Group: System Environment/Libraries
|
||||
@ -56,6 +56,11 @@ Patch21: 0021-Correctly-handle-non-unicode-iSCSI-initiator-names.patch
|
||||
Patch22: 0022-Do-not-crash-if-dm_get_member_raid_sets-fails.patch
|
||||
Patch23: 0023-Minor-cleanups-to-reduce-log-noise.patch
|
||||
Patch24: 0024-Fix-util.detect_virt-function.patch
|
||||
Patch25: 0025-Check-for-PV-sector-size-when-creating-new-VG.patch
|
||||
Patch26: 0026-Tell-lvm-to-ignore-skip-activation-flag-on-lvs-we-are-removing-or-otherwise-modifying.patch
|
||||
Patch27: 0027-Align-base-partition-sizes-in-PartitionFactory.patch
|
||||
Patch28: 0028-Add-recognition-of-Dell-FW-RAID-to-udev-device_is_disk.patch
|
||||
Patch29: 0029-add-y-to-lvm.pvcreate.patch
|
||||
|
||||
# Versions of required components (done so we make sure the buildrequires
|
||||
# match the requires versions of things).
|
||||
@ -218,6 +223,28 @@ configuration.
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Mon Mar 02 2020 Vojtech Trefny <vtrefny@redhat.com> - 3.1.0-20
|
||||
- add `-y' to lvm.pvcreate
|
||||
Resolves: rhbz#1768494
|
||||
|
||||
* Wed Jan 29 2020 Vojtech Trefny <vtrefny@redhat.com> - 3.1.0-19
|
||||
- Override LVM skip-activation to allow for thorough removal
|
||||
Resolves: rhbz#1766498
|
||||
- Make sure LVs are writable before wiping
|
||||
Related: rhbz#1766498
|
||||
- Fix udev test names so they actually get run.
|
||||
Related: rhbz#1758102
|
||||
- Add recognition of Dell FW RAID to udev.device_is_disk.
|
||||
Resolves: rhbz#1758102
|
||||
- Align base sizes up if smaller than min I/O size.
|
||||
Resolves: rhbz#1781106
|
||||
- Make minimal and optimal alignment getters public.
|
||||
Related: rhbz#1781106
|
||||
|
||||
* Tue Nov 19 2019 Vojtech Trefny <vtrefny@redhat.com> - 3.1.0-18
|
||||
- Check for PV sector size when creating new VG
|
||||
Resolves: rhbz#1754446
|
||||
|
||||
* Wed Oct 02 2019 David Lehman <dlehman@redhat.com> - 3.1.0-17
|
||||
- Fix util.detect_virt function
|
||||
Resolves: rhbz#1676935
|
||||
|
Loading…
Reference in New Issue
Block a user