]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Add volume quota in volume/api.py and olume/manager.py
authorRongze Zhu <zrzhit@gmail.com>
Wed, 12 Sep 2012 07:10:53 +0000 (07:10 +0000)
committerRongze Zhu <zrzhit@gmail.com>
Wed, 12 Sep 2012 07:10:53 +0000 (07:10 +0000)
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
cinder/volume/manager.py

index 0d340bc4aa31527fb0d6c44719a5f29dc32dcb3f..d344441a0de94265783a5f9ea02fad522714e41a 100644 (file)
@@ -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):
index bc82a5eb76a1bd04f753fa65de8bbc0838865198..beb038c2ec1ac0a2578034b933df6d7e3708471a 100644 (file)
@@ -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):