mirror of https://github.com/apache/cloudstack.git
Fix ExtractVolume bug for S3 as secondary storage.
This commit is contained in:
parent
d6c6634d97
commit
614e08e19f
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
package org.apache.cloudstack.engine.subsystem.api.storage;
|
||||
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.storage.Volume;
|
||||
|
||||
|
|
@ -33,4 +34,10 @@ public interface VolumeInfo extends DataObject, Volume {
|
|||
public Long getLastPoolId();
|
||||
|
||||
public String getAttachedVmName();
|
||||
|
||||
public void processEventOnly(ObjectInDataStoreStateMachine.Event event);
|
||||
|
||||
public void processEventOnly(ObjectInDataStoreStateMachine.Event event, Answer answer);
|
||||
|
||||
public boolean stateTransit(Volume.Event event);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -126,6 +126,7 @@ public class VolumeObject implements VolumeInfo {
|
|||
return volumeVO.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stateTransit(Volume.Event event) {
|
||||
boolean result = false;
|
||||
try {
|
||||
|
|
@ -236,6 +237,22 @@ public class VolumeObject implements VolumeInfo {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processEventOnly(ObjectInDataStoreStateMachine.Event event) {
|
||||
try {
|
||||
objectInStoreMgr.update(this, event);
|
||||
} catch (Exception e) {
|
||||
s_logger.debug("Failed to update state", e);
|
||||
throw new CloudRuntimeException("Failed to update state:" + e.toString());
|
||||
} finally {
|
||||
// in case of OperationFailed, expunge the entry
|
||||
if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) {
|
||||
objectInStoreMgr.delete(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return this.volumeVO.getName();
|
||||
|
|
@ -434,6 +451,56 @@ public class VolumeObject implements VolumeInfo {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processEventOnly(ObjectInDataStoreStateMachine.Event event, Answer answer) {
|
||||
try {
|
||||
if (this.dataStore.getRole() == DataStoreRole.Primary) {
|
||||
if (answer instanceof CopyCmdAnswer) {
|
||||
CopyCmdAnswer cpyAnswer = (CopyCmdAnswer) answer;
|
||||
VolumeVO vol = this.volumeDao.findById(this.getId());
|
||||
VolumeObjectTO newVol = (VolumeObjectTO) cpyAnswer.getNewData();
|
||||
vol.setPath(newVol.getPath());
|
||||
vol.setSize(newVol.getSize());
|
||||
vol.setPoolId(this.getDataStore().getId());
|
||||
volumeDao.update(vol.getId(), vol);
|
||||
} else if (answer instanceof CreateObjectAnswer) {
|
||||
CreateObjectAnswer createAnswer = (CreateObjectAnswer) answer;
|
||||
VolumeObjectTO newVol = (VolumeObjectTO) createAnswer.getData();
|
||||
VolumeVO vol = this.volumeDao.findById(this.getId());
|
||||
vol.setPath(newVol.getPath());
|
||||
vol.setSize(newVol.getSize());
|
||||
vol.setPoolId(this.getDataStore().getId());
|
||||
volumeDao.update(vol.getId(), vol);
|
||||
}
|
||||
} else {
|
||||
// image store or imageCache store
|
||||
if (answer instanceof DownloadAnswer) {
|
||||
DownloadAnswer dwdAnswer = (DownloadAnswer) answer;
|
||||
VolumeDataStoreVO volStore = this.volumeStoreDao.findByStoreVolume(this.dataStore.getId(),
|
||||
this.getId());
|
||||
volStore.setInstallPath(dwdAnswer.getInstallPath());
|
||||
volStore.setChecksum(dwdAnswer.getCheckSum());
|
||||
this.volumeStoreDao.update(volStore.getId(), volStore);
|
||||
} else if (answer instanceof CopyCmdAnswer) {
|
||||
CopyCmdAnswer cpyAnswer = (CopyCmdAnswer) answer;
|
||||
VolumeDataStoreVO volStore = this.volumeStoreDao.findByStoreVolume(this.dataStore.getId(),
|
||||
this.getId());
|
||||
VolumeObjectTO newVol = (VolumeObjectTO) cpyAnswer.getNewData();
|
||||
volStore.setInstallPath(newVol.getPath());
|
||||
volStore.setSize(newVol.getSize());
|
||||
this.volumeStoreDao.update(volStore.getId(), volStore);
|
||||
}
|
||||
}
|
||||
} catch (RuntimeException ex) {
|
||||
if (event == ObjectInDataStoreStateMachine.Event.OperationFailed) {
|
||||
objectInStoreMgr.delete(this);
|
||||
}
|
||||
throw ex;
|
||||
}
|
||||
this.processEventOnly(event);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageFormat getFormat() {
|
||||
return this.volumeVO.getFormat();
|
||||
|
|
|
|||
|
|
@ -623,6 +623,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||
srcVolume.processEvent(Event.OperationFailed);
|
||||
res.setResult(result.getResult());
|
||||
future.complete(res);
|
||||
return null;
|
||||
}
|
||||
|
||||
srcVolume.processEvent(Event.OperationSuccessed);
|
||||
|
|
@ -643,8 +644,8 @@ public class VolumeServiceImpl implements VolumeService {
|
|||
VolumeInfo destVolume = null;
|
||||
try {
|
||||
destVolume = (VolumeInfo)destStore.create(srcVolume);
|
||||
destVolume.processEvent(Event.CreateOnlyRequested);
|
||||
srcVolume.processEvent(Event.CopyingRequested); // this is just used for locking that src volume record in DB to avoid using lock
|
||||
srcVolume.processEvent(Event.MigrationRequested); // this is just used for locking that src volume record in DB to avoid using lock
|
||||
destVolume.processEventOnly(Event.CreateOnlyRequested);
|
||||
|
||||
CopyVolumeContext<VolumeApiResult> context = new CopyVolumeContext<VolumeApiResult>(null, future, srcVolume,
|
||||
destVolume,
|
||||
|
|
@ -658,7 +659,7 @@ public class VolumeServiceImpl implements VolumeService {
|
|||
} catch (Exception e) {
|
||||
s_logger.error("failed to copy volume to image store", e);
|
||||
if (destVolume != null) {
|
||||
destVolume.processEvent(Event.OperationFailed);
|
||||
destVolume.getDataStore().delete(destVolume);
|
||||
}
|
||||
srcVolume.processEvent(Event.OperationFailed); // unlock source volume record
|
||||
res.setResult(e.toString());
|
||||
|
|
@ -675,13 +676,13 @@ public class VolumeServiceImpl implements VolumeService {
|
|||
VolumeApiResult res = new VolumeApiResult(destVolume);
|
||||
try {
|
||||
if (res.isFailed()) {
|
||||
destVolume.processEvent(Event.OperationFailed);
|
||||
srcVolume.processEvent(Event.OperationFailed);
|
||||
srcVolume.processEvent(Event.OperationFailed); // back to Ready state in Volume table
|
||||
destVolume.processEventOnly(Event.OperationFailed);
|
||||
res.setResult(result.getResult());
|
||||
future.complete(res);
|
||||
}else{
|
||||
srcVolume.processEvent(Event.OperationSuccessed);
|
||||
destVolume.processEvent(Event.OperationSuccessed, result.getAnswer());
|
||||
srcVolume.processEvent(Event.OperationSuccessed); // back to Ready state in Volume table
|
||||
destVolume.processEventOnly(Event.OperationSuccessed, result.getAnswer());
|
||||
future.complete(res);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue