my $volhash = {};
my $cdromhash = {};
+ my $sharedvm = 1;
+
my @sids = PVE::Storage::storage_ids($self->{storecfg});
foreach my $storeid (@sids) {
my $scfg = PVE::Storage::storage_config($self->{storecfg}, $storeid);
PVE::Storage::storage_check_node($self->{storecfg}, $sid, $self->{node});
$volhash->{$volid} = 1;
+ $sharedvm = 0; # there is a non-shared disk
});
}
- # and add used,owned/non-shared disks (just to be sure we have all)
+ # and add used, owned/non-shared disks (just to be sure we have all)
- my $sharedvm = 1;
- PVE::QemuServer::foreach_drive($conf, sub {
- my ($ds, $drive) = @_;
+ PVE::QemuServer::foreach_volid($conf, sub {
+ my ($volid, $is_cdrom) = @_;
- my $volid = $drive->{file};
return if !$volid;
die "cant migrate local file/device '$volid'\n" if $volid =~ m|^/|;
- if (PVE::QemuServer::drive_is_cdrom($drive)) {
+ if ($is_cdrom) {
die "cant migrate local cdrom drive\n" if $volid eq 'cdrom';
return if $volid eq 'none';
$cdromhash->{$volid} = 1;
my $start = time();
+ # load_defaults
+ my $defaults = PVE::QemuServer::load_defaults();
+
+ # always set migrate speed (overwrite kvm default of 32m)
+ # we set a very hight default of 8192m which is basically unlimited
+ my $migrate_speed = $defaults->{migrate_speed} || 8192;
+ $migrate_speed = $conf->{migrate_speed} || $migrate_speed;
+ $migrate_speed = $migrate_speed * 1048576;
+ $self->log('info', "migrate_set_speed: $migrate_speed");
+ eval {
+ PVE::QemuServer::vm_mon_cmd_nocheck($vmid, "migrate_set_speed", value => int($migrate_speed));
+ };
+ $self->log('info', "migrate_set_speed error: $@") if $@;
+
+ my $migrate_downtime = $defaults->{migrate_downtime};
+ $migrate_downtime = $conf->{migrate_downtime} if defined($conf->{migrate_downtime});
+ if (defined($migrate_downtime)) {
+ $self->log('info', "migrate_set_downtime: $migrate_downtime");
+ eval {
+ PVE::QemuServer::vm_mon_cmd_nocheck($vmid, "migrate_set_downtime", value => int($migrate_downtime));
+ };
+ $self->log('info', "migrate_set_downtime error: $@") if $@;
+ }
+
my $capabilities = {};
$capabilities->{capability} = "xbzrle";
- $capabilities->{state} = JSON::true;
+ $capabilities->{state} = JSON::false;
eval {
PVE::QemuServer::vm_mon_cmd_nocheck($vmid, "migrate-set-capabilities", capabilities => [$capabilities]);
my $lstat = 0;
my $usleep = 2000000;
my $i = 0;
+ my $err_count = 0;
while (1) {
$i++;
my $avglstat = $lstat/$i if $lstat;
- usleep ($usleep);
- my $stat = PVE::QemuServer::vm_mon_cmd_nocheck($vmid, "query-migrate");
+ 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) {
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 $rem < $avglstat;
+ $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}");
+ #$self->log('info', "migration xbzrle cachesize: ${xbzrlecachesize} transferred ${xbzrlebytes} pages ${xbzrlepages} cachemiss ${xbzrlecachemiss} overflow ${xbzrleoverflow}");
}
$lstat = $stat->{ram}->{transferred};