X-Git-Url: https://git.proxmox.com/?p=pve-common.git;a=blobdiff_plain;f=src%2FPVE%2FTools.pm;h=6303d2047f5fc02898feb553321336c702710a2c;hp=125c3073f0a2b32fb1cfc2185cbd47e4285305f0;hb=44acb12c2714f7289e60ad3b9c5e0a36ee4dab59;hpb=be8f0477bcbca480f4374a8e963f5690eec910db diff --git a/src/PVE/Tools.pm b/src/PVE/Tools.pm index 125c307..6303d20 100644 --- a/src/PVE/Tools.pm +++ b/src/PVE/Tools.pm @@ -41,6 +41,7 @@ template_replace safe_print trim extract_param +file_copy ); my $pvelogdir = "/var/log/pve"; @@ -74,6 +75,8 @@ use constant {CLONE_NEWNS => 0x00020000, CLONE_NEWPID => 0x20000000, CLONE_NEWNET => 0x40000000}; +use constant O_PATH => 0x10000000; + sub run_with_timeout { my ($timeout, $code, @param) = @_; @@ -125,15 +128,16 @@ sub lock_file_full { my $lock_func = sub { if (!$lock_handles->{$$}->{$filename}) { - $lock_handles->{$$}->{$filename} = new IO::File (">>$filename") || - die "can't open file - $!\n"; + my $fh = new IO::File(">>$filename") || + die "can't open file - $!\n"; + $lock_handles->{$$}->{$filename} = { fh => $fh, refcount => 0}; } - if (!flock ($lock_handles->{$$}->{$filename}, $mode|LOCK_NB)) { - print STDERR "trying to aquire lock..."; + if (!flock($lock_handles->{$$}->{$filename}->{fh}, $mode|LOCK_NB)) { + print STDERR "trying to acquire lock..."; my $success; while(1) { - $success = flock($lock_handles->{$$}->{$filename}, $mode); + $success = flock($lock_handles->{$$}->{$filename}->{fh}, $mode); # try again on EINTR (see bug #273) if ($success || ($! != EINTR)) { last; @@ -141,10 +145,11 @@ sub lock_file_full { } if (!$success) { print STDERR " failed\n"; - die "can't aquire lock - $!\n"; + die "can't acquire lock '$filename' - $!\n"; } print STDERR " OK\n"; } + $lock_handles->{$$}->{$filename}->{refcount}++; }; my $res; @@ -158,9 +163,12 @@ sub lock_file_full { $err = $@; } - if (my $fh = $lock_handles->{$$}->{$filename}) { - $lock_handles->{$$}->{$filename} = undef; - close ($fh); + if (my $fh = $lock_handles->{$$}->{$filename}->{fh}) { + my $refcount = --$lock_handles->{$$}->{$filename}->{refcount}; + if ($refcount <= 0) { + $lock_handles->{$$}->{$filename} = undef; + close ($fh); + } } if ($err) { @@ -220,6 +228,12 @@ sub file_get_contents { return $content; } +sub file_copy { + my ($filename, $dst, $max, $perm) = @_; + + file_set_contents ($dst, file_get_contents($filename, $max), $perm); +} + sub file_read_firstline { my ($filename) = @_; @@ -312,6 +326,7 @@ sub run_command { my $timeout; my $oldtimeout; my $pid; + my $exitcode; my $outfunc; my $errfunc; @@ -319,6 +334,7 @@ sub run_command { my $input; my $output; my $afterfork; + my $noerr; eval { @@ -341,6 +357,8 @@ sub run_command { $logfunc = $param{$p}; } elsif ($p eq 'afterfork') { $afterfork = $param{$p}; + } elsif ($p eq 'noerr') { + $noerr = $param{$p}; } else { die "got unknown parameter '$p' for run_command\n"; } @@ -486,14 +504,14 @@ sub run_command { die "failed to execute\n"; } elsif (my $sig = ($? & 127)) { die "got signal $sig\n"; - } elsif (my $ec = ($? >> 8)) { - if (!($ec == 24 && ($cmdstr =~ m|^(\S+/)?rsync\s|))) { + } elsif ($exitcode = ($? >> 8)) { + if (!($exitcode == 24 && ($cmdstr =~ m|^(\S+/)?rsync\s|))) { if ($errmsg && $laststderr) { my $lerr = $laststderr; $laststderr = undef; die "$lerr\n"; } - die "exit code $ec\n"; + die "exit code $exitcode\n"; } } @@ -522,12 +540,12 @@ sub run_command { if ($errmsg) { $err =~ s/^usermod:\s*// if $cmdstr =~ m|^(\S+/)?usermod\s|; die "$errmsg: $err"; - } else { + } elsif(!$noerr) { die "command '$cmdstr' failed: $err"; } } - return undef; + return $exitcode; } sub split_list { @@ -1174,4 +1192,22 @@ sub unshare($) { return 0 == syscall(272, $flags); } +sub setns($$) { + my ($fileno, $nstype) = @_; + return 0 == syscall(308, $fileno, $nstype); +} + +sub syncfs($) { + my ($fileno) = @_; + return 0 == syscall(306, $fileno); +} + +sub sync_mountpoint { + my ($path) = @_; + sysopen my $fd, $path, O_PATH or die "failed to open $path: $!\n"; + my $result = syncfs(fileno($fd)); + close($fd); + return $result; +} + 1;