Merge "VMware: iscsi target discovery fails while attaching volumes"

This commit is contained in:
Jenkins 2014-03-19 23:30:30 +00:00 committed by Gerrit Code Review
commit b7adaa96ab
4 changed files with 75 additions and 10 deletions

View File

@ -276,7 +276,6 @@ class VMwareAPIVMTestCase(test.NoDBTestCase):
self.flags(host_ip='test_url',
host_username='test_username',
host_password='test_pass',
cluster_name='test_cluster',
datastore_regex='.*',
api_retry_count=1,
use_linked_clone=False, group='vmware')
@ -1554,14 +1553,22 @@ class VMwareAPIVMTestCase(test.NoDBTestCase):
def test_attach_iscsi_disk_to_vm(self):
self._create_vm()
connection_info = self._test_vmdk_connection_info('iscsi')
connection_info['data']['target_portal'] = 'fake_target_portal'
connection_info['data']['target_portal'] = 'fake_target_host:port'
connection_info['data']['target_iqn'] = 'fake_target_iqn'
mount_point = '/dev/vdc'
discover = ('fake_name', 'fake_uuid')
self.mox.StubOutWithMock(volumeops.VMwareVolumeOps,
'discover_st')
volumeops.VMwareVolumeOps.discover_st(
connection_info['data']).AndReturn(discover)
self.mox.StubOutWithMock(volume_util, 'find_st')
# simulate target not found
volume_util.find_st(mox.IgnoreArg(), connection_info['data'],
mox.IgnoreArg()).AndReturn((None, None))
self.mox.StubOutWithMock(volume_util, '_add_iscsi_send_target_host')
# rescan gets called with target portal
volume_util.rescan_iscsi_hba(
self.conn._session,
target_portal=connection_info['data']['target_portal'])
# simulate target found
volume_util.find_st(mox.IgnoreArg(), connection_info['data'],
mox.IgnoreArg()).AndReturn(discover)
self.mox.StubOutWithMock(volumeops.VMwareVolumeOps,
'attach_disk_to_vm')
volumeops.VMwareVolumeOps.attach_disk_to_vm(mox.IgnoreArg(),
@ -1571,6 +1578,27 @@ class VMwareAPIVMTestCase(test.NoDBTestCase):
self.conn.attach_volume(None, connection_info, self.instance,
mount_point)
def test_rescan_iscsi_hba(self):
fake_target_portal = 'fake_target_host:port'
host_storage_sys = vmwareapi_fake._get_objects(
"HostStorageSystem").objects[0]
iscsi_hba_array = host_storage_sys.get('storageDeviceInfo'
'.hostBusAdapter')
iscsi_hba = iscsi_hba_array.HostHostBusAdapter[0]
# Check the host system does not have the send target
self.assertRaises(AttributeError, getattr, iscsi_hba,
'configuredSendTarget')
# Rescan HBA with the target portal
volume_util.rescan_iscsi_hba(self.conn._session, None,
fake_target_portal)
# Check if HBA has the target portal configured
self.assertEqual('fake_target_host',
iscsi_hba.configuredSendTarget[0].address)
# Rescan HBA with same portal
volume_util.rescan_iscsi_hba(self.conn._session, None,
fake_target_portal)
self.assertEqual(1, len(iscsi_hba.configuredSendTarget))
def test_find_st(self):
data = {'target_portal': 'fake_target_host:port',
'target_iqn': 'fake_target_iqn'}

View File

@ -1289,6 +1289,18 @@ class FakeVim(object):
host_mdo = _db_content["HostSystem"][_host_sk]
host_mdo._add_port_group(kwargs.get("portgrp"))
def _add_iscsi_send_tgt(self, method, *args, **kwargs):
"""Adds a iscsi send target to the hba."""
send_targets = kwargs.get('targets')
host_storage_sys = _get_objects('HostStorageSystem').objects[0]
iscsi_hba_array = host_storage_sys.get('storageDeviceInfo'
'.hostBusAdapter')
iscsi_hba = iscsi_hba_array.HostHostBusAdapter[0]
if hasattr(iscsi_hba, 'configuredSendTarget'):
iscsi_hba.configuredSendTarget.extend(send_targets)
else:
iscsi_hba.configuredSendTarget = send_targets
def __getattr__(self, attr_name):
if attr_name != "Login":
self._check_session()
@ -1388,3 +1400,8 @@ class FakeVim(object):
return lambda *args, **kwargs: self._just_return_task(attr_name)
elif attr_name == "ExitMaintenanceMode_Task":
return lambda *args, **kwargs: self._just_return_task(attr_name)
elif attr_name == "AddInternetScsiSendTargets":
return lambda *args, **kwargs: self._add_iscsi_send_tgt(attr_name,
*args, **kwargs)
elif attr_name == "RescanHba":
return lambda *args, **kwargs: self._just_return_task(attr_name)

View File

@ -121,7 +121,7 @@ def find_st(session, data, cluster=None):
return result
def rescan_iscsi_hba(session, cluster=None):
def rescan_iscsi_hba(session, cluster=None, target_portal=None):
"""Rescan the iSCSI HBA to discover iSCSI targets."""
host_mor = vm_util.get_host_ref(session, cluster)
storage_system_mor = session._call_method(vim_util, "get_dynamic_property",
@ -141,11 +141,30 @@ def rescan_iscsi_hba(session, cluster=None):
for hba in host_hbas:
if hba.__class__.__name__ == 'HostInternetScsiHba':
hba_device = hba.device
if target_portal:
# Check if iscsi host is already in the send target host list
send_targets = getattr(hba, 'configuredSendTarget', [])
send_tgt_portals = ['%s:%s' % (s.address, s.port) for s in
send_targets]
if target_portal not in send_tgt_portals:
_add_iscsi_send_target_host(session, storage_system_mor,
hba_device, target_portal)
break
else:
return
LOG.debug(_("Rescanning HBA %s") % hba_device)
session._call_method(session._get_vim(), "RescanHba", storage_system_mor,
hbaDevice=hba_device)
LOG.debug(_("Rescanned HBA %s ") % hba_device)
def _add_iscsi_send_target_host(session, storage_system_mor, hba_device,
target_portal):
"""Adds the iscsi host to send target host list."""
client_factory = session._get_vim().client.factory
send_tgt = client_factory.create('ns0:HostInternetScsiHbaSendTarget')
(send_tgt.address, send_tgt.port) = target_portal.split(':')
LOG.debug(_("Adding iSCSI host %s to send targets"), send_tgt.address)
session._call_method(
session._get_vim(), "AddInternetScsiSendTargets", storage_system_mor,
iScsiHbaDevice=hba_device, targets=[send_tgt])

View File

@ -144,8 +144,9 @@ class VMwareVolumeOps(object):
if device_name:
LOG.debug(_("Storage target found. No need to discover"))
return (device_name, uuid)
# Rescan iSCSI HBA
volume_util.rescan_iscsi_hba(self._session, self._cluster)
# Rescan iSCSI HBA with iscsi target host
volume_util.rescan_iscsi_hba(self._session, self._cluster,
target_portal)
# Find iSCSI Target again
device_name, uuid = volume_util.find_st(self._session, data,
self._cluster)