@@ -1803,9 +1803,10 @@ public boolean storagePoolHasEnoughSpace(List<Volume> volumes, StoragePool pool,
18031803 }
18041804
18051805 // allocated space includes templates
1806- if (s_logger .isDebugEnabled ()) {
1806+ if (s_logger .isDebugEnabled ()) {
18071807 s_logger .debug ("Destination pool id: " + pool .getId ());
18081808 }
1809+
18091810 StoragePoolVO poolVO = _storagePoolDao .findById (pool .getId ());
18101811 long allocatedSizeWithTemplate = _capacityMgr .getAllocatedPoolCapacity (poolVO , null );
18111812 long totalAskingSize = 0 ;
@@ -1833,67 +1834,88 @@ public boolean storagePoolHasEnoughSpace(List<Volume> volumes, StoragePool pool,
18331834 allocatedSizeWithTemplate = _capacityMgr .getAllocatedPoolCapacity (poolVO , tmpl );
18341835 }
18351836 }
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
1837+
18381838 if (s_logger .isDebugEnabled ()) {
1839- s_logger .debug ("pool id for the volume with id: " + volumeVO .getId () + " is " + volumeVO .getPoolId ());
1839+ s_logger .debug ("Pool ID for the volume with ID " + volumeVO .getId () + " is " + volumeVO .getPoolId ());
18401840 }
1841+
1842+ // A ready-state volume is already allocated in a pool, so the asking size is zero for it.
1843+ // In case the volume is moving across pools or is not ready yet, the asking size has to be computed.
18411844 if ((volumeVO .getState () != Volume .State .Ready ) || (volumeVO .getPoolId () != pool .getId ())) {
1842- if (ScopeType .ZONE .equals (poolVO .getScope ()) && volumeVO .getTemplateId () != null ) {
1845+ totalAskingSize += getDataObjectSizeIncludingHypervisorSnapshotReserve (volumeVO , poolVO );
1846+
1847+ if (poolVO .isManaged () && volumeVO .getTemplateId () != null ) {
18431848 VMTemplateVO tmpl = _templateDao .findByIdIncludingRemoved (volumeVO .getTemplateId ());
18441849
18451850 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) .
1851+ // Storage plug-ins for managed storage can be designed in such a way as to store a template on the
1852+ // primary storage once and make use of it via storage-side cloning.
18481853 // This next call leads to CloudStack asking how many more bytes it will need for the template (if the template is
18491854 // already stored on the primary storage, then the answer is 0).
18501855
1851- if (clusterId != null && _clusterDao .getSupportsResigning (clusterId )) {
1852- totalAskingSize += getBytesRequiredForTemplate (tmpl , pool );
1856+ if (clusterId != null ) {
1857+ HypervisorType hypervisorType = tmpl .getHypervisorType ();
1858+
1859+ // The getSupportsResigning method is applicable for XenServer as a UUID-resigning patch may or may not be installed
1860+ // on those hypervisor hosts.
1861+ if (_clusterDao .getSupportsResigning (clusterId ) ||
1862+ HypervisorType .VMware .equals (hypervisorType ) || HypervisorType .KVM .equals (hypervisorType )) {
1863+ totalAskingSize += getBytesRequiredForTemplate (tmpl , pool );
1864+ }
18531865 }
18541866 }
18551867 }
18561868 }
18571869 }
18581870
18591871 long totalOverProvCapacity ;
1872+
18601873 if (pool .getPoolType ().supportsOverProvisioning ()) {
18611874 BigDecimal overProvFactor = getStorageOverProvisioningFactor (pool .getId ());
1875+
18621876 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 ());
1877+
1878+ s_logger .debug ("Found storage pool " + poolVO .getName () + " of type " + pool .getPoolType ().toString () + " with over-provisioning factor " +
1879+ overProvFactor .toString ());
1880+ s_logger .debug ("Total over-provisioned capacity calculated is " + overProvFactor + " * " + pool .getCapacityBytes ());
18661881 } else {
18671882 totalOverProvCapacity = pool .getCapacityBytes ();
1883+
18681884 s_logger .debug ("Found storage pool " + poolVO .getName () + " of type " + pool .getPoolType ().toString ());
18691885 }
18701886
1871- s_logger .debug ("Total capacity of the pool " + poolVO .getName () + " id: " + pool .getId () + " is " + totalOverProvCapacity );
1887+ s_logger .debug ("Total capacity of the pool " + poolVO .getName () + " with ID " + pool .getId () + " is " + totalOverProvCapacity );
1888+
18721889 double storageAllocatedThreshold = CapacityManager .StorageAllocatedCapacityDisableThreshold .valueIn (pool .getDataCenterId ());
1890+
18731891 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 );
1892+ s_logger .debug ("Checking pool with ID " + pool .getId () + " for volume allocation " + volumes .toString () + ", maxSize: " +
1893+ totalOverProvCapacity + ", totalAllocatedSize: " + allocatedSizeWithTemplate + ", askingSize: " + totalAskingSize +
1894+ ", allocated disable threshold: " + storageAllocatedThreshold );
18771895 }
18781896
18791897 double usedPercentage = (allocatedSizeWithTemplate + totalAskingSize ) / (double )(totalOverProvCapacity );
1898+
18801899 if (usedPercentage > storageAllocatedThreshold ) {
18811900 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: " +
1901+ s_logger .debug ("Insufficient un-allocated capacity on the pool with ID " + pool .getId () + " for volume allocation: " + volumes .toString () +
1902+ " since its allocated percentage " + usedPercentage + " has crossed the allocated pool.storage.allocated.capacity.disablethreshold " +
18841903 storageAllocatedThreshold + ", skipping this pool" );
18851904 }
1905+
18861906 return false ;
18871907 }
18881908
18891909 if (totalOverProvCapacity < (allocatedSizeWithTemplate + totalAskingSize )) {
18901910 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 : " +
1911+ s_logger .debug ("Insufficient un-allocated capacity on the pool with ID " + pool .getId () + " for volume allocation: " + volumes .toString () +
1912+ "; not enough storage, maxSize: " + totalOverProvCapacity + ", totalAllocatedSize: " + allocatedSizeWithTemplate + ", askingSize: " +
18931913 totalAskingSize );
18941914 }
1915+
18951916 return false ;
18961917 }
1918+
18971919 return true ;
18981920 }
18991921
0 commit comments