mirror of
https://github.com/NixOS/nixpkgs.git
synced 2024-11-27 17:33:09 +00:00
* Don't use /hostfs to signal the test driver that a VM is up, but
write some magic string to ttyS0. This removes the dependency on having a CIFS mount. * Use a thread to process the stdout/stderr of each QEMU instance. * Add a kernel command line parameter "stage1panic" to tell stage 1 to panic if an error occurs. This is faster than waiting until connect() times out. svn path=/nixos/trunk/; revision=19212
This commit is contained in:
parent
5730c27aed
commit
170331be30
@ -1,9 +1,12 @@
|
||||
package Machine;
|
||||
|
||||
use strict;
|
||||
use threads;
|
||||
use Thread::Queue;
|
||||
use Socket;
|
||||
use IO::Handle;
|
||||
use POSIX qw(dup2);
|
||||
use FileHandle;
|
||||
|
||||
|
||||
# Stuff our PID in the multicast address/port to prevent collissions
|
||||
@ -26,6 +29,7 @@ sub new {
|
||||
booted => 0,
|
||||
pid => 0,
|
||||
connected => 0,
|
||||
connectedQueue => Thread::Queue->new(),
|
||||
socket => undef,
|
||||
stateDir => "$tmpDir/$name",
|
||||
};
|
||||
@ -62,14 +66,15 @@ sub start {
|
||||
|
||||
$self->log("starting vm");
|
||||
|
||||
my ($read, $write) = FileHandle::pipe;
|
||||
|
||||
my $pid = fork();
|
||||
die if $pid == -1;
|
||||
|
||||
if ($pid == 0) {
|
||||
my $name = $self->{name};
|
||||
open LOG, "| sed --unbuffered 's|^|$name console: |'" or die;
|
||||
dup2(fileno(LOG), fileno(STDOUT));
|
||||
dup2(fileno(LOG), fileno(STDERR));
|
||||
close $read;
|
||||
dup2(fileno($write), fileno(STDOUT));
|
||||
dup2(fileno($write), fileno(STDERR));
|
||||
open NUL, "</dev/null" or die;
|
||||
dup2(fileno(NUL), fileno(STDIN));
|
||||
$ENV{TMPDIR} = $self->{stateDir};
|
||||
@ -79,7 +84,22 @@ sub start {
|
||||
exec $self->{script};
|
||||
die;
|
||||
}
|
||||
|
||||
|
||||
close $write;
|
||||
|
||||
threads->create(\&processQemuOutput)->detach;
|
||||
|
||||
sub processQemuOutput {
|
||||
$/ = "\r\n";
|
||||
while (<$read>) {
|
||||
chomp;
|
||||
print STDERR $self->name, "# $_\n";
|
||||
$self->{connectedQueue}->enqueue(1) if $_ eq "===UP===";
|
||||
}
|
||||
# If the child dies, wake up connect().
|
||||
$self->{connectedQueue}->enqueue(1);
|
||||
}
|
||||
|
||||
$self->log("vm running as pid $pid");
|
||||
$self->{pid} = $pid;
|
||||
$self->{booted} = 1;
|
||||
@ -92,12 +112,9 @@ sub connect {
|
||||
|
||||
$self->start;
|
||||
|
||||
my $try = 0;
|
||||
while (1) {
|
||||
last if -e ($self->{stateDir} . "/running");
|
||||
sleep 1;
|
||||
die ("VM " . $self->{name} . " timed out") if $try++ > 300;
|
||||
}
|
||||
# Wait until the processQemuOutput thread signals that the machine
|
||||
# is up.
|
||||
$self->{connectedQueue}->dequeue();
|
||||
|
||||
while (1) {
|
||||
$self->log("trying to connect");
|
||||
|
@ -7,13 +7,15 @@ export PATH=@extraUtils@/bin:@klibc@/bin
|
||||
|
||||
|
||||
fail() {
|
||||
if [ -n "$panicOnFail" ]; then exit 1; fi
|
||||
|
||||
# If starting stage 2 failed, allow the user to repair the problem
|
||||
# in an interactive shell.
|
||||
cat <<EOF
|
||||
|
||||
An error occured in stage 1 of the boot process, which must mount the
|
||||
root filesystem on \`$targetRoot' and then start stage 2. Press one
|
||||
of the following keys within $timeout seconds:
|
||||
of the following keys:
|
||||
|
||||
i) to launch an interactive shell;
|
||||
f) to start an interactive shell having pid 1 (needed if you want to
|
||||
@ -74,6 +76,9 @@ for o in $(cat /proc/cmdline); do
|
||||
debug1mounts) # stop after mounting file systems
|
||||
debug1mounts=1
|
||||
;;
|
||||
stage1panic)
|
||||
panicOnFail=1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
|
@ -14,9 +14,8 @@ with pkgs.lib;
|
||||
|
||||
preStart =
|
||||
''
|
||||
eval $(cat /proc/cmdline)
|
||||
echo "guest running, will write in $hostTmpDir on host" > /dev/ttyS0
|
||||
touch /hostfs/$hostTmpDir/running
|
||||
echo "guest running" > /dev/ttyS0
|
||||
echo "===UP===" > dev/ttyS0
|
||||
'';
|
||||
|
||||
exec = "${pkgs.socat}/bin/socat tcp-listen:514,fork exec:/bin/sh,stderr";
|
||||
@ -45,6 +44,10 @@ with pkgs.lib;
|
||||
# If the kernel has been built with coverage instrumentation, make
|
||||
# it available under /proc/gcov.
|
||||
boot.kernelModules = [ "gcov-proc" ];
|
||||
|
||||
# Panic if an error occurs in stage 1 (rather than waiting for
|
||||
# user intervention).
|
||||
boot.kernelParams = [ "stage1panic" ];
|
||||
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user