diff --git a/engine/schema/src/com/cloud/storage/dao/VolumeDao.java b/engine/schema/src/com/cloud/storage/dao/VolumeDao.java index 4959ce4d63b..a05dc1f560d 100644 --- a/engine/schema/src/com/cloud/storage/dao/VolumeDao.java +++ b/engine/schema/src/com/cloud/storage/dao/VolumeDao.java @@ -16,6 +16,7 @@ // under the License. package com.cloud.storage.dao; +import java.util.Date; import java.util.List; import com.cloud.hypervisor.Hypervisor.HypervisorType; @@ -79,6 +80,8 @@ public interface VolumeDao extends GenericDao, StateDao listVolumesToBeDestroyed(); + List listVolumesToBeDestroyed(Date date); + ImageFormat getImageFormat(Long volumeId); List findReadyRootVolumesByInstance(long instanceId); diff --git a/engine/schema/src/com/cloud/storage/dao/VolumeDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/VolumeDaoImpl.java index f5738477540..d53471fee5c 100644 --- a/engine/schema/src/com/cloud/storage/dao/VolumeDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/VolumeDaoImpl.java @@ -331,6 +331,7 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol AllFieldsSearch.and("id", AllFieldsSearch.entity().getId(), Op.EQ); AllFieldsSearch.and("destroyed", AllFieldsSearch.entity().getState(), Op.EQ); AllFieldsSearch.and("notDestroyed", AllFieldsSearch.entity().getState(), Op.NEQ); + AllFieldsSearch.and("updateTime", AllFieldsSearch.entity().getUpdated(), SearchCriteria.Op.LT); AllFieldsSearch.and("updatedCount", AllFieldsSearch.entity().getUpdatedCount(), Op.EQ); AllFieldsSearch.and("name", AllFieldsSearch.entity().getName(), Op.EQ); AllFieldsSearch.done(); @@ -482,6 +483,15 @@ public class VolumeDaoImpl extends GenericDaoBase implements Vol return listBy(sc); } + @Override + public List listVolumesToBeDestroyed(Date date) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("state", Volume.State.Destroy); + sc.setParameters("updateTime", date); + + return listBy(sc); + } + @Override public boolean updateState(com.cloud.storage.Volume.State currentState, Event event, com.cloud.storage.Volume.State nextState, Volume vo, Object data) { diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index 182ec50e300..d9abecde86e 100644 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -672,6 +672,7 @@ public enum Config { "86400", "The interval (in seconds) to wait before running the storage cleanup thread.", null), + StorageCleanupDelay("Advanced", StorageManager.class, Integer.class, "storage.cleanup.delay", "86400", "Determines how long (in seconds) to wait before actually expunging destroyed volumes. The default value = the default value of storage.cleanup.interval.", null), StorageCleanupEnabled("Advanced", StorageManager.class, Boolean.class, "storage.cleanup.enabled", "true", "Enables/disables the storage cleanup thread.", null), UpdateWait("Advanced", AgentManager.class, Integer.class, "update.wait", "600", "Time to wait (in seconds) before alerting on a updating agent", null), XapiWait("Advanced", AgentManager.class, Integer.class, "xapiwait", "60", "Time (in seconds) to wait for XAPI to return", null), diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index ba39e1f0fa8..595cf145b3e 100644 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -301,6 +301,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C boolean _templateCleanupEnabled = true; int _storageCleanupInterval; int _storagePoolAcquisitionWaitSeconds = 1800; // 30 minutes + int _storageCleanupDelay; int _downloadUrlCleanupInterval; int _downloadUrlExpirationInterval; // protected BigDecimal _overProvisioningFactor = new BigDecimal(1); @@ -470,9 +471,11 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C String time = configs.get("storage.cleanup.interval"); _storageCleanupInterval = NumbersUtil.parseInt(time, 86400); + time = configs.get("storage.cleanup.delay"); + _storageCleanupDelay = NumbersUtil.parseInt(time, _storageCleanupInterval); - s_logger.info("Storage cleanup enabled: " + _storageCleanupEnabled + ", interval: " + _storageCleanupInterval + ", template cleanup enabled: " + - _templateCleanupEnabled); + s_logger.info("Storage cleanup enabled: " + _storageCleanupEnabled + ", interval: " + _storageCleanupInterval + ", delay: " + _storageCleanupDelay + + ", template cleanup enabled: " + _templateCleanupEnabled); String cleanupInterval = configs.get("extract.url.cleanup.interval"); _downloadUrlCleanupInterval = NumbersUtil.parseInt(cleanupInterval, 7200); @@ -1111,7 +1114,7 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C cleanupSecondaryStorage(recurring); - List vols = _volsDao.listVolumesToBeDestroyed(); + List vols = _volsDao.listVolumesToBeDestroyed(new Date(System.currentTimeMillis() - ((long) _storageCleanupDelay << 10))); for (VolumeVO vol : vols) { try { volService.expungeVolumeAsync(volFactory.getVolume(vol.getId()));