|
24 | 24 | import org.apache.log4j.Logger; |
25 | 25 | import org.libvirt.Connect; |
26 | 26 | import org.libvirt.Domain; |
27 | | -import org.libvirt.DomainInfo.DomainState; |
| 27 | +import org.libvirt.DomainInfo; |
28 | 28 | import org.libvirt.DomainSnapshot; |
29 | 29 | import org.libvirt.LibvirtException; |
30 | 30 |
|
@@ -52,18 +52,33 @@ public Answer execute(final DeleteVMSnapshotCommand cmd, final LibvirtComputingR |
52 | 52 | final KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr(); |
53 | 53 | Domain dm = null; |
54 | 54 | DomainSnapshot snapshot = null; |
| 55 | + DomainInfo.DomainState oldState = null; |
| 56 | + boolean tryingResume = false; |
| 57 | + Connect conn = null; |
55 | 58 | try { |
56 | 59 | final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper(); |
57 | | - Connect conn = libvirtUtilitiesHelper.getConnection(); |
| 60 | + conn = libvirtUtilitiesHelper.getConnection(); |
58 | 61 | dm = libvirtComputingResource.getDomain(conn, vmName); |
59 | 62 |
|
60 | 63 | snapshot = dm.snapshotLookupByName(cmd.getTarget().getSnapshotName()); |
61 | 64 |
|
62 | | - s_logger.debug("Suspending domain " + vmName); |
63 | | - dm.suspend(); // suspend the vm to avoid image corruption |
| 65 | + oldState = dm.getInfo().state; |
| 66 | + if (oldState == DomainInfo.DomainState.VIR_DOMAIN_RUNNING) { |
| 67 | + s_logger.debug("Suspending domain " + vmName); |
| 68 | + dm.suspend(); // suspend the vm to avoid image corruption |
| 69 | + } |
64 | 70 |
|
65 | 71 | snapshot.delete(0); // only remove this snapshot, not children |
66 | 72 |
|
| 73 | + if (oldState == DomainInfo.DomainState.VIR_DOMAIN_RUNNING) { |
| 74 | + // Resume the VM |
| 75 | + tryingResume = true; |
| 76 | + dm = libvirtComputingResource.getDomain(conn, vmName); |
| 77 | + if (dm.getInfo().state == DomainInfo.DomainState.VIR_DOMAIN_PAUSED) { |
| 78 | + dm.resume(); |
| 79 | + } |
| 80 | + } |
| 81 | + |
67 | 82 | return new DeleteVMSnapshotAnswer(cmd, cmd.getVolumeTOs()); |
68 | 83 | } catch (LibvirtException e) { |
69 | 84 | String msg = " Delete VM snapshot failed due to " + e.toString(); |
@@ -97,21 +112,26 @@ public Answer execute(final DeleteVMSnapshotCommand cmd, final LibvirtComputingR |
97 | 112 | } else if (snapshot == null) { |
98 | 113 | s_logger.debug("Can not find vm snapshot " + cmd.getTarget().getSnapshotName() + " on vm: " + vmName + ", return true"); |
99 | 114 | return new DeleteVMSnapshotAnswer(cmd, cmd.getVolumeTOs()); |
| 115 | + } else if (tryingResume) { |
| 116 | + s_logger.error("Failed to resume vm after delete snapshot " + cmd.getTarget().getSnapshotName() + " on vm: " + vmName + " return true : " + e); |
| 117 | + return new DeleteVMSnapshotAnswer(cmd, cmd.getVolumeTOs()); |
100 | 118 | } |
101 | 119 |
|
102 | 120 | s_logger.warn(msg, e); |
103 | 121 | return new DeleteVMSnapshotAnswer(cmd, false, msg); |
104 | 122 | } finally { |
105 | 123 | if (dm != null) { |
| 124 | + // Make sure if the VM is paused, then resume it, in case we got an exception during our delete() and didn't have the chance before |
106 | 125 | try { |
107 | | - if (dm.getInfo().state == DomainState.VIR_DOMAIN_PAUSED) { |
| 126 | + dm = libvirtComputingResource.getDomain(conn, vmName); |
| 127 | + if (oldState == DomainInfo.DomainState.VIR_DOMAIN_RUNNING && dm.getInfo().state == DomainInfo.DomainState.VIR_DOMAIN_PAUSED) { |
108 | 128 | s_logger.debug("Resuming domain " + vmName); |
109 | 129 | dm.resume(); |
110 | 130 | } |
111 | 131 | dm.free(); |
112 | | - } catch (LibvirtException l) { |
113 | | - s_logger.trace("Ignoring libvirt error.", l); |
114 | | - }; |
| 132 | + } catch (LibvirtException e) { |
| 133 | + s_logger.error("Failed to resume vm after delete snapshot " + cmd.getTarget().getSnapshotName() + " on vm: " + vmName + " return true : " + e); |
| 134 | + } |
115 | 135 | } |
116 | 136 | } |
117 | 137 | } |
|
0 commit comments