Skip to content

Commit e303baa

Browse files
committed
Merge pull request #1905 from nvazquez/expungeVmRefactor
CLOUDSTACK-9738: [Vmware] Optimize vm expunge process for instances with vm snapshots## Description It was noticed that expunging instances with many vm snapshots took a look of time, as hypervisor received as many tasks as vm snapshots instance had, apart from the delete vm task. We propose a way to optimize this process for instances with vm snapshots by sending only one delete task to hypervisor, which will delete vm and its snapshots ## Use cases 1. deleteVMsnapohsot-> no changes to current behavior 2. destroyVM with expunge=false -> no actions to VMsnaphsot is performed at the moment. When VM cleanup thread is executed it will perform the same sequence as (3). If instance is recovered before expunged by the cleanup thread it will remain intact with VMSnapshot chain present 3. destroyVM with expunge=true: * Vmsnaphsot is marked with removed timestamp and state = Expunging in DB * VM is deleted in HW * pr/1905: CLOUDSTACK-9738: [Vmware] Optimize vm expunge process for instances with vm snapshots Signed-off-by: Rajani Karuturi <rajani.karuturi@accelerite.com>
2 parents 202b92f + 6ce6cf6 commit e303baa

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)