From 18308807de7e7090854d6fde9ae06c7ffbf9b7ac Mon Sep 17 00:00:00 2001 From: John Griffith Date: Fri, 12 Jul 2013 17:43:27 -0600 Subject: [PATCH] Be sure to check deleted types on quota update. If a volume-type is deleted, and later a volume that's assigned that type is deleted the quota update will fail and result in a trace for VolumeTypeNotFound exception. The volume is succesfully deleted, however the quota information for the volume-type let alone the other quota items for the volume are not updated. Fixes bug: 1200709 Change-Id: Idd687514be9d622df84aad54b1b33ddc6615851b --- cinder/db/api.py | 4 ++-- cinder/db/sqlalchemy/api.py | 12 ++++++++---- cinder/quota.py | 12 ++++++++++-- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/cinder/db/api.py b/cinder/db/api.py index 0cd60c1c0..28e349f36 100644 --- a/cinder/db/api.py +++ b/cinder/db/api.py @@ -384,9 +384,9 @@ def volume_type_get_all(context, inactive=False): return IMPL.volume_type_get_all(context, inactive) -def volume_type_get(context, id): +def volume_type_get(context, id, inactive=False): """Get volume type by id.""" - return IMPL.volume_type_get(context, id) + return IMPL.volume_type_get(context, id, inactive) def volume_type_get_by_name(context, name): diff --git a/cinder/db/sqlalchemy/api.py b/cinder/db/sqlalchemy/api.py index 7259db9a2..10d053f49 100644 --- a/cinder/db/sqlalchemy/api.py +++ b/cinder/db/sqlalchemy/api.py @@ -1607,8 +1607,12 @@ def volume_type_get_all(context, inactive=False, filters=None): @require_context -def _volume_type_get(context, id, session=None): - result = model_query(context, models.VolumeTypes, session=session).\ +def _volume_type_get(context, id, session=None, inactive=False): + read_deleted = "yes" if inactive else "no" + result = model_query(context, + models.VolumeTypes, + session=session, + read_deleted=read_deleted).\ options(joinedload('extra_specs')).\ filter_by(id=id).\ first() @@ -1620,10 +1624,10 @@ def _volume_type_get(context, id, session=None): @require_context -def volume_type_get(context, id): +def volume_type_get(context, id, inactive=False): """Returns a dict describing specific volume_type""" - return _volume_type_get(context, id) + return _volume_type_get(context, id, None, inactive) @require_context diff --git a/cinder/quota.py b/cinder/quota.py index 16f77a510..f5bcccb7c 100644 --- a/cinder/quota.py +++ b/cinder/quota.py @@ -879,7 +879,12 @@ class QuotaEngine(object): """ if not volume_type_id: return - volume_type = db.volume_type_get(context, volume_type_id) + + # NOTE(jdg): set inactive to True in volume_type_get, as we + # may be operating on a volume that was created with a type + # that has since been deleted. + volume_type = db.volume_type_get(context, volume_type_id, True) + for quota in ('volumes', 'gigabytes', 'snapshots'): if quota in opts: vtype_quota = "%s_%s" % (quota, volume_type['name']) @@ -911,7 +916,10 @@ class VolumeTypeQuotaEngine(QuotaEngine): result[resource.name] = resource # Volume type quotas. - volume_types = db.volume_type_get_all(context.get_admin_context()) + # NOTE(jdg): We also want to check deleted types here as well + # if we don't the _get_quotas resource len check on will fail + volume_types = db.volume_type_get_all(context.get_admin_context(), + True) for volume_type in volume_types.values(): for part_name in ('volumes', 'gigabytes', 'snapshots'): resource = VolumeTypeResource(part_name, volume_type) -- 2.45.2