X-Git-Url: https://git.proxmox.com/?p=pve-common.git;a=blobdiff_plain;f=src%2FPVE%2FProcFSTools.pm;h=eadb4e6cda52abf1dc83a7432d33aaad00cffa00;hp=467069430c6a7baa927a4975ae3e9159925f3abe;hb=5f80891404277a0678a18d477a38de8217f30c11;hpb=115c838376b7ef67913542827a65b54e80d8c6c6 diff --git a/src/PVE/ProcFSTools.pm b/src/PVE/ProcFSTools.pm index 4670694..eadb4e6 100644 --- a/src/PVE/ProcFSTools.pm +++ b/src/PVE/ProcFSTools.pm @@ -6,6 +6,7 @@ use POSIX; use Time::HiRes qw (gettimeofday); use IO::File; use PVE::Tools; +use Cwd qw(); my $clock_ticks = POSIX::sysconf(&POSIX::_SC_CLK_TCK); @@ -288,16 +289,44 @@ sub read_proc_mounts { return PVE::Tools::file_get_contents("/proc/mounts"); } +# mounts encode spaces (\040), tabs (\011), newlines (\012), backslashes (\\ or \134) +sub decode_mount { + my ($str) = @_; + return $str =~ s/\\(?:040|01[12]|134|\\)/"\"$&\""/geer; +} + +sub parse_mounts { + my ($mounts) = @_; + my $mntent = []; + while ($mounts =~ /^\s*([^#].*)$/gm) { + # lines from the file are encoded so we can just split at spaces + my ($what, $dir, $fstype, $opts) = split(/[ \t]/, $1, 4); + my ($freq, $passno) = (0, 0); + # in glibc's parser frequency and pass seem to be optional + $freq = $1 if $opts =~ s/\s+(\d+)$//; + $passno = $1 if $opts =~ s/\s+(\d+)$//; + push @$mntent, [decode_mount($what), + decode_mount($dir), + decode_mount($fstype), + decode_mount($opts), + $freq, $passno]; + } + return $mntent; +} + +sub parse_proc_mounts { + return parse_mounts(read_proc_mounts()); +} + sub is_mounted { my ($mountpoint) = @_; - my $mountdata = read_proc_mounts(); + $mountpoint = Cwd::realpath($mountpoint); - if ($mountdata =~ m/\s$mountpoint\s/) { - return 1; - } else { - return 0; - } + return 0 if !defined($mountpoint); # path does not exist + + my $mounts = parse_proc_mounts(); + return (grep { $_->[1] eq $mountpoint } @$mounts) ? 1 : 0; } sub read_proc_net_ipv6_route { @@ -308,16 +337,16 @@ sub read_proc_net_ipv6_route { my $fh = IO::File->new ($filename, "r"); return $res if !$fh; - my $read_v6addr = sub { s/....(?!$)/$&:/g }; + my $read_v6addr = sub { $_[0] =~ s/....(?!$)/$&:/gr }; # ipv6_route has no header while (defined(my $line = <$fh>)) { my ($dest, $prefix, $nexthop, $metric, $iface) = (split(/\s+/, $line))[0,1,4,5,9]; push @$res, { dest => &$read_v6addr($dest), - prefix => $prefix, + prefix => hex("$prefix"), gateway => &$read_v6addr($nexthop), - metric => $metric, + metric => hex("$metric"), iface => $iface }; } @@ -325,4 +354,24 @@ sub read_proc_net_ipv6_route { return $res; } +sub upid_wait { + my ($upid, $waitfunc, $sleep_intervall) = @_; + + my $task = PVE::Tools::upid_decode($upid); + + $sleep_intervall = $sleep_intervall ? $sleep_intervall : 1; + + my $next_time = time + $sleep_intervall; + + while (check_process_running($task->{pid}, $task->{pstart})) { + + if (time >= $next_time && $waitfunc && ref($waitfunc) eq 'CODE'){ + &$waitfunc($task); + $next_time = time + $sleep_intervall; + } + + CORE::sleep(1); + } +} + 1;