From 94c9e6afdfb9c2e3cb3b7c9be934646733dcf312 Mon Sep 17 00:00:00 2001 From: preethipy Date: Tue, 7 Feb 2017 15:05:41 +0530 Subject: [PATCH] Introduce list of ignored target wwpn for boot options The implementation helps in providing an optional configuration parameter target_wwpn_ignore_list which can be used by administrator to manually list the target wwpns that has to be ignored. There are certain storage configuration types like nas/file module connected storage ports which cannot be used for booting from a required LUN. Of the entire list of target wwpns returned by Storewize driver, the nas type of target wwpns have to be ignored. Closes bug: 1662429 Change-Id: I6bc25f2d3ef0cb51aed4e02d870c3a19af8e7d77 --- nova_dpm/conf/dpm.py | 5 ++- nova_dpm/tests/unit/virt/dpm/test_driver.py | 19 +++++++++++ nova_dpm/virt/dpm/driver.py | 35 ++++++++++++++++----- 3 files changed, 51 insertions(+), 8 deletions(-) diff --git a/nova_dpm/conf/dpm.py b/nova_dpm/conf/dpm.py index ac6d3dc..72fd548 100644 --- a/nova_dpm/conf/dpm.py +++ b/nova_dpm/conf/dpm.py @@ -37,7 +37,10 @@ ALL_DPM_OPTS = [ Maximum number of instances (partitions) that can be created for this OpenStack hypervisor host"""), cfg.MultiStrOpt('physical_storage_adapter_mappings', help=""" - Physical storage adapter with port details for hba creation""") + Physical storage adapter with port details for hba creation"""), + cfg.ListOpt('target_wwpn_ignore_list', default='', help=""" + list of target/remote wwpns can be used for example to exclude NAS/file + WWPNs returned by the V7000 Unified.""") ] diff --git a/nova_dpm/tests/unit/virt/dpm/test_driver.py b/nova_dpm/tests/unit/virt/dpm/test_driver.py index 065afbc..ff7dde0 100644 --- a/nova_dpm/tests/unit/virt/dpm/test_driver.py +++ b/nova_dpm/tests/unit/virt/dpm/test_driver.py @@ -169,12 +169,31 @@ class DPMdriverTestCase(TestCase): mock_get_partition): dummy_virt_api = None dpm_driver = driver.DPMDriver(dummy_virt_api) + dpm_driver.init_host(None) inst = vm.PartitionInstance(mock.Mock(), mock.Mock()) target_wwpn, lun = dpm_driver.get_fc_boot_props( mock.Mock(), inst) self.assertEqual(target_wwpn, '500507680B214AC1') self.assertEqual(lun, '0') + @mock.patch.object(vm.PartitionInstance, 'get_partition') + @mock.patch.object(vm.PartitionInstance, + 'get_partition_wwpns', return_value=[PARTITION_WWPN]) + @mock.patch.object(driv, 'block_device_info_get_mapping', + return_value=BLOCK_DEVICE) + def test_get_fc_boot_props_ignore_list(self, mock_block_device, + mock_get_partition_wwpns, + mock_get_partition): + self.flags(group="dpm", target_wwpn_ignore_list=["500507680B214AC1"]) + dummy_virt_api = None + dpm_driver = driver.DPMDriver(dummy_virt_api) + dpm_driver.init_host(None) + inst = vm.PartitionInstance(mock.Mock(), mock.Mock()) + target_wwpn, lun = dpm_driver.get_fc_boot_props( + mock.Mock(), inst) + self.assertEqual(target_wwpn, '500507680B244AC0') + self.assertEqual(lun, '0') + @mock.patch.object(flavor_object.Flavor, 'get_by_id') @mock.patch.object(context_object, 'get_admin_context') @mock.patch.object(vm.PartitionInstance, 'create') diff --git a/nova_dpm/virt/dpm/driver.py b/nova_dpm/virt/dpm/driver.py index 82c27f5..8c88197 100644 --- a/nova_dpm/virt/dpm/driver.py +++ b/nova_dpm/virt/dpm/driver.py @@ -79,7 +79,9 @@ class DPMDriver(driver.ComputeDriver): 'max_memory_mb': CONF.dpm.max_memory, 'max_partitions': CONF.dpm.max_instances, 'physical_storage_adapter_mappings': - CONF.dpm.physical_storage_adapter_mappings} + CONF.dpm.physical_storage_adapter_mappings, + 'target_wwpn_ignore_list': + CONF.dpm.target_wwpn_ignore_list} self._cpc = self._client.cpcs.find(**{ "object-id": self._conf['cpc_object_id']}) @@ -320,16 +322,35 @@ class DPMDriver(driver.ComputeDriver): if partition_wwpn not in host_wwpns: raise Exception('Partition WWPN not found from cinder') - target_wwpns = (mapped_block_device['connection_info']['data'] - ['initiator_target_map'][partition_wwpn]) - # target_wwpns is a list of wwpns which will be accessible - # from host wwpn. So we can use any of the target wwpn in the - # list. Default we are using first target wwpn target_wwpns[0] - target_wwpn = target_wwpns[0] + # There is a list of target WWPNs which can be configured that + # has to be ignored. The storewize driver as of today returns + # complete set of Target WWPNS both supported and unsupported + # (nas/file module connected)out of which we need to filter + # out those mentioned as target_wwpn_ignore_list + target_wwpn = self._fetch_valid_target_wwpn(mapped_block_device, + partition_wwpn) lun = str(mapped_block_device['connection_info'] ['data']['target_lun']) return target_wwpn, lun + def _fetch_valid_target_wwpn(self, mapped_block_device, partition_wwpn): + LOG.debug("_fetch_valid_target_wwpn") + list_target_wwpns = (mapped_block_device['connection_info']['data'] + ['initiator_target_map'][partition_wwpn]) + + target_wwpns = [wwpn for wwpn in list_target_wwpns + if wwpn not in self._conf['target_wwpn_ignore_list']] + + # target_wwpns is a list of wwpns which will be accessible + # from host wwpn. So we can use any of the target wwpn in the + # list. + target_wwpn = (target_wwpns[0] + if len(target_wwpns) > 0 else '') + + LOG.debug("Returning valid TargetWWPN %(target_wwpn)s" % + {'target_wwpn': target_wwpn}) + return target_wwpn + def destroy(self, context, instance, network_info, block_device_info=None, destroy_disks=True, migrate_data=None): inst = vm.PartitionInstance(instance, self._cpc)