CLOUDSTACK-5813: With S3 as secondary storage, snapshot taken in one

zone cannot be used to create volume in another zone. zoneId parameter
in createVolumeCmd is not observed.
This commit is contained in:
Min Chen 2014-01-08 17:15:04 -08:00
parent fefe82618c
commit 858b9b1177
2 changed files with 22 additions and 14 deletions

View File

@ -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;

View File

@ -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);
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(),