From b3e0099e0a0ea9b22a350320f56a8421823fedc1 Mon Sep 17 00:00:00 2001 From: Koushik Das Date: Tue, 21 Jul 2015 14:28:38 +0530 Subject: [PATCH] CLOUDSTACK-8655: [Browser Based Upload Volume] Partially uploaded volumes are not getting destroyed as part of storage GC As part of volume sync, that runs during of SSVM start-up, the volume_store_ref entry was getting deleted. Volume GC relies on this entry to move volume to destroyed state. Since the entry was getting deleted, GC thread never moved the volume from UploadError/UploadAbandoned to Destroyed. Fix is to not remove the volume_store_ref entry as part of volume sync and let GC thread handle the clean up. --- .../storage/volume/VolumeObject.java | 3 +- .../component/test_browse_volumes.py | 28 +++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java index e8518704d9ef..5bf49a9a8138 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java @@ -333,11 +333,10 @@ public void processEvent(ObjectInDataStoreStateMachine.Event event) { } finally { // in case of OperationFailed, expunge the entry if (event == ObjectInDataStoreStateMachine.Event.OperationFailed && - (volumeVO.getState() != Volume.State.Copying && volumeVO.getState() != Volume.State.Uploaded)) { + (volumeVO.getState() != Volume.State.Copying && volumeVO.getState() != Volume.State.Uploaded && volumeVO.getState() != Volume.State.UploadError)) { objectInStoreMgr.deleteIfNotReady(this); } } - } @Override diff --git a/test/integration/component/test_browse_volumes.py b/test/integration/component/test_browse_volumes.py index 4c153517a3f1..12aa037d57ac 100644 --- a/test/integration/component/test_browse_volumes.py +++ b/test/integration/component/test_browse_volumes.py @@ -2678,6 +2678,34 @@ def test_17_Browser_Upload_Volume_secondary_storage_resource_limits_after_deleti return + @attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="false") + def test_browser_upload_volume_incomplete(self): + """ + Test browser based incomplete volume upload, followed by SSVM destroy. Volume should go to UploadAbandoned/Error state and get cleaned up. + """ + try: + self.debug("========================= Test browser based incomplete volume upload ========================") + + #Only register volume, without uploading + cmd = getUploadParamsForVolume.getUploadParamsForVolumeCmd() + cmd.zoneid = self.zone.id + cmd.format = self.uploadvolumeformat + cmd.name = self.volname + self.account.name + (random.choice(string.ascii_uppercase)) + cmd.account = self.account.name + cmd.domainid = self.domain.id + upload_volume_response = self.apiclient.getUploadParamsForVolume(cmd) + + #Destroy SSVM, and wait for new one to start + self.destroy_ssvm() + + #Verify that the volume is cleaned up as part of sync-up during new SSVM start + self.validate_uploaded_volume(upload_volume_response.id, 'UploadAbandoned') + + except Exception as e: + self.fail("Exceptione occurred : %s" % e) + return + + @classmethod def tearDownClass(self): try: