mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
bug 11380: taking VM snapshot is moved to do it at the same time when backup it to secondary storage, wait snapshot MOR really appears in vCenter until we continue.
This commit is contained in:
parent
45c595d558
commit
6b33d114e8
@ -9,7 +9,6 @@ import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.rmi.RemoteException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
@ -34,8 +33,6 @@ import com.cloud.agent.api.to.StorageFilerTO;
|
||||
import com.cloud.hypervisor.vmware.mo.CustomFieldConstants;
|
||||
import com.cloud.hypervisor.vmware.mo.DatacenterMO;
|
||||
import com.cloud.hypervisor.vmware.mo.DatastoreMO;
|
||||
import com.cloud.hypervisor.vmware.mo.HostMO;
|
||||
import com.cloud.hypervisor.vmware.mo.HypervisorHostHelper;
|
||||
import com.cloud.hypervisor.vmware.mo.VirtualMachineMO;
|
||||
import com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost;
|
||||
import com.vmware.vim25.VirtualDeviceConfigSpec;
|
||||
@ -177,10 +174,10 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
||||
vmMo = hyperHost.findVmOnPeerHyperHost(cmd.getVmName());
|
||||
if(vmMo == null) {
|
||||
dsMo = new DatastoreMO(hyperHost.getContext(), morDs);
|
||||
//restrict VM name to 32 chars, (else snapshot descriptor file name will be truncated to 32 chars of vm name)
|
||||
// restrict VM name to 32 chars, (else snapshot descriptor file name will be truncated to 32 chars of vm name)
|
||||
workerVMName = UUID.randomUUID().toString().replaceAll("-", "");
|
||||
|
||||
//attach a volume to dummay wrapper VM for taking snapshot and exporting the VM for backup
|
||||
// attach a volume to dummay wrapper VM for taking snapshot and exporting the VM for backup
|
||||
if (!hyperHost.createBlankVm(workerVMName, 1, 512, 0, false, 4, 0, VirtualMachineGuestOsIdentifier._otherGuest.toString(), morDs, false)) {
|
||||
String msg = "Unable to create worker VM to execute BackupSnapshotCommand";
|
||||
s_logger.error(msg);
|
||||
@ -192,7 +189,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
||||
}
|
||||
workerVm = vmMo;
|
||||
|
||||
//attach volume to worker VM
|
||||
// attach volume to worker VM
|
||||
String datastoreVolumePath = String.format("[%s] %s.vmdk", dsMo.getName(), volumePath);
|
||||
vmMo.attachDisk(new String[] { datastoreVolumePath }, morDs);
|
||||
snapshotUUID = UUID.randomUUID().toString();
|
||||
@ -200,6 +197,10 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
||||
throw new Exception("Failed to take snapshot " + cmd.getSnapshotName() + " on vm: " + cmd.getVmName());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!vmMo.createSnapshot(snapshotUuid, "Snapshot taken for " + cmd.getSnapshotName(), false, false)) {
|
||||
throw new Exception("Failed to take snapshot " + cmd.getSnapshotName() + " on vm: " + cmd.getVmName());
|
||||
}
|
||||
}
|
||||
|
||||
snapshotBackupUuid = backupSnapshotToSecondaryStorage(vmMo, accountId,
|
||||
@ -226,7 +227,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
||||
} finally {
|
||||
try {
|
||||
if (workerVm != null) {
|
||||
//detach volume and destroy worker vm
|
||||
// detach volume and destroy worker vm
|
||||
workerVm.moveAllVmDiskFiles(dsMo, "", false);
|
||||
workerVm.detachAllDisks();
|
||||
workerVm.destroy();
|
||||
|
||||
@ -2226,52 +2226,11 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
||||
String details = "ManageSnapshotCommand operation: " + snapshotOp + " Failed for snapshotId: " + snapshotId;
|
||||
String snapshotUUID = null;
|
||||
|
||||
try {
|
||||
VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext());
|
||||
VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(cmd.getVmName());
|
||||
if (vmMo == null) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Unable to find the owner VM for ManageSnapshotCommand on host " + hyperHost.getHyperHostName() + ", try within datacenter");
|
||||
}
|
||||
|
||||
vmMo = hyperHost.findVmOnPeerHyperHost(cmd.getVmName());
|
||||
}
|
||||
|
||||
if (vmMo == null) {
|
||||
// when no vm instance attached fake as if snapshot is taken, and handle actual taking snapshot as part of BackupSnapshotCommand
|
||||
// snapshot operation (create or destroy) is handled inside BackupSnapshotCommand(), we just fake
|
||||
// a success return here
|
||||
snapshotUUID = UUID.randomUUID().toString();
|
||||
success = true;
|
||||
details = null;
|
||||
} else {
|
||||
if (cmdSwitch.equals(ManageSnapshotCommand.CREATE_SNAPSHOT)) {
|
||||
snapshotUUID = UUID.randomUUID().toString();
|
||||
if (!vmMo.createSnapshot(snapshotUUID, "Snapshot taken for " + cmd.getSnapshotName(), false, false)) {
|
||||
throw new Exception("Failed to take snapshot " + cmd.getSnapshotName() + " on vm: " + cmd.getVmName());
|
||||
}
|
||||
|
||||
success = true;
|
||||
details = null;
|
||||
} else if (cmd.getCommandSwitch().equals(ManageSnapshotCommand.DESTROY_SNAPSHOT)) {
|
||||
snapshotUUID = cmd.getSnapshotPath();
|
||||
|
||||
if (!vmMo.removeSnapshot(snapshotUUID, false)) {
|
||||
throw new Exception("Failed to destroy snapshot: " + cmd.getSnapshotName());
|
||||
}
|
||||
|
||||
success = true;
|
||||
details = null;
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
if (e instanceof RemoteException) {
|
||||
s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
|
||||
invalidateServiceContext();
|
||||
}
|
||||
|
||||
details = "ManageSnapshotCommand failed due to " + VmwareHelper.getExceptionMessage(e);
|
||||
s_logger.error(details);
|
||||
return new ManageSnapshotAnswer(cmd, snapshotId, snapshotUUID, false, details);
|
||||
}
|
||||
|
||||
return new ManageSnapshotAnswer(cmd, snapshotId, snapshotUUID, success, details);
|
||||
}
|
||||
|
||||
@ -326,6 +326,22 @@ public class VirtualMachineMO extends BaseMO {
|
||||
String result = _context.getServiceUtil().waitForTask(morTask);
|
||||
if(result.equals("sucess")) {
|
||||
_context.waitForTaskProgressDone(morTask);
|
||||
|
||||
ManagedObjectReference morSnapshot = null;
|
||||
// We still need to wait until the object appear in vCenter
|
||||
long startTick = System.currentTimeMillis();
|
||||
while(System.currentTimeMillis() - startTick < 10000) {
|
||||
morSnapshot = getSnapshotMor(snapshotName);
|
||||
if(morSnapshot != null) {
|
||||
break;
|
||||
}
|
||||
|
||||
try { Thread.sleep(1000); } catch(InterruptedException e) {}
|
||||
}
|
||||
|
||||
if(morSnapshot == null)
|
||||
s_logger.error("We've been waiting for over 10 seconds for snapshot MOR to be appearing in vCenter after CreateSnapshot task is done, but it is still not there?!");
|
||||
|
||||
return true;
|
||||
} else {
|
||||
s_logger.error("VMware createSnapshot_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user