From d53e75aad06074446851134e8aeaa5b97062c830 Mon Sep 17 00:00:00 2001 From: Peter Krempa Date: Tue, 26 Apr 2022 17:00:36 +0200 Subject: [PATCH] conf: Introduce 'absolute' clock offset The 'absolute' clock offset type has a 'start' attribute which is an unix epoch timestamp to which the hardware clock is always set at start of the VM. This is useful if some VM needs to be kept set to an arbitrary time for e.g. testing or working around broken software. Signed-off-by: Peter Krempa Reviewed-by: Michal Privoznik --- docs/formatdomain.rst | 5 +++ src/conf/domain_conf.c | 13 +++++++ src/conf/domain_conf.h | 4 ++ src/conf/schemas/domaincommon.rng | 8 ++++ src/libxl/libxl_conf.c | 1 + tests/qemuxml2argvdata/clock-absolute.xml | 30 +++++++++++++++ .../clock-absolute.x86_64-latest.xml | 38 +++++++++++++++++++ tests/qemuxml2xmltest.c | 1 + 8 files changed, 100 insertions(+) create mode 100644 tests/qemuxml2argvdata/clock-absolute.xml create mode 100644 tests/qemuxml2xmloutdata/clock-absolute.x86_64-latest.xml diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index c1e99951a6..c132d2abbb 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -2170,6 +2170,11 @@ Windows, however, expects it to be in so called 'localtime'. the RTC adjustments are lost at each reboot. :since:`Since 0.7.7` :since:`Since 0.9.11` the ``basis`` attribute can be either 'utc' (default) or 'localtime'. + ``absolute`` + The guest clock will be always set to the value of the ``start`` + attribute at startup of the domain. The ``start`` attribute takes an + epoch timestamp. + :since:`Since 8.4.0`. A ``clock`` may have zero or more ``timer`` sub-elements. :since:`Since 0.8.0` diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 70562cc993..1167e06f09 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1172,6 +1172,7 @@ VIR_ENUM_IMPL(virDomainClockOffset, "localtime", "variable", "timezone", + "absolute", ); VIR_ENUM_IMPL(virDomainClockBasis, @@ -19459,6 +19460,15 @@ virDomainDefClockParse(virDomainDef *def, return -1; } break; + + case VIR_DOMAIN_CLOCK_OFFSET_ABSOLUTE: + if (virXPathULongLong("number(./clock/@start)", ctxt, + &def->clock.data.starttime) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("missing 'start' attribute for clock with offset='absolute'")); + return -1; + } + break; } if ((n = virXPathNodeSet("./clock/timer", ctxt, &nodes)) < 0) @@ -26263,6 +26273,9 @@ virDomainClockDefFormat(virBuffer *buf, case VIR_DOMAIN_CLOCK_OFFSET_TIMEZONE: virBufferEscapeString(&clockAttr, " timezone='%s'", def->data.timezone); break; + case VIR_DOMAIN_CLOCK_OFFSET_ABSOLUTE: + virBufferAsprintf(&clockAttr, " start='%llu'", def->data.starttime); + break; } for (n = 0; n < def->ntimers; n++) { diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 2e2da0c69c..4e9790b385 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2453,6 +2453,7 @@ typedef enum { VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME = 1, VIR_DOMAIN_CLOCK_OFFSET_VARIABLE = 2, VIR_DOMAIN_CLOCK_OFFSET_TIMEZONE = 3, + VIR_DOMAIN_CLOCK_OFFSET_ABSOLUTE = 4, VIR_DOMAIN_CLOCK_OFFSET_LAST } virDomainClockOffsetType; @@ -2487,6 +2488,9 @@ struct _virDomainClockDef { /* Timezone name, when * offset == VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME */ char *timezone; + + /* absolute clock start time for VIR_DOMAIN_CLOCK_OFFSET_ABSOLUTE */ + unsigned long long starttime; } data; size_t ntimers; diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng index 2544864eb4..35c973c354 100644 --- a/src/conf/schemas/domaincommon.rng +++ b/src/conf/schemas/domaincommon.rng @@ -1252,6 +1252,14 @@ + + + absolute + + + + + diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c index e5fe209718..a96dd09e80 100644 --- a/src/libxl/libxl_conf.c +++ b/src/libxl/libxl_conf.c @@ -391,6 +391,7 @@ libxlMakeDomBuildInfo(virDomainDef *def, virDomainClockOffsetTypeToString(clock.offset)); return -1; + case VIR_DOMAIN_CLOCK_OFFSET_ABSOLUTE: case VIR_DOMAIN_CLOCK_OFFSET_LAST: default: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, diff --git a/tests/qemuxml2argvdata/clock-absolute.xml b/tests/qemuxml2argvdata/clock-absolute.xml new file mode 100644 index 0000000000..e79f53ed3c --- /dev/null +++ b/tests/qemuxml2argvdata/clock-absolute.xml @@ -0,0 +1,30 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219100 + 219100 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu-system-x86_64 + + + + +
+ + + + + + + + + diff --git a/tests/qemuxml2xmloutdata/clock-absolute.x86_64-latest.xml b/tests/qemuxml2xmloutdata/clock-absolute.x86_64-latest.xml new file mode 100644 index 0000000000..b313a74039 --- /dev/null +++ b/tests/qemuxml2xmloutdata/clock-absolute.x86_64-latest.xml @@ -0,0 +1,38 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219100 + 219100 + 1 + + hvm + + + + qemu64 + + + destroy + restart + destroy + + /usr/bin/qemu-system-x86_64 + + + + +
+ + +
+ + +
+ + + + +