summary refs log tree commit diff
path: root/lib/test-driver/Machine.pm
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2010-01-04 18:04:57 +0000
committerEelco Dolstra <eelco.dolstra@logicblox.com>2010-01-04 18:04:57 +0000
commit170331be30ce02b37746d10b5fdcf307cc660bfb (patch)
treea62040ca080a8a010fe0c44cf44f6d69c29eeea2 /lib/test-driver/Machine.pm
parent5730c27aedb5ecf957a6125b130a43107a68b61d (diff)
downloadnixpkgs-170331be30ce02b37746d10b5fdcf307cc660bfb.tar
nixpkgs-170331be30ce02b37746d10b5fdcf307cc660bfb.tar.gz
nixpkgs-170331be30ce02b37746d10b5fdcf307cc660bfb.tar.bz2
nixpkgs-170331be30ce02b37746d10b5fdcf307cc660bfb.tar.lz
nixpkgs-170331be30ce02b37746d10b5fdcf307cc660bfb.tar.xz
nixpkgs-170331be30ce02b37746d10b5fdcf307cc660bfb.tar.zst
nixpkgs-170331be30ce02b37746d10b5fdcf307cc660bfb.zip
* 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
Diffstat (limited to 'lib/test-driver/Machine.pm')
-rw-r--r--lib/test-driver/Machine.pm39
1 files changed, 28 insertions, 11 deletions
diff --git a/lib/test-driver/Machine.pm b/lib/test-driver/Machine.pm
index df1ace15453..85ef80f0d37 100644
--- a/lib/test-driver/Machine.pm
+++ b/lib/test-driver/Machine.pm
@@ -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");