Software RAID: Don't delete partitions too early

Partions on the holder disk should only be deleted after
all RAID devices have been deleted. Otherwise, super blocks
on partitions which reside on the same disks cannot be cleaned.

Story: #2008199
Task: #40979
Change-Id: I19293f5b992cd1fa68957d6f306dcec8f3b7a820
This commit is contained in:
Arne Wiebalck 2020-09-28 10:31:15 +02:00
parent 6cb781b24e
commit c7aec775ff
3 changed files with 27 additions and 12 deletions

View File

@ -1881,6 +1881,7 @@ class GenericHardwareManager(HardwareManager):
raise errors.SoftwareRAIDError(msg) raise errors.SoftwareRAIDError(msg)
def _delete_config_pass(self, raid_devices): def _delete_config_pass(self, raid_devices):
all_holder_disks = []
for raid_device in raid_devices: for raid_device in raid_devices:
component_devices = _get_component_devices(raid_device.name) component_devices = _get_component_devices(raid_device.name)
if not component_devices: if not component_devices:
@ -1933,14 +1934,11 @@ class GenericHardwareManager(HardwareManager):
LOG.warning('Failed to remove superblock from %s: %s', LOG.warning('Failed to remove superblock from %s: %s',
raid_device.name, e) raid_device.name, e)
# Remove the partitions we created during create_configuration. # NOTE(arne_wiebalck): We cannot delete the partitions right
for holder_disk in holder_disks: # away since there may be other partitions on the same disks
LOG.debug('Removing partitions on %s', holder_disk) # which are members of other RAID devices. So we remember them
try: # for later.
utils.execute('wipefs', '-af', holder_disk) all_holder_disks.extend(holder_disks)
except processutils.ProcessExecutionError:
LOG.warning('Failed to remove partitions on %s',
holder_disk)
LOG.info('Deleted Software RAID device %s', raid_device.name) LOG.info('Deleted Software RAID device %s', raid_device.name)
@ -1986,6 +1984,17 @@ class GenericHardwareManager(HardwareManager):
LOG.warning('Failed to remove superblock from %s: %s', LOG.warning('Failed to remove superblock from %s: %s',
raid_device.name, e) raid_device.name, e)
# Erase all partition tables we created
all_holder_disks_uniq = list(
collections.OrderedDict.fromkeys(all_holder_disks))
for holder_disk in all_holder_disks_uniq:
LOG.info('Removing partitions on holder disk %s', holder_disk)
try:
utils.execute('wipefs', '-af', holder_disk)
except processutils.ProcessExecutionError as e:
LOG.warning('Failed to remove partitions on %s',
holder_disk, e)
LOG.debug("Finished deleting Software RAID(s)") LOG.debug("Finished deleting Software RAID(s)")
def validate_configuration(self, raid_config, node): def validate_configuration(self, raid_config, node):

View File

@ -4016,8 +4016,6 @@ class TestGenericHardwareManager(base.IronicAgentTest):
mock.call('mdadm', '--examine', '/dev/sdb1', mock.call('mdadm', '--examine', '/dev/sdb1',
use_standard_locale=True), use_standard_locale=True),
mock.call('mdadm', '--zero-superblock', '/dev/sdb1'), mock.call('mdadm', '--zero-superblock', '/dev/sdb1'),
mock.call('wipefs', '-af', '/dev/sda'),
mock.call('wipefs', '-af', '/dev/sdb'),
mock.call('wipefs', '-af', '/dev/md1'), mock.call('wipefs', '-af', '/dev/md1'),
mock.call('mdadm', '--stop', '/dev/md1'), mock.call('mdadm', '--stop', '/dev/md1'),
mock.call('mdadm', '--examine', '/dev/sda2', mock.call('mdadm', '--examine', '/dev/sda2',
@ -4026,15 +4024,17 @@ class TestGenericHardwareManager(base.IronicAgentTest):
mock.call('mdadm', '--examine', '/dev/sdb2', mock.call('mdadm', '--examine', '/dev/sdb2',
use_standard_locale=True), use_standard_locale=True),
mock.call('mdadm', '--zero-superblock', '/dev/sdb2'), mock.call('mdadm', '--zero-superblock', '/dev/sdb2'),
mock.call('wipefs', '-af', '/dev/sda'),
mock.call('wipefs', '-af', '/dev/sdb'),
mock.call('mdadm', '--examine', '/dev/sdc', mock.call('mdadm', '--examine', '/dev/sdc',
use_standard_locale=True), use_standard_locale=True),
mock.call('mdadm', '--zero-superblock', '/dev/sdc'), mock.call('mdadm', '--zero-superblock', '/dev/sdc'),
mock.call('mdadm', '--examine', '/dev/sdb', mock.call('mdadm', '--examine', '/dev/sdb',
use_standard_locale=True), use_standard_locale=True),
mock.call('mdadm', '--zero-superblock', '/dev/sdb'),
mock.call('mdadm', '--examine', '/dev/sda', mock.call('mdadm', '--examine', '/dev/sda',
use_standard_locale=True), use_standard_locale=True),
mock.call('mdadm', '--zero-superblock', '/dev/sda'),
mock.call('wipefs', '-af', '/dev/sda'),
mock.call('wipefs', '-af', '/dev/sdb'),
mock.call('mdadm', '--assemble', '--scan', check_exit_code=False), mock.call('mdadm', '--assemble', '--scan', check_exit_code=False),
]) ])

View File

@ -0,0 +1,6 @@
---
fixes:
- |
Fixes a bug where the partitions created during software RAID setup are cleaned
too early and therefore may prevent the proper cleaning of the md superblocks.
Leaving superblocks behind will impact the creation of new md devices later on.