From: Ray Strode Date: Mon, 9 Dec 2013 02:09:15 +0000 (-0500) Subject: main: use new device manager class X-Git-Tag: 0.9.0~65^2~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c17a836b77d34fec94ebbc9410763974edaa88bd;p=thirdparty%2Fplymouth.git main: use new device manager class 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. --- diff --git a/src/main.c b/src/main.c index 2c088cf4..b1dee587 100644 --- a/src/main.c +++ b/src/main.c @@ -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");