Merge "FC discover existing devices for removal"
This commit is contained in:
commit
34ab000e38
@ -818,6 +818,28 @@ class FibreChannelConnector(InitiatorConnector):
|
|||||||
self._linuxscsi.set_execute(execute)
|
self._linuxscsi.set_execute(execute)
|
||||||
self._linuxfc.set_execute(execute)
|
self._linuxfc.set_execute(execute)
|
||||||
|
|
||||||
|
def _get_possible_volume_paths(self, connection_properties, hbas):
|
||||||
|
ports = connection_properties['target_wwn']
|
||||||
|
possible_devs = self._get_possible_devices(hbas, ports)
|
||||||
|
|
||||||
|
lun = connection_properties.get('target_lun', 0)
|
||||||
|
host_paths = self._get_host_devices(possible_devs, lun)
|
||||||
|
return host_paths
|
||||||
|
|
||||||
|
def _get_volume_paths(self, connection_properties):
|
||||||
|
"""Get a list of existing paths for a volume on the system."""
|
||||||
|
volume_paths = []
|
||||||
|
# first fetch all of the potential paths that might exist
|
||||||
|
# and then filter those by what's actually on the system.
|
||||||
|
hbas = self._linuxfc.get_fc_hbas_info()
|
||||||
|
host_paths = self._get_possible_volume_paths(connection_properties,
|
||||||
|
hbas)
|
||||||
|
for path in host_paths:
|
||||||
|
if os.path.exists(path):
|
||||||
|
volume_paths.append(path)
|
||||||
|
|
||||||
|
return volume_paths
|
||||||
|
|
||||||
@synchronized('connect_volume')
|
@synchronized('connect_volume')
|
||||||
def connect_volume(self, connection_properties):
|
def connect_volume(self, connection_properties):
|
||||||
"""Attach the volume to instance_name.
|
"""Attach the volume to instance_name.
|
||||||
@ -831,11 +853,8 @@ class FibreChannelConnector(InitiatorConnector):
|
|||||||
device_info = {'type': 'block'}
|
device_info = {'type': 'block'}
|
||||||
|
|
||||||
hbas = self._linuxfc.get_fc_hbas_info()
|
hbas = self._linuxfc.get_fc_hbas_info()
|
||||||
ports = connection_properties['target_wwn']
|
host_devices = self._get_possible_volume_paths(connection_properties,
|
||||||
possible_devs = self._get_possible_devices(hbas, ports)
|
hbas)
|
||||||
|
|
||||||
lun = connection_properties.get('target_lun', 0)
|
|
||||||
host_devices = self._get_host_devices(possible_devs, lun)
|
|
||||||
|
|
||||||
if len(host_devices) == 0:
|
if len(host_devices) == 0:
|
||||||
# this is empty because we don't have any FC HBAs
|
# this is empty because we don't have any FC HBAs
|
||||||
@ -961,18 +980,16 @@ class FibreChannelConnector(InitiatorConnector):
|
|||||||
multipath_id = device_info['multipath_id']
|
multipath_id = device_info['multipath_id']
|
||||||
mdev_info = self._linuxscsi.find_multipath_device(multipath_id)
|
mdev_info = self._linuxscsi.find_multipath_device(multipath_id)
|
||||||
devices = mdev_info['devices']
|
devices = mdev_info['devices']
|
||||||
LOG.debug("devices to remove = %s", devices)
|
|
||||||
self._linuxscsi.flush_multipath_device(multipath_id)
|
self._linuxscsi.flush_multipath_device(multipath_id)
|
||||||
else:
|
else:
|
||||||
device = device_info['path']
|
devices = []
|
||||||
# now resolve this to a /dev/sdX path
|
volume_paths = self._get_volume_paths(connection_properties)
|
||||||
if os.path.exists(device):
|
for path in volume_paths:
|
||||||
# get the /dev/sdX device from the
|
real_path = self._linuxscsi.get_name_from_path(path)
|
||||||
# /dev/disk/by-path entry
|
device_info = self._linuxscsi.get_device_info(real_path)
|
||||||
dev_name = os.path.realpath(device)
|
devices.append(device_info)
|
||||||
dev_info = self._linuxscsi.get_device_info(dev_name)
|
|
||||||
devices = [dev_info]
|
|
||||||
|
|
||||||
|
LOG.debug("devices to remove = %s", devices)
|
||||||
self._remove_devices(connection_properties, devices)
|
self._remove_devices(connection_properties, devices)
|
||||||
|
|
||||||
def _remove_devices(self, connection_properties, devices):
|
def _remove_devices(self, connection_properties, devices):
|
||||||
|
@ -920,15 +920,34 @@ class FibreChannelConnectorTestCase(ConnectorTestCase):
|
|||||||
'target_lun': 1,
|
'target_lun': 1,
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
@mock.patch.object(os.path, 'exists', return_value=True)
|
||||||
|
@mock.patch.object(linuxfc.LinuxFibreChannel, 'get_fc_hbas')
|
||||||
|
@mock.patch.object(linuxfc.LinuxFibreChannel, 'get_fc_hbas_info')
|
||||||
|
def test_get_volume_paths(self, fake_fc_hbas_info,
|
||||||
|
fake_fc_hbas, fake_exists):
|
||||||
|
fake_fc_hbas.side_effect = self.fake_get_fc_hbas
|
||||||
|
fake_fc_hbas_info.side_effect = self.fake_get_fc_hbas_info
|
||||||
|
|
||||||
|
name = 'volume-00000001'
|
||||||
|
vol = {'id': 1, 'name': name}
|
||||||
|
location = '10.0.2.15:3260'
|
||||||
|
wwn = '1234567890123456'
|
||||||
|
connection_info = self.fibrechan_connection(vol, location, wwn)
|
||||||
|
volume_paths = self.connector._get_volume_paths(
|
||||||
|
connection_info['data'])
|
||||||
|
|
||||||
|
expected = ['/dev/disk/by-path/pci-0000:05:00.2'
|
||||||
|
'-fc-0x1234567890123456-lun-1']
|
||||||
|
self.assertEqual(expected, volume_paths)
|
||||||
|
|
||||||
@mock.patch.object(os.path, 'exists', return_value=True)
|
@mock.patch.object(os.path, 'exists', return_value=True)
|
||||||
@mock.patch.object(os.path, 'realpath', return_value='/dev/sdb')
|
@mock.patch.object(os.path, 'realpath', return_value='/dev/sdb')
|
||||||
@mock.patch.object(linuxfc.LinuxFibreChannel, 'get_fc_hbas')
|
@mock.patch.object(linuxfc.LinuxFibreChannel, 'get_fc_hbas')
|
||||||
@mock.patch.object(linuxfc.LinuxFibreChannel, 'get_fc_hbas_info')
|
@mock.patch.object(linuxfc.LinuxFibreChannel, 'get_fc_hbas_info')
|
||||||
@mock.patch.object(linuxscsi.LinuxSCSI, 'find_multipath_device')
|
|
||||||
@mock.patch.object(linuxscsi.LinuxSCSI, 'remove_scsi_device')
|
@mock.patch.object(linuxscsi.LinuxSCSI, 'remove_scsi_device')
|
||||||
@mock.patch.object(linuxscsi.LinuxSCSI, 'get_device_info')
|
@mock.patch.object(linuxscsi.LinuxSCSI, 'get_device_info')
|
||||||
def test_connect_volume(self, get_device_info_mock, remove_device_mock,
|
def test_connect_volume(self, get_device_info_mock, remove_device_mock,
|
||||||
find_device_mock, get_fc_hbas_info_mock,
|
get_fc_hbas_info_mock,
|
||||||
get_fc_hbas_mock, realpath_mock, exists_mock):
|
get_fc_hbas_mock, realpath_mock, exists_mock):
|
||||||
get_fc_hbas_mock.side_effect = self.fake_get_fc_hbas
|
get_fc_hbas_mock.side_effect = self.fake_get_fc_hbas
|
||||||
get_fc_hbas_info_mock.side_effect = self.fake_get_fc_hbas_info
|
get_fc_hbas_info_mock.side_effect = self.fake_get_fc_hbas_info
|
||||||
@ -940,7 +959,6 @@ class FibreChannelConnectorTestCase(ConnectorTestCase):
|
|||||||
'address': '1:0:0:1',
|
'address': '1:0:0:1',
|
||||||
'host': 1, 'channel': 0,
|
'host': 1, 'channel': 0,
|
||||||
'id': 0, 'lun': 1}]}
|
'id': 0, 'lun': 1}]}
|
||||||
find_device_mock.return_value = devices
|
|
||||||
get_device_info_mock.return_value = devices['devices'][0]
|
get_device_info_mock.return_value = devices['devices'][0]
|
||||||
|
|
||||||
location = '10.0.2.15:3260'
|
location = '10.0.2.15:3260'
|
||||||
@ -957,6 +975,7 @@ class FibreChannelConnectorTestCase(ConnectorTestCase):
|
|||||||
exp_wwn)
|
exp_wwn)
|
||||||
self.assertEqual(dev_info['type'], 'block')
|
self.assertEqual(dev_info['type'], 'block')
|
||||||
self.assertEqual(dev_info['path'], dev_str)
|
self.assertEqual(dev_info['path'], dev_str)
|
||||||
|
self.assertTrue('multipath_id' not in dev_info)
|
||||||
self.assertTrue('devices' not in dev_info)
|
self.assertTrue('devices' not in dev_info)
|
||||||
|
|
||||||
self.connector.disconnect_volume(connection_info['data'], dev_info)
|
self.connector.disconnect_volume(connection_info['data'], dev_info)
|
||||||
|
Loading…
Reference in New Issue
Block a user