Skip to contentSkip to conversation

ktest: console pty support

PATCH In review Josh Poimboeuf 2 participants 7 messages Jan 28, 2015 – Jan 30, 2015 Ktest

lore
Share & tools
lore
#0 lore raw

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
#1 lore raw

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
index ba20f89..10b8825 100755
@@ -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
#2 lore raw

PATCH v2 2/2 ktest: enable user input to the console

In reply to Josh Poimboeuf

Allow 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
index 10b8825..acaf05b 100755
@@ -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
maintainer
#3 lore raw
In reply to Josh Poimboeuf
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 console

Quoted 7 lines

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(-)

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

#4 lore raw
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 console

Quoted 7 lines

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(-)
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
maintainer
#5 lore raw
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.

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

#6 lore raw

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 by fail().

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
index acaf05b..04e9391 100755
@@ -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