]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Update quota when deleting volume that failed to be scheduled
authorZhiteng Huang <zhiteng.huang@intel.com>
Mon, 17 Sep 2012 09:26:09 +0000 (17:26 +0800)
committerZhiteng Huang <zhiteng.huang@intel.com>
Mon, 17 Sep 2012 16:51:48 +0000 (00:51 +0800)
If one volume was failed to get scheduled, removing such volume should
also clean up reservation.
Also when create_volume is ready to send to scheduler, reservation
should be committed no matter backend can successfully create that
volume or not since deleting volume call will do a minus reservation
even on volume with 'error' status.

Fix bug 1052052

Change-Id: Iaec9926024ad5adb38b08b07772095f49b8593c2

cinder/volume/api.py
cinder/volume/manager.py

index d344441a0de94265783a5f9ea02fad522714e41a..3a2a9a3c782143ea6f0a66bd7a7a9a42c648d8ab 100644 (file)
@@ -164,12 +164,15 @@ class API(base.Base):
             }
 
         volume = self.db.volume_create(context, options)
+
+        QUOTAS.commit(context, reservations)
+
         self._cast_create_volume(context, volume['id'], snapshot_id,
-                                 image_id, reservations)
+                                 image_id)
         return volume
 
     def _cast_create_volume(self, context, volume_id, snapshot_id,
-                            image_id, reservations):
+                            image_id):
 
         # NOTE(Rongze Zhu): It is a simple solution for bug 1008866
         # If snapshot_id is set, make the call create volume directly to
@@ -188,8 +191,7 @@ class API(base.Base):
                      {"method": "create_volume",
                       "args": {"volume_id": volume_id,
                                "snapshot_id": snapshot_id,
-                               "image_id": image_id,
-                               "reservations": reservations}})
+                               "image_id": image_id}})
         else:
             rpc.cast(context,
                      FLAGS.scheduler_topic,
@@ -197,15 +199,25 @@ class API(base.Base):
                       "args": {"topic": FLAGS.volume_topic,
                                "volume_id": volume_id,
                                "snapshot_id": snapshot_id,
-                               "image_id": image_id,
-                               "reservations": reservations}})
+                               "image_id": image_id}})
 
     @wrap_check_policy
     def delete(self, context, volume, force=False):
         volume_id = volume['id']
         if not volume['host']:
             # NOTE(vish): scheduling failed, so delete it
+            # Note(zhiteng): update volume quota reservation
+            try:
+                reservations = QUOTAS.reserve(context, volumes=-1,
+                                              gigabytes=-volume['size'])
+            except Exception:
+                reservations = None
+                LOG.exception(_("Failed to update quota for deleting volume"))
+
             self.db.volume_destroy(context, volume_id)
+
+            if reservations:
+                QUOTAS.commit(context, reservations)
             return
         if not force and volume['status'] not in ["available", "error"]:
             msg = _("Volume status must be available or error")
index d1d1bfe23c5747e5cd5bce3dd9310b6bcce527f7..fbefce21303895b6a7708b16a870adc33104cbe2 100644 (file)
@@ -105,11 +105,11 @@ class VolumeManager(manager.SchedulerDependentManager):
         LOG.debug(_('Resuming any in progress delete operations'))
         for volume in volumes:
             if volume['status'] == 'deleting':
-                LOG.info(_('Resuming delete on volume: %s' % volume['id']))
+                LOG.info(_('Resuming delete on volume: %s') % volume['id'])
                 self.delete_volume(ctxt, volume['id'])
 
     def create_volume(self, context, volume_id, snapshot_id=None,
-                      image_id=None, reservations=None):
+                      image_id=None):
         """Creates and exports the volume."""
         context = context.elevated()
         volume_ref = self.db.volume_get(context, volume_id)
@@ -157,13 +157,8 @@ class VolumeManager(manager.SchedulerDependentManager):
             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'})