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 <eskultet@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
Erik Skultety 2018-11-14 16:48:27 +01:00
parent 255e073263
commit 27cc9f6ac1
6 changed files with 89 additions and 2 deletions

View File

@ -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");

View File

@ -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:

View File

@ -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

View File

@ -0,0 +1,24 @@
<domain type='qemu'>
<name>QEMUGuest1</name>
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
<memory unit='KiB'>219136</memory>
<currentMemory unit='KiB'>219136</currentMemory>
<vcpu placement='static'>1</vcpu>
<os>
<type arch='i686' machine='pc'>hvm</type>
<boot dev='hd'/>
</os>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/bin/qemu-system-i686</emulator>
<input type='mouse' bus='ps2'/>
<input type='keyboard' bus='ps2'/>
<graphics type='spice' autoport='no'>
<gl enable='yes'/>
</graphics>
<memballoon model='virtio'/>
</devices>
</domain>

View File

@ -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 };

View File

@ -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);