Skip to content

Commit ea7c48c

Browse files
committed
Merge pull request #1941 from anshul1886/CLOUDSTACK-8663
CLOUDSTACK-8663: Fixed various issues to allow VM snapshots and volumesnapshots to exist together Reverting VM to disk only snapshot in Xenserver corrupts VM Stale NFS secondary storage on XS leads to volume creation failure from snapshot Fixed various concerns raised in #672 * pr/1941: CLOUDSTACK-8663: Fixed various issues to allow VM snapshots and volume snapshots to exist together Signed-off-by: Rajani Karuturi <rajani.karuturi@accelerite.com>
2 parents c4d63af + ca84fd4 commit ea7c48c

File tree

5 files changed

+32
-14
lines changed

5 files changed

+32
-14
lines changed

plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
import java.net.URL;
3030
import java.net.URLConnection;
3131
import java.nio.charset.Charset;
32+
33+
import org.apache.commons.collections.MapUtils;
3234
import org.joda.time.Duration;
3335
import java.util.ArrayList;
3436
import java.util.Date;
@@ -1415,6 +1417,10 @@ public VM createWorkingVM(final Connection conn, final String vmName, final Stri
14151417
vbdr.userdevice = "autodetect";
14161418
vbdr.mode = Types.VbdMode.RW;
14171419
vbdr.type = Types.VbdType.DISK;
1420+
Long deviceId = volumeTO.getDeviceId();
1421+
if (deviceId != null && (!isDeviceUsed(conn, vm, deviceId) || deviceId > 3)) {
1422+
vbdr.userdevice = deviceId.toString();
1423+
}
14181424
VBD.create(conn, vbdr);
14191425
}
14201426
return vm;
@@ -4350,6 +4356,30 @@ public void rebootVM(final Connection conn, final VM vm, final String vmName) th
43504356
}
43514357
}
43524358

4359+
protected void skipOrRemoveSR(Connection conn, SR sr) {
4360+
if (sr == null) {
4361+
return;
4362+
}
4363+
if (s_logger.isDebugEnabled()) {
4364+
s_logger.debug(logX(sr, "Removing SR"));
4365+
}
4366+
try {
4367+
Set<VDI> vdis = sr.getVDIs(conn);
4368+
for (VDI vdi : vdis) {
4369+
if (MapUtils.isEmpty(vdi.getCurrentOperations(conn))) {
4370+
continue;
4371+
}
4372+
return;
4373+
}
4374+
removeSR(conn, sr);
4375+
return;
4376+
} catch (XenAPIException | XmlRpcException e) {
4377+
s_logger.warn(logX(sr, "Unable to get current opertions " + e.toString()), e);
4378+
}
4379+
String msg = "Remove SR failed";
4380+
s_logger.warn(msg);
4381+
}
4382+
43534383
public void removeSR(final Connection conn, final SR sr) {
43544384
if (sr == null) {
43554385
return;

plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/XenServerStorageProcessor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1199,7 +1199,7 @@ protected boolean destroySnapshotOnPrimaryStorageExceptThis(final Connection con
11991199
final Set<VDI> snapshots = volume.getSnapshots(conn);
12001200
for (final VDI snapshot : snapshots) {
12011201
try {
1202-
if (!snapshot.getUuid(conn).equals(avoidSnapshotUuid) && snapshot.getSnapshotTime(conn).before(avoidSnapshot.getSnapshotTime(conn))) {
1202+
if (!snapshot.getUuid(conn).equals(avoidSnapshotUuid) && snapshot.getSnapshotTime(conn).before(avoidSnapshot.getSnapshotTime(conn)) && snapshot.getVBDs(conn).isEmpty()) {
12031203
snapshot.destroy(conn);
12041204
}
12051205
} catch (final Exception e) {

plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/Xenserver625StorageProcessor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -738,7 +738,7 @@ public Answer createVolumeFromSnapshot(final CopyCommand cmd) {
738738
s_logger.warn(details, e);
739739
} finally {
740740
if (srcSr != null) {
741-
hypervisorResource.removeSR(conn, srcSr);
741+
hypervisorResource.skipOrRemoveSR(conn, srcSr);
742742
}
743743
if (!result && destVdi != null) {
744744
try {

server/src/com/cloud/storage/VolumeApiServiceImpl.java

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2146,13 +2146,6 @@ public Snapshot allocSnapshot(Long volumeId, Long policyId, String snapshotName)
21462146
throw new InvalidParameterValueException("Can't find zone by id " + volume.getDataCenterId());
21472147
}
21482148

2149-
if (volume.getInstanceId() != null) {
2150-
// Check that Vm to which this volume is attached does not have VM Snapshots
2151-
if (_vmSnapshotDao.findByVm(volume.getInstanceId()).size() > 0) {
2152-
throw new InvalidParameterValueException("Volume snapshot is not allowed, please detach it from VM with VM Snapshots");
2153-
}
2154-
}
2155-
21562149
if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getId())) {
21572150
throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + zone.getName());
21582151
}

server/src/com/cloud/vm/snapshot/VMSnapshotManagerImpl.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -263,11 +263,6 @@ public VMSnapshot allocVMSnapshot(Long vmId, String vsDisplayName, String vsDesc
263263
throw new InvalidParameterValueException("Creating VM snapshot failed due to VM:" + vmId + " is a system VM or does not exist");
264264
}
265265

266-
if (_snapshotDao.listByInstanceId(vmId, Snapshot.State.BackedUp).size() > 0) {
267-
throw new InvalidParameterValueException(
268-
"VM snapshot for this VM is not allowed. This VM has volumes attached which has snapshots, please remove all snapshots before taking VM snapshot");
269-
}
270-
271266
// VM snapshot with memory is not supported for VGPU Vms
272267
if (snapshotMemory && _serviceOfferingDetailsDao.findDetail(userVmVo.getServiceOfferingId(), GPU.Keys.vgpuType.toString()) != null) {
273268
throw new InvalidParameterValueException("VM snapshot with MEMORY is not supported for vGPU enabled VMs.");

0 commit comments

Comments
 (0)