Skip to content
This repository has been archived by the owner on Mar 15, 2024. It is now read-only.

Stucked while trying to match login prompt #16

Open
shunghsiyu opened this issue Jul 6, 2020 · 2 comments
Open

Stucked while trying to match login prompt #16

shunghsiyu opened this issue Jul 6, 2020 · 2 comments
Labels
bug Something isn't working

Comments

@shunghsiyu
Copy link
Contributor

shunghsiyu commented Jul 6, 2020

When there is a newline before the login prompt (i.e. "\nlocalhost login: "), runltp-ng will fail to recognize the prompt, thus not proceed with entering the username; this is because it get stucked polling forever at $poll->poll($timeout) (since timeout is not passed to backend::start).

Below is a script that mimics this issue.
wait_regexp and try_readline is copied directly from the backend module, with minor modification to avoid actually reading file descriptor (by mocking sysread).

#!/usr/bin/env perl
use strict;
use warnings;
use Time::HiRes qw(clock_gettime CLOCK_MONOTONIC);

use lib './';
use backend;
use log;

my $mock_sysread_cnt = 0;
my $out_fd_buf = "\nlocalhost login: ";

sub try_readline
{
	my ($self, $timeout) = @_;

	return backend::split_line($self) if backend::has_newline($self);

	#my $poll = IO::Poll->new();
	#$poll->mask($self->{'out_fd'} => POLLIN);

	while (1) {
		#if ($poll->poll($timeout) == 0) {
		#	msg("$self->{'name'}: Timeouted!\n");
		#	return undef;
		#}
		if (!defined($timeout) && $out_fd_buf eq '') {
			die("Will get stucked here polling forever\n");
		}

		my $buf = '';
		#my $ret = sysread($self->{'out_fd'}, $buf, 128);
		# --- Mocking sysread ---
		my $ret = 0;
		if ($mock_sysread_cnt == 0) {
			$ret = length($out_fd_buf);
			$buf = $out_fd_buf;
			$out_fd_buf = '';
			$mock_sysread_cnt += 1;
		} else {
			die("Will not reach here");
		}
		# -----------------------
		
		#print("R: '$buf'\n");
		$self->{'buf'} .= $buf;
		last if !defined($ret) && $!{EAGAIN};
		last if $ret > 0;
		return undef if !defined($ret);
		return undef if $ret == 0;
	}

	return backend::split_line($self) if backend::has_newline($self);

	return $self->{'buf'};
}

sub wait_regexp
{
	my ($self, $regexp, $newline, $timeout) = @_;
	my $out_fd = $self->{'out_fd'};
	my @log;
	my $line;

	msg("Waiting for regexp '$regexp'\n");

	my $start_time = backend::clock_gettime(CLOCK_MONOTONIC);

	while (1) {
		$line = try_readline($self, $timeout);

		if (!defined($line)) {
			msg("$self->{'name'}: died!\n");
			return @log;
		}

		if ($line =~ /\n/) {
			msg("$self->{'name'}: $line");
			my $l = $line;
			# Strip CR LF
			$l =~ s/(\x0d|\x0a)//g;
			# Strip escape sequencies
			$l =~ s/\x1b\[[0-9;]*[a-zA-Z]//g;
			push(@log, $l);
			my $fh = $self->{'raw_logfile'};
			print($fh "$l\n") if defined($fh);
		}
		#print("N: $self->{'name'}: $line\n") if $verbose;

		if (defined($timeout) and clock_gettime(CLOCK_MONOTONIC) - $start_time > $timeout) {
			msg("$self->{'name'}: timeouted!\n");
			return @log;
		}

		next if (defined($newline) && $newline && $line !~ /\n/);

		last if ($line =~ m/$regexp/);
	}

	return @log;
}

log::set_verbosity(1);

my %instance;
$instance{'name'} = 'qemu';
$instance{'buf'} = '';
wait_regexp(\%instance, qr/login:/);
@shunghsiyu
Copy link
Contributor Author

A possible workaround is to have the console set to automatic login

@richiejp
Copy link
Collaborator

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants