]> git.proxmox.com Git - qemu-server.git/commitdiff
migration: fail when aliased volume is detected
authorAaron Lauterer <a.lauterer@proxmox.com>
Mon, 19 Jun 2023 09:29:33 +0000 (11:29 +0200)
committerFiona Ebner <f.ebner@proxmox.com>
Wed, 21 Jun 2023 10:48:11 +0000 (12:48 +0200)
Aliased volids can lead to unexpected behavior in a migration.

An aliased volid can happen if we have two storage configurations,
pointing to the same place. The resulting 'path' for a disk image
will be the same.
Therefore, stop the migration in such a case.

The check works by comparing the path returned by the storage plugin.

We decided against checking the storages themselves being aliased. It is
not possible to infer that reliably from just the storage configuration
options alone.

Reviewed-by: Fiona Ebner <f.ebner@proxmox.com>
Signed-off-by: Aaron Lauterer <a.lauterer@proxmox.com>
PVE/QemuMigrate.pm

index 97a9fbba10ee7b0d0a86ebbbb388b50fc7963e5e..1e19d838c7b844b557411ba0f7e8f655e4587efb 100644 (file)
@@ -316,12 +316,12 @@ sub scan_local_volumes {
 
     my $storecfg = $self->{storecfg};
     eval {
-
        # found local volumes and their origin
        my $local_volumes = $self->{local_volumes};
        my $local_volumes_errors = {};
        my $other_errors = [];
        my $abort = 0;
+       my $path_to_volid = {};
 
        my $log_error = sub {
            my ($msg, $volid) = @_;
@@ -411,6 +411,8 @@ sub scan_local_volumes {
            die "owned by other VM (owner = VM $owner)\n"
                if !$owner || ($owner != $vmid);
 
+           $path_to_volid->{$path}->{$volid} = 1;
+
            return if $attr->{is_vmstate};
 
            if (defined($snaprefs)) {
@@ -444,6 +446,12 @@ sub scan_local_volumes {
            }
         });
 
+       for my $path (keys %$path_to_volid) {
+           my @volids = keys $path_to_volid->{$path}->%*;
+           die "detected not supported aliased volumes: '" . join("', '", @volids) . "'"
+               if (scalar(@volids) > 1);
+       }
+
        foreach my $vol (sort keys %$local_volumes) {
            my $type = $replicatable_volumes->{$vol} ? 'local, replicated' : 'local';
            my $ref = $local_volumes->{$vol}->{ref};