Blob Blame History Raw
From 8a1dfbe91c1b309d361b4053e05bd5e01056fd41 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Mon, 3 Mar 2014 17:55:59 -0500
Subject: [PATCH 1/4] device-manager: ignore udev if only console is serial
 console

Right now we use the heuristic, "more than one entry in
/sys/class/tty/console/active" to mean "has serial consoles".

We used to use the heuristic "file has more than tty0 in it".
The older heuristic is more accurate because a user may have
console=ttyS0 without console=tty0 on the kernel command line.
---
 src/libply-splash-core/ply-device-manager.c | 27 +++++++++++++--------------
 1 file changed, 13 insertions(+), 14 deletions(-)

diff --git a/src/libply-splash-core/ply-device-manager.c b/src/libply-splash-core/ply-device-manager.c
index d06e1b5..098fd85 100644
--- a/src/libply-splash-core/ply-device-manager.c
+++ b/src/libply-splash-core/ply-device-manager.c
@@ -514,204 +514,203 @@ ply_device_manager_new (const char                 *default_tty,
   return manager;
 }
 
 void
 ply_device_manager_free (ply_device_manager_t *manager)
 {
   ply_trace ("freeing device manager");
 
   if (manager == NULL)
     return;
 
   ply_event_loop_stop_watching_for_exit (manager->loop,
                                          (ply_event_loop_exit_handler_t)
                                          detach_from_event_loop,
                                          manager);
   free_seats (manager);
   ply_list_free (manager->seats);
 
   free_terminals (manager);
   ply_hashtable_free (manager->terminals);
 
   if (manager->udev_monitor != NULL)
     udev_monitor_unref (manager->udev_monitor);
 
   if (manager->udev_context != NULL)
     udev_unref (manager->udev_context);
 
   free (manager);
 }
 
-static int
+static bool
 add_consoles_from_file (ply_device_manager_t *manager,
                         const char           *path)
 {
   int fd;
   char contents[512] = "";
   ssize_t contents_length;
-  int num_consoles;
+  bool has_serial_consoles;
   const char *remaining_file_contents;
 
   ply_trace ("opening %s", path);
   fd = open (path, O_RDONLY);
 
   if (fd < 0)
     {
       ply_trace ("couldn't open it: %m");
-      return 0;
+      return false;
     }
 
   ply_trace ("reading file");
   contents_length = read (fd, contents, sizeof (contents) - 1);
 
   if (contents_length <= 0)
     {
       ply_trace ("couldn't read it: %m");
       close (fd);
-      return 0;
+      return false;
     }
   close (fd);
 
   remaining_file_contents = contents;
-  num_consoles = 0;
+  has_serial_consoles = false;
 
   while (remaining_file_contents < contents + contents_length)
     {
       char *console;
       size_t console_length;
       const char *console_device;
       ply_terminal_t *terminal;
 
       /* Advance past any leading whitespace */
       remaining_file_contents += strspn (remaining_file_contents, " \n\t\v");
 
       if (*remaining_file_contents == '\0')
         {
           /* There's nothing left after the whitespace, we're done */
           break;
         }
 
       /* Find trailing whitespace and NUL terminate.  If strcspn
        * doesn't find whitespace, it gives us the length of the string
        * until the next NUL byte, which we'll just overwrite with
        * another NUL byte anyway. */
       console_length = strcspn (remaining_file_contents, " \n\t\v");
       console = strndup (remaining_file_contents, console_length);
 
       terminal = get_terminal (manager, console);
       console_device = ply_terminal_get_name (terminal);
 
       free (console);
 
       ply_trace ("console %s found!", console_device);
-      num_consoles++;
+
+      if (terminal != manager->local_console_terminal)
+        has_serial_consoles = true;
 
       /* Move past the parsed console string, and the whitespace we
        * may have found above.  If we found a NUL above and not whitespace,
        * then we're going to jump past the end of the buffer and the loop
        * will terminate
        */
       remaining_file_contents += console_length + 1;
     }
 
-  return num_consoles;
+  return has_serial_consoles;
 }
 
 static void
 create_seat_for_terminal_and_renderer_type (ply_device_manager_t *manager,
                                             const char           *device_path,
                                             ply_terminal_t       *terminal,
                                             ply_renderer_type_t   renderer_type)
 {
   ply_seat_t *seat;
   bool is_local_terminal = false;
 
   if (terminal != NULL && manager->local_console_terminal == terminal)
     is_local_terminal = true;
 
   if (is_local_terminal && manager->local_console_seat != NULL)
     {
       ply_trace ("trying to create seat for local console when one already exists");
       return;
     }
 
   ply_trace ("creating seat for %s (renderer type: %u) (terminal: %s)",
              device_path? : "", renderer_type, terminal? ply_terminal_get_name (terminal): "none");
   seat = ply_seat_new (terminal);
 
   if (!ply_seat_open (seat, renderer_type, device_path))
     {
       ply_trace ("could not create seat");
       ply_seat_free (seat);
       return;
     }
 
   ply_list_append_data (manager->seats, seat);
 
   if (is_local_terminal)
     manager->local_console_seat = seat;
 
   if (manager->seat_added_handler != NULL)
     manager->seat_added_handler (manager->seat_event_handler_data, seat);
 }
 
 static void
 create_seat_for_terminal (const char           *device_path,
                           ply_terminal_t       *terminal,
                           ply_device_manager_t *manager)
 {
   create_seat_for_terminal_and_renderer_type (manager,
                                               device_path,
                                               terminal,
                                               PLY_RENDERER_TYPE_NONE);
 }
 static bool
 create_seats_from_terminals (ply_device_manager_t *manager)
 {
-  int num_consoles;
+  bool has_serial_consoles;
 
   ply_trace ("checking for consoles");
 
   if (manager->flags & PLY_DEVICE_MANAGER_FLAGS_IGNORE_SERIAL_CONSOLES)
     {
-      num_consoles = 0;
+      has_serial_consoles = false;
       ply_trace ("ignoring all consoles but default console because explicitly told to.");
     }
   else
     {
-      num_consoles = add_consoles_from_file (manager, "/sys/class/tty/console/active");
-
-      if (num_consoles == 0)
-        ply_trace ("ignoring all consoles but default console because /sys/class/tty/console/active could not be read");
+      has_serial_consoles = add_consoles_from_file (manager, "/sys/class/tty/console/active");
     }
 
-  if (num_consoles > 1)
+  if (has_serial_consoles)
     {
       ply_trace ("serial consoles detected, managing them with details forced");
       ply_hashtable_foreach (manager->terminals,
                              (ply_hashtable_foreach_func_t *)
                              create_seat_for_terminal,
                              manager);
       return true;
     }
 
   return false;
 }
 
 static void
 create_seats_from_udev (ply_device_manager_t *manager)
 {
   bool found_drm_device, found_fb_device;
 
   ply_trace ("Looking for devices from udev");
 
   found_drm_device = create_seats_for_subsystem (manager, SUBSYSTEM_DRM);
   found_fb_device = create_seats_for_subsystem (manager, SUBSYSTEM_FRAME_BUFFER);
 
   if (found_drm_device || found_fb_device)
     return;
 
   ply_trace ("Creating non-graphical seat, since there's no suitable graphics hardware");
   create_seat_for_terminal_and_renderer_type (manager,
                                               ply_terminal_get_name (manager->local_console_terminal),
                                               manager->local_console_terminal,
                                               PLY_RENDERER_TYPE_NONE);
-- 
1.8.3.1


From 5fbfc8d1ec9da9060ebeaf0938afe8e2e0102b3d Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Mon, 3 Mar 2014 18:00:19 -0500
Subject: [PATCH 2/4] device-manager: be more tolerant of tty active console
 value

Some kernels mistakenly put tty1 instead of tty0 in the file,
so try to cope with them for maximium compatibility.
---
 src/libply-splash-core/ply-device-manager.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/libply-splash-core/ply-device-manager.c b/src/libply-splash-core/ply-device-manager.c
index 098fd85..dbc203d 100644
--- a/src/libply-splash-core/ply-device-manager.c
+++ b/src/libply-splash-core/ply-device-manager.c
@@ -441,61 +441,62 @@ free_terminal (char                 *device,
                ply_device_manager_t *manager)
 {
   ply_hashtable_remove (manager->terminals, device);
 
   ply_terminal_close (terminal);
   ply_terminal_free (terminal);
 }
 
 static void
 free_terminals (ply_device_manager_t *manager)
 {
   ply_hashtable_foreach (manager->terminals,
                          (ply_hashtable_foreach_func_t *)
                          free_terminal,
                          manager);
 }
 
 static ply_terminal_t *
 get_terminal (ply_device_manager_t *manager,
               const char           *device_name)
 {
   char *full_name = NULL;
   ply_terminal_t *terminal;
 
   if (strncmp (device_name, "/dev/", strlen ("/dev/")) == 0)
     full_name = strdup (device_name);
   else
     asprintf (&full_name, "/dev/%s", device_name);
 
   if (strcmp (full_name, "/dev/tty0") == 0 ||
-      strcmp (full_name, "/dev/tty") == 0)
+      strcmp (full_name, "/dev/tty") == 0 ||
+      strcmp (full_name, ply_terminal_get_name (manager->local_console_terminal)) == 0)
     {
       terminal = manager->local_console_terminal;
       goto done;
     }
 
   terminal = ply_hashtable_lookup (manager->terminals, full_name);
 
   if (terminal == NULL)
     {
       terminal = ply_terminal_new (full_name);
 
       ply_hashtable_insert (manager->terminals,
                             (void *) ply_terminal_get_name (terminal),
                             terminal);
     }
 
 done:
   free (full_name);
   return terminal;
 }
 
 ply_device_manager_t *
 ply_device_manager_new (const char                 *default_tty,
                         ply_device_manager_flags_t  flags)
 {
   ply_device_manager_t *manager;
 
   manager = calloc (1, sizeof (ply_device_manager_t));
   manager->loop = NULL;
   manager->terminals = ply_hashtable_new (ply_hashtable_string_hash, ply_hashtable_string_compare);
-- 
1.8.3.1


From 0d5fae7feb3c2fb462f124940e91fea16298eb1f Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Thu, 6 Mar 2014 14:42:16 -0500
Subject: [PATCH 3/4] seat: make sure to open terminal when adding text
 displays

If we have a pixel display, the renderer will handle opening the
associated terminal. but if we don't have a pixel display, something
needs to open the terminal.

This commit adds code to do that.
---
 src/libply-splash-core/ply-seat.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/src/libply-splash-core/ply-seat.c b/src/libply-splash-core/ply-seat.c
index 541b29e..2ac8bf7 100644
--- a/src/libply-splash-core/ply-seat.c
+++ b/src/libply-splash-core/ply-seat.c
@@ -75,60 +75,73 @@ add_pixel_displays (ply_seat_t *seat)
   ply_list_node_t *node;
 
   heads = ply_renderer_get_heads (seat->renderer);
 
   ply_trace ("Adding displays for %d heads",
              ply_list_get_length (heads));
 
   node = ply_list_get_first_node (heads);
   while (node != NULL)
     {
       ply_list_node_t *next_node;
       ply_renderer_head_t *head;
       ply_pixel_display_t *display;
 
       head = ply_list_node_get_data (node);
       next_node = ply_list_get_next_node (heads, node);
 
       display = ply_pixel_display_new (seat->renderer, head);
 
       ply_list_append_data (seat->pixel_displays, display);
 
       node = next_node;
     }
 }
 
 static void
 add_text_displays (ply_seat_t *seat)
 {
   ply_text_display_t *display;
 
+  if (!ply_terminal_is_open (seat->terminal))
+    {
+      if (!ply_terminal_open (seat->terminal))
+        {
+          ply_trace ("could not add terminal %s: %m",
+                     ply_terminal_get_name (seat->terminal));
+          return;
+        }
+    }
+
+  ply_trace ("adding text display for terminal %s",
+             ply_terminal_get_name (seat->terminal));
+
   display = ply_text_display_new (seat->terminal);
   ply_list_append_data (seat->text_displays, display);
 }
 
 bool
 ply_seat_open (ply_seat_t          *seat,
                ply_renderer_type_t  renderer_type,
                const char          *device)
 {
   if (renderer_type != PLY_RENDERER_TYPE_NONE)
     {
       ply_renderer_t *renderer;
 
       renderer = ply_renderer_new (renderer_type, device, seat->terminal);
 
       if (!ply_renderer_open (renderer))
         {
           ply_trace ("could not open renderer for %s", device);
           ply_renderer_free (renderer);
 
           seat->renderer = NULL;
           seat->renderer_active = false;
 
           if (renderer_type != PLY_RENDERER_TYPE_AUTO)
             return false;
         }
       else
         {
           seat->renderer = renderer;
           seat->renderer_active = true;
-- 
1.8.3.1


From aa2f5ac95c7cc0f4eb5f61465ecaf22247c7047c Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Thu, 6 Mar 2014 15:31:20 -0500
Subject: [PATCH 4/4] device-manager: Don't add local console to terminals hash
 table unless passed on cmdline

it's unexpected for plymouth to show boot messages on the local console
if there is not console=tty0 on the kernel command line.

This commit fixes that.
---
 src/libply-splash-core/ply-device-manager.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/libply-splash-core/ply-device-manager.c b/src/libply-splash-core/ply-device-manager.c
index dbc203d..8f5360c 100644
--- a/src/libply-splash-core/ply-device-manager.c
+++ b/src/libply-splash-core/ply-device-manager.c
@@ -445,92 +445,93 @@ free_terminal (char                 *device,
   ply_terminal_close (terminal);
   ply_terminal_free (terminal);
 }
 
 static void
 free_terminals (ply_device_manager_t *manager)
 {
   ply_hashtable_foreach (manager->terminals,
                          (ply_hashtable_foreach_func_t *)
                          free_terminal,
                          manager);
 }
 
 static ply_terminal_t *
 get_terminal (ply_device_manager_t *manager,
               const char           *device_name)
 {
   char *full_name = NULL;
   ply_terminal_t *terminal;
 
   if (strncmp (device_name, "/dev/", strlen ("/dev/")) == 0)
     full_name = strdup (device_name);
   else
     asprintf (&full_name, "/dev/%s", device_name);
 
   if (strcmp (full_name, "/dev/tty0") == 0 ||
       strcmp (full_name, "/dev/tty") == 0 ||
       strcmp (full_name, ply_terminal_get_name (manager->local_console_terminal)) == 0)
     {
       terminal = manager->local_console_terminal;
+
+      ply_hashtable_insert (manager->terminals,
+                            (void *) ply_terminal_get_name (terminal),
+                            terminal);
       goto done;
     }
 
   terminal = ply_hashtable_lookup (manager->terminals, full_name);
 
   if (terminal == NULL)
     {
       terminal = ply_terminal_new (full_name);
 
       ply_hashtable_insert (manager->terminals,
                             (void *) ply_terminal_get_name (terminal),
                             terminal);
     }
 
 done:
   free (full_name);
   return terminal;
 }
 
 ply_device_manager_t *
 ply_device_manager_new (const char                 *default_tty,
                         ply_device_manager_flags_t  flags)
 {
   ply_device_manager_t *manager;
 
   manager = calloc (1, sizeof (ply_device_manager_t));
   manager->loop = NULL;
   manager->terminals = ply_hashtable_new (ply_hashtable_string_hash, ply_hashtable_string_compare);
   manager->local_console_terminal = ply_terminal_new (default_tty);
-  ply_hashtable_insert (manager->terminals,
-                        (void *) ply_terminal_get_name (manager->local_console_terminal),
-                        manager->local_console_terminal);
   manager->seats = ply_list_new ();
   manager->flags = flags;
 
   if (!(flags & PLY_DEVICE_MANAGER_FLAGS_IGNORE_UDEV))
     manager->udev_context = udev_new ();
 
   attach_to_event_loop (manager, ply_event_loop_get_default ());
 
   return manager;
 }
 
 void
 ply_device_manager_free (ply_device_manager_t *manager)
 {
   ply_trace ("freeing device manager");
 
   if (manager == NULL)
     return;
 
   ply_event_loop_stop_watching_for_exit (manager->loop,
                                          (ply_event_loop_exit_handler_t)
                                          detach_from_event_loop,
                                          manager);
   free_seats (manager);
   ply_list_free (manager->seats);
 
   free_terminals (manager);
   ply_hashtable_free (manager->terminals);
 
   if (manager->udev_monitor != NULL)
-- 
1.8.3.1