]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: command: move virDomainClockDef validation to qemu_domain.c
authorDaniel Henrique Barboza <danielhb413@gmail.com>
Mon, 9 Dec 2019 23:15:21 +0000 (20:15 -0300)
committerCole Robinson <crobinso@redhat.com>
Mon, 16 Dec 2019 22:51:03 +0000 (17:51 -0500)
@def->clock validation is done by qemuBuildClockCommandLine() and
qemuBuildClockArgStr(). This patch centralize the validation done
in both these functions to a new qemuDomainDefValidateClockTimers()
function. This new function is then called by qemuDomainDefValidate(),
promoting clock validation in domain define time.

Tests were adapted to consider the new caps being needed in
this earlier stage.

Reviewed-by: Cole Robinson <crobinso@redhat.com>
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
src/qemu/qemu_command.c
src/qemu/qemu_domain.c
tests/qemuxml2xmltest.c

index 90f5f5642ca0a626655b0dd7decc08584d50ca15..e94c977e85969641c56c2ce8f7f483938dbecc4f 100644 (file)
@@ -6154,9 +6154,6 @@ qemuBuildClockArgStr(virDomainClockDefPtr def)
             case -1: /* unspecified - use hypervisor default */
                 break;
             case VIR_DOMAIN_TIMER_TRACK_BOOT:
-                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                               _("unsupported rtc timer track '%s'"),
-                               virDomainTimerTrackTypeToString(def->timers[i]->track));
                 return NULL;
             case VIR_DOMAIN_TIMER_TRACK_GUEST:
                 virBufferAddLit(&buf, ",clock=vm");
@@ -6178,9 +6175,6 @@ qemuBuildClockArgStr(virDomainClockDefPtr def)
                 break;
             case VIR_DOMAIN_TIMER_TICKPOLICY_MERGE:
             case VIR_DOMAIN_TIMER_TICKPOLICY_DISCARD:
-                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                               _("unsupported rtc timer tickpolicy '%s'"),
-                               virDomainTimerTickpolicyTypeToString(def->timers[i]->tickpolicy));
                 return NULL;
             }
             break; /* no need to check other timers - there is only one rtc */
@@ -6215,9 +6209,8 @@ qemuBuildClockCommandLine(virCommandPtr cmd,
     for (i = 0; i < def->clock.ntimers; i++) {
         switch ((virDomainTimerNameType)def->clock.timers[i]->name) {
         case VIR_DOMAIN_TIMER_NAME_PLATFORM:
-            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                           _("unsupported timer type (name) '%s'"),
-                           virDomainTimerNameTypeToString(def->clock.timers[i]->name));
+            /* qemuDomainDefValidateClockTimers will handle this
+             * error condition  */
             return -1;
 
         case VIR_DOMAIN_TIMER_NAME_TSC:
@@ -6228,7 +6221,7 @@ qemuBuildClockCommandLine(virCommandPtr cmd,
             break;
 
         case VIR_DOMAIN_TIMER_NAME_RTC:
-            /* Already handled in qemuBuildClockArgStr */
+            /* Already handled in qemuDomainDefValidateClockTimers */
             break;
 
         case VIR_DOMAIN_TIMER_NAME_PIT:
@@ -6242,15 +6235,8 @@ qemuBuildClockCommandLine(virCommandPtr cmd,
                                          "kvm-pit.lost_tick_policy=delay", NULL);
                 break;
             case VIR_DOMAIN_TIMER_TICKPOLICY_CATCHUP:
-                if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM_PIT_TICK_POLICY)) {
-                    /* do nothing - this is default for kvm-pit */
-                } else {
-                    /* can't catchup if we don't have kvm-pit */
-                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                                   _("unsupported pit tickpolicy '%s'"),
-                                   virDomainTimerTickpolicyTypeToString(def->clock.timers[i]->tickpolicy));
-                    return -1;
-                }
+                /* Do nothing - qemuDomainDefValidateClockTimers handled
+                 * the possible error condition here. */
                 break;
             case VIR_DOMAIN_TIMER_TICKPOLICY_DISCARD:
                 if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM_PIT_TICK_POLICY))
@@ -6259,9 +6245,6 @@ qemuBuildClockCommandLine(virCommandPtr cmd,
                 break;
             case VIR_DOMAIN_TIMER_TICKPOLICY_MERGE:
                 /* no way to support this mode for pit in qemu */
-                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                               _("unsupported pit tickpolicy '%s'"),
-                               virDomainTimerTickpolicyTypeToString(def->clock.timers[i]->tickpolicy));
                 return -1;
             }
             break;
@@ -6277,14 +6260,6 @@ qemuBuildClockCommandLine(virCommandPtr cmd,
             if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NO_HPET)) {
                 if (def->clock.timers[i]->present == 0)
                     virCommandAddArg(cmd, "-no-hpet");
-            } else {
-                /* no hpet timer available. The only possible action
-                   is to raise an error if present="yes" */
-                if (def->clock.timers[i]->present == 1) {
-                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                                   "%s", _("hpet timer is not supported"));
-                    return -1;
-                }
             }
             break;
         }
index 9b4882df969fa02ff76dee129577ef7067c63ba6..3fc09dc4a5ada49bec5c991d58a604acd0d09ae4 100644 (file)
@@ -5366,6 +5366,103 @@ qemuDomainDeviceDefValidateHub(virDomainHubDefPtr hub,
 }
 
 
+static int
+qemuDomainDefValidateClockTimers(const virDomainDef *def,
+                                 virQEMUCapsPtr qemuCaps)
+{
+    size_t i;
+
+    for (i = 0; i < def->clock.ntimers; i++) {
+        virDomainTimerDefPtr timer = def->clock.timers[i];
+
+        switch ((virDomainTimerNameType)timer->name) {
+        case VIR_DOMAIN_TIMER_NAME_PLATFORM:
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           _("unsupported timer type (name) '%s'"),
+                           virDomainTimerNameTypeToString(timer->name));
+            return -1;
+
+        case VIR_DOMAIN_TIMER_NAME_TSC:
+        case VIR_DOMAIN_TIMER_NAME_KVMCLOCK:
+        case VIR_DOMAIN_TIMER_NAME_HYPERVCLOCK:
+        case VIR_DOMAIN_TIMER_NAME_LAST:
+            break;
+
+        case VIR_DOMAIN_TIMER_NAME_RTC:
+            switch (timer->track) {
+            case -1: /* unspecified - use hypervisor default */
+            case VIR_DOMAIN_TIMER_TRACK_GUEST:
+            case VIR_DOMAIN_TIMER_TRACK_WALL:
+                break;
+            case VIR_DOMAIN_TIMER_TRACK_BOOT:
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                               _("unsupported rtc timer track '%s'"),
+                               virDomainTimerTrackTypeToString(timer->track));
+                return -1;
+            }
+
+            switch (timer->tickpolicy) {
+            case -1:
+            case VIR_DOMAIN_TIMER_TICKPOLICY_DELAY:
+                /* This is the default - missed ticks delivered when
+                   next scheduled, at normal rate */
+                break;
+            case VIR_DOMAIN_TIMER_TICKPOLICY_CATCHUP:
+                /* deliver ticks at a faster rate until caught up */
+                break;
+            case VIR_DOMAIN_TIMER_TICKPOLICY_MERGE:
+            case VIR_DOMAIN_TIMER_TICKPOLICY_DISCARD:
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                               _("unsupported rtc timer tickpolicy '%s'"),
+                               virDomainTimerTickpolicyTypeToString(
+                                   timer->tickpolicy));
+                return -1;
+            }
+            break;
+
+        case VIR_DOMAIN_TIMER_NAME_PIT:
+            switch (timer->tickpolicy) {
+            case -1:
+            case VIR_DOMAIN_TIMER_TICKPOLICY_DELAY:
+            case VIR_DOMAIN_TIMER_TICKPOLICY_DISCARD:
+                break;
+            case VIR_DOMAIN_TIMER_TICKPOLICY_CATCHUP:
+                if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM_PIT_TICK_POLICY)) {
+                    /* can't catchup if we don't have kvm-pit */
+                    virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                                   _("unsupported pit tickpolicy '%s'"),
+                                   virDomainTimerTickpolicyTypeToString(
+                                       timer->tickpolicy));
+                    return -1;
+                }
+                break;
+            case VIR_DOMAIN_TIMER_TICKPOLICY_MERGE:
+                /* no way to support this mode for pit in qemu */
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                               _("unsupported pit tickpolicy '%s'"),
+                               virDomainTimerTickpolicyTypeToString(
+                                   timer->tickpolicy));
+                return -1;
+            }
+            break;
+
+        case VIR_DOMAIN_TIMER_NAME_HPET:
+            /* no hpet timer available. The only possible action
+              is to raise an error if present="yes" */
+            if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_NO_HPET) &&
+                timer->present == 1) {
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                               "%s", _("hpet timer is not supported"));
+                return -1;
+            }
+            break;
+        }
+    }
+
+    return 0;
+}
+
+
 static int
 qemuDomainDefValidate(const virDomainDef *def,
                       void *opaque)
@@ -5479,6 +5576,9 @@ qemuDomainDefValidate(const virDomainDef *def,
         }
     }
 
+    if (qemuDomainDefValidateClockTimers(def, qemuCaps) < 0)
+        goto cleanup;
+
     /* QEMU 2.7 (detected via the availability of query-hotpluggable-cpus)
      * enforces stricter rules than previous versions when it comes to guest
      * CPU topology. Verify known constraints are respected */
index 17519b865798f4da7836e29e183fb006b7726009..5e4766567aa999222f7f9e939184dd6218f00fdd 100644 (file)
@@ -266,7 +266,7 @@ mymain(void)
     DO_TEST("cpu-host-kvmclock", NONE);
     DO_TEST("cpu-host-passthrough-features", NONE);
     DO_TEST("cpu-host-model-features", NONE);
-    DO_TEST("clock-catchup", NONE);
+    DO_TEST("clock-catchup", QEMU_CAPS_KVM_PIT_TICK_POLICY);
     DO_TEST("kvmclock", NONE);
     DO_TEST("clock-timer-hyperv-rtc", NONE);