@@ -1728,6 +1728,11 @@ public HypervisorType getHypervisorTypeFromFormat(ImageFormat format) {
17281728 }
17291729
17301730 private boolean checkUsagedSpace (StoragePool pool ) {
1731+ // Managed storage does not currently deal with accounting for physically used space (only provisioned space). Just return true if "pool" is managed.
1732+ if (pool .isManaged ()) {
1733+ return true ;
1734+ }
1735+
17311736 StatsCollector sc = StatsCollector .getInstance ();
17321737 double storageUsedThreshold = CapacityManager .StorageCapacityDisableThreshold .valueIn (pool .getDataCenterId ());
17331738 if (sc != null ) {
@@ -1803,9 +1808,10 @@ public boolean storagePoolHasEnoughSpace(List<Volume> volumes, StoragePool pool,
18031808 }
18041809
18051810 // allocated space includes templates
1806- if (s_logger .isDebugEnabled ()) {
1811+ if (s_logger .isDebugEnabled ()) {
18071812 s_logger .debug ("Destination pool id: " + pool .getId ());
18081813 }
1814+
18091815 StoragePoolVO poolVO = _storagePoolDao .findById (pool .getId ());
18101816 long allocatedSizeWithTemplate = _capacityMgr .getAllocatedPoolCapacity (poolVO , null );
18111817 long totalAskingSize = 0 ;
@@ -1833,67 +1839,88 @@ public boolean storagePoolHasEnoughSpace(List<Volume> volumes, StoragePool pool,
18331839 allocatedSizeWithTemplate = _capacityMgr .getAllocatedPoolCapacity (poolVO , tmpl );
18341840 }
18351841 }
1836- // A ready state volume is already allocated in a pool. so the asking size is zero for it.
1837- // In case the volume is moving across pools or is not ready yet, the asking size has to be computed
1842+
18381843 if (s_logger .isDebugEnabled ()) {
1839- s_logger .debug ("pool id for the volume with id: " + volumeVO .getId () + " is " + volumeVO .getPoolId ());
1844+ s_logger .debug ("Pool ID for the volume with ID " + volumeVO .getId () + " is " + volumeVO .getPoolId ());
18401845 }
1846+
1847+ // A ready-state volume is already allocated in a pool, so the asking size is zero for it.
1848+ // In case the volume is moving across pools or is not ready yet, the asking size has to be computed.
18411849 if ((volumeVO .getState () != Volume .State .Ready ) || (volumeVO .getPoolId () != pool .getId ())) {
1842- if (ScopeType .ZONE .equals (poolVO .getScope ()) && volumeVO .getTemplateId () != null ) {
1850+ totalAskingSize += getDataObjectSizeIncludingHypervisorSnapshotReserve (volumeVO , poolVO );
1851+
1852+ if (poolVO .isManaged () && volumeVO .getTemplateId () != null ) {
18431853 VMTemplateVO tmpl = _templateDao .findByIdIncludingRemoved (volumeVO .getTemplateId ());
18441854
18451855 if (tmpl != null && !ImageFormat .ISO .equals (tmpl .getFormat ())) {
1846- // Storage plug-ins for zone-wide primary storage can be designed in such a way as to store a template on the
1847- // primary storage once and make use of it in different clusters ( via cloning) .
1856+ // Storage plug-ins for managed storage can be designed in such a way as to store a template on the
1857+ // primary storage once and make use of it via storage-side cloning.
18481858 // This next call leads to CloudStack asking how many more bytes it will need for the template (if the template is
18491859 // already stored on the primary storage, then the answer is 0).
18501860
1851- if (clusterId != null && _clusterDao .getSupportsResigning (clusterId )) {
1852- totalAskingSize += getBytesRequiredForTemplate (tmpl , pool );
1861+ if (clusterId != null ) {
1862+ HypervisorType hypervisorType = tmpl .getHypervisorType ();
1863+
1864+ // The getSupportsResigning method is applicable for XenServer as a UUID-resigning patch may or may not be installed
1865+ // on those hypervisor hosts.
1866+ if (_clusterDao .getSupportsResigning (clusterId ) ||
1867+ HypervisorType .VMware .equals (hypervisorType ) || HypervisorType .KVM .equals (hypervisorType )) {
1868+ totalAskingSize += getBytesRequiredForTemplate (tmpl , pool );
1869+ }
18531870 }
18541871 }
18551872 }
18561873 }
18571874 }
18581875
18591876 long totalOverProvCapacity ;
1877+
18601878 if (pool .getPoolType ().supportsOverProvisioning ()) {
18611879 BigDecimal overProvFactor = getStorageOverProvisioningFactor (pool .getId ());
1880+
18621881 totalOverProvCapacity = overProvFactor .multiply (new BigDecimal (pool .getCapacityBytes ())).longValue ();
1863- s_logger .debug ("Found storage pool " + poolVO .getName () + " of type " + pool .getPoolType ().toString () + " with overprovisioning factor "
1864- + overProvFactor .toString ());
1865- s_logger .debug ("Total over provisioned capacity calculated is " + overProvFactor + " * " + pool .getCapacityBytes ());
1882+
1883+ s_logger .debug ("Found storage pool " + poolVO .getName () + " of type " + pool .getPoolType ().toString () + " with over-provisioning factor " +
1884+ overProvFactor .toString ());
1885+ s_logger .debug ("Total over-provisioned capacity calculated is " + overProvFactor + " * " + pool .getCapacityBytes ());
18661886 } else {
18671887 totalOverProvCapacity = pool .getCapacityBytes ();
1888+
18681889 s_logger .debug ("Found storage pool " + poolVO .getName () + " of type " + pool .getPoolType ().toString ());
18691890 }
18701891
1871- s_logger .debug ("Total capacity of the pool " + poolVO .getName () + " id: " + pool .getId () + " is " + totalOverProvCapacity );
1892+ s_logger .debug ("Total capacity of the pool " + poolVO .getName () + " with ID " + pool .getId () + " is " + totalOverProvCapacity );
1893+
18721894 double storageAllocatedThreshold = CapacityManager .StorageAllocatedCapacityDisableThreshold .valueIn (pool .getDataCenterId ());
1895+
18731896 if (s_logger .isDebugEnabled ()) {
1874- s_logger .debug ("Checking pool: " + pool .getId () + " for volume allocation " + volumes .toString () + ", maxSize : " + totalOverProvCapacity +
1875- ", totalAllocatedSize : " + allocatedSizeWithTemplate + ", askingSize : " + totalAskingSize + ", allocated disable threshold: " +
1876- storageAllocatedThreshold );
1897+ s_logger .debug ("Checking pool with ID " + pool .getId () + " for volume allocation " + volumes .toString () + ", maxSize: " +
1898+ totalOverProvCapacity + ", totalAllocatedSize: " + allocatedSizeWithTemplate + ", askingSize: " + totalAskingSize +
1899+ ", allocated disable threshold: " + storageAllocatedThreshold );
18771900 }
18781901
18791902 double usedPercentage = (allocatedSizeWithTemplate + totalAskingSize ) / (double )(totalOverProvCapacity );
1903+
18801904 if (usedPercentage > storageAllocatedThreshold ) {
18811905 if (s_logger .isDebugEnabled ()) {
1882- s_logger .debug ("Insufficient un-allocated capacity on: " + pool .getId () + " for volume allocation: " + volumes .toString () +
1883- " since its allocated percentage: " + usedPercentage + " has crossed the allocated pool.storage.allocated.capacity.disablethreshold: " +
1906+ s_logger .debug ("Insufficient un-allocated capacity on the pool with ID " + pool .getId () + " for volume allocation: " + volumes .toString () +
1907+ " since its allocated percentage " + usedPercentage + " has crossed the allocated pool.storage.allocated.capacity.disablethreshold " +
18841908 storageAllocatedThreshold + ", skipping this pool" );
18851909 }
1910+
18861911 return false ;
18871912 }
18881913
18891914 if (totalOverProvCapacity < (allocatedSizeWithTemplate + totalAskingSize )) {
18901915 if (s_logger .isDebugEnabled ()) {
1891- s_logger .debug ("Insufficient un-allocated capacity on: " + pool .getId () + " for volume allocation: " + volumes .toString () +
1892- ", not enough storage, maxSize : " + totalOverProvCapacity + ", totalAllocatedSize : " + allocatedSizeWithTemplate + ", askingSize : " +
1916+ s_logger .debug ("Insufficient un-allocated capacity on the pool with ID " + pool .getId () + " for volume allocation: " + volumes .toString () +
1917+ "; not enough storage, maxSize: " + totalOverProvCapacity + ", totalAllocatedSize: " + allocatedSizeWithTemplate + ", askingSize: " +
18931918 totalAskingSize );
18941919 }
1920+
18951921 return false ;
18961922 }
1923+
18971924 return true ;
18981925 }
18991926
0 commit comments