del self._mappings_list[this_mapping]
return ('', '')
- # List information about vdisk-host mappings
+ # List information about host->vdisk mappings
def _cmd_lshostvdiskmap(self, **kwargs):
index = 1
no_hdr = 0
return self._print_info_cmd(rows=rows, **kwargs)
+ # List information about vdisk->host mappings
+ def _cmd_lsvdiskhostmap(self, **kwargs):
+ mappings_found = 0
+ vdisk_name = kwargs['obj']
+
+ if vdisk_name not in self._volumes_list:
+ return self._errors['CMMVC5753E']
+
+ rows = []
+ rows.append(['id name', 'SCSI_id', 'host_id', 'host_name', 'vdisk_UID',
+ 'IO_group_id', 'IO_group_name'])
+
+ for k, mapping in self._mappings_list.iteritems():
+ if (mapping['vol'] == vdisk_name):
+ mappings_found += 1
+ volume = self._volumes_list[mapping['vol']]
+ host = self._hosts_list[mapping['host']]
+ rows.append([volume['id'], volume['name'], host['id'],
+ host['host_name'], volume['uid'],
+ volume['IO_group_id'], volume['IO_group_name']])
+
+ if mappings_found:
+ return self._print_info_cmd(rows=rows, **kwargs)
+ else:
+ return ('', '')
+
# Create a FlashCopy mapping
def _cmd_mkfcmap(self, **kwargs):
source = ''
out, err = self._cmd_rmvdiskhostmap(**kwargs)
elif command == 'lshostvdiskmap':
out, err = self._cmd_lshostvdiskmap(**kwargs)
+ elif command == 'lsvdiskhostmap':
+ out, err = self._cmd_lsvdiskhostmap(**kwargs)
elif command == 'mkfcmap':
out, err = self._cmd_mkfcmap(**kwargs)
elif command == 'prestartfcmap':
# Try to remove connection from volume that isn't mapped (should print
# message but NOT fail)
- vol_no_exist = {'name': 'i_dont_exist'}
- self.driver.terminate_connection(vol_no_exist, self._connector)
+ unmapped_vol = self._generate_vol_info(None, None)
+ self.driver.create_volume(unmapped_vol)
+ self.driver.terminate_connection(unmapped_vol, self._connector)
+ self.driver.delete_volume(unmapped_vol)
# Remove the mapping from the 1st volume and delete it
self.driver.terminate_connection(volume1, self._connector)
host_name = self.driver._get_host_from_connector(self._connector)
self.assertIsNotNone(host_name)
- # Remove the mapping from the 2nd volume and delete it. The host should
+ # Remove the mapping from the 2nd volume. The host should
# be automatically removed because there are no more mappings.
self.driver.terminate_connection(volume2, self._connector)
+
+ # Check if we successfully terminate connections when the host is not
+ # specified (see bug #1244257)
+ fake_conn = {'ip': '127.0.0.1', 'initiator': 'iqn.fake'}
+ self.driver.initialize_connection(volume2, self._connector)
+ host_name = self.driver._get_host_from_connector(self._connector)
+ self.assertIsNotNone(host_name)
+ self.driver.terminate_connection(volume2, fake_conn)
+ host_name = self.driver._get_host_from_connector(self._connector)
+ self.assertIsNone(host_name)
self.driver.delete_volume(volume2)
self._assert_vol_exists(volume2['name'], False)
"""
- prefix = self._connector_to_hostname_prefix(connector)
- LOG.debug(_('enter: _get_host_from_connector: prefix %s') % prefix)
+ LOG.debug(_('enter: _get_host_from_connector: %s') % str(connector))
# Get list of host in the storage
ssh_cmd = ['svcinfo', 'lshost', '-delim', '!']
{'host': connector['host'], 'host_name': host_name})
return host_name
+ def _get_vdiskhost_mappings(self, vdisk_name):
+ """Return the defined storage mappings for a vdisk."""
+
+ return_data = {}
+ ssh_cmd = ['svcinfo', 'lsvdiskhostmap', '-delim', '!', vdisk_name]
+ out, err = self._run_ssh(ssh_cmd)
+
+ mappings = out.strip().split('\n')
+ if len(mappings):
+ header = mappings.pop(0)
+ for mapping_line in mappings:
+ mapping_data = self._get_hdr_dic(header, mapping_line, '!')
+ return_data[mapping_data['host_name']] = mapping_data
+
+ return return_data
+
def _get_hostvdisk_mappings(self, host_name):
"""Return the defined storage mappings for a host."""
'conn': str(connector)})
vol_name = volume['name']
- host_name = self._get_host_from_connector(connector)
- # Verify that _get_host_from_connector returned the host.
- # This should always succeed as we terminate an existing connection.
- self._driver_assert(
- host_name is not None,
- _('_get_host_from_connector failed to return the host name '
- 'for connector'))
-
- # Check if vdisk-host mapping exists, remove if it does
- mapping_data = self._get_hostvdisk_mappings(host_name)
- if vol_name in mapping_data:
- ssh_cmd = ['svctask', 'rmvdiskhostmap', '-host', host_name,
- vol_name]
- out, err = self._run_ssh(ssh_cmd)
- # Verify CLI behaviour - no output is returned from
- # rmvdiskhostmap
- self._assert_ssh_return(len(out.strip()) == 0,
- 'terminate_connection', ssh_cmd, out, err)
- del mapping_data[vol_name]
+ if 'host' in connector:
+ host_name = self._get_host_from_connector(connector)
+ self._driver_assert(
+ host_name is not None,
+ _('_get_host_from_connector failed to return the host name '
+ 'for connector'))
else:
- LOG.error(_('terminate_connection: No mapping of volume '
- '%(vol_name)s to host %(host_name)s found') %
- {'vol_name': vol_name, 'host_name': host_name})
+ # See bug #1244257
+ host_name = None
+
+ # Check if vdisk-host mapping exists, remove if it does. If no host
+ # name was given, but only one mapping exists, we can use that.
+ mapping_data = self._get_vdiskhost_mappings(vol_name)
+ if len(mapping_data) == 0:
+ LOG.warning(_('terminate_connection: No mapping of volume '
+ '%(vol_name)s to any host found.') %
+ {'vol_name': vol_name})
+ return
+ if host_name is None:
+ if len(mapping_data) > 1:
+ LOG.warning(_('terminate_connection: Multiple mappings of '
+ 'volume %(vol_name)s found, no host '
+ 'specified.') % {'vol_name': vol_name})
+ return
+ else:
+ host_name = mapping_data.keys()[0]
+ else:
+ if host_name not in mapping_data:
+ LOG.error(_('terminate_connection: No mapping of volume '
+ '%(vol_name)s to host %(host_name)s found') %
+ {'vol_name': vol_name, 'host_name': host_name})
+ return
+
+ # We have a valid host_name now
+ ssh_cmd = ['svctask', 'rmvdiskhostmap', '-host', host_name,
+ vol_name]
+ out, err = self._run_ssh(ssh_cmd)
+ # Verify CLI behaviour - no output is returned from rmvdiskhostmap
+ self._assert_ssh_return(len(out.strip()) == 0,
+ 'terminate_connection', ssh_cmd, out, err)
# If this host has no more mappings, delete it
+ mapping_data = self._get_hostvdisk_mappings(host_name)
if not mapping_data:
self._delete_host(host_name)