Merge "Rework Storwize/SVC protocol to fix add_vdisk_copy"

This commit is contained in:
Jenkins 2016-03-17 02:52:41 +00:00 committed by Gerrit Code Review
commit 76a19863df
4 changed files with 60 additions and 107 deletions

View File

@ -2130,6 +2130,13 @@ class StorwizeSVCISCSIDriverTestCase(test.TestCase):
self.iscsi_driver.terminate_connection(volume, conn2)
self.iscsi_driver.terminate_connection(volume, self._connector)
def test_add_vdisk_copy_iscsi(self):
# Ensure only iSCSI is available
self.iscsi_driver._state['enabled_protocols'] = set(['iSCSI'])
volume = self._generate_vol_info(None, None)
self.iscsi_driver.create_volume(volume)
self.iscsi_driver.add_vdisk_copy(volume['name'], 'fake-pool', None)
class StorwizeSVCFcDriverTestCase(test.TestCase):
@mock.patch.object(time, 'sleep')
@ -2563,6 +2570,13 @@ class StorwizeSVCFcDriverTestCase(test.TestCase):
self.fc_driver.terminate_connection(volume, conn2)
self.fc_driver.terminate_connection(volume, self._connector)
def test_add_vdisk_copy_fc(self):
# Ensure only FC is available
self.fc_driver._state['enabled_protocols'] = set(['FC'])
volume = self._generate_vol_info(None, None)
self.fc_driver.create_volume(volume)
self.fc_driver.add_vdisk_copy(volume['name'], 'fake-pool', None)
class StorwizeSVCCommonDriverTestCase(test.TestCase):
@mock.patch.object(time, 'sleep')
@ -2875,7 +2889,6 @@ class StorwizeSVCCommonDriverTestCase(test.TestCase):
'grainsize': 256,
'compression': False,
'easytier': True,
'protocol': 'iSCSI',
'iogrp': 0,
'qos': None,
'replication': False,

View File

@ -888,7 +888,7 @@ class StorwizeHelpers(object):
return self.ssh.lshostvdiskmap(host_name)
@staticmethod
def build_default_opts(config, protocol):
def build_default_opts(config):
# Ignore capitalization
cluster_partner = config.storwize_svc_stretched_cluster_partner
@ -898,7 +898,6 @@ class StorwizeHelpers(object):
'grainsize': config.storwize_svc_vol_grainsize,
'compression': config.storwize_svc_vol_compression,
'easytier': config.storwize_svc_vol_easytier,
'protocol': protocol,
'iogrp': config.storwize_svc_vol_iogrp,
'qos': None,
'stretched_cluster': cluster_partner,
@ -926,14 +925,6 @@ class StorwizeHelpers(object):
reason=_('If compression is set to True, rsize must '
'also be set (not equal to -1).'))
# Check that the requested protocol is enabled
if opts['protocol'] not in state['enabled_protocols']:
raise exception.InvalidInput(
reason=_('The storage device does not support %(prot)s. '
'Please configure the device to support %(prot)s or '
'switch to a driver using a different protocol.')
% {'prot': opts['protocol']})
if opts['iogrp'] not in state['available_iogrps']:
avail_grps = ''.join(str(e) for e in state['available_iogrps'])
raise exception.InvalidInput(
@ -959,21 +950,6 @@ class StorwizeHelpers(object):
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 ((not scope or scope == 'capabilities') and
key == 'storage_protocol'):
scope = None
key = 'protocol'
words = value.split()
if not (words and len(words) == 2 and words[0] == '<in>'):
LOG.error(_LE('Protocol must be specified as '
'\'<in> iSCSI\' or \'<in> FC\'.'))
del words[0]
value = words[0]
# We generally do not look at capabilities in the driver, but
# replication is a special case where the user asks for
# a volume to be replicated, and we want both the scheduler and
@ -1066,13 +1042,13 @@ class StorwizeHelpers(object):
timer = loopingcall.FixedIntervalLoopingCall(_inner)
timer.start(interval=interval).wait()
def get_vdisk_params(self, config, state, type_id, protocol = 'iSCSI',
def get_vdisk_params(self, config, state, type_id,
volume_type=None, volume_metadata=None):
"""Return the parameters for creating the vdisk.
Takes volume type and defaults from config options into account.
"""
opts = self.build_default_opts(config, protocol)
opts = self.build_default_opts(config)
ctxt = context.get_admin_context()
if volume_type is None and type_id is not None:
volume_type = volume_types.get_volume_type(ctxt, type_id)
@ -1870,7 +1846,7 @@ class StorwizeSVCCommonDriver(san.SanDriver,
self._helpers = StorwizeHelpers(self._run_ssh)
self._vdiskcopyops = {}
self._vdiskcopyops_loop = None
self.protocol = ''
self.protocol = None
self.replication = None
self._state = {'storage_nodes': {},
'enabled_protocols': set(),
@ -1926,6 +1902,26 @@ class StorwizeSVCCommonDriver(san.SanDriver,
# Get the iSCSI and FC names of the Storwize/SVC nodes
self._state['storage_nodes'] = self._helpers.get_node_info()
# Add the iSCSI IP addresses and WWPNs to the storage node info
self._helpers.add_iscsi_ip_addrs(self._state['storage_nodes'])
self._helpers.add_fc_wwpns(self._state['storage_nodes'])
# For each node, check what connection modes it supports. Delete any
# nodes that do not support any types (may be partially configured).
to_delete = []
for k, node in self._state['storage_nodes'].items():
if ((len(node['ipv4']) or len(node['ipv6']))
and len(node['iscsi_name'])):
node['enabled_protocols'].append('iSCSI')
self._state['enabled_protocols'].add('iSCSI')
if len(node['WWPN']):
node['enabled_protocols'].append('FC')
self._state['enabled_protocols'].add('FC')
if not len(node['enabled_protocols']):
to_delete.append(k)
for delkey in to_delete:
del self._state['storage_nodes'][delkey]
# Build the list of in-progress vdisk copy operations
if ctxt is None:
admin_context = context.get_admin_context()
@ -1946,6 +1942,7 @@ class StorwizeSVCCommonDriver(san.SanDriver,
self._vdiskcopyops_loop = loopingcall.FixedIntervalLoopingCall(
self._check_volume_copy_ops)
self._vdiskcopyops_loop.start(interval=self.VDISKCOPYOPS_INTERVAL)
LOG.debug('leave: do_setup')
# v2 replication setup
self._do_replication_setup()
@ -1972,6 +1969,21 @@ class StorwizeSVCCommonDriver(san.SanDriver,
exception_msg = (_('Unable to determine system id.'))
raise exception.VolumeBackendAPIException(data=exception_msg)
# Make sure we have at least one node configured
if not len(self._state['storage_nodes']):
msg = _('do_setup: No configured nodes.')
LOG.error(msg)
raise exception.VolumeDriverException(message=msg)
if self.protocol not in self._state['enabled_protocols']:
# TODO(mc_nair): improve this error message by looking at
# self._state['enabled_protocols'] to tell user what driver to use
raise exception.InvalidInput(
reason=_('The storage device does not support %(prot)s. '
'Please configure the device to support %(prot)s or '
'switch to a driver using a different protocol.')
% {'prot': self.protocol})
required_flags = ['san_ip', 'san_ssh_port', 'san_login',
'storwize_svc_volpool_name']
for flag in required_flags:
@ -1986,8 +1998,7 @@ class StorwizeSVCCommonDriver(san.SanDriver,
'authentication: set either san_password or '
'san_private_key option.'))
opts = self._helpers.build_default_opts(self.configuration,
self.protocol)
opts = self._helpers.build_default_opts(self.configuration)
self._helpers.check_vdisk_opts(self._state, opts)
LOG.debug('leave: check_for_setup_error')
@ -2119,7 +2130,6 @@ class StorwizeSVCCommonDriver(san.SanDriver,
volume_metadata=None):
return self._helpers.get_vdisk_params(self.configuration,
self._state, type_id,
self.protocol,
volume_type=volume_type,
volume_metadata=volume_metadata)
@ -2722,10 +2732,9 @@ class StorwizeSVCCommonDriver(san.SanDriver,
'diff': diff,
'host': host})
ignore_keys = ['protocol']
no_copy_keys = ['warning', 'autoexpand', 'easytier']
copy_keys = ['rsize', 'grainsize', 'compression']
all_keys = ignore_keys + no_copy_keys + copy_keys
all_keys = no_copy_keys + copy_keys
old_opts = self._get_vdisk_params(volume['volume_type_id'],
volume_metadata=
volume.get('volume_matadata'))

View File

@ -89,42 +89,10 @@ class StorwizeSVCFCDriver(storwize_common.StorwizeSVCCommonDriver):
def __init__(self, *args, **kwargs):
super(StorwizeSVCFCDriver, self).__init__(*args, **kwargs)
self.protocol = 'FC'
self.configuration.append_config_values(
storwize_svc_fc_opts)
def do_setup(self, ctxt):
# Set protocol
self.protocol = 'FC'
# Setup common functionality between FC
super(StorwizeSVCFCDriver, self).do_setup(ctxt)
# Add WWPNs to the storage node info
self._helpers.add_fc_wwpns(self._state['storage_nodes'])
# For each node, check what connection modes it supports. Delete any
# nodes that do not support any types (may be partially configured).
to_delete = []
for k, node in self._state['storage_nodes'].items():
if len(node['WWPN']):
node['enabled_protocols'].append('FC')
self._state['enabled_protocols'].add('FC')
if not len(node['enabled_protocols']):
LOG.info(_LI("%(node)s will be removed since "
"it is not supported by the"
" FC driver."), {'node': node['name']})
to_delete.append(k)
for delkey in to_delete:
del self._state['storage_nodes'][delkey]
# Make sure we have at least one node configured
if not len(self._state['storage_nodes']):
msg = _('do_setup: No configured nodes.')
LOG.error(msg)
raise exception.VolumeDriverException(message=msg)
LOG.debug('leave: do_setup')
def validate_connector(self, connector):
"""Check connector for at least one enabled FC protocol."""
if 'wwpns' not in connector:

View File

@ -39,7 +39,7 @@ from oslo_log import log as logging
from oslo_utils import excutils
from cinder import exception
from cinder.i18n import _, _LE, _LI, _LW
from cinder.i18n import _, _LE, _LW
from cinder import utils
from cinder.volume.drivers.ibm.storwize_svc import (
@ -89,46 +89,10 @@ class StorwizeSVCISCSIDriver(storwize_common.StorwizeSVCCommonDriver):
def __init__(self, *args, **kwargs):
super(StorwizeSVCISCSIDriver, self).__init__(*args, **kwargs)
self.protocol = 'iSCSI'
self.configuration.append_config_values(
storwize_svc_iscsi_opts)
def do_setup(self, ctxt):
# Set protocol
self.protocol = 'iSCSI'
# Setup common functionality between FC and iSCSI
super(StorwizeSVCISCSIDriver, self).do_setup(ctxt)
# Get the iSCSI names of the Storwize/SVC nodes
self._state['storage_nodes'] = self._helpers.get_node_info()
# Add the iSCSI IP addresses to the storage node info
self._helpers.add_iscsi_ip_addrs(self._state['storage_nodes'])
# For each node, check what connection modes it supports. Delete any
# nodes that do not support any types (may be partially configured).
to_delete = []
for k, node in self._state['storage_nodes'].items():
if ((len(node['ipv4']) or len(node['ipv6']))
and len(node['iscsi_name'])):
node['enabled_protocols'].append('iSCSI')
self._state['enabled_protocols'].add('iSCSI')
if not len(node['enabled_protocols']):
LOG.info(_LI("%(node)s will be removed since "
"it is not supported by the "
"iSCSI driver."), {'node': node['name']})
to_delete.append(k)
for delkey in to_delete:
del self._state['storage_nodes'][delkey]
# Make sure we have at least one node configured
if not len(self._state['storage_nodes']):
msg = _('do_setup: No configured nodes.')
LOG.error(msg)
raise exception.VolumeDriverException(message=msg)
LOG.debug('leave: do_setup')
def validate_connector(self, connector):
"""Check connector for at least one enabled iSCSI protocol."""
if 'initiator' not in connector:
@ -152,7 +116,6 @@ class StorwizeSVCISCSIDriver(storwize_common.StorwizeSVCCommonDriver):
LOG.debug('enter: initialize_connection: volume %(vol)s with connector'
' %(conn)s', {'vol': volume['id'], 'conn': connector})
vol_opts = self._get_vdisk_params(volume['volume_type_id'])
volume_name = volume['name']
# Check if a host object is defined for this host name
@ -194,7 +157,7 @@ class StorwizeSVCISCSIDriver(storwize_common.StorwizeSVCCommonDriver):
preferred_node_entry = None
io_group_nodes = []
for node in self._state['storage_nodes'].values():
if vol_opts['protocol'] not in node['enabled_protocols']:
if self.protocol not in node['enabled_protocols']:
continue
if node['id'] == preferred_node:
preferred_node_entry = node