<div dir="ltr">I'm not sure either. We definitely need zero_blocks :)</div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Nov 3, 2014 at 1:24 PM, Alexandre DERUMIER <span dir="ltr"><<a href="mailto:aderumier@odiso.com" target="_blank">aderumier@odiso.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi,<br>
<br>
I didn't known about the blk=> option in qmp migrate.<br>
<br>
Seem to be a lot easier than before.<br>
<br>
<br>
I'll try to test it this week.<br>
<span class=""><br>
<br>
>>- enable migration caps: xbzrle and zero_blocks<br>
<br>
</span>Why do you need xbzrle ? (I'm not sure It's 100% stable yet)<br>
<br>
<br>
<br>
<br>
<br>
----- Mail original -----<br>
<br>
De: "Kamil Trzcinski" <<a href="mailto:ayufan@ayufan.eu">ayufan@ayufan.eu</a>><br>
À: <a href="mailto:pve-devel@pve.proxmox.com">pve-devel@pve.proxmox.com</a><br>
Envoyé: Lundi 3 Novembre 2014 12:12:57<br>
Objet: [pve-devel] [PATCH] Use block storage migration for migration of KVM machines with local based storages<br>
<div><div class="h5"><br>
- allow to migrate only VMs with either local or shared storage<br>
- for stopped VM start it for migration<br>
- allocate remote storage using ssh<br>
- enable migration caps: xbzrle and zero_blocks<br>
<br>
Signed-off-by: Kamil Trzcinski <<a href="mailto:ayufan@ayufan.eu">ayufan@ayufan.eu</a>><br>
---<br>
PVE/QemuMigrate.pm | 77 ++++++++++++++++++++++++++++++++++++++++--------------<br>
PVE/QemuServer.pm | 4 +--<br>
2 files changed, 60 insertions(+), 21 deletions(-)<br>
<br>
diff --git a/PVE/QemuMigrate.pm b/PVE/QemuMigrate.pm<br>
index a49cdcc..8dcc8ab 100644<br>
--- a/PVE/QemuMigrate.pm<br>
+++ b/PVE/QemuMigrate.pm<br>
@@ -3,6 +3,7 @@ package PVE::QemuMigrate;<br>
use strict;<br>
use warnings;<br>
use PVE::AbstractMigrate;<br>
+use JSON;<br>
use IO::File;<br>
use IPC::Open2;<br>
use PVE::INotify;<br>
@@ -141,17 +142,14 @@ sub prepare {<br>
if (my $pid = PVE::QemuServer::check_running($vmid)) {<br>
die "cant migrate running VM without --online\n" if !$online;<br>
$running = $pid;<br>
+ $self->{livemigration} = 1;<br>
$self->{forcemachine} = PVE::QemuServer::get_current_qemu_machine($vmid);<br>
- }<br>
-<br>
- if (my $loc_res = PVE::QemuServer::check_local_resources($conf, 1)) {<br>
- if ($self->{running} || !$self->{opts}->{force}) {<br>
- die "can't migrate VM which uses local devices\n";<br>
} else {<br>
- $self->log('info', "migrating VM which uses local devices");<br>
- }<br>
+ $self->log('info', "starting VM $vmid on local node to perform migration");<br>
+ PVE::QemuServer::vm_start($self->{storecfg}, $vmid, undef, 1, undef, 1);<br>
}<br>
<br>
+ # do we need it? if we already do vm_start?<br>
# activate volumes<br>
my $vollist = PVE::QemuServer::get_vm_volumes($conf);<br>
PVE::Storage::activate_volumes($self->{storecfg}, $vollist);<br>
@@ -163,13 +161,14 @@ sub prepare {<br>
eval { $self->cmd_quiet($cmd); };<br>
die "Can't connect to destination address using public key\n" if $@;<br>
<br>
- return $running;<br>
+ # always perform online migration<br>
+ return 1;<br>
}<br>
<br>
sub sync_disks {<br>
my ($self, $vmid) = @_;<br>
<br>
- $self->log('info', "copying disk images");<br>
+ $self->log('info', "allocating disk images");<br>
<br>
my $conf = $self->{vmconf};<br>
<br>
@@ -238,8 +237,8 @@ sub sync_disks {<br>
$volhash->{$volid} = 1;<br>
});<br>
<br>
- if ($self->{running} && !$sharedvm) {<br>
- die "can't do online migration - VM uses local disks\n";<br>
+ if (%$volhash) {<br>
+ die "can't do migration - VM uses shared and local storage\n" if $sharedvm;<br>
}<br>
<br>
# do some checks first<br>
@@ -247,9 +246,6 @@ sub sync_disks {<br>
my ($sid, $volname) = PVE::Storage::parse_volume_id($volid);<br>
my $scfg = PVE::Storage::storage_config($self->{storecfg}, $sid);<br>
<br>
- die "can't migrate '$volid' - storagy type '$scfg->{type}' not supported\n"<br>
- if $scfg->{type} ne 'dir';<br>
-<br>
# if file, check if a backing file exist<br>
if (($scfg->{type} eq 'dir') && (!$sharedvm)) {<br>
my (undef, undef, undef, $parent) = PVE::Storage::volume_size_info($self->{storecfg}, $volid, 1);<br>
@@ -259,8 +255,8 @@ sub sync_disks {<br>
<br>
foreach my $volid (keys %$volhash) {<br>
my ($sid, $volname) = PVE::Storage::parse_volume_id($volid);<br>
+ PVE::Storage::storage_migrate_alloc($self, $self->{storecfg}, $volid, $self->{nodeip}, $sid);<br>
push @{$self->{volumes}}, $volid;<br>
- PVE::Storage::storage_migrate($self->{storecfg}, $volid, $self->{nodeip}, $sid);<br>
}<br>
};<br>
die "Failed to sync data - $@" if $@;<br>
@@ -286,6 +282,15 @@ sub phase1_cleanup {<br>
<br>
$self->log('info', "aborting phase 1 - cleanup resources");<br>
<br>
+ # always stop local VM if not doing livemigration<br>
+ if(!$self->{livemigration}) {<br>
+ eval { PVE::QemuServer::vm_stop($self->{storecfg}, $vmid, 1, 1); };<br>
+ if (my $err = $@) {<br>
+ $self->log('err', "stopping vm failed - $err");<br>
+ $self->{errors} = 1;<br>
+ }<br>
+ }<br>
+<br>
my $conf = $self->{vmconf};<br>
delete $conf->{lock};<br>
eval { PVE::QemuServer::update_config_nolock($vmid, $conf, 1) };<br>
@@ -296,7 +301,8 @@ sub phase1_cleanup {<br>
if ($self->{volumes}) {<br>
foreach my $volid (@{$self->{volumes}}) {<br>
$self->log('err', "found stale volume copy '$volid' on node '$self->{node}'");<br>
- # fixme: try to remove ?<br>
+ my ($sid, $volname) = PVE::Storage::parse_volume_id($volid);<br>
+ PVE::Storage::storage_migrate_free($self, $self->{storecfg}, $volid, $self->{nodeip}, $sid);<br>
}<br>
}<br>
}<br>
@@ -359,7 +365,6 @@ sub phase2 {<br>
<br>
my $start = time();<br>
$self->log('info', "starting online/live migration on $raddr:$rport");<br>
- $self->{livemigration} = 1;<br>
<br>
# load_defaults<br>
my $defaults = PVE::QemuServer::load_defaults();<br>
@@ -417,7 +422,8 @@ sub phase2 {<br>
}<br>
<br>
eval {<br>
- PVE::QemuServer::vm_mon_cmd_nocheck($vmid, "migrate", uri => "tcp:$raddr:$rport");<br>
+ my $blk = $self->{volumes} ? JSON::true : JSON::false;<br>
+ PVE::QemuServer::vm_mon_cmd_nocheck($vmid, "migrate", uri => "tcp:$raddr:$rport", blk => $blk);<br>
};<br>
my $merr = $@;<br>
$self->log('info', "migrate uri => tcp:$raddr:$rport failed: $merr") if $merr;<br>
@@ -533,6 +539,11 @@ sub phase2_cleanup {<br>
};<br>
$self->log('info', "migrate_cancel error: $@") if $@;<br>
<br>
+ # stop started VM<br>
+ if (!$self->{livemigration}) {<br>
+ eval{ PVE::QemuServer::vm_stop($self->{storecfg}, $vmid, 1); }<br>
+ }<br>
+<br>
my $conf = $self->{vmconf};<br>
delete $conf->{lock};<br>
eval { PVE::QemuServer::update_config_nolock($vmid, $conf, 1) };<br>
@@ -549,6 +560,14 @@ sub phase2_cleanup {<br>
$self->log('err', $err);<br>
$self->{errors} = 1;<br>
}<br>
+<br>
+ if ($self->{volumes}) {<br>
+ foreach my $volid (@{$self->{volumes}}) {<br>
+ $self->log('err', "found stale volume copy '$volid' on node '$self->{node}'");<br>
+ my ($sid, $volname) = PVE::Storage::parse_volume_id($volid);<br>
+ PVE::Storage::storage_migrate_free($self, $self->{storecfg}, $volid, $self->{nodeip}, $sid);<br>
+ }<br>
+ }<br>
}<br>
<br>
sub phase3 {<br>
@@ -557,6 +576,13 @@ sub phase3 {<br>
my $volids = $self->{volumes};<br>
return if $self->{phase2errors};<br>
<br>
+ # stop local VM so we can destroy local copies<br>
+ eval { PVE::QemuServer::vm_stop($self->{storecfg}, $vmid, 1, 1); };<br>
+ if (my $err = $@) {<br>
+ $self->log('err', "stopping vm failed - $err");<br>
+ $self->{errors} = 1;<br>
+ }<br>
+<br>
# destroy local copies<br>
foreach my $volid (@$volids) {<br>
eval { PVE::Storage::vdisk_free($self->{storecfg}, $volid); };<br>
@@ -594,12 +620,25 @@ sub phase3_cleanup {<br>
$self->log('err', $err);<br>
$self->{errors} = 1;<br>
}<br>
+ } else {<br>
+ # now that config file is move, we can stop vm on target if not doing livemigrate<br>
+ my $cmd = [@{$self->{rem_ssh}}, 'qm', 'stop', $vmid, '--skiplock'];<br>
+ eval{ PVE::Tools::run_command($cmd, outfunc => sub {},<br>
+ errfunc => sub {<br>
+ my $line = shift;<br>
+ $self->log('err', $line);<br>
+ });<br>
+ };<br>
+ if (my $err = $@) {<br>
+ $self->log('err', $err);<br>
+ $self->{errors} = 1;<br>
+ }<br>
}<br>
<br>
eval {<br>
<br>
my $timer = 0;<br>
- if (PVE::QemuServer::vga_conf_has_spice($conf->{vga}) && $self->{running}) {<br>
+ if (PVE::QemuServer::vga_conf_has_spice($conf->{vga}) && $self->{livemigration}) {<br>
$self->log('info', "Waiting for spice server migration");<br>
while (1) {<br>
my $res = PVE::QemuServer::vm_mon_cmd_nocheck($vmid, 'query-spice');<br>
diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm<br>
index 98264d1..da4c2b7 100644<br>
--- a/PVE/QemuServer.pm<br>
+++ b/PVE/QemuServer.pm<br>
@@ -3330,9 +3330,9 @@ sub set_migration_caps {<br>
<br>
my $enabled_cap = {<br>
"auto-converge" => 1,<br>
- "xbzrle" => 0,<br>
+ "xbzrle" => 1,<br>
"x-rdma-pin-all" => 0,<br>
- "zero-blocks" => 0,<br>
+ "zero-blocks" => 1,<br>
};<br>
<br>
my $supported_capabilities = vm_mon_cmd_nocheck($vmid, "query-migrate-capabilities");<br>
--<br>
1.9.3 (Apple Git-50)<br>
<br>
</div></div>_______________________________________________<br>
pve-devel mailing list<br>
<a href="mailto:pve-devel@pve.proxmox.com">pve-devel@pve.proxmox.com</a><br>
<a href="http://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel" target="_blank">http://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel</a><br>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature">Kamil Trzciński<br><br><a href="mailto:ayufan@ayufan.eu" target="_blank">ayufan@ayufan.eu</a><br><a href="http://www.ayufan.eu" target="_blank">www.ayufan.eu</a></div>
</div>