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@xxxxxxxxxxxx | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/ -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list