]> git.proxmox.com Git - qemu-server.git/blobdiff - PVE/QemuMigrate.pm
add hugepages option
[qemu-server.git] / PVE / QemuMigrate.pm
index 7b9506f93a65a8e4568a00defcbb61d09f05a1ab..1305b5ca3803b7e09fcd0141aec6f5861cebbe3a 100644 (file)
@@ -164,7 +164,7 @@ sub prepare {
 
     my $running = 0;
     if (my $pid = PVE::QemuServer::check_running($vmid)) {
-       die "cant migrate running VM without --online\n" if !$online;
+       die "can't migrate running VM without --online\n" if !$online;
        $running = $pid;
 
        $self->{forcemachine} = PVE::QemuServer::qemu_machine_pxe($vmid, $conf);
@@ -225,42 +225,41 @@ sub sync_disks {
     eval {
 
        my $volhash = {};
-       my $cdromhash = {};
 
        my $sharedvm = 1;
 
        my @sids = PVE::Storage::storage_ids($self->{storecfg});
-        foreach my $storeid (@sids) {
+       foreach my $storeid (@sids) {
            my $scfg = PVE::Storage::storage_config($self->{storecfg}, $storeid);
-            next if $scfg->{shared};
+           next if $scfg->{shared};
            next if !PVE::Storage::storage_check_enabled($self->{storecfg}, $storeid, undef, 1);
 
-            # get list from PVE::Storage (for unused volumes)
-            my $dl = PVE::Storage::vdisk_list($self->{storecfg}, $storeid, $vmid);
-            PVE::Storage::foreach_volid($dl, sub {
-                my ($volid, $sid, $volname) = @_;
+           # get list from PVE::Storage (for unused volumes)
+           my $dl = PVE::Storage::vdisk_list($self->{storecfg}, $storeid, $vmid);
 
-                # check if storage is available on target node
-                PVE::Storage::storage_check_node($self->{storecfg}, $sid, $self->{node});
+           next if @{$dl->{$storeid}} == 0;
 
-                $volhash->{$volid} = 1;
-               $sharedvm = 0; # there is a non-shared disk
-            });
-        }
+           # check if storage is available on target node
+           PVE::Storage::storage_check_node($self->{storecfg}, $storeid, $self->{node});
+           $sharedvm = 0; # there is a non-shared disk
+
+           PVE::Storage::foreach_volid($dl, sub {
+               my ($volid, $sid, $volname) = @_;
 
-       # and add used, owned/non-shared disks (just to be sure we have all)
+               $volhash->{$volid} = 1;
+           });
+       }
 
-       PVE::QemuServer::foreach_volid($conf, sub {
-           my ($volid, $is_cdrom) = @_;
+       my $test_volid = sub {
+           my ($volid, $is_cdrom, $snapname) = @_;
 
            return if !$volid;
 
            die "can't migrate local file/device '$volid'\n" if $volid =~ m|^/|;
 
            if ($is_cdrom) {
-               die "cant migrate local cdrom drive\n" if $volid eq 'cdrom';
+               die "can't migrate local cdrom drive\n" if $volid eq 'cdrom';
                return if $volid eq 'none';
-               $cdromhash->{$volid} = 1;
            }
 
            my ($sid, $volname) = PVE::Storage::parse_volume_id($volid);
@@ -271,34 +270,64 @@ sub sync_disks {
 
            return if $scfg->{shared};
 
-           die "can't migrate local cdrom '$volid'\n" if $cdromhash->{$volid};
-
            $sharedvm = 0;
 
+           die "can't migrate local cdrom '$volid'\n" if $is_cdrom;
+
            my ($path, $owner) = PVE::Storage::path($self->{storecfg}, $volid);
 
            die "can't migrate volume '$volid' - owned by other VM (owner = VM $owner)\n"
                if !$owner || ($owner != $self->{vmid});
 
-           $volhash->{$volid} = 1;
-       });
+           if (defined($snapname)) {
+               # we cannot migrate shapshots on local storage
+               # exceptions: 'zfspool' or 'qcow2' files (on directory storage)
+
+               my $format = PVE::QemuServer::qemu_img_format($scfg, $volname);
+
+               if (($scfg->{type} eq 'zfspool') || ($format eq 'qcow2')) {
+                   $volhash->{$volid} = 1;
+                   return;
+               }
+
+               die "can't migrate snapshot of local volume '$volid'\n";
+
+           } else {
+               $volhash->{$volid} = 1;
+           }
+       };
+
+       my $test_drive = sub {
+           my ($ds, $drive, $snapname) = @_;
+
+           &$test_volid($drive->{file}, PVE::QemuServer::drive_is_cdrom($drive), $snapname);
+       };
+
+       PVE::QemuServer::foreach_drive($conf, $test_drive);
+       foreach my $snapname (keys %{$conf->{snapshots}}) {
+           &$test_volid($conf->{snapshots}->{$snapname}->{'vmstate'}, 0, undef)
+               if defined($conf->{snapshots}->{$snapname}->{'vmstate'});
+           PVE::QemuServer::foreach_drive($conf->{snapshots}->{$snapname}, $test_drive, $snapname);
+       }
 
        if ($self->{running} && !$sharedvm) {
            die "can't do online migration - VM uses local disks\n";
        }
 
-       # do some checks first
+       # additional checks for local storage
        foreach my $volid (keys %$volhash) {
            my ($sid, $volname) = PVE::Storage::parse_volume_id($volid);
            my $scfg =  PVE::Storage::storage_config($self->{storecfg}, $sid);
 
+           my $migratable = ($scfg->{type} eq 'dir') || ($scfg->{type} eq 'zfspool') ||
+               ($scfg->{type} eq 'lvmthin') || ($scfg->{type} eq 'lvm');
+
            die "can't migrate '$volid' - storage type '$scfg->{type}' not supported\n"
-               if (!($scfg->{type} eq 'dir' || $scfg->{type} eq 'zfspool') && (!$sharedvm));
+               if !$migratable;
 
-           # if file, check if a backing file exist
-           if (!($scfg->{type} eq 'dir' || $scfg->{type} eq 'zfspool') && (!$sharedvm)) {
-               my (undef, undef, undef, $parent) = PVE::Storage::volume_size_info($self->{storecfg}, $volid, 1);
-               die "can't migrate '$volid' as it's a clone of '$parent'" if $parent;
+           # image is a linked clone on local storage, se we can't migrate.
+           if (my $basename = (PVE::Storage::parse_volname($self->{storecfg}, $volid))[3]) {
+               die "can't migrate '$volid' as it's a clone of '$basename'";
            }
        }