This issue is for Non-NPIV attachments (i.e. regular host attachments). In emc_vmax_common.py, at the beginning of initialize_connection(), there is a short-circuit branch that no-ops the function:
deviceInfoDict = self._wrap_find_device_number(volume, connector)
if ('hostlunid' in deviceInfoDict and
deviceInfoDict['hostlunid'] is not None):
# Device is already mapped so we will leave the state as is
deviceNumber = deviceInfoDict['hostlunid']
LOG.info(_("Volume %(volume)s is already mapped. "
"The device number is %(deviceNumber)s ")
% {'volume': volumeName,
'deviceNumber': deviceNumber})
The problem is that the code flow for _wrap_find_device_number() does not take into account the connector at all. It returns a LUN id if the volume is mapped anywhere. A specific use case where this is a problem is for live migration where the volume is mapped to the target host before it is unmapped from the source host. Since find_device_number() does not take the connector 'wwpns' into account when finding a LUN id mapping, the volume mapping never happens for the target host.
There is a similar issue for terminate_connection() in _unmap_lun() where the 'hostlunid' is looked up the same way. In this case the volume will be unmapped from a host that was not requested in the connector.
A potential work-around is to have both (or all) host wwpns in the same Initiator Group to begin with. Then when the volume is originally attached to the source host, it is also mapped to the target at the same time such that common.initialize_connection() need not do anything for the second host.
This seems to be a real problem and we'll look into it. We can't have both host WWPNs in the same initiator group to start with though because we won't know the destination host when we attached the first volume. The real fix needs to check the host info in connector and determine whether the device is already mapped to the host contained in the connector, not just any host.