diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 8d5960e3e8..a6a9d75766 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -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) && diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index c8757c53a1..1821252d62 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -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 */ diff --git a/tests/qemuhelptest.c b/tests/qemuhelptest.c index ad355d7eb9..e61f4e2de7 100644 --- a/tests/qemuhelptest.c +++ b/tests/qemuhelptest.c @@ -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 index 0000000000..09a91979e6 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-clock-variable.args @@ -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 index 0000000000..fa20b27374 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-clock-variable.xml @@ -0,0 +1,24 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219200 + 219200 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu + + + +
+ + + + diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index a8c9ed3ff0..6525daec94 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -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);