X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=data%2FPVE%2FTools.pm;h=235178a68cd68b4bebe08db263243905a46a48df;hb=8d3190617daca4220546fa718cf49766099ed051;hp=27b4361f7f11c9a6d76d3a48b0a9a465bc86c074;hpb=e0cabd2caad4fd64893b1589ad36824ac0cf61e2;p=pve-common.git diff --git a/data/PVE/Tools.pm b/data/PVE/Tools.pm index 27b4361..235178a 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; @@ -19,6 +19,7 @@ use String::ShellQuote; our @EXPORT_OK = qw( lock_file +lock_file_full run_command file_set_contents file_get_contents @@ -79,20 +80,30 @@ sub run_with_timeout { my $lock_handles = {}; -sub lock_file { - my ($filename, $timeout, $code, @param) = @_; +sub lock_file_full { + my ($filename, $timeout, $shared, $code, @param) = @_; $timeout = 10 if !$timeout; + my $mode = $shared ? LOCK_SH : LOCK_EX; + my $lock_func = sub { if (!$lock_handles->{$$}->{$filename}) { $lock_handles->{$$}->{$filename} = new IO::File (">>$filename") || die "can't open file - $!\n"; } - if (!flock ($lock_handles->{$$}->{$filename}, LOCK_EX|LOCK_NB)) { + if (!flock ($lock_handles->{$$}->{$filename}, $mode|LOCK_NB)) { print STDERR "trying to aquire lock..."; - if (!flock ($lock_handles->{$$}->{$filename}, LOCK_EX)) { + my $success; + while(1) { + $success = flock($lock_handles->{$$}->{$filename}, $mode); + # try again on EINTR (see bug #273) + if ($success || ($! != EINTR)) { + last; + } + } + if (!$success) { print STDERR " failed\n"; die "can't aquire lock - $!\n"; } @@ -127,6 +138,13 @@ sub lock_file { return $res; } + +sub lock_file { + my ($filename, $timeout, $code, @param) = @_; + + return lock_file_full($filename, $timeout, 0, $code, @param); +} + sub file_set_contents { my ($filename, $data, $perm) = @_; @@ -228,6 +246,7 @@ sub run_command { my $logfunc; my $input; my $output; + my $afterfork; eval { @@ -248,6 +267,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"; } @@ -308,6 +329,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; @@ -727,7 +750,7 @@ sub upid_read_status { my ($task, $filename) = upid_decode($upid); my $fh = IO::File->new($filename, "r"); return "unable to open file - $!" if !$fh; - my $maxlen = 1024; + my $maxlen = 4096; sysseek($fh, -$maxlen, 2); my $readbuf = ''; my $br = sysread($fh, $readbuf, $maxlen);