From: Zhiteng Huang Date: Mon, 17 Sep 2012 09:26:09 +0000 (+0800) Subject: Update quota when deleting volume that failed to be scheduled X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=9696bd9a8c11618edf970812de822ad0ba99498c;p=openstack-build%2Fcinder-build.git Update quota when deleting volume that failed to be scheduled 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 --- diff --git a/cinder/volume/api.py b/cinder/volume/api.py index d344441a0..3a2a9a3c7 100644 --- a/cinder/volume/api.py +++ b/cinder/volume/api.py @@ -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") diff --git a/cinder/volume/manager.py b/cinder/volume/manager.py index d1d1bfe23..fbefce213 100644 --- a/cinder/volume/manager.py +++ b/cinder/volume/manager.py @@ -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'})