]> xenbits.xensource.com Git - libvirt.git/commitdiff
util: Introduce virHostGetDRMRenderNode helper
authorErik Skultety <eskultet@redhat.com>
Thu, 8 Nov 2018 10:47:09 +0000 (11:47 +0100)
committerErik Skultety <eskultet@redhat.com>
Mon, 3 Dec 2018 13:56:08 +0000 (14:56 +0100)
This is the first step towards libvirt picking the first available
render node instead of QEMU. It also makes sense for us to be able to do
that, since we allow specifying the node directly for SPICE, so if
there's no render node specified by the user, we should pick the first
available one. The algorithm used for that is essentially the same as
the one QEMU uses.

Signed-off-by: Erik Skultety <eskultet@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
src/libvirt_private.syms
src/util/virutil.c
src/util/virutil.h

index 5018a13e9c99c366c8aa66dfeaa3cfbbc05e9851..c7f08f96204f19e7d6dc7265e0e43caa4858e35b 100644 (file)
@@ -3151,6 +3151,7 @@ virGetUserName;
 virGetUserRuntimeDirectory;
 virGetUserShell;
 virHexToBin;
+virHostGetDRMRenderNode;
 virHostHasIOMMU;
 virIndexToDiskName;
 virIsDevMapperDevice;
index 974cffc2eeb74a93407211969020c4143d5dbd0d..da12a11e04a5d90cdc709194d0862f8818ad2bde 100644 (file)
@@ -2145,3 +2145,56 @@ virHostHasIOMMU(void)
     VIR_DIR_CLOSE(iommuDir);
     return ret;
 }
+
+
+/**
+ * virHostGetDRMRenderNode:
+ *
+ * Picks the first DRM render node available. Missing DRI or missing DRM render
+ * nodes in the system results in an error.
+ *
+ * Returns an absolute path to the first render node available or NULL in case
+ * of an error with the error being reported.
+ * Caller is responsible for freeing the result string.
+ *
+ */
+char *
+virHostGetDRMRenderNode(void)
+{
+    char *ret = NULL;
+    DIR *driDir = NULL;
+    const char *driPath = "/dev/dri";
+    struct dirent *ent = NULL;
+    int dirErr = 0;
+    bool have_rendernode = false;
+
+    if (virDirOpen(&driDir, driPath) < 0)
+        return NULL;
+
+    while ((dirErr = virDirRead(driDir, &ent, driPath)) > 0) {
+        if (ent->d_type != DT_CHR)
+            continue;
+
+        if (STRPREFIX(ent->d_name, "renderD")) {
+            have_rendernode = true;
+            break;
+        }
+    }
+
+    if (dirErr < 0)
+        goto cleanup;
+
+    /* even if /dev/dri exists, there might be no renderDX nodes available */
+    if (!have_rendernode) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("No DRM render nodes available"));
+        goto cleanup;
+    }
+
+    if (virAsprintf(&ret, "%s/%s", driPath, ent->d_name) < 0)
+        goto cleanup;
+
+ cleanup:
+    VIR_DIR_CLOSE(driDir);
+    return ret;
+}
index e0ab0da0f2fc0a03c197179c485afb59b46992dc..89bd21b14843d3c14fc4deda2994a18aa23ef3ac 100644 (file)
@@ -222,6 +222,8 @@ unsigned long long virMemoryMaxValue(bool ulong) ATTRIBUTE_NOINLINE;
 
 bool virHostHasIOMMU(void);
 
+char *virHostGetDRMRenderNode(void);
+
 /**
  * VIR_ASSIGN_IS_OVERFLOW:
  * @rvalue: value that is checked (evaluated twice)