[libvirt] [PATCH 3/6] Support variable clock offset mode in QEMU
Daniel Veillard
veillard at redhat.com
Mon Mar 1 14:03:10 UTC 2010
On Thu, Feb 18, 2010 at 05:54:29PM +0000, Daniel P. Berrange wrote:
> 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 | 82 ++++++++++++++++++--
> src/qemu/qemu_conf.h | 1 +
> tests/qemuhelptest.c | 3 +-
> .../qemuxml2argv-clock-variable.args | 1 +
> .../qemuxml2argv-clock-variable.xml | 24 ++++++
> tests/qemuxml2argvtest.c | 4 +
> 6 files changed, 107 insertions(+), 8 deletions(-)
> create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-clock-variable.args
> create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-clock-variable.xml
>
> diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
> index a207fc7..112a7c2 100644
> --- a/src/qemu/qemu_conf.c
> +++ b/src/qemu/qemu_conf.c
> @@ -1155,6 +1155,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
> @@ -2969,6 +2972,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->adjustment;
> + gmtime_r(&now, &nowbits);
> +
> + virBufferVSprintf(&buf, "base=%d-%d-%dT%d:%d:%d",
> + nowbits.tm_year,
> + 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,
> @@ -3400,13 +3453,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 7041489..e32a3d7 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 0f2b509..619d7cc 100644
> --- a/tests/qemuhelptest.c
> +++ b/tests/qemuhelptest.c
> @@ -225,7 +225,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 0000000..09a9197
> --- /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 0000000..fa20b27
> --- /dev/null
> +++ b/tests/qemuxml2argvdata/qemuxml2argv-clock-variable.xml
> @@ -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>
> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
> index aa42f99..510176c 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);
ACK,
Daniel
--
Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/
daniel at veillard.com | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library http://libvirt.org/
More information about the libvir-list
mailing list