99cbc7
From a3e0637aa224b31438a8ae550344362ee02a327b Mon Sep 17 00:00:00 2001
99cbc7
Message-Id: <a3e0637aa224b31438a8ae550344362ee02a327b@dist-git>
99cbc7
From: Erik Skultety <eskultet@redhat.com>
99cbc7
Date: Tue, 9 Apr 2019 08:34:25 +0200
99cbc7
Subject: [PATCH] util: Introduce virHostGetDRMRenderNode helper
99cbc7
MIME-Version: 1.0
99cbc7
Content-Type: text/plain; charset=UTF-8
99cbc7
Content-Transfer-Encoding: 8bit
99cbc7
99cbc7
This is the first step towards libvirt picking the first available
99cbc7
render node instead of QEMU. It also makes sense for us to be able to do
99cbc7
that, since we allow specifying the node directly for SPICE, so if
99cbc7
there's no render node specified by the user, we should pick the first
99cbc7
available one. The algorithm used for that is essentially the same as
99cbc7
the one QEMU uses.
99cbc7
99cbc7
Signed-off-by: Erik Skultety <eskultet@redhat.com>
99cbc7
Reviewed-by: Ján Tomko <jtomko@redhat.com>
99cbc7
(cherry picked from commit 394809694a5bcb6e1e6890f360c60993c0b63a74)
99cbc7
99cbc7
https: //bugzilla.redhat.com/show_bug.cgi?id=1628892
99cbc7
Signed-off-by: Erik Skultety <eskultet@redhat.com>
99cbc7
Message-Id: <48159f44f12685eb8c52061e09c27e37a5a157ea.1554791287.git.eskultet@redhat.com>
99cbc7
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
99cbc7
---
99cbc7
 src/libvirt_private.syms |  1 +
99cbc7
 src/util/virutil.c       | 53 ++++++++++++++++++++++++++++++++++++++++
99cbc7
 src/util/virutil.h       |  2 ++
99cbc7
 3 files changed, 56 insertions(+)
99cbc7
99cbc7
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
99cbc7
index af9b61fbdc..6655dfdecc 100644
99cbc7
--- a/src/libvirt_private.syms
99cbc7
+++ b/src/libvirt_private.syms
99cbc7
@@ -3116,6 +3116,7 @@ virGetUserName;
99cbc7
 virGetUserRuntimeDirectory;
99cbc7
 virGetUserShell;
99cbc7
 virHexToBin;
99cbc7
+virHostGetDRMRenderNode;
99cbc7
 virHostHasIOMMU;
99cbc7
 virIndexToDiskName;
99cbc7
 virIsDevMapperDevice;
99cbc7
diff --git a/src/util/virutil.c b/src/util/virutil.c
99cbc7
index a908422feb..b25d2a5ca4 100644
99cbc7
--- a/src/util/virutil.c
99cbc7
+++ b/src/util/virutil.c
99cbc7
@@ -2115,3 +2115,56 @@ virHostHasIOMMU(void)
99cbc7
     VIR_DIR_CLOSE(iommuDir);
99cbc7
     return ret;
99cbc7
 }
99cbc7
+
99cbc7
+
99cbc7
+/**
99cbc7
+ * virHostGetDRMRenderNode:
99cbc7
+ *
99cbc7
+ * Picks the first DRM render node available. Missing DRI or missing DRM render
99cbc7
+ * nodes in the system results in an error.
99cbc7
+ *
99cbc7
+ * Returns an absolute path to the first render node available or NULL in case
99cbc7
+ * of an error with the error being reported.
99cbc7
+ * Caller is responsible for freeing the result string.
99cbc7
+ *
99cbc7
+ */
99cbc7
+char *
99cbc7
+virHostGetDRMRenderNode(void)
99cbc7
+{
99cbc7
+    char *ret = NULL;
99cbc7
+    DIR *driDir = NULL;
99cbc7
+    const char *driPath = "/dev/dri";
99cbc7
+    struct dirent *ent = NULL;
99cbc7
+    int dirErr = 0;
99cbc7
+    bool have_rendernode = false;
99cbc7
+
99cbc7
+    if (virDirOpen(&driDir, driPath) < 0)
99cbc7
+        return NULL;
99cbc7
+
99cbc7
+    while ((dirErr = virDirRead(driDir, &ent, driPath)) > 0) {
99cbc7
+        if (ent->d_type != DT_CHR)
99cbc7
+            continue;
99cbc7
+
99cbc7
+        if (STRPREFIX(ent->d_name, "renderD")) {
99cbc7
+            have_rendernode = true;
99cbc7
+            break;
99cbc7
+        }
99cbc7
+    }
99cbc7
+
99cbc7
+    if (dirErr < 0)
99cbc7
+        goto cleanup;
99cbc7
+
99cbc7
+    /* even if /dev/dri exists, there might be no renderDX nodes available */
99cbc7
+    if (!have_rendernode) {
99cbc7
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
99cbc7
+                       _("No DRM render nodes available"));
99cbc7
+        goto cleanup;
99cbc7
+    }
99cbc7
+
99cbc7
+    if (virAsprintf(&ret, "%s/%s", driPath, ent->d_name) < 0)
99cbc7
+        goto cleanup;
99cbc7
+
99cbc7
+ cleanup:
99cbc7
+    VIR_DIR_CLOSE(driDir);
99cbc7
+    return ret;
99cbc7
+}
99cbc7
diff --git a/src/util/virutil.h b/src/util/virutil.h
99cbc7
index 1ba9635bd9..284c713be4 100644
99cbc7
--- a/src/util/virutil.h
99cbc7
+++ b/src/util/virutil.h
99cbc7
@@ -218,6 +218,8 @@ unsigned long long virMemoryMaxValue(bool ulong) ATTRIBUTE_NOINLINE;
99cbc7
 
99cbc7
 bool virHostHasIOMMU(void);
99cbc7
 
99cbc7
+char *virHostGetDRMRenderNode(void);
99cbc7
+
99cbc7
 /**
99cbc7
  * VIR_ASSIGN_IS_OVERFLOW:
99cbc7
  * @rvalue: value that is checked (evaluated twice)
99cbc7
-- 
99cbc7
2.21.0
99cbc7