diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 5018a13e9c99c366c8aa66dfeaa3cfbbc05e9851..c7f08f96204f19e7d6dc7265e0e43caa4858e35b 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -3151,6 +3151,7 @@ virGetUserName; virGetUserRuntimeDirectory; virGetUserShell; virHexToBin; +virHostGetDRMRenderNode; virHostHasIOMMU; virIndexToDiskName; virIsDevMapperDevice; diff --git a/src/util/virutil.c b/src/util/virutil.c index 974cffc2eeb74a93407211969020c4143d5dbd0d..da12a11e04a5d90cdc709194d0862f8818ad2bde 100644 --- a/src/util/virutil.c +++ b/src/util/virutil.c @@ -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; +} diff --git a/src/util/virutil.h b/src/util/virutil.h index e0ab0da0f2fc0a03c197179c485afb59b46992dc..89bd21b14843d3c14fc4deda2994a18aa23ef3ac 100644 --- a/src/util/virutil.h +++ b/src/util/virutil.h @@ -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)