From a955730b569be6f1132cbd254d8f21828c54d2f2 Mon Sep 17 00:00:00 2001 From: Rongze Zhu Date: Wed, 12 Sep 2012 07:10:53 +0000 Subject: [PATCH] Add volume quota in volume/api.py and olume/manager.py Fixes bug #1048158 volume.api.API.create() call QUOTAS.reserve(), then volume.manager.VolumeManager.create_volume call QUOTAS.commit(). volume.manager.VolumeManager.delete_volume call QUOTAS.reserve() and QUOTAS.commit(). It also fixes bug #1049459. Change-Id: I764aeec83cce93595fbe9aa00205a7d8c9e13c35 --- cinder/volume/api.py | 12 ++++++++---- cinder/volume/manager.py | 24 +++++++++++++++++++++++- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/cinder/volume/api.py b/cinder/volume/api.py index 0d340bc4a..d344441a0 100644 --- a/cinder/volume/api.py +++ b/cinder/volume/api.py @@ -164,10 +164,12 @@ class API(base.Base): } volume = self.db.volume_create(context, options) - self._cast_create_volume(context, volume['id'], snapshot_id, image_id) + self._cast_create_volume(context, volume['id'], snapshot_id, + image_id, reservations) return volume - def _cast_create_volume(self, context, volume_id, snapshot_id, image_id): + def _cast_create_volume(self, context, volume_id, snapshot_id, + image_id, reservations): # NOTE(Rongze Zhu): It is a simple solution for bug 1008866 # If snapshot_id is set, make the call create volume directly to @@ -186,7 +188,8 @@ class API(base.Base): {"method": "create_volume", "args": {"volume_id": volume_id, "snapshot_id": snapshot_id, - "image_id": image_id}}) + "image_id": image_id, + "reservations": reservations}}) else: rpc.cast(context, FLAGS.scheduler_topic, @@ -194,7 +197,8 @@ class API(base.Base): "args": {"topic": FLAGS.volume_topic, "volume_id": volume_id, "snapshot_id": snapshot_id, - "image_id": image_id}}) + "image_id": image_id, + "reservations": reservations}}) @wrap_check_policy def delete(self, context, volume, force=False): diff --git a/cinder/volume/manager.py b/cinder/volume/manager.py index bc82a5eb7..beb038c2e 100644 --- a/cinder/volume/manager.py +++ b/cinder/volume/manager.py @@ -47,12 +47,15 @@ from cinder.openstack.common import cfg from cinder.openstack.common import excutils from cinder.openstack.common import importutils from cinder.openstack.common import timeutils +from cinder import quota from cinder import utils from cinder.volume import utils as volume_utils LOG = logging.getLogger(__name__) +QUOTAS = quota.QUOTAS + volume_manager_opts = [ cfg.StrOpt('volume_driver', default='cinder.volume.driver.ISCSIDriver', @@ -100,7 +103,7 @@ class VolumeManager(manager.SchedulerDependentManager): LOG.info(_("volume %s: skipping export"), volume['name']) def create_volume(self, context, volume_id, snapshot_id=None, - image_id=None): + image_id=None, reservations=None): """Creates and exports the volume.""" context = context.elevated() volume_ref = self.db.volume_get(context, volume_id) @@ -147,8 +150,14 @@ class VolumeManager(manager.SchedulerDependentManager): model_update = self.driver.create_export(context, volume_ref) if model_update: self.db.volume_update(context, volume_ref['id'], model_update) + + # Commit the reservation + if reservations: + QUOTAS.commit(context, reservations) except Exception: with excutils.save_and_reraise_exception(): + if reservations: + QUOTAS.rollback(context, reservations) self.db.volume_update(context, volume_ref['id'], {'status': 'error'}) @@ -195,9 +204,22 @@ class VolumeManager(manager.SchedulerDependentManager): volume_ref['id'], {'status': 'error_deleting'}) + # Get reservations + try: + reservations = QUOTAS.reserve(context, volumes=-1, + gigabytes=-volume_ref['size']) + except Exception: + reservations = None + LOG.exception(_("Failed to update usages deleting volume")) + self.db.volume_destroy(context, volume_id) LOG.debug(_("volume %s: deleted successfully"), volume_ref['name']) self._notify_about_volume_usage(context, volume_ref, "delete.end") + + # Commit the reservations + if reservations: + QUOTAS.commit(context, reservations) + return True def create_snapshot(self, context, volume_id, snapshot_id): -- 2.45.2