[pve-devel] [PATCH pve-common] Tools::df: fork and use Filesys::Df
Wolfgang Bumiller
w.bumiller at proxmox.com
Thu Oct 29 14:16:59 CET 2015
Instead of depending on the 'df' commandline tool do a
fork() to create a killable process and run Filesys::Df,
returning the data over a pipe.
---
debian/control | 2 +-
src/PVE/Tools.pm | 50 +++++++++++++++++++++++++++++++++++---------------
2 files changed, 36 insertions(+), 16 deletions(-)
diff --git a/debian/control b/debian/control
index 2d85e01..c00ca5e 100644
--- a/debian/control
+++ b/debian/control
@@ -7,6 +7,6 @@ Standards-Version: 3.8.4
Package: libpve-common-perl
Architecture: all
-Depends: ${perl:Depends} ${misc:Depends}, libclone-perl, libdevel-cycle-perl, libwww-perl, libjson-perl, liblinux-inotify2-perl, libio-stringy-perl, liburi-perl, libstring-shellquote-perl, libnet-ip-perl
+Depends: ${perl:Depends} ${misc:Depends}, libclone-perl, libdevel-cycle-perl, libwww-perl, libjson-perl, liblinux-inotify2-perl, libio-stringy-perl, liburi-perl, libstring-shellquote-perl, libnet-ip-perl, libfilesys-df-perl
Description: Proxmox VE base library
This package contains the base library used by other Proxmox VE components.
diff --git a/src/PVE/Tools.pm b/src/PVE/Tools.pm
index 32f36ac..c52a3d0 100644
--- a/src/PVE/Tools.pm
+++ b/src/PVE/Tools.pm
@@ -8,6 +8,8 @@ use Socket qw(AF_INET AF_INET6 AI_ALL AI_V4MAPPED);
use IO::Select;
use File::Basename;
use File::Path qw(make_path);
+use Filesys::Df (); # don't overwrite our df()
+use IO::Pipe;
use IO::File;
use IO::Dir;
use IPC::Open3;
@@ -790,33 +792,51 @@ sub next_spice_port {
# NOTE: NFS syscall can't be interrupted, so alarm does
# not work to provide timeouts.
# from 'man nfs': "Only SIGKILL can interrupt a pending NFS operation"
-# So the spawn external 'df' process instead of using
-# Filesys::Df (which uses statfs syscall)
+# So fork() before using Filesys::Df
sub df {
my ($path, $timeout) = @_;
- my $cmd = [ 'df', '-P', '-B', '1', $path];
-
my $res = {
total => 0,
used => 0,
avail => 0,
};
- my $parser = sub {
- my $line = shift;
- if (my ($fsid, $total, $used, $avail) = $line =~
- m/^(\S+.*)\s+(\d+)\s+(\d+)\s+(\d+)\s+\d+%\s.*$/) {
- $res = {
- total => $total,
- used => $used,
- avail => $avail,
- };
+ my $pipe = IO::Pipe->new();
+ my $child = fork();
+ if (!defined($child)) {
+ warn "fork failed: $!\n";
+ return $res;
+ }
+
+ if (!$child) {
+ $pipe->writer();
+ eval {
+ my $df = Filesys::Df::df($path, 1);
+ print {$pipe} "$df->{blocks}\n$df->{used}\n$df->{bavail}\n";
+ $pipe->close();
+ };
+ if (my $err = $@) {
+ warn $err;
+ POSIX::_exit(1);
}
+ POSIX::_exit(0);
+ }
+
+ $pipe->reader();
+
+ my $readvalues = sub {
+ $res->{total} = int(<$pipe>);
+ $res->{used} = int(<$pipe>);
+ $res->{avail} = int(<$pipe>);
+ };
+ eval {
+ run_with_timeout($timeout, $readvalues);
};
- eval { run_command($cmd, timeout => $timeout, outfunc => $parser); };
warn $@ if $@;
-
+ $pipe->close();
+ kill('KILL', $child);
+ waitpid($child, 0);
return $res;
}
--
2.1.4
More information about the pve-devel
mailing list