mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
bug 12787: improve worker VM cleanup in snapshot operation
This commit is contained in:
parent
9b706697fb
commit
bde008ed7e
@ -13,5 +13,5 @@ public interface VmwareHostService {
|
||||
void invalidateServiceContext(VmwareContext context);
|
||||
VmwareHypervisorHost getHyperHost(VmwareContext context, Command cmd);
|
||||
|
||||
String getWorkerName(VmwareContext context, Command cmd);
|
||||
String getWorkerName(VmwareContext context, Command cmd, int workerSequence);
|
||||
}
|
||||
|
||||
@ -174,7 +174,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
||||
if(vmMo == null) {
|
||||
dsMo = new DatastoreMO(hyperHost.getContext(), morDs);
|
||||
|
||||
workerVMName = hostService.getWorkerName(context, cmd);
|
||||
workerVMName = hostService.getWorkerName(context, cmd, 0);
|
||||
|
||||
// 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)) {
|
||||
@ -203,7 +203,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
||||
}
|
||||
|
||||
snapshotBackupUuid = backupSnapshotToSecondaryStorage(vmMo, accountId, volumeId, cmd.getVolumePath(), snapshotUuid, secondaryStorageUrl, prevSnapshotUuid, prevBackupUuid,
|
||||
UUID.randomUUID().toString().replace("-", ""));
|
||||
hostService.getWorkerName(context, cmd, 1));
|
||||
|
||||
success = (snapshotBackupUuid != null);
|
||||
if (success) {
|
||||
@ -238,8 +238,6 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
||||
return new BackupSnapshotAnswer(cmd, success, details, snapshotBackupUuid, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public Answer execute(VmwareHostService hostService, CreatePrivateTemplateFromVolumeCommand cmd) {
|
||||
String secondaryStoragePoolURL = cmd.getSecondaryStorageUrl();
|
||||
@ -268,7 +266,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
||||
Ternary<String, Long, Long> result = createTemplateFromVolume(vmMo,
|
||||
accountId, templateId, cmd.getTemplateName(),
|
||||
secondaryStoragePoolURL, volumePath,
|
||||
hostService.getWorkerName(context, cmd));
|
||||
hostService.getWorkerName(context, cmd, 0));
|
||||
|
||||
return new CreatePrivateTemplateAnswer(cmd, true, null,
|
||||
result.first(), result.third(), result.second(),
|
||||
@ -331,10 +329,10 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
||||
|
||||
Pair<String, String> result;
|
||||
if (cmd.toSecondaryStorage()) {
|
||||
result = copyVolumeToSecStorage(
|
||||
hyperHost, vmName, volumeId, cmd.getPool().getUuid(), volumePath,
|
||||
result = copyVolumeToSecStorage(hostService,
|
||||
hyperHost, cmd, vmName, volumeId, cmd.getPool().getUuid(), volumePath,
|
||||
secondaryStorageURL,
|
||||
hostService.getWorkerName(context, cmd));
|
||||
hostService.getWorkerName(context, cmd, 0));
|
||||
} else {
|
||||
StorageFilerTO poolTO = cmd.getPool();
|
||||
|
||||
@ -393,8 +391,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
||||
|
||||
DatastoreMO primaryDsMo = new DatastoreMO(hyperHost.getContext(), morPrimaryDs);
|
||||
details = createVolumeFromSnapshot(hyperHost, primaryDsMo,
|
||||
newVolumeName, accountId, volumeId,
|
||||
secondaryStorageUrl, backedUpSnapshotUuid);
|
||||
newVolumeName, accountId, volumeId, secondaryStorageUrl, backedUpSnapshotUuid);
|
||||
if (details == null) {
|
||||
success = true;
|
||||
}
|
||||
@ -738,8 +735,10 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
||||
return "Failed to delete snapshot backup file, backupUuid: " + backupUuid;
|
||||
}
|
||||
|
||||
private Pair<String, String> copyVolumeToSecStorage(VmwareHypervisorHost hyperHost, String vmName, long volumeId, String poolId, String volumePath,
|
||||
private Pair<String, String> copyVolumeToSecStorage(VmwareHostService hostService, VmwareHypervisorHost hyperHost, CopyVolumeCommand cmd,
|
||||
String vmName, long volumeId, String poolId, String volumePath,
|
||||
String secStorageUrl, String workerVmName) throws Exception {
|
||||
|
||||
String volumeFolder = String.valueOf(volumeId) + "/";
|
||||
VirtualMachineMO workerVm=null;
|
||||
VirtualMachineMO vmMo=null;
|
||||
@ -756,12 +755,11 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
||||
|
||||
vmMo = hyperHost.findVmOnHyperHost(vmName);
|
||||
if (vmMo == null) {
|
||||
//create a dummy worker vm for attaching the volume
|
||||
// create a dummy worker vm for attaching the volume
|
||||
DatastoreMO 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)
|
||||
String workerVMName = UUID.randomUUID().toString().replaceAll("-", "");
|
||||
VirtualMachineConfigSpec vmConfig = new VirtualMachineConfigSpec();
|
||||
vmConfig.setName(workerVMName);
|
||||
vmConfig.setName(workerVmName);
|
||||
vmConfig.setMemoryMB((long) 4);
|
||||
vmConfig.setNumCPUs(1);
|
||||
vmConfig.setGuestId(VirtualMachineGuestOsIdentifier._otherGuest.toString());
|
||||
@ -780,7 +778,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
||||
vmConfig.setDeviceChange(new VirtualDeviceConfigSpec[] { scsiControllerSpec });
|
||||
|
||||
hyperHost.createVm(vmConfig);
|
||||
workerVm = hyperHost.findVmOnHyperHost(workerVMName);
|
||||
workerVm = hyperHost.findVmOnHyperHost(workerVmName);
|
||||
if (workerVm == null) {
|
||||
String msg = "Unable to create worker VM to execute CopyVolumeCommand";
|
||||
s_logger.error(msg);
|
||||
@ -795,7 +793,8 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
|
||||
|
||||
vmMo.createSnapshot(exportName, "Temporary snapshot for copy-volume command", false, false);
|
||||
|
||||
exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, "volumes/" + volumeFolder, exportName, workerVmName);
|
||||
exportVolumeToSecondaryStroage(vmMo, volumePath, secStorageUrl, "volumes/" + volumeFolder, exportName,
|
||||
hostService.getWorkerName(hyperHost.getContext(), cmd, 1));
|
||||
return new Pair<String, String>(volumeFolder, exportName);
|
||||
|
||||
} finally {
|
||||
|
||||
@ -2885,7 +2885,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
||||
if (cmd.getDiskCharacteristics().getType() == Volume.Type.ROOT) {
|
||||
if (cmd.getTemplateUrl() == null) {
|
||||
// create a root volume for blank VM
|
||||
String dummyVmName = getWorkerName(context, cmd);
|
||||
String dummyVmName = getWorkerName(context, cmd, 0);
|
||||
VirtualMachineMO vmMo = null;
|
||||
|
||||
try {
|
||||
@ -2969,7 +2969,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
||||
VirtualMachineMO vmMo = null;
|
||||
String volumeUuid = UUID.randomUUID().toString().replace("-", "");
|
||||
String volumeDatastorePath = String.format("[%s] %s.vmdk", dsMo.getName(), volumeUuid);
|
||||
String dummyVmName = getWorkerName(context, cmd);
|
||||
String dummyVmName = getWorkerName(context, cmd, 0);
|
||||
try {
|
||||
vmMo = prepareVolumeHostDummyVm(hyperHost, dsMo, dummyVmName);
|
||||
if (vmMo == null) {
|
||||
@ -3968,7 +3968,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
||||
|
||||
@Override
|
||||
@DB
|
||||
public String getWorkerName(VmwareContext context, Command cmd) {
|
||||
public String getWorkerName(VmwareContext context, Command cmd, int workerSequence) {
|
||||
VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
|
||||
String vmName = mgr.composeWorkerName();
|
||||
|
||||
|
||||
@ -66,13 +66,19 @@ public class VmwareSecondaryStorageResourceHandler implements SecondaryStorageRe
|
||||
answer = _resource.defaultAction(cmd);
|
||||
}
|
||||
|
||||
// special handling to pass-back context info for cleanups
|
||||
if(cmd.getContextParam("execid") != null) {
|
||||
answer.setContextParam("execid", cmd.getContextParam("execid"));
|
||||
}
|
||||
|
||||
if(cmd.getContextParam("checkpoint") != null) {
|
||||
answer.setContextParam("checkpoint", cmd.getContextParam("checkpoint"));
|
||||
}
|
||||
|
||||
if(cmd.getContextParam("checkpoint2") != null) {
|
||||
answer.setContextParam("checkpoint2", cmd.getContextParam("checkpoint2"));
|
||||
}
|
||||
|
||||
return answer;
|
||||
}
|
||||
|
||||
@ -219,9 +225,13 @@ public class VmwareSecondaryStorageResourceHandler implements SecondaryStorageRe
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWorkerName(VmwareContext context, Command cmd) {
|
||||
public String getWorkerName(VmwareContext context, Command cmd, int workerSequence) {
|
||||
assert(cmd.getContextParam("worker") != null);
|
||||
return cmd.getContextParam("worker");
|
||||
assert(workerSequence < 2);
|
||||
|
||||
if(workerSequence == 0)
|
||||
return cmd.getContextParam("worker");
|
||||
return cmd.getContextParam("worker2");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -266,6 +266,12 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru {
|
||||
long checkPointId = _checkPointMgr.pushCheckPoint(new VmwareCleanupMaid(hostDetails.get("guid"), workerName));
|
||||
cmd.setContextParam("worker", workerName);
|
||||
cmd.setContextParam("checkpoint", String.valueOf(checkPointId));
|
||||
|
||||
// some commands use 2 workers
|
||||
String workerName2 = _vmwareMgr.composeWorkerName();
|
||||
long checkPointId2 = _checkPointMgr.pushCheckPoint(new VmwareCleanupMaid(hostDetails.get("guid"), workerName2));
|
||||
cmd.setContextParam("worker2", workerName2);
|
||||
cmd.setContextParam("checkpoint2", String.valueOf(checkPointId2));
|
||||
}
|
||||
|
||||
return cmdTarget.first().getId();
|
||||
|
||||
@ -749,6 +749,11 @@ public class VmwareManagerImpl implements VmwareManager, VmwareStorageMount, Lis
|
||||
if(checkPointIdStr != null) {
|
||||
_checkPointMgr.popCheckPoint(Long.parseLong(checkPointIdStr));
|
||||
}
|
||||
|
||||
checkPointIdStr = answer.getContextParam("checkpoint2");
|
||||
if(checkPointIdStr != null) {
|
||||
_checkPointMgr.popCheckPoint(Long.parseLong(checkPointIdStr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1411,19 +1411,32 @@ public class VirtualMachineMO extends BaseMO {
|
||||
HostMO hostMo = getRunningHost();
|
||||
VirtualMachineConfigInfo vmConfigInfo = getConfigInfo();
|
||||
|
||||
hostMo.createBlankVm(clonedVmName, 1, cpuSpeedMHz, 0, false, memoryMb, 0, vmConfigInfo.getGuestId(), morDs, false);
|
||||
if(!hostMo.createBlankVm(clonedVmName, 1, cpuSpeedMHz, 0, false, memoryMb, 0, vmConfigInfo.getGuestId(), morDs, false))
|
||||
throw new Exception("Unable to create a blank VM");
|
||||
|
||||
VirtualMachineMO clonedVmMo = hostMo.findVmOnHyperHost(clonedVmName);
|
||||
if(clonedVmMo == null)
|
||||
throw new Exception("Unable to find just-created blank VM");
|
||||
|
||||
VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
|
||||
VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[1];
|
||||
deviceConfigSpecArray[0] = new VirtualDeviceConfigSpec();
|
||||
boolean bSuccess = false;
|
||||
try {
|
||||
VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
|
||||
VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[1];
|
||||
deviceConfigSpecArray[0] = new VirtualDeviceConfigSpec();
|
||||
|
||||
VirtualDevice device = VmwareHelper.prepareDiskDevice(clonedVmMo, -1, disks, morDs, -1, 1);
|
||||
VirtualDevice device = VmwareHelper.prepareDiskDevice(clonedVmMo, -1, disks, morDs, -1, 1);
|
||||
|
||||
deviceConfigSpecArray[0].setDevice(device);
|
||||
deviceConfigSpecArray[0].setOperation(VirtualDeviceConfigSpecOperation.add);
|
||||
vmConfigSpec.setDeviceChange(deviceConfigSpecArray);
|
||||
clonedVmMo.configureVm(vmConfigSpec);
|
||||
deviceConfigSpecArray[0].setDevice(device);
|
||||
deviceConfigSpecArray[0].setOperation(VirtualDeviceConfigSpecOperation.add);
|
||||
vmConfigSpec.setDeviceChange(deviceConfigSpecArray);
|
||||
clonedVmMo.configureVm(vmConfigSpec);
|
||||
bSuccess = true;
|
||||
} finally {
|
||||
if(!bSuccess) {
|
||||
clonedVmMo.detachAllDisks();
|
||||
clonedVmMo.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void plugDevice(VirtualDevice device) throws Exception {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user