mirror of
https://git.proxmox.com/git/qemu-server
synced 2025-08-07 21:34:21 +00:00
fix bug #841: replace get_used_paths with is_volume_in_use
get_used_paths returned a hash of used paths for all the volumes in a VM's config, which is not enough to figure out whether there are snapshots, as snapshots often have different paths. Eg. on ZFS it is not enough to check for /dev/zvol/tank/vm-123-disk-1 because the snapshot's path is /dev/zvol/tank/vm-123-disk-1@snap1 and thus we allowed deleting the drive. Then when trying to delete the snapshot later you get: zfs error: cannot open 'tank/vm-751-disk-1': dataset does not exist and it refuses to delete the snapshot. Since its only use was to check whether or not a drive is still in use it is now renamed to is_volume_in_use and beside checking paths now also checks volume-ids as those should stay the same.
This commit is contained in:
parent
b944d5edbb
commit
77019edfe0
@ -2471,10 +2471,8 @@ __PACKAGE__->register_method({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($param->{delete}) {
|
if ($param->{delete}) {
|
||||||
my $used_paths = PVE::QemuServer::get_used_paths($vmid, $storecfg, $conf, 1, 1);
|
if (PVE::QemuServer::is_volume_in_use($storecfg, $conf, undef, $old_volid)) {
|
||||||
my $path = PVE::Storage::path($storecfg, $old_volid);
|
warn "volume $old_volid still has snapshots, can't delete it\n";
|
||||||
if ($used_paths->{$path}){
|
|
||||||
warn "volume $old_volid have snapshots. Can't delete it\n";
|
|
||||||
PVE::QemuServer::add_unused_volume($conf, $old_volid);
|
PVE::QemuServer::add_unused_volume($conf, $old_volid);
|
||||||
PVE::QemuServer::update_config_nolock($vmid, $conf, 1);
|
PVE::QemuServer::update_config_nolock($vmid, $conf, 1);
|
||||||
} else {
|
} else {
|
||||||
|
@ -4088,10 +4088,8 @@ sub try_deallocate_drive {
|
|||||||
$rpcenv->check($authuser, "/storage/$sid", ['Datastore.AllocateSpace']);
|
$rpcenv->check($authuser, "/storage/$sid", ['Datastore.AllocateSpace']);
|
||||||
|
|
||||||
# check if the disk is really unused
|
# check if the disk is really unused
|
||||||
my $used_paths = PVE::QemuServer::get_used_paths($vmid, $storecfg, $conf, 1, $key);
|
|
||||||
my $path = PVE::Storage::path($storecfg, $volid);
|
|
||||||
die "unable to delete '$volid' - volume is still in use (snapshot?)\n"
|
die "unable to delete '$volid' - volume is still in use (snapshot?)\n"
|
||||||
if $used_paths->{$path};
|
if is_volume_in_use($storecfg, $conf, $key, $volid);
|
||||||
PVE::Storage::vdisk_free($storecfg, $volid);
|
PVE::Storage::vdisk_free($storecfg, $volid);
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
@ -5113,10 +5111,10 @@ sub scan_volids {
|
|||||||
return $volid_hash;
|
return $volid_hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub get_used_paths {
|
sub is_volume_in_use {
|
||||||
my ($vmid, $storecfg, $conf, $scan_snapshots, $skip_drive) = @_;
|
my ($storecfg, $conf, $skip_drive, $volid) = @_;
|
||||||
|
|
||||||
my $used_path = {};
|
my $path = PVE::Storage::path($storecfg, $volid);
|
||||||
|
|
||||||
my $scan_config = sub {
|
my $scan_config = sub {
|
||||||
my ($cref, $snapname) = @_;
|
my ($cref, $snapname) = @_;
|
||||||
@ -5127,31 +5125,31 @@ sub get_used_paths {
|
|||||||
next if $skip_drive && $key eq $skip_drive;
|
next if $skip_drive && $key eq $skip_drive;
|
||||||
my $drive = parse_drive($key, $value);
|
my $drive = parse_drive($key, $value);
|
||||||
next if !$drive || !$drive->{file} || drive_is_cdrom($drive);
|
next if !$drive || !$drive->{file} || drive_is_cdrom($drive);
|
||||||
|
return 1 if $volid eq $drive->{file};
|
||||||
if ($drive->{file} =~ m!^/!) {
|
if ($drive->{file} =~ m!^/!) {
|
||||||
$used_path->{$drive->{file}}++; # = 1;
|
return 1 if $drive->{file} eq $path;
|
||||||
} else {
|
} else {
|
||||||
my ($storeid, $volname) = PVE::Storage::parse_volume_id($drive->{file}, 1);
|
my ($storeid, $volname) = PVE::Storage::parse_volume_id($drive->{file}, 1);
|
||||||
next if !$storeid;
|
next if !$storeid;
|
||||||
my $scfg = PVE::Storage::storage_config($storecfg, $storeid, 1);
|
my $scfg = PVE::Storage::storage_config($storecfg, $storeid, 1);
|
||||||
next if !$scfg;
|
next if !$scfg;
|
||||||
my $path = PVE::Storage::path($storecfg, $drive->{file}, $snapname);
|
return 1 if $path eq PVE::Storage::path($storecfg, $drive->{file}, $snapname);
|
||||||
$used_path->{$path}++; # = 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
&$scan_config($conf);
|
return 1 if &$scan_config($conf);
|
||||||
|
|
||||||
undef $skip_drive;
|
undef $skip_drive;
|
||||||
|
|
||||||
if ($scan_snapshots) {
|
foreach my $snapname (keys %{$conf->{snapshots}}) {
|
||||||
foreach my $snapname (keys %{$conf->{snapshots}}) {
|
return 1 if &$scan_config($conf->{snapshots}->{$snapname}, $snapname);
|
||||||
&$scan_config($conf->{snapshots}->{$snapname}, $snapname);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $used_path;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub update_disksize {
|
sub update_disksize {
|
||||||
|
@ -2,6 +2,8 @@ qemu-server (4.0-41) unstable; urgency=medium
|
|||||||
|
|
||||||
* add new option to select BIOS (--bios <seabios|ovmf>)
|
* add new option to select BIOS (--bios <seabios|ovmf>)
|
||||||
|
|
||||||
|
* fix bug #841: replace get_used_paths with is_volume_in_use
|
||||||
|
|
||||||
-- Proxmox Support Team <support@proxmox.com> Thu, 10 Dec 2015 11:15:23 +0100
|
-- Proxmox Support Team <support@proxmox.com> Thu, 10 Dec 2015 11:15:23 +0100
|
||||||
|
|
||||||
qemu-server (4.0-40) unstable; urgency=medium
|
qemu-server (4.0-40) unstable; urgency=medium
|
||||||
|
Loading…
Reference in New Issue
Block a user