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