diff --git a/modules/compiler_vm/compiler_server.pl b/modules/compiler_vm/compiler_server.pl index 42cc2733..0841af11 100755 --- a/modules/compiler_vm/compiler_server.pl +++ b/modules/compiler_vm/compiler_server.pl @@ -1,9 +1,5 @@ #!/usr/bin/perl -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - use warnings; use strict; @@ -13,12 +9,11 @@ use IPC::Shareable; use Time::HiRes qw/gettimeofday/; my $SERVER_PORT = 9000; -my $MONITOR_PORT = 3335; my $SERIAL_PORT = 3333; my $HEARTBEAT_PORT = 3336; +my $DOMAIN_NAME = 'compiler'; my $COMPILE_TIMEOUT = 10; -my $NOGRAPHIC = 1; sub server_listen { my $port = shift @_; @@ -37,41 +32,18 @@ sub server_listen { } sub vm_stop { - my $pid = shift @_; - return if not defined $pid; - print "killing vm $pid\n"; - kill 'INT', $pid; - waitpid($pid, 0); + system("virsh shutdown $DOMAIN_NAME"); } sub vm_start { - my $pid = fork; - - if(not defined $pid) { - die "fork failed: $!"; - } - - if($pid == 0) { - my $command = "qemu-system-x86_64 -M pc -net none -hda compiler-snap.qcow2 -m 512 -monitor tcp:127.0.0.1:$MONITOR_PORT,server,nowait -serial tcp:127.0.0.1:$SERIAL_PORT,server,nowait -serial tcp:127.0.0.1:$HEARTBEAT_PORT,server -boot c -enable-kvm -loadvm 1" . ($NOGRAPHIC ? " -nographic" : ""); - my @command_list = split / /, $command; - exec(@command_list); - } else { - return $pid; - } + system("virsh start $DOMAIN_NAME"); } sub vm_reset { - use IO::Socket; - - print "Resetting vm\n"; - my $sock = IO::Socket::INET->new(PeerAddr => '127.0.0.1', PeerPort => $MONITOR_PORT, Prot => 'tcp'); - if(not defined $sock) { - print "[vm_reset] Unable to connect to monitor: $!\n"; - return; - } - - print $sock "loadvm 1\n"; - close $sock; + return if $ENV{NORESET}; + #system("virsh detach-disk $DOMAIN_NAME vdb"); + system("virsh snapshot-revert $DOMAIN_NAME 1"); + #system("virsh attach-disk $DOMAIN_NAME --source /var/lib/libvirt/images/factdata.qcow2 --target vdb"); print "Reset vm\n"; } @@ -80,28 +52,41 @@ sub execute { print "execute($cmdline)\n"; + my @list = split / /, $cmdline; + my ($ret, $result); + #$SIG{CHLD} = 'IGNORE'; + my $child = fork; if($child == 0) { ($ret, $result) = eval { my $result = ''; - my $pid = open(my $fh, '-|', "$cmdline 2>&1"); + my $pid = open(my $fh, '-|', @list); + + if (not defined $pid) { + print "Couldn't fork: $!\n"; + return (-13, "[Fatal error]"); + } local $SIG{ALRM} = sub { print "Time out\n"; kill 9, $pid; print "sent KILL to $pid\n"; die "Timed-out: $result\n"; }; alarm($COMPILE_TIMEOUT); + print "Reading...\n"; while(my $line = <$fh>) { + print "read [$line]\n"; $result .= $line; } close $fh; + print "Done reading.\n"; my $ret = $? >> 8; alarm 0; - #print "[$ret, $result]\n"; + + print "[$ret, $result]\n"; return ($ret, $result); }; @@ -113,6 +98,7 @@ sub execute { return ($ret, $result); } else { waitpid($child, 0); + print "?: $?\n"; my $result = $? >> 8; print "child exited, parent continuing [result = $result]\n"; return (undef, $result); @@ -134,8 +120,8 @@ sub compiler_server { $running = 1; $heartbeat = 0; - my $vm_pid = vm_start; - print "vm started pid: $vm_pid\n"; + vm_reset; + print "vm started\n"; $heartbeat_pid = fork; die "Fork failed: $!" if not defined $heartbeat_pid; @@ -188,7 +174,7 @@ sub compiler_server { if ($heartbeat == -1) { print "fucking dead, restarting\n"; waitpid $heartbeat_pid, 0; - vm_stop $vm_pid; + #vm_stop; next; } @@ -212,11 +198,6 @@ sub compiler_server { my $killed = 0; eval { - my $lang; - my $nick; - my $channel; - my $code = ""; - local $SIG{ALRM} = sub { die 'Timed-out'; }; alarm 5; @@ -226,58 +207,42 @@ sub compiler_server { alarm 5; print "got: [$line]\n"; - if($line =~ m/^compile:end$/) { - if($heartbeat <= 0) { - print "No heartbeat yet, ignoring compile attempt.\n"; - print $client "$nick: Recovering from previous snippet, please wait.\n" if gettimeofday - $last_wait > 60; - $last_wait = gettimeofday; - last; - } - - print "Attempting compile...\n"; - alarm 0; - - my ($ret, $result) = execute("./compiler_vm_client.pl \Q$lang\E \Q$nick\E \Q$channel\E \Q$code\E"); - - if(not defined $ret) { - #print "parent continued\n"; - print "parent continued [$result]\n"; - $timed_out = 1 if $result == 243; # -13 == 243 - $killed = 1 if $result == 242; # -14 = 242 - last; - } - - $result =~ s/\s+$//; - print "Ret: $ret; result: [$result]\n"; - - if($result =~ m/\[Killed\]$/) { - print "Process was killed\n"; - $killed = 1; - } - - if($ret == -13) { - print $client "$nick: "; - } - - print $client $result . "\n"; - close $client; - - $ret = -14 if $killed; - - # child exit - print "child exit\n"; - exit $ret; + if($heartbeat <= 0) { + print "No heartbeat yet, ignoring compile attempt.\n"; + print $client "Recovering from previous snippet, please wait.\n" if gettimeofday - $last_wait > 60; + $last_wait = gettimeofday; + last; } - if($line =~ /compile:([^:]+):([^:]+):(.*)$/) { - $nick = $1; - $channel = $2; - $lang = $3; - $code = ""; - next; + print "Attempting compile...\n"; + alarm 0; + + my ($ret, $result) = execute("perl compiler_vm_client.pl $line"); + + if(not defined $ret) { + #print "parent continued\n"; + print "parent continued [$result]\n"; + $timed_out = 1 if $result == 243 or $result == -13; # -13 == 243 + $killed = 1 if $result == 242 or $result == -14; # -14 = 242 + last; } - $code .= $line . "\n"; + $result =~ s/\s+$//; + print "Ret: $ret; result: [$result]\n"; + + if($result =~ m/\[Killed\]$/) { + print "Process was killed\n"; + $killed = 1; + } + + print $client $result . "\n"; + close $client; + + $ret = -14 if $killed; + + # child exit + print "child exit\n"; + exit $ret; } alarm 0; @@ -287,16 +252,20 @@ sub compiler_server { close $client; - #next unless ($timed_out or $killed); - #next unless $timed_out; + print "timed out: $timed_out; killed: $killed\n"; + next unless ($timed_out or $killed); - print "stopping vm $vm_pid\n"; - vm_stop $vm_pid; + vm_reset; + next; + + print "stopping vm\n"; + #vm_stop; $running = 0; last; } print "Compiler server no longer running, restarting...\n"; } + print "waiting on heartbeat pid?\n"; waitpid($heartbeat_pid, 0); } } diff --git a/modules/compiler_vm/compiler_server_virsh.pl b/modules/compiler_vm/misc/compiler_server_qemu.pl similarity index 58% rename from modules/compiler_vm/compiler_server_virsh.pl rename to modules/compiler_vm/misc/compiler_server_qemu.pl index 0841af11..42cc2733 100755 --- a/modules/compiler_vm/compiler_server_virsh.pl +++ b/modules/compiler_vm/misc/compiler_server_qemu.pl @@ -1,5 +1,9 @@ #!/usr/bin/perl +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + use warnings; use strict; @@ -9,11 +13,12 @@ use IPC::Shareable; use Time::HiRes qw/gettimeofday/; my $SERVER_PORT = 9000; +my $MONITOR_PORT = 3335; my $SERIAL_PORT = 3333; my $HEARTBEAT_PORT = 3336; -my $DOMAIN_NAME = 'compiler'; my $COMPILE_TIMEOUT = 10; +my $NOGRAPHIC = 1; sub server_listen { my $port = shift @_; @@ -32,18 +37,41 @@ sub server_listen { } sub vm_stop { - system("virsh shutdown $DOMAIN_NAME"); + my $pid = shift @_; + return if not defined $pid; + print "killing vm $pid\n"; + kill 'INT', $pid; + waitpid($pid, 0); } sub vm_start { - system("virsh start $DOMAIN_NAME"); + my $pid = fork; + + if(not defined $pid) { + die "fork failed: $!"; + } + + if($pid == 0) { + my $command = "qemu-system-x86_64 -M pc -net none -hda compiler-snap.qcow2 -m 512 -monitor tcp:127.0.0.1:$MONITOR_PORT,server,nowait -serial tcp:127.0.0.1:$SERIAL_PORT,server,nowait -serial tcp:127.0.0.1:$HEARTBEAT_PORT,server -boot c -enable-kvm -loadvm 1" . ($NOGRAPHIC ? " -nographic" : ""); + my @command_list = split / /, $command; + exec(@command_list); + } else { + return $pid; + } } sub vm_reset { - return if $ENV{NORESET}; - #system("virsh detach-disk $DOMAIN_NAME vdb"); - system("virsh snapshot-revert $DOMAIN_NAME 1"); - #system("virsh attach-disk $DOMAIN_NAME --source /var/lib/libvirt/images/factdata.qcow2 --target vdb"); + use IO::Socket; + + print "Resetting vm\n"; + my $sock = IO::Socket::INET->new(PeerAddr => '127.0.0.1', PeerPort => $MONITOR_PORT, Prot => 'tcp'); + if(not defined $sock) { + print "[vm_reset] Unable to connect to monitor: $!\n"; + return; + } + + print $sock "loadvm 1\n"; + close $sock; print "Reset vm\n"; } @@ -52,41 +80,28 @@ sub execute { print "execute($cmdline)\n"; - my @list = split / /, $cmdline; - my ($ret, $result); - #$SIG{CHLD} = 'IGNORE'; - my $child = fork; if($child == 0) { ($ret, $result) = eval { my $result = ''; - my $pid = open(my $fh, '-|', @list); - - if (not defined $pid) { - print "Couldn't fork: $!\n"; - return (-13, "[Fatal error]"); - } + my $pid = open(my $fh, '-|', "$cmdline 2>&1"); local $SIG{ALRM} = sub { print "Time out\n"; kill 9, $pid; print "sent KILL to $pid\n"; die "Timed-out: $result\n"; }; alarm($COMPILE_TIMEOUT); - print "Reading...\n"; while(my $line = <$fh>) { - print "read [$line]\n"; $result .= $line; } close $fh; - print "Done reading.\n"; my $ret = $? >> 8; alarm 0; - - print "[$ret, $result]\n"; + #print "[$ret, $result]\n"; return ($ret, $result); }; @@ -98,7 +113,6 @@ sub execute { return ($ret, $result); } else { waitpid($child, 0); - print "?: $?\n"; my $result = $? >> 8; print "child exited, parent continuing [result = $result]\n"; return (undef, $result); @@ -120,8 +134,8 @@ sub compiler_server { $running = 1; $heartbeat = 0; - vm_reset; - print "vm started\n"; + my $vm_pid = vm_start; + print "vm started pid: $vm_pid\n"; $heartbeat_pid = fork; die "Fork failed: $!" if not defined $heartbeat_pid; @@ -174,7 +188,7 @@ sub compiler_server { if ($heartbeat == -1) { print "fucking dead, restarting\n"; waitpid $heartbeat_pid, 0; - #vm_stop; + vm_stop $vm_pid; next; } @@ -198,6 +212,11 @@ sub compiler_server { my $killed = 0; eval { + my $lang; + my $nick; + my $channel; + my $code = ""; + local $SIG{ALRM} = sub { die 'Timed-out'; }; alarm 5; @@ -207,42 +226,58 @@ sub compiler_server { alarm 5; print "got: [$line]\n"; - if($heartbeat <= 0) { - print "No heartbeat yet, ignoring compile attempt.\n"; - print $client "Recovering from previous snippet, please wait.\n" if gettimeofday - $last_wait > 60; - $last_wait = gettimeofday; - last; + if($line =~ m/^compile:end$/) { + if($heartbeat <= 0) { + print "No heartbeat yet, ignoring compile attempt.\n"; + print $client "$nick: Recovering from previous snippet, please wait.\n" if gettimeofday - $last_wait > 60; + $last_wait = gettimeofday; + last; + } + + print "Attempting compile...\n"; + alarm 0; + + my ($ret, $result) = execute("./compiler_vm_client.pl \Q$lang\E \Q$nick\E \Q$channel\E \Q$code\E"); + + if(not defined $ret) { + #print "parent continued\n"; + print "parent continued [$result]\n"; + $timed_out = 1 if $result == 243; # -13 == 243 + $killed = 1 if $result == 242; # -14 = 242 + last; + } + + $result =~ s/\s+$//; + print "Ret: $ret; result: [$result]\n"; + + if($result =~ m/\[Killed\]$/) { + print "Process was killed\n"; + $killed = 1; + } + + if($ret == -13) { + print $client "$nick: "; + } + + print $client $result . "\n"; + close $client; + + $ret = -14 if $killed; + + # child exit + print "child exit\n"; + exit $ret; } - print "Attempting compile...\n"; - alarm 0; - - my ($ret, $result) = execute("perl compiler_vm_client.pl $line"); - - if(not defined $ret) { - #print "parent continued\n"; - print "parent continued [$result]\n"; - $timed_out = 1 if $result == 243 or $result == -13; # -13 == 243 - $killed = 1 if $result == 242 or $result == -14; # -14 = 242 - last; + if($line =~ /compile:([^:]+):([^:]+):(.*)$/) { + $nick = $1; + $channel = $2; + $lang = $3; + $code = ""; + next; } - $result =~ s/\s+$//; - print "Ret: $ret; result: [$result]\n"; - - if($result =~ m/\[Killed\]$/) { - print "Process was killed\n"; - $killed = 1; - } - - print $client $result . "\n"; - close $client; - - $ret = -14 if $killed; - - # child exit - print "child exit\n"; - exit $ret; + $code .= $line . "\n"; } alarm 0; @@ -252,20 +287,16 @@ sub compiler_server { close $client; - print "timed out: $timed_out; killed: $killed\n"; - next unless ($timed_out or $killed); + #next unless ($timed_out or $killed); + #next unless $timed_out; - vm_reset; - next; - - print "stopping vm\n"; - #vm_stop; + print "stopping vm $vm_pid\n"; + vm_stop $vm_pid; $running = 0; last; } print "Compiler server no longer running, restarting...\n"; } - print "waiting on heartbeat pid?\n"; waitpid($heartbeat_pid, 0); } }