Bug 66824 - plymouthd hangs in ply_terminal_deactivate_vt during quit
Summary: plymouthd hangs in ply_terminal_deactivate_vt during quit
Status: RESOLVED FIXED
Alias: None
Product: plymouth
Classification: Unclassified
Component: general (show other bugs)
Version: unspecified
Hardware: Other All
: medium normal
Assignee: Ray Strode [halfline]
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-07-11 14:33 UTC by Stefan Brüns
Modified: 2014-02-03 15:03 UTC (History)
1 user (show)

See Also:
i915 platform:
i915 features:


Attachments
reset the console to mode KD_TEXT on quit (740 bytes, patch)
2013-07-11 14:35 UTC, Stefan Brüns
Details | Splinter Review

Description Stefan Brüns 2013-07-11 14:33:32 UTC
During shutdown plymouthd tries to switch back to the initial VT (if --retain-splash is not given).

If the console is in mode KD_GRAPHICS during the VT_ACTIVATE ioctl, the request will be silently dropped by the kernel:

== kernel: drivers/tty/vt/vt.c ==
int set_console(int nr)
{
	struct vc_data *vc = vc_cons[fg_console].d;

	if (!vc_cons_allocated(nr) || vt_dont_switch ||
		(vc->vt_mode.mode == VT_AUTO && vc->vc_mode == KD_GRAPHICS)) {

		/*
		 * Console switch will fail in console_callback() or
		 * change_console() so there is no point scheduling
		 * the callback
		 *
		 * Existing set_console() users don't check the return
		 * value so this shouldn't break anything
		 */
		return -EINVAL;
	}

	want_console = nr;
	schedule_console_callback();

	return 0;
}
===

Plymouth will then hang in the VT_WAITACTIVE ioctl forever.

The right thing to do here is to switch to KD_TEXT before leaving the VT. This should also be done if we do not have an initial VT, as otherwise we are stuck on this VT forever.
Comment 1 Stefan Brüns 2013-07-11 14:35:43 UTC
Created attachment 82339 [details] [review]
reset the console to mode KD_TEXT on quit
Comment 2 Stefan Brüns 2013-07-11 14:37:49 UTC
set_console is called by VT_ACTIVATE ioctl in vt_ioctl.c, but the return value is not passed on.
Comment 3 Ray Strode [halfline] 2013-07-11 14:38:16 UTC
plymouth takes the console out of VT_AUTO mode (into VT_PROCESS mode), so there's a missing peice to the puzzle here.
Comment 4 Stefan Brüns 2013-07-11 14:43:16 UTC
from src/libply-splash-core/ply-terminal.c, ply_terminal_deactivate_vt (ply_terminal_t *terminal):
---
/* Otherwise we'd close and free the terminal before handling the
   * "leaving the VT" signal.
   */
  ply_terminal_stop_watching_for_vt_changes (terminal);

  old_vt_number = terminal->vt_number;

  if (ply_terminal_is_active (terminal))
    {
      ply_trace ("Attempting to set active vt back to %d from %d",
                 terminal->initial_vt_number, old_vt_number);
      if (!set_active_vt (terminal, terminal->initial_vt_number))
        {
          ply_trace ("Couldn't move console to initial vt: %m");
          return false;
        }

      if (!wait_for_vt_to_become_active (terminal, terminal->initial_vt_number))
        {
          ply_trace ("Error while waiting for vt %d to become active: %m",
                     terminal->initial_vt_number);
          return false;
        }
    }
---

ply_terminal_stop_watching_for_vt_changes sets VT_AUTO
Comment 5 Stefan Brüns 2013-07-21 01:25:05 UTC
Any comments?
Comment 6 Ray Strode [halfline] 2013-07-22 21:00:37 UTC
hey sorry for the slow response.
ply_terminal has a function call ply_terminal_set_mode that wraps the ioctl for toggling between KD_GRAPHICS and KD_TEXT mode.

ply_boot_splash calls this method to put the terminal into KD_GRAPHICS mode before showing the boot splash. For symmetry it should probably be responsible for putting it back in KD_TEXT mode.

Indeed, there is a function in the ply_boot_splash code called ply_boot_splash_hide that has such a call:

      if (terminal != NULL)
        ply_terminal_set_mode (terminal, PLY_TERMINAL_MODE_TEXT);

ply_terminal_deactivate_vt is called from quit_splash in main.  All the callers of quit_splash call ply_boot_splash_hide() a few calls above their quit_splash call.

Any chance you could debug why that isn't sufficient?
Comment 7 Stefan Brüns 2013-07-23 18:35:16 UTC
(In reply to comment #6)
> hey sorry for the slow response.
> ply_terminal has a function call ply_terminal_set_mode that wraps the ioctl
> for toggling between KD_GRAPHICS and KD_TEXT mode.

This wrapper also checks for a flag to ignore mode change calls ...
 
> ply_boot_splash calls this method to put the terminal into KD_GRAPHICS mode
> before showing the boot splash. For symmetry it should probably be
> responsible for putting it back in KD_TEXT mode.
> 
> Indeed, there is a function in the ply_boot_splash code called
> ply_boot_splash_hide that has such a call:
> 
>       if (terminal != NULL)
>         ply_terminal_set_mode (terminal, PLY_TERMINAL_MODE_TEXT);
> 
> ply_terminal_deactivate_vt is called from quit_splash in main.  All the
> callers of quit_splash call ply_boot_splash_hide() a few calls above their
> quit_splash call.
> 
> Any chance you could debug why that isn't sufficient?

In case "plymouth deactivate" has been issued before the quit, the mode change is unplugged by the call to ply_terminal_ignore_mode_changes (state->local_console_terminal, true);

According to
http://www.mail-archive.com/plymouth@lists.freedesktop.org/msg00107.html
"plymouth deactivate" should be called if plymouth is running before the X server startup triggered by the display managerer (gdm, kdm, ...).

So either the dm calls reactivate before plymouth quit (without --retain-splash)
, or plymouth handles this on its own.
Comment 8 Stefan Brüns 2013-11-04 20:41:59 UTC
Ping!
Comment 9 Ray Strode [halfline] 2013-12-03 02:38:25 UTC
hey sorry again for the slow response.

So, I wonder if we actually need that ignore_mode_changes call.

It was added here:

http://cgit.freedesktop.org/plymouth/commit/?id=47452a1bc97c6e964f35623d4472018a6c7016e7

If the renderer is deactivated, I don't expect there to be any mode changes.

Does just dropping that one call fix things for you?
Comment 10 Stefan Brüns 2014-02-02 19:58:23 UTC
I have tried commenting out  ply_terminal_ignore_mode_changes (state->terminal, true); in src/main.c:deactivate_splash, and it works as expected.

So please apply.
Comment 11 Ray Strode [halfline] 2014-02-03 15:03:48 UTC
thanks for testing.  appreciated.


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.