mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 21:55:25 +00:00
qemu: use newer -device video device in qemu commandline
'-device VGA' maps to '-vga std' '-device cirrus-vga' maps to '-vga cirrus' '-device qxl-vga' maps to '-vga qxl' (there is also '-device qxl' for secondary devices) '-device vmware-svga' maps to '-vga vmware' For qemu(>=1.2), we can use -device to replace -vga for video device. For the primary video device, the patch tries to use 0x2 slot for matching old qemu. If the 0x2 slot is allocated already, the addr property could help for using any available slot. For qemu(< 1.2), we keep using -vga for primary device.
This commit is contained in:
parent
09938bb3b0
commit
aa51202b72
@ -93,6 +93,16 @@ VIR_ENUM_IMPL(qemuVideo, VIR_DOMAIN_VIDEO_TYPE_LAST,
|
|||||||
"", /* don't support vbox */
|
"", /* don't support vbox */
|
||||||
"qxl");
|
"qxl");
|
||||||
|
|
||||||
|
VIR_ENUM_DECL(qemuDeviceVideo)
|
||||||
|
|
||||||
|
VIR_ENUM_IMPL(qemuDeviceVideo, VIR_DOMAIN_VIDEO_TYPE_LAST,
|
||||||
|
"VGA",
|
||||||
|
"cirrus-vga",
|
||||||
|
"vmware-svga",
|
||||||
|
"", /* no device for xen */
|
||||||
|
"", /* don't support vbox */
|
||||||
|
"qxl-vga");
|
||||||
|
|
||||||
VIR_ENUM_DECL(qemuSoundCodec)
|
VIR_ENUM_DECL(qemuSoundCodec)
|
||||||
|
|
||||||
VIR_ENUM_IMPL(qemuSoundCodec, VIR_DOMAIN_SOUND_CODEC_TYPE_LAST,
|
VIR_ENUM_IMPL(qemuSoundCodec, VIR_DOMAIN_SOUND_CODEC_TYPE_LAST,
|
||||||
@ -1063,7 +1073,7 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def,
|
|||||||
if (!(addrs = qemuDomainPCIAddressSetCreate(def)))
|
if (!(addrs = qemuDomainPCIAddressSetCreate(def)))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (qemuAssignDevicePCISlots(def, addrs) < 0)
|
if (qemuAssignDevicePCISlots(def, caps, addrs) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1421,12 +1431,15 @@ int qemuDomainPCIAddressSetNextAddr(qemuDomainPCIAddressSetPtr addrs,
|
|||||||
* skip over info.type == PCI
|
* skip over info.type == PCI
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
qemuAssignDevicePCISlots(virDomainDefPtr def, qemuDomainPCIAddressSetPtr addrs)
|
qemuAssignDevicePCISlots(virDomainDefPtr def,
|
||||||
|
qemuCapsPtr caps,
|
||||||
|
qemuDomainPCIAddressSetPtr addrs)
|
||||||
{
|
{
|
||||||
size_t i, j;
|
size_t i, j;
|
||||||
bool reservedIDE = false;
|
bool reservedIDE = false;
|
||||||
bool reservedUSB = false;
|
bool reservedUSB = false;
|
||||||
int function;
|
int function;
|
||||||
|
bool qemuDeviceVideoUsable = qemuCapsGet(caps, QEMU_CAPS_DEVICE_VIDEO_PRIMARY);
|
||||||
|
|
||||||
/* Host bridge */
|
/* Host bridge */
|
||||||
if (qemuDomainPCIAddressReserveSlot(addrs, 0) < 0)
|
if (qemuDomainPCIAddressReserveSlot(addrs, 0) < 0)
|
||||||
@ -1493,29 +1506,42 @@ qemuAssignDevicePCISlots(virDomainDefPtr def, qemuDomainPCIAddressSetPtr addrs)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* First VGA is hardcoded slot=2 */
|
|
||||||
if (def->nvideos > 0) {
|
if (def->nvideos > 0) {
|
||||||
if (def->videos[0]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
|
virDomainVideoDefPtr primaryVideo = def->videos[0];
|
||||||
if (def->videos[0]->info.addr.pci.domain != 0 ||
|
if (primaryVideo->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
|
||||||
def->videos[0]->info.addr.pci.bus != 0 ||
|
primaryVideo->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
|
||||||
def->videos[0]->info.addr.pci.slot != 2 ||
|
primaryVideo->info.addr.pci.domain = 0;
|
||||||
def->videos[0]->info.addr.pci.function != 0) {
|
primaryVideo->info.addr.pci.bus = 0;
|
||||||
|
primaryVideo->info.addr.pci.slot = 2;
|
||||||
|
primaryVideo->info.addr.pci.function = 0;
|
||||||
|
|
||||||
|
if (qemuDomainPCIAddressCheckSlot(addrs, &primaryVideo->info) < 0) {
|
||||||
|
if (qemuDeviceVideoUsable) {
|
||||||
|
virResetLastError();
|
||||||
|
if (qemuDomainPCIAddressSetNextAddr(addrs, &primaryVideo->info) < 0)
|
||||||
|
goto error;
|
||||||
|
} else {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("PCI address 0:0:2.0 is in use, "
|
||||||
|
"QEMU needs it for primary video"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
} else if (qemuDomainPCIAddressReserveSlot(addrs, 2) < 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
} else if (!qemuDeviceVideoUsable) {
|
||||||
|
if (primaryVideo->info.addr.pci.domain != 0 ||
|
||||||
|
primaryVideo->info.addr.pci.bus != 0 ||
|
||||||
|
primaryVideo->info.addr.pci.slot != 2 ||
|
||||||
|
primaryVideo->info.addr.pci.function != 0) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
_("Primary video card must have PCI address 0:0:2.0"));
|
_("Primary video card must have PCI address 0:0:2.0"));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
/* If TYPE==PCI, then qemuCollectPCIAddress() function
|
/* If TYPE==PCI, then qemuCollectPCIAddress() function
|
||||||
* has already reserved the address, so we must skip */
|
* has already reserved the address, so we must skip */
|
||||||
} else {
|
|
||||||
def->videos[0]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
|
|
||||||
def->videos[0]->info.addr.pci.domain = 0;
|
|
||||||
def->videos[0]->info.addr.pci.bus = 0;
|
|
||||||
def->videos[0]->info.addr.pci.slot = 2;
|
|
||||||
def->videos[0]->info.addr.pci.function = 0;
|
|
||||||
if (qemuDomainPCIAddressReserveSlot(addrs, 2) < 0)
|
|
||||||
goto error;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else if (!qemuDeviceVideoUsable) {
|
||||||
virDomainDeviceInfo dev;
|
virDomainDeviceInfo dev;
|
||||||
memset(&dev, 0, sizeof(dev));
|
memset(&dev, 0, sizeof(dev));
|
||||||
dev.addr.pci.slot = 2;
|
dev.addr.pci.slot = 2;
|
||||||
@ -1688,8 +1714,13 @@ qemuAssignDevicePCISlots(virDomainDefPtr def, qemuDomainPCIAddressSetPtr addrs)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Further non-primary video cards */
|
/* Further non-primary video cards which have to be qxl type */
|
||||||
for (i = 1; i < def->nvideos ; i++) {
|
for (i = 1; i < def->nvideos ; i++) {
|
||||||
|
if (def->videos[i]->type != VIR_DOMAIN_VIDEO_TYPE_QXL) {
|
||||||
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||||
|
_("non-primary video device must be type of 'qxl'"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
if (def->videos[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
|
if (def->videos[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
|
||||||
continue;
|
continue;
|
||||||
if (qemuDomainPCIAddressSetNextAddr(addrs, &def->videos[i]->info) < 0)
|
if (qemuDomainPCIAddressSetNextAddr(addrs, &def->videos[i]->info) < 0)
|
||||||
@ -3507,16 +3538,35 @@ error:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
qemuBuildVideoDevStr(virDomainVideoDefPtr video,
|
qemuBuildDeviceVideoStr(virDomainVideoDefPtr video,
|
||||||
qemuCapsPtr caps)
|
qemuCapsPtr caps,
|
||||||
|
bool primary)
|
||||||
{
|
{
|
||||||
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
||||||
const char *model = qemuVideoTypeToString(video->type);
|
const char *model;
|
||||||
|
|
||||||
if (!model) {
|
if (primary) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
model = qemuDeviceVideoTypeToString(video->type);
|
||||||
"%s", _("invalid video model"));
|
if (!model || STREQ(model, "")) {
|
||||||
goto error;
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
|
_("video type %s is not supported with QEMU"),
|
||||||
|
virDomainVideoTypeToString(video->type));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (video->type != VIR_DOMAIN_VIDEO_TYPE_QXL) {
|
||||||
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
|
"%s", _("non-primary video device must be type of 'qxl'"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!qemuCapsGet(caps, QEMU_CAPS_DEVICE_QXL)) {
|
||||||
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
|
"%s", _("only one video card is currently supported"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
model = "qxl";
|
||||||
}
|
}
|
||||||
|
|
||||||
virBufferAsprintf(&buf, "%s,id=%s", model, video->info.alias);
|
virBufferAsprintf(&buf, "%s,id=%s", model, video->info.alias);
|
||||||
@ -6433,22 +6483,42 @@ qemuBuildCommandLine(virConnectPtr conn,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if (def->nvideos > 0) {
|
if (def->nvideos > 0) {
|
||||||
if (qemuCapsGet(caps, QEMU_CAPS_VGA)) {
|
int primaryVideoType = def->videos[0]->type;
|
||||||
if (def->videos[0]->type == VIR_DOMAIN_VIDEO_TYPE_XEN) {
|
if (qemuCapsGet(caps, QEMU_CAPS_DEVICE_VIDEO_PRIMARY) &&
|
||||||
|
((primaryVideoType == VIR_DOMAIN_VIDEO_TYPE_VGA &&
|
||||||
|
qemuCapsGet(caps, QEMU_CAPS_DEVICE_VGA)) ||
|
||||||
|
(primaryVideoType == VIR_DOMAIN_VIDEO_TYPE_CIRRUS &&
|
||||||
|
qemuCapsGet(caps, QEMU_CAPS_DEVICE_CIRRUS_VGA)) ||
|
||||||
|
(primaryVideoType == VIR_DOMAIN_VIDEO_TYPE_VMVGA &&
|
||||||
|
qemuCapsGet(caps, QEMU_CAPS_DEVICE_VMWARE_SVGA)) ||
|
||||||
|
(primaryVideoType == VIR_DOMAIN_VIDEO_TYPE_QXL &&
|
||||||
|
qemuCapsGet(caps, QEMU_CAPS_DEVICE_QXL_VGA)))
|
||||||
|
) {
|
||||||
|
for (i = 0 ; i < def->nvideos ; i++) {
|
||||||
|
char *str;
|
||||||
|
virCommandAddArg(cmd, "-device");
|
||||||
|
if (!(str = qemuBuildDeviceVideoStr(def->videos[i], caps, !i)))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
virCommandAddArg(cmd, str);
|
||||||
|
VIR_FREE(str);
|
||||||
|
}
|
||||||
|
} else if (qemuCapsGet(caps, QEMU_CAPS_VGA)) {
|
||||||
|
if (primaryVideoType == VIR_DOMAIN_VIDEO_TYPE_XEN) {
|
||||||
/* nothing - vga has no effect on Xen pvfb */
|
/* nothing - vga has no effect on Xen pvfb */
|
||||||
} else {
|
} else {
|
||||||
if ((def->videos[0]->type == VIR_DOMAIN_VIDEO_TYPE_QXL) &&
|
if ((primaryVideoType == VIR_DOMAIN_VIDEO_TYPE_QXL) &&
|
||||||
!qemuCapsGet(caps, QEMU_CAPS_VGA_QXL)) {
|
!qemuCapsGet(caps, QEMU_CAPS_VGA_QXL)) {
|
||||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||||
_("This QEMU does not support QXL graphics adapters"));
|
_("This QEMU does not support QXL graphics adapters"));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *vgastr = qemuVideoTypeToString(def->videos[0]->type);
|
const char *vgastr = qemuVideoTypeToString(primaryVideoType);
|
||||||
if (!vgastr || STREQ(vgastr, "")) {
|
if (!vgastr || STREQ(vgastr, "")) {
|
||||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
_("video type %s is not supported with QEMU"),
|
_("video type %s is not supported with QEMU"),
|
||||||
virDomainVideoTypeToString(def->videos[0]->type));
|
virDomainVideoTypeToString(primaryVideoType));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6475,6 +6545,32 @@ qemuBuildCommandLine(virConnectPtr conn,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (def->nvideos > 1) {
|
||||||
|
if (qemuCapsGet(caps, QEMU_CAPS_DEVICE)) {
|
||||||
|
for (i = 1 ; i < def->nvideos ; i++) {
|
||||||
|
char *str;
|
||||||
|
if (def->videos[i]->type != VIR_DOMAIN_VIDEO_TYPE_QXL) {
|
||||||
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
|
_("video type %s is only valid as primary video card"),
|
||||||
|
virDomainVideoTypeToString(def->videos[0]->type));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
virCommandAddArg(cmd, "-device");
|
||||||
|
|
||||||
|
if (!(str = qemuBuildDeviceVideoStr(def->videos[i], caps, false)))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
virCommandAddArg(cmd, str);
|
||||||
|
VIR_FREE(str);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
|
"%s", _("only one video card is currently supported"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
switch (def->videos[0]->type) {
|
switch (def->videos[0]->type) {
|
||||||
@ -6497,28 +6593,8 @@ qemuBuildCommandLine(virConnectPtr conn,
|
|||||||
virDomainVideoTypeToString(def->videos[0]->type));
|
virDomainVideoTypeToString(def->videos[0]->type));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (def->nvideos > 1) {
|
if (def->nvideos > 1) {
|
||||||
if (qemuCapsGet(caps, QEMU_CAPS_DEVICE)) {
|
|
||||||
for (i = 1 ; i < def->nvideos ; i++) {
|
|
||||||
char *str;
|
|
||||||
if (def->videos[i]->type != VIR_DOMAIN_VIDEO_TYPE_QXL) {
|
|
||||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
||||||
_("video type %s is only valid as primary video card"),
|
|
||||||
virDomainVideoTypeToString(def->videos[0]->type));
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
virCommandAddArg(cmd, "-device");
|
|
||||||
|
|
||||||
if (!(str = qemuBuildVideoDevStr(def->videos[i], caps)))
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
virCommandAddArg(cmd, str);
|
|
||||||
VIR_FREE(str);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
"%s", _("only one video card is currently supported"));
|
"%s", _("only one video card is currently supported"));
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -211,7 +211,9 @@ int qemuDomainPCIAddressReleaseFunction(qemuDomainPCIAddressSetPtr addrs,
|
|||||||
int qemuDomainPCIAddressReleaseSlot(qemuDomainPCIAddressSetPtr addrs, int slot);
|
int qemuDomainPCIAddressReleaseSlot(qemuDomainPCIAddressSetPtr addrs, int slot);
|
||||||
|
|
||||||
void qemuDomainPCIAddressSetFree(qemuDomainPCIAddressSetPtr addrs);
|
void qemuDomainPCIAddressSetFree(qemuDomainPCIAddressSetPtr addrs);
|
||||||
int qemuAssignDevicePCISlots(virDomainDefPtr def, qemuDomainPCIAddressSetPtr addrs);
|
int qemuAssignDevicePCISlots(virDomainDefPtr def,
|
||||||
|
qemuCapsPtr caps,
|
||||||
|
qemuDomainPCIAddressSetPtr addrs);
|
||||||
|
|
||||||
int qemuAssignDeviceAliases(virDomainDefPtr def, qemuCapsPtr caps);
|
int qemuAssignDeviceAliases(virDomainDefPtr def, qemuCapsPtr caps);
|
||||||
int qemuDomainNetVLAN(virDomainNetDefPtr def);
|
int qemuDomainNetVLAN(virDomainNetDefPtr def);
|
||||||
|
@ -574,7 +574,8 @@ mymain(void)
|
|||||||
QEMU_CAPS_VGA, QEMU_CAPS_VGA_NONE);
|
QEMU_CAPS_VGA, QEMU_CAPS_VGA_NONE);
|
||||||
DO_TEST("graphics-spice",
|
DO_TEST("graphics-spice",
|
||||||
QEMU_CAPS_VGA, QEMU_CAPS_VGA_QXL,
|
QEMU_CAPS_VGA, QEMU_CAPS_VGA_QXL,
|
||||||
QEMU_CAPS_DEVICE, QEMU_CAPS_SPICE);
|
QEMU_CAPS_DEVICE, QEMU_CAPS_SPICE,
|
||||||
|
QEMU_CAPS_DEVICE_QXL);
|
||||||
DO_TEST("graphics-spice-agentmouse",
|
DO_TEST("graphics-spice-agentmouse",
|
||||||
QEMU_CAPS_VGA, QEMU_CAPS_VGA_QXL,
|
QEMU_CAPS_VGA, QEMU_CAPS_VGA_QXL,
|
||||||
QEMU_CAPS_DEVICE, QEMU_CAPS_SPICE,
|
QEMU_CAPS_DEVICE, QEMU_CAPS_SPICE,
|
||||||
@ -582,7 +583,8 @@ mymain(void)
|
|||||||
QEMU_CAPS_NODEFCONFIG);
|
QEMU_CAPS_NODEFCONFIG);
|
||||||
DO_TEST("graphics-spice-compression",
|
DO_TEST("graphics-spice-compression",
|
||||||
QEMU_CAPS_VGA, QEMU_CAPS_VGA_QXL,
|
QEMU_CAPS_VGA, QEMU_CAPS_VGA_QXL,
|
||||||
QEMU_CAPS_DEVICE, QEMU_CAPS_SPICE);
|
QEMU_CAPS_DEVICE, QEMU_CAPS_SPICE,
|
||||||
|
QEMU_CAPS_DEVICE_QXL);
|
||||||
DO_TEST("graphics-spice-timeout",
|
DO_TEST("graphics-spice-timeout",
|
||||||
QEMU_CAPS_DRIVE,
|
QEMU_CAPS_DRIVE,
|
||||||
QEMU_CAPS_VGA, QEMU_CAPS_VGA_QXL,
|
QEMU_CAPS_VGA, QEMU_CAPS_VGA_QXL,
|
||||||
@ -591,7 +593,8 @@ mymain(void)
|
|||||||
DO_TEST("graphics-spice-qxl-vga",
|
DO_TEST("graphics-spice-qxl-vga",
|
||||||
QEMU_CAPS_VGA, QEMU_CAPS_VGA_QXL,
|
QEMU_CAPS_VGA, QEMU_CAPS_VGA_QXL,
|
||||||
QEMU_CAPS_DEVICE, QEMU_CAPS_SPICE,
|
QEMU_CAPS_DEVICE, QEMU_CAPS_SPICE,
|
||||||
QEMU_CAPS_DEVICE_QXL_VGA);
|
QEMU_CAPS_DEVICE_QXL_VGA,
|
||||||
|
QEMU_CAPS_DEVICE_QXL);
|
||||||
DO_TEST("graphics-spice-usb-redir",
|
DO_TEST("graphics-spice-usb-redir",
|
||||||
QEMU_CAPS_VGA, QEMU_CAPS_SPICE,
|
QEMU_CAPS_VGA, QEMU_CAPS_SPICE,
|
||||||
QEMU_CAPS_CHARDEV, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG,
|
QEMU_CAPS_CHARDEV, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG,
|
||||||
|
Loading…
Reference in New Issue
Block a user