diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java index ba5a7d19605..0c0aa996793 100644 --- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java +++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java @@ -167,7 +167,7 @@ public class TemplateObject implements TemplateInfo { } finally { // in case of OperationFailed, expunge the entry if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) { - objectInStoreMgr.delete(this); + objectInStoreMgr.deleteIfNotReady(this); } } } @@ -218,7 +218,7 @@ public class TemplateObject implements TemplateInfo { } finally { // in case of OperationFailed, expunge the entry if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) { - objectInStoreMgr.delete(this); + objectInStoreMgr.deleteIfNotReady(this); } } } diff --git a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java index c8a0bc8a794..3d67d3805c4 100644 --- a/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java +++ b/engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java @@ -160,7 +160,7 @@ public class SnapshotObject implements SnapshotInfo { throw new CloudRuntimeException("Failed to update state: " + e.toString()); } finally { if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) { - objectInStoreMgr.delete(this); + objectInStoreMgr.deleteIfNotReady(this); } } } @@ -267,13 +267,14 @@ public class SnapshotObject implements SnapshotInfo { } } catch (RuntimeException ex) { if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) { - objectInStoreMgr.delete(this); + objectInStoreMgr.deleteIfNotReady(this); } throw ex; } this.processEvent(event); } + @Override public void incRefCount() { if (this.store == null) { return; diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java index fbd315e3826..3dc6ac497a9 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java @@ -31,6 +31,8 @@ public interface ObjectInDataStoreManager { public boolean delete(DataObject dataObj); + public boolean deleteIfNotReady(DataObject dataObj); + public DataObject get(DataObject dataObj, DataStore store); public boolean update(DataObject vo, Event event) throws NoTransitionException, ConcurrentOperationException; diff --git a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java index c673776357e..6b925ce3797 100644 --- a/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java +++ b/engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java @@ -232,6 +232,54 @@ public class ObjectInDataStoreManagerImpl implements ObjectInDataStoreManager { return false; } + @Override + public boolean deleteIfNotReady(DataObject dataObj) { + long objId = dataObj.getId(); + DataStore dataStore = dataObj.getDataStore(); + if (dataStore.getRole() == DataStoreRole.Primary) { + if (dataObj.getType() == DataObjectType.TEMPLATE) { + VMTemplateStoragePoolVO destTmpltPool = templatePoolDao.findByPoolTemplate(dataStore.getId(), objId); + if (destTmpltPool != null && destTmpltPool.getState() != ObjectInDataStoreStateMachine.State.Ready) { + return templatePoolDao.remove(destTmpltPool.getId()); + } else { + s_logger.warn("Template " + objId + " is not found on storage pool " + dataStore.getId() + ", so no need to delete"); + return true; + } + } + } else { + // Image store + switch (dataObj.getType()) { + case TEMPLATE: + TemplateDataStoreVO destTmpltStore = templateDataStoreDao.findByStoreTemplate(dataStore.getId(), objId); + if (destTmpltStore != null && destTmpltStore.getState() != ObjectInDataStoreStateMachine.State.Ready) { + return templateDataStoreDao.remove(destTmpltStore.getId()); + } else { + s_logger.warn("Template " + objId + " is not found on image store " + dataStore.getId() + ", so no need to delete"); + return true; + } + case SNAPSHOT: + SnapshotDataStoreVO destSnapshotStore = snapshotDataStoreDao.findByStoreSnapshot(dataStore.getRole(), dataStore.getId(), objId); + if (destSnapshotStore != null && destSnapshotStore.getState() != ObjectInDataStoreStateMachine.State.Ready) { + return snapshotDataStoreDao.remove(destSnapshotStore.getId()); + } else { + s_logger.warn("Snapshot " + objId + " is not found on image store " + dataStore.getId() + ", so no need to delete"); + return true; + } + case VOLUME: + VolumeDataStoreVO destVolumeStore = volumeDataStoreDao.findByStoreVolume(dataStore.getId(), objId); + if (destVolumeStore != null && destVolumeStore.getState() != ObjectInDataStoreStateMachine.State.Ready) { + return volumeDataStoreDao.remove(destVolumeStore.getId()); + } else { + s_logger.warn("Volume " + objId + " is not found on image store " + dataStore.getId() + ", so no need to delete"); + return true; + } + } + } + + s_logger.warn("Unsupported data object (" + dataObj.getType() + ", " + dataObj.getDataStore() + "), no need to delete from object in store ref table"); + return false; + } + @Override public boolean update(DataObject data, Event event) throws NoTransitionException, ConcurrentOperationException { DataObjectInStore obj = this.findObject(data, data.getDataStore()); 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 b5968b676d7..7ec502241e6 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 @@ -293,7 +293,7 @@ public class VolumeObject implements VolumeInfo { // in case of OperationFailed, expunge the entry if (event == ObjectInDataStoreStateMachine.Event.OperationFailed && (this.volumeVO.getState() != Volume.State.Copying && this.volumeVO.getState() != Volume.State.Uploaded)) { - objectInStoreMgr.delete(this); + objectInStoreMgr.deleteIfNotReady(this); } } @@ -309,7 +309,7 @@ public class VolumeObject implements VolumeInfo { } finally { // in case of OperationFailed, expunge the entry if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) { - objectInStoreMgr.delete(this); + objectInStoreMgr.deleteIfNotReady(this); } } } @@ -504,7 +504,7 @@ public class VolumeObject implements VolumeInfo { } } catch (RuntimeException ex) { if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) { - objectInStoreMgr.delete(this); + objectInStoreMgr.deleteIfNotReady(this); } throw ex; } @@ -593,7 +593,7 @@ public class VolumeObject implements VolumeInfo { } } catch (RuntimeException ex) { if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) { - objectInStoreMgr.delete(this); + objectInStoreMgr.deleteIfNotReady(this); } throw ex; }