From: Erik Skultety Date: Wed, 14 Nov 2018 15:48:27 +0000 (+0100) Subject: qemu: process: spice: Pick the first available DRM render node X-Git-Tag: v5.0.0-rc1~168 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=27cc9f6ac187924456b658683e490f6d318ebe08;p=thirdparty%2Flibvirt.git qemu: process: spice: Pick the first available DRM render node Up until now, we formatted 'rendernode=' onto QEMU cmdline only if the user specified it in the XML, otherwise we let QEMU do it for us. This causes permission issues because by default the /dev/dri/renderDX permissions are as follows: crw-rw----. 1 root video There's literally no reason why it shouldn't be libvirt picking the DRM render node instead of QEMU, that way (and because we're using namespaces by default), we can safely relabel the device within the namespace. Signed-off-by: Erik Skultety Reviewed-by: Ján Tomko --- diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 12d1fca0d4..4f21f1e034 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -4784,9 +4784,28 @@ qemuProcessGraphicsSetupListen(virQEMUDriverPtr driver, } +static int +qemuProcessGraphicsSetupRenderNode(virDomainGraphicsDefPtr graphics, + virQEMUCapsPtr qemuCaps) +{ + if (!virDomainGraphicsNeedsAutoRenderNode(graphics)) + return 0; + + /* Don't bother picking a DRM node if QEMU doesn't support it. */ + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SPICE_RENDERNODE)) + return 0; + + if (!(graphics->data.spice.rendernode = virHostGetDRMRenderNode())) + return -1; + + return 0; +} + + static int qemuProcessSetupGraphics(virQEMUDriverPtr driver, virDomainObjPtr vm, + virQEMUCapsPtr qemuCaps, unsigned int flags) { virDomainGraphicsDefPtr graphics; @@ -4797,6 +4816,9 @@ qemuProcessSetupGraphics(virQEMUDriverPtr driver, for (i = 0; i < vm->def->ngraphics; i++) { graphics = vm->def->graphics[i]; + if (qemuProcessGraphicsSetupRenderNode(graphics, qemuCaps) < 0) + goto cleanup; + if (qemuProcessGraphicsSetupListen(driver, graphics, vm) < 0) goto cleanup; } @@ -5953,7 +5975,7 @@ qemuProcessPrepareDomain(virQEMUDriverPtr driver, goto cleanup; VIR_DEBUG("Setting graphics devices"); - if (qemuProcessSetupGraphics(driver, vm, flags) < 0) + if (qemuProcessSetupGraphics(driver, vm, priv->qemuCaps, flags) < 0) goto cleanup; VIR_DEBUG("Create domain masterKey"); diff --git a/src/util/virutil.h b/src/util/virutil.h index 89bd21b148..588d779d10 100644 --- a/src/util/virutil.h +++ b/src/util/virutil.h @@ -222,7 +222,7 @@ unsigned long long virMemoryMaxValue(bool ulong) ATTRIBUTE_NOINLINE; bool virHostHasIOMMU(void); -char *virHostGetDRMRenderNode(void); +char *virHostGetDRMRenderNode(void) ATTRIBUTE_NOINLINE; /** * VIR_ASSIGN_IS_OVERFLOW: diff --git a/tests/qemuxml2argvdata/graphics-spice-gl-auto-rendernode.x86_64-latest.args b/tests/qemuxml2argvdata/graphics-spice-gl-auto-rendernode.x86_64-latest.args new file mode 100644 index 0000000000..ee92e1fa5a --- /dev/null +++ b/tests/qemuxml2argvdata/graphics-spice-gl-auto-rendernode.x86_64-latest.args @@ -0,0 +1,31 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/home/test \ +USER=test \ +LOGNAME=test \ +QEMU_AUDIO_DRV=spice \ +/usr/bin/qemu-system-i686 \ +-name guest=QEMUGuest1,debug-threads=on \ +-S \ +-object secret,id=masterKey0,format=raw,\ +file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \ +-machine pc,accel=tcg,usb=off,dump-guest-core=off \ +-m 214 \ +-realtime mlock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,fd=1729,server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-no-acpi \ +-boot strict=on \ +-device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \ +-spice port=0,gl=on,rendernode=/dev/dri/foo,seamless-migration=on \ +-device cirrus-vga,id=video0,bus=pci.0,addr=0x2 \ +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\ +resourcecontrol=deny \ +-msg timestamp=on diff --git a/tests/qemuxml2argvdata/graphics-spice-gl-auto-rendernode.xml b/tests/qemuxml2argvdata/graphics-spice-gl-auto-rendernode.xml new file mode 100644 index 0000000000..b48e7bc94e --- /dev/null +++ b/tests/qemuxml2argvdata/graphics-spice-gl-auto-rendernode.xml @@ -0,0 +1,24 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219136 + 219136 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu-system-i686 + + + + + + + + diff --git a/tests/qemuxml2argvmock.c b/tests/qemuxml2argvmock.c index 79152d928e..a64cd955c4 100644 --- a/tests/qemuxml2argvmock.c +++ b/tests/qemuxml2argvmock.c @@ -184,6 +184,15 @@ virNetDevRunEthernetScript(const char *ifname ATTRIBUTE_UNUSED, return 0; } +char * +virHostGetDRMRenderNode(void) +{ + char *dst = NULL; + + ignore_value(VIR_STRDUP(dst, "/dev/dri/foo")); + return dst; +} + static void (*real_virCommandPassFD)(virCommandPtr cmd, int fd, unsigned int flags); static const int testCommandPassSafeFDs[] = { 1730, 1731 }; diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index eae2b7edf7..89c51a5e78 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1351,6 +1351,7 @@ mymain(void) QEMU_CAPS_SPICE, QEMU_CAPS_EGL_HEADLESS, QEMU_CAPS_DEVICE_QXL); + DO_TEST_CAPS_LATEST("graphics-spice-gl-auto-rendernode"); DO_TEST("input-usbmouse", NONE); DO_TEST("input-usbtablet", NONE);