bug 12787: improve worker VM cleanup in snapshot operation

This commit is contained in:
Kelven Yang 2012-01-06 18:56:14 -08:00
parent 9b706697fb
commit bde008ed7e
7 changed files with 68 additions and 35 deletions

View File

@ -13,5 +13,5 @@ public interface VmwareHostService {
void invalidateServiceContext(VmwareContext context); void invalidateServiceContext(VmwareContext context);
VmwareHypervisorHost getHyperHost(VmwareContext context, Command cmd); VmwareHypervisorHost getHyperHost(VmwareContext context, Command cmd);
String getWorkerName(VmwareContext context, Command cmd); String getWorkerName(VmwareContext context, Command cmd, int workerSequence);
} }

View File

@ -174,7 +174,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
if(vmMo == null) { if(vmMo == null) {
dsMo = new DatastoreMO(hyperHost.getContext(), morDs); 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 // 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)) { 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, snapshotBackupUuid = backupSnapshotToSecondaryStorage(vmMo, accountId, volumeId, cmd.getVolumePath(), snapshotUuid, secondaryStorageUrl, prevSnapshotUuid, prevBackupUuid,
UUID.randomUUID().toString().replace("-", "")); hostService.getWorkerName(context, cmd, 1));
success = (snapshotBackupUuid != null); success = (snapshotBackupUuid != null);
if (success) { if (success) {
@ -238,8 +238,6 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
return new BackupSnapshotAnswer(cmd, success, details, snapshotBackupUuid, true); return new BackupSnapshotAnswer(cmd, success, details, snapshotBackupUuid, true);
} }
@Override @Override
public Answer execute(VmwareHostService hostService, CreatePrivateTemplateFromVolumeCommand cmd) { public Answer execute(VmwareHostService hostService, CreatePrivateTemplateFromVolumeCommand cmd) {
String secondaryStoragePoolURL = cmd.getSecondaryStorageUrl(); String secondaryStoragePoolURL = cmd.getSecondaryStorageUrl();
@ -268,7 +266,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
Ternary<String, Long, Long> result = createTemplateFromVolume(vmMo, Ternary<String, Long, Long> result = createTemplateFromVolume(vmMo,
accountId, templateId, cmd.getTemplateName(), accountId, templateId, cmd.getTemplateName(),
secondaryStoragePoolURL, volumePath, secondaryStoragePoolURL, volumePath,
hostService.getWorkerName(context, cmd)); hostService.getWorkerName(context, cmd, 0));
return new CreatePrivateTemplateAnswer(cmd, true, null, return new CreatePrivateTemplateAnswer(cmd, true, null,
result.first(), result.third(), result.second(), result.first(), result.third(), result.second(),
@ -331,10 +329,10 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
Pair<String, String> result; Pair<String, String> result;
if (cmd.toSecondaryStorage()) { if (cmd.toSecondaryStorage()) {
result = copyVolumeToSecStorage( result = copyVolumeToSecStorage(hostService,
hyperHost, vmName, volumeId, cmd.getPool().getUuid(), volumePath, hyperHost, cmd, vmName, volumeId, cmd.getPool().getUuid(), volumePath,
secondaryStorageURL, secondaryStorageURL,
hostService.getWorkerName(context, cmd)); hostService.getWorkerName(context, cmd, 0));
} else { } else {
StorageFilerTO poolTO = cmd.getPool(); StorageFilerTO poolTO = cmd.getPool();
@ -393,8 +391,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
DatastoreMO primaryDsMo = new DatastoreMO(hyperHost.getContext(), morPrimaryDs); DatastoreMO primaryDsMo = new DatastoreMO(hyperHost.getContext(), morPrimaryDs);
details = createVolumeFromSnapshot(hyperHost, primaryDsMo, details = createVolumeFromSnapshot(hyperHost, primaryDsMo,
newVolumeName, accountId, volumeId, newVolumeName, accountId, volumeId, secondaryStorageUrl, backedUpSnapshotUuid);
secondaryStorageUrl, backedUpSnapshotUuid);
if (details == null) { if (details == null) {
success = true; success = true;
} }
@ -738,8 +735,10 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
return "Failed to delete snapshot backup file, backupUuid: " + backupUuid; 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 secStorageUrl, String workerVmName) throws Exception { String vmName, long volumeId, String poolId, String volumePath,
String secStorageUrl, String workerVmName) throws Exception {
String volumeFolder = String.valueOf(volumeId) + "/"; String volumeFolder = String.valueOf(volumeId) + "/";
VirtualMachineMO workerVm=null; VirtualMachineMO workerVm=null;
VirtualMachineMO vmMo=null; VirtualMachineMO vmMo=null;
@ -756,12 +755,11 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
vmMo = hyperHost.findVmOnHyperHost(vmName); vmMo = hyperHost.findVmOnHyperHost(vmName);
if (vmMo == null) { 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); 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) //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(); VirtualMachineConfigSpec vmConfig = new VirtualMachineConfigSpec();
vmConfig.setName(workerVMName); vmConfig.setName(workerVmName);
vmConfig.setMemoryMB((long) 4); vmConfig.setMemoryMB((long) 4);
vmConfig.setNumCPUs(1); vmConfig.setNumCPUs(1);
vmConfig.setGuestId(VirtualMachineGuestOsIdentifier._otherGuest.toString()); vmConfig.setGuestId(VirtualMachineGuestOsIdentifier._otherGuest.toString());
@ -780,7 +778,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
vmConfig.setDeviceChange(new VirtualDeviceConfigSpec[] { scsiControllerSpec }); vmConfig.setDeviceChange(new VirtualDeviceConfigSpec[] { scsiControllerSpec });
hyperHost.createVm(vmConfig); hyperHost.createVm(vmConfig);
workerVm = hyperHost.findVmOnHyperHost(workerVMName); workerVm = hyperHost.findVmOnHyperHost(workerVmName);
if (workerVm == null) { if (workerVm == null) {
String msg = "Unable to create worker VM to execute CopyVolumeCommand"; String msg = "Unable to create worker VM to execute CopyVolumeCommand";
s_logger.error(msg); s_logger.error(msg);
@ -795,7 +793,8 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
vmMo.createSnapshot(exportName, "Temporary snapshot for copy-volume command", false, false); 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); return new Pair<String, String>(volumeFolder, exportName);
} finally { } finally {

View File

@ -2885,7 +2885,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
if (cmd.getDiskCharacteristics().getType() == Volume.Type.ROOT) { if (cmd.getDiskCharacteristics().getType() == Volume.Type.ROOT) {
if (cmd.getTemplateUrl() == null) { if (cmd.getTemplateUrl() == null) {
// create a root volume for blank VM // create a root volume for blank VM
String dummyVmName = getWorkerName(context, cmd); String dummyVmName = getWorkerName(context, cmd, 0);
VirtualMachineMO vmMo = null; VirtualMachineMO vmMo = null;
try { try {
@ -2969,7 +2969,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
VirtualMachineMO vmMo = null; VirtualMachineMO vmMo = null;
String volumeUuid = UUID.randomUUID().toString().replace("-", ""); String volumeUuid = UUID.randomUUID().toString().replace("-", "");
String volumeDatastorePath = String.format("[%s] %s.vmdk", dsMo.getName(), volumeUuid); String volumeDatastorePath = String.format("[%s] %s.vmdk", dsMo.getName(), volumeUuid);
String dummyVmName = getWorkerName(context, cmd); String dummyVmName = getWorkerName(context, cmd, 0);
try { try {
vmMo = prepareVolumeHostDummyVm(hyperHost, dsMo, dummyVmName); vmMo = prepareVolumeHostDummyVm(hyperHost, dsMo, dummyVmName);
if (vmMo == null) { if (vmMo == null) {
@ -3968,7 +3968,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
@Override @Override
@DB @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); VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
String vmName = mgr.composeWorkerName(); String vmName = mgr.composeWorkerName();

View File

@ -66,12 +66,18 @@ public class VmwareSecondaryStorageResourceHandler implements SecondaryStorageRe
answer = _resource.defaultAction(cmd); answer = _resource.defaultAction(cmd);
} }
// special handling to pass-back context info for cleanups
if(cmd.getContextParam("execid") != null) { if(cmd.getContextParam("execid") != null) {
answer.setContextParam("execid", cmd.getContextParam("execid")); answer.setContextParam("execid", cmd.getContextParam("execid"));
} }
if(cmd.getContextParam("checkpoint") != null) { if(cmd.getContextParam("checkpoint") != null) {
answer.setContextParam("checkpoint", cmd.getContextParam("checkpoint")); answer.setContextParam("checkpoint", cmd.getContextParam("checkpoint"));
} }
if(cmd.getContextParam("checkpoint2") != null) {
answer.setContextParam("checkpoint2", cmd.getContextParam("checkpoint2"));
}
return answer; return answer;
} }
@ -219,9 +225,13 @@ public class VmwareSecondaryStorageResourceHandler implements SecondaryStorageRe
} }
@Override @Override
public String getWorkerName(VmwareContext context, Command cmd) { public String getWorkerName(VmwareContext context, Command cmd, int workerSequence) {
assert(cmd.getContextParam("worker") != null); assert(cmd.getContextParam("worker") != null);
return cmd.getContextParam("worker"); assert(workerSequence < 2);
if(workerSequence == 0)
return cmd.getContextParam("worker");
return cmd.getContextParam("worker2");
} }
@Override @Override

View File

@ -266,6 +266,12 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru {
long checkPointId = _checkPointMgr.pushCheckPoint(new VmwareCleanupMaid(hostDetails.get("guid"), workerName)); long checkPointId = _checkPointMgr.pushCheckPoint(new VmwareCleanupMaid(hostDetails.get("guid"), workerName));
cmd.setContextParam("worker", workerName); cmd.setContextParam("worker", workerName);
cmd.setContextParam("checkpoint", String.valueOf(checkPointId)); 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(); return cmdTarget.first().getId();

View File

@ -749,6 +749,11 @@ public class VmwareManagerImpl implements VmwareManager, VmwareStorageMount, Lis
if(checkPointIdStr != null) { if(checkPointIdStr != null) {
_checkPointMgr.popCheckPoint(Long.parseLong(checkPointIdStr)); _checkPointMgr.popCheckPoint(Long.parseLong(checkPointIdStr));
} }
checkPointIdStr = answer.getContextParam("checkpoint2");
if(checkPointIdStr != null) {
_checkPointMgr.popCheckPoint(Long.parseLong(checkPointIdStr));
}
} }
} }

View File

@ -1411,19 +1411,32 @@ public class VirtualMachineMO extends BaseMO {
HostMO hostMo = getRunningHost(); HostMO hostMo = getRunningHost();
VirtualMachineConfigInfo vmConfigInfo = getConfigInfo(); 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))
VirtualMachineMO clonedVmMo = hostMo.findVmOnHyperHost(clonedVmName); throw new Exception("Unable to create a blank VM");
VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec(); VirtualMachineMO clonedVmMo = hostMo.findVmOnHyperHost(clonedVmName);
VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[1]; if(clonedVmMo == null)
deviceConfigSpecArray[0] = new VirtualDeviceConfigSpec(); throw new Exception("Unable to find just-created blank VM");
VirtualDevice device = VmwareHelper.prepareDiskDevice(clonedVmMo, -1, disks, morDs, -1, 1); boolean bSuccess = false;
try {
deviceConfigSpecArray[0].setDevice(device); VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
deviceConfigSpecArray[0].setOperation(VirtualDeviceConfigSpecOperation.add); VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[1];
vmConfigSpec.setDeviceChange(deviceConfigSpecArray); deviceConfigSpecArray[0] = new VirtualDeviceConfigSpec();
clonedVmMo.configureVm(vmConfigSpec);
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);
bSuccess = true;
} finally {
if(!bSuccess) {
clonedVmMo.detachAllDisks();
clonedVmMo.destroy();
}
}
} }
public void plugDevice(VirtualDevice device) throws Exception { public void plugDevice(VirtualDevice device) throws Exception {