diff --git a/cinder/volume/drivers/ibm/storwize_svc/__init__.py b/cinder/volume/drivers/ibm/storwize_svc/__init__.py index 463e080aee3..24709b81f9a 100644 --- a/cinder/volume/drivers/ibm/storwize_svc/__init__.py +++ b/cinder/volume/drivers/ibm/storwize_svc/__init__.py @@ -635,7 +635,16 @@ class StorwizeSVCDriver(san.SanDriver): ctxt = context.get_admin_context() copy_items = self._vdiskcopyops.items() for vol_id, copy_ops in copy_items: - volume = self.db.volume_get(ctxt, vol_id) + try: + volume = self.db.volume_get(ctxt, vol_id) + except Exception: + LOG.warn(_('Volume %s does not exist.'), vol_id) + del self._vdiskcopyops[vol_id] + if not len(self._vdiskcopyops): + self._vdiskcopyops_loop.stop() + self._vdiskcopyops_loop = None + continue + for copy_op in copy_ops: try: synced = self._helpers.is_vdisk_copy_synced(volume['name'], @@ -682,6 +691,7 @@ class StorwizeSVCDriver(san.SanDriver): else: vol_type = None + self._check_volume_copy_ops() new_op = self._helpers.add_vdisk_copy(volume['name'], dest_pool, vol_type, self._state, self.configuration) @@ -703,6 +713,11 @@ class StorwizeSVCDriver(san.SanDriver): host['host'] is its name, and host['capabilities'] is a dictionary of its reported capabilities. """ + def retype_iogrp_property(volume, new, old): + if new != old: + self._helpers.change_vdisk_iogrp(volume['name'], + self._state, (new, old)) + LOG.debug(_('enter: retype: id=%(id)s, new_type=%(new_type)s,' 'diff=%(diff)s, host=%(host)s') % {'id': volume['id'], 'new_type': new_type, @@ -732,24 +747,27 @@ class StorwizeSVCDriver(san.SanDriver): need_copy = True if need_copy: + self._check_volume_copy_ops() dest_pool = self._helpers.can_migrate_to_host(host, self._state) if dest_pool is None: return False - if old_opts['iogrp'] != new_opts['iogrp']: - self._helpers.change_vdisk_iogrp(volume['name'], self._state, - (new_opts['iogrp'], - old_opts['iogrp'])) - - new_op = self._helpers.add_vdisk_copy(volume['name'], dest_pool, - new_type, self._state, - self.configuration) - self._add_vdisk_copy_op(ctxt, volume, new_op) + retype_iogrp_property(volume, new_opts['iogrp'], old_opts['iogrp']) + try: + new = self._helpers.add_vdisk_copy(volume['name'], dest_pool, + new_type, self._state, + self.configuration) + self._add_vdisk_copy_op(ctxt, volume, new) + except exception.VolumeDriverException: + # roll back changing iogrp property + retype_iogrp_property(volume, old_opts['iogrp'], + new_opts['iogrp']) + msg = (_('Unable to retype: A copy of volume %s exists. ' + 'Retyping would exceed the limit of 2 copies.'), + volume['id']) + raise exception.VolumeDriverException(message=msg) else: - if old_opts['iogrp'] != new_opts['iogrp']: - self._helpers.change_vdisk_iogrp(volume['name'], self._state, - (new_opts['iogrp'], - old_opts['iogrp'])) + retype_iogrp_property(volume, new_opts['iogrp'], old_opts['iogrp']) self._helpers.change_vdisk_options(volume['name'], vdisk_changes, new_opts, self._state) diff --git a/cinder/volume/drivers/ibm/storwize_svc/helpers.py b/cinder/volume/drivers/ibm/storwize_svc/helpers.py index b973c45844d..558117526a4 100644 --- a/cinder/volume/drivers/ibm/storwize_svc/helpers.py +++ b/cinder/volume/drivers/ibm/storwize_svc/helpers.py @@ -681,12 +681,13 @@ class StorwizeHelpers(object): def add_vdisk_copy(self, vdisk, dest_pool, volume_type, state, config): """Add a vdisk copy in the given pool.""" - this_pool = config.storwize_svc_volpool_name resp = self.ssh.lsvdiskcopy(vdisk) - orig_copy_id = None - for copy_id, mdisk_grp in resp.select('copy_id', 'mdisk_grp_name'): - if mdisk_grp == this_pool: - orig_copy_id = copy_id + if len(resp) > 1: + msg = (_('add_vdisk_copy failed: A copy of volume %s exists. ' + 'Adding another copy would exceed the limit of ' + '2 copies.') % vdisk) + raise exception.VolumeDriverException(message=msg) + orig_copy_id = resp[0].get("copy_id", None) if orig_copy_id is None: msg = (_('add_vdisk_copy started without a vdisk copy in the '