diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 8ff092cc44..9937cb773a 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -7568,7 +7568,6 @@ qemuBuildGraphicsVNCCommandLine(virQEMUDriverConfigPtr cfg, static int qemuBuildGraphicsSPICECommandLine(virQEMUDriverConfigPtr cfg, virCommandPtr cmd, - virQEMUCapsPtr qemuCaps, virDomainGraphicsDefPtr graphics) { g_auto(virBuffer) opt = VIR_BUFFER_INITIALIZER; @@ -7579,12 +7578,6 @@ qemuBuildGraphicsSPICECommandLine(virQEMUDriverConfigPtr cfg, bool hasSecure = false; bool hasInsecure = false; - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SPICE)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("spice graphics are not supported with this QEMU")); - return -1; - } - if (!(glisten = virDomainGraphicsGetListen(graphics, 0))) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("missing listen element")); @@ -7593,13 +7586,6 @@ qemuBuildGraphicsSPICECommandLine(virQEMUDriverConfigPtr cfg, switch (glisten->type) { case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET: - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SPICE_UNIX)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("unix socket for spice graphics are not supported " - "with this QEMU")); - return -1; - } - virBufferAddLit(&opt, "unix,addr="); virQEMUBuildBufferEscapeComma(&opt, glisten->socket); virBufferAddLit(&opt, ","); @@ -7614,12 +7600,6 @@ qemuBuildGraphicsSPICECommandLine(virQEMUDriverConfigPtr cfg, } if (tlsPort > 0) { - if (!cfg->spiceTLS) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("spice TLS port set in XML configuration, " - "but TLS is disabled in qemu.conf")); - return -1; - } virBufferAsprintf(&opt, "tls-port=%u,", tlsPort); hasSecure = true; } @@ -7758,35 +7738,16 @@ qemuBuildGraphicsSPICECommandLine(virQEMUDriverConfigPtr cfg, if (graphics->data.spice.copypaste == VIR_TRISTATE_BOOL_NO) virBufferAddLit(&opt, "disable-copy-paste,"); - if (graphics->data.spice.filetransfer == VIR_TRISTATE_BOOL_NO) { - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SPICE_FILE_XFER_DISABLE)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("This QEMU can't disable file transfers through spice")); - return -1; - } else { - virBufferAddLit(&opt, "disable-agent-file-xfer,"); - } - } + if (graphics->data.spice.filetransfer == VIR_TRISTATE_BOOL_NO) + virBufferAddLit(&opt, "disable-agent-file-xfer,"); if (graphics->data.spice.gl == VIR_TRISTATE_BOOL_YES) { - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SPICE_GL)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("This QEMU doesn't support spice OpenGL")); - return -1; - } - /* spice.gl is a TristateBool, but qemu expects on/off: use * TristateSwitch helper */ virBufferAsprintf(&opt, "gl=%s,", virTristateSwitchTypeToString(graphics->data.spice.gl)); if (graphics->data.spice.rendernode) { - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SPICE_RENDERNODE)) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("This QEMU doesn't support spice OpenGL rendernode")); - return -1; - } - virBufferAddLit(&opt, "rendernode="); virQEMUBuildBufferEscapeComma(&opt, graphics->data.spice.rendernode); virBufferAddLit(&opt, ","); @@ -7869,7 +7830,7 @@ qemuBuildGraphicsCommandLine(virQEMUDriverConfigPtr cfg, break; case VIR_DOMAIN_GRAPHICS_TYPE_SPICE: if (qemuBuildGraphicsSPICECommandLine(cfg, cmd, - qemuCaps, graphics) < 0) + graphics) < 0) return -1; break; diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index a8b4762320..30c35fefb5 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -7633,9 +7633,84 @@ qemuDomainDeviceDefValidateTPM(virDomainTPMDef *tpm, } +static int +qemuDomainDeviceDefValidateSPICEGraphics(const virDomainGraphicsDef *graphics, + virQEMUDriverPtr driver, + virQEMUCapsPtr qemuCaps) +{ + g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver); + virDomainGraphicsListenDefPtr glisten = NULL; + int tlsPort = graphics->data.spice.tlsPort; + + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SPICE)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("spice graphics are not supported with this QEMU")); + return -1; + } + + glisten = virDomainGraphicsGetListen((virDomainGraphicsDefPtr)graphics, 0); + if (!glisten) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("missing listen element")); + return -1; + } + + switch (glisten->type) { + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_SOCKET: + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SPICE_UNIX)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("unix socket for spice graphics are not supported " + "with this QEMU")); + return -1; + } + break; + + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS: + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK: + if (tlsPort > 0 && !cfg->spiceTLS) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("spice TLS port set in XML configuration, " + "but TLS is disabled in qemu.conf")); + return -1; + } + break; + + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NONE: + break; + case VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_LAST: + break; + } + + if (graphics->data.spice.filetransfer == VIR_TRISTATE_BOOL_NO && + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_SPICE_FILE_XFER_DISABLE)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("This QEMU can't disable file transfers through spice")); + return -1; + } + + if (graphics->data.spice.gl == VIR_TRISTATE_BOOL_YES) { + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SPICE_GL)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("This QEMU doesn't support spice OpenGL")); + return -1; + } + + if (graphics->data.spice.rendernode && + !virQEMUCapsGet(qemuCaps, QEMU_CAPS_SPICE_RENDERNODE)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("This QEMU doesn't support spice OpenGL rendernode")); + return -1; + } + } + + return 0; +} + + static int qemuDomainDeviceDefValidateGraphics(const virDomainGraphicsDef *graphics, const virDomainDef *def, + virQEMUDriverPtr driver, virQEMUCapsPtr qemuCaps) { bool have_egl_headless = false; @@ -7702,6 +7777,12 @@ qemuDomainDeviceDefValidateGraphics(const virDomainGraphicsDef *graphics, break; case VIR_DOMAIN_GRAPHICS_TYPE_SPICE: + if (qemuDomainDeviceDefValidateSPICEGraphics(graphics, driver, + qemuCaps) < 0) + return -1; + + break; + case VIR_DOMAIN_GRAPHICS_TYPE_EGL_HEADLESS: break; case VIR_DOMAIN_GRAPHICS_TYPE_RDP: @@ -8109,7 +8190,7 @@ qemuDomainDeviceDefValidate(const virDomainDeviceDef *dev, case VIR_DOMAIN_DEVICE_GRAPHICS: ret = qemuDomainDeviceDefValidateGraphics(dev->data.graphics, def, - qemuCaps); + driver, qemuCaps); break; case VIR_DOMAIN_DEVICE_INPUT: diff --git a/tests/qemuhotplugtest.c b/tests/qemuhotplugtest.c index 6490067494..6ab2d9b0f4 100644 --- a/tests/qemuhotplugtest.c +++ b/tests/qemuhotplugtest.c @@ -85,6 +85,8 @@ qemuHotplugCreateObjects(virDomainXMLOptionPtr xmlopt, virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_PIIX_DISABLE_S3); virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_PIIX_DISABLE_S4); virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_VNC); + virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_SPICE); + virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_SPICE_FILE_XFER_DISABLE); if (qemuTestCapsCacheInsert(driver.qemuCapsCache, priv->qemuCaps) < 0) return -1; @@ -592,6 +594,7 @@ mymain(void) struct qemuHotplugTestData data = {0}; struct testQemuHotplugCpuParams cpudata; g_autofree char *fakerootdir = NULL; + g_autoptr(virQEMUDriverConfig) cfg = NULL; fakerootdir = g_strdup(FAKEROOTDIRTEMPLATE); @@ -605,6 +608,8 @@ mymain(void) if (qemuTestDriverInit(&driver) < 0) return EXIT_FAILURE; + cfg = virQEMUDriverGetConfig(&driver); + virEventRegisterDefaultImpl(); VIR_FREE(driver.config->spiceListen); @@ -671,6 +676,7 @@ mymain(void) " }" \ "}\r\n" + cfg->spiceTLS = true; DO_TEST_UPDATE("graphics-spice", "graphics-spice-nochange", false, false, NULL); DO_TEST_UPDATE("graphics-spice-timeout", "graphics-spice-timeout-nochange", false, false, "set_password", QMP_OK, "expire_password", QMP_OK); @@ -679,6 +685,7 @@ mymain(void) DO_TEST_UPDATE("graphics-spice", "graphics-spice-listen", true, false, NULL); DO_TEST_UPDATE("graphics-spice-listen-network", "graphics-spice-listen-network-password", false, false, "set_password", QMP_OK, "expire_password", QMP_OK); + cfg->spiceTLS = false; /* Strange huh? Currently, only graphics can be updated :-P */ DO_TEST_UPDATE("disk-cdrom", "disk-cdrom-nochange", true, false, NULL); diff --git a/tests/qemuxml2argvdata/default-video-type-aarch64.xml b/tests/qemuxml2argvdata/default-video-type-aarch64.xml index 03326d3c9b..f7d2d5d94a 100644 --- a/tests/qemuxml2argvdata/default-video-type-aarch64.xml +++ b/tests/qemuxml2argvdata/default-video-type-aarch64.xml @@ -11,6 +11,6 @@ /usr/bin/qemu-system-aarch64 - + diff --git a/tests/qemuxml2argvdata/default-video-type-ppc64.xml b/tests/qemuxml2argvdata/default-video-type-ppc64.xml index 739e07fc19..ea5b966cfd 100644 --- a/tests/qemuxml2argvdata/default-video-type-ppc64.xml +++ b/tests/qemuxml2argvdata/default-video-type-ppc64.xml @@ -11,6 +11,6 @@ /usr/bin/qemu-system-ppc64 - + diff --git a/tests/qemuxml2argvdata/default-video-type-s390x.xml b/tests/qemuxml2argvdata/default-video-type-s390x.xml index 9eda06a3a1..fe402d2c7f 100644 --- a/tests/qemuxml2argvdata/default-video-type-s390x.xml +++ b/tests/qemuxml2argvdata/default-video-type-s390x.xml @@ -11,6 +11,6 @@ /usr/bin/qemu-system-s390x - + diff --git a/tests/qemuxml2xmloutdata/default-video-type-aarch64.aarch64-latest.xml b/tests/qemuxml2xmloutdata/default-video-type-aarch64.aarch64-latest.xml index 4b660b8d70..1efea62f6f 100644 --- a/tests/qemuxml2xmloutdata/default-video-type-aarch64.aarch64-latest.xml +++ b/tests/qemuxml2xmloutdata/default-video-type-aarch64.aarch64-latest.xml @@ -30,8 +30,8 @@
- - + +