Scan the VM config and store the volid and full path for each storage. Do the same when we scan each storage. Then we can have these scenarios: * multiple storage configurations might point to the same storage The result is, that when scanning the storages, we find the disk image multiple times. -> we ignore them
* a VM might have multiple disks configured, pointing to the same disk image -> We fail with a warning that two disk configs point to the same disk image Without these checks, it was possible to multiply the number of disk images with each migration (with local disk) if at least another storage was configured, pointing to the same place. Signed-off-by: Aaron Lauterer <a.laute...@proxmox.com> --- PVE/QemuMigrate.pm | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/PVE/QemuMigrate.pm b/PVE/QemuMigrate.pm index 09cc1d8..bd3ea00 100644 --- a/PVE/QemuMigrate.pm +++ b/PVE/QemuMigrate.pm @@ -301,6 +301,10 @@ sub scan_local_volumes { my $other_errors = []; my $abort = 0; + # store and map already referenced absolute paths and volids + my $referencedpath = {}; # path -> volid + my $referenced = {}; # volid -> config key (e.g. scsi0) + my $log_error = sub { my ($msg, $volid) = @_; @@ -312,6 +316,26 @@ sub scan_local_volumes { $abort = 1; }; + # reference disks in config first + PVE::QemuConfig->foreach_volume_full($conf, { include_unused => 1 }, sub { + my ($key, $drive) = @_; + my $volid = $drive->{file}; + return if PVE::QemuServer::Drive::drive_is_cdrom($drive); + return if !$volid || $volid =~ m|^/|; + + my $path = PVE::Storage::path($storecfg, $volid); + if (defined $referencedpath->{$path}) { + my $rkey = $referenced->{$referencedpath->{$path}}; + &$log_error( + "cannot migrate local image '$volid': '$key' and '$rkey' ". + "reference the same volume. (check guest and storage configuration?)\n" + ); + return; + } + $referencedpath->{$path} = $volid; + $referenced->{$volid} = $key; + }); + my @sids = PVE::Storage::storage_ids($storecfg); foreach my $storeid (@sids) { my $scfg = PVE::Storage::storage_config($storecfg, $storeid); @@ -342,6 +366,15 @@ sub scan_local_volumes { PVE::Storage::foreach_volid($dl, sub { my ($volid, $sid, $volinfo) = @_; + # check if image is already referenced + my $path = PVE::Storage::path($storecfg, $volid); + if (defined $referencedpath->{$path} && !$referenced->{$volid}) { + $self->log('info', "ignoring '$volid' - already referenced by other storage '$referencedpath->{$path}'\n"); + return; + } + $referencedpath->{$path} = $volid; + $referenced->{$volid} = 1; + $local_volumes->{$volid}->{ref} = 'storage'; $local_volumes->{$volid}->{size} = $volinfo->{size}; $local_volumes->{$volid}->{targetsid} = $targetsid; -- 2.30.2 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel