[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH] qemu driver: sync guest time via qemu-guest-agent when domain is resumed



Since QEMU commit "kvmclock: clock should count only if vm is running"
(http://lists.gnu.org/archive/html/qemu-devel/2013-06/msg01225.html), 
guests have their realtime clock stopped during pause.

To correct the situation, invoke guest agent to sync time from
host time.

Signed-off-by: Marcelo Tosatti <mtosatti redhat com>

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 8bcd98e..df01244 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -2695,6 +2695,40 @@ qemuProcessPrepareMonitorChr(virQEMUDriverConfigPtr cfg,
 }
 
 
+
+#include <sys/time.h>
+
+static void
+qemuAgentSyncGuestTime(virDomainObjPtr vm)
+{
+    int ret;
+    struct timeval tv;
+    char *result;
+    qemuDomainObjPrivatePtr priv;
+    char buf[500];
+
+    priv = vm->privateData;
+
+    ret = gettimeofday(&tv, NULL);
+    if (ret) {
+        virReportSystemError(errno, "%s", _("gettimeofday failure"));
+        return;
+    }
+
+    memset(buf, 0, sizeof(buf));
+
+    sprintf(buf, "{ \"execute\": \"guest-set-time\","
+                     "\"arguments\":{\"time\":%lld}}\" ",
+                    tv.tv_usec * 1000 + (tv.tv_sec * 1000000000LL));
+
+    qemuDomainObjEnterAgent(vm);
+    ret = qemuAgentArbitraryCommand(priv->agent, buf, &result,
+                                    VIR_DOMAIN_QEMU_AGENT_COMMAND_DEFAULT);
+    qemuDomainObjExitAgent(vm);
+    if (ret < 0)
+        VIR_FREE(result);
+}
+
 /*
  * Precondition: vm must be locked, and a job must be active.
  * This method will call {Enter,Exit}Monitor
@@ -2727,6 +2761,7 @@ qemuProcessStartCPUs(virQEMUDriverPtr driver, virDomainObjPtr vm,
 
     if (ret == 0) {
         virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, reason);
+        qemuAgentSyncGuestTime(vm);
     } else {
         if (virDomainLockProcessPause(driver->lockManager, vm, &priv->lockState) < 0)
             VIR_WARN("Unable to release lease on %s", vm->def->name);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]