From bda8dd050e75e11e269bc00fee34917e5ae4f0cf Mon Sep 17 00:00:00 2001 From: Avishay Traeger Date: Tue, 5 Mar 2013 10:00:11 +0200 Subject: [PATCH] Fix Storwize/SVC storage_protocol reporting. The Storwize/SVC driver supports both FC and iSCSI protocols simultaneously. Therefore, 'storage_protocol' should be defined as a list of enabled protocols, not simply 'iSCSI'. The extra_specs key-value would then be, for example, storage_protocol=' iSCSI' or storage_protocol=' FC'. Fixes bug: 1142196 Change-Id: Ib99a6d4e4e61d07ddb4f173c13fe7e9f5482fa2b --- cinder/tests/test_storwize_svc.py | 27 ++++++------- cinder/volume/drivers/storwize_svc.py | 56 ++++++++++++++++++--------- 2 files changed, 49 insertions(+), 34 deletions(-) diff --git a/cinder/tests/test_storwize_svc.py b/cinder/tests/test_storwize_svc.py index 5f9d7b782..96062e1c1 100644 --- a/cinder/tests/test_storwize_svc.py +++ b/cinder/tests/test_storwize_svc.py @@ -1243,7 +1243,8 @@ class StorwizeSVCDriverTestCase(test.TestCase): 'san_login': 'user', 'san_password': 'pass', 'storwize_svc_flashcopy_timeout': 20, - 'storwize_svc_connection_protocol': 'iscsi', + # Test ignore capitalization + 'storwize_svc_connection_protocol': 'iScSi', 'storwize_svc_multipath_enabled': False} self._host_name = 'storwize-svc-test' self._host_ip = '1.234.56.78' @@ -1266,7 +1267,8 @@ class StorwizeSVCDriverTestCase(test.TestCase): 'san_login': 'user', 'san_password': 'password', 'storwize_svc_volpool_name': 'openstack', - 'storwize_svc_connection_protocol': 'iscsi', + # Test ignore capitalization + 'storwize_svc_connection_protocol': 'iScSi', 'storwize_svc_multipath_enabled': False, 'ssh_conn_timeout': 0} self._host_name = socket.gethostname() @@ -1382,7 +1384,7 @@ class StorwizeSVCDriverTestCase(test.TestCase): self.driver.check_for_setup_error) self._reset_flags() - self.flags(storwize_svc_connection_protocol='iscsi') + self.flags(storwize_svc_connection_protocol='iSCSI') self.flags(storwize_svc_multipath_enabled=True) self.assertRaises(exception.InvalidInput, self.driver.check_for_setup_error) @@ -1624,7 +1626,7 @@ class StorwizeSVCDriverTestCase(test.TestCase): def test_storwize_svc_unicode_host_and_volume_names(self): # We'll check with iSCSI only - nothing protocol-dependednt here - self.flags(storwize_svc_connection_protocol='iscsi') + self.flags(storwize_svc_connection_protocol='iSCSI') self.driver.do_setup(None) rand_id = random.randint(10000, 99999) @@ -1681,8 +1683,8 @@ class StorwizeSVCDriverTestCase(test.TestCase): # Create volume types that we created types = {} - for protocol in ['fc', 'iscsi']: - opts = {'protocol': protocol} + for protocol in ['FC', 'iSCSI']: + opts = {'storage_protocol': ' ' + protocol} types[protocol] = volume_types.create(ctxt, protocol, opts) conn = {'initiator': self._iscsi_name, @@ -1690,7 +1692,7 @@ class StorwizeSVCDriverTestCase(test.TestCase): 'host': self._host_name, 'wwpns': self._host_wwpns} - for protocol in ['fc', 'iscsi']: + for protocol in ['FC', 'iSCSI']: volume1['volume_type_id'] = types[protocol]['id'] volume2['volume_type_id'] = types[protocol]['id'] @@ -1703,7 +1705,7 @@ class StorwizeSVCDriverTestCase(test.TestCase): self._assert_vol_exists(volume2['name'], True) # Check bad output from lsfabric - if protocol == 'fc' and self.USESIM: + if protocol == 'FC' and self.USESIM: for error in ['remove_field', 'header_mismatch']: self.sim.error_injection('lsfabric', error) self.assertRaises(exception.VolumeBackendAPIException, @@ -1733,7 +1735,7 @@ class StorwizeSVCDriverTestCase(test.TestCase): 'ip': '11.11.11.11', 'host': 'host-%s' % case} self.sim._add_host_to_list(conn_na) - volume1['volume_type_id'] = types['iscsi']['id'] + volume1['volume_type_id'] = types['iSCSI']['id'] if case == 'no_info': self.sim.error_injection('lsiscsiauth', 'no_info') self.driver.initialize_connection(volume1, conn_na) @@ -1785,7 +1787,7 @@ class StorwizeSVCDriverTestCase(test.TestCase): self._assert_vol_exists(volume2['name'], False) # Delete volume types that we created - for protocol in ['fc', 'iscsi']: + for protocol in ['FC', 'iSCSI']: volume_types.destroy(ctxt, types[protocol]['id']) # Check if our host still exists (it should not) @@ -1874,12 +1876,7 @@ class StorwizeSVCDriverTestCase(test.TestCase): self.fail('%s not less than or equal to %s' % (repr(a), repr(b))) def test_storwize_svc_get_volume_stats(self): - #first call, no refresh, expect None stats = self.driver.get_volume_stats() - self.assertEqual(stats, {}) - - #call with refresh - stats = self.driver.get_volume_stats(refresh=True) self.assertLessEqual(stats['free_capacity_gb'], stats['total_capacity_gb']) if self.USESIM: diff --git a/cinder/volume/drivers/storwize_svc.py b/cinder/volume/drivers/storwize_svc.py index b3c1a61a4..8c43c0310 100644 --- a/cinder/volume/drivers/storwize_svc.py +++ b/cinder/volume/drivers/storwize_svc.py @@ -90,8 +90,8 @@ storwize_svc_opts = [ help='Maximum number of seconds to wait for FlashCopy to be ' 'prepared. Maximum value is 600 seconds (10 minutes).'), cfg.StrOpt('storwize_svc_connection_protocol', - default='iscsi', - help='Connection protocol (iscsi/fc)'), + default='iSCSI', + help='Connection protocol (iSCSI/FC)'), cfg.BoolOpt('storwize_svc_multipath_enabled', default=False, help='Connect with multipath (currently FC-only)'), @@ -119,7 +119,6 @@ class StorwizeSVCDriver(san.SanISCSIDriver): super(StorwizeSVCDriver, self).__init__(*args, **kwargs) self._storage_nodes = {} self._enabled_protocols = set() - self._supported_protocols = ['iscsi', 'fc'] self._compression_enabled = False self._context = None @@ -251,11 +250,11 @@ class StorwizeSVCDriver(san.SanISCSIDriver): for k, node in self._storage_nodes.iteritems(): if ((len(node['ipv4']) or len(node['ipv6'])) and len(node['iscsi_name'])): - node['enabled_protocols'].append('iscsi') - self._enabled_protocols.add('iscsi') + node['enabled_protocols'].append('iSCSI') + self._enabled_protocols.add('iSCSI') if len(node['WWPN']): - node['enabled_protocols'].append('fc') - self._enabled_protocols.add('fc') + node['enabled_protocols'].append('FC') + self._enabled_protocols.add('FC') if not len(node['enabled_protocols']): to_delete.append(k) @@ -269,13 +268,20 @@ class StorwizeSVCDriver(san.SanISCSIDriver): LOG.debug(_('leave: do_setup')) def _build_default_opts(self): + # Ignore capitalization + protocol = FLAGS.storwize_svc_connection_protocol + if protocol.lower() == 'fc': + protocol = 'FC' + elif protocol.lower() == 'iscsi': + protocol = 'iSCSI' + opts = {'rsize': FLAGS.storwize_svc_vol_rsize, 'warning': FLAGS.storwize_svc_vol_warning, 'autoexpand': FLAGS.storwize_svc_vol_autoexpand, 'grainsize': FLAGS.storwize_svc_vol_grainsize, 'compression': FLAGS.storwize_svc_vol_compression, 'easytier': FLAGS.storwize_svc_vol_easytier, - 'protocol': FLAGS.storwize_svc_connection_protocol, + 'protocol': protocol, 'multipath': FLAGS.storwize_svc_multipath_enabled} return opts @@ -639,7 +645,7 @@ class StorwizeSVCDriver(san.SanISCSIDriver): host_name is not None, _('_create_host failed to return the host name.')) - if vol_opts['protocol'] == 'iscsi': + if vol_opts['protocol'] == 'iSCSI': chap_secret = self._get_chap_secret_for_host(host_name) if chap_secret is None: chap_secret = self._add_chapsecret_to_host(host_name) @@ -689,7 +695,7 @@ class StorwizeSVCDriver(san.SanISCSIDriver): properties['target_discovered'] = False properties['target_lun'] = lun_id properties['volume_id'] = volume['id'] - if vol_opts['protocol'] == 'iscsi': + if vol_opts['protocol'] == 'iSCSI': type_str = 'iscsi' # We take the first IP address for now. Ideally, OpenStack will # support iSCSI multipath for improved performance. @@ -807,7 +813,19 @@ class StorwizeSVCDriver(san.SanISCSIDriver): ctxt = context.get_admin_context() volume_type = volume_types.get_volume_type(ctxt, type_id) specs = volume_type.get('extra_specs') + key_trans = {'storage_protocol': 'protocol'} for key, value in specs.iteritems(): + if key in key_trans: + key = key_trans[key] + if key == 'protocol': + words = value.split() + self._driver_assert(words and + len(words) == 2 and + words[0] == '', + _('protocol must be specified as ' + '\' iSCSI\' or \' FC\'')) + del words[0] + value = words[0] if key in opts: this_type = type(opts[key]).__name__ if this_type == 'int': @@ -1223,7 +1241,7 @@ class StorwizeSVCDriver(san.SanISCSIDriver): def copy_image_to_volume(self, context, volume, image_service, image_id): opts = self._get_vdisk_params(volume['volume_type_id']) - if opts['protocol'] == 'iscsi': + if opts['protocol'] == 'iSCSI': # Implemented in base iSCSI class return super(StorwizeSVCDriver, self).copy_image_to_volume( context, volume, image_service, image_id) @@ -1232,7 +1250,7 @@ class StorwizeSVCDriver(san.SanISCSIDriver): def copy_volume_to_image(self, context, volume, image_service, image_meta): opts = self._get_vdisk_params(volume['volume_type_id']) - if opts['protocol'] == 'iscsi': + if opts['protocol'] == 'iSCSI': # Implemented in base iSCSI class return super(StorwizeSVCDriver, self).copy_volume_to_image( context, volume, image_service, image_meta) @@ -1246,8 +1264,9 @@ class StorwizeSVCDriver(san.SanISCSIDriver): def get_volume_stats(self, refresh=False): """Get volume status. - If 'refresh' is True, run update the stats first.""" - if refresh: + If we haven't gotten stats yet or 'refresh' is True, + run update the stats first.""" + if not self._stats or refresh: self._update_volume_status() return self._stats @@ -1261,11 +1280,10 @@ class StorwizeSVCDriver(san.SanISCSIDriver): data['volume_backend_name'] = 'IBM_STORWIZE_SVC' # To be overwritten data['vendor_name'] = 'IBM' data['driver_version'] = '1.1' - data['storage_protocol'] = 'iSCSI' - data['storage_protocols'] = self._enabled_protocols + data['storage_protocol'] = list(self._enabled_protocols) - data['total_capacity_gb'] = 0 - data['free_capacity_gb'] = 0 + data['total_capacity_gb'] = 0 # To be overwritten + data['free_capacity_gb'] = 0 # To be overwritten data['reserved_percentage'] = 0 data['QoS_support'] = False @@ -1358,7 +1376,7 @@ class StorwizeSVCDriver(san.SanISCSIDriver): 'enabled': ','.join(self._enabled_protocols)}) # Check that multipath is only enabled for fc - if opts['protocol'] != 'fc' and opts['multipath']: + if opts['protocol'] != 'FC' and opts['multipath']: raise exception.InvalidInput( reason=_('Multipath is currently only supported for FC ' 'connections and not iSCSI. (This is a Nova ' -- 2.45.2