Skip to content

Commit 6ce6cf6

Browse files
committed
CLOUDSTACK-9738: [Vmware] Optimize vm expunge process for instances with vm snapshots
1 parent 8e069ed commit 6ce6cf6

18 files changed

Lines changed: 93 additions & 27 deletions

File tree

api/src/com/cloud/vm/UserVmService.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,14 @@ public interface UserVmService {
7575
/**
7676
* Destroys one virtual machine
7777
*
78-
* @param userId
79-
* the id of the user performing the action
8078
* @param vmId
8179
* the id of the virtual machine.
80+
* @param expunge
81+
* indicates if vm should be expunged
8282
* @throws ConcurrentOperationException
8383
* @throws ResourceUnavailableException
8484
*/
85-
UserVm destroyVm(long vmId) throws ResourceUnavailableException, ConcurrentOperationException;
85+
UserVm destroyVm(long vmId, boolean expunge) throws ResourceUnavailableException, ConcurrentOperationException;
8686

8787
/**
8888
* Resets the password of a virtual machine.

api/src/com/cloud/vm/snapshot/VMSnapshotService.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,11 @@ UserVm revertToSnapshot(Long vmSnapshotId) throws InsufficientServerCapacityExce
4646
ConcurrentOperationException;
4747

4848
VirtualMachine getVMBySnapshotId(Long id);
49+
50+
/**
51+
* Delete vm snapshots only from database. Introduced as a Vmware optimization in which vm snapshots are deleted when
52+
* the vm gets deleted on hypervisor (no need to delete each vm snapshot before deleting vm, just mark them as deleted on DB)
53+
* @param id vm id
54+
*/
55+
boolean deleteVMSnapshotsFromDB(Long vmId);
4956
}

engine/api/src/com/cloud/vm/VirtualMachineManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ void orchestrateStart(String vmUuid, Map<VirtualMachineProfile.Param, Object> pa
110110

111111
void advanceExpunge(String vmUuid) throws ResourceUnavailableException, OperationTimedoutException, ConcurrentOperationException;
112112

113-
void destroy(String vmUuid) throws AgentUnavailableException, OperationTimedoutException, ConcurrentOperationException;
113+
void destroy(String vmUuid, boolean expunge) throws AgentUnavailableException, OperationTimedoutException, ConcurrentOperationException;
114114

115115
void migrateAway(String vmUuid, long hostId) throws InsufficientServerCapacityException;
116116

engine/api/src/org/apache/cloudstack/engine/cloud/entity/api/VirtualMachineEntity.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,9 @@ String reserve(DeploymentPlanner plannerToUse, @BeanParam DeploymentPlan plan, E
129129

130130
/**
131131
* Destroys the VM.
132+
* @param expunge indicates if vm should be expunged
132133
*/
133-
boolean destroy(String caller) throws AgentUnavailableException, CloudException, ConcurrentOperationException;
134+
boolean destroy(String caller, boolean expunge) throws AgentUnavailableException, CloudException, ConcurrentOperationException;
134135

135136
/**
136137
* Duplicate this VM in the database so that it will start new

engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/VMSnapshotStrategy.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,12 @@ public interface VMSnapshotStrategy {
2828
boolean revertVMSnapshot(VMSnapshot vmSnapshot);
2929

3030
StrategyPriority canHandle(VMSnapshot vmSnapshot);
31+
32+
/**
33+
* Delete vm snapshot only from database. Introduced as a Vmware optimization in which vm snapshots are deleted when
34+
* the vm gets deleted on hypervisor (no need to delete each vm snapshot before deleting vm, just mark them as deleted on DB)
35+
* @param vmSnapshot vm snapshot to be marked as deleted.
36+
* @return true if vm snapshot removed from DB, false if not.
37+
*/
38+
boolean deleteVMSnapshotFromDB(VMSnapshot vmSnapshot);
3139
}

engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java

100644100755
Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1679,7 +1679,7 @@ public boolean stateTransitTo(final VirtualMachine vm1, final VirtualMachine.Eve
16791679
}
16801680

16811681
@Override
1682-
public void destroy(final String vmUuid) throws AgentUnavailableException, OperationTimedoutException, ConcurrentOperationException {
1682+
public void destroy(final String vmUuid, final boolean expunge) throws AgentUnavailableException, OperationTimedoutException, ConcurrentOperationException {
16831683
VMInstanceVO vm = _vmDao.findByUuid(vmUuid);
16841684
if (vm == null || vm.getState() == State.Destroyed || vm.getState() == State.Expunging || vm.getRemoved() != null) {
16851685
if (s_logger.isDebugEnabled()) {
@@ -1689,15 +1689,12 @@ public void destroy(final String vmUuid) throws AgentUnavailableException, Opera
16891689
}
16901690

16911691
if (s_logger.isDebugEnabled()) {
1692-
s_logger.debug("Destroying vm " + vm);
1692+
s_logger.debug("Destroying vm " + vm + ", expunge flag " + (expunge ? "on" : "off"));
16931693
}
16941694

16951695
advanceStop(vmUuid, VmDestroyForcestop.value());
16961696

1697-
if (!_vmSnapshotMgr.deleteAllVMSnapshots(vm.getId(), null)) {
1698-
s_logger.debug("Unable to delete all snapshots for " + vm);
1699-
throw new CloudRuntimeException("Unable to delete vm snapshots for " + vm);
1700-
}
1697+
deleteVMSnapshots(vm, expunge);
17011698

17021699
// reload the vm object from db
17031700
vm = _vmDao.findByUuid(vmUuid);
@@ -1712,6 +1709,27 @@ public void destroy(final String vmUuid) throws AgentUnavailableException, Opera
17121709
}
17131710
}
17141711

1712+
/**
1713+
* Delete vm snapshots depending on vm's hypervisor type. For Vmware, vm snapshots removal is delegated to vm cleanup thread
1714+
* to reduce tasks sent to hypervisor (one tasks to delete vm snapshots and vm itself
1715+
* instead of one task for each vm snapshot plus another for the vm)
1716+
* @param vm vm
1717+
* @param expunge indicates if vm should be expunged
1718+
*/
1719+
private void deleteVMSnapshots(VMInstanceVO vm, boolean expunge) {
1720+
if (! vm.getHypervisorType().equals(HypervisorType.VMware)) {
1721+
if (!_vmSnapshotMgr.deleteAllVMSnapshots(vm.getId(), null)) {
1722+
s_logger.debug("Unable to delete all snapshots for " + vm);
1723+
throw new CloudRuntimeException("Unable to delete vm snapshots for " + vm);
1724+
}
1725+
}
1726+
else {
1727+
if (expunge) {
1728+
_vmSnapshotMgr.deleteVMSnapshotsFromDB(vm.getId());
1729+
}
1730+
}
1731+
}
1732+
17151733
protected boolean checkVmOnHost(final VirtualMachine vm, final long hostId) throws AgentUnavailableException, OperationTimedoutException {
17161734
final Answer answer = _agentMgr.send(hostId, new CheckVirtualMachineCommand(vm.getInstanceName()));
17171735
if (answer == null || !answer.getResult()) {

engine/orchestration/src/org/apache/cloudstack/engine/cloud/entity/api/VMEntityManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,5 +46,5 @@ void deployVirtualMachine(String reservationId, VMEntityVO vmEntityVO, String ca
4646

4747
boolean stopvirtualmachineforced(VMEntityVO vmEntityVO, String caller) throws ResourceUnavailableException;
4848

49-
boolean destroyVirtualMachine(VMEntityVO vmEntityVO, String caller) throws AgentUnavailableException, OperationTimedoutException, ConcurrentOperationException;
49+
boolean destroyVirtualMachine(VMEntityVO vmEntityVO, String caller, boolean expunge) throws AgentUnavailableException, OperationTimedoutException, ConcurrentOperationException;
5050
}

engine/orchestration/src/org/apache/cloudstack/engine/cloud/entity/api/VMEntityManagerImpl.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -261,10 +261,10 @@ public boolean stopvirtualmachineforced(VMEntityVO vmEntityVO, String caller) th
261261
}
262262

263263
@Override
264-
public boolean destroyVirtualMachine(VMEntityVO vmEntityVO, String caller) throws AgentUnavailableException, OperationTimedoutException, ConcurrentOperationException {
264+
public boolean destroyVirtualMachine(VMEntityVO vmEntityVO, String caller, boolean expunge) throws AgentUnavailableException, OperationTimedoutException, ConcurrentOperationException {
265265

266266
VMInstanceVO vm = _vmDao.findByUuid(vmEntityVO.getUuid());
267-
_itMgr.destroy(vm.getUuid());
267+
_itMgr.destroy(vm.getUuid(), expunge);
268268
return true;
269269
}
270270

engine/orchestration/src/org/apache/cloudstack/engine/cloud/entity/api/VirtualMachineEntityImpl.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -229,8 +229,8 @@ public void cleanup() {
229229
}
230230

231231
@Override
232-
public boolean destroy(String caller) throws AgentUnavailableException, OperationTimedoutException, ConcurrentOperationException {
233-
return manager.destroyVirtualMachine(this.vmEntityVO, caller);
232+
public boolean destroy(String caller, boolean expunge) throws AgentUnavailableException, OperationTimedoutException, ConcurrentOperationException {
233+
return manager.destroyVirtualMachine(this.vmEntityVO, caller, expunge);
234234
}
235235

236236
@Override

engine/storage/snapshot/src/org/apache/cloudstack/storage/vmsnapshot/DefaultVMSnapshotStrategy.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,4 +392,15 @@ public boolean revertVMSnapshot(VMSnapshot vmSnapshot) {
392392
public StrategyPriority canHandle(VMSnapshot vmSnapshot) {
393393
return StrategyPriority.DEFAULT;
394394
}
395+
396+
@Override
397+
public boolean deleteVMSnapshotFromDB(VMSnapshot vmSnapshot) {
398+
try {
399+
vmSnapshotHelper.vmSnapshotStateTransitTo(vmSnapshot, VMSnapshot.Event.ExpungeRequested);
400+
} catch (NoTransitionException e) {
401+
s_logger.debug("Failed to change vm snapshot state with event ExpungeRequested");
402+
throw new CloudRuntimeException("Failed to change vm snapshot state with event ExpungeRequested: " + e.getMessage());
403+
}
404+
return vmSnapshotDao.remove(vmSnapshot.getId());
405+
}
395406
}

0 commit comments

Comments
 (0)