]> git.proxmox.com Git - qemu-server.git/blobdiff - PVE/QemuMigrate.pm
include additional info in snapshot list
[qemu-server.git] / PVE / QemuMigrate.pm
index 3a8942b42fa7e852f2a7948971dffa339e01998f..c6302b05b10b2cd9ecfd05cb652c0f169948abc9 100644 (file)
@@ -9,6 +9,7 @@ use PVE::INotify;
 use PVE::Cluster;
 use PVE::Storage;
 use PVE::QemuServer;
+use Time::HiRes qw( usleep );
 
 use base qw(PVE::AbstractMigrate);
 
@@ -324,18 +325,51 @@ sub phase2 {
     # start migration
 
     my $start = time();
+
+    my $capabilities = {};
+    $capabilities->{capability} =  "xbzrle";
+    $capabilities->{state} = JSON::false;
+
+    eval {
+       PVE::QemuServer::vm_mon_cmd_nocheck($vmid, "migrate-set-capabilities", capabilities => [$capabilities]);
+    };
+
+    #set cachesize 10% of the total memory
+    my $cachesize = int($conf->{memory}*1048576/10);
+    eval {
+       PVE::QemuServer::vm_mon_cmd_nocheck($vmid, "migrate-set-cache-size", value => $cachesize);
+    };
+
     eval {
         PVE::QemuServer::vm_mon_cmd_nocheck($vmid, "migrate", uri => "tcp:localhost:$lport");
     };
     my $merr = $@;
 
     my $lstat = 0;
+    my $usleep = 2000000;
+    my $i = 0;
+    my $err_count = 0;
     while (1) {
-       sleep (2);
-       my $stat = PVE::QemuServer::vm_mon_cmd_nocheck($vmid, "query-migrate");
+       $i++;
+       my $avglstat = $lstat/$i if $lstat;
+
+       usleep($usleep);
+       my $stat;
+       eval {
+           $stat = PVE::QemuServer::vm_mon_cmd_nocheck($vmid, "query-migrate");
+       };
+       if (my $err = $@) {
+           $err_count++;
+           warn "query migrate failed: $err\n";
+           if ($err_count <= 5) {
+               usleep(1000000);
+               next;
+           }
+           die "too many query migrate failures - aborting\n";
+       }
        if ($stat->{status} =~ m/^(active|completed|failed|cancelled)$/im) {
            $merr = undef;
-
+           $err_count = 0;
            if ($stat->{status} eq 'completed') {
                my $delay = time() - $start;
                if ($delay > 0) {
@@ -357,13 +391,22 @@ sub phase2 {
                my $trans = $stat->{ram}->{transferred} || 0;
                my $rem = $stat->{ram}->{remaining} || 0;
                my $total = $stat->{ram}->{total} || 0;
+               my $xbzrlecachesize = $stat->{"xbzrle-cache"}->{"cache-size"} || 0;
+               my $xbzrlebytes = $stat->{"xbzrle-cache"}->{"bytes"} || 0;
+               my $xbzrlepages = $stat->{"xbzrle-cache"}->{"pages"} || 0;
+               my $xbzrlecachemiss = $stat->{"xbzrle-cache"}->{"cache-miss"} || 0;
+               my $xbzrleoverflow = $stat->{"xbzrle-cache"}->{"overflow"} || 0;
+               #reduce sleep if remainig memory if lower than the everage transfert 
+               $usleep = 300000 if $avglstat && $rem < $avglstat;
 
                $self->log('info', "migration status: $stat->{status} (transferred ${trans}, " .
                           "remaining ${rem}), total ${total})");
+
+               #$self->log('info', "migration xbzrle cachesize: ${xbzrlecachesize} transferred ${xbzrlebytes} pages ${xbzrlepages} cachemiss ${xbzrlecachemiss} overflow ${xbzrleoverflow}");
            }
 
            $lstat = $stat->{ram}->{transferred};
-
+           
        } else {
            die $merr if $merr;
            die "unable to parse migration status '$stat->{status}' - aborting\n";
@@ -374,6 +417,9 @@ sub phase2 {
 sub phase2_cleanup {
     my ($self, $vmid, $err) = @_;
 
+    return if !$self->{errors};
+    $self->{phase2errors} = 1;
+
     $self->log('info', "aborting phase 2 - cleanup resources");
 
     my $conf = $self->{vmconf};
@@ -383,15 +429,22 @@ sub phase2_cleanup {
         $self->log('err', $err);
     }
 
-    ## fixme : vm_stop_cleanup on target vm
-
-
+    # cleanup ressources on target host
+    my $nodename = PVE::INotify::nodename();
+    my $cmd = [@{$self->{rem_ssh}}, 'qm', 'stop', $vmid, '--skiplock', '--migratedfrom', $nodename];
+    eval{ PVE::Tools::run_command($cmd, outfunc => sub {}, errfunc => sub {}) };
+    if (my $err = $@) {
+        $self->log('err', $err);
+        $self->{errors} = 1;
+    }
 }
 
 sub phase3 {
     my ($self, $vmid) = @_;
 
     my $volids = $self->{volumes};
+    return if $self->{phase2errors};
 
     # destroy local copies
     foreach my $volid (@$volids) {
@@ -408,6 +461,7 @@ sub phase3_cleanup {
     my ($self, $vmid, $err) = @_;
 
     my $conf = $self->{vmconf};
+    return if $self->{phase2errors};
 
     # move config to remote node
     my $conffile = PVE::QemuServer::config_file($vmid);