
* Tomoki Sekiyama <tomoki.sekiyama@hds.com> wrote:
Adds an quiesced flag into qemuDomainObjPrivate that tracks whether guest filesystems of the domain is quiesced or not.
It also modify error code from qemuDomainSnapshotFSFreeze and qemuDomainSnapshotFSThaw, so that a caller can know whether the command is actually sent to the guest agent. If the error is caused before sending a freeze command, a counterpart thaw command shouldn't be sent either, not to thaw the guest unexpectedly by error handling code.
Signed-off-by: Tomoki Sekiyama <tomoki.sekiyama@hds.com> --- src/qemu/qemu_domain.c | 5 ++++ src/qemu/qemu_domain.h | 2 + src/qemu/qemu_driver.c | 66 +++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 60 insertions(+), 13 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 7d375e5..1fb1652 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -357,6 +357,9 @@ qemuDomainObjPrivateXMLFormat(virBufferPtr buf, void *data) virBufferAddLit(buf, "</devices>\n"); }
+ if (priv->quiesced) + virBufferAddLit(buf, "<quiesced/>\n"); + return 0; }
@@ -518,6 +521,8 @@ qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt, void *data) } VIR_FREE(nodes);
+ priv->quiesced = virXPathBoolean("boolean(./quiesced)", ctxt) == 1; + return 0;
error: diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index b2830c4..5fb1665 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -176,6 +176,8 @@ struct _qemuDomainObjPrivate { char **qemuDevices; /* NULL-terminated list of devices aliases known to QEMU */
bool hookRun; /* true if there was a hook run over this domain */ + + bool quiesced; /* true if the domain filesystems are quiesced */ };
typedef enum { diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 2707bec..bd469ba 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -12005,31 +12005,60 @@ cleanup: }
+/* Return -1 if request is not sent to agent due to misconfig, -2 if request + * is sent but failed, and number of frozen filesystems on success. */ static int -qemuDomainSnapshotFSFreeze(virDomainObjPtr vm) { +qemuDomainSnapshotFSFreeze(virQEMUDriverPtr driver, virDomainObjPtr vm) { qemuDomainObjPrivatePtr priv = vm->privateData; + virQEMUDriverConfigPtr cfg; int freezed;
if (!qemuDomainAgentAvailable(priv, true)) return -1;
+ if (priv->quiesced) { + virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("domain is already quiesced")); + return -1; + } + qemuDomainObjEnterAgent(vm); freezed = qemuAgentFSFreeze(priv->agent); qemuDomainObjExitAgent(vm);
- return freezed; + if (freezed >= 0) + priv->quiesced = true; + + cfg = virQEMUDriverGetConfig(driver); + if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0) { + virObjectUnref(cfg); + return -2; + } + virObjectUnref(cfg); + + return freezed < 0 ? -2 : freezed; }
+/* Return -1 if request is not sent to agent due to misconfig, -2 if request + * is send but failed, and number of thawed filesystems on success. */ static int -qemuDomainSnapshotFSThaw(virDomainObjPtr vm, bool report) +qemuDomainSnapshotFSThaw(virQEMUDriverPtr driver, + virDomainObjPtr vm, bool report) { qemuDomainObjPrivatePtr priv = vm->privateData; + virQEMUDriverConfigPtr cfg; int thawed; virErrorPtr err = NULL;
if (!qemuDomainAgentAvailable(priv, report)) return -1;
+ if (!priv->quiesced && report) { + virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("domain is not quiesced")); + return -1; + } + qemuDomainObjEnterAgent(vm); if (!report) err = virSaveLastError(); @@ -12038,8 +12067,18 @@ qemuDomainSnapshotFSThaw(virDomainObjPtr vm, bool report) virSetError(err); qemuDomainObjExitAgent(vm);
+ if (thawed >= 0) + priv->quiesced = false; + + cfg = virQEMUDriverGetConfig(driver); + if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0) { + virObjectUnref(cfg); + return -2; + } + virObjectUnref(cfg); + virFreeError(err); - return thawed; + return thawed < 0 ? -2 : thawed; }
/* The domain is expected to be locked and inactive. */ @@ -13014,17 +13053,18 @@ qemuDomainSnapshotCreateActiveExternal(virConnectPtr conn, goto cleanup;
/* If quiesce was requested, then issue a freeze command, and a - * counterpart thaw command, no matter what. The command will - * fail if the guest is paused or the guest agent is not - * running. */ + * counterpart thaw command when the it is actually sent to agent.
Small typo "the it is". It appears a rebase is in order, at least the 3rd patch in the set will not apply cleanly without intervention - but it's an easy fix. I'll test these tomorrow and report results. Thanks for this patch. -- Jon