Source:
public void attemptResolution() { Set<Guid> images; if (getVmDao().get(getParameters().getVmId()).isDown()) { StoragePool pool = getStoragePoolDao().get(getParameters().getStoragePoolId()); if (pool.getSpmVdsId() == null || pool.getStatus() != StoragePoolStatus.Up) { log.info("VM down, waiting on SPM election to resolve Live Merge"); setSucceeded(true); return; } else { log.error("VM is not running, proceeding with Live Merge recovery"); images = getVolumeChainFromRecovery(); } } else { images = getVolumeChain(); } if (images == null) { setCommandStatus(CommandStatus.FAILED); return; } Set<Guid> imagesToRemove = getImagesToRemove(); images.retainAll(imagesToRemove); if (images.size() != 1) { log.error("Failed to live merge, still in volume chain: {}", images); setCommandStatus(CommandStatus.FAILED); return; } else if (!images.contains(getParameters().getBaseImage().getImageId())) { log.error("Failed to live merge, base volume '{}' already removed from qemu chain. " + "Please verify that the base volume state isn't ILLEGAL in parent snapshot." + "If parent snapshot contains volume(s) in ILLEGAL state, please delete that snapshot " + "before deleting this one. Otherwise, please contact support.", getParameters().getBaseImage().getImageId()); setCommandStatus(CommandStatus.FAILED); return; } imagesToRemove.removeAll(images); log.info("Successfully removed volume(s): {}", imagesToRemove); log.info("Volume merge type '{}'", VmBlockJobType.COMMIT.name()); MergeStatusReturnValue returnValue = new MergeStatusReturnValue(VmBlockJobType.COMMIT, imagesToRemove); getReturnValue().setActionReturnValue(returnValue); setSucceeded(true); persistCommand(getParameters().getParentCommand(), true); setCommandStatus(CommandStatus.SUCCEEDED); }

Target:
public void attemptResolution() { Set<Guid> images; if (getVmDao().get(getParameters().getVmId()).isDown()) { StoragePool pool = getStoragePoolDao().get(getParameters().getStoragePoolId()); if (pool.getSpmVdsId() == null || pool.getStatus() != StoragePoolStatus.Up) { log.info("VM down, waiting on SPM election to resolve Live Merge"); setSucceeded(true); return; } else { log.error("VM is not running, proceeding with Live Merge recovery"); images = getVolumeChainFromRecovery(); } } else { images = getVolumeChain(); } if (images == null) { setCommandStatus(CommandStatus.FAILED); return; } Set<Guid> imagesToRemove = getImagesToRemove(); images.retainAll(imagesToRemove); if (images.size() != 1) { log.error("Failed to live merge, still in volume chain: {}", images); setCommandStatus(CommandStatus.FAILED); return; } else if (!images.contains(getParameters().getBaseImage().getImageId())) { String snapshotName = getSnapshotDao().get(getParameters().getBaseImage().getSnapshotId()).getDescription(); log.error("Failed to merge images of snapshot '{}': base volume '{}' is missing. " + "This may have been caused by a failed attempt to remove the parent snapshot; " + "if this is the case, please retry deletion of the parent snapshot before deleting this one.", snapshotName, getParameters().getBaseImage().getImageId()); addCustomValue("SnapshotName", snapshotName); addCustomValue("BaseVolumeId", getParameters().getBaseImage().getImageId().toString()); auditLog(this, AuditLogType.USER_REMOVE_SNAPSHOT_FINISHED_FAILURE_BASE_NOT_FOUND); setCommandStatus(CommandStatus.FAILED); return; } imagesToRemove.removeAll(images); log.info("Successfully removed volume(s): {}", imagesToRemove); log.info("Volume merge type '{}'", VmBlockJobType.COMMIT.name()); MergeStatusReturnValue returnValue = new MergeStatusReturnValue(VmBlockJobType.COMMIT, imagesToRemove); getReturnValue().setActionReturnValue(returnValue); setSucceeded(true); persistCommand(getParameters().getParentCommand(), true); setCommandStatus(CommandStatus.SUCCEEDED); }