X-Git-Url: https://git.proxmox.com/?p=pve-common.git;a=blobdiff_plain;f=data%2FPVE%2FTools.pm;h=20fc1ea3ad0f73c1ee4f03b8d6b93586833b6e5b;hp=4f62cd7d2c137911a6241b33d605a09d357107c4;hb=a84b65c0da5eb1c1e3a3d4c51f01e24aa577253e;hpb=eb9e24df41de7c3c80ab0df8422f0b88b8c834de diff --git a/data/PVE/Tools.pm b/data/PVE/Tools.pm index 4f62cd7..20fc1ea 100644 --- a/data/PVE/Tools.pm +++ b/data/PVE/Tools.pm @@ -1,7 +1,7 @@ package PVE::Tools; use strict; -use POSIX; +use POSIX qw(EINTR); use IO::Socket::INET; use IO::Select; use File::Basename; @@ -92,7 +92,15 @@ sub lock_file { 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"; } @@ -173,7 +181,7 @@ sub file_read_firstline { my $fh = IO::File->new ($filename, "r"); return undef if !$fh; my $res = <$fh>; - chomp $res; + chomp $res if $res; $fh->close; return $res; } @@ -207,7 +215,12 @@ sub run_command { 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); } @@ -223,6 +236,7 @@ sub run_command { my $logfunc; my $input; my $output; + my $afterfork; eval { @@ -243,6 +257,8 @@ sub run_command { $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"; } @@ -303,6 +319,8 @@ sub run_command { 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; @@ -580,6 +598,30 @@ sub extract_param { 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++) {