Re: [PATCH] ktest: restore tty settings after closing console

From: Josh Poimboeuf
Date: Wed Jan 28 2015 - 16:10:38 EST


On Tue, Jan 27, 2015 at 05:01:29PM -0500, Steven Rostedt wrote:
> On Tue, 27 Jan 2015 12:10:04 -0600
> Josh Poimboeuf <jpoimboe@xxxxxxxxxx> wrote:
>
> > When ktest runs the console program as a child process, the parent and
> > child share the same tty for stdin and stderr. This is problematic when
> > using a libvirt target. The "virsh console" program makes a lot of
> > changes to the tty settings, making ktest's output hard to read
> > (carriage returns don't work). After ktest exits, the terminal is
> > unusable (CRs broken, stdin isn't echoed).
> >
> > I think the best way to fix this issue would be to create a
> > pseudoterminal (pty pair) so the child process would have a dedicated
> > tty, and then use pipes to connect the two ttys. I'm not sure if that's
> > overkill, but it's far beyond my current Perl abilities.
>
> And beyond mine too. I tried to get that right a few times, and it
> never worked out. Maybe someone with more oyster skilz can fix this.

I decided to level up my oyster skilz. I came up with this (to be
applied instead of the original patch). It's working well for me.
Right now, stdin isn't hooked up, so the user can't mess with the
console. Is stdin needed?

---8<---

Subject: [PATCH] ktest: give console process a dedicated tty

ktest's sharing of its tty with its child console monitoring process
creates problems when the console program changes tty settings. In the
case of "virsh console", it makes ktest's output unreadable and makes
the post-ktest terminal unusable (carriage returns broken, stdin not
echoed).

Create a pseudoterminal (pty pair) to give the console a dedicated tty
so it doesn't mess up ktest's tty.

Signed-off-by: Josh Poimboeuf <jpoimboe@xxxxxxxxxx>
---
tools/testing/ktest/ktest.pl | 64 ++++++++++++++++++++++++++++++++++++++------
1 file changed, 56 insertions(+), 8 deletions(-)

diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl
index b9cd036..5886169 100755
--- a/tools/testing/ktest/ktest.pl
+++ b/tools/testing/ktest/ktest.pl
@@ -1344,20 +1344,68 @@ 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);

- my $flags;
+ close(\*STDIN);
+ close(\*STDOUT);
+ close(\*STDERR);

- my $pid = open($fp, "$console|") or
+ open(\*STDIN, '<&', $pts);
+ open(\*STDOUT, '>&', $pts);
+ open(\*STDERR, '>&', $pts);
+
+ close($pts);
+
+ exec $console or
dodie "Can't open console $console";
+}

- $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: $!";
+sub open_console {
+ my ($ptm) = @_;
+ my $pts = \*PTSFD;
+ my $pid;
+
+ create_pty($ptm, $pts);
+
+ $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 {
--
2.1.0


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/