]> git.ipfire.org Git - thirdparty/plymouth.git/commitdiff
main: use new device manager class
authorRay Strode <rstrode@redhat.com>
Mon, 9 Dec 2013 02:09:15 +0000 (21:09 -0500)
committerRay Strode <rstrode@redhat.com>
Tue, 10 Dec 2013 06:01:30 +0000 (01:01 -0500)
Now that we have a class for managing our seats, let's use it.
This gets a lot of the nitty gritty logic out of main.c and
paves the way for us to do smartcard device management going
forward.

src/main.c

index 2c088cf45d1aef7449290d461183db7829f26352..b1dee5878567793be8bacbd3b8291cc0c5688575 100644 (file)
@@ -43,6 +43,7 @@
 #include "ply-command-parser.h"
 #include "ply-boot-server.h"
 #include "ply-boot-splash.h"
+#include "ply-device-manager.h"
 #include "ply-event-loop.h"
 #include "ply-hashtable.h"
 #include "ply-list.h"
@@ -85,8 +86,6 @@ typedef struct
 {
   ply_event_loop_t *loop;
   ply_boot_server_t *boot_server;
-  ply_hashtable_t *terminals;
-  ply_hashtable_t *seats;
   ply_boot_splash_t *boot_splash;
   ply_terminal_session_t *session;
   ply_buffer_t *boot_buffer;
@@ -98,6 +97,7 @@ typedef struct
   ply_command_parser_t *command_parser;
   ply_mode_t mode;
   ply_terminal_t *local_console_terminal;
+  ply_device_manager_t *device_manager;
 
   ply_trigger_t *deactivate_trigger;
   ply_trigger_t *quit_trigger;
@@ -113,7 +113,6 @@ typedef struct
   uint32_t should_retain_splash : 1;
   uint32_t is_inactive : 1;
   uint32_t is_shown : 1;
-  uint32_t has_open_seats : 1;
   uint32_t should_force_details : 1;
 
   char *override_splash_path;
@@ -131,9 +130,7 @@ static ply_boot_splash_t *load_theme (state_t    *state,
 static void show_theme (state_t           *state,
                         ply_boot_splash_t *splash);
 
-static void add_displays_and_keyboard_to_boot_splash (state_t           *state,
-                                                      ply_boot_splash_t *splash);
-
+static void attach_splash_to_seats (state_t *state);
 static bool attach_to_running_session (state_t *state);
 static void detach_from_running_session (state_t *state);
 static void on_escape_pressed (state_t *state);
@@ -146,7 +143,6 @@ static void on_error_message (ply_buffer_t *debug_buffer,
 static ply_buffer_t *debug_buffer;
 static char *debug_buffer_path = NULL;
 static char *pid_file = NULL;
-static void check_for_consoles (state_t *state);
 static void toggle_between_splash_and_details (state_t *state);
 #ifdef PLY_ENABLE_SYSTEMD_INTEGRATION
 static void tell_systemd_to_print_details (state_t *state);
@@ -161,164 +157,6 @@ static void on_keyboard_input (state_t    *state,
                                size_t      character_size);
 static void on_backspace (state_t *state);
 
-static void
-detach_from_seat (const char *device_path,
-                  ply_seat_t *seat,
-                  state_t    *state)
-{
-  ply_hashtable_remove (state->seats, (void *) device_path);
-  ply_seat_free (seat);
-}
-
-static void
-detach_from_seats (state_t *state)
-{
-  ply_trace ("removing seats");
-  ply_hashtable_foreach (state->seats,
-                         (ply_hashtable_foreach_func_t *)
-                         detach_from_seat,
-                         state);
-}
-
-static void
-ensure_seat_for_terminal_and_renderer_type (state_t             *state,
-                                            const char          *device_path,
-                                            ply_terminal_t      *terminal,
-                                            ply_renderer_type_t  renderer_type)
-{
-  ply_seat_t *seat;
-  bool has_seat;
-  ply_keyboard_t *keyboard;
-
-  seat = ply_hashtable_lookup (state->seats, (void *) device_path);
-
-  if (seat != NULL)
-    {
-      has_seat = true;
-    }
-  else
-    {
-      has_seat = false;
-      seat = ply_seat_new (terminal);
-    }
-
-  if (!ply_seat_is_open (seat))
-    state->has_open_seats = ply_seat_open (seat, renderer_type, NULL);
-
-  keyboard = ply_seat_get_keyboard (seat);
-  ply_keyboard_add_escape_handler (keyboard,
-                                   (ply_keyboard_escape_handler_t)
-                                   on_escape_pressed, state);
-  ply_trace ("listening for keystrokes");
-  ply_keyboard_add_input_handler (keyboard,
-                                  (ply_keyboard_input_handler_t)
-                                  on_keyboard_input, state);
-  ply_trace ("listening for backspace");
-  ply_keyboard_add_backspace_handler (keyboard,
-                                      (ply_keyboard_backspace_handler_t)
-                                      on_backspace, state);
-  ply_trace ("listening for enter");
-  ply_keyboard_add_enter_handler (keyboard,
-                                  (ply_keyboard_enter_handler_t)
-                                  on_enter, state);
-
-  if (!has_seat)
-    ply_hashtable_insert (state->seats, strdup (device_path), seat);
-}
-
-static void
-ensure_seat_for_terminal (const char     *device_path,
-                          ply_terminal_t *terminal,
-                          state_t        *state)
-{
-  ensure_seat_for_terminal_and_renderer_type (state,
-                                              device_path,
-                                              terminal,
-                                              PLY_RENDERER_TYPE_NONE);
-}
-
-static void
-open_closed_seats (state_t *state)
-{
-  int number_of_terminals;
-  ply_terminal_t *default_terminal;
-
-  number_of_terminals = ply_hashtable_get_size (state->terminals);
-  default_terminal = ply_hashtable_lookup (state->terminals, (void *) state->default_tty);
-
-  if ((number_of_terminals == 0) ||
-      ((number_of_terminals == 1) &&
-       (default_terminal != NULL)))
-    {
-      ensure_seat_for_terminal_and_renderer_type (state,
-                                                  state->default_tty,
-                                                  default_terminal,
-                                                  PLY_RENDERER_TYPE_AUTO);
-    }
-  else
-    {
-      ply_hashtable_foreach (state->terminals,
-                             (ply_hashtable_foreach_func_t *)
-                             ensure_seat_for_terminal,
-                             state);
-    }
-}
-
-static void
-free_terminal (char           *device,
-               ply_terminal_t *terminal,
-               state_t        *state)
-{
-  ply_hashtable_remove (state->terminals, device);
-
-  ply_terminal_close (terminal);
-  ply_terminal_free (terminal);
-}
-
-static void
-free_terminals (state_t *state)
-{
-  ply_hashtable_foreach (state->terminals,
-                         (ply_hashtable_foreach_func_t *)
-                         free_terminal,
-                         state);
-}
-
-static ply_terminal_t *
-get_terminal (state_t    *state,
-              const char *device_name)
-{
-  char *full_name;
-  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)
-    {
-      free (full_name);
-      full_name = strdup (state->default_tty);
-    }
-
-  terminal = ply_hashtable_lookup (state->terminals, full_name);
-
-  if (terminal == NULL)
-    {
-      terminal = ply_terminal_new (full_name);
-
-      if (strcmp (full_name, state->default_tty) == 0)
-        state->local_console_terminal = terminal;
-
-      ply_hashtable_insert (state->terminals, (void *) ply_terminal_get_name (terminal), terminal);
-    }
-  free (full_name);
-
-  return terminal;
-}
-
 static void
 on_session_output (state_t    *state,
                    const char *output,
@@ -979,6 +817,8 @@ plymouth_should_show_default_splash (state_t *state)
 static void
 on_show_splash (state_t *state)
 {
+  bool has_open_seats;
+
   if (state->is_shown)
     {
       ply_trace ("show splash called while already shown");
@@ -999,15 +839,50 @@ on_show_splash (state_t *state)
     }
 
   state->is_shown = true;
+  has_open_seats = ply_device_manager_has_open_seats (state->device_manager);
 
-  check_for_consoles (state);
-  open_closed_seats (state);
-
-  if (!state->is_attached && state->should_be_attached && state->has_open_seats)
+  if (!state->is_attached && state->should_be_attached && has_open_seats)
     attach_to_running_session (state);
 
-  load_splash (state);
-  show_theme (state, state->boot_splash);
+  if (has_open_seats)
+    {
+      ply_trace ("at least one seat already open, so loading splash");
+      load_splash (state);
+      show_theme (state, state->boot_splash);
+    }
+  else
+    {
+      ply_trace ("no seats available to show splash on, waiting...");
+    }
+}
+
+static void
+on_seat_removed (state_t    *state,
+                 ply_seat_t *seat)
+{
+  ply_keyboard_t *keyboard;
+
+  keyboard = ply_seat_get_keyboard (seat);
+
+  ply_trace ("no longer listening for keystrokes");
+  ply_keyboard_remove_input_handler (keyboard,
+                                     (ply_keyboard_input_handler_t)
+                                     on_keyboard_input);
+  ply_trace ("no longer listening for escape");
+  ply_keyboard_remove_escape_handler (keyboard,
+                                      (ply_keyboard_escape_handler_t)
+                                      on_escape_pressed);
+  ply_trace ("no longer listening for backspace");
+  ply_keyboard_remove_backspace_handler (keyboard,
+                                         (ply_keyboard_backspace_handler_t)
+                                         on_backspace);
+  ply_trace ("no longer listening for enter");
+  ply_keyboard_remove_enter_handler (keyboard,
+                                     (ply_keyboard_enter_handler_t)
+                                     on_enter);
+
+  if (state->boot_splash != NULL)
+   ply_boot_splash_detach_from_seat (state->boot_splash, seat);
 }
 
 static void
@@ -1028,6 +903,60 @@ load_splash (state_t *state)
     }
 }
 
+static void
+on_seat_added (state_t    *state,
+               ply_seat_t *seat)
+{
+  ply_keyboard_t *keyboard;
+
+  if (state->boot_splash == NULL)
+    {
+      ply_trace ("seat added before splash loaded, so loading splash now");
+      load_splash (state);
+    }
+
+  if (state->boot_splash != NULL && state->is_shown)
+    {
+      ply_trace ("show-splash already requested, so showing splash now");
+      show_theme (state, state->boot_splash);
+    }
+
+  keyboard = ply_seat_get_keyboard (seat);
+
+  ply_trace ("listening for keystrokes");
+  ply_keyboard_add_input_handler (keyboard,
+                                  (ply_keyboard_input_handler_t)
+                                  on_keyboard_input, state);
+  ply_trace ("listening for escape");
+  ply_keyboard_add_escape_handler (keyboard,
+                                   (ply_keyboard_escape_handler_t)
+                                   on_escape_pressed, state);
+  ply_trace ("listening for backspace");
+  ply_keyboard_add_backspace_handler (keyboard,
+                                      (ply_keyboard_backspace_handler_t)
+                                      on_backspace, state);
+  ply_trace ("listening for enter");
+  ply_keyboard_add_enter_handler (keyboard,
+                                  (ply_keyboard_enter_handler_t)
+                                  on_enter, state);
+
+}
+
+static void
+load_devices (state_t                    *state,
+              ply_device_manager_flags_t  flags)
+{
+  state->device_manager = ply_device_manager_new (state->default_tty, flags);
+  state->local_console_terminal = ply_device_manager_get_default_terminal (state->device_manager);
+
+  ply_device_manager_watch_seats (state->device_manager,
+                                  (ply_seat_added_handler_t)
+                                  on_seat_added,
+                                  (ply_seat_removed_handler_t)
+                                  on_seat_removed,
+                                  state);
+}
+
 static void
 quit_splash (state_t *state)
 {
@@ -1039,9 +968,6 @@ quit_splash (state_t *state)
       state->boot_splash = NULL;
     }
 
-  ply_trace ("removing displays and keyboard");
-  detach_from_seats (state);
-
   if (state->local_console_terminal != NULL)
     {
       if (!state->should_retain_splash)
@@ -1052,29 +978,9 @@ quit_splash (state_t *state)
       state->local_console_terminal = NULL;
     }
 
-  free_terminals (state);
-
   detach_from_running_session (state);
 }
 
-static void
-deactivate_renderer (const char *device_path,
-                     ply_seat_t *seat,
-                     state_t    *state)
-{
-  ply_seat_deactivate_renderer (seat);
-}
-
-static void
-deactivate_renderers (state_t *state)
-{
-  ply_trace ("removing seats");
-  ply_hashtable_foreach (state->seats,
-                         (ply_hashtable_foreach_func_t *)
-                         deactivate_renderer,
-                         state);
-}
-
 static void
 hide_splash (state_t *state)
 {
@@ -1093,7 +999,7 @@ dump_details_and_quit_splash (state_t *state)
   state->showing_details = false;
   toggle_between_splash_and_details (state);
 
-  deactivate_renderers (state);
+  ply_device_manager_deactivate_renderers (state->device_manager);
   hide_splash (state);
 
   state->is_shown = false;
@@ -1128,6 +1034,9 @@ tell_gdm_to_transition (void)
 static void
 quit_program (state_t *state)
 {
+  ply_trace ("cleaning up devices");
+  ply_device_manager_free (state->device_manager);
+
   ply_trace ("exiting event loop");
   ply_event_loop_exit (state->loop, 0);
 
@@ -1163,7 +1072,7 @@ deactivate_splash (state_t *state)
 {
   assert (!state->is_inactive);
 
-  deactivate_renderers (state);
+  ply_device_manager_deactivate_renderers (state->device_manager);
 
   detach_from_running_session (state);
 
@@ -1201,7 +1110,7 @@ on_boot_splash_idle (state_t *state)
       if (!state->should_retain_splash)
         {
           ply_trace ("hiding splash");
-          deactivate_renderers (state);
+          ply_device_manager_deactivate_renderers (state->device_manager);
           hide_splash (state);
 
           state->is_shown = false;
@@ -1219,24 +1128,6 @@ on_boot_splash_idle (state_t *state)
     }
 }
 
-static void
-deactivate_keyboard (const char *device_path,
-                     ply_seat_t *seat,
-                     state_t    *state)
-{
-  ply_seat_deactivate_keyboard (seat);
-}
-
-static void
-deactivate_keyboards (state_t *state)
-{
-  ply_trace ("deactivating keyboards");
-  ply_hashtable_foreach (state->seats,
-                         (ply_hashtable_foreach_func_t *)
-                         deactivate_keyboard,
-                         state);
-}
-
 static void
 on_deactivate (state_t       *state,
                ply_trigger_t *deactivate_trigger)
@@ -1259,7 +1150,7 @@ on_deactivate (state_t       *state,
   state->deactivate_trigger = deactivate_trigger;
 
   ply_trace ("deactivating");
-  deactivate_keyboards (state);
+  ply_device_manager_deactivate_keyboards (state->device_manager);
 
   if (state->boot_splash != NULL)
     {
@@ -1275,42 +1166,6 @@ on_deactivate (state_t       *state,
     }
 }
 
-static void
-activate_keyboard (const char *device_path,
-                   ply_seat_t *seat,
-                   state_t    *state)
-{
-  ply_seat_activate_keyboard (seat);
-}
-
-static void
-activate_keyboards (state_t *state)
-{
-  ply_trace ("activating keyboards");
-  ply_hashtable_foreach (state->seats,
-                         (ply_hashtable_foreach_func_t *)
-                         activate_keyboard,
-                         state);
-}
-
-static void
-activate_renderer (const char *device_path,
-                   ply_seat_t *seat,
-                   state_t    *state)
-{
-  ply_seat_activate_renderer (seat);
-}
-
-static void
-activate_renderers (state_t *state)
-{
-  ply_trace ("removing seats");
-  ply_hashtable_foreach (state->seats,
-                         (ply_hashtable_foreach_func_t *)
-                         activate_renderer,
-                         state);
-}
-
 static void
 on_reactivate (state_t *state)
 {
@@ -1331,8 +1186,8 @@ on_reactivate (state_t *state)
       attach_to_running_session (state);
     }
 
-  activate_keyboards (state);
-  activate_renderers (state);
+  ply_device_manager_activate_keyboards (state->device_manager);
+  ply_device_manager_activate_renderers (state->device_manager);
 
   state->is_inactive = false;
 
@@ -1368,8 +1223,7 @@ on_quit (state_t       *state,
   if (state->session != NULL)
     ply_terminal_session_close_log (state->session);
 
-  ply_trace ("deactivating keyboard");
-  deactivate_keyboards (state);
+  ply_device_manager_deactivate_keyboards (state->device_manager);
 
   ply_trace ("unloading splash");
   if (state->is_inactive && !retain_splash)
@@ -1610,21 +1464,26 @@ on_enter (state_t                  *state,
 }
 
 static void
-add_seat_to_boot_splash (const char        *device_path,
-                         ply_seat_t        *seat,
-                         ply_boot_splash_t *splash)
+attach_splash_to_seats (state_t *state)
 {
-  ply_boot_splash_attach_to_seat (splash, seat);
-}
 
-static void
-add_displays_and_keyboard_to_boot_splash (state_t           *state,
-                                          ply_boot_splash_t *splash)
-{
-  ply_hashtable_foreach (state->seats,
-                         (ply_hashtable_foreach_func_t *)
-                         add_seat_to_boot_splash,
-                         splash);
+  ply_list_t *seats;
+  ply_list_node_t *node;
+
+  seats = ply_device_manager_get_seats (state->device_manager);
+  node = ply_list_get_first_node (seats);
+  while (node != NULL)
+    {
+      ply_seat_t *seat;
+      ply_list_node_t *next_node;
+
+      seat = ply_list_node_get_data (node);
+      next_node = ply_list_get_next_node (seats, node);
+
+      ply_boot_splash_attach_to_seat (state->boot_splash, seat);
+
+      node = next_node;
+    }
 }
 
 #ifdef PLY_ENABLE_SYSTEMD_INTEGRATION
@@ -1715,7 +1574,8 @@ show_theme (state_t           *state,
 {
   ply_boot_splash_mode_t splash_mode;
 
-  add_displays_and_keyboard_to_boot_splash (state, state->boot_splash);
+  attach_splash_to_seats (state);
+  ply_device_manager_activate_renderers (state->device_manager);
 
   ply_trace ("showing plugin");
   if (state->mode == PLY_MODE_SHUTDOWN)
@@ -1736,7 +1596,7 @@ show_theme (state_t           *state,
     tell_systemd_to_print_details (state);
 #endif
 
-  activate_keyboards (state);
+  ply_device_manager_activate_keyboards (state->device_manager);
   show_messages (state);
   update_display (state);
 }
@@ -1971,117 +1831,6 @@ check_logging (state_t *state)
     }
 }
 
-static int
-add_consoles_from_file (state_t         *state,
-                        const char      *path)
-{
-  int fd;
-  char contents[512] = "";
-  ssize_t contents_length;
-  int num_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;
-    }
-
-  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;
-    }
-  close (fd);
-
-  remaining_file_contents = contents;
-  num_consoles = 0;
-
-  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);
-
-      /* If this console is anything besides tty0, then the user is sort
-       * of a weird case (uses a serial console or whatever) and they
-       * most likely don't want a graphical splash, so force details.
-       */
-      if (strcmp (console, "tty0") != 0)
-        state->should_force_details = true;
-
-      terminal = get_terminal (state, console);
-      console_device = ply_terminal_get_name (terminal);
-
-      free (console);
-
-      ply_trace ("console %s found!", console_device);
-      num_consoles++;
-
-      /* 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;
-}
-
-static void
-check_for_consoles (state_t *state)
-{
-  int num_consoles;
-  bool ignore_serial_consoles;
-
-  ply_trace ("checking for consoles%s",
-             state->is_shown? " and adding displays": "");
-
-  ignore_serial_consoles = command_line_has_argument (state->kernel_command_line, "plymouth.ignore-serial-consoles");
-
-  num_consoles = 0;
-
-  if (!ignore_serial_consoles)
-    {
-      num_consoles = add_consoles_from_file (state, "/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");
-        }
-    }
-  else
-    {
-      ply_trace ("ignoring all consoles but default console because of plymouth.ignore-serial-consoles");
-      get_terminal (state, state->default_tty);
-    }
-}
-
 static bool
 redirect_standard_io_to_dev_null (void)
 {
@@ -2163,8 +1912,6 @@ initialize_environment (state_t *state)
   state->keystroke_triggers = ply_list_new ();
   state->entry_triggers = ply_list_new ();
   state->entry_buffer = ply_buffer_new();
-  state->terminals = ply_hashtable_new (ply_hashtable_string_hash, ply_hashtable_string_compare);
-  state->seats = ply_hashtable_new (ply_hashtable_string_hash, ply_hashtable_string_compare);
   state->messages = ply_list_new ();
 
   redirect_standard_io_to_dev_null ();
@@ -2275,6 +2022,7 @@ main (int    argc,
   char *mode_string = NULL;
   char *kernel_command_line = NULL;
   char *tty = NULL;
+  ply_device_manager_flags_t device_manager_flags = PLY_DEVICE_MANAGER_FLAGS_NONE;
 
   state.command_parser = ply_command_parser_new ("plymouthd", "Splash server");
 
@@ -2449,6 +2197,11 @@ main (int    argc,
       return EX_UNAVAILABLE;
     }
 
+  if (command_line_has_argument (state.kernel_command_line, "plymouth.ignore-serial-consoles"))
+    device_manager_flags |= PLY_DEVICE_MANAGER_FLAGS_IGNORE_SERIAL_CONSOLES;
+
+  load_devices (&state, device_manager_flags);
+
   ply_trace ("entering event loop");
   exit_code = ply_event_loop_run (state.loop);
   ply_trace ("exited event loop");