1
0
Fork 0

backend/native: Find render node directly via udev

Don't try to find the card, and then the render node from it, just ask
udev to list the render nodes directly. This avoids running into
permission errors when the user cannot open /dev/dri/card* even without
mode setting capabilities.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3805>
(cherry picked from commit 6bd2fd6a74)
This commit is contained in:
Jonas Ådahl 2024-06-12 10:54:59 +02:00
parent e1efc4c64e
commit 80d1b79849
5 changed files with 44 additions and 42 deletions

View file

@ -418,38 +418,6 @@ create_render_device (MetaBackendNative *backend_native,
if (!device_file)
return NULL;
if (meta_backend_is_headless (backend))
{
int fd;
g_autofree char *render_node_path = NULL;
g_autoptr (MetaDeviceFile) render_node_device_file = NULL;
fd = meta_device_file_get_fd (device_file);
render_node_path = drmGetRenderDeviceNameFromFd (fd);
if (!render_node_path)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Couldn't find render node device for '%s'",
meta_device_file_get_path (device_file));
return NULL;
}
meta_topic (META_DEBUG_KMS, "Found render node '%s' from '%s'",
render_node_path,
meta_device_file_get_path (device_file));
render_node_device_file =
meta_device_pool_open (device_pool, render_node_path,
META_DEVICE_FILE_FLAG_NONE,
error);
if (!render_node_device_file)
return NULL;
g_clear_pointer (&device_file, meta_device_file_release);
device_file = g_steal_pointer (&render_node_device_file);
}
#ifdef HAVE_EGL_DEVICE
if (g_strcmp0 (getenv ("MUTTER_DEBUG_FORCE_EGL_STREAM"), "1") != 0)
#endif
@ -642,10 +610,22 @@ init_gpus (MetaBackendNative *native,
MetaBackend *backend = META_BACKEND (native);
MetaUdev *udev = meta_backend_native_get_udev (native);
g_autoptr (GError) local_error = NULL;
MetaUdevDeviceType device_type = 0;
GList *devices;
GList *l;
devices = meta_udev_list_drm_devices (udev, &local_error);
switch (native->mode)
{
case META_BACKEND_NATIVE_MODE_DEFAULT:
case META_BACKEND_NATIVE_MODE_TEST:
device_type = META_UDEV_DEVICE_TYPE_CARD;
break;
case META_BACKEND_NATIVE_MODE_HEADLESS:
device_type = META_UDEV_DEVICE_TYPE_RENDER_NODE;
break;
}
devices = meta_udev_list_drm_devices (udev, device_type, &local_error);
if (local_error)
{
g_propagate_error (error, g_steal_pointer (&local_error));

View file

@ -164,8 +164,9 @@ meta_udev_is_drm_device (MetaUdev *udev,
}
GList *
meta_udev_list_drm_devices (MetaUdev *udev,
GError **error)
meta_udev_list_drm_devices (MetaUdev *udev,
MetaUdevDeviceType device_type,
GError **error)
{
g_autoptr (GUdevEnumerator) enumerator = NULL;
GList *devices;
@ -173,8 +174,16 @@ meta_udev_list_drm_devices (MetaUdev *udev,
enumerator = g_udev_enumerator_new (udev->gudev_client);
g_udev_enumerator_add_match_name (enumerator, "card*");
g_udev_enumerator_add_match_tag (enumerator, "seat");
switch (device_type)
{
case META_UDEV_DEVICE_TYPE_CARD:
g_udev_enumerator_add_match_name (enumerator, "card*");
g_udev_enumerator_add_match_tag (enumerator, "seat");
break;
case META_UDEV_DEVICE_TYPE_RENDER_NODE:
g_udev_enumerator_add_match_name (enumerator, "render*");
break;
}
/*
* We need to explicitly match the subsystem for now.

View file

@ -23,6 +23,12 @@
#include "backends/native/meta-backend-native-types.h"
#include "core/util-private.h"
typedef enum _MetaUdevDeviceType
{
META_UDEV_DEVICE_TYPE_CARD,
META_UDEV_DEVICE_TYPE_RENDER_NODE,
} MetaUdevDeviceType;
#define META_TYPE_UDEV (meta_udev_get_type ())
G_DECLARE_FINAL_TYPE (MetaUdev, meta_udev, META, UDEV, GObject)
@ -44,8 +50,9 @@ gboolean meta_udev_is_drm_device (MetaUdev *udev,
GUdevDevice *device);
META_EXPORT_TEST
GList * meta_udev_list_drm_devices (MetaUdev *udev,
GError **error);
GList * meta_udev_list_drm_devices (MetaUdev *udev,
MetaUdevDeviceType device_type,
GError **error);
void meta_udev_pause (MetaUdev *udev);

View file

@ -84,7 +84,9 @@ meta_test_headless_monitor_connect (void)
drm_mock_unset_resource_filter (DRM_MOCK_CALL_FILTER_GET_CONNECTOR);
udev_devices = meta_udev_list_drm_devices (udev, &error);
udev_devices = meta_udev_list_drm_devices (udev,
META_UDEV_DEVICE_TYPE_CARD,
&error);
g_assert_cmpuint (g_list_length (udev_devices), ==, 1);
g_signal_emit_by_name (udev, "hotplug", g_list_first (udev_devices)->data);

View file

@ -147,7 +147,9 @@ meta_test_disconnect_connect (void)
g_autoptr (GError) error = NULL;
State state;
udev_devices = meta_udev_list_drm_devices (udev, &error);
udev_devices = meta_udev_list_drm_devices (udev,
META_UDEV_DEVICE_TYPE_CARD,
&error);
g_assert_cmpuint (g_list_length (udev_devices), ==, 1);
udev_device = g_list_first (udev_devices)->data;
@ -374,7 +376,9 @@ emulate_hotplug (void)
g_autolist (GObject) udev_devices = NULL;
GUdevDevice *udev_device;
udev_devices = meta_udev_list_drm_devices (udev, &error);
udev_devices = meta_udev_list_drm_devices (udev,
META_UDEV_DEVICE_TYPE_CARD,
&error);
g_assert_cmpuint (g_list_length (udev_devices), ==, 1);
udev_device = g_list_first (udev_devices)->data;
g_signal_emit_by_name (udev, "hotplug", udev_device);