Abort disconnect if invalid udid

The vSCSI physical volume may hit an issue if there is an hdisk without
a UDID.  The connect flow handles this and will not map.  Which then
causes a revert.  However, during the revert the code tries to remove
the hdisk.  This causes a significant issue.

This change set detects this path by adding a flag to check if udid is
None.  If so, it presents a warning message to the operator.  It then
allows the revert flow to continue properly.

Change-Id: If7af35c7e7b68f9a5cf5496fdfded482b45064e0
Closes-Bug: 1505388
This commit is contained in:
Drew Thorstensen
2015-10-13 12:15:06 -04:00
parent f2d4c27d27
commit c26ba8ab1a
2 changed files with 35 additions and 1 deletions

View File

@@ -253,17 +253,19 @@ class TestVSCSIAdapter(BaseVSCSITest):
self.assertEqual(1, mock_remove_maps.call_count)
self.assertEqual(0, self.ft_fx.patchers['update'].mock.call_count)
@mock.patch('pypowervm.tasks.hdisk.good_discovery')
@mock.patch('pypowervm.tasks.hdisk.remove_hdisk')
@mock.patch('pypowervm.wrappers.virtual_io_server.VIOS.hdisk_from_uuid')
@mock.patch('pypowervm.tasks.scsi_mapper.remove_maps')
@mock.patch('nova_powervm.virt.powervm.vm.get_vm_id')
def test_disconnect_volume_no_udid(
self, mock_get_vm_id, mock_remove_maps, mock_hdisk_from_uuid,
mock_remove_hdisk):
mock_remove_hdisk, mock_good_discover):
# The mock return values
mock_hdisk_from_uuid.return_value = 'device_name'
mock_get_vm_id.return_value = 'partition_id'
mock_good_discover.return_value = True
def validate_remove_maps(vios_w, vm_uuid, match_func):
self.assertIsInstance(vios_w, pvm_vios.VIOS)
@@ -284,6 +286,25 @@ class TestVSCSIAdapter(BaseVSCSITest):
mock_remove_hdisk.assert_called_once_with(
self.adpt, mock.ANY, 'dev_name', self.vios_uuid)
@mock.patch('pypowervm.tasks.hdisk.good_discovery')
@mock.patch('pypowervm.tasks.hdisk.remove_hdisk')
@mock.patch('pypowervm.tasks.scsi_mapper.remove_maps')
def test_disconnect_volume_no_udid_on_discover(
self, mock_remove_maps, mock_remove_hdisk, mock_good_discover):
"""Ensures that if the UDID can not be found, no disconnect."""
mock_good_discover.return_value = False
with mock.patch.object(
self.vol_drv, '_discover_volume_on_vios',
return_value=('status', 'dev_name', None)):
# Run the method
self.vol_drv.disconnect_volume()
# As initialized above, remove_maps returns True to trigger update.
self.assertEqual(0, mock_remove_maps.call_count)
self.assertEqual(0, self.ft_fx.patchers['update'].mock.call_count)
self.assertEqual(0, mock_remove_hdisk.call_count)
@mock.patch('pypowervm.wrappers.virtual_io_server.VIOS.hdisk_from_uuid')
@mock.patch('pypowervm.tasks.scsi_mapper.remove_maps')
def test_disconnect_volume_no_valid_vio(self, mock_remove_maps,

View File

@@ -258,6 +258,19 @@ class VscsiVolumeAdapter(v_driver.FibreChannelVolumeAdapter):
status, device_name, udid = self._discover_volume_on_vios(
vios_w, self.volume_id)
# If we have a device name, but not a udid, at this point
# we should not continue. The hdisk is in a bad state
# in the I/O Server. Subsequent scrub code on future
# deploys will clean this up.
if not hdisk.good_discovery(status, device_name):
LOG.warn(_LW(
"Disconnect Volume: The backing hdisk for volume "
"%(volume_id)s on Virtual I/O Server %(vios)s is "
"not in a valid state. No disconnect "
"actions to be taken as volume is not healthy."),
{'volume_id': self.volume_id, 'vios': vios_w.name})
return False
if udid and not device_name:
device_name = vios_w.hdisk_from_uuid(udid)