Blame SOURCES/ignore-early-fb-devices.patch

e22087
From 10e686c2128bde0e70e7c137191dbe004d2f46fd Mon Sep 17 00:00:00 2001
e22087
From: Ray Strode <rstrode@redhat.com>
e22087
Date: Mon, 3 Mar 2014 13:27:30 -0500
e22087
Subject: [PATCH 1/2] device-manager: handle drm hotplug separately from
e22087
 /dev/fb
e22087
e22087
Right now, we piggyback off fb subsystem events to know whether or
e22087
not a drm device is hotplugged (since all drm devices have fb devices
e22087
for backward compat).
e22087
e22087
This commit makes drm and fb processing more independent, so we don't
e22087
rely on the compat device being available for drm hotplug to work..
e22087
---
e22087
 src/libply-splash-core/ply-device-manager.c | 182 ++++++++++++++--------------
e22087
 1 file changed, 89 insertions(+), 93 deletions(-)
e22087
e22087
diff --git a/src/libply-splash-core/ply-device-manager.c b/src/libply-splash-core/ply-device-manager.c
e22087
index 36e814d..25f7d54 100644
e22087
--- a/src/libply-splash-core/ply-device-manager.c
e22087
+++ b/src/libply-splash-core/ply-device-manager.c
e22087
@@ -11,60 +11,63 @@
e22087
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
e22087
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
e22087
  * GNU General Public License for more details.
e22087
  *
e22087
  * You should have received a copy of the GNU General Public License
e22087
  * along with this program; if not, write to the Free Software
e22087
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
e22087
  * 02111-1307, USA.
e22087
  */
e22087
 #include "config.h"
e22087
 #include "ply-device-manager.h"
e22087
 
e22087
 #include <assert.h>
e22087
 #include <fcntl.h>
e22087
 #include <stdbool.h>
e22087
 #include <stdlib.h>
e22087
 #include <stdio.h>
e22087
 #include <string.h>
e22087
 #include <sys/inotify.h>
e22087
 #include <sys/stat.h>
e22087
 #include <sys/types.h>
e22087
 
e22087
 #include <libudev.h>
e22087
 
e22087
 #include "ply-logger.h"
e22087
 #include "ply-event-loop.h"
e22087
 #include "ply-hashtable.h"
e22087
 #include "ply-list.h"
e22087
 #include "ply-utils.h"
e22087
 
e22087
+#define SUBSYSTEM_DRM "drm"
e22087
+#define SUBSYSTEM_FRAME_BUFFER "graphics"
e22087
+
e22087
 static void create_seat_for_terminal_and_renderer_type (ply_device_manager_t *manager,
e22087
                                                         const char           *device_path,
e22087
                                                         ply_terminal_t       *terminal,
e22087
                                                         ply_renderer_type_t   renderer_type);
e22087
 struct _ply_device_manager
e22087
 {
e22087
   ply_device_manager_flags_t  flags;
e22087
   ply_event_loop_t           *loop;
e22087
   ply_hashtable_t            *terminals;
e22087
   ply_terminal_t             *local_console_terminal;
e22087
   ply_seat_t                 *local_console_seat;
e22087
   ply_list_t                 *seats;
e22087
   struct udev                *udev_context;
e22087
   struct udev_queue          *udev_queue;
e22087
   int                         udev_queue_fd;
e22087
   ply_fd_watch_t             *udev_queue_fd_watch;
e22087
   struct udev_monitor        *udev_monitor;
e22087
 
e22087
   ply_seat_added_handler_t    seat_added_handler;
e22087
   ply_seat_removed_handler_t  seat_removed_handler;
e22087
   void                       *seat_event_handler_data;
e22087
 };
e22087
 
e22087
 static void
e22087
 detach_from_event_loop (ply_device_manager_t *manager)
e22087
 {
e22087
   assert (manager != NULL);
e22087
 
e22087
   manager->loop = NULL;
e22087
 }
e22087
@@ -84,342 +87,334 @@ attach_to_event_loop (ply_device_manager_t *manager,
e22087
                                  manager);
e22087
 }
e22087
 
e22087
 static bool
e22087
 device_is_for_local_console (ply_device_manager_t *manager,
e22087
                              struct udev_device   *device)
e22087
 {
e22087
   const char *device_path;
e22087
   struct udev_device *bus_device;
e22087
   char *bus_device_path;
e22087
   const char *boot_vga;
e22087
   bool for_local_console;
e22087
 
e22087
   /* Look at the associated bus device to see if this card is the
e22087
    * card the kernel is using for its console. */
e22087
   device_path = udev_device_get_syspath (device);
e22087
   asprintf (&bus_device_path, "%s/device", device_path);
e22087
   bus_device = udev_device_new_from_syspath (manager->udev_context, bus_device_path);
e22087
 
e22087
   boot_vga = udev_device_get_sysattr_value (bus_device, "boot_vga");
e22087
   free (bus_device_path);
e22087
 
e22087
   if (boot_vga != NULL && strcmp (boot_vga, "1") == 0)
e22087
     for_local_console = true;
e22087
   else
e22087
     for_local_console = false;
e22087
 
e22087
   return for_local_console;
e22087
 }
e22087
 
e22087
-static char *
e22087
-get_drm_device_node_path_from_fb_device (ply_device_manager_t *manager,
e22087
-                                         struct udev_device   *fb_device)
e22087
+static bool
e22087
+fb_device_has_drm_device (ply_device_manager_t *manager,
e22087
+                          struct udev_device   *fb_device)
e22087
 {
e22087
   struct udev_enumerate *card_matches;
e22087
   struct udev_list_entry *card_entry;
e22087
   const char *id_path;
e22087
-  char *device_node_path = NULL;
e22087
+  bool has_drm_device = false;
e22087
 
e22087
   /* We want to see if the framebuffer is associated with a DRM-capable
e22087
    * graphics card, if it is, we'll use the DRM device */
e22087
   card_matches = udev_enumerate_new (manager->udev_context);
e22087
   udev_enumerate_add_match_is_initialized(card_matches);
e22087
   udev_enumerate_add_match_parent (card_matches, udev_device_get_parent (fb_device));
e22087
   udev_enumerate_add_match_subsystem (card_matches, "drm");
e22087
   id_path = udev_device_get_property_value (fb_device, "ID_PATH");
e22087
   udev_enumerate_add_match_property (card_matches, "ID_PATH", id_path);
e22087
 
e22087
   ply_trace ("trying to find associated drm node for fb device (path: %s)", id_path);
e22087
 
e22087
   udev_enumerate_scan_devices (card_matches);
e22087
 
e22087
   /* there should only ever be at most one match so we don't iterate through
e22087
    * the list, but just look at the first entry */
e22087
   card_entry = udev_enumerate_get_list_entry (card_matches);
e22087
 
e22087
   if (card_entry != NULL)
e22087
     {
e22087
       struct udev_device *card_device = NULL;
e22087
       const char *card_node;
e22087
       const char *card_path;
e22087
 
e22087
       card_path = udev_list_entry_get_name (card_entry);
e22087
       card_device = udev_device_new_from_syspath (manager->udev_context, card_path);
e22087
       card_node = udev_device_get_devnode (card_device);
e22087
       if (card_node != NULL)
e22087
-        device_node_path = strdup (card_node);
e22087
+        has_drm_device = true;
e22087
       else
e22087
         ply_trace ("no card node!");
e22087
 
e22087
       udev_device_unref (card_device);
e22087
     }
e22087
   else
e22087
     {
e22087
       ply_trace ("no card entry!");
e22087
     }
e22087
 
e22087
   udev_enumerate_unref (card_matches);
e22087
-  return device_node_path;
e22087
+  return has_drm_device;
e22087
 }
e22087
 
e22087
 static void
e22087
 create_seat_for_udev_device (ply_device_manager_t *manager,
e22087
                              struct udev_device   *device)
e22087
 {
e22087
   bool for_local_console;
e22087
-  char *card_path;
e22087
+  const char *device_path;
e22087
   ply_terminal_t *terminal = NULL;
e22087
 
e22087
   for_local_console = device_is_for_local_console (manager, device);
e22087
 
e22087
   ply_trace ("device is for local console: %s", for_local_console? "yes" : "no");
e22087
 
e22087
   if (for_local_console)
e22087
     terminal = manager->local_console_terminal;
e22087
 
e22087
-  card_path = get_drm_device_node_path_from_fb_device (manager, device);
e22087
+  device_path = udev_device_get_devnode (device);
e22087
 
e22087
-  if (card_path != NULL)
e22087
-    {
e22087
-      create_seat_for_terminal_and_renderer_type (manager,
e22087
-                                                  card_path,
e22087
-                                                  terminal,
e22087
-                                                  PLY_RENDERER_TYPE_DRM);
e22087
-      free (card_path);
e22087
-    }
e22087
-  else
e22087
+  if (device_path != NULL)
e22087
     {
e22087
-      const char *fb_device_node_path;
e22087
+      const char *subsystem;
e22087
+      ply_renderer_type_t renderer_type = PLY_RENDERER_TYPE_NONE;
e22087
+
e22087
+      subsystem = udev_device_get_subsystem (device);
e22087
+
e22087
+      if (strcmp (subsystem, SUBSYSTEM_DRM) == 0)
e22087
+        {
e22087
+          ply_trace ("found DRM device %s", device_path);
e22087
+          renderer_type = PLY_RENDERER_TYPE_DRM;
e22087
+        }
e22087
+      else if (strcmp (subsystem, SUBSYSTEM_FRAME_BUFFER) == 0)
e22087
+        {
e22087
+          ply_trace ("found frame buffer device %s", device_path);
e22087
+          if (!fb_device_has_drm_device (manager, device))
e22087
+            {
e22087
+              renderer_type = PLY_RENDERER_TYPE_FRAME_BUFFER;
e22087
+            }
e22087
+          else
e22087
+            {
e22087
+              ply_trace ("ignoring, since there's a DRM device associated with it");
e22087
+            }
e22087
+        }
e22087
 
e22087
-      fb_device_node_path = udev_device_get_devnode (device);
e22087
-      if (fb_device_node_path != NULL)
e22087
+      if (renderer_type != PLY_RENDERER_TYPE_NONE)
e22087
         create_seat_for_terminal_and_renderer_type (manager,
e22087
-                                                    fb_device_node_path,
e22087
+                                                    device_path,
e22087
                                                     terminal,
e22087
-                                                    PLY_RENDERER_TYPE_FRAME_BUFFER);
e22087
+                                                    renderer_type);
e22087
     }
e22087
 }
e22087
 
e22087
 static void
e22087
 free_seat_from_device_path (ply_device_manager_t *manager,
e22087
                             const char           *device_path)
e22087
 {
e22087
   ply_list_node_t *node;
e22087
 
e22087
   node = ply_list_get_first_node (manager->seats);
e22087
   while (node != NULL)
e22087
     {
e22087
       ply_seat_t *seat;
e22087
       ply_renderer_t *renderer;
e22087
       ply_list_node_t *next_node;
e22087
       const char *renderer_device_path;
e22087
 
e22087
       seat = ply_list_node_get_data (node);
e22087
       next_node = ply_list_get_next_node (manager->seats, node);
e22087
       renderer = ply_seat_get_renderer (seat);
e22087
 
e22087
       if (renderer != NULL)
e22087
         {
e22087
           renderer_device_path = ply_renderer_get_device_name (renderer);
e22087
 
e22087
           if (renderer_device_path != NULL)
e22087
             {
e22087
               if (strcmp (device_path, renderer_device_path) == 0)
e22087
                 {
e22087
                   ply_trace ("removing seat associated with %s", device_path);
e22087
 
e22087
                   if (manager->seat_removed_handler != NULL)
e22087
                     manager->seat_removed_handler (manager->seat_event_handler_data, seat);
e22087
 
e22087
                   ply_seat_free (seat);
e22087
                   ply_list_remove_node (manager->seats, node);
e22087
                   break;
e22087
                 }
e22087
             }
e22087
         }
e22087
 
e22087
       node = next_node;
e22087
     }
e22087
 }
e22087
 
e22087
 static void
e22087
 free_seat_for_udev_device (ply_device_manager_t *manager,
e22087
                            struct udev_device   *device)
e22087
 {
e22087
-  char *card_path;
e22087
-
e22087
- card_path = get_drm_device_node_path_from_fb_device (manager, device);
e22087
-
e22087
-  if (card_path != NULL)
e22087
-    {
e22087
-      free_seat_from_device_path (manager, card_path);
e22087
-      free (card_path);
e22087
-    }
e22087
-  else
e22087
-    {
e22087
-      const char *fb_device_node_path;
e22087
+  const char *device_path;
e22087
 
e22087
-      fb_device_node_path = udev_device_get_devnode (device);
e22087
+  device_path = udev_device_get_devnode (device);
e22087
 
e22087
-      if (fb_device_node_path != NULL)
e22087
-        free_seat_from_device_path (manager, fb_device_node_path);
e22087
-    }
e22087
+  if (device_path != NULL)
e22087
+    free_seat_from_device_path (manager, device_path);
e22087
 }
e22087
 
e22087
 static bool
e22087
-scan_graphics_devices (ply_device_manager_t *manager)
e22087
+create_seats_for_subsystem (ply_device_manager_t *manager,
e22087
+                            const char           *subsystem)
e22087
 {
e22087
-  struct udev_enumerate *fb_matches;
e22087
-  struct udev_list_entry *fb_entry;
e22087
+  struct udev_enumerate *matches;
e22087
+  struct udev_list_entry *entry;
e22087
   bool found_device = false;
e22087
 
e22087
-  ply_trace ("scanning for graphics devices");
e22087
-  /* graphics subsystem is for /dev/fb devices.  kms drivers provide /dev/fb for backward
e22087
-   * compatibility, and do so at the end of their initialization, so we can be confident
e22087
-   * that when this subsystem is available the drm device is fully initialized */
e22087
-  fb_matches = udev_enumerate_new (manager->udev_context);
e22087
-  udev_enumerate_add_match_subsystem (fb_matches, "graphics");
e22087
-  udev_enumerate_scan_devices (fb_matches);
e22087
+  ply_trace ("creating seats for %s devices",
e22087
+             strcmp (subsystem, SUBSYSTEM_FRAME_BUFFER) == 0?
e22087
+             "frame buffer":
e22087
+             subsystem);
e22087
 
e22087
-  udev_list_entry_foreach (fb_entry, udev_enumerate_get_list_entry (fb_matches))
e22087
+  matches = udev_enumerate_new (manager->udev_context);
e22087
+  udev_enumerate_add_match_subsystem (matches, subsystem);
e22087
+  udev_enumerate_scan_devices (matches);
e22087
+
e22087
+  udev_list_entry_foreach (entry, udev_enumerate_get_list_entry (matches))
e22087
     {
e22087
-      struct udev_device *fb_device = NULL;
e22087
-      const char *fb_path;
e22087
+      struct udev_device *device = NULL;
e22087
+      const char *path;
e22087
 
e22087
-      fb_path = udev_list_entry_get_name (fb_entry);
e22087
+      path = udev_list_entry_get_name (entry);
e22087
 
e22087
-      if (fb_path == NULL)
e22087
+      if (path == NULL)
e22087
         {
e22087
-          ply_trace ("fb path was null!");
e22087
+          ply_trace ("path was null!");
e22087
           continue;
e22087
         }
e22087
 
e22087
-      ply_trace ("found device %s", fb_path);
e22087
+      ply_trace ("found device %s", path);
e22087
 
e22087
-      /* skip virtual fbcon device
e22087
-       */
e22087
-      if (strcmp (fb_path, "/sys/devices/virtual/graphics/fbcon") == 0)
e22087
-        {
e22087
-          ply_trace ("ignoring since it's fbcon");
e22087
-          continue;
e22087
-        }
e22087
-
e22087
-      fb_device = udev_device_new_from_syspath (manager->udev_context, fb_path);
e22087
+      device = udev_device_new_from_syspath (manager->udev_context, path);
e22087
 
e22087
       /* if device isn't fully initialized, we'll get an add event later
e22087
        */
e22087
-      if (udev_device_get_is_initialized (fb_device))
e22087
+      if (udev_device_get_is_initialized (device))
e22087
         {
e22087
           ply_trace ("device is initialized");
e22087
+
e22087
           /* We only care about devices assigned to a (any) seat. Floating
e22087
-           * devices should be ignored.  As a side-effect, this conveniently
e22087
-           * filters out the fbcon device which we don't care about.
e22087
+           * devices should be ignored.
e22087
            */
e22087
-          if (udev_device_has_tag (fb_device, "seat"))
e22087
+          if (udev_device_has_tag (device, "seat"))
e22087
             {
e22087
-              const char *fb_node;
e22087
-              fb_node = udev_device_get_devnode (fb_device);
e22087
-              if (fb_node != NULL)
e22087
+              const char *node;
e22087
+              node = udev_device_get_devnode (device);
e22087
+              if (node != NULL)
e22087
                 {
e22087
-                  ply_trace ("found node %s", fb_node);
e22087
+                  ply_trace ("found node %s", node);
e22087
                   found_device = true;
e22087
-                  create_seat_for_udev_device (manager, fb_device);
e22087
+                  create_seat_for_udev_device (manager, device);
e22087
                 }
e22087
             }
e22087
           else
e22087
             {
e22087
               ply_trace ("device doesn't have a seat tag");
e22087
             }
e22087
         }
e22087
       else
e22087
         {
e22087
           ply_trace ("it's not initialized");
e22087
         }
e22087
 
e22087
-      udev_device_unref (fb_device);
e22087
+      udev_device_unref (device);
e22087
     }
e22087
 
e22087
-  udev_enumerate_unref (fb_matches);
e22087
+  udev_enumerate_unref (matches);
e22087
 
e22087
   return found_device;
e22087
 }
e22087
 
e22087
 static void
e22087
-on_udev_graphics_event (ply_device_manager_t *manager)
e22087
+on_udev_event (ply_device_manager_t *manager)
e22087
 {
e22087
   struct udev_device *device;
e22087
   const char *action;
e22087
 
e22087
   device = udev_monitor_receive_device (manager->udev_monitor);
e22087
   if (device == NULL)
e22087
     return;
e22087
 
e22087
   action = udev_device_get_action (device);
e22087
 
e22087
   ply_trace ("got %s event for device %s", action, udev_device_get_sysname (device));
e22087
 
e22087
   if (action == NULL)
e22087
     return;
e22087
 
e22087
   if (strcmp (action, "add") == 0)
e22087
     create_seat_for_udev_device (manager, device);
e22087
   else if (strcmp (action, "remove") == 0)
e22087
     free_seat_for_udev_device (manager, device);
e22087
 
e22087
   udev_device_unref (device);
e22087
 }
e22087
 
e22087
 static void
e22087
 watch_for_udev_events (ply_device_manager_t *manager)
e22087
 {
e22087
   int fd;
e22087
   assert (manager != NULL);
e22087
   assert (manager->udev_monitor == NULL);
e22087
 
e22087
   ply_trace ("watching for udev graphics device add and remove events");
e22087
 
e22087
   manager->udev_monitor = udev_monitor_new_from_netlink (manager->udev_context, "udev");
e22087
 
e22087
-  /* The filter matching here mimics the matching done in scan_graphics_devices.
e22087
-   * See the comments in that function, for an explanation of what we're doing.
e22087
-   */
e22087
-  udev_monitor_filter_add_match_subsystem_devtype (manager->udev_monitor, "graphics", NULL);
e22087
+  udev_monitor_filter_add_match_subsystem_devtype (manager->udev_monitor, SUBSYSTEM_DRM, NULL);
e22087
+  udev_monitor_filter_add_match_subsystem_devtype (manager->udev_monitor, SUBSYSTEM_FRAME_BUFFER, NULL);
e22087
   udev_monitor_filter_add_match_tag (manager->udev_monitor, "seat");
e22087
   udev_monitor_enable_receiving (manager->udev_monitor);
e22087
 
e22087
   fd = udev_monitor_get_fd (manager->udev_monitor);
e22087
   ply_event_loop_watch_fd (manager->loop,
e22087
                            fd,
e22087
                            PLY_EVENT_LOOP_FD_STATUS_HAS_DATA,
e22087
                            (ply_event_handler_t)
e22087
-                           on_udev_graphics_event,
e22087
+                           on_udev_event,
e22087
                            NULL,
e22087
                            manager);
e22087
 }
e22087
 
e22087
 static void
e22087
 free_seats (ply_device_manager_t *manager)
e22087
 {
e22087
   ply_list_node_t *node;
e22087
 
e22087
   ply_trace ("removing seats");
e22087
   node = ply_list_get_first_node (manager->seats);
e22087
   while (node != NULL)
e22087
     {
e22087
       ply_seat_t *seat;
e22087
       ply_list_node_t *next_node;
e22087
 
e22087
       seat = ply_list_node_get_data (node);
e22087
       next_node = ply_list_get_next_node (manager->seats, node);
e22087
 
e22087
       if (manager->seat_removed_handler != NULL)
e22087
         manager->seat_removed_handler (manager->seat_event_handler_data, seat);
e22087
 
e22087
       ply_seat_free (seat);
e22087
       ply_list_remove_node (manager->seats, node);
e22087
 
e22087
       node = next_node;
e22087
     }
e22087
 }
e22087
 
e22087
 static void
e22087
@@ -657,77 +652,78 @@ create_seats_from_terminals (ply_device_manager_t *manager)
e22087
   int num_consoles;
e22087
 
e22087
   ply_trace ("checking for consoles");
e22087
 
e22087
   if (manager->flags & PLY_DEVICE_MANAGER_FLAGS_IGNORE_SERIAL_CONSOLES)
e22087
     {
e22087
       num_consoles = 0;
e22087
       ply_trace ("ignoring all consoles but default console because explicitly told to.");
e22087
     }
e22087
   else
e22087
     {
e22087
       num_consoles = add_consoles_from_file (manager, "/sys/class/tty/console/active");
e22087
 
e22087
       if (num_consoles == 0)
e22087
         ply_trace ("ignoring all consoles but default console because /sys/class/tty/console/active could not be read");
e22087
     }
e22087
 
e22087
   if (num_consoles > 1)
e22087
     {
e22087
       ply_trace ("serial consoles detected, managing them with details forced");
e22087
       ply_hashtable_foreach (manager->terminals,
e22087
                              (ply_hashtable_foreach_func_t *)
e22087
                              create_seat_for_terminal,
e22087
                              manager);
e22087
       return true;
e22087
     }
e22087
 
e22087
   return false;
e22087
 }
e22087
 
e22087
-static bool
e22087
+static void
e22087
 create_seats_from_udev (ply_device_manager_t *manager)
e22087
 {
e22087
-  bool found_device;
e22087
+  bool found_drm_device, found_fb_device;
e22087
 
e22087
   ply_trace ("Looking for devices from udev");
e22087
-  found_device = scan_graphics_devices (manager);
e22087
-  if (!found_device)
e22087
-    {
e22087
-      ply_trace ("Creating non-graphical seat, since there's no suitable graphics hardware");
e22087
-      create_seat_for_terminal_and_renderer_type (manager,
e22087
-                                                  ply_terminal_get_name (manager->local_console_terminal),
e22087
-                                                  manager->local_console_terminal,
e22087
-                                                  PLY_RENDERER_TYPE_NONE);
e22087
-    }
e22087
 
e22087
-  return true;
e22087
+  found_drm_device = create_seats_for_subsystem (manager, SUBSYSTEM_DRM);
e22087
+  found_fb_device = create_seats_for_subsystem (manager, SUBSYSTEM_FRAME_BUFFER);
e22087
+
e22087
+  if (found_drm_device || found_fb_device)
e22087
+    return;
e22087
+
e22087
+  ply_trace ("Creating non-graphical seat, since there's no suitable graphics hardware");
e22087
+  create_seat_for_terminal_and_renderer_type (manager,
e22087
+                                              ply_terminal_get_name (manager->local_console_terminal),
e22087
+                                              manager->local_console_terminal,
e22087
+                                              PLY_RENDERER_TYPE_NONE);
e22087
 }
e22087
 
e22087
 static void
e22087
 create_fallback_seat (ply_device_manager_t *manager)
e22087
 {
e22087
   create_seat_for_terminal_and_renderer_type (manager,
e22087
                                               ply_terminal_get_name (manager->local_console_terminal),
e22087
                                               manager->local_console_terminal,
e22087
                                               PLY_RENDERER_TYPE_AUTO);
e22087
 }
e22087
 
e22087
 static void
e22087
 on_udev_queue_changed (ply_device_manager_t *manager)
e22087
 {
e22087
 
e22087
   if (!udev_queue_get_queue_is_empty (manager->udev_queue))
e22087
     return;
e22087
 
e22087
   ply_trace ("udev coldplug complete");
e22087
   ply_event_loop_stop_watching_fd (manager->loop, manager->udev_queue_fd_watch);
e22087
   manager->udev_queue_fd_watch = NULL;
e22087
   udev_queue_unref (manager->udev_queue);
e22087
 
e22087
   close (manager->udev_queue_fd);
e22087
   manager->udev_queue_fd = -1;
e22087
 
e22087
   manager->udev_queue = NULL;
e22087
 
e22087
   create_seats_from_udev (manager);
e22087
 }
e22087
-- 
e22087
1.8.3.1
e22087
e22087
e22087
From 20603c552e7e31f65f6265ed7230ba4bcaf12bf5 Mon Sep 17 00:00:00 2001
e22087
From: Ray Strode <rstrode@redhat.com>
e22087
Date: Mon, 3 Mar 2014 17:25:44 -0500
e22087
Subject: [PATCH 2/2] device-manager: defer /dev/fb compat processing until
e22087
 after coldplug
e22087
e22087
We never want to use a /dev/fb device if a DRM device will work instead
e22087
(since it supports multi-monitor, isn't a legacy interface, etc)
e22087
e22087
Unfortunately, right now plymouthd notices efifb at early start up,
e22087
see's there is no DRM device associated with it and chooses it for
e22087
the main display, which causes all sort of problems.
e22087
e22087
This commit defers using /dev/fb devices until after udev settles.
e22087
---
e22087
 src/libply-splash-core/ply-device-manager.c | 24 +++++++++++++++++++++---
e22087
 1 file changed, 21 insertions(+), 3 deletions(-)
e22087
e22087
diff --git a/src/libply-splash-core/ply-device-manager.c b/src/libply-splash-core/ply-device-manager.c
e22087
index 25f7d54..d06e1b5 100644
e22087
--- a/src/libply-splash-core/ply-device-manager.c
e22087
+++ b/src/libply-splash-core/ply-device-manager.c
e22087
@@ -161,62 +161,63 @@ fb_device_has_drm_device (ply_device_manager_t *manager,
e22087
       ply_trace ("no card entry!");
e22087
     }
e22087
 
e22087
   udev_enumerate_unref (card_matches);
e22087
   return has_drm_device;
e22087
 }
e22087
 
e22087
 static void
e22087
 create_seat_for_udev_device (ply_device_manager_t *manager,
e22087
                              struct udev_device   *device)
e22087
 {
e22087
   bool for_local_console;
e22087
   const char *device_path;
e22087
   ply_terminal_t *terminal = NULL;
e22087
 
e22087
   for_local_console = device_is_for_local_console (manager, device);
e22087
 
e22087
   ply_trace ("device is for local console: %s", for_local_console? "yes" : "no");
e22087
 
e22087
   if (for_local_console)
e22087
     terminal = manager->local_console_terminal;
e22087
 
e22087
   device_path = udev_device_get_devnode (device);
e22087
 
e22087
   if (device_path != NULL)
e22087
     {
e22087
       const char *subsystem;
e22087
       ply_renderer_type_t renderer_type = PLY_RENDERER_TYPE_NONE;
e22087
 
e22087
       subsystem = udev_device_get_subsystem (device);
e22087
+      ply_trace ("device subsystem is %s", subsystem);
e22087
 
e22087
-      if (strcmp (subsystem, SUBSYSTEM_DRM) == 0)
e22087
+      if (subsystem != NULL && strcmp (subsystem, SUBSYSTEM_DRM) == 0)
e22087
         {
e22087
           ply_trace ("found DRM device %s", device_path);
e22087
           renderer_type = PLY_RENDERER_TYPE_DRM;
e22087
         }
e22087
       else if (strcmp (subsystem, SUBSYSTEM_FRAME_BUFFER) == 0)
e22087
         {
e22087
           ply_trace ("found frame buffer device %s", device_path);
e22087
           if (!fb_device_has_drm_device (manager, device))
e22087
             {
e22087
               renderer_type = PLY_RENDERER_TYPE_FRAME_BUFFER;
e22087
             }
e22087
           else
e22087
             {
e22087
               ply_trace ("ignoring, since there's a DRM device associated with it");
e22087
             }
e22087
         }
e22087
 
e22087
       if (renderer_type != PLY_RENDERER_TYPE_NONE)
e22087
         create_seat_for_terminal_and_renderer_type (manager,
e22087
                                                     device_path,
e22087
                                                     terminal,
e22087
                                                     renderer_type);
e22087
     }
e22087
 }
e22087
 
e22087
 static void
e22087
 free_seat_from_device_path (ply_device_manager_t *manager,
e22087
                             const char           *device_path)
e22087
 {
e22087
   ply_list_node_t *node;
e22087
@@ -332,63 +333,80 @@ create_seats_for_subsystem (ply_device_manager_t *manager,
e22087
         {
e22087
           ply_trace ("it's not initialized");
e22087
         }
e22087
 
e22087
       udev_device_unref (device);
e22087
     }
e22087
 
e22087
   udev_enumerate_unref (matches);
e22087
 
e22087
   return found_device;
e22087
 }
e22087
 
e22087
 static void
e22087
 on_udev_event (ply_device_manager_t *manager)
e22087
 {
e22087
   struct udev_device *device;
e22087
   const char *action;
e22087
 
e22087
   device = udev_monitor_receive_device (manager->udev_monitor);
e22087
   if (device == NULL)
e22087
     return;
e22087
 
e22087
   action = udev_device_get_action (device);
e22087
 
e22087
   ply_trace ("got %s event for device %s", action, udev_device_get_sysname (device));
e22087
 
e22087
   if (action == NULL)
e22087
     return;
e22087
 
e22087
   if (strcmp (action, "add") == 0)
e22087
-    create_seat_for_udev_device (manager, device);
e22087
+    {
e22087
+      const char *subsystem;
e22087
+      bool coldplug_complete = manager->udev_queue_fd_watch == NULL;
e22087
+
e22087
+      subsystem = udev_device_get_subsystem (device);
e22087
+
e22087
+      if (strcmp (subsystem, SUBSYSTEM_DRM) == 0 ||
e22087
+          coldplug_complete)
e22087
+        {
e22087
+          create_seat_for_udev_device (manager, device);
e22087
+        }
e22087
+      else
e22087
+        {
e22087
+          ply_trace ("ignoring since we only handle subsystem %s devices after coldplug completes", subsystem);
e22087
+        }
e22087
+    }
e22087
   else if (strcmp (action, "remove") == 0)
e22087
-    free_seat_for_udev_device (manager, device);
e22087
+    {
e22087
+      free_seat_for_udev_device (manager, device);
e22087
+    }
e22087
 
e22087
   udev_device_unref (device);
e22087
 }
e22087
 
e22087
 static void
e22087
 watch_for_udev_events (ply_device_manager_t *manager)
e22087
 {
e22087
   int fd;
e22087
   assert (manager != NULL);
e22087
   assert (manager->udev_monitor == NULL);
e22087
 
e22087
   ply_trace ("watching for udev graphics device add and remove events");
e22087
 
e22087
   manager->udev_monitor = udev_monitor_new_from_netlink (manager->udev_context, "udev");
e22087
 
e22087
   udev_monitor_filter_add_match_subsystem_devtype (manager->udev_monitor, SUBSYSTEM_DRM, NULL);
e22087
   udev_monitor_filter_add_match_subsystem_devtype (manager->udev_monitor, SUBSYSTEM_FRAME_BUFFER, NULL);
e22087
   udev_monitor_filter_add_match_tag (manager->udev_monitor, "seat");
e22087
   udev_monitor_enable_receiving (manager->udev_monitor);
e22087
 
e22087
   fd = udev_monitor_get_fd (manager->udev_monitor);
e22087
   ply_event_loop_watch_fd (manager->loop,
e22087
                            fd,
e22087
                            PLY_EVENT_LOOP_FD_STATUS_HAS_DATA,
e22087
                            (ply_event_handler_t)
e22087
                            on_udev_event,
e22087
                            NULL,
e22087
                            manager);
e22087
 }
e22087
 
e22087
-- 
e22087
1.8.3.1
e22087