5
0
mirror of git://git.proxmox.com/git/pve-storage.git synced 2024-12-22 13:34:16 +03:00

api: fix get content call response type for RBD/ZFS/iSCSI volumes

`pvesh get /nodes/{node}/storage/{storage}/content/{volume}` failed for
several storage types, because the respective storage plugins returned
only the volumes `size` on `volume_size_info` calls, while also the format
is required.

This patch fixes the issue by returning also `format` and where possible `used`.

The issue was reported in the forum:
https://forum.proxmox.com/threads/pvesh-get-nodes-node-storage-storage-content-volume-returns-error.123747/

Signed-off-by: Christian Ebner <c.ebner@proxmox.com>
 [ T: fixup white space error ]
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
This commit is contained in:
Christian Ebner 2023-03-09 10:41:23 +01:00 committed by Thomas Lamprecht
parent 13e1af437a
commit d70d814ccf
3 changed files with 50 additions and 7 deletions

View File

@ -208,7 +208,7 @@ sub volume_size_info {
my $vollist = iscsi_ls($scfg,$storeid);
my $info = $vollist->{$storeid}->{$volname};
return $info->{size};
return wantarray ? ($info->{size}, 'raw', 0, undef) : $info->{size};
}
sub volume_resize {

View File

@ -308,6 +308,45 @@ sub rbd_volume_info {
return $volume->@{qw(size parent format protected features)};
}
sub rbd_volume_du {
my ($scfg, $storeid, $volname) = @_;
my @options = ('du', $volname, '--format', 'json');
my $cmd = $rbd_cmd->($scfg, $storeid, @options);
my $raw = '';
my $parser = sub { $raw .= shift };
run_rbd_command($cmd, errmsg => "rbd error", errfunc => sub {}, outfunc => $parser);
my $volume;
if ($raw eq '') {
$volume = {};
} elsif ($raw =~ m/^(\{.*\})$/s) { # untaint
$volume = JSON::decode_json($1);
} else {
die "got unexpected data from rbd du: '$raw'\n";
}
if (!defined($volume->{images})) {
die "got no images from rbd du\n";
}
# `rbd du` returns array of images for name matching `volname`,
# including snapshots.
my $images = $volume->{images};
foreach my $image (@$images) {
next if defined($image->{snapshot});
next if !defined($image->{used_size}) || !defined($image->{name});
# Return `used_size` of first volume with matching name which
# is not a snapshot.
return $image->{used_size} if $image->{name} eq $volname;
}
die "got no matching image from rbd du\n";
}
# Configuration
sub type {
@ -729,8 +768,9 @@ sub volume_size_info {
my ($class, $scfg, $storeid, $volname, $timeout) = @_;
my ($vtype, $name, $vmid) = $class->parse_volname($volname);
my ($size, undef) = rbd_volume_info($scfg, $storeid, $name);
return $size;
my ($size, $parent) = rbd_volume_info($scfg, $storeid, $name);
my $used = wantarray ? rbd_volume_du($scfg, $storeid, $name) : 0;
return wantarray ? ($size, 'raw', $used, $parent) : $size;
}
sub volume_resize {

View File

@ -446,13 +446,16 @@ sub status {
sub volume_size_info {
my ($class, $scfg, $storeid, $volname, $timeout) = @_;
my (undef, $vname, undef, undef, undef, undef, $format) =
my (undef, $vname, undef, $parent, undef, undef, $format) =
$class->parse_volname($volname);
my $attr = $format eq 'subvol' ? 'refquota' : 'volsize';
my $value = $class->zfs_get_properties($scfg, $attr, "$scfg->{pool}/$vname");
if ($value =~ /^(\d+)$/) {
return $1;
my ($size, $used) = $class->zfs_get_properties($scfg, "$attr,usedbydataset", "$scfg->{pool}/$vname");
$used = ($used =~ /^(\d+)$/) ? $1 : 0;
if ($size =~ /^(\d+)$/) {
return wantarray ? ($1, $format, $used, $parent) : $1;
}
die "Could not get zfs volume size\n";