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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index a8e1cb2400..0b2cb0bb2f 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -276,6 +276,7 @@ mymain(void)
DO_TEST_NOCAPS("clock-timer-hyperv-rtc");
DO_TEST_CAPS_ARCH_LATEST("clock-timer-armvtimer", "aarch64");
DO_TEST_NOCAPS("clock-realtime");
+ DO_TEST_CAPS_LATEST("clock-absolute");
DO_TEST_NOCAPS("cpu-eoi-disabled");
DO_TEST_NOCAPS("cpu-eoi-enabled");