summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.opendev.org>2020-08-12 16:39:01 +0000
committerGerrit Code Review <review@openstack.org>2020-08-12 16:39:01 +0000
commit9ab511c4661d78cd8fb83792dbbe0846d254de91 (patch)
treedab97cf337dad8d87f29a5b60ad1ff2bbcb8c46b
parent0153622c289e0af4d5895098468d1b1c118fb8bf (diff)
parentc78d6beedd4ed7bebb113d7f1597e035f1d01a57 (diff)
downloadironic-python-agent-9ab511c4661d78cd8fb83792dbbe0846d254de91.tar.gz
Merge "Fix bootloader install issue with MDRAID" into stable/ussuri
-rw-r--r--ironic_python_agent/hardware.py30
-rw-r--r--ironic_python_agent/tests/unit/test_hardware.py21
-rw-r--r--releasenotes/notes/fix-bootloader-install-with-mdraid-0a254035df9d0bed.yaml7
3 files changed, 52 insertions, 6 deletions
diff --git a/ironic_python_agent/hardware.py b/ironic_python_agent/hardware.py
index b8dc644c..76507c84 100644
--- a/ironic_python_agent/hardware.py
+++ b/ironic_python_agent/hardware.py
@@ -358,12 +358,24 @@ def list_all_block_devices(block_type='disk',
# Other possible type values, which we skip recording:
# lvm, part, rom, loop
if devtype != block_type:
- if (devtype is not None
- and any(x in devtype for x in ['raid', 'md'])
- and not ignore_raid):
+ if (devtype is None or ignore_raid):
+ LOG.debug("Skipping: {!r}".format(line))
+ continue
+ elif ('raid' in devtype
+ and block_type in ['raid', 'disk']):
LOG.debug(
- "TYPE detected to contain 'raid' or 'md', signifying a "
+ "TYPE detected to contain 'raid', signifying a "
"RAID volume. Found: {!r}".format(line))
+ elif (devtype == 'md'
+ and (block_type == 'part'
+ or block_type == 'md')):
+ # NOTE(dszumski): Partitions on software RAID devices have type
+ # 'md'. This may also contain RAID devices in a broken state in
+ # rare occasions. See https://review.opendev.org/#/c/670807 for
+ # more detail.
+ LOG.debug(
+ "TYPE detected to contain 'md', signifying a "
+ "RAID partition. Found: {!r}".format(line))
else:
LOG.debug(
"TYPE did not match. Wanted: {!r} but found: {!r}".format(
@@ -1786,6 +1798,16 @@ class GenericHardwareManager(HardwareManager):
raid_devices = list_all_block_devices(block_type='raid',
ignore_raid=False,
ignore_empty=False)
+ # NOTE(dszumski): Fetch all devices of type 'md'. This
+ # will generally contain partitions on a software RAID
+ # device, but crucially may also contain devices in a
+ # broken state. See https://review.opendev.org/#/c/670807/
+ # for more detail.
+ raid_devices.extend(
+ list_all_block_devices(block_type='md',
+ ignore_raid=False,
+ ignore_empty=False)
+ )
return raid_devices
raid_devices = _scan_raids()
diff --git a/ironic_python_agent/tests/unit/test_hardware.py b/ironic_python_agent/tests/unit/test_hardware.py
index e298212b..4f049b43 100644
--- a/ironic_python_agent/tests/unit/test_hardware.py
+++ b/ironic_python_agent/tests/unit/test_hardware.py
@@ -163,13 +163,24 @@ BLK_DEVICE_TEMPLATE_SMALL_DEVICES = [
# NOTE(TheJulia): This list intentionally contains duplicates
# as the code filters them out by kernel device name.
+# NOTE(dszumski): We include some partitions here to verify that
+# they are filtered out when not requested. It is assumed that
+# ROTA has been set to 0 on some software RAID devices for testing
+# purposes. In practice is appears to inherit from the underyling
+# devices, so in this example it would normally be 1.
RAID_BLK_DEVICE_TEMPLATE = (
'KNAME="sda" MODEL="DRIVE 0" SIZE="1765517033472" '
'ROTA="1" TYPE="disk"\n'
+ 'KNAME="sda1" MODEL="DRIVE 0" SIZE="107373133824" '
+ 'ROTA="1" TYPE="part"\n'
'KNAME="sdb" MODEL="DRIVE 1" SIZE="1765517033472" '
'ROTA="1" TYPE="disk"\n'
'KNAME="sdb" MODEL="DRIVE 1" SIZE="1765517033472" '
'ROTA="1" TYPE="disk"\n'
+ 'KNAME="sdb1" MODEL="DRIVE 1" SIZE="107373133824" '
+ 'ROTA="1" TYPE="part"\n'
+ 'KNAME="md0p1" MODEL="RAID" SIZE="107236818944" '
+ 'ROTA="0" TYPE="md"\n'
'KNAME="md0" MODEL="RAID" SIZE="1765517033470" '
'ROTA="0" TYPE="raid1"\n'
'KNAME="md0" MODEL="RAID" SIZE="1765517033470" '
@@ -3910,9 +3921,11 @@ class TestGenericHardwareManager(base.IronicAgentTest):
hardware.list_all_block_devices.side_effect = [
[raid_device1, raid_device2], # list_all_block_devices raid
+ [], # list_all_block_devices raid (md)
[sda, sdb, sdc], # list_all_block_devices disks
[], # list_all_block_devices parts
[], # list_all_block_devices raid
+ [], # list_all_block_devices raid (md)
]
mocked_get_component.side_effect = [
["/dev/sda1", "/dev/sdb1"],
@@ -3992,13 +4005,14 @@ class TestGenericHardwareManager(base.IronicAgentTest):
raid_device1_part1 = hardware.BlockDevice('/dev/md0p1', 'RAID-1',
1073741824, True)
hardware.list_all_block_devices.side_effect = [
- [raid_device1_part1], # list_all_block_devices raid
+ [], # list_all_block_devices raid
+ [raid_device1_part1], # list_all_block_devices raid (md)
[], # list_all_block_devices disks
[], # list_all_block_devices parts
[], # list_all_block_devices raid
+ [], # list_all_block_devices raid (md)
]
mocked_get_component.return_value = []
-
self.assertIsNone(self.hardware.delete_configuration(self.node, []))
mocked_execute.assert_has_calls([
mock.call('mdadm', '--assemble', '--scan', check_exit_code=False),
@@ -4019,12 +4033,15 @@ class TestGenericHardwareManager(base.IronicAgentTest):
hardware.list_all_block_devices.side_effect = [
[raid_device1], # list_all_block_devices raid
+ [], # list_all_block_devices raid (type md)
[], # list_all_block_devices disks
[], # list_all_block_devices parts
[raid_device1], # list_all_block_devices raid
+ [], # list_all_block_devices raid (type md)
[], # list_all_block_devices disks
[], # list_all_block_devices parts
[raid_device1], # list_all_block_devices raid
+ [], # list_all_block_devices raid (type md)
]
mocked_get_component.return_value = []
diff --git a/releasenotes/notes/fix-bootloader-install-with-mdraid-0a254035df9d0bed.yaml b/releasenotes/notes/fix-bootloader-install-with-mdraid-0a254035df9d0bed.yaml
new file mode 100644
index 00000000..b9a1f685
--- /dev/null
+++ b/releasenotes/notes/fix-bootloader-install-with-mdraid-0a254035df9d0bed.yaml
@@ -0,0 +1,7 @@
+---
+fixes:
+ - |
+ Fixes an issue where the bootloader installation can fail on a software
+ RAID volume when no root_device hint is set.
+ See `Story 2007905
+ <https://storyboard.openstack.org/#!/story/2007905>`_