mirror of https://gitee.com/openkylin/libvirt.git
qemu_snapshot: revert: move inactive snapshot to separate function
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
parent
405375ceb0
commit
85e4a13c3f
|
@ -2153,6 +2153,84 @@ qemuSnapshotInternalRevertInactive(virQEMUDriver *driver,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
qemuSnapshotRevertInactive(virDomainObj *vm,
|
||||||
|
virDomainSnapshotPtr snapshot,
|
||||||
|
virDomainMomentObj *snap,
|
||||||
|
virQEMUDriver *driver,
|
||||||
|
virQEMUDriverConfig *cfg,
|
||||||
|
virDomainDef **inactiveConfig,
|
||||||
|
unsigned int start_flags,
|
||||||
|
unsigned int flags)
|
||||||
|
{
|
||||||
|
virObjectEvent *event = NULL;
|
||||||
|
virObjectEvent *event2 = NULL;
|
||||||
|
int detail;
|
||||||
|
bool defined = false;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
/* Transitions 1, 4, 7 */
|
||||||
|
/* Newer qemu -loadvm refuses to revert to the state of a snapshot
|
||||||
|
* created by qemu-img snapshot -c. If the domain is running, we
|
||||||
|
* must take it offline; then do the revert using qemu-img.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (virDomainObjIsActive(vm)) {
|
||||||
|
/* Transitions 4, 7 */
|
||||||
|
qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FROM_SNAPSHOT,
|
||||||
|
QEMU_ASYNC_JOB_START, 0);
|
||||||
|
virDomainAuditStop(vm, "from-snapshot");
|
||||||
|
detail = VIR_DOMAIN_EVENT_STOPPED_FROM_SNAPSHOT;
|
||||||
|
event = virDomainEventLifecycleNewFromObj(vm,
|
||||||
|
VIR_DOMAIN_EVENT_STOPPED,
|
||||||
|
detail);
|
||||||
|
virObjectEventStateQueue(driver->domainEventState, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qemuSnapshotInternalRevertInactive(driver, vm, snap) < 0) {
|
||||||
|
qemuDomainRemoveInactive(driver, vm);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*inactiveConfig) {
|
||||||
|
virDomainObjAssignDef(vm, inactiveConfig, false, NULL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & (VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING |
|
||||||
|
VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED)) {
|
||||||
|
/* Flush first event, now do transition 2 or 3 */
|
||||||
|
bool paused = (flags & VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED) != 0;
|
||||||
|
|
||||||
|
start_flags |= paused ? VIR_QEMU_PROCESS_START_PAUSED : 0;
|
||||||
|
|
||||||
|
rc = qemuProcessStart(snapshot->domain->conn, driver, vm, NULL,
|
||||||
|
QEMU_ASYNC_JOB_START, NULL, -1, NULL, NULL,
|
||||||
|
VIR_NETDEV_VPORT_PROFILE_OP_CREATE,
|
||||||
|
start_flags);
|
||||||
|
virDomainAuditStart(vm, "from-snapshot", rc >= 0);
|
||||||
|
if (rc < 0) {
|
||||||
|
qemuDomainRemoveInactive(driver, vm);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
detail = VIR_DOMAIN_EVENT_STARTED_FROM_SNAPSHOT;
|
||||||
|
event = virDomainEventLifecycleNewFromObj(vm,
|
||||||
|
VIR_DOMAIN_EVENT_STARTED,
|
||||||
|
detail);
|
||||||
|
virObjectEventStateQueue(driver->domainEventState, event);
|
||||||
|
if (paused) {
|
||||||
|
detail = VIR_DOMAIN_EVENT_SUSPENDED_FROM_SNAPSHOT;
|
||||||
|
event2 = virDomainEventLifecycleNewFromObj(vm,
|
||||||
|
VIR_DOMAIN_EVENT_SUSPENDED,
|
||||||
|
detail);
|
||||||
|
virObjectEventStateQueue(driver->domainEventState, event2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return qemuSnapshotRevertWriteMetadata(vm, snap, driver, cfg, defined);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
qemuSnapshotRevert(virDomainObj *vm,
|
qemuSnapshotRevert(virDomainObj *vm,
|
||||||
virDomainSnapshotPtr snapshot,
|
virDomainSnapshotPtr snapshot,
|
||||||
|
@ -2162,15 +2240,10 @@ qemuSnapshotRevert(virDomainObj *vm,
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
virDomainMomentObj *snap = NULL;
|
virDomainMomentObj *snap = NULL;
|
||||||
virDomainSnapshotDef *snapdef;
|
virDomainSnapshotDef *snapdef;
|
||||||
virObjectEvent *event = NULL;
|
|
||||||
virObjectEvent *event2 = NULL;
|
|
||||||
int detail;
|
|
||||||
int rc;
|
|
||||||
g_autoptr(virDomainDef) config = NULL;
|
g_autoptr(virDomainDef) config = NULL;
|
||||||
g_autoptr(virDomainDef) inactiveConfig = NULL;
|
g_autoptr(virDomainDef) inactiveConfig = NULL;
|
||||||
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
|
g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
|
||||||
unsigned int start_flags = VIR_QEMU_PROCESS_START_GEN_VMID;
|
unsigned int start_flags = VIR_QEMU_PROCESS_START_GEN_VMID;
|
||||||
bool defined = false;
|
|
||||||
|
|
||||||
virCheckFlags(VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING |
|
virCheckFlags(VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING |
|
||||||
VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED |
|
VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED |
|
||||||
|
@ -2224,64 +2297,11 @@ qemuSnapshotRevert(virDomainObj *vm,
|
||||||
case VIR_DOMAIN_SNAPSHOT_SHUTDOWN:
|
case VIR_DOMAIN_SNAPSHOT_SHUTDOWN:
|
||||||
case VIR_DOMAIN_SNAPSHOT_SHUTOFF:
|
case VIR_DOMAIN_SNAPSHOT_SHUTOFF:
|
||||||
case VIR_DOMAIN_SNAPSHOT_CRASHED:
|
case VIR_DOMAIN_SNAPSHOT_CRASHED:
|
||||||
/* Transitions 1, 4, 7 */
|
ret = qemuSnapshotRevertInactive(vm, snapshot, snap,
|
||||||
/* Newer qemu -loadvm refuses to revert to the state of a snapshot
|
driver, cfg,
|
||||||
* created by qemu-img snapshot -c. If the domain is running, we
|
&inactiveConfig,
|
||||||
* must take it offline; then do the revert using qemu-img.
|
start_flags, flags);
|
||||||
*/
|
goto endjob;
|
||||||
|
|
||||||
if (virDomainObjIsActive(vm)) {
|
|
||||||
/* Transitions 4, 7 */
|
|
||||||
qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FROM_SNAPSHOT,
|
|
||||||
QEMU_ASYNC_JOB_START, 0);
|
|
||||||
virDomainAuditStop(vm, "from-snapshot");
|
|
||||||
detail = VIR_DOMAIN_EVENT_STOPPED_FROM_SNAPSHOT;
|
|
||||||
event = virDomainEventLifecycleNewFromObj(vm,
|
|
||||||
VIR_DOMAIN_EVENT_STOPPED,
|
|
||||||
detail);
|
|
||||||
virObjectEventStateQueue(driver->domainEventState, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (qemuSnapshotInternalRevertInactive(driver, vm, snap) < 0) {
|
|
||||||
qemuDomainRemoveInactive(driver, vm);
|
|
||||||
goto endjob;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inactiveConfig) {
|
|
||||||
virDomainObjAssignDef(vm, &inactiveConfig, false, NULL);
|
|
||||||
defined = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags & (VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING |
|
|
||||||
VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED)) {
|
|
||||||
/* Flush first event, now do transition 2 or 3 */
|
|
||||||
bool paused = (flags & VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED) != 0;
|
|
||||||
|
|
||||||
start_flags |= paused ? VIR_QEMU_PROCESS_START_PAUSED : 0;
|
|
||||||
|
|
||||||
rc = qemuProcessStart(snapshot->domain->conn, driver, vm, NULL,
|
|
||||||
QEMU_ASYNC_JOB_START, NULL, -1, NULL, NULL,
|
|
||||||
VIR_NETDEV_VPORT_PROFILE_OP_CREATE,
|
|
||||||
start_flags);
|
|
||||||
virDomainAuditStart(vm, "from-snapshot", rc >= 0);
|
|
||||||
if (rc < 0) {
|
|
||||||
qemuDomainRemoveInactive(driver, vm);
|
|
||||||
goto endjob;
|
|
||||||
}
|
|
||||||
detail = VIR_DOMAIN_EVENT_STARTED_FROM_SNAPSHOT;
|
|
||||||
event = virDomainEventLifecycleNewFromObj(vm,
|
|
||||||
VIR_DOMAIN_EVENT_STARTED,
|
|
||||||
detail);
|
|
||||||
virObjectEventStateQueue(driver->domainEventState, event);
|
|
||||||
if (paused) {
|
|
||||||
detail = VIR_DOMAIN_EVENT_SUSPENDED_FROM_SNAPSHOT;
|
|
||||||
event2 = virDomainEventLifecycleNewFromObj(vm,
|
|
||||||
VIR_DOMAIN_EVENT_SUSPENDED,
|
|
||||||
detail);
|
|
||||||
virObjectEventStateQueue(driver->domainEventState, event2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VIR_DOMAIN_SNAPSHOT_PMSUSPENDED:
|
case VIR_DOMAIN_SNAPSHOT_PMSUSPENDED:
|
||||||
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
|
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
|
||||||
|
@ -2301,8 +2321,6 @@ qemuSnapshotRevert(virDomainObj *vm,
|
||||||
goto endjob;
|
goto endjob;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = qemuSnapshotRevertWriteMetadata(vm, snap, driver, cfg, defined);
|
|
||||||
|
|
||||||
endjob:
|
endjob:
|
||||||
qemuProcessEndJob(driver, vm);
|
qemuProcessEndJob(driver, vm);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue