[libvirt] [PATCH v2 4/5] qemu: Wire up virDomainSuspendForDuration API

Michal Privoznik mprivozn at redhat.com
Thu Jan 26 19:59:46 UTC 2012


This makes use of QEMU guest agent to implement the
virDomainSuspendForDuration API.
---
 src/qemu/qemu_driver.c |   93 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 93 insertions(+), 0 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index ab69dca..277b152 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1457,6 +1457,98 @@ cleanup:
     return ret;
 }
 
+static int
+qemuDomainSuspendForDuration(virDomainPtr dom,
+                             unsigned int target,
+                             unsigned long long duration,
+                             unsigned int flags)
+{
+    struct qemud_driver *driver = dom->conn->privateData;
+    virDomainObjPtr vm;
+    int ret = -1;
+    qemuDomainObjPrivatePtr priv;
+    int agent_mode;
+
+    virCheckFlags(0, -1);
+
+    if (duration) {
+        qemuReportError(VIR_ERR_INVALID_ARG, "%s",
+                        _("Suspending for duration is not supported."));
+            return -1;
+    }
+
+    switch (target) {
+    case VIR_NODE_SUSPEND_TARGET_MEM:
+        agent_mode = QEMU_AGENT_SUSPEND_SLEEP;
+        break;
+    case VIR_NODE_SUSPEND_TARGET_DISK:
+        agent_mode = QEMU_AGENT_SUSPEND_HIBERNATE;
+        break;
+    case VIR_NODE_SUSPEND_TARGET_HYBRID:
+        agent_mode = QEMU_AGENT_SUSPEND_HYBRID;
+        break;
+    default:
+        qemuReportError(VIR_ERR_INVALID_ARG,
+                        _("Unsupported suspend target: %u"),
+                        target);
+        return -1;
+    }
+
+    qemuDriverLock(driver);
+    vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+    qemuDriverUnlock(driver);
+
+    if (!vm) {
+        char uuidstr[VIR_UUID_STRING_BUFLEN];
+        virUUIDFormat(dom->uuid, uuidstr);
+        qemuReportError(VIR_ERR_NO_DOMAIN,
+                        _("no domain with matching uuid '%s'"), uuidstr);
+        goto cleanup;
+    }
+
+    if (!virDomainObjIsActive(vm)) {
+        qemuReportError(VIR_ERR_OPERATION_INVALID,
+                        "%s", _("domain is not running"));
+        goto cleanup;
+    }
+
+    priv = vm->privateData;
+
+    if (!priv->agent) {
+        qemuReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+                        _("QEMU guest agent is not configured"));
+        goto cleanup;
+    }
+
+    if (priv->agentError) {
+        qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                        _("QEMU guest agent is not "
+                          "available due to an error"));
+        goto cleanup;
+    }
+
+    if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_SUSPEND) < 0)
+        goto cleanup;
+
+    if (!virDomainObjIsActive(vm)) {
+        qemuReportError(VIR_ERR_OPERATION_INVALID,
+                        "%s", _("domain is not running"));
+        goto endjob;
+    }
+
+    qemuDomainObjEnterAgent(driver, vm);
+    ret = qemuAgentSuspend(priv->agent, agent_mode);
+    qemuDomainObjExitAgent(driver, vm);
+
+endjob:
+    if (qemuDomainObjEndJob(driver, vm) == 0)
+        vm = NULL;
+
+cleanup:
+    if (vm)
+        virDomainObjUnlock(vm);
+    return ret;
+}
 
 static int qemudDomainResume(virDomainPtr dom) {
     struct qemud_driver *driver = dom->conn->privateData;
@@ -11761,6 +11853,7 @@ static virDriver qemuDriver = {
     .domainLookupByName = qemudDomainLookupByName, /* 0.2.0 */
     .domainSuspend = qemudDomainSuspend, /* 0.2.0 */
     .domainResume = qemudDomainResume, /* 0.2.0 */
+    .domainSuspendForDuration = qemuDomainSuspendForDuration, /* 0.9.10 */
     .domainShutdown = qemuDomainShutdown, /* 0.2.0 */
     .domainShutdownFlags = qemuDomainShutdownFlags, /* 0.9.10 */
     .domainReboot = qemuDomainReboot, /* 0.9.3 */
-- 
1.7.3.4




More information about the libvir-list mailing list