|
|
01552a |
From 6cffa8daaca920f1d57da40d93ff112f5f096ae9 Mon Sep 17 00:00:00 2001
|
|
|
01552a |
From: Ray Strode <rstrode@redhat.com>
|
|
|
01552a |
Date: Tue, 7 Nov 2017 13:49:30 -0500
|
|
|
01552a |
Subject: [PATCH] device-manager: fall back to text mode if graphical devices
|
|
|
01552a |
fail
|
|
|
01552a |
|
|
|
01552a |
Right now we assume if we find a /dev/dri/card0 that it will work.
|
|
|
01552a |
That may not be true. The proprietary nvidia driver, for instance,
|
|
|
01552a |
provides /dev/dri/card0 but disables modesetting by default.
|
|
|
01552a |
|
|
|
01552a |
This commit makes sure we fall back to text mode if /dev/dri/card0
|
|
|
01552a |
is insufficient for our needs.
|
|
|
01552a |
---
|
|
|
01552a |
src/libply-splash-core/ply-device-manager.c | 25 ++++++++++++++-----------
|
|
|
01552a |
1 file changed, 14 insertions(+), 11 deletions(-)
|
|
|
01552a |
|
|
|
01552a |
diff --git a/src/libply-splash-core/ply-device-manager.c b/src/libply-splash-core/ply-device-manager.c
|
|
|
01552a |
index 14d7616..3a2db06 100644
|
|
|
01552a |
--- a/src/libply-splash-core/ply-device-manager.c
|
|
|
01552a |
+++ b/src/libply-splash-core/ply-device-manager.c
|
|
|
01552a |
@@ -14,61 +14,61 @@
|
|
|
01552a |
*
|
|
|
01552a |
* You should have received a copy of the GNU General Public License
|
|
|
01552a |
* along with this program; if not, write to the Free Software
|
|
|
01552a |
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
|
01552a |
* 02111-1307, USA.
|
|
|
01552a |
*/
|
|
|
01552a |
#include "config.h"
|
|
|
01552a |
#include "ply-device-manager.h"
|
|
|
01552a |
|
|
|
01552a |
#include <assert.h>
|
|
|
01552a |
#include <fcntl.h>
|
|
|
01552a |
#include <stdbool.h>
|
|
|
01552a |
#include <stdlib.h>
|
|
|
01552a |
#include <stdio.h>
|
|
|
01552a |
#include <string.h>
|
|
|
01552a |
#include <sys/inotify.h>
|
|
|
01552a |
#include <sys/stat.h>
|
|
|
01552a |
#include <sys/types.h>
|
|
|
01552a |
|
|
|
01552a |
#include <libudev.h>
|
|
|
01552a |
|
|
|
01552a |
#include "ply-logger.h"
|
|
|
01552a |
#include "ply-event-loop.h"
|
|
|
01552a |
#include "ply-hashtable.h"
|
|
|
01552a |
#include "ply-list.h"
|
|
|
01552a |
#include "ply-utils.h"
|
|
|
01552a |
|
|
|
01552a |
#define SUBSYSTEM_DRM "drm"
|
|
|
01552a |
#define SUBSYSTEM_FRAME_BUFFER "graphics"
|
|
|
01552a |
|
|
|
01552a |
-static void create_devices_for_terminal_and_renderer_type (ply_device_manager_t *manager,
|
|
|
01552a |
+static bool create_devices_for_terminal_and_renderer_type (ply_device_manager_t *manager,
|
|
|
01552a |
const char *device_path,
|
|
|
01552a |
ply_terminal_t *terminal,
|
|
|
01552a |
ply_renderer_type_t renderer_type);
|
|
|
01552a |
struct _ply_device_manager
|
|
|
01552a |
{
|
|
|
01552a |
ply_device_manager_flags_t flags;
|
|
|
01552a |
ply_event_loop_t *loop;
|
|
|
01552a |
ply_hashtable_t *terminals;
|
|
|
01552a |
ply_hashtable_t *renderers;
|
|
|
01552a |
ply_terminal_t *local_console_terminal;
|
|
|
01552a |
ply_list_t *keyboards;
|
|
|
01552a |
ply_list_t *text_displays;
|
|
|
01552a |
ply_list_t *pixel_displays;
|
|
|
01552a |
struct udev *udev_context;
|
|
|
01552a |
struct udev_queue *udev_queue;
|
|
|
01552a |
int udev_queue_fd;
|
|
|
01552a |
ply_fd_watch_t *udev_queue_fd_watch;
|
|
|
01552a |
struct udev_monitor *udev_monitor;
|
|
|
01552a |
|
|
|
01552a |
ply_keyboard_added_handler_t keyboard_added_handler;
|
|
|
01552a |
ply_keyboard_removed_handler_t keyboard_removed_handler;
|
|
|
01552a |
ply_pixel_display_added_handler_t pixel_display_added_handler;
|
|
|
01552a |
ply_pixel_display_removed_handler_t pixel_display_removed_handler;
|
|
|
01552a |
ply_text_display_added_handler_t text_display_added_handler;
|
|
|
01552a |
ply_text_display_removed_handler_t text_display_removed_handler;
|
|
|
01552a |
void *event_handler_data;
|
|
|
01552a |
|
|
|
01552a |
uint32_t local_console_managed : 1;
|
|
|
01552a |
uint32_t local_console_is_text : 1;
|
|
|
01552a |
uint32_t serial_consoles_detected : 1;
|
|
|
01552a |
@@ -134,110 +134,112 @@ fb_device_has_drm_device (ply_device_manager_t *manager,
|
|
|
01552a |
|
|
|
01552a |
/* there should only ever be at most one match so we don't iterate through
|
|
|
01552a |
* the list, but just look at the first entry */
|
|
|
01552a |
card_entry = udev_enumerate_get_list_entry (card_matches);
|
|
|
01552a |
|
|
|
01552a |
if (card_entry != NULL)
|
|
|
01552a |
{
|
|
|
01552a |
struct udev_device *card_device = NULL;
|
|
|
01552a |
const char *card_node;
|
|
|
01552a |
const char *card_path;
|
|
|
01552a |
|
|
|
01552a |
card_path = udev_list_entry_get_name (card_entry);
|
|
|
01552a |
card_device = udev_device_new_from_syspath (manager->udev_context, card_path);
|
|
|
01552a |
card_node = udev_device_get_devnode (card_device);
|
|
|
01552a |
if (card_node != NULL && drm_device_in_use (manager, card_node))
|
|
|
01552a |
has_drm_device = true;
|
|
|
01552a |
else
|
|
|
01552a |
ply_trace ("no card node!");
|
|
|
01552a |
|
|
|
01552a |
udev_device_unref (card_device);
|
|
|
01552a |
}
|
|
|
01552a |
else
|
|
|
01552a |
{
|
|
|
01552a |
ply_trace ("no card entry!");
|
|
|
01552a |
}
|
|
|
01552a |
|
|
|
01552a |
udev_enumerate_unref (card_matches);
|
|
|
01552a |
return has_drm_device;
|
|
|
01552a |
}
|
|
|
01552a |
|
|
|
01552a |
-static void
|
|
|
01552a |
+static bool
|
|
|
01552a |
create_devices_for_udev_device (ply_device_manager_t *manager,
|
|
|
01552a |
struct udev_device *device)
|
|
|
01552a |
{
|
|
|
01552a |
const char *device_path;
|
|
|
01552a |
+ bool created = false;
|
|
|
01552a |
|
|
|
01552a |
device_path = udev_device_get_devnode (device);
|
|
|
01552a |
|
|
|
01552a |
if (device_path != NULL)
|
|
|
01552a |
{
|
|
|
01552a |
const char *subsystem;
|
|
|
01552a |
|
|
|
01552a |
ply_renderer_type_t renderer_type = PLY_RENDERER_TYPE_NONE;
|
|
|
01552a |
|
|
|
01552a |
subsystem = udev_device_get_subsystem (device);
|
|
|
01552a |
ply_trace ("device subsystem is %s", subsystem);
|
|
|
01552a |
|
|
|
01552a |
if (subsystem != NULL && strcmp (subsystem, SUBSYSTEM_DRM) == 0)
|
|
|
01552a |
{
|
|
|
01552a |
ply_trace ("found DRM device %s", device_path);
|
|
|
01552a |
renderer_type = PLY_RENDERER_TYPE_DRM;
|
|
|
01552a |
}
|
|
|
01552a |
else if (strcmp (subsystem, SUBSYSTEM_FRAME_BUFFER) == 0)
|
|
|
01552a |
{
|
|
|
01552a |
ply_trace ("found frame buffer device %s", device_path);
|
|
|
01552a |
if (!fb_device_has_drm_device (manager, device))
|
|
|
01552a |
{
|
|
|
01552a |
renderer_type = PLY_RENDERER_TYPE_FRAME_BUFFER;
|
|
|
01552a |
}
|
|
|
01552a |
else
|
|
|
01552a |
{
|
|
|
01552a |
ply_trace ("ignoring, since there's a DRM device associated with it");
|
|
|
01552a |
}
|
|
|
01552a |
}
|
|
|
01552a |
|
|
|
01552a |
if (renderer_type != PLY_RENDERER_TYPE_NONE)
|
|
|
01552a |
{
|
|
|
01552a |
ply_terminal_t *terminal = NULL;
|
|
|
01552a |
|
|
|
01552a |
if (!manager->local_console_managed)
|
|
|
01552a |
{
|
|
|
01552a |
terminal = manager->local_console_terminal;
|
|
|
01552a |
}
|
|
|
01552a |
|
|
|
01552a |
- create_devices_for_terminal_and_renderer_type (manager,
|
|
|
01552a |
- device_path,
|
|
|
01552a |
- terminal,
|
|
|
01552a |
- renderer_type);
|
|
|
01552a |
+ created = create_devices_for_terminal_and_renderer_type (manager,
|
|
|
01552a |
+ device_path,
|
|
|
01552a |
+ terminal,
|
|
|
01552a |
+ renderer_type);
|
|
|
01552a |
}
|
|
|
01552a |
}
|
|
|
01552a |
+ return created;
|
|
|
01552a |
}
|
|
|
01552a |
|
|
|
01552a |
static void
|
|
|
01552a |
free_displays_for_renderer (ply_device_manager_t *manager,
|
|
|
01552a |
ply_renderer_t *renderer)
|
|
|
01552a |
{
|
|
|
01552a |
ply_list_node_t *node;
|
|
|
01552a |
|
|
|
01552a |
node = ply_list_get_first_node (manager->pixel_displays);
|
|
|
01552a |
while (node != NULL)
|
|
|
01552a |
{
|
|
|
01552a |
ply_list_node_t *next_node;
|
|
|
01552a |
ply_pixel_display_t *display;
|
|
|
01552a |
ply_renderer_t *display_renderer;
|
|
|
01552a |
|
|
|
01552a |
display = ply_list_node_get_data (node);
|
|
|
01552a |
next_node = ply_list_get_next_node (manager->pixel_displays, node);
|
|
|
01552a |
display_renderer = ply_pixel_display_get_renderer (display);
|
|
|
01552a |
|
|
|
01552a |
if (display_renderer == renderer)
|
|
|
01552a |
{
|
|
|
01552a |
if (manager->pixel_display_removed_handler != NULL)
|
|
|
01552a |
manager->pixel_display_removed_handler (manager->event_handler_data, display);
|
|
|
01552a |
|
|
|
01552a |
ply_pixel_display_free (display);
|
|
|
01552a |
ply_list_remove_node (manager->pixel_displays, node);
|
|
|
01552a |
}
|
|
|
01552a |
|
|
|
01552a |
node = next_node;
|
|
|
01552a |
}
|
|
|
01552a |
@@ -300,62 +302,61 @@ create_devices_for_subsystem (ply_device_manager_t *manager,
|
|
|
01552a |
const char *path;
|
|
|
01552a |
|
|
|
01552a |
path = udev_list_entry_get_name (entry);
|
|
|
01552a |
|
|
|
01552a |
if (path == NULL)
|
|
|
01552a |
{
|
|
|
01552a |
ply_trace ("path was null!");
|
|
|
01552a |
continue;
|
|
|
01552a |
}
|
|
|
01552a |
|
|
|
01552a |
ply_trace ("found device %s", path);
|
|
|
01552a |
|
|
|
01552a |
device = udev_device_new_from_syspath (manager->udev_context, path);
|
|
|
01552a |
|
|
|
01552a |
/* if device isn't fully initialized, we'll get an add event later
|
|
|
01552a |
*/
|
|
|
01552a |
if (udev_device_get_is_initialized (device))
|
|
|
01552a |
{
|
|
|
01552a |
ply_trace ("device is initialized");
|
|
|
01552a |
|
|
|
01552a |
/* We only care about devices assigned to a (any) seat. Floating
|
|
|
01552a |
* devices should be ignored.
|
|
|
01552a |
*/
|
|
|
01552a |
if (udev_device_has_tag (device, "seat"))
|
|
|
01552a |
{
|
|
|
01552a |
const char *node;
|
|
|
01552a |
node = udev_device_get_devnode (device);
|
|
|
01552a |
if (node != NULL)
|
|
|
01552a |
{
|
|
|
01552a |
ply_trace ("found node %s", node);
|
|
|
01552a |
- found_device = true;
|
|
|
01552a |
- create_devices_for_udev_device (manager, device);
|
|
|
01552a |
+ found_device = create_devices_for_udev_device (manager, device);
|
|
|
01552a |
}
|
|
|
01552a |
}
|
|
|
01552a |
else
|
|
|
01552a |
{
|
|
|
01552a |
ply_trace ("device doesn't have a seat tag");
|
|
|
01552a |
}
|
|
|
01552a |
}
|
|
|
01552a |
else
|
|
|
01552a |
{
|
|
|
01552a |
ply_trace ("it's not initialized");
|
|
|
01552a |
}
|
|
|
01552a |
|
|
|
01552a |
udev_device_unref (device);
|
|
|
01552a |
}
|
|
|
01552a |
|
|
|
01552a |
udev_enumerate_unref (matches);
|
|
|
01552a |
|
|
|
01552a |
return found_device;
|
|
|
01552a |
}
|
|
|
01552a |
|
|
|
01552a |
static void
|
|
|
01552a |
on_udev_event (ply_device_manager_t *manager)
|
|
|
01552a |
{
|
|
|
01552a |
struct udev_device *device;
|
|
|
01552a |
const char *action;
|
|
|
01552a |
|
|
|
01552a |
device = udev_monitor_receive_device (manager->udev_monitor);
|
|
|
01552a |
if (device == NULL)
|
|
|
01552a |
return;
|
|
|
01552a |
|
|
|
01552a |
@@ -655,137 +656,139 @@ create_pixel_displays_for_renderer (ply_device_manager_t *manager,
|
|
|
01552a |
node = next_node;
|
|
|
01552a |
}
|
|
|
01552a |
}
|
|
|
01552a |
|
|
|
01552a |
static void
|
|
|
01552a |
create_text_displays_for_terminal (ply_device_manager_t *manager,
|
|
|
01552a |
ply_terminal_t *terminal)
|
|
|
01552a |
{
|
|
|
01552a |
ply_text_display_t *display;
|
|
|
01552a |
|
|
|
01552a |
if (!ply_terminal_is_open (terminal))
|
|
|
01552a |
{
|
|
|
01552a |
if (!ply_terminal_open (terminal))
|
|
|
01552a |
{
|
|
|
01552a |
ply_trace ("could not add terminal %s: %m",
|
|
|
01552a |
ply_terminal_get_name (terminal));
|
|
|
01552a |
return;
|
|
|
01552a |
}
|
|
|
01552a |
}
|
|
|
01552a |
|
|
|
01552a |
ply_trace ("adding text display for terminal %s",
|
|
|
01552a |
ply_terminal_get_name (terminal));
|
|
|
01552a |
|
|
|
01552a |
display = ply_text_display_new (terminal);
|
|
|
01552a |
ply_list_append_data (manager->text_displays, display);
|
|
|
01552a |
|
|
|
01552a |
if (manager->text_display_added_handler != NULL)
|
|
|
01552a |
manager->text_display_added_handler (manager->event_handler_data, display);
|
|
|
01552a |
}
|
|
|
01552a |
|
|
|
01552a |
-static void
|
|
|
01552a |
+static bool
|
|
|
01552a |
create_devices_for_terminal_and_renderer_type (ply_device_manager_t *manager,
|
|
|
01552a |
const char *device_path,
|
|
|
01552a |
ply_terminal_t *terminal,
|
|
|
01552a |
ply_renderer_type_t renderer_type)
|
|
|
01552a |
{
|
|
|
01552a |
ply_renderer_t *renderer = NULL;
|
|
|
01552a |
ply_keyboard_t *keyboard = NULL;
|
|
|
01552a |
|
|
|
01552a |
renderer = ply_hashtable_lookup (manager->renderers, (void *) device_path);
|
|
|
01552a |
|
|
|
01552a |
if (renderer != NULL)
|
|
|
01552a |
{
|
|
|
01552a |
ply_trace ("ignoring device %s since it's already managed",
|
|
|
01552a |
device_path);
|
|
|
01552a |
- return;
|
|
|
01552a |
+ return true;
|
|
|
01552a |
}
|
|
|
01552a |
|
|
|
01552a |
ply_trace ("creating devices for %s (renderer type: %u) (terminal: %s)",
|
|
|
01552a |
device_path? : "", renderer_type, terminal? ply_terminal_get_name (terminal): "none");
|
|
|
01552a |
|
|
|
01552a |
if (renderer_type != PLY_RENDERER_TYPE_NONE)
|
|
|
01552a |
{
|
|
|
01552a |
renderer = ply_renderer_new (renderer_type, device_path, terminal);
|
|
|
01552a |
|
|
|
01552a |
if (!ply_renderer_open (renderer))
|
|
|
01552a |
{
|
|
|
01552a |
ply_trace ("could not open renderer for %s", device_path);
|
|
|
01552a |
ply_renderer_free (renderer);
|
|
|
01552a |
renderer = NULL;
|
|
|
01552a |
if (renderer_type != PLY_RENDERER_TYPE_AUTO)
|
|
|
01552a |
- return;
|
|
|
01552a |
+ return false;
|
|
|
01552a |
}
|
|
|
01552a |
}
|
|
|
01552a |
|
|
|
01552a |
if (renderer != NULL)
|
|
|
01552a |
{
|
|
|
01552a |
keyboard = ply_keyboard_new_for_renderer (renderer);
|
|
|
01552a |
ply_list_append_data (manager->keyboards, keyboard);
|
|
|
01552a |
|
|
|
01552a |
if (manager->keyboard_added_handler != NULL)
|
|
|
01552a |
manager->keyboard_added_handler (manager->event_handler_data, keyboard);
|
|
|
01552a |
|
|
|
01552a |
ply_hashtable_insert (manager->renderers, strdup (device_path), renderer);
|
|
|
01552a |
create_pixel_displays_for_renderer (manager, renderer);
|
|
|
01552a |
|
|
|
01552a |
if (manager->renderers_activated)
|
|
|
01552a |
{
|
|
|
01552a |
ply_trace ("activating renderer");
|
|
|
01552a |
ply_renderer_activate (renderer);
|
|
|
01552a |
}
|
|
|
01552a |
}
|
|
|
01552a |
else if (terminal != NULL)
|
|
|
01552a |
{
|
|
|
01552a |
keyboard = ply_keyboard_new_for_terminal (terminal);
|
|
|
01552a |
ply_list_append_data (manager->keyboards, keyboard);
|
|
|
01552a |
|
|
|
01552a |
if (manager->keyboard_added_handler != NULL)
|
|
|
01552a |
manager->keyboard_added_handler (manager->event_handler_data, keyboard);
|
|
|
01552a |
}
|
|
|
01552a |
|
|
|
01552a |
if (terminal != NULL)
|
|
|
01552a |
{
|
|
|
01552a |
create_text_displays_for_terminal (manager, terminal);
|
|
|
01552a |
|
|
|
01552a |
if (terminal == manager->local_console_terminal)
|
|
|
01552a |
{
|
|
|
01552a |
manager->local_console_is_text = renderer == NULL;
|
|
|
01552a |
manager->local_console_managed = true;
|
|
|
01552a |
}
|
|
|
01552a |
}
|
|
|
01552a |
|
|
|
01552a |
if (keyboard != NULL && manager->keyboards_activated)
|
|
|
01552a |
{
|
|
|
01552a |
ply_trace ("activating keyboards");
|
|
|
01552a |
ply_keyboard_watch_for_input (keyboard);
|
|
|
01552a |
}
|
|
|
01552a |
+
|
|
|
01552a |
+ return true;
|
|
|
01552a |
}
|
|
|
01552a |
|
|
|
01552a |
static void
|
|
|
01552a |
create_devices_for_terminal (const char *device_path,
|
|
|
01552a |
ply_terminal_t *terminal,
|
|
|
01552a |
ply_device_manager_t *manager)
|
|
|
01552a |
{
|
|
|
01552a |
create_devices_for_terminal_and_renderer_type (manager,
|
|
|
01552a |
device_path,
|
|
|
01552a |
terminal,
|
|
|
01552a |
PLY_RENDERER_TYPE_NONE);
|
|
|
01552a |
}
|
|
|
01552a |
static bool
|
|
|
01552a |
create_devices_from_terminals (ply_device_manager_t *manager)
|
|
|
01552a |
{
|
|
|
01552a |
bool has_serial_consoles;
|
|
|
01552a |
|
|
|
01552a |
ply_trace ("checking for consoles");
|
|
|
01552a |
|
|
|
01552a |
if (manager->flags & PLY_DEVICE_MANAGER_FLAGS_IGNORE_SERIAL_CONSOLES)
|
|
|
01552a |
{
|
|
|
01552a |
has_serial_consoles = false;
|
|
|
01552a |
ply_trace ("ignoring all consoles but default console because explicitly told to.");
|
|
|
01552a |
}
|
|
|
01552a |
else
|
|
|
01552a |
{
|
|
|
01552a |
has_serial_consoles = add_consoles_from_file (manager, "/sys/class/tty/console/active");
|
|
|
01552a |
}
|
|
|
01552a |
|
|
|
01552a |
if (has_serial_consoles)
|
|
|
01552a |
--
|
|
|
01552a |
2.14.3
|
|
|
01552a |
|