Merge "Fixed nova VM live migration issue with 3PAR"

This commit is contained in:
Jenkins 2014-03-12 19:23:21 +00:00 committed by Gerrit Code Review
commit 2869d0161c
2 changed files with 51 additions and 21 deletions

View File

@ -701,7 +701,10 @@ class HP3PARBaseDriver(object):
# setup_mock_client drive with default configuration
# and return the mock HTTP 3PAR client
mock_client = self.setup_driver()
mock_client.getVLUN.return_value = {'lun': None, 'type': 0}
mock_client.getHostVLUNs.return_value = [
{'active': True,
'volumeName': self.VOLUME_3PAR_NAME,
'lun': None, 'type': 0}]
self.driver.terminate_connection(
self.volume,
@ -710,7 +713,7 @@ class HP3PARBaseDriver(object):
expected = [
mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
mock.call.getVLUN(self.VOLUME_3PAR_NAME),
mock.call.getHostVLUNs(self.FAKE_HOST),
mock.call.deleteVLUN(
self.VOLUME_3PAR_NAME,
None,
@ -986,7 +989,10 @@ class TestHP3PARFCDriver(HP3PARBaseDriver, test.TestCase):
'vendor': None,
'wwn': self.wwn[1]}]}]
mock_client.findHost.return_value = self.FAKE_HOST
mock_client.getVLUN.return_value = {'lun': 90}
mock_client.getHostVLUNs.return_value = [
{'active': True,
'volumeName': self.VOLUME_3PAR_NAME,
'lun': 90, 'type': 0}]
mock_client.getPorts.return_value = {
'members': self.FAKE_FC_PORTS + [self.FAKE_ISCSI_PORT]}
@ -994,16 +1000,16 @@ class TestHP3PARFCDriver(HP3PARBaseDriver, test.TestCase):
expected = [
mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
mock.call.getVolume('osv-0DM4qZEVSKON-DXN-NwVpw'),
mock.call.getVolume(self.VOLUME_3PAR_NAME),
mock.call.getCPG(HP3PAR_CPG),
mock.call.getHost(self.FAKE_HOST),
mock.ANY,
mock.call.getHost(self.FAKE_HOST),
mock.call.createVLUN(
'osv-0DM4qZEVSKON-DXN-NwVpw',
self.VOLUME_3PAR_NAME,
auto=True,
hostname=self.FAKE_HOST),
mock.call.getVLUN('osv-0DM4qZEVSKON-DXN-NwVpw'),
mock.call.getHostVLUNs(self.FAKE_HOST),
mock.call.getPorts(),
mock.call.logout()]
@ -1015,7 +1021,10 @@ class TestHP3PARFCDriver(HP3PARBaseDriver, test.TestCase):
# setup_mock_client drive with default configuration
# and return the mock HTTP 3PAR client
mock_client = self.setup_driver()
mock_client.getVLUN.return_value = {'lun': None, 'type': 0}
mock_client.getHostVLUNs.return_value = [
{'active': True,
'volumeName': self.VOLUME_3PAR_NAME,
'lun': None, 'type': 0}]
mock_client.getPorts.return_value = {
'members': self.FAKE_FC_PORTS + [self.FAKE_ISCSI_PORT]}
@ -1026,7 +1035,7 @@ class TestHP3PARFCDriver(HP3PARBaseDriver, test.TestCase):
expected = [
mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
mock.call.getVLUN(self.VOLUME_3PAR_NAME),
mock.call.getHostVLUNs(self.FAKE_HOST),
mock.call.deleteVLUN(
self.VOLUME_3PAR_NAME,
None,
@ -1304,23 +1313,26 @@ class TestHP3PARISCSIDriver(HP3PARBaseDriver, test.TestCase):
hpexceptions.HTTPNotFound('fake'),
{'name': self.FAKE_HOST}]
mock_client.findHost.return_value = self.FAKE_HOST
mock_client.getVLUN.return_value = {'lun': self.TARGET_LUN}
mock_client.getHostVLUNs.return_value = [
{'active': True,
'volumeName': self.VOLUME_3PAR_NAME,
'lun': self.TARGET_LUN, 'type': 0}]
result = self.driver.initialize_connection(self.volume, self.connector)
expected = [
mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
mock.call.getVolume('osv-0DM4qZEVSKON-DXN-NwVpw'),
mock.call.getVolume(self.VOLUME_3PAR_NAME),
mock.call.getCPG(HP3PAR_CPG),
mock.call.getHost(self.FAKE_HOST),
mock.call.findHost(iqn='iqn.1993-08.org.debian:01:222'),
mock.call.getHost(self.FAKE_HOST),
mock.call.createVLUN(
'osv-0DM4qZEVSKON-DXN-NwVpw',
self.VOLUME_3PAR_NAME,
auto=True,
hostname='fakehost',
portPos={'node': 8, 'slot': 1, 'cardPort': 1}),
mock.call.getVLUN('osv-0DM4qZEVSKON-DXN-NwVpw'),
mock.call.getHostVLUNs(self.FAKE_HOST),
mock.call.logout()]
mock_client.assert_has_calls(expected)

View File

@ -121,10 +121,11 @@ class HP3PARCommon(object):
2.0.5 - Fix extend volume units bug #1284368
2.0.6 - use loopingcall.wait instead of time.sleep
2.0.7 - Allow extend volume based on snapshot bug #1285906
2.0.8 - Fix detach issue for multiple hosts Bug #1288927
"""
VERSION = "2.0.7"
VERSION = "2.0.8"
stats = {}
@ -450,6 +451,21 @@ class HP3PARCommon(object):
'hp3par_cpg')})
self.stats = stats
def _get_vlun(self, volume_name, hostname):
"""find a VLUN on a 3PAR host."""
vluns = self.client.getHostVLUNs(hostname)
found_vlun = None
for vlun in vluns:
if volume_name in vlun['volumeName']:
found_vlun = vlun
break
msg = (_("3PAR vlun %(name)s not found on host %(host)s") %
{'name': volume_name, 'host': hostname})
if found_vlun is None:
LOG.warn(msg)
return found_vlun
def create_vlun(self, volume, host, nsp=None):
"""Create a VLUN.
@ -457,17 +473,19 @@ class HP3PARCommon(object):
"""
volume_name = self._get_3par_vol_name(volume['id'])
self._create_3par_vlun(volume_name, host['name'], nsp)
return self.client.getVLUN(volume_name)
return self._get_vlun(volume_name, host['name'])
def delete_vlun(self, volume, hostname):
volume_name = self._get_3par_vol_name(volume['id'])
vlun = self.client.getVLUN(volume_name)
# VLUN Type of MATCHED_SET 4 requires the port to be provided
if self.VLUN_TYPE_MATCHED_SET == vlun['type']:
self.client.deleteVLUN(volume_name, vlun['lun'], hostname,
vlun['portPos'])
else:
self.client.deleteVLUN(volume_name, vlun['lun'], hostname)
vlun = self._get_vlun(volume_name, hostname)
if vlun is not None:
# VLUN Type of MATCHED_SET 4 requires the port to be provided
if self.VLUN_TYPE_MATCHED_SET == vlun['type']:
self.client.deleteVLUN(volume_name, vlun['lun'], hostname,
vlun['portPos'])
else:
self.client.deleteVLUN(volume_name, vlun['lun'], hostname)
try:
self._delete_3par_host(hostname)