Fixes a problem in attach volume in EMC driver.
This patch fixes a problem in attach volume in EMC SMI-S driver. The existing logic checks if a volume is already attached to any host, but it doesn't check whether a volume is already attached to the specific host that nova wants cinder to attach. As a result, initialize_connection could return success (thinking it is already attached), but nova will fail to discover the LUN later and fail the attach. This patch adds a check to see if a volume is already attached to a specific host. If not, it will do the attach. The reason that the volume being attached already could be due to a nova live-migration use case. Cinder doesn't support multiple attaches currently, but allows a volume to be attached multiple times from nova during live-migration. Change-Id: I05a2f57cd8708d7fcbe902ec13665a9cfb44db07 Closes-Bug: #1295906
This commit is contained in:
parent
532e99589b
commit
7320422e5a
|
@ -398,8 +398,12 @@ class FakeEcomConnection():
|
|||
def _assoc_hdwid(self):
|
||||
assocs = []
|
||||
assoc = {}
|
||||
assoc['StorageID'] = self.data.initiator1
|
||||
assoc['StorageID'] = self.data.connector['initiator']
|
||||
assocs.append(assoc)
|
||||
for wwpn in self.data.connector['wwpns']:
|
||||
assoc2 = {}
|
||||
assoc2['StorageID'] = wwpn
|
||||
assocs.append(assoc2)
|
||||
return assocs
|
||||
|
||||
def _assoc_endpoint(self):
|
||||
|
|
|
@ -901,7 +901,7 @@ class EMCSMISCommon():
|
|||
LOG.info(_('Unmap volume: %(volume)s')
|
||||
% {'volume': volumename})
|
||||
|
||||
device_info = self.find_device_number(volume)
|
||||
device_info = self.find_device_number(volume, connector)
|
||||
device_number = device_info['hostlunid']
|
||||
if device_number is None:
|
||||
LOG.info(_("Volume %s is not mapped. No volume to unmap.")
|
||||
|
@ -931,7 +931,7 @@ class EMCSMISCommon():
|
|||
LOG.info(_('Initialize connection: %(volume)s')
|
||||
% {'volume': volumename})
|
||||
self.conn = self._get_ecom_connection()
|
||||
device_info = self.find_device_number(volume)
|
||||
device_info = self.find_device_number(volume, connector)
|
||||
device_number = device_info['hostlunid']
|
||||
if device_number is not None:
|
||||
LOG.info(_("Volume %s is already mapped.")
|
||||
|
@ -939,7 +939,7 @@ class EMCSMISCommon():
|
|||
else:
|
||||
self._map_lun(volume, connector)
|
||||
# Find host lun id again after the volume is exported to the host
|
||||
device_info = self.find_device_number(volume)
|
||||
device_info = self.find_device_number(volume, connector)
|
||||
|
||||
return device_info
|
||||
|
||||
|
@ -1533,7 +1533,7 @@ class EMCSMISCommon():
|
|||
return out_device_number
|
||||
|
||||
# Find a device number that a host can see for a volume
|
||||
def find_device_number(self, volume):
|
||||
def find_device_number(self, volume, connector):
|
||||
out_num_device_number = None
|
||||
|
||||
volumename = volume['name']
|
||||
|
@ -1546,29 +1546,47 @@ class EMCSMISCommon():
|
|||
# VMAX LUN doesn't have this property
|
||||
pass
|
||||
|
||||
unitnames = self.conn.ReferenceNames(
|
||||
vol_instance.path,
|
||||
ResultClass='CIM_ProtocolControllerForUnit')
|
||||
indexVMAX = storage_system.find('SYMMETRIX')
|
||||
if indexVMAX == -1:
|
||||
# find out whether the volume is already attached to the host
|
||||
ctrl = self._find_lunmasking_scsi_protocol_controller_for_vol(
|
||||
vol_instance,
|
||||
connector)
|
||||
|
||||
for unitname in unitnames:
|
||||
controller = unitname['Antecedent']
|
||||
classname = controller['CreationClassName']
|
||||
index = classname.find('LunMaskingSCSIProtocolController')
|
||||
if index > -1: # VNX
|
||||
# Get an instance of CIM_ProtocolControllerForUnit
|
||||
unitinstance = self.conn.GetInstance(unitname,
|
||||
LocalOnly=False)
|
||||
numDeviceNumber = int(unitinstance['DeviceNumber'], 16)
|
||||
out_num_device_number = numDeviceNumber
|
||||
break
|
||||
else:
|
||||
index = classname.find('Symm_LunMaskingView')
|
||||
if index > -1: # VMAX
|
||||
LOG.debug(_("LunMaskingSCSIProtocolController for "
|
||||
"volume %(vol)s and connector %(connector)s "
|
||||
"is %(ctrl)s.")
|
||||
% {'vol': vol_instance.path,
|
||||
'connector': connector,
|
||||
'ctrl': ctrl})
|
||||
|
||||
if indexVMAX > -1 or ctrl:
|
||||
unitnames = self.conn.ReferenceNames(
|
||||
vol_instance.path,
|
||||
ResultClass='CIM_ProtocolControllerForUnit')
|
||||
|
||||
for unitname in unitnames:
|
||||
controller = unitname['Antecedent']
|
||||
classname = controller['CreationClassName']
|
||||
index = classname.find('LunMaskingSCSIProtocolController')
|
||||
if index > -1: # VNX
|
||||
if ctrl['DeviceID'] != controller['DeviceID']:
|
||||
continue
|
||||
# Get an instance of CIM_ProtocolControllerForUnit
|
||||
unitinstance = self.conn.GetInstance(unitname,
|
||||
LocalOnly=False)
|
||||
numDeviceNumber = int(unitinstance['DeviceNumber'], 16)
|
||||
out_num_device_number = numDeviceNumber
|
||||
break
|
||||
else:
|
||||
index = classname.find('Symm_LunMaskingView')
|
||||
if index > -1: # VMAX
|
||||
unitinstance = self.conn.GetInstance(unitname,
|
||||
LocalOnly=False)
|
||||
numDeviceNumber = int(unitinstance['DeviceNumber'],
|
||||
16)
|
||||
out_num_device_number = numDeviceNumber
|
||||
break
|
||||
|
||||
if out_num_device_number is None:
|
||||
LOG.info(_("Device number not found for volume "
|
||||
|
|
|
@ -127,7 +127,7 @@ class EMCSMISISCSIDriver(driver.ISCSIDriver):
|
|||
"""Initializes the connection and returns connection info.
|
||||
|
||||
The iscsi driver returns a driver_volume_type of 'iscsi'.
|
||||
the format of the driver data is defined in _get_iscsi_properties.
|
||||
the format of the driver data is defined in smis_get_iscsi_properties.
|
||||
Example return value::
|
||||
|
||||
{
|
||||
|
@ -136,14 +136,14 @@ class EMCSMISISCSIDriver(driver.ISCSIDriver):
|
|||
'target_discovered': True,
|
||||
'target_iqn': 'iqn.2010-10.org.openstack:volume-00000001',
|
||||
'target_portal': '127.0.0.0.1:3260',
|
||||
'volume_id': 1,
|
||||
'volume_id': '12345678-1234-4321-1234-123456789012',
|
||||
}
|
||||
}
|
||||
|
||||
"""
|
||||
self.common.initialize_connection(volume, connector)
|
||||
|
||||
iscsi_properties = self._get_iscsi_properties(volume)
|
||||
iscsi_properties = self.smis_get_iscsi_properties(volume, connector)
|
||||
return {
|
||||
'driver_volume_type': 'iscsi',
|
||||
'data': iscsi_properties
|
||||
|
@ -163,7 +163,7 @@ class EMCSMISISCSIDriver(driver.ISCSIDriver):
|
|||
|
||||
return targets
|
||||
|
||||
def _get_iscsi_properties(self, volume):
|
||||
def smis_get_iscsi_properties(self, volume, connector):
|
||||
"""Gets iscsi configuration.
|
||||
|
||||
We ideally get saved information in the volume entity, but fall back
|
||||
|
@ -178,7 +178,7 @@ class EMCSMISISCSIDriver(driver.ISCSIDriver):
|
|||
|
||||
:target_lun: the lun of the iSCSI target
|
||||
|
||||
:volume_id: the id of the volume (currently used by xen)
|
||||
:volume_id: the UUID of the volume
|
||||
|
||||
:auth_method:, :auth_username:, :auth_password:
|
||||
|
||||
|
@ -197,7 +197,7 @@ class EMCSMISISCSIDriver(driver.ISCSIDriver):
|
|||
LOG.debug(_("ISCSI Discovery: Found %s") % (location))
|
||||
properties['target_discovered'] = True
|
||||
|
||||
device_info = self.common.find_device_number(volume)
|
||||
device_info = self.common.find_device_number(volume, connector)
|
||||
if device_info is None or device_info['hostlunid'] is None:
|
||||
exception_message = (_("Cannot find device number for volume %s")
|
||||
% volume['name'])
|
||||
|
@ -245,6 +245,8 @@ class EMCSMISISCSIDriver(driver.ISCSIDriver):
|
|||
|
||||
properties['volume_id'] = volume['id']
|
||||
|
||||
LOG.debug(_("ISCSI properties: %s") % (properties))
|
||||
|
||||
auth = volume['provider_auth']
|
||||
if auth:
|
||||
(auth_method, auth_username, auth_secret) = auth.split()
|
||||
|
@ -253,8 +255,6 @@ class EMCSMISISCSIDriver(driver.ISCSIDriver):
|
|||
properties['auth_username'] = auth_username
|
||||
properties['auth_password'] = auth_secret
|
||||
|
||||
LOG.debug(_("ISCSI properties: %s") % (properties))
|
||||
|
||||
return properties
|
||||
|
||||
def terminate_connection(self, volume, connector, **kwargs):
|
||||
|
|
Loading…
Reference in New Issue