Remove a vol in error state from a CG

Before calling update_consistencygroup, a validation is done if volumes
are in valid states for action.

Divide the states allowed for adding and removing volumes from a CG,
and allow volume removal in states error and error_deleting.

Also added missing verification in manager update_consistencygroup in
case state has changed from cinder-api to cinder-volume.

Change-Id: I6f5fa8e9af67e17ab49e7f3423d4469640df790c
Closes-Bug: #1519377
This commit is contained in:
Alon Marx 2016-01-20 22:14:14 +02:00
parent c4770f7466
commit 80620b1fea
4 changed files with 46 additions and 9 deletions

View File

@ -43,8 +43,14 @@ CONF = cfg.CONF
LOG = logging.getLogger(__name__)
CGQUOTAS = quota.CGQUOTAS
VALID_REMOVE_VOL_FROM_CG_STATUS = (c_fields.ConsistencyGroupStatus.AVAILABLE,
c_fields.ConsistencyGroupStatus.IN_USE)
VALID_REMOVE_VOL_FROM_CG_STATUS = (
'available',
'in-use',
'error',
'error_deleting')
VALID_ADD_VOL_TO_CG_STATUS = (
'available',
'in-use')
def wrap_check_policy(func):
@ -648,7 +654,7 @@ class API(base.Base):
'volume_type': add_vol_type_id})
raise exception.InvalidVolume(reason=msg)
if (add_vol_ref['status'] not in
VALID_REMOVE_VOL_FROM_CG_STATUS):
VALID_ADD_VOL_TO_CG_STATUS):
msg = (_("Cannot add volume %(volume_id)s to consistency "
"group %(group_id)s because volume is in an "
"invalid state: %(status)s. Valid states are: "
@ -656,7 +662,7 @@ class API(base.Base):
{'volume_id': add_vol_ref['id'],
'group_id': group.id,
'status': add_vol_ref['status'],
'valid': VALID_REMOVE_VOL_FROM_CG_STATUS})
'valid': VALID_ADD_VOL_TO_CG_STATUS})
raise exception.InvalidVolume(reason=msg)
# group.host and add_vol_ref['host'] are in this format:

View File

@ -668,7 +668,13 @@ class ConsistencyGroupsAPITestCase(test.TestCase):
remove_volume_id2 = utils.create_volume(
self.ctxt,
volume_type_id=volume_type_id,
consistencygroup_id=consistencygroup.id)['id']
consistencygroup_id=consistencygroup.id,
status='error')['id']
remove_volume_id3 = utils.create_volume(
self.ctxt,
volume_type_id=volume_type_id,
consistencygroup_id=consistencygroup.id,
status='error_deleting')['id']
self.assertEqual(fields.ConsistencyGroupStatus.AVAILABLE,
consistencygroup.status)
@ -678,6 +684,7 @@ class ConsistencyGroupsAPITestCase(test.TestCase):
cg_vol_ids = [cg_vol['id'] for cg_vol in cg_volumes]
self.assertIn(remove_volume_id, cg_vol_ids)
self.assertIn(remove_volume_id2, cg_vol_ids)
self.assertIn(remove_volume_id3, cg_vol_ids)
add_volume_id = utils.create_volume(
self.ctxt,
@ -692,7 +699,8 @@ class ConsistencyGroupsAPITestCase(test.TestCase):
name = 'newcg'
description = 'New Consistency Group Description'
add_volumes = add_volume_id + "," + add_volume_id2
remove_volumes = remove_volume_id + "," + remove_volume_id2
remove_volumes = ','.join(
[remove_volume_id, remove_volume_id2, remove_volume_id3])
body = {"consistencygroup": {"name": name,
"description": description,
"add_volumes": add_volumes,

View File

@ -78,7 +78,14 @@ LOG = logging.getLogger(__name__)
QUOTAS = quota.QUOTAS
CGQUOTAS = quota.CGQUOTAS
VALID_REMOVE_VOL_FROM_CG_STATUS = ('available', 'in-use',)
VALID_REMOVE_VOL_FROM_CG_STATUS = (
'available',
'in-use',
'error',
'error_deleting')
VALID_ADD_VOL_TO_CG_STATUS = (
'available',
'in-use')
VALID_CREATE_CG_SRC_SNAP_STATUS = ('available',)
VALID_CREATE_CG_SRC_CG_STATUS = ('available',)
@ -2805,14 +2812,14 @@ class VolumeManager(manager.SchedulerDependentManager):
resource={'type': 'consistency_group',
'id': group.id})
raise
if add_vol_ref['status'] not in ['in-use', 'available']:
if add_vol_ref['status'] not in VALID_ADD_VOL_TO_CG_STATUS:
msg = (_("Cannot add volume %(volume_id)s to consistency "
"group %(group_id)s because volume is in an invalid "
"state: %(status)s. Valid states are: %(valid)s.") %
{'volume_id': add_vol_ref['id'],
'group_id': group.id,
'status': add_vol_ref['status'],
'valid': VALID_REMOVE_VOL_FROM_CG_STATUS})
'valid': VALID_ADD_VOL_TO_CG_STATUS})
raise exception.InvalidVolume(reason=msg)
# self.host is 'host@backend'
# volume_ref['host'] is 'host@backend#pool'
@ -2834,6 +2841,15 @@ class VolumeManager(manager.SchedulerDependentManager):
resource={'type': 'consistency_group',
'id': group.id})
raise
if remove_vol_ref['status'] not in VALID_REMOVE_VOL_FROM_CG_STATUS:
msg = (_("Cannot remove volume %(volume_id)s from consistency "
"group %(group_id)s because volume is in an invalid "
"state: %(status)s. Valid states are: %(valid)s.") %
{'volume_id': remove_vol_ref['id'],
'group_id': group.id,
'status': remove_vol_ref['status'],
'valid': VALID_REMOVE_VOL_FROM_CG_STATUS})
raise exception.InvalidVolume(reason=msg)
remove_volumes_ref.append(remove_vol_ref)
self._notify_about_consistencygroup_usage(

View File

@ -0,0 +1,7 @@
---
fixes:
- Previously the only way to remove volumes in error
states from a consistency-group was to delete the
consistency group and create it again. Now it is
possible to remove volumes in error and error_deleting
states.