]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
Support variable clock offset mode in QEMU
authorDaniel P. Berrange <berrange@redhat.com>
Tue, 2 Feb 2010 18:07:12 +0000 (18:07 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Mon, 1 Mar 2010 18:41:40 +0000 (18:41 +0000)
This allows QEMU guests to be started with an arbitrary clock
offset

The test case can't actually be enabled, since QEMU argv expects
an absolute timestring, and this will obviously change every
time the test runs :-( Hopefully QEMU will allow a relative
time offset in the future.

* src/qemu/qemu_conf.c, src/qemu/qemu_conf.h: Use the -rtc arg
  if available to support variable clock offset mode
* tests/qemuhelptest.c: Add QEMUD_CMD_FLAG_RTC for qemu 0.12.1
* qemuxml2argvdata/qemuxml2argv-clock-variable.args,
  qemuxml2argvdata/qemuxml2argv-clock-variable.xml,
  qemuxml2argvtest.c: Test case, except we can't actually enable
  it yet.

src/qemu/qemu_conf.c
src/qemu/qemu_conf.h
tests/qemuhelptest.c
tests/qemuxml2argvdata/qemuxml2argv-clock-variable.args [new file with mode: 0644]
tests/qemuxml2argvdata/qemuxml2argv-clock-variable.xml [new file with mode: 0644]
tests/qemuxml2argvtest.c

index 8d5960e3e8b5268d0f5c1301bb0e31a17762c122..a6a9d757666c49143afa98942578fece08790085 100644 (file)
@@ -1156,6 +1156,9 @@ static unsigned long long qemudComputeCmdFlags(const char *help,
         flags |= QEMUD_CMD_FLAG_BALLOON;
     if (strstr(help, "-device"))
         flags |= QEMUD_CMD_FLAG_DEVICE;
+    /* The trailing ' ' is important to avoid a bogus match */
+    if (strstr(help, "-rtc "))
+        flags |= QEMUD_CMD_FLAG_RTC;
     /* Keep disabled till we're actually ready to turn on netdev mode
      * The plan is todo it in 0.13.0 QEMU, but lets wait & see... */
 #if 0
@@ -3057,6 +3060,56 @@ error:
 }
 
 
+static char *
+qemuBuildClockArgStr(virDomainClockDefPtr def)
+{
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+    switch (def->offset) {
+    case VIR_DOMAIN_CLOCK_OFFSET_UTC:
+        virBufferAddLit(&buf, "base=utc");
+        break;
+
+    case VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME:
+        virBufferAddLit(&buf, "base=localtime");
+        break;
+
+    case VIR_DOMAIN_CLOCK_OFFSET_VARIABLE: {
+        time_t now = time(NULL);
+        struct tm nowbits;
+
+        now += def->data.adjustment;
+        gmtime_r(&now, &nowbits);
+
+        virBufferVSprintf(&buf, "base=%d-%d-%dT%d:%d:%d",
+                          nowbits.tm_year + 1900,
+                          nowbits.tm_mon,
+                          nowbits.tm_mday,
+                          nowbits.tm_hour,
+                          nowbits.tm_min,
+                          nowbits.tm_sec);
+    }   break;
+
+    default:
+        qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                        _("unsupported clock offset '%s'"),
+                        virDomainClockOffsetTypeToString(def->offset));
+        goto error;
+    }
+
+    if (virBufferError(&buf)) {
+        virReportOOMError();
+        goto error;
+    }
+
+    return virBufferContentAndReset(&buf);
+
+error:
+    virBufferFreeAndReset(&buf);
+    return NULL;
+}
+
+
 static int
 qemuBuildCpuArgStr(const struct qemud_driver *driver,
                    const virDomainDefPtr def,
@@ -3488,13 +3541,28 @@ int qemudBuildCommandLine(virConnectPtr conn,
         }
     }
 
-    if (def->clock.offset == VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME)
-        ADD_ARG_LIT("-localtime");
-    else if (def->clock.offset != VIR_DOMAIN_CLOCK_OFFSET_UTC) {
-        qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                        _("unsupported clock offset '%s'"),
-                        virDomainClockOffsetTypeToString(def->clock.offset));
-        goto error;
+    if (qemuCmdFlags & QEMUD_CMD_FLAG_RTC) {
+        const char *rtcopt;
+        ADD_ARG_LIT("-rtc");
+        if (!(rtcopt = qemuBuildClockArgStr(&def->clock)))
+            goto error;
+        ADD_ARG(rtcopt);
+    } else {
+        switch (def->clock.offset) {
+        case VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME:
+            ADD_ARG_LIT("-localtime");
+            break;
+
+        case VIR_DOMAIN_CLOCK_OFFSET_UTC:
+            /* Nothing, its the default */
+            break;
+
+        default:
+            qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                            _("unsupported clock offset '%s'"),
+                            virDomainClockOffsetTypeToString(def->clock.offset));
+            goto error;
+        }
     }
 
     if ((qemuCmdFlags & QEMUD_CMD_FLAG_NO_REBOOT) &&
index c8757c53a1ef468fd74769673146e6dc56ee3294..1821252d6232266a71ade8a066ba4de438c8a609 100644 (file)
@@ -82,6 +82,7 @@ enum qemud_cmd_flags {
     QEMUD_CMD_FLAG_SDL           = (1 << 27), /* Is the new -sdl arg available */
     QEMUD_CMD_FLAG_SMP_TOPOLOGY  = (1 << 28), /* Is sockets=s,cores=c,threads=t available for -smp? */
     QEMUD_CMD_FLAG_NETDEV        = (1 << 29), /* The -netdev flag & netdev_add/remove monitor commands */
+    QEMUD_CMD_FLAG_RTC           = (1 << 30), /* The -rtc flag for clock options */
 };
 
 /* Main driver state */
index ad355d7eb965a22eca6b4a14e4f4cee4c27c35d6..e61f4e2de7edfc60504e16928046c11961da29d4 100644 (file)
@@ -226,7 +226,8 @@ mymain(int argc, char **argv)
             QEMUD_CMD_FLAG_CHARDEV |
             QEMUD_CMD_FLAG_BALLOON |
             QEMUD_CMD_FLAG_DEVICE |
-            QEMUD_CMD_FLAG_SMP_TOPOLOGY,
+            QEMUD_CMD_FLAG_SMP_TOPOLOGY |
+            QEMUD_CMD_FLAG_RTC,
             12001, 0,  0);
 
     return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-clock-variable.args b/tests/qemuxml2argvdata/qemuxml2argv-clock-variable.args
new file mode 100644 (file)
index 0000000..09a9197
--- /dev/null
@@ -0,0 +1 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -rtc base=2010-2-2T18:22:10 -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -usb
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-clock-variable.xml b/tests/qemuxml2argvdata/qemuxml2argv-clock-variable.xml
new file mode 100644 (file)
index 0000000..fa20b27
--- /dev/null
@@ -0,0 +1,24 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory>219200</memory>
+  <currentMemory>219200</currentMemory>
+  <vcpu>1</vcpu>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='variable' adjustment='123456'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu</emulator>
+    <disk type='block' device='disk'>
+      <source dev='/dev/HostVG/QEMUGuest1'/>
+      <target dev='hda' bus='ide'/>
+      <address type='drive' controller='0' bus='0' unit='0'/>
+    </disk>
+    <controller type='ide' index='0'/>
+  </devices>
+</domain>
index a8c9ed3ff097d68848e4d380fc686c9a34db591a..6525daec94ef171999fa872f5e8e8f6dd6fc9bc8 100644 (file)
@@ -226,6 +226,10 @@ mymain(int argc, char **argv)
     DO_TEST("bootloader", QEMUD_CMD_FLAG_DOMID);
     DO_TEST("clock-utc", 0);
     DO_TEST("clock-localtime", 0);
+    /*
+     * Can't be enabled since the absolute timestamp changes every time
+    DO_TEST("clock-variable", QEMUD_CMD_FLAG_RTC);
+    */
     DO_TEST("hugepages", QEMUD_CMD_FLAG_MEM_PATH);
     DO_TEST("disk-cdrom", 0);
     DO_TEST("disk-cdrom-empty", QEMUD_CMD_FLAG_DRIVE);