NetApp: block drivers fail when volume missing.
The block driver will fail when attempting to perform a Cinder delete
when the volume does not exist on the backend. The Cinder volume status
is then set to error_deleting even though the volume no longer exists.
This fix logs a warning if the volume doesn't exist on the backend and
allows Cinder to successfully remove the Cinder volume.
Change-Id: I259f72cab4e6843e74f33fb566fc6201346c9ea1
Closes-Bug: #1682928
(cherry picked from commit 630ef764c9)
This commit is contained in:
@@ -885,6 +885,7 @@ class NetAppBlockStorageLibraryTestCase(test.TestCase):
|
||||
def test_delete_lun_no_metadata(self):
|
||||
self.mock_object(self.library, '_get_lun_attr', return_value=None)
|
||||
self.library.zapi_client = mock.Mock()
|
||||
self.library.lun_table = fake.LUN_TABLE
|
||||
self.mock_object(self.library, 'zapi_client')
|
||||
|
||||
self.library._delete_lun(fake.LUN_NAME)
|
||||
@@ -896,6 +897,40 @@ class NetAppBlockStorageLibraryTestCase(test.TestCase):
|
||||
self.zapi_client.
|
||||
mark_qos_policy_group_for_deletion.call_count)
|
||||
|
||||
@mock.patch.object(block_base, 'LOG', mock.Mock())
|
||||
def test_delete_lun_missing_lun(self):
|
||||
mock_get_lun_attr = self.mock_object(self.library, '_get_lun_attr')
|
||||
mock_get_lun_attr.return_value = fake.LUN_METADATA
|
||||
self.library.zapi_client = mock.Mock()
|
||||
error = netapp_api.NaApiError(code=netapp_api.EOBJECTNOTFOUND)
|
||||
self.mock_object(self.library.zapi_client, 'destroy_lun',
|
||||
side_effect=error)
|
||||
self.library.lun_table = {fake.LUN_NAME: None}
|
||||
|
||||
self.library._delete_lun(fake.LUN_NAME)
|
||||
|
||||
mock_get_lun_attr.assert_called_once_with(
|
||||
fake.LUN_NAME, 'metadata')
|
||||
self.library.zapi_client.destroy_lun.assert_called_once_with(fake.PATH)
|
||||
block_base.LOG.error.assert_not_called()
|
||||
block_base.LOG.warning.assert_called_once()
|
||||
self.assertFalse(self.library.lun_table)
|
||||
|
||||
@mock.patch.object(block_base, 'LOG', mock.Mock())
|
||||
def test_delete_lun_client_exception(self):
|
||||
mock_get_lun_attr = self.mock_object(self.library, '_get_lun_attr')
|
||||
mock_get_lun_attr.return_value = fake.LUN_METADATA
|
||||
self.library.zapi_client = mock.Mock()
|
||||
self.mock_object(self.library.zapi_client, 'destroy_lun',
|
||||
side_effect=netapp_api.NaApiError)
|
||||
|
||||
self.assertRaises(exception.NetAppDriverException,
|
||||
self.library._delete_lun,
|
||||
fake.LUN_NAME)
|
||||
|
||||
block_base.LOG.error.assert_not_called()
|
||||
block_base.LOG.warning.assert_not_called()
|
||||
|
||||
def test_delete_snapshot(self):
|
||||
mock_delete_lun = self.mock_object(self.library, '_delete_lun')
|
||||
|
||||
|
||||
@@ -282,7 +282,16 @@ class NetAppBlockStorageLibrary(object):
|
||||
|
||||
metadata = self._get_lun_attr(lun_name, 'metadata')
|
||||
if metadata:
|
||||
self.zapi_client.destroy_lun(metadata['Path'])
|
||||
try:
|
||||
self.zapi_client.destroy_lun(metadata['Path'])
|
||||
except netapp_api.NaApiError as e:
|
||||
if e.code == netapp_api.EOBJECTNOTFOUND:
|
||||
LOG.warning(_LW("Failure deleting LUN %(name)s."
|
||||
" %(message)s"),
|
||||
{'name': lun_name, 'message': e})
|
||||
else:
|
||||
error_message = (_('A NetApp Api Error occurred: %s') % e)
|
||||
raise exception.NetAppDriverException(error_message)
|
||||
self.lun_table.pop(lun_name)
|
||||
else:
|
||||
LOG.warning(_LW("No entry in LUN table for volume/snapshot"
|
||||
|
||||
Reference in New Issue
Block a user