ktest: console pty support
v2 cover ktest: console pty support
These patches can be applied on top of yesterday's "ktest: restore tty settings after closing console" patch. They create a pty pair for the console to prevent the console child process from messing up ktest's tty settings.
v2 changes:
- rebased onto the stty save/restore patch
- added a patch to enable user input to the console
Josh Poimboeuf (2):
ktest: give console process a dedicated tty
ktest: enable user input to the console
tools/testing/ktest/ktest.pl | 117 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 93 insertions(+), 24 deletions(-)
Signature · 1 line
2.1.0
PATCH v2 1/2 ktest: give console process a dedicated tty
Create a pseudoterminal (pty pair) to give the console a dedicated tty so it doesn't mess with ktest's terminal settings.
--- tools/testing/ktest/ktest.pl | 66 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 57 insertions(+), 9 deletions(-)
tools/testing/ktest/ktest.pl +57 -9
@@ -1345,23 +1345,71 @@ sub dodie { die @_, "\n"; } -sub open_console { - my ($fp) = @_; +sub create_pty { + my ($ptm, $pts) = @_; + my $tmp; + my $TIOCSPTLCK = 0x40045431; + my $TIOCGPTN = 0x80045430; + + sysopen($ptm, "/dev/ptmx", O_RDWR | O_NONBLOCK) or + dodie "Cant open /dev/ptmx"; + + # unlockpt() + $tmp = pack("i", 0); + ioctl($ptm, $TIOCSPTLCK, $tmp) or + dodie "ioctl TIOCSPTLCK for /dev/ptmx failed"; + + # ptsname() + ioctl($ptm, $TIOCGPTN, $tmp) or + dodie "ioctl TIOCGPTN for /dev/ptmx failed"; + $tmp = unpack("i", $tmp); + + sysopen($pts, "/dev/pts/$tmp", O_RDWR | O_NONBLOCK) or + dodie "Can't open /dev/pts/$tmp"; +} + +sub exec_console { + my ($ptm, $pts) = @_; + + close($ptm); + + close(\*STDIN); + close(\*STDOUT); + close(\*STDERR); - my $flags; + open(\*STDIN, '<&', $pts); + open(\*STDOUT, '>&', $pts); + open(\*STDERR, '>&', $pts); + + close($pts); + + exec $console or + dodie "Can't open console $console"; +} + +sub open_console { + my ($ptm) = @_; + my $pts = \*PTSFD; + my $pid; # save terminal settings $stty = `stty -g`; - my $pid = open($fp, "$console|") or - dodie "Can't open console $console"; + create_pty($ptm, $pts); - $flags = fcntl($fp, F_GETFL, 0) or - dodie "Can't get flags for the socket: $!"; - $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or - dodie "Can't set flags for the socket: $!"; + $pid = fork; + + if (!$pid) { + # child + exec_console($ptm, $pts) + } + + # parent + close($pts); return $pid; + + open(PTSFD, "Stop perl from warning about single use of PTSFD"); } sub close_console {
Signature · 1 line
2.1.0
PATCH v2 2/2 ktest: enable user input to the console
In reply to Josh PoimboeufAllow the user to send input to the console by putting the terminal in cbreak mode (to allow reading stdin one character at a time) and copying all stdin data to the console's pty.
--- tools/testing/ktest/ktest.pl | 51 +++++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 15 deletions(-)
tools/testing/ktest/ktest.pl +36 -15
@@ -178,7 +178,7 @@ my $checkout; my $localversion; my $iteration = 0; my $successes = 0; -my $stty; +my $stty_orig; my $bisect_good; my $bisect_bad;
@@ -1393,7 +1393,11 @@ sub open_console { my $pid; # save terminal settings - $stty = `stty -g`; + $stty_orig = `stty -g`; + + # place terminal in cbreak mode so that stdin can be read one character at + # a time without having to wait for a newline + system("stty -icanon -echo -icrnl"); create_pty($ptm, $pts);
@@ -1422,7 +1426,7 @@ sub close_console { close($fp); # restore terminal settings - system("stty $stty"); + system("stty $stty_orig"); } sub start_monitor {
@@ -1749,7 +1753,9 @@ sub wait_for_input { my ($fp, $time) = @_; my $rin; - my $ready; + my $rout; + my $nr; + my $buf; my $line; my $ch;
@@ -1759,21 +1765,36 @@ sub wait_for_input $rin = ''; vec($rin, fileno($fp), 1) = 1; - ($ready, $time) = select($rin, undef, undef, $time); + vec($rin, fileno(\*STDIN), 1) = 1; - $line = ""; + while (1) { + $nr = select($rout=$rin, undef, undef, $time); - # try to read one char at a time - while (sysread $fp, $ch, 1) { - $line .= $ch; - last if ($ch eq "\n"); - } + if ($nr <= 0) { + return undef; + } - if (!length($line)) { - return undef; - } + # copy data from stdin to the console + if (vec($rout, fileno(\*STDIN), 1) == 1) { + sysread(\*STDIN, $buf, 1000); + syswrite($fp, $buf, 1000); + next; + } - return $line; + $line = ""; + + # try to read one char at a time + while (sysread $fp, $ch, 1) { + $line .= $ch; + last if ($ch eq "\n"); + } + + if (!length($line)) { + return undef; + } + + return $line; + } } sub reboot_to {
Signature · 1 line
2.1.0
Steven Rostedt
maintainerQuoted 8 lines · On Wed, 28 Jan 2015 13:38:37 -0600 Josh Poimboeuf <[email protected]> wrote:
These patches can be applied on top of yesterday's "ktest: restore tty settings after closing console" patch. They create a pty pair for the console to prevent the console child process from messing up ktest's tty settings.
v2 changes:
- rebased onto the stty save/restore patch
- added a patch to enable user input to the console
Quoted 7 lines
Josh Poimboeuf (2):
ktest: give console process a dedicated tty
ktest: enable user input to the consoletools/testing/ktest/ktest.pl | 117 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 93 insertions(+), 24 deletions(-)
OK, I applied these and been using ktest since. But after one of my tests failed (got a bug report), I had no console. I think there's a die someplace that does not put everything back.
Think you could find out where?
-- Steve
Quoted 19 lines · Steven Rostedt
Quoted 8 lines · On Wed, 28 Jan 2015 13:38:37 -0600 Josh Poimboeuf <[email protected]> wrote:
These patches can be applied on top of yesterday's "ktest: restore tty settings after closing console" patch. They create a pty pair for the console to prevent the console child process from messing up ktest's tty settings.
v2 changes:
- rebased onto the stty save/restore patch
- added a patch to enable user input to the consoleQuoted 7 lines
Josh Poimboeuf (2):
ktest: give console process a dedicated tty
ktest: enable user input to the consoletools/testing/ktest/ktest.pl | 117 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 93 insertions(+), 24 deletions(-)
Quoted 5 lines
OK, I applied these and been using ktest since. But after one of my tests failed (got a bug report), I had no console. I think there's a die someplace that does not put everything back.
Think you could find out where?
Can you tell if it died via dodie()? Looks like that wouldn't clean up the stty settings.
Signature · 1 line
Josh
Steven Rostedt
maintainerQuoted 3 lines · On Thu, 29 Jan 2015 15:39:39 -0600 Josh Poimboeuf <[email protected]> wrote:
Can you tell if it died via
dodie()? Looks like that wouldn't clean up the stty settings.
Looks to have happen in monitor where it called:
fail "failed - got a bug report" and return 0;
And must have had $die_on_failure set because it did not post a KTEST RESULT message. That means yes, it would hit dodie() called by fail().
-- Steve
PATCH 1/1 ktest: cleanup terminal on dodie() failure
Quoted 8 lines · Steven Rostedt
Quoted 3 lines · On Thu, 29 Jan 2015 15:39:39 -0600 Josh Poimboeuf <[email protected]> wrote:
Can you tell if it died via
dodie()? Looks like that wouldn't clean up the stty settings.
Quoted 6 lines
Looks to have happen in monitor where it called:
fail "failed - got a bug report" and return 0;And must have had $die_on_failure set because it did not post a KTEST RESULT message. That means yes, it would hit
dodie()called byfail().
This fixes it for me:
--8<--
Subject: [PATCH] ktest: cleanup terminal on dodie() failure
If dodie() is called with the console open, restore the terminal's original settings before dying.
--- tools/testing/ktest/ktest.pl | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
tools/testing/ktest/ktest.pl +6 -1
@@ -1342,6 +1342,11 @@ sub dodie { print " See $opt{LOG_FILE} for more info.\n"; } + if ($monitor_cnt) { + # restore terminal settings + system("stty $stty_orig"); + } + die @_, "\n"; }
@@ -1384,7 +1389,7 @@ sub exec_console { close($pts); exec $console or - dodie "Can't open console $console"; + die "Can't open console $console"; } sub open_console {
Signature · 1 line
2.1.0