From af0335e82fbe9e91e8ebeafe8ba1d255a3d30657 Mon Sep 17 00:00:00 2001 From: Tim Marx Date: Fri, 20 Sep 2019 11:12:46 +0200 Subject: [PATCH] change file_size_info sub to use qemu-img info json decoding Using the json output, as suggested by Thomas, we now die if the decoding fails and, if not, all return values are set to the corresponding decoded values. That should prevent any unforeseen null size values, except if qemu-img info reports it, which we then consider as valid. Signed-off-by: Tim Marx --- PVE/Storage/Plugin.pm | 43 ++++++++++++++++--------------------------- 1 file changed, 16 insertions(+), 27 deletions(-) diff --git a/PVE/Storage/Plugin.pm b/PVE/Storage/Plugin.pm index 39622f3..741e889 100644 --- a/PVE/Storage/Plugin.pm +++ b/PVE/Storage/Plugin.pm @@ -712,38 +712,27 @@ sub file_size_info { return wantarray ? (0, 'subvol', 0, undef) : 1; } - my $format; - my $parent; - my $size = 0; - my $used = 0; + my $cmd = ['/usr/bin/qemu-img', 'info', '--output=json', $filename]; + my $json = ''; - my $parse_qemu_img_info = sub { - my $line = shift; - if ($line =~ m/^file format:\s+(\S+)\s*$/) { - $format = $1; - } elsif ($line =~ m/^backing file:\s(\S+)\s/) { - $parent = $1; - } elsif ($line =~ m/^virtual size:\s\S+\s+\((\d+)\s+bytes\)$/) { - $size = int($1); - } elsif ($line =~ m/^disk size:\s+(\d+(.\d+)?)([KMGT])\s*$/) { - $used = $1; - my $u = $3; - - $used *= 1024 if $u eq 'K'; - $used *= (1024*1024) if $u eq 'M'; - $used *= (1024*1024*1024) if $u eq 'G'; - $used *= (1024*1024*1024*1024) if $u eq 'T'; - - $used = int($used); - } - }; - - my $cmd = ['/usr/bin/qemu-img', 'info', $filename]; eval { - run_command($cmd, timeout => $timeout, outfunc => $parse_qemu_img_info ); + run_command($cmd, timeout => $timeout, outfunc => sub { $json .= shift }, + errfunc => sub { + my $line = shift; + warn $line; + }); + }; + warn $@ if $@; + my $decoded = decode_json($json); + + my $format = $decoded->{format}; + my $parent = $decoded->{'backing-filename'}; + my $size = $decoded->{'virtual-size'}; + my $used = $decoded->{'actual-size'}; + return wantarray ? ($size, $format, $used, $parent) : $size; }