X-Git-Url: https://git.proxmox.com/?p=pve-common.git;a=blobdiff_plain;f=data%2FPVE%2FTools.pm;h=20fc1ea3ad0f73c1ee4f03b8d6b93586833b6e5b;hp=543829596c94f255af68d6d4631de9110c986f87;hb=a84b65c0da5eb1c1e3a3d4c51f01e24aa577253e;hpb=c10cc11237e51bc399893eadb636977970f3a94f diff --git a/data/PVE/Tools.pm b/data/PVE/Tools.pm index 5438295..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 { @@ -230,7 +244,7 @@ sub run_command { 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') { @@ -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++) { @@ -652,16 +694,16 @@ sub upid_decode { 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 {