提交 339bdd99 编写于 作者: E Eric Blake

snapshot: fix state after external snapshot of S3 domain

https://bugzilla.redhat.com/show_bug.cgi?id=876829 complains that
if a guest is put into S3 state (such as via virsh dompmsuspend)
and then an external snapshot is taken, qemu forcefully transitions
the domain to paused, but libvirt doesn't reflect that change
internally.  Thus, a user has to use 'virsh suspend' to get libvirt
back in sync with qemu state, and if the user doesn't know this
trick, then the guest appears hung.

* src/qemu/qemu_driver.c (qemuDomainSnapshotCreateActiveExternal):
Track fact that qemu wakes up a suspended domain on migration.
上级 678e8913
/* /*
* qemu_driver.c: core driver methods for managing qemu guests * qemu_driver.c: core driver methods for managing qemu guests
* *
* Copyright (C) 2006-2012 Red Hat, Inc. * Copyright (C) 2006-2013 Red Hat, Inc.
* Copyright (C) 2006 Daniel P. Berrange * Copyright (C) 2006 Daniel P. Berrange
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
...@@ -11128,6 +11128,7 @@ qemuDomainSnapshotCreateActiveExternal(virConnectPtr conn, ...@@ -11128,6 +11128,7 @@ qemuDomainSnapshotCreateActiveExternal(virConnectPtr conn,
bool atomic = !!(flags & VIR_DOMAIN_SNAPSHOT_CREATE_ATOMIC); bool atomic = !!(flags & VIR_DOMAIN_SNAPSHOT_CREATE_ATOMIC);
bool transaction = qemuCapsGet(priv->caps, QEMU_CAPS_TRANSACTION); bool transaction = qemuCapsGet(priv->caps, QEMU_CAPS_TRANSACTION);
int thaw = 0; /* 1 if freeze succeeded, -1 if freeze failed */ int thaw = 0; /* 1 if freeze succeeded, -1 if freeze failed */
bool pmsuspended = false;
if (qemuDomainObjBeginAsyncJobWithDriver(driver, vm, if (qemuDomainObjBeginAsyncJobWithDriver(driver, vm,
QEMU_ASYNC_JOB_SNAPSHOT) < 0) QEMU_ASYNC_JOB_SNAPSHOT) < 0)
...@@ -11147,8 +11148,11 @@ qemuDomainSnapshotCreateActiveExternal(virConnectPtr conn, ...@@ -11147,8 +11148,11 @@ qemuDomainSnapshotCreateActiveExternal(virConnectPtr conn,
} }
} }
/* we need to resume the guest only if it was previously running */ /* We need to track what state the guest is in, since taking the
if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) { * snapshot may alter that state and we must restore it later. */
if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PMSUSPENDED) {
pmsuspended = true;
} else if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_RUNNING) {
resume = true; resume = true;
/* For external checkpoints (those with memory), the guest /* For external checkpoints (those with memory), the guest
...@@ -11230,6 +11234,18 @@ qemuDomainSnapshotCreateActiveExternal(virConnectPtr conn, ...@@ -11230,6 +11234,18 @@ qemuDomainSnapshotCreateActiveExternal(virConnectPtr conn,
vm = NULL; vm = NULL;
if (event) if (event)
qemuDomainEventQueue(driver, event); qemuDomainEventQueue(driver, event);
} else if (memory && pmsuspended) {
/* qemu 1.3 is unable to save a domain in pm-suspended (S3)
* state; so we must emit an event stating that it was
* converted to paused. */
virDomainEventPtr event;
virDomainObjSetState(vm, VIR_DOMAIN_PAUSED,
VIR_DOMAIN_PAUSED_FROM_SNAPSHOT);
event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_SUSPENDED,
VIR_DOMAIN_EVENT_SUSPENDED_FROM_SNAPSHOT);
if (event)
qemuDomainEventQueue(driver, event);
} }
ret = 0; ret = 0;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册