]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
conf: Introduce 'absolute' clock offset
authorPeter Krempa <pkrempa@redhat.com>
Tue, 26 Apr 2022 15:00:36 +0000 (17:00 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Tue, 17 May 2022 17:30:59 +0000 (19:30 +0200)
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 <pkrempa@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
docs/formatdomain.rst
src/conf/domain_conf.c
src/conf/domain_conf.h
src/conf/schemas/domaincommon.rng
src/libxl/libxl_conf.c
tests/qemuxml2argvdata/clock-absolute.xml [new file with mode: 0644]
tests/qemuxml2xmloutdata/clock-absolute.x86_64-latest.xml [new file with mode: 0644]
tests/qemuxml2xmltest.c

index c1e99951a6558355d96e7d57a8463467f39e6dbe..c132d2abbb27fec13aa9b07a2bc8ced1d3147c16 100644 (file)
@@ -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`
index 70562cc9935727b5c18e78a6926f32e07cb47abe..1167e06f09d1e2dcac345a3d7da2647c24299d54 100644 (file)
@@ -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++) {
index 2e2da0c69c3be36450a98c5cddc857828f85fe69..4e9790b3856da940e3c0fe73bc06b8f4f9e3bcb1 100644 (file)
@@ -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;
index 2544864eb46f82ab367a9dc2cb0045861011f637..35c973c354b4eea47c8fa6f943ce11f18639305d 100644 (file)
               </attribute>
             </optional>
           </group>
+          <group>
+            <attribute name="offset">
+              <value>absolute</value>
+            </attribute>
+            <attribute name="start">
+              <ref name="unsignedInt"/>
+            </attribute>
+          </group>
         </choice>
         <zeroOrMore>
           <ref name="timer"/>
index e5fe209718edf62c3c7d5513a10cf0b2397b4e4a..a96dd09e809dd21e1d00d686f0a6c8cbcda4ec3b 100644 (file)
@@ -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 (file)
index 0000000..e79f53e
--- /dev/null
@@ -0,0 +1,30 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>219100</memory>
+  <currentMemory unit='KiB'>219100</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='x86_64' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='absolute' start='1234'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-system-x86_64</emulator>
+    <disk type='block' device='disk'>
+      <driver name='qemu' type='raw'/>
+      <source dev='/dev/HostVG/QEMUGuest1'/>
+      <target dev='hda' bus='ide'/>
+      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+    </disk>
+    <controller type='usb' index='0'/>
+    <controller type='ide' index='0'/>
+    <controller type='pci' index='0' model='pci-root'/>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <memballoon model='none'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2xmloutdata/clock-absolute.x86_64-latest.xml b/tests/qemuxml2xmloutdata/clock-absolute.x86_64-latest.xml
new file mode 100644 (file)
index 0000000..b313a74
--- /dev/null
@@ -0,0 +1,38 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>219100</memory>
+  <currentMemory unit='KiB'>219100</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='x86_64' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <cpu mode='custom' match='exact' check='none'>
+    <model fallback='forbid'>qemu64</model>
+  </cpu>
+  <clock offset='absolute' start='1234'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-system-x86_64</emulator>
+    <disk type='block' device='disk'>
+      <driver name='qemu' type='raw'/>
+      <source dev='/dev/HostVG/QEMUGuest1'/>
+      <target dev='hda' bus='ide'/>
+      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+    </disk>
+    <controller type='usb' index='0' model='piix3-uhci'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
+    </controller>
+    <controller type='ide' index='0'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
+    </controller>
+    <controller type='pci' index='0' model='pci-root'/>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <audio id='1' type='none'/>
+    <memballoon model='none'/>
+  </devices>
+</domain>
index a8e1cb240082431cfcf875b6ad8db1f721adf9f4..0b2cb0bb2f2bd12fb6b42bca7eec3441d87c261e 100644 (file)
@@ -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");