qemuBuildVideoCommandLine: Generate via JSON

We control the following properties of the devices in question:

'virtio-gpu'
  virgl=<bool>           - on/off (default: true)

'qxl'
  ram_size=<uint32>      -  (default: 67108864)
  vram_size=<uint64>     -  (default: 67108864)
  vram64_size_mb=<uint32> -  (default: 4294967295)
  vgamem_mb=<uint32>     -  (default: 16)
  max_outputs=<uint16>   -  (default: 0)

'vhost-user-gpu'
  max_outputs=<uint32>   -  (default: 1)
  chardev=<string>

'VGA'
  vgamem_mb=<uint32>     -  (default: 16)

'bochs-display'
  vgamem=<size>          -  (default: 16777216)

common for all devices:
  xres=<uint32>          -  (default: 0)
  yres=<uint32>          -  (default: 0)

The only noticable change is using memory size in bytes for
'bochs-display' instead of kibibytes.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
Peter Krempa 2021-10-05 17:04:40 +02:00
parent a8fec8848c
commit 6e9231d6c0
2 changed files with 74 additions and 58 deletions

View File

@ -4660,99 +4660,120 @@ qemuBuildSoundCommandLine(virCommand *cmd,
} }
static char * static int
qemuBuildDeviceVideoStr(const virDomainDef *def, qemuBuildDeviceVideoCmd(virCommand *cmd,
const virDomainDef *def,
virDomainVideoDef *video, virDomainVideoDef *video,
virQEMUCaps *qemuCaps) virQEMUCaps *qemuCaps)
{ {
g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
const char *model = NULL; const char *model = NULL;
virTristateSwitch accel3d = VIR_TRISTATE_SWITCH_ABSENT; virTristateSwitch virgl = VIR_TRISTATE_SWITCH_ABSENT;
bool virtio = false; bool virtio = false;
bool virtioBusSuffix = false; bool virtioBusSuffix = false;
g_autoptr(virJSONValue) props = NULL;
if (video->accel)
accel3d = video->accel->accel3d;
if (!(model = qemuDeviceVideoGetModel(qemuCaps, video, &virtio, &virtioBusSuffix))) if (!(model = qemuDeviceVideoGetModel(qemuCaps, video, &virtio, &virtioBusSuffix)))
return NULL; return -1;
if (virtio) { if (virtio) {
if (qemuBuildVirtioDevStr(&buf, qemuCaps, VIR_DOMAIN_DEVICE_VIDEO, video) < 0) { if (!(props = qemuBuildVirtioDevProps(VIR_DOMAIN_DEVICE_VIDEO, video, qemuCaps)))
return NULL; return -1;
}
} else { } else {
virBufferAsprintf(&buf, "%s", model); if (virJSONValueObjectCreate(&props,
"s:driver", model,
NULL) < 0)
return -1;
} }
virBufferAsprintf(&buf, ",id=%s", video->info.alias);
if (video->backend != VIR_DOMAIN_VIDEO_BACKEND_TYPE_VHOSTUSER && if (video->backend != VIR_DOMAIN_VIDEO_BACKEND_TYPE_VHOSTUSER &&
video->type == VIR_DOMAIN_VIDEO_TYPE_VIRTIO) { video->type == VIR_DOMAIN_VIDEO_TYPE_VIRTIO) {
if (video->accel && if (video->accel &&
virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_GPU_VIRGL) && virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_GPU_VIRGL)) {
(accel3d == VIR_TRISTATE_SWITCH_ON || virgl = video->accel->accel3d;
accel3d == VIR_TRISTATE_SWITCH_OFF)) {
virBufferAsprintf(&buf, ",virgl=%s",
virTristateSwitchTypeToString(accel3d));
} }
} }
if (video->type == VIR_DOMAIN_VIDEO_TYPE_QXL) { if (virJSONValueObjectAdd(props,
if (video->ram) { "s:id", video->info.alias,
/* QEMU accepts bytes for ram_size. */ "T:virgl", virgl,
virBufferAsprintf(&buf, ",ram_size=%u", video->ram * 1024); NULL) < 0)
} return -1;
if (video->vram) { if (video->type == VIR_DOMAIN_VIDEO_TYPE_QXL) {
/* QEMU accepts bytes for vram_size. */ if (virJSONValueObjectAdd(props,
virBufferAsprintf(&buf, ",vram_size=%u", video->vram * 1024); "p:ram_size", video->ram * 1024,
} "p:vram_size", video->vram * 1024,
NULL) < 0)
return -1;
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_QXL_VRAM64)) { if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_QXL_VRAM64)) {
/* QEMU accepts mebibytes for vram64_size_mb. */ if (virJSONValueObjectAdd(props,
virBufferAsprintf(&buf, ",vram64_size_mb=%u", video->vram64 / 1024); "u:vram64_size_mb", video->vram64 / 1024,
NULL) < 0)
return -1;
} }
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_QXL_VGAMEM)) { if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_QXL_VGAMEM)) {
/* QEMU accepts mebibytes for vgamem_mb. */ if (virJSONValueObjectAdd(props,
virBufferAsprintf(&buf, ",vgamem_mb=%u", video->vgamem / 1024); "u:vgamem_mb", video->vgamem / 1024,
NULL) < 0)
return -1;
} }
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_QXL_MAX_OUTPUTS)) { if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_QXL_MAX_OUTPUTS)) {
if (video->heads) if (virJSONValueObjectAdd(props,
virBufferAsprintf(&buf, ",max_outputs=%u", video->heads); "p:max_outputs", video->heads,
NULL) < 0)
return -1;
} }
} else if (video->backend == VIR_DOMAIN_VIDEO_BACKEND_TYPE_VHOSTUSER) { } else if (video->backend == VIR_DOMAIN_VIDEO_BACKEND_TYPE_VHOSTUSER) {
g_autofree char *alias = qemuDomainGetVhostUserChrAlias(video->info.alias); g_autofree char *alias = qemuDomainGetVhostUserChrAlias(video->info.alias);
if (video->heads)
virBufferAsprintf(&buf, ",max_outputs=%u", video->heads); if (virJSONValueObjectAdd(props,
virBufferAsprintf(&buf, ",chardev=%s", alias); "p:max_outputs", video->heads,
"s:chardev", alias,
NULL) < 0)
return -1;
} else if (video->type == VIR_DOMAIN_VIDEO_TYPE_VIRTIO) { } else if (video->type == VIR_DOMAIN_VIDEO_TYPE_VIRTIO) {
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_GPU_MAX_OUTPUTS)) { unsigned int heads = 0;
if (video->heads)
virBufferAsprintf(&buf, ",max_outputs=%u", video->heads); if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_GPU_MAX_OUTPUTS))
} heads = video->heads;
if (virJSONValueObjectAdd(props,
"p:max_outputs", heads,
NULL) < 0)
return -1;
} else if ((video->type == VIR_DOMAIN_VIDEO_TYPE_VGA && } else if ((video->type == VIR_DOMAIN_VIDEO_TYPE_VGA &&
virQEMUCapsGet(qemuCaps, QEMU_CAPS_VGA_VGAMEM)) || virQEMUCapsGet(qemuCaps, QEMU_CAPS_VGA_VGAMEM)) ||
(video->type == VIR_DOMAIN_VIDEO_TYPE_VMVGA && (video->type == VIR_DOMAIN_VIDEO_TYPE_VMVGA &&
virQEMUCapsGet(qemuCaps, QEMU_CAPS_VMWARE_SVGA_VGAMEM))) { virQEMUCapsGet(qemuCaps, QEMU_CAPS_VMWARE_SVGA_VGAMEM))) {
if (video->vram) if (virJSONValueObjectAdd(props,
virBufferAsprintf(&buf, ",vgamem_mb=%u", video->vram / 1024); "p:vgamem_mb", video->vram / 1024,
NULL) < 0)
return -1;
} else if (video->type == VIR_DOMAIN_VIDEO_TYPE_BOCHS) { } else if (video->type == VIR_DOMAIN_VIDEO_TYPE_BOCHS) {
if (video->vram) if (virJSONValueObjectAdd(props,
virBufferAsprintf(&buf, ",vgamem=%uk", video->vram); "p:vgamem", video->vram * 1024,
NULL) < 0)
return -1;
} }
if (video->res && video->res->x && video->res->y) { if (video->res) {
/* QEMU accepts resolution xres and yres. */ if (virJSONValueObjectAdd(props,
virBufferAsprintf(&buf, ",xres=%u,yres=%u", video->res->x, video->res->y); "p:xres", video->res->x,
"p:yres", video->res->y,
NULL) < 0)
return -1;
} }
if (qemuBuildDeviceAddressStr(&buf, def, &video->info) < 0) if (qemuBuildDeviceAddressProps(props, def, &video->info) < 0)
return NULL; return -1;
return virBufferContentAndReset(&buf); if (qemuBuildDeviceCommandlineFromJSON(cmd, props, qemuCaps) < 0)
return -1;
return 0;
} }
@ -4801,7 +4822,6 @@ qemuBuildVideoCommandLine(virCommand *cmd,
} }
for (i = 0; i < def->nvideos; i++) { for (i = 0; i < def->nvideos; i++) {
g_autofree char *str = NULL;
virDomainVideoDef *video = def->videos[i]; virDomainVideoDef *video = def->videos[i];
if (video->type == VIR_DOMAIN_VIDEO_TYPE_NONE) if (video->type == VIR_DOMAIN_VIDEO_TYPE_NONE)
@ -4810,12 +4830,8 @@ qemuBuildVideoCommandLine(virCommand *cmd,
if (qemuCommandAddExtDevice(cmd, &def->videos[i]->info, qemuCaps) < 0) if (qemuCommandAddExtDevice(cmd, &def->videos[i]->info, qemuCaps) < 0)
return -1; return -1;
virCommandAddArg(cmd, "-device"); if (qemuBuildDeviceVideoCmd(cmd, def, video, qemuCaps) < 0)
if (!(str = qemuBuildDeviceVideoStr(def, video, qemuCaps)))
return -1; return -1;
virCommandAddArg(cmd, str);
} }
return 0; return 0;

View File

@ -31,7 +31,7 @@ XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \
-blockdev '{"node-name":"libvirt-1-format","read-only":false,"cache":{"direct":true,"no-flush":false},"driver":"qcow2","file":"libvirt-1-storage"}' \ -blockdev '{"node-name":"libvirt-1-format","read-only":false,"cache":{"direct":true,"no-flush":false},"driver":"qcow2","file":"libvirt-1-storage"}' \
-device ide-hd,bus=ide.0,unit=0,drive=libvirt-1-format,id=ide0-0-0,bootindex=1,write-cache=on \ -device ide-hd,bus=ide.0,unit=0,drive=libvirt-1-format,id=ide0-0-0,bootindex=1,write-cache=on \
-audiodev id=audio1,driver=none \ -audiodev id=audio1,driver=none \
-device bochs-display,id=video0,vgamem=16384k,bus=pci.0,addr=0x2 \ -device bochs-display,id=video0,vgamem=16777216,bus=pci.0,addr=0x2 \
-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 \ -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 \
-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
-msg timestamp=on -msg timestamp=on