package PVE::Tools;
use strict;
-use POSIX;
+use POSIX qw(EINTR);
use IO::Socket::INET;
use IO::Select;
use File::Basename;
if (!flock ($lock_handles->{$$}->{$filename}, LOCK_EX|LOCK_NB)) {
print STDERR "trying to aquire lock...";
- if (!flock ($lock_handles->{$$}->{$filename}, LOCK_EX)) {
+ my $success;
+ while(1) {
+ $success = flock($lock_handles->{$$}->{$filename}, LOCK_EX);
+ # try again on EINTR (see bug #273)
+ if ($success || ($! != EINTR)) {
+ last;
+ }
+ }
+ if (!$success) {
print STDERR " failed\n";
die "can't aquire lock - $!\n";
}
my $fh = IO::File->new ($filename, "r");
return undef if !$fh;
my $res = <$fh>;
- chomp $res;
+ chomp $res if $res;
$fh->close;
return $res;
}
if (!ref($cmd)) {
$cmdstr = $cmd;
- $cmd = [ $cmd ];
+ if ($cmd =~ m/|/) {
+ # see 'man bash' for option pipefail
+ $cmd = [ '/bin/bash', '-c', "set -o pipefail && $cmd" ];
+ } else {
+ $cmd = [ $cmd ];
+ }
} else {
$cmdstr = cmd2string($cmd);
}
my $logfunc;
my $input;
my $output;
+ my $afterfork;
eval {
if ($p eq 'timeout') {
$timeout = $param{$p};
} elsif ($p eq 'umask') {
- umask($param{$p});
+ $old_umask = umask($param{$p});
} elsif ($p eq 'errmsg') {
$errmsg = $param{$p};
} elsif ($p eq 'input') {
$errfunc = $param{$p};
} elsif ($p eq 'logfunc') {
$logfunc = $param{$p};
+ } elsif ($p eq 'afterfork') {
+ $afterfork = $param{$p};
} else {
die "got unknown parameter '$p' for run_command\n";
}
local $SIG{ALRM} = sub { die "got timeout\n"; } if $timeout;
$oldtimeout = alarm($timeout) if $timeout;
+ &$afterfork() if $afterfork;
+
if (ref($writer)) {
print $writer $input if defined $input;
close $writer;
return $res;
}
+# Note: we use this to wait until vncterm is ready
+sub wait_for_vnc_port {
+ my ($port, $timeout) = @_;
+
+ $timeout = 5 if !$timeout;
+
+ for (my $i = 0; $i < $timeout; $i++) {
+ if (my $fh = IO::File->new ("/proc/net/tcp", "r")) {
+ while (defined (my $line = <$fh>)) {
+ if ($line =~ m/^\s*\d+:\s+([0-9A-Fa-f]{8}):([0-9A-Fa-f]{4})\s/) {
+ if ($port == hex($2)) {
+ close($fh);
+ return 1;
+ }
+ }
+ }
+ close($fh);
+ }
+ sleep(1);
+ }
+
+ return undef;
+}
+
sub next_vnc_port {
for (my $p = 5900; $p < 6000; $p++) {
my $filename;
# "UPID:$node:$pid:$pstart:$startime:$dtype:$id:$user"
- if ($upid =~ m/^UPID:([A-Za-z][[:alnum:]\-]*[[:alnum:]]+):([0-9A-Fa-f]{8}):([0-9A-Fa-f]{8}):([0-9A-Fa-f]{8}):([^:\s]+):([^:\s]*):([^:\s]+):$/) {
+ if ($upid =~ m/^UPID:([a-zA-Z0-9]([a-zA-Z0-9\-]*[a-zA-Z0-9])?):([0-9A-Fa-f]{8}):([0-9A-Fa-f]{8}):([0-9A-Fa-f]{8}):([^:\s]+):([^:\s]*):([^:\s]+):$/) {
$res->{node} = $1;
- $res->{pid} = hex($2);
- $res->{pstart} = hex($3);
- $res->{starttime} = hex($4);
- $res->{type} = $5;
- $res->{id} = $6;
- $res->{user} = $7;
-
- my $subdir = substr($4, 7, 8);
+ $res->{pid} = hex($3);
+ $res->{pstart} = hex($4);
+ $res->{starttime} = hex($5);
+ $res->{type} = $6;
+ $res->{id} = $7;
+ $res->{user} = $8;
+
+ my $subdir = substr($5, 7, 8);
$filename = "$pvetaskdir/$subdir/$upid";
} else {