diff --git a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java index 99f57142242..fa1dce45719 100644 --- a/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java +++ b/engine/storage/datamotion/src/org/apache/cloudstack/storage/motion/AncientDataMotionStrategy.java @@ -23,6 +23,9 @@ import java.util.Map; import javax.inject.Inject; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + import org.apache.cloudstack.engine.subsystem.api.storage.ClusterScope; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; import org.apache.cloudstack.engine.subsystem.api.storage.DataMotionStrategy; @@ -45,8 +48,6 @@ import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.storage.command.CopyCommand; import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity; -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; import com.cloud.agent.api.Answer; import com.cloud.agent.api.storage.MigrateVolumeAnswer; @@ -192,9 +193,9 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { } } - protected DataObject cacheSnapshotChain(SnapshotInfo snapshot) { + protected DataObject cacheSnapshotChain(SnapshotInfo snapshot, Scope scope) { DataObject leafData = null; - DataStore store = cacheMgr.getCacheStorage(snapshot.getDataStore().getScope()); + DataStore store = cacheMgr.getCacheStorage(scope); while (snapshot != null) { DataObject cacheData = cacheMgr.createCacheObject(snapshot, store); if (leafData == null) { @@ -205,6 +206,7 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { return leafData; } + protected void deleteSnapshotCacheChain(SnapshotInfo snapshot) { while (snapshot != null) { cacheMgr.deleteCacheObject(snapshot); @@ -229,7 +231,8 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { DataObject srcData = snapObj; try { if (!(storTO instanceof NfsTO)) { - srcData = cacheSnapshotChain(snapshot); + // cache snapshot to zone-wide staging store for the volume to be created + srcData = cacheSnapshotChain(snapshot, new ZoneScope(pool.getDataCenterId())); } String value = configDao.getValue(Config.CreateVolumeFromSnapshotWait.toString()); @@ -438,8 +441,8 @@ public class AncientDataMotionStrategy implements DataMotionStrategy { boolean needCache = false; if (needCacheStorage(srcData, destData)) { needCache = true; - SnapshotInfo snapshot = (SnapshotInfo)srcData; - srcData = cacheSnapshotChain(snapshot); + SnapshotInfo snapshot = (SnapshotInfo) srcData; + srcData = cacheSnapshotChain(snapshot, snapshot.getDataStore().getScope()); } EndPoint ep = null; diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java index 4de635c8ba5..e1d1c7c4750 100644 --- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java @@ -26,6 +26,8 @@ import java.util.concurrent.ExecutionException; import javax.inject.Inject; +import org.apache.log4j.Logger; + import org.apache.cloudstack.api.BaseCmd; import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd; import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd; @@ -44,6 +46,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.HostScope; import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo; import org.apache.cloudstack.engine.subsystem.api.storage.Scope; import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory; +import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotService; import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory; import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory; @@ -72,7 +75,6 @@ import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao; import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO; import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity; -import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; @@ -120,7 +122,6 @@ import com.cloud.storage.dao.SnapshotDao; import com.cloud.storage.dao.SnapshotPolicyDao; import com.cloud.storage.dao.StoragePoolHostDao; import com.cloud.storage.dao.StoragePoolWorkDao; -import com.cloud.storage.dao.UploadDao; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VMTemplatePoolDao; import com.cloud.storage.dao.VolumeDao; @@ -130,7 +131,6 @@ import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.storage.snapshot.SnapshotApiService; import com.cloud.storage.snapshot.SnapshotManager; import com.cloud.storage.snapshot.SnapshotScheduler; -import com.cloud.storage.upload.UploadMonitor; import com.cloud.tags.dao.ResourceTagDao; import com.cloud.template.TemplateManager; import com.cloud.user.Account; @@ -317,9 +317,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic @Inject SnapshotApiService snapshotMgr; @Inject - UploadMonitor _uploadMonitor; - @Inject - UploadDao _uploadDao; + SnapshotService snapshotSrv; @Inject UUIDManager _uuidMgr; @@ -604,7 +602,10 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic diskOfferingId = snapshotCheck.getDiskOfferingId(); diskOffering = _diskOfferingDao.findById(diskOfferingId); - zoneId = snapshotCheck.getDataCenterId(); + if (zoneId == null) { + // if zoneId is not provided, we default to create volume in the same zone as the snapshot zone. + zoneId = snapshotCheck.getDataCenterId(); + } size = snapshotCheck.getSize(); // ; disk offering is used for tags // purposes @@ -767,11 +768,15 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic protected VolumeVO createVolumeFromSnapshot(VolumeVO volume, long snapshotId, Long vmId) throws StorageUnavailableException { VolumeInfo createdVolume = null; SnapshotVO snapshot = _snapshotDao.findById(snapshotId); + long snapshotVolId = snapshot.getVolumeId(); UserVmVO vm = null; if (vmId != null) { vm = _userVmDao.findById(vmId); } + + // sync old snapshots to region store if necessary + createdVolume = _volumeMgr.createVolumeFromSnapshot(volume, snapshot, vm); UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, createdVolume.getAccountId(), createdVolume.getDataCenterId(), createdVolume.getId(),