99cbc7
From 92f60bbc60e5ff60069f6d775d23f228eb3b5c78 Mon Sep 17 00:00:00 2001
99cbc7
Message-Id: <92f60bbc60e5ff60069f6d775d23f228eb3b5c78@dist-git>
99cbc7
From: Erik Skultety <eskultet@redhat.com>
99cbc7
Date: Tue, 9 Apr 2019 08:34:27 +0200
99cbc7
Subject: [PATCH] qemu: process: spice: Pick the first available DRM render
99cbc7
 node
99cbc7
MIME-Version: 1.0
99cbc7
Content-Type: text/plain; charset=UTF-8
99cbc7
Content-Transfer-Encoding: 8bit
99cbc7
99cbc7
Up until now, we formatted 'rendernode=' onto QEMU cmdline only if the
99cbc7
user specified it in the XML, otherwise we let QEMU do it for us. This
99cbc7
causes permission issues because by default the /dev/dri/renderDX
99cbc7
permissions are as follows:
99cbc7
99cbc7
crw-rw----. 1 root video
99cbc7
99cbc7
There's literally no reason why it shouldn't be libvirt picking the DRM
99cbc7
render node instead of QEMU, that way (and because we're using
99cbc7
namespaces by default), we can safely relabel the device within the
99cbc7
namespace.
99cbc7
99cbc7
Signed-off-by: Erik Skultety <eskultet@redhat.com>
99cbc7
Reviewed-by: Ján Tomko <jtomko@redhat.com>
99cbc7
(cherry picked from commit 27cc9f6ac187924456b658683e490f6d318ebe08)
99cbc7
99cbc7
https://bugzilla.redhat.com/show_bug.cgi?id=1628892
99cbc7
Signed-off-by: Erik Skultety <eskultet@redhat.com>
99cbc7
99cbc7
 Conflicts:
99cbc7
	tests/qemuxml2argvmock.c
99cbc7
            Missing context because v4.6.0-309-gd06a8ebe8f and
99cbc7
            v4.6.0-311-g3411fd4db4 were not backported
99cbc7
Message-Id: <be2bca27f2b84bfebbe62a699d78bd91e59e96bd.1554791287.git.eskultet@redhat.com>
99cbc7
99cbc7
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
99cbc7
---
99cbc7
 src/qemu/qemu_process.c                       | 24 +++++++++++++-
99cbc7
 src/util/virutil.h                            |  2 +-
99cbc7
 ...pice-gl-auto-rendernode.x86_64-latest.args | 31 +++++++++++++++++++
99cbc7
 .../graphics-spice-gl-auto-rendernode.xml     | 24 ++++++++++++++
99cbc7
 tests/qemuxml2argvmock.c                      |  9 ++++++
99cbc7
 tests/qemuxml2argvtest.c                      |  1 +
99cbc7
 6 files changed, 89 insertions(+), 2 deletions(-)
99cbc7
 create mode 100644 tests/qemuxml2argvdata/graphics-spice-gl-auto-rendernode.x86_64-latest.args
99cbc7
 create mode 100644 tests/qemuxml2argvdata/graphics-spice-gl-auto-rendernode.xml
99cbc7
99cbc7
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
99cbc7
index a44f371346..465dabd8e3 100644
99cbc7
--- a/src/qemu/qemu_process.c
99cbc7
+++ b/src/qemu/qemu_process.c
99cbc7
@@ -4751,9 +4751,28 @@ qemuProcessGraphicsSetupListen(virQEMUDriverPtr driver,
99cbc7
 }
99cbc7
 
99cbc7
 
99cbc7
+static int
99cbc7
+qemuProcessGraphicsSetupRenderNode(virDomainGraphicsDefPtr graphics,
99cbc7
+                                   virQEMUCapsPtr qemuCaps)
99cbc7
+{
99cbc7
+    if (!virDomainGraphicsNeedsAutoRenderNode(graphics))
99cbc7
+        return 0;
99cbc7
+
99cbc7
+    /* Don't bother picking a DRM node if QEMU doesn't support it. */
99cbc7
+    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SPICE_RENDERNODE))
99cbc7
+        return 0;
99cbc7
+
99cbc7
+    if (!(graphics->data.spice.rendernode = virHostGetDRMRenderNode()))
99cbc7
+        return -1;
99cbc7
+
99cbc7
+    return 0;
99cbc7
+}
99cbc7
+
99cbc7
+
99cbc7
 static int
99cbc7
 qemuProcessSetupGraphics(virQEMUDriverPtr driver,
99cbc7
                          virDomainObjPtr vm,
99cbc7
+                         virQEMUCapsPtr qemuCaps,
99cbc7
                          unsigned int flags)
99cbc7
 {
99cbc7
     virDomainGraphicsDefPtr graphics;
99cbc7
@@ -4764,6 +4783,9 @@ qemuProcessSetupGraphics(virQEMUDriverPtr driver,
99cbc7
     for (i = 0; i < vm->def->ngraphics; i++) {
99cbc7
         graphics = vm->def->graphics[i];
99cbc7
 
99cbc7
+        if (qemuProcessGraphicsSetupRenderNode(graphics, qemuCaps) < 0)
99cbc7
+            goto cleanup;
99cbc7
+
99cbc7
         if (qemuProcessGraphicsSetupListen(driver, graphics, vm) < 0)
99cbc7
             goto cleanup;
99cbc7
     }
99cbc7
@@ -5924,7 +5946,7 @@ qemuProcessPrepareDomain(virQEMUDriverPtr driver,
99cbc7
         goto cleanup;
99cbc7
 
99cbc7
     VIR_DEBUG("Setting graphics devices");
99cbc7
-    if (qemuProcessSetupGraphics(driver, vm, flags) < 0)
99cbc7
+    if (qemuProcessSetupGraphics(driver, vm, priv->qemuCaps, flags) < 0)
99cbc7
         goto cleanup;
99cbc7
 
99cbc7
     VIR_DEBUG("Create domain masterKey");
99cbc7
diff --git a/src/util/virutil.h b/src/util/virutil.h
99cbc7
index 284c713be4..abbbb7101e 100644
99cbc7
--- a/src/util/virutil.h
99cbc7
+++ b/src/util/virutil.h
99cbc7
@@ -218,7 +218,7 @@ unsigned long long virMemoryMaxValue(bool ulong) ATTRIBUTE_NOINLINE;
99cbc7
 
99cbc7
 bool virHostHasIOMMU(void);
99cbc7
 
99cbc7
-char *virHostGetDRMRenderNode(void);
99cbc7
+char *virHostGetDRMRenderNode(void) ATTRIBUTE_NOINLINE;
99cbc7
 
99cbc7
 /**
99cbc7
  * VIR_ASSIGN_IS_OVERFLOW:
99cbc7
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
99cbc7
new file mode 100644
99cbc7
index 0000000000..ee92e1fa5a
99cbc7
--- /dev/null
99cbc7
+++ b/tests/qemuxml2argvdata/graphics-spice-gl-auto-rendernode.x86_64-latest.args
99cbc7
@@ -0,0 +1,31 @@
99cbc7
+LC_ALL=C \
99cbc7
+PATH=/bin \
99cbc7
+HOME=/home/test \
99cbc7
+USER=test \
99cbc7
+LOGNAME=test \
99cbc7
+QEMU_AUDIO_DRV=spice \
99cbc7
+/usr/bin/qemu-system-i686 \
99cbc7
+-name guest=QEMUGuest1,debug-threads=on \
99cbc7
+-S \
99cbc7
+-object secret,id=masterKey0,format=raw,\
99cbc7
+file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \
99cbc7
+-machine pc,accel=tcg,usb=off,dump-guest-core=off \
99cbc7
+-m 214 \
99cbc7
+-realtime mlock=off \
99cbc7
+-smp 1,sockets=1,cores=1,threads=1 \
99cbc7
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
99cbc7
+-no-user-config \
99cbc7
+-nodefaults \
99cbc7
+-chardev socket,id=charmonitor,fd=1729,server,nowait \
99cbc7
+-mon chardev=charmonitor,id=monitor,mode=control \
99cbc7
+-rtc base=utc \
99cbc7
+-no-shutdown \
99cbc7
+-no-acpi \
99cbc7
+-boot strict=on \
99cbc7
+-device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \
99cbc7
+-spice port=0,gl=on,rendernode=/dev/dri/foo,seamless-migration=on \
99cbc7
+-device cirrus-vga,id=video0,bus=pci.0,addr=0x2 \
99cbc7
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 \
99cbc7
+-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\
99cbc7
+resourcecontrol=deny \
99cbc7
+-msg timestamp=on
99cbc7
diff --git a/tests/qemuxml2argvdata/graphics-spice-gl-auto-rendernode.xml b/tests/qemuxml2argvdata/graphics-spice-gl-auto-rendernode.xml
99cbc7
new file mode 100644
99cbc7
index 0000000000..b48e7bc94e
99cbc7
--- /dev/null
99cbc7
+++ b/tests/qemuxml2argvdata/graphics-spice-gl-auto-rendernode.xml
99cbc7
@@ -0,0 +1,24 @@
99cbc7
+<domain type='qemu'>
99cbc7
+  <name>QEMUGuest1</name>
99cbc7
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
99cbc7
+  <memory unit='KiB'>219136</memory>
99cbc7
+  <currentMemory unit='KiB'>219136</currentMemory>
99cbc7
+  <vcpu placement='static'>1</vcpu>
99cbc7
+  <os>
99cbc7
+    <type arch='i686' machine='pc'>hvm</type>
99cbc7
+    <boot dev='hd'/>
99cbc7
+  </os>
99cbc7
+  <clock offset='utc'/>
99cbc7
+  <on_poweroff>destroy</on_poweroff>
99cbc7
+  <on_reboot>restart</on_reboot>
99cbc7
+  <on_crash>destroy</on_crash>
99cbc7
+  <devices>
99cbc7
+    <emulator>/usr/bin/qemu-system-i686</emulator>
99cbc7
+    <input type='mouse' bus='ps2'/>
99cbc7
+    <input type='keyboard' bus='ps2'/>
99cbc7
+    <graphics type='spice' autoport='no'>
99cbc7
+      <gl enable='yes'/>
99cbc7
+    </graphics>
99cbc7
+    <memballoon model='virtio'/>
99cbc7
+  </devices>
99cbc7
+</domain>
99cbc7
diff --git a/tests/qemuxml2argvmock.c b/tests/qemuxml2argvmock.c
99cbc7
index 4df92cf396..d826793d28 100644
99cbc7
--- a/tests/qemuxml2argvmock.c
99cbc7
+++ b/tests/qemuxml2argvmock.c
99cbc7
@@ -184,6 +184,15 @@ virNetDevRunEthernetScript(const char *ifname ATTRIBUTE_UNUSED,
99cbc7
     return 0;
99cbc7
 }
99cbc7
 
99cbc7
+char *
99cbc7
+virHostGetDRMRenderNode(void)
99cbc7
+{
99cbc7
+    char *dst = NULL;
99cbc7
+
99cbc7
+    ignore_value(VIR_STRDUP(dst, "/dev/dri/foo"));
99cbc7
+    return dst;
99cbc7
+}
99cbc7
+
99cbc7
 void
99cbc7
 virCommandPassFD(virCommandPtr cmd ATTRIBUTE_UNUSED,
99cbc7
                  int fd ATTRIBUTE_UNUSED,
99cbc7
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
99cbc7
index 693e768d66..f76856dc5f 100644
99cbc7
--- a/tests/qemuxml2argvtest.c
99cbc7
+++ b/tests/qemuxml2argvtest.c
99cbc7
@@ -1279,6 +1279,7 @@ mymain(void)
99cbc7
                     QEMU_CAPS_SPICE,
99cbc7
                     QEMU_CAPS_EGL_HEADLESS,
99cbc7
                     QEMU_CAPS_DEVICE_QXL);
99cbc7
+    DO_TEST_CAPS_LATEST("graphics-spice-gl-auto-rendernode");
99cbc7
 
99cbc7
     DO_TEST("input-usbmouse", NONE);
99cbc7
     DO_TEST("input-usbtablet", NONE);
99cbc7
-- 
99cbc7
2.21.0
99cbc7