@@ -1748,17 +1748,17 @@ public Snapshot allocSnapshot(Long volumeId, Long policyId, String snapshotName,
17481748
17491749 try (CheckedReservation volumeSnapshotReservation = new CheckedReservation (owner , ResourceType .snapshot , null , null , 1L , reservationDao , _resourceLimitMgr );
17501750 CheckedReservation storageReservation = new CheckedReservation (owner , storeResourceType , null , null , volume .getSize (), reservationDao , _resourceLimitMgr )) {
1751- SnapshotVO snapshotVO = new SnapshotVO (volume .getDataCenterId (), volume .getAccountId (), volume .getDomainId (), volume .getId (), volume .getDiskOfferingId (), snapshotName ,
1752- (short )snapshotType .ordinal (), snapshotType .name (), volume .getSize (), volume .getMinIops (), volume .getMaxIops (), hypervisorType , locationType );
1751+ SnapshotVO snapshotVO = new SnapshotVO (volume .getDataCenterId (), volume .getAccountId (), volume .getDomainId (), volume .getId (), volume .getDiskOfferingId (), snapshotName ,
1752+ (short )snapshotType .ordinal (), snapshotType .name (), volume .getSize (), volume .getMinIops (), volume .getMaxIops (), hypervisorType , locationType );
17531753
1754- SnapshotVO snapshot = _snapshotDao .persist (snapshotVO );
1755- if (snapshot == null ) {
1756- throw new CloudRuntimeException (String .format ("Failed to create snapshot for volume: %s" , volume ));
1757- }
1758- CallContext .current ().putContextParameter (Snapshot .class , snapshot .getUuid ());
1759- _resourceLimitMgr .incrementResourceCount (volume .getAccountId (), ResourceType .snapshot );
1760- _resourceLimitMgr .incrementResourceCount (volume .getAccountId (), storeResourceType , volume .getSize ());
1761- return snapshot ;
1754+ SnapshotVO snapshot = _snapshotDao .persist (snapshotVO );
1755+ if (snapshot == null ) {
1756+ throw new CloudRuntimeException (String .format ("Failed to create snapshot for volume: %s" , volume ));
1757+ }
1758+ CallContext .current ().putContextParameter (Snapshot .class , snapshot .getUuid ());
1759+ _resourceLimitMgr .incrementResourceCount (volume .getAccountId (), ResourceType .snapshot );
1760+ _resourceLimitMgr .incrementResourceCount (volume .getAccountId (), storeResourceType , volume .getSize ());
1761+ return snapshot ;
17621762 } catch (ResourceAllocationException e ) {
17631763 if (snapshotType != Type .MANUAL ) {
17641764 String msg = String .format ("Snapshot resource limit exceeded for account id : %s. Failed to create recurring snapshots" , owner .getId ());
@@ -1807,50 +1807,54 @@ private boolean checkAndProcessSnapshotAlreadyExistInStore(long snapshotId, Data
18071807
18081808 @ DB
18091809 private boolean copySnapshotToZone (SnapshotDataStoreVO snapshotDataStoreVO , DataStore srcSecStore ,
1810- DataCenterVO dstZone , DataStore dstSecStore , Account account )
1810+ DataCenterVO dstZone , DataStore dstSecStore , Account account , boolean shouldCheckResourceLimits )
18111811 throws ResourceAllocationException {
18121812 final long snapshotId = snapshotDataStoreVO .getSnapshotId ();
18131813 final long dstZoneId = dstZone .getId ();
18141814 if (checkAndProcessSnapshotAlreadyExistInStore (snapshotId , dstSecStore )) {
18151815 return true ;
18161816 }
1817- _resourceLimitMgr .checkResourceLimit (account , ResourceType .secondary_storage , snapshotDataStoreVO .getSize ());
1818- // snapshotId may refer to ID of a removed parent snapshot
1819- SnapshotInfo snapshotOnSecondary = snapshotFactory .getSnapshot (snapshotId , srcSecStore );
1820- String copyUrl = null ;
1821- try {
1822- AsyncCallFuture <CreateCmdResult > future = snapshotSrv .queryCopySnapshot (snapshotOnSecondary );
1823- CreateCmdResult result = future .get ();
1824- if (!result .isFailed ()) {
1825- copyUrl = result .getPath ();
1817+ // Resource limit checks are not performed here at the moment, but they were added in case this method is used
1818+ // in the future to copy a standalone snapshot
1819+ long requiredSecondaryStorageSpace = shouldCheckResourceLimits ? snapshotDataStoreVO .getSize () : 0L ;
1820+ try (CheckedReservation secondaryStorageReservation = new CheckedReservation (account , ResourceType .secondary_storage , null , null , null , requiredSecondaryStorageSpace , null , reservationDao , _resourceLimitMgr )) {
1821+ SnapshotInfo snapshotOnSecondary = snapshotFactory .getSnapshot (snapshotId , srcSecStore );
1822+ String copyUrl = null ;
1823+ try {
1824+ AsyncCallFuture <CreateCmdResult > future = snapshotSrv .queryCopySnapshot (snapshotOnSecondary );
1825+ CreateCmdResult result = future .get ();
1826+ if (!result .isFailed ()) {
1827+ copyUrl = result .getPath ();
1828+ }
1829+ } catch (InterruptedException | ExecutionException | ResourceUnavailableException ex ) {
1830+ logger .error ("Failed to prepare URL for copy for snapshot ID: {} on store: {}" , snapshotId , srcSecStore , ex );
18261831 }
1827- } catch (InterruptedException | ExecutionException | ResourceUnavailableException ex ) {
1828- logger .error ("Failed to prepare URL for copy for snapshot ID: {} on store: {}" , snapshotId , srcSecStore , ex );
1829- }
1830- if (StringUtils .isEmpty (copyUrl )) {
1831- logger .error ("Unable to prepare URL for copy for snapshot ID: {} on store: {}" , snapshotId , srcSecStore );
1832- return false ;
1833- }
1834- logger .debug (String .format ("Copying snapshot ID: %d to destination zones using download URL: %s" , snapshotId , copyUrl ));
1835- try {
1836- AsyncCallFuture <SnapshotResult > future = snapshotSrv .copySnapshot (snapshotOnSecondary , copyUrl , dstSecStore );
1837- SnapshotResult result = future .get ();
1838- if (result .isFailed ()) {
1839- logger .debug ("Copy snapshot ID: {} failed for image store {}: {}" , snapshotId , dstSecStore , result .getResult ());
1832+ if (StringUtils .isEmpty (copyUrl )) {
1833+ logger .error ("Unable to prepare URL for copy for snapshot ID: {} on store: {}" , snapshotId , srcSecStore );
18401834 return false ;
18411835 }
1842- snapshotZoneDao .addSnapshotToZone (snapshotId , dstZoneId );
1843- _resourceLimitMgr .incrementResourceCount (account .getId (), ResourceType .secondary_storage , snapshotDataStoreVO .getSize ());
1844- if (account .getId () != Account .ACCOUNT_ID_SYSTEM ) {
1845- SnapshotVO snapshotVO = _snapshotDao .findByIdIncludingRemoved (snapshotId );
1846- UsageEventUtils .publishUsageEvent (EventTypes .EVENT_SNAPSHOT_COPY , account .getId (), dstZoneId , snapshotId , null , null , null , snapshotVO .getSize (),
1847- snapshotVO .getSize (), snapshotVO .getClass ().getName (), snapshotVO .getUuid ());
1836+ logger .debug (String .format ("Copying snapshot ID: %d to destination zones using download URL: %s" , snapshotId , copyUrl ));
1837+ try {
1838+ AsyncCallFuture <SnapshotResult > future = snapshotSrv .copySnapshot (snapshotOnSecondary , copyUrl , dstSecStore );
1839+ SnapshotResult result = future .get ();
1840+ if (result .isFailed ()) {
1841+ logger .debug ("Copy snapshot ID: {} failed for image store {}: {}" , snapshotId , dstSecStore , result .getResult ());
1842+ return false ;
1843+ }
1844+ snapshotZoneDao .addSnapshotToZone (snapshotId , dstZoneId );
1845+ _resourceLimitMgr .incrementResourceCount (account .getId (), ResourceType .secondary_storage , snapshotDataStoreVO .getSize ());
1846+ if (account .getId () != Account .ACCOUNT_ID_SYSTEM ) {
1847+ SnapshotVO snapshotVO = _snapshotDao .findByIdIncludingRemoved (snapshotId );
1848+ UsageEventUtils .publishUsageEvent (EventTypes .EVENT_SNAPSHOT_COPY , account .getId (), dstZoneId , snapshotId , null , null , null , snapshotVO .getSize (),
1849+ snapshotVO .getSize (), snapshotVO .getClass ().getName (), snapshotVO .getUuid ());
1850+ }
1851+
1852+ return true ;
1853+ } catch (InterruptedException | ExecutionException | ResourceUnavailableException ex ) {
1854+ logger .debug ("Failed to copy snapshot ID: {} to image store: {}" , snapshotId , dstSecStore );
18481855 }
1849- return true ;
1850- } catch (InterruptedException | ExecutionException | ResourceUnavailableException ex ) {
1851- logger .debug ("Failed to copy snapshot ID: {} to image store: {}" , snapshotId , dstSecStore );
1856+ return false ;
18521857 }
1853- return false ;
18541858 }
18551859
18561860 @ DB
@@ -1881,13 +1885,6 @@ private boolean copySnapshotChainToZone(SnapshotVO snapshotVO, DataStore srcSecS
18811885 if (CollectionUtils .isEmpty (snapshotChain )) {
18821886 return true ;
18831887 }
1884- try {
1885- _resourceLimitMgr .checkResourceLimit (account , ResourceType .secondary_storage , size );
1886- } catch (ResourceAllocationException e ) {
1887- logger .error (String .format ("Unable to allocate secondary storage resources for snapshot chain for %s with size: %d" , snapshotVO , size ), e );
1888- return false ;
1889- }
1890- Collections .reverse (snapshotChain );
18911888 if (dstSecStore == null ) {
18921889 // find all eligible image stores for the destination zone
18931890 List <DataStore > dstSecStores = dataStoreMgr .getImageStoresByScopeExcludingReadOnly (new ZoneScope (destZoneId ));
@@ -1899,15 +1896,21 @@ private boolean copySnapshotChainToZone(SnapshotVO snapshotVO, DataStore srcSecS
18991896 throw new StorageUnavailableException ("Destination zone is not ready, no image store with free capacity" , DataCenter .class , destZoneId );
19001897 }
19011898 }
1902- logger .debug ("Copying snapshot chain for snapshot ID: {} on secondary store: {} of zone ID: {}" , snapshotVO , dstSecStore , destZone );
1903- for (SnapshotDataStoreVO snapshotDataStoreVO : snapshotChain ) {
1904- if (!copySnapshotToZone (snapshotDataStoreVO , srcSecStore , destZone , dstSecStore , account )) {
1905- logger .error ("Failed to copy snapshot: {} to zone: {} due to failure to copy snapshot ID: {} from snapshot chain" ,
1906- snapshotVO , destZone , snapshotDataStoreVO .getSnapshotId ());
1907- return false ;
1899+ try (CheckedReservation secondaryStorageReservation = new CheckedReservation (account , ResourceType .secondary_storage , null , null , null , size , null , reservationDao , _resourceLimitMgr )) {
1900+ logger .debug ("Copying snapshot chain for snapshot ID: {} on secondary store: {} of zone ID: {}" , snapshotVO , dstSecStore , destZone );
1901+ Collections .reverse (snapshotChain );
1902+ for (SnapshotDataStoreVO snapshotDataStoreVO : snapshotChain ) {
1903+ if (!copySnapshotToZone (snapshotDataStoreVO , srcSecStore , destZone , dstSecStore , account , false )) {
1904+ logger .error ("Failed to copy snapshot: {} to zone: {} due to failure to copy snapshot ID: {} from snapshot chain" ,
1905+ snapshotVO , destZone , snapshotDataStoreVO .getSnapshotId ());
1906+ return false ;
1907+ }
19081908 }
1909+ return true ;
1910+ } catch (ResourceAllocationException e ) {
1911+ logger .error (String .format ("Unable to allocate secondary storage resources for snapshot chain for %s with size: %d" , snapshotVO , size ), e );
1912+ return false ;
19091913 }
1910- return true ;
19111914 }
19121915
19131916 @ DB
0 commit comments