Skip to content

Commit 92c3486

Browse files
committed
fix merge witthout events and parent search
1 parent af9090e commit 92c3486

File tree

4 files changed

+45
-9
lines changed

4 files changed

+45
-9
lines changed

engine/schema/src/main/java/com/cloud/vm/snapshot/dao/VMSnapshotDao.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ public interface VMSnapshotDao extends GenericDao<VMSnapshotVO, Long>, StateDao<
3737

3838
List<VMSnapshotVO> listByParent(Long vmSnapshotId);
3939

40+
List<VMSnapshotVO> listByParentAndStateIn(Long vmSnapshotId, VMSnapshot.State... states);
41+
4042
VMSnapshotVO findByName(Long vmId, String name);
4143

4244
List<VMSnapshotVO> listByAccountId(Long accountId);

engine/schema/src/main/java/com/cloud/vm/snapshot/dao/VMSnapshotDaoImpl.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ public class VMSnapshotDaoImpl extends GenericDaoBase<VMSnapshotVO, Long> implem
4242
private final SearchBuilder<VMSnapshotVO> SnapshotStatusSearch;
4343
private final SearchBuilder<VMSnapshotVO> AllFieldsSearch;
4444

45+
private SearchBuilder<VMSnapshotVO> parentIdEqAndStateIn;
46+
47+
private static final String PARENT = "parent";
48+
49+
private static final String STATE = "state";
50+
4551
protected VMSnapshotDaoImpl() {
4652
AllFieldsSearch = createSearchBuilder();
4753
AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), Op.EQ);
@@ -71,6 +77,11 @@ protected VMSnapshotDaoImpl() {
7177
SnapshotStatusSearch.and("vm_id", SnapshotStatusSearch.entity().getVmId(), SearchCriteria.Op.EQ);
7278
SnapshotStatusSearch.and("state", SnapshotStatusSearch.entity().getState(), SearchCriteria.Op.IN);
7379
SnapshotStatusSearch.done();
80+
81+
parentIdEqAndStateIn = createSearchBuilder();
82+
parentIdEqAndStateIn.and(PARENT, parentIdEqAndStateIn.entity().getParent(), Op.EQ);
83+
parentIdEqAndStateIn.and(STATE, parentIdEqAndStateIn.entity().getState(), Op.IN);
84+
parentIdEqAndStateIn.done();
7485
}
7586

7687
@Override
@@ -119,6 +130,14 @@ public List<VMSnapshotVO> listByParent(Long vmSnapshotId) {
119130
return listBy(sc, null);
120131
}
121132

133+
@Override
134+
public List<VMSnapshotVO> listByParentAndStateIn(Long vmSnapshotId, State... states) {
135+
SearchCriteria<VMSnapshotVO> sc = parentIdEqAndStateIn.create();
136+
sc.setParameters(PARENT, vmSnapshotId);
137+
sc.setParameters(STATE, (Object[])states);
138+
return listBy(sc, null);
139+
}
140+
122141
@Override
123142
public VMSnapshotVO findByName(Long vmId, String name) {
124143
SearchCriteria<VMSnapshotVO> sc = AllFieldsSearch.create();

engine/storage/snapshot/src/main/java/org/apache/cloudstack/storage/vmsnapshot/KvmFileBasedStorageVmSnapshotStrategy.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ public boolean deleteVMSnapshot(VMSnapshot vmSnapshot) {
123123
transitStateWithoutThrow(vmSnapshotBeingDeleted, VMSnapshot.Event.ExpungeRequested);
124124

125125
List<VolumeObjectTO> volumeTOs = vmSnapshotHelper.getVolumeTOList(vmSnapshotBeingDeleted.getVmId());
126-
List<VMSnapshotVO> snapshotChildren = vmSnapshotDao.listByParent(vmSnapshotBeingDeleted.getId());
126+
List<VMSnapshotVO> snapshotChildren = vmSnapshotDao.listByParentAndStateIn(vmSnapshotBeingDeleted.getId(), VMSnapshot.State.Ready, VMSnapshot.State.Hidden);
127127

128128
long realSize = getVMSnapshotRealSize(vmSnapshotBeingDeleted);
129129
int numberOfChildren = snapshotChildren.size();
@@ -248,10 +248,10 @@ private void mergeOldSiblingWithOldParentIfOldParentIsDead(VMSnapshotVO oldParen
248248
if (oldParent.getCurrent()) {
249249
snapshotVos = mergeCurrentDeltaOnSnapshot(oldParent, userVm, hostId, volumeTOs);
250250
} else {
251-
List<VMSnapshotVO> oldSiblings = vmSnapshotDao.listByParent(oldParent.getId());
251+
List<VMSnapshotVO> oldSiblings = vmSnapshotDao.listByParentAndStateIn(oldParent.getId(), VMSnapshot.State.Ready, VMSnapshot.State.Hidden);
252252

253253
if (oldSiblings.size() > 1) {
254-
logger.debug("The old snapshot [{}] is dead and still has more than one live snapshot. We will keep it on storage still.", oldParent.getUuid());
254+
logger.debug("The old snapshot [{}] is dead and still has more than one live child snapshot. We will keep it on storage still.", oldParent.getUuid());
255255
return;
256256
}
257257

@@ -366,7 +366,7 @@ private List<SnapshotVO> deleteSnapshot(VMSnapshotVO vmSnapshotVO, Long hostId)
366366
private List<SnapshotVO> mergeSnapshots(VMSnapshotVO vmSnapshotVO, VMSnapshotVO childSnapshot, UserVmVO userVm, List<VolumeObjectTO> volumeObjectTOS, Long hostId) {
367367
logger.debug("Merging VM snapshot [{}] with its child [{}].", vmSnapshotVO.getUuid(), childSnapshot.getUuid());
368368

369-
List<VMSnapshotVO> snapshotGrandChildren = vmSnapshotDao.listByParent(childSnapshot.getId());
369+
List<VMSnapshotVO> snapshotGrandChildren = vmSnapshotDao.listByParentAndStateIn(childSnapshot.getId(), VMSnapshot.State.Ready, VMSnapshot.State.Hidden);
370370

371371
if (userVm.getState().equals(VirtualMachine.State.Running) && !snapshotGrandChildren.isEmpty()) {
372372
logger.debug("Removing VM snapshots that are part of the VM's [{}] current backing chain from the list of snapshots to be rebased.", userVm.getUuid());

plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -571,9 +571,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
571571
* 1st parameter: VM's name;<br>
572572
* 2nd parameter: disk's label (target.dev tag from VM's XML);<br>
573573
* 3rd parameter: the absolute path of the base file;
574-
* 4th parameter: the flag '--delete', if Libvirt supports it. Libvirt started to support it on version <b>6.0.0</b>;
575574
*/
576-
private static final String COMMAND_MERGE_SNAPSHOT = "virsh blockcommit %s %s --base %s --active --wait %s --pivot";
575+
private static final String COMMAND_MERGE_SNAPSHOT = "virsh blockcommit %s %s --base %s";
577576

578577
public long getHypervisorLibvirtVersion() {
579578
return hypervisorLibvirtVersion;
@@ -5878,7 +5877,7 @@ public void mergeSnapshotIntoBaseFile(Domain vm, String diskLabel, String baseFi
58785877
if (AgentPropertiesFileHandler.getPropertyValue(AgentProperties.LIBVIRT_EVENTS_ENABLED)) {
58795878
mergeSnapshotIntoBaseFileWithEventsAndConfigurableTimeout(vm, diskLabel, baseFilePath, topFilePath, active, snapshotName, volume, conn);
58805879
} else {
5881-
mergeSnapshotIntoBaseFileWithoutEvents(vm, diskLabel, baseFilePath, snapshotName, volume, conn);
5880+
mergeSnapshotIntoBaseFileWithoutEvents(vm, diskLabel, baseFilePath, topFilePath, active, snapshotName, volume, conn);
58825881
}
58835882
}
58845883

@@ -5949,10 +5948,10 @@ protected void mergeSnapshotIntoBaseFileWithEventsAndConfigurableTimeout(Domain
59495948
* @param snapshotName Name of the snapshot;
59505949
* @throws LibvirtException
59515950
*/
5952-
protected void mergeSnapshotIntoBaseFileWithoutEvents(Domain vm, String diskLabel, String baseFilePath, String snapshotName, VolumeObjectTO volume, Connect conn) throws LibvirtException {
5951+
protected void mergeSnapshotIntoBaseFileWithoutEvents(Domain vm, String diskLabel, String baseFilePath, String topFilePath, boolean active, String snapshotName, VolumeObjectTO volume, Connect conn) throws LibvirtException {
59535952
boolean isLibvirtSupportingFlagDeleteOnCommandVirshBlockcommit = LibvirtUtilitiesHelper.isLibvirtSupportingFlagDeleteOnCommandVirshBlockcommit(conn);
59545953
String vmName = vm.getName();
5955-
String mergeCommand = String.format(COMMAND_MERGE_SNAPSHOT, vmName, diskLabel, baseFilePath, isLibvirtSupportingFlagDeleteOnCommandVirshBlockcommit ? "--delete" : "");
5954+
String mergeCommand = buildMergeCommand(vmName, diskLabel, baseFilePath, topFilePath, active, isLibvirtSupportingFlagDeleteOnCommandVirshBlockcommit);
59565955
String mergeResult = Script.runSimpleBashScript(mergeCommand);
59575956

59585957
if (mergeResult == null) {
@@ -5969,6 +5968,22 @@ protected void mergeSnapshotIntoBaseFileWithoutEvents(Domain vm, String diskLabe
59695968
throw new CloudRuntimeException(errorMsg);
59705969
}
59715970

5971+
protected String buildMergeCommand(String vmName, String diskLabel, String baseFilePath, String topFilePath, boolean active, boolean delete) {
5972+
StringBuilder cmd = new StringBuilder(COMMAND_MERGE_SNAPSHOT);
5973+
if (StringUtils.isNotEmpty(topFilePath)) {
5974+
cmd.append(" --top ");
5975+
cmd.append(topFilePath);
5976+
}
5977+
if (active) {
5978+
cmd.append(" --active --pivot");
5979+
}
5980+
if (delete) {
5981+
cmd.append(" --delete");
5982+
}
5983+
cmd.append(" --wait");
5984+
return String.format(cmd.toString(), vmName, diskLabel, baseFilePath);
5985+
}
5986+
59725987
/**
59735988
* This was created to facilitate testing.
59745989
* */

0 commit comments

Comments
 (0)