Skip to content

Commit a8990cf

Browse files
committed
CLOUDSTACK-4003: We should not delete a READY data object from object
store ref table in case of any operation failure related to this data object.
1 parent 5908a39 commit a8990cf

5 files changed

Lines changed: 59 additions & 8 deletions

File tree

engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ public void processEvent(Event event) {
167167
} finally {
168168
// in case of OperationFailed, expunge the entry
169169
if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) {
170-
objectInStoreMgr.delete(this);
170+
objectInStoreMgr.deleteIfNotReady(this);
171171
}
172172
}
173173
}
@@ -218,7 +218,7 @@ public void processEvent(ObjectInDataStoreStateMachine.Event event, Answer answe
218218
} finally {
219219
// in case of OperationFailed, expunge the entry
220220
if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) {
221-
objectInStoreMgr.delete(this);
221+
objectInStoreMgr.deleteIfNotReady(this);
222222
}
223223
}
224224
}

engine/storage/snapshot/src/org/apache/cloudstack/storage/snapshot/SnapshotObject.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ public void processEvent(ObjectInDataStoreStateMachine.Event event) {
160160
throw new CloudRuntimeException("Failed to update state: " + e.toString());
161161
} finally {
162162
if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) {
163-
objectInStoreMgr.delete(this);
163+
objectInStoreMgr.deleteIfNotReady(this);
164164
}
165165
}
166166
}
@@ -267,13 +267,14 @@ public void processEvent(ObjectInDataStoreStateMachine.Event event, Answer answe
267267
}
268268
} catch (RuntimeException ex) {
269269
if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) {
270-
objectInStoreMgr.delete(this);
270+
objectInStoreMgr.deleteIfNotReady(this);
271271
}
272272
throw ex;
273273
}
274274
this.processEvent(event);
275275
}
276276

277+
@Override
277278
public void incRefCount() {
278279
if (this.store == null) {
279280
return;

engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManager.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ public interface ObjectInDataStoreManager {
3131

3232
public boolean delete(DataObject dataObj);
3333

34+
public boolean deleteIfNotReady(DataObject dataObj);
35+
3436
public DataObject get(DataObject dataObj, DataStore store);
3537

3638
public boolean update(DataObject vo, Event event) throws NoTransitionException, ConcurrentOperationException;

engine/storage/src/org/apache/cloudstack/storage/datastore/ObjectInDataStoreManagerImpl.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,54 @@ public boolean delete(DataObject dataObj) {
232232
return false;
233233
}
234234

235+
@Override
236+
public boolean deleteIfNotReady(DataObject dataObj) {
237+
long objId = dataObj.getId();
238+
DataStore dataStore = dataObj.getDataStore();
239+
if (dataStore.getRole() == DataStoreRole.Primary) {
240+
if (dataObj.getType() == DataObjectType.TEMPLATE) {
241+
VMTemplateStoragePoolVO destTmpltPool = templatePoolDao.findByPoolTemplate(dataStore.getId(), objId);
242+
if (destTmpltPool != null && destTmpltPool.getState() != ObjectInDataStoreStateMachine.State.Ready) {
243+
return templatePoolDao.remove(destTmpltPool.getId());
244+
} else {
245+
s_logger.warn("Template " + objId + " is not found on storage pool " + dataStore.getId() + ", so no need to delete");
246+
return true;
247+
}
248+
}
249+
} else {
250+
// Image store
251+
switch (dataObj.getType()) {
252+
case TEMPLATE:
253+
TemplateDataStoreVO destTmpltStore = templateDataStoreDao.findByStoreTemplate(dataStore.getId(), objId);
254+
if (destTmpltStore != null && destTmpltStore.getState() != ObjectInDataStoreStateMachine.State.Ready) {
255+
return templateDataStoreDao.remove(destTmpltStore.getId());
256+
} else {
257+
s_logger.warn("Template " + objId + " is not found on image store " + dataStore.getId() + ", so no need to delete");
258+
return true;
259+
}
260+
case SNAPSHOT:
261+
SnapshotDataStoreVO destSnapshotStore = snapshotDataStoreDao.findByStoreSnapshot(dataStore.getRole(), dataStore.getId(), objId);
262+
if (destSnapshotStore != null && destSnapshotStore.getState() != ObjectInDataStoreStateMachine.State.Ready) {
263+
return snapshotDataStoreDao.remove(destSnapshotStore.getId());
264+
} else {
265+
s_logger.warn("Snapshot " + objId + " is not found on image store " + dataStore.getId() + ", so no need to delete");
266+
return true;
267+
}
268+
case VOLUME:
269+
VolumeDataStoreVO destVolumeStore = volumeDataStoreDao.findByStoreVolume(dataStore.getId(), objId);
270+
if (destVolumeStore != null && destVolumeStore.getState() != ObjectInDataStoreStateMachine.State.Ready) {
271+
return volumeDataStoreDao.remove(destVolumeStore.getId());
272+
} else {
273+
s_logger.warn("Volume " + objId + " is not found on image store " + dataStore.getId() + ", so no need to delete");
274+
return true;
275+
}
276+
}
277+
}
278+
279+
s_logger.warn("Unsupported data object (" + dataObj.getType() + ", " + dataObj.getDataStore() + "), no need to delete from object in store ref table");
280+
return false;
281+
}
282+
235283
@Override
236284
public boolean update(DataObject data, Event event) throws NoTransitionException, ConcurrentOperationException {
237285
DataObjectInStore obj = this.findObject(data, data.getDataStore());

engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeObject.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ public void processEvent(ObjectInDataStoreStateMachine.Event event) {
293293
// in case of OperationFailed, expunge the entry
294294
if (event == ObjectInDataStoreStateMachine.Event.OperationFailed
295295
&& (this.volumeVO.getState() != Volume.State.Copying && this.volumeVO.getState() != Volume.State.Uploaded)) {
296-
objectInStoreMgr.delete(this);
296+
objectInStoreMgr.deleteIfNotReady(this);
297297
}
298298
}
299299

@@ -309,7 +309,7 @@ public void processEventOnly(ObjectInDataStoreStateMachine.Event event) {
309309
} finally {
310310
// in case of OperationFailed, expunge the entry
311311
if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) {
312-
objectInStoreMgr.delete(this);
312+
objectInStoreMgr.deleteIfNotReady(this);
313313
}
314314
}
315315
}
@@ -504,7 +504,7 @@ public void processEvent(ObjectInDataStoreStateMachine.Event event, Answer answe
504504
}
505505
} catch (RuntimeException ex) {
506506
if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) {
507-
objectInStoreMgr.delete(this);
507+
objectInStoreMgr.deleteIfNotReady(this);
508508
}
509509
throw ex;
510510
}
@@ -593,7 +593,7 @@ public void processEventOnly(ObjectInDataStoreStateMachine.Event event, Answer a
593593
}
594594
} catch (RuntimeException ex) {
595595
if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) {
596-
objectInStoreMgr.delete(this);
596+
objectInStoreMgr.deleteIfNotReady(this);
597597
}
598598
throw ex;
599599
}

0 commit comments

Comments
 (0)