From: Avishay Traeger Date: Wed, 13 Mar 2013 12:56:30 +0000 (+0200) Subject: Compression/tier capabilities for Storwize/SVC. X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=e8e0cdbbc0a1e4d1f9c5d74ada135ea91e02ef3b;p=openstack-build%2Fcinder-build.git Compression/tier capabilities for Storwize/SVC. Compression and tiering support were not exported as capabilities, and are important features. Also fix a couple bugs introduced by https://review.openstack.org/#/c/23830/ Change-Id: I41c304d0da89a050c0345b930b3f45741214b425 Fixes: bug 1146341 Fixed: bug 1155071 --- diff --git a/cinder/tests/test_storwize_svc.py b/cinder/tests/test_storwize_svc.py index 958613d05..7e05731f6 100644 --- a/cinder/tests/test_storwize_svc.py +++ b/cinder/tests/test_storwize_svc.py @@ -497,11 +497,11 @@ class StorwizeSVCManagementSimulator: host_info['host_name'], '', 'host']) if self._next_cmd_error['lsfabric'] == 'header_mismatch': - rows[0].pop(2) + rows[0].pop(0) self._next_cmd_error['lsfabric'] = '' if self._next_cmd_error['lsfabric'] == 'remove_field': for row in rows: - row.pop(4) + row.pop(0) self._next_cmd_error['lsfabric'] = '' return self._print_info_cmd(rows=rows, **kwargs) @@ -1697,23 +1697,14 @@ class StorwizeSVCDriverTestCase(test.TestCase): volume2['volume_type_id'] = types[protocol]['id'] # Check case where no hosts exist - ret = self.driver._get_host_from_connector(conn) - self.assertEqual(ret, None) + if self.USESIM: + ret = self.driver._get_host_from_connector(conn) + self.assertEqual(ret, None) # Make sure that the volumes have been created self._assert_vol_exists(volume1['name'], True) self._assert_vol_exists(volume2['name'], True) - # Check bad output from lsfabric - if protocol == 'FC' and self.USESIM: - for error in ['remove_field', 'header_mismatch']: - self.sim.error_injection('lsfabric', error) - self.assertRaises(exception.VolumeBackendAPIException, - self.driver.initialize_connection, - volume1, conn) - host_name = self.driver._get_host_from_connector(conn) - self.assertEqual(host_name, None) - # Initialize connection from the first volume to a host self.driver.initialize_connection(volume1, conn) @@ -1725,7 +1716,18 @@ class StorwizeSVCDriverTestCase(test.TestCase): self.driver.delete_volume, volume1) + # Check bad output from lsfabric for the 2nd volume + if protocol == 'FC' and self.USESIM: + for error in ['remove_field', 'header_mismatch']: + self.sim.error_injection('lsfabric', error) + self.assertRaises(exception.VolumeBackendAPIException, + self.driver.initialize_connection, + volume2, conn) + self.driver.terminate_connection(volume1, conn) + if self.USESIM: + host_name = self.driver._get_host_from_connector(conn) + self.assertEqual(host_name, None) # Check cases with no auth set for host if self.USESIM: @@ -1760,7 +1762,7 @@ class StorwizeSVCDriverTestCase(test.TestCase): # Try to remove connection from host that doesn't exist (should fail) conn_no_exist = conn.copy() conn_no_exist['initiator'] = 'i_dont_exist' - conn_no_exist['wwpns'] = ['i_dont_exist'] + conn_no_exist['wwpns'] = ['0000000000000000'] self.assertRaises(exception.VolumeBackendAPIException, self.driver.terminate_connection, volume1, diff --git a/cinder/volume/drivers/storwize_svc.py b/cinder/volume/drivers/storwize_svc.py index 95cf10881..8d72b6f29 100644 --- a/cinder/volume/drivers/storwize_svc.py +++ b/cinder/volume/drivers/storwize_svc.py @@ -51,6 +51,7 @@ from cinder import context from cinder import exception from cinder.openstack.common import excutils from cinder.openstack.common import log as logging +from cinder.openstack.common import strutils from cinder import utils from cinder.volume.drivers.san import san from cinder.volume import volume_types @@ -422,12 +423,12 @@ class StorwizeSVCDriver(san.SanISCSIDriver): for wwpn in connector['wwpns']: ssh_cmd = 'lsfabric -wwpn %s -delim !' % wwpn out, err = self._run_ssh(ssh_cmd) - host_lines = out.strip().split('\n') - if len(host_lines) == 0: + if not len(out.strip()): # This WWPN is not in use continue + host_lines = out.strip().split('\n') header = host_lines.pop(0).split('!') self._assert_ssh_return('remote_wwpn' in header and 'name' in header, @@ -840,11 +841,23 @@ 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': + for k, value in specs.iteritems(): + # Get the scope, if using scope format + key_split = k.split(':') + if len(key_split) == 1: + scope = None + key = key_split[0] + else: + scope = key_split[0] + key = key_split[1] + + # We generally do not look at capabilities in the driver, but + # protocol is a special case where the user asks for a given + # protocol and we want both the scheduler and the driver to act + # on the value. + if scope == 'capabilities' and key == 'storage_protocol': + scope = None + key = 'protocol' words = value.split() self._driver_assert(words and len(words) == 2 and @@ -853,13 +866,20 @@ class StorwizeSVCDriver(san.SanISCSIDriver): '\' iSCSI\' or \' FC\'')) del words[0] value = words[0] + + # Anything keys that the driver should look at should have the + # 'drivers' scope. + if scope and scope != "drivers": + continue + if key in opts: this_type = type(opts[key]).__name__ if this_type == 'int': value = int(value) elif this_type == 'bool': - value = False if value == "0" else True + value = strutils.bool_from_string(value) opts[key] = value + self._check_vdisk_opts(opts) return opts @@ -1313,8 +1333,6 @@ class StorwizeSVCDriver(san.SanISCSIDriver): data['reserved_percentage'] = 0 data['QoS_support'] = False - data['compression_enabled'] = self._compression_enabled - pool = self.configuration.storwize_svc_volpool_name #Get storage system name ssh_cmd = 'lssystem -delim !' @@ -1341,6 +1359,8 @@ class StorwizeSVCDriver(san.SanISCSIDriver): (1024 ** 3)) data['free_capacity_gb'] = (float(attributes['free_capacity']) / (1024 ** 3)) + data['easytier_support'] = attributes['easy_tier'] in ['on', 'auto'] + data['compression_support'] = self._compression_enabled self._stats = data