mirror of
https://github.com/pragma-/pbot.git
synced 2025-03-28 10:31:12 +01:00
Add heartbeat logic to compiler server to detect when vm is booted (prevents unnecessary vm restarts)
This commit is contained in:
parent
38fb275234
commit
7388bf9cfc
@ -13,8 +13,8 @@ use warnings;
|
|||||||
# These are set automatically by the build/commit script
|
# These are set automatically by the build/commit script
|
||||||
use constant {
|
use constant {
|
||||||
BUILD_NAME => "PBot",
|
BUILD_NAME => "PBot",
|
||||||
BUILD_REVISION => 482,
|
BUILD_REVISION => 483,
|
||||||
BUILD_DATE => "2014-02-21",
|
BUILD_DATE => "2014-02-22",
|
||||||
};
|
};
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
@ -5,8 +5,12 @@ use strict;
|
|||||||
|
|
||||||
use IO::Socket;
|
use IO::Socket;
|
||||||
use Net::hostent;
|
use Net::hostent;
|
||||||
|
use IPC::Shareable;
|
||||||
|
|
||||||
my $PORT = 9000;
|
my $SERVER_PORT = 9000;
|
||||||
|
my $MONITOR_PORT = 3335;
|
||||||
|
my $SERIAL_PORT = 3333;
|
||||||
|
my $HEARTBEAT_PORT = 3336;
|
||||||
|
|
||||||
sub server_listen {
|
sub server_listen {
|
||||||
my $port = shift @_;
|
my $port = shift @_;
|
||||||
@ -17,7 +21,7 @@ sub server_listen {
|
|||||||
Listen => SOMAXCONN,
|
Listen => SOMAXCONN,
|
||||||
Reuse => 1);
|
Reuse => 1);
|
||||||
|
|
||||||
die "can't setup server" unless $server;
|
die "can't setup server: $!" unless $server;
|
||||||
|
|
||||||
print "[Server $0 accepting clients]\n";
|
print "[Server $0 accepting clients]\n";
|
||||||
|
|
||||||
@ -39,7 +43,7 @@ sub vm_start {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if($pid == 0) {
|
if($pid == 0) {
|
||||||
my $command = 'nice -n -20 qemu-system-x86_64 -M pc -net none -hda /home/compiler/compiler/compiler-savedvm.qcow2 -m 128 -monitor tcp:127.0.0.1:3335,server,nowait -serial tcp:127.0.0.1:3333,server,nowait -boot c -loadvm 1 -enable-kvm -nographic -no-kvm-irqchip';
|
my $command = "nice -n -20 qemu-system-x86_64 -M pc -net none -hda /home/compiler/compiler/compiler-savedvm.qcow2 -m 128 -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 -loadvm 1 -enable-kvm -no-kvm-irqchip -nographic";
|
||||||
my @command_list = split / /, $command;
|
my @command_list = split / /, $command;
|
||||||
exec(@command_list);
|
exec(@command_list);
|
||||||
} else {
|
} else {
|
||||||
@ -51,7 +55,7 @@ sub vm_reset {
|
|||||||
use IO::Socket;
|
use IO::Socket;
|
||||||
|
|
||||||
print "Resetting vm\n";
|
print "Resetting vm\n";
|
||||||
my $sock = IO::Socket::INET->new(PeerAddr => '127.0.0.1', PeerPort => 4445, Prot => 'tcp');
|
my $sock = IO::Socket::INET->new(PeerAddr => '127.0.0.1', PeerPort => $MONITOR_PORT, Prot => 'tcp');
|
||||||
if(not defined $sock) {
|
if(not defined $sock) {
|
||||||
print "[vm_reset] Unable to connect to monitor: $!\n";
|
print "[vm_reset] Unable to connect to monitor: $!\n";
|
||||||
return;
|
return;
|
||||||
@ -59,7 +63,7 @@ sub vm_reset {
|
|||||||
|
|
||||||
print $sock "loadvm 1\n";
|
print $sock "loadvm 1\n";
|
||||||
close $sock;
|
close $sock;
|
||||||
print "Resetted vm\n";
|
print "Reset vm\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
sub execute {
|
sub execute {
|
||||||
@ -107,16 +111,64 @@ sub execute {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub compiler_server {
|
sub compiler_server {
|
||||||
|
my ($server, $heartbeat_pid, $heartbeat_monitor);
|
||||||
|
|
||||||
|
my $heartbeat;
|
||||||
|
my $running;
|
||||||
|
|
||||||
|
tie $heartbeat, 'IPC::Shareable', 'dat1', { create => 1 };
|
||||||
|
tie $running, 'IPC::Shareable', 'dat2', { create => 1 };
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
$running = 1;
|
||||||
|
$heartbeat = 0;
|
||||||
|
|
||||||
my $vm_pid = vm_start;
|
my $vm_pid = vm_start;
|
||||||
print "vm started pid: $vm_pid\n";
|
print "vm started pid: $vm_pid\n";
|
||||||
|
|
||||||
my $server = server_listen($PORT);
|
$heartbeat_pid = fork;
|
||||||
|
die "Fork failed: $!" if not defined $heartbeat_pid;
|
||||||
|
|
||||||
while (my $client = $server->accept()) {
|
if($heartbeat_pid == 0) {
|
||||||
|
tie $heartbeat, 'IPC::Shareable', 'dat1', { create => 1 };
|
||||||
|
tie $running, 'IPC::Shareable', 'dat2', { create => 1 };
|
||||||
|
|
||||||
|
$heartbeat_monitor = undef;
|
||||||
|
while(not $heartbeat_monitor) {
|
||||||
|
print "Connecting to heartbeat ...";
|
||||||
|
$heartbeat_monitor = IO::Socket::INET->new(PeerAddr => '127.0.0.1', PeerPort => $HEARTBEAT_PORT, Proto => 'tcp', Type => SOCK_STREAM);
|
||||||
|
if(not $heartbeat_monitor) {
|
||||||
|
print " failed.\n";
|
||||||
|
sleep 2;
|
||||||
|
} else {
|
||||||
|
print " success!\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#print "child: running: $running\n";
|
||||||
|
|
||||||
|
while($running and <$heartbeat_monitor>) {
|
||||||
|
$heartbeat = 1;
|
||||||
|
#print "child: got heartbeat\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
#print "child no longer running\n";
|
||||||
|
exit;
|
||||||
|
} else {
|
||||||
|
if(not defined $server) {
|
||||||
|
print "Starting compiler server on port $SERVER_PORT\n";
|
||||||
|
$server = server_listen($SERVER_PORT);
|
||||||
|
} else {
|
||||||
|
print "Compiler server already listening on port $SERVER_PORT\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
#print "parent: running: $running\n";
|
||||||
|
|
||||||
|
while ($running and my $client = $server->accept()) {
|
||||||
$client->autoflush(1);
|
$client->autoflush(1);
|
||||||
my $hostinfo = gethostbyaddr($client->peeraddr);
|
my $hostinfo = gethostbyaddr($client->peeraddr);
|
||||||
print '-' x 20, "\n";
|
print '-' x 20, "\n";
|
||||||
printf "[Connect from %s]\n", $client->peerhost;
|
printf "[Connect from %s at %s]\n", $client->peerhost, scalar localtime;
|
||||||
my $timed_out = 0;
|
my $timed_out = 0;
|
||||||
my $killed = 0;
|
my $killed = 0;
|
||||||
|
|
||||||
@ -135,8 +187,14 @@ sub compiler_server {
|
|||||||
print "got: [$line]\n";
|
print "got: [$line]\n";
|
||||||
|
|
||||||
if($line =~ m/^compile:end$/) {
|
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";
|
||||||
|
last;
|
||||||
|
}
|
||||||
|
|
||||||
$code = quotemeta($code);
|
$code = quotemeta($code);
|
||||||
print "Attemping compile...\n";
|
print "Attempting compile...\n";
|
||||||
alarm 0;
|
alarm 0;
|
||||||
my $tnick = quotemeta($nick);
|
my $tnick = quotemeta($nick);
|
||||||
my $tlang = quotemeta($lang);
|
my $tlang = quotemeta($lang);
|
||||||
@ -155,7 +213,7 @@ sub compiler_server {
|
|||||||
print "Ret: $ret; result: [$result]\n";
|
print "Ret: $ret; result: [$result]\n";
|
||||||
|
|
||||||
if($result =~ m/\[Killed\]$/) {
|
if($result =~ m/\[Killed\]$/) {
|
||||||
print "Processed was killed\n";
|
print "Process was killed\n";
|
||||||
$killed = 1;
|
$killed = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,8 +252,12 @@ sub compiler_server {
|
|||||||
|
|
||||||
print "stopping vm $vm_pid\n";
|
print "stopping vm $vm_pid\n";
|
||||||
vm_stop $vm_pid;
|
vm_stop $vm_pid;
|
||||||
$vm_pid = vm_start;
|
$running = 0;
|
||||||
print "new vm pid: $vm_pid\n";
|
last;
|
||||||
|
}
|
||||||
|
#print "Compiler server no longer running, restarting...\n";
|
||||||
|
}
|
||||||
|
waitpid($heartbeat_pid, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,11 +29,12 @@ my %languages = (
|
|||||||
);
|
);
|
||||||
|
|
||||||
sub runserver {
|
sub runserver {
|
||||||
my ($input, $output);
|
my ($input, $output, $heartbeat);
|
||||||
|
|
||||||
if(not defined $USE_LOCAL or $USE_LOCAL == 0) {
|
if(not defined $USE_LOCAL or $USE_LOCAL == 0) {
|
||||||
open($input, '<', "/dev/ttyS0") or die $!;
|
open($input, '<', "/dev/ttyS0") or die $!;
|
||||||
open($output, '>', "/dev/ttyS0") or die $!;
|
open($output, '>', "/dev/ttyS0") or die $!;
|
||||||
|
open($heartbeat, '>', "/dev/ttyS1") or die $!;
|
||||||
} else {
|
} else {
|
||||||
open($input, '<', "/dev/stdin") or die $!;
|
open($input, '<', "/dev/stdin") or die $!;
|
||||||
open($output, '>', "/dev/stdout") or die $!;
|
open($output, '>', "/dev/stdout") or die $!;
|
||||||
@ -47,6 +48,10 @@ sub runserver {
|
|||||||
|
|
||||||
print "Waiting for input...\n";
|
print "Waiting for input...\n";
|
||||||
|
|
||||||
|
my $pid = fork;
|
||||||
|
die "Fork failed: $!" if not defined $pid;
|
||||||
|
|
||||||
|
if($pid == 0) {
|
||||||
while(my $line = <$input>) {
|
while(my $line = <$input>) {
|
||||||
chomp $line;
|
chomp $line;
|
||||||
|
|
||||||
@ -63,7 +68,7 @@ sub runserver {
|
|||||||
print $output "result:$result\n";
|
print $output "result:$result\n";
|
||||||
print $output "result:end\n";
|
print $output "result:end\n";
|
||||||
|
|
||||||
system("rm prog");
|
#system("rm prog");
|
||||||
|
|
||||||
if(not defined $USE_LOCAL or $USE_LOCAL == 0) {
|
if(not defined $USE_LOCAL or $USE_LOCAL == 0) {
|
||||||
print "input: ";
|
print "input: ";
|
||||||
@ -92,9 +97,16 @@ sub runserver {
|
|||||||
|
|
||||||
$code .= $line . "\n";
|
$code .= $line . "\n";
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
while(1) {
|
||||||
|
print $heartbeat "\n";
|
||||||
|
sleep 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
close $input;
|
close $input;
|
||||||
close $output;
|
close $output;
|
||||||
|
close $heartbeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub interpret {
|
sub interpret {
|
||||||
@ -108,6 +120,8 @@ sub interpret {
|
|||||||
return "No support for language '$lang' at this time.\n";
|
return "No support for language '$lang' at this time.\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
system("chmod -R 755 /home/compiler");
|
||||||
|
|
||||||
open(my $fh, '>', $languages{$lang}{'file'}) or die $!;
|
open(my $fh, '>', $languages{$lang}{'file'}) or die $!;
|
||||||
print $fh $code . "\n";
|
print $fh $code . "\n";
|
||||||
close $fh;
|
close $fh;
|
||||||
@ -149,6 +163,7 @@ sub interpret {
|
|||||||
$output = "[$result]\n";
|
$output = "[$result]\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
print "Executing gdb\n";
|
||||||
my $user_input_quoted = quotemeta $user_input;
|
my $user_input_quoted = quotemeta $user_input;
|
||||||
($ret, $result) = execute(60, "bash -c 'date -s \@$date; ulimit -t 1; compiler_watchdog.pl $user_input_quoted > .output'");
|
($ret, $result) = execute(60, "bash -c 'date -s \@$date; ulimit -t 1; compiler_watchdog.pl $user_input_quoted > .output'");
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user