Adds software raid creation support on nvme drives.
Change-Id: Ia725fcaee6018255af3dd7ff0eb2fb1cfbd2b322 Story: #2006341 Task: #36091
This commit is contained in:
parent
248a4ccda5
commit
570584f9ab
@ -1454,6 +1454,15 @@ class GenericHardwareManager(HardwareManager):
|
||||
utils.execute('parted', device.name, '-s', '-a',
|
||||
'optimal', '--', 'mkpart', 'primary',
|
||||
sector, psize)
|
||||
# Necessary, if we want to avoid hitting
|
||||
# an error when creating the mdadm array below
|
||||
# 'mdadm: cannot open /dev/nvme1n1p1: No such file
|
||||
# or directory'.
|
||||
# The real difference between partx and partprobe is
|
||||
# unclear, but note that partprobe does not seem to
|
||||
# work synchronously for nvme drives...
|
||||
utils.execute("partx", "-u", device.name,
|
||||
check_exit_code=False)
|
||||
except processutils.ProcessExecutionError as e:
|
||||
msg = "Failed to create partitions on {}: {}".format(
|
||||
device.name, e)
|
||||
@ -1464,8 +1473,14 @@ class GenericHardwareManager(HardwareManager):
|
||||
raid_device_count = len(block_devices)
|
||||
for index, logical_disk in enumerate(logical_disks):
|
||||
md_device = '/dev/md%d' % index
|
||||
component_devices = [device.name + str(index + 1)
|
||||
for device in block_devices]
|
||||
component_devices = []
|
||||
for device in block_devices:
|
||||
# The partition delimiter for all common harddrives (sd[a-z]+)
|
||||
part_delimiter = ''
|
||||
if 'nvme' in device.name:
|
||||
part_delimiter = 'p'
|
||||
component_devices.append(
|
||||
device.name + part_delimiter + str(index + 1))
|
||||
raid_level = logical_disk['raid_level']
|
||||
# The schema check allows '1+0', but mdadm knows it as '10'.
|
||||
if raid_level == '1+0':
|
||||
|
@ -2594,12 +2594,16 @@ class TestGenericHardwareManager(base.IronicAgentTest):
|
||||
mock.call('parted', '/dev/sdb', '-s', '--', 'mklabel', 'msdos'),
|
||||
mock.call('parted', '/dev/sda', '-s', '-a', 'optimal', '--',
|
||||
'mkpart', 'primary', '2048s', 102400),
|
||||
mock.call('partx', '-u', '/dev/sda', check_exit_code=False),
|
||||
mock.call('parted', '/dev/sdb', '-s', '-a', 'optimal', '--',
|
||||
'mkpart', 'primary', '2048s', 102400),
|
||||
mock.call('partx', '-u', '/dev/sdb', check_exit_code=False),
|
||||
mock.call('parted', '/dev/sda', '-s', '-a', 'optimal', '--',
|
||||
'mkpart', 'primary', 102400, '-1'),
|
||||
mock.call('partx', '-u', '/dev/sda', check_exit_code=False),
|
||||
mock.call('parted', '/dev/sdb', '-s', '-a', 'optimal', '--',
|
||||
'mkpart', 'primary', 102400, '-1'),
|
||||
mock.call('partx', '-u', '/dev/sdb', check_exit_code=False),
|
||||
mock.call('mdadm', '--create', '/dev/md0', '--force', '--run',
|
||||
'--metadata=1', '--level', '1', '--raid-devices', 2,
|
||||
'/dev/sda1', '/dev/sdb1'),
|
||||
@ -2696,7 +2700,7 @@ class TestGenericHardwareManager(base.IronicAgentTest):
|
||||
# partition creation
|
||||
error_regex = "Failed to create partitions on /dev/sda"
|
||||
mocked_execute.side_effect = [
|
||||
None, None, # partition tables on sd{a,b}
|
||||
None, None, # partition tables and partx on sd{a,b}
|
||||
processutils.ProcessExecutionError]
|
||||
self.assertRaisesRegex(errors.SoftwareRAIDError, error_regex,
|
||||
self.hardware.create_configuration,
|
||||
@ -2706,8 +2710,116 @@ class TestGenericHardwareManager(base.IronicAgentTest):
|
||||
"on /dev/sda1 /dev/sdb1")
|
||||
mocked_execute.side_effect = [
|
||||
None, None, # partition tables on sd{a,b}
|
||||
None, None, # RAID-1 partitions on sd{a,b}
|
||||
None, None, # RAID-N partitions on sd{a,b}
|
||||
None, None, None, None, # RAID-1 partitions on sd{a,b} + partx
|
||||
None, None, None, None, # RAID-N partitions on sd{a,b} + partx
|
||||
processutils.ProcessExecutionError]
|
||||
self.assertRaisesRegex(errors.SoftwareRAIDError, error_regex,
|
||||
self.hardware.create_configuration,
|
||||
self.node, [])
|
||||
|
||||
@mock.patch.object(utils, 'execute', autospec=True)
|
||||
def test_create_configuration_with_nvme(self, mocked_execute):
|
||||
raid_config = {
|
||||
"logical_disks": [
|
||||
{
|
||||
"size_gb": "100",
|
||||
"raid_level": "1",
|
||||
"controller": "software",
|
||||
},
|
||||
{
|
||||
"size_gb": "MAX",
|
||||
"raid_level": "0",
|
||||
"controller": "software",
|
||||
},
|
||||
]
|
||||
}
|
||||
self.node['target_raid_config'] = raid_config
|
||||
device1 = hardware.BlockDevice('/dev/nvme0n1', 'nvme0n1',
|
||||
1073741824, True)
|
||||
device2 = hardware.BlockDevice('/dev/nvme1n1', 'nvme1n1',
|
||||
1073741824, True)
|
||||
self.hardware.list_block_devices = mock.Mock()
|
||||
self.hardware.list_block_devices.return_value = [device1, device2]
|
||||
|
||||
result = self.hardware.create_configuration(self.node, [])
|
||||
|
||||
mocked_execute.assert_has_calls([
|
||||
mock.call('parted', '/dev/nvme0n1', '-s', '--', 'mklabel',
|
||||
'msdos'),
|
||||
mock.call('parted', '/dev/nvme1n1', '-s', '--', 'mklabel',
|
||||
'msdos'),
|
||||
mock.call('parted', '/dev/nvme0n1', '-s', '-a', 'optimal', '--',
|
||||
'mkpart', 'primary', '2048s', 102400),
|
||||
mock.call('partx', '-u', '/dev/nvme0n1', check_exit_code=False),
|
||||
mock.call('parted', '/dev/nvme1n1', '-s', '-a', 'optimal', '--',
|
||||
'mkpart', 'primary', '2048s', 102400),
|
||||
mock.call('partx', '-u', '/dev/nvme1n1', check_exit_code=False),
|
||||
mock.call('parted', '/dev/nvme0n1', '-s', '-a', 'optimal', '--',
|
||||
'mkpart', 'primary', 102400, '-1'),
|
||||
mock.call('partx', '-u', '/dev/nvme0n1', check_exit_code=False),
|
||||
mock.call('parted', '/dev/nvme1n1', '-s', '-a', 'optimal', '--',
|
||||
'mkpart', 'primary', 102400, '-1'),
|
||||
mock.call('partx', '-u', '/dev/nvme1n1', check_exit_code=False),
|
||||
mock.call('mdadm', '--create', '/dev/md0', '--force', '--run',
|
||||
'--metadata=1', '--level', '1', '--raid-devices', 2,
|
||||
'/dev/nvme0n1p1', '/dev/nvme1n1p1'),
|
||||
mock.call('mdadm', '--create', '/dev/md1', '--force', '--run',
|
||||
'--metadata=1', '--level', '0', '--raid-devices', 2,
|
||||
'/dev/nvme0n1p2', '/dev/nvme1n1p2')])
|
||||
self.assertEqual(raid_config, result)
|
||||
|
||||
@mock.patch.object(utils, 'execute', autospec=True)
|
||||
def test_create_configuration_failure_with_nvme(self, mocked_execute):
|
||||
raid_config = {
|
||||
"logical_disks": [
|
||||
{
|
||||
"size_gb": "100",
|
||||
"raid_level": "1",
|
||||
"controller": "software",
|
||||
},
|
||||
{
|
||||
"size_gb": "MAX",
|
||||
"raid_level": "0",
|
||||
"controller": "software",
|
||||
},
|
||||
]
|
||||
}
|
||||
self.node['target_raid_config'] = raid_config
|
||||
device1 = hardware.BlockDevice('/dev/nvme0n1', 'nvme0n1',
|
||||
1073741824, True)
|
||||
device2 = hardware.BlockDevice('/dev/nvme1n1', 'nvme1n1',
|
||||
1073741824, True)
|
||||
self.hardware.list_block_devices = mock.Mock()
|
||||
self.hardware.list_block_devices.side_effect = [
|
||||
[device1, device2],
|
||||
[device1, device2],
|
||||
[device1, device2],
|
||||
[device1, device2],
|
||||
[device1, device2],
|
||||
[device1, device2]]
|
||||
|
||||
# partition table creation
|
||||
error_regex = "Failed to create partition table on /dev/nvme0n1"
|
||||
mocked_execute.side_effect = [
|
||||
processutils.ProcessExecutionError]
|
||||
self.assertRaisesRegex(errors.SoftwareRAIDError, error_regex,
|
||||
self.hardware.create_configuration,
|
||||
self.node, [])
|
||||
# partition creation
|
||||
error_regex = "Failed to create partitions on /dev/nvme0n1"
|
||||
mocked_execute.side_effect = [
|
||||
None, None, # partition tables and partx on sd{a,b}
|
||||
processutils.ProcessExecutionError]
|
||||
self.assertRaisesRegex(errors.SoftwareRAIDError, error_regex,
|
||||
self.hardware.create_configuration,
|
||||
self.node, [])
|
||||
# raid device creation
|
||||
error_regex = ("Failed to create md device /dev/md0 "
|
||||
"on /dev/nvme0n1p1 /dev/nvme1n1p1")
|
||||
mocked_execute.side_effect = [
|
||||
None, None, # partition tables on sd{a,b}
|
||||
None, None, None, None, # RAID-1 partitions on sd{a,b} + partx
|
||||
None, None, None, None, # RAID-N partitions on sd{a,b} + partx
|
||||
processutils.ProcessExecutionError]
|
||||
self.assertRaisesRegex(errors.SoftwareRAIDError, error_regex,
|
||||
self.hardware.create_configuration,
|
||||
|
@ -0,0 +1,3 @@
|
||||
---
|
||||
features:
|
||||
- Adds software raid creation support on nvme drives.
|
Loading…
Reference in New Issue
Block a user