diff --git a/engine/schema/src/com/cloud/storage/dao/SnapshotDao.java b/engine/schema/src/com/cloud/storage/dao/SnapshotDao.java index a58902121cc..0868ac401f0 100644 --- a/engine/schema/src/com/cloud/storage/dao/SnapshotDao.java +++ b/engine/schema/src/com/cloud/storage/dao/SnapshotDao.java @@ -56,14 +56,4 @@ public interface SnapshotDao extends GenericDao, StateDao listByStatus(long volumeId, Snapshot.State... status); List listAllByStatus(Snapshot.State... status); - - /** - * Gets the Total Secondary Storage space (in bytes) used by snapshots - * allocated for an account - * - * @param account - * @return total Secondary Storage space allocated - */ - long secondaryStorageUsedForAccount(long accountId); - } diff --git a/engine/schema/src/com/cloud/storage/dao/SnapshotDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/SnapshotDaoImpl.java index c56a3cf43b8..30a135087cc 100644 --- a/engine/schema/src/com/cloud/storage/dao/SnapshotDaoImpl.java +++ b/engine/schema/src/com/cloud/storage/dao/SnapshotDaoImpl.java @@ -36,7 +36,6 @@ import com.cloud.storage.Snapshot.Type; import com.cloud.storage.SnapshotVO; import com.cloud.storage.Volume; import com.cloud.storage.VolumeVO; -import com.cloud.storage.dao.VolumeDaoImpl.SumCount; import com.cloud.tags.dao.ResourceTagDao; import com.cloud.utils.db.DB; import com.cloud.utils.db.Filter; @@ -46,7 +45,6 @@ import com.cloud.utils.db.JoinBuilder.JoinType; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria.Func; -import com.cloud.utils.db.SearchCriteria.Op; import com.cloud.utils.db.TransactionLegacy; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.dao.VMInstanceDao; @@ -70,7 +68,6 @@ public class SnapshotDaoImpl extends GenericDaoBase implements private SearchBuilder InstanceIdSearch; private SearchBuilder StatusSearch; private GenericSearchBuilder CountSnapshotsByAccount; - private GenericSearchBuilder secondaryStorageSearch; @Inject ResourceTagDao _tagsDao; @Inject @@ -193,12 +190,6 @@ public class SnapshotDaoImpl extends GenericDaoBase implements InstanceIdSearch.join("instanceSnapshots", volumeSearch, volumeSearch.entity().getId(), InstanceIdSearch .entity().getVolumeId(), JoinType.INNER); InstanceIdSearch.done(); - - secondaryStorageSearch = createSearchBuilder(SumCount.class); - secondaryStorageSearch.select("sum", Func.SUM, secondaryStorageSearch.entity().getSize()); - secondaryStorageSearch.and("accountId", secondaryStorageSearch.entity().getAccountId(), Op.EQ); - secondaryStorageSearch.and("isRemoved", secondaryStorageSearch.entity().getRemoved(), Op.NULL); - secondaryStorageSearch.done(); } @Override @@ -333,15 +324,4 @@ public class SnapshotDaoImpl extends GenericDaoBase implements return true; } - @Override - public long secondaryStorageUsedForAccount(long accountId) { - SearchCriteria sc = secondaryStorageSearch.create(); - sc.setParameters("accountId", accountId); - List storageSpace = customSearch(sc, null); - if (storageSpace != null) { - return storageSpace.get(0).sum; - } else { - return 0; - } - } } diff --git a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java index c0e9ad7a732..fc9099dfe9c 100755 --- a/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java +++ b/server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java @@ -31,8 +31,11 @@ import javax.naming.ConfigurationException; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.context.CallContext; +import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.managed.context.ManagedContextRunnable; +import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.SnapshotDataStoreVO; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.log4j.Logger; @@ -67,6 +70,8 @@ import com.cloud.projects.dao.ProjectAccountDao; import com.cloud.projects.dao.ProjectDao; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; +import com.cloud.storage.DataStoreRole; +import com.cloud.storage.SnapshotVO; import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.VMTemplateVO; @@ -152,8 +157,11 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim private TemplateDataStoreDao _vmTemplateStoreDao; @Inject private VlanDao _vlanDao; + @Inject + private SnapshotDataStoreDao _snapshotDataStoreDao; protected GenericSearchBuilder templateSizeSearch; + protected GenericSearchBuilder snapshotSizeSearch; protected SearchBuilder ResourceCountSearch; ScheduledExecutorService _rcExecutor; @@ -192,6 +200,15 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim templateSizeSearch.join("templates", join1, templateSizeSearch.entity().getTemplateId(), join1.entity().getId(), JoinBuilder.JoinType.INNER); templateSizeSearch.done(); + snapshotSizeSearch = _snapshotDataStoreDao.createSearchBuilder(SumCount.class); + snapshotSizeSearch.select("sum", Func.SUM, snapshotSizeSearch.entity().getSize()); + snapshotSizeSearch.and("state", snapshotSizeSearch.entity().getState(), Op.EQ); + snapshotSizeSearch.and("storeRole", snapshotSizeSearch.entity().getRole(), Op.EQ); + SearchBuilder join2 = _snapshotDao.createSearchBuilder(); + join2.and("accountId", join2.entity().getAccountId(), Op.EQ); + snapshotSizeSearch.join("snapshots", join2, snapshotSizeSearch.entity().getSnapshotId(), join2.entity().getId(), JoinBuilder.JoinType.INNER); + snapshotSizeSearch.done(); + _resourceCountCheckInterval = NumbersUtil.parseInt(_configDao.getValue(Config.ResourceCountCheckInterval.key()), 0); if (_resourceCountCheckInterval > 0) { _rcExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("ResourceCountChecker")); @@ -912,7 +929,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim public long calculateSecondaryStorageForAccount(long accountId) { long totalVolumesSize = _volumeDao.secondaryStorageUsedForAccount(accountId); - long totalSnapshotsSize = _snapshotDao.secondaryStorageUsedForAccount(accountId); + long totalSnapshotsSize = 0; long totalTemplatesSize = 0; SearchCriteria sc = templateSizeSearch.create(); @@ -924,6 +941,14 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim totalTemplatesSize = templates.get(0).sum; } + SearchCriteria sc2 = snapshotSizeSearch.create(); + sc2.setParameters("state", ObjectInDataStoreStateMachine.State.Ready); + sc2.setParameters("storeRole", DataStoreRole.Image); + sc2.setJoinParameters("snapshots", "accountId", accountId); + List snapshots = _snapshotDataStoreDao.customSearch(sc2, null); + if (snapshots != null) { + totalSnapshotsSize = snapshots.get(0).sum; + } return totalVolumesSize + totalSnapshotsSize + totalTemplatesSize; } diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java index 7187e1ea14a..1e4e1712f6f 100644 --- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java @@ -759,7 +759,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic if (!created) { s_logger.trace("Decrementing volume resource count for account id=" + volume.getAccountId() + " as volume failed to create on the backend"); _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume); - _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, new Long(volume.getSize())); + _resourceLimitMgr.recalculateResourceCount(volume.getAccountId(), volume.getDomainId(), ResourceType.primary_storage.getOrdinal()); } } } @@ -1042,7 +1042,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic /* If volume is in primary storage, decrement primary storage count else decrement secondary storage count (in case of upload volume). */ if (volume.getFolder() != null || volume.getPath() != null || volume.getState() == Volume.State.Allocated) { - _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.primary_storage, new Long(volume.getSize())); + _resourceLimitMgr.recalculateResourceCount(volume.getAccountId(), volume.getDomainId(), ResourceType.primary_storage.getOrdinal()); } else { _resourceLimitMgr.recalculateResourceCount(volume.getAccountId(), volume.getDomainId(), ResourceType.secondary_storage.getOrdinal()); } diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 0a51d2cdd84..23df880c1f2 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -1705,8 +1705,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir // Update Resource count if (vm.getAccountId() != Account.ACCOUNT_ID_SYSTEM && !rootVol.isEmpty()) { _resourceLimitMgr.decrementResourceCount(vm.getAccountId(), ResourceType.volume); - _resourceLimitMgr.decrementResourceCount(vm.getAccountId(), ResourceType.primary_storage, - new Long(rootVol.get(0).getSize())); + _resourceLimitMgr.recalculateResourceCount(vm.getAccountId(), vm.getDomainId(), ResourceType.primary_storage.getOrdinal()); } // Only if vm is not expunged already, cleanup it's resources