* [pve-devel] [PATCH v4 qemu-server 0/2] remote-migration: migration with different cpu @ 2023-09-28 14:45 Alexandre Derumier 2023-09-28 14:45 ` [pve-devel] [PATCH v4 qemu-server 1/2] migration: move livemigration code in a dedicated sub Alexandre Derumier 2023-09-28 14:45 ` [pve-devel] [PATCH v4 qemu-server 2/2] remote-migration: add target-cpu && target-reboot params Alexandre Derumier 0 siblings, 2 replies; 15+ messages in thread From: Alexandre Derumier @ 2023-09-28 14:45 UTC (permalink / raw) To: pve-devel This patch series allow remote migration between cluster with different cpu model. 2 new params are introduced: "target-cpu" && "target-reboot" If target-cpu is defined, this will replace the cpu model of the target vm. If vm is online/running, an extra "target-reboot" safeguard option is needed. Indeed, as the target cpu is different, the live migration with memory transfert is skipped (as anyway, the target will die with a different cpu). Then, after the storage copy, we switch source vm disk to the targetvm nbd export, then shutdown the source vm and restart the target vm. (Like a virtual reboot between source/target) Changelog v2: The first version was simply shuting down the target vm, wihout doing the block-job-complete. After doing production migration with around 400vms, I had some fs corruption, like some datas was still in buffer. This v2 has been tested with another 400vms batch, without any corruption. Changelog v3: v2 was not perfect, still have some 1 or 2 fs corruption with vms doing a lot of write. This v3 retake idea of the v1 but in a cleaner way - we migrate disk to target vm - source vm is switching disk to the nbd of the target vm. (with a block-job-complete, and not a block-job-cancel with standard disk migration). We are 100% sure it that no pending write is still pending in the migration job. - source vm is shutdown - target with is restart Changelog v4: - bugfix: no not override cpu with empty config if targetcpu is not defined - small cleanups with params We have redone a lot of migration this summer( maybe another 4000vm), 0 corruption, windows or linux guest vms. Alexandre Derumier (2): migration: move livemigration code in a dedicated sub remote-migration: add target-cpu && target-reboot params PVE/API2/Qemu.pm | 23 ++- PVE/CLI/qm.pm | 11 ++ PVE/QemuMigrate.pm | 451 ++++++++++++++++++++++++--------------------- 3 files changed, 276 insertions(+), 209 deletions(-) -- 2.39.2 ^ permalink raw reply [flat|nested] 15+ messages in thread
* [pve-devel] [PATCH v4 qemu-server 1/2] migration: move livemigration code in a dedicated sub 2023-09-28 14:45 [pve-devel] [PATCH v4 qemu-server 0/2] remote-migration: migration with different cpu Alexandre Derumier @ 2023-09-28 14:45 ` Alexandre Derumier 2023-10-09 11:25 ` Fiona Ebner 2023-09-28 14:45 ` [pve-devel] [PATCH v4 qemu-server 2/2] remote-migration: add target-cpu && target-reboot params Alexandre Derumier 1 sibling, 1 reply; 15+ messages in thread From: Alexandre Derumier @ 2023-09-28 14:45 UTC (permalink / raw) To: pve-devel --- PVE/QemuMigrate.pm | 420 +++++++++++++++++++++++---------------------- 1 file changed, 214 insertions(+), 206 deletions(-) diff --git a/PVE/QemuMigrate.pm b/PVE/QemuMigrate.pm index f41c61f..5ea78a7 100644 --- a/PVE/QemuMigrate.pm +++ b/PVE/QemuMigrate.pm @@ -726,6 +726,219 @@ sub cleanup_bitmaps { } } +sub live_migration { + my ($self, $vmid, $migrate_uri, $spice_port) = @_; + + my $conf = $self->{vmconf}; + + $self->log('info', "starting online/live migration on $migrate_uri"); + $self->{livemigration} = 1; + + # load_defaults + my $defaults = PVE::QemuServer::load_defaults(); + + $self->log('info', "set migration capabilities"); + eval { PVE::QemuServer::set_migration_caps($vmid) }; + warn $@ if $@; + + my $qemu_migrate_params = {}; + + # migrate speed can be set via bwlimit (datacenter.cfg and API) and via the + # migrate_speed parameter in qm.conf - take the lower of the two. + my $bwlimit = $self->get_bwlimit(); + + my $migrate_speed = $conf->{migrate_speed} // 0; + $migrate_speed *= 1024; # migrate_speed is in MB/s, bwlimit in KB/s + + if ($bwlimit && $migrate_speed) { + $migrate_speed = ($bwlimit < $migrate_speed) ? $bwlimit : $migrate_speed; + } else { + $migrate_speed ||= $bwlimit; + } + $migrate_speed ||= ($defaults->{migrate_speed} || 0) * 1024; + + if ($migrate_speed) { + $migrate_speed *= 1024; # qmp takes migrate_speed in B/s. + $self->log('info', "migration speed limit: ". render_bytes($migrate_speed, 1) ."/s"); + } else { + # always set migrate speed as QEMU default to 128 MiBps == 1 Gbps, use 16 GiBps == 128 Gbps + $migrate_speed = (16 << 30); + } + $qemu_migrate_params->{'max-bandwidth'} = int($migrate_speed); + + my $migrate_downtime = $defaults->{migrate_downtime}; + $migrate_downtime = $conf->{migrate_downtime} if defined($conf->{migrate_downtime}); + # migrate-set-parameters expects limit in ms + $migrate_downtime *= 1000; + $self->log('info', "migration downtime limit: $migrate_downtime ms"); + $qemu_migrate_params->{'downtime-limit'} = int($migrate_downtime); + + # set cachesize to 10% of the total memory + my $memory = get_current_memory($conf->{memory}); + my $cachesize = int($memory * 1048576 / 10); + $cachesize = round_powerof2($cachesize); + + $self->log('info', "migration cachesize: " . render_bytes($cachesize, 1)); + $qemu_migrate_params->{'xbzrle-cache-size'} = int($cachesize); + + $self->log('info', "set migration parameters"); + eval { + mon_cmd($vmid, "migrate-set-parameters", %{$qemu_migrate_params}); + }; + $self->log('info', "migrate-set-parameters error: $@") if $@; + + if (PVE::QemuServer::vga_conf_has_spice($conf->{vga}) && !$self->{opts}->{remote}) { + my $rpcenv = PVE::RPCEnvironment::get(); + my $authuser = $rpcenv->get_user(); + + my (undef, $proxyticket) = PVE::AccessControl::assemble_spice_ticket($authuser, $vmid, $self->{node}); + + my $filename = "/etc/pve/nodes/$self->{node}/pve-ssl.pem"; + my $subject = PVE::AccessControl::read_x509_subject_spice($filename); + + $self->log('info', "spice client_migrate_info"); + + eval { + mon_cmd($vmid, "client_migrate_info", protocol => 'spice', + hostname => $proxyticket, 'port' => 0, 'tls-port' => $spice_port, + 'cert-subject' => $subject); + }; + $self->log('info', "client_migrate_info error: $@") if $@; + + } + + my $start = time(); + + $self->log('info', "start migrate command to $migrate_uri"); + eval { + mon_cmd($vmid, "migrate", uri => $migrate_uri); + }; + my $merr = $@; + $self->log('info', "migrate uri => $migrate_uri failed: $merr") if $merr; + + my $last_mem_transferred = 0; + my $usleep = 1000000; + my $i = 0; + my $err_count = 0; + my $lastrem = undef; + my $downtimecounter = 0; + while (1) { + $i++; + my $avglstat = $last_mem_transferred ? $last_mem_transferred / $i : 0; + + usleep($usleep); + + my $stat = eval { mon_cmd($vmid, "query-migrate") }; + if (my $err = $@) { + $err_count++; + warn "query migrate failed: $err\n"; + $self->log('info', "query migrate failed: $err"); + if ($err_count <= 5) { + usleep(1_000_000); + next; + } + die "too many query migrate failures - aborting\n"; + } + + my $status = $stat->{status}; + if (defined($status) && $status =~ m/^(setup)$/im) { + sleep(1); + next; + } + + if (!defined($status) || $status !~ m/^(active|completed|failed|cancelled)$/im) { + die $merr if $merr; + die "unable to parse migration status '$status' - aborting\n"; + } + $merr = undef; + $err_count = 0; + + my $memstat = $stat->{ram}; + + if ($status eq 'completed') { + my $delay = time() - $start; + if ($delay > 0) { + my $total = $memstat->{total} || 0; + my $avg_speed = render_bytes($total / $delay, 1); + my $downtime = $stat->{downtime} || 0; + $self->log('info', "average migration speed: $avg_speed/s - downtime $downtime ms"); + } + } + + if ($status eq 'failed' || $status eq 'cancelled') { + my $message = $stat->{'error-desc'} ? "$status - $stat->{'error-desc'}" : $status; + $self->log('info', "migration status error: $message"); + die "aborting\n" + } + + if ($status ne 'active') { + $self->log('info', "migration status: $status"); + last; + } + + if ($memstat->{transferred} ne $last_mem_transferred) { + my $trans = $memstat->{transferred} || 0; + my $rem = $memstat->{remaining} || 0; + my $total = $memstat->{total} || 0; + my $speed = ($memstat->{'pages-per-second'} // 0) * ($memstat->{'page-size'} // 0); + my $dirty_rate = ($memstat->{'dirty-pages-rate'} // 0) * ($memstat->{'page-size'} // 0); + + # reduce sleep if remainig memory is lower than the average transfer speed + $usleep = 100_000 if $avglstat && $rem < $avglstat; + + # also reduce loggin if we poll more frequent + my $should_log = $usleep > 100_000 ? 1 : ($i % 10) == 0; + + my $total_h = render_bytes($total, 1); + my $transferred_h = render_bytes($trans, 1); + my $speed_h = render_bytes($speed, 1); + + my $progress = "transferred $transferred_h of $total_h VM-state, ${speed_h}/s"; + + if ($dirty_rate > $speed) { + my $dirty_rate_h = render_bytes($dirty_rate, 1); + $progress .= ", VM dirties lots of memory: $dirty_rate_h/s"; + } + + $self->log('info', "migration $status, $progress") if $should_log; + + my $xbzrle = $stat->{"xbzrle-cache"} || {}; + my ($xbzrlebytes, $xbzrlepages) = $xbzrle->@{'bytes', 'pages'}; + if ($xbzrlebytes || $xbzrlepages) { + my $bytes_h = render_bytes($xbzrlebytes, 1); + + my $msg = "send updates to $xbzrlepages pages in $bytes_h encoded memory"; + + $msg .= sprintf(", cache-miss %.2f%%", $xbzrle->{'cache-miss-rate'} * 100) + if $xbzrle->{'cache-miss-rate'}; + + $msg .= ", overflow $xbzrle->{overflow}" if $xbzrle->{overflow}; + + $self->log('info', "xbzrle: $msg") if $should_log; + } + + if (($lastrem && $rem > $lastrem) || ($rem == 0)) { + $downtimecounter++; + } + $lastrem = $rem; + + if ($downtimecounter > 5) { + $downtimecounter = 0; + $migrate_downtime *= 2; + $self->log('info', "auto-increased downtime to continue migration: $migrate_downtime ms"); + eval { + # migrate-set-parameters does not touch values not + # specified, so this only changes downtime-limit + mon_cmd($vmid, "migrate-set-parameters", 'downtime-limit' => int($migrate_downtime)); + }; + $self->log('info', "migrate-set-parameters error: $@") if $@; + } + } + + $last_mem_transferred = $memstat->{transferred}; + } +} + sub phase1 { my ($self, $vmid) = @_; @@ -1137,212 +1350,7 @@ sub phase2 { } } - $self->log('info', "starting online/live migration on $migrate_uri"); - $self->{livemigration} = 1; - - # load_defaults - my $defaults = PVE::QemuServer::load_defaults(); - - $self->log('info', "set migration capabilities"); - eval { PVE::QemuServer::set_migration_caps($vmid) }; - warn $@ if $@; - - my $qemu_migrate_params = {}; - - # migrate speed can be set via bwlimit (datacenter.cfg and API) and via the - # migrate_speed parameter in qm.conf - take the lower of the two. - my $bwlimit = $self->get_bwlimit(); - - my $migrate_speed = $conf->{migrate_speed} // 0; - $migrate_speed *= 1024; # migrate_speed is in MB/s, bwlimit in KB/s - - if ($bwlimit && $migrate_speed) { - $migrate_speed = ($bwlimit < $migrate_speed) ? $bwlimit : $migrate_speed; - } else { - $migrate_speed ||= $bwlimit; - } - $migrate_speed ||= ($defaults->{migrate_speed} || 0) * 1024; - - if ($migrate_speed) { - $migrate_speed *= 1024; # qmp takes migrate_speed in B/s. - $self->log('info', "migration speed limit: ". render_bytes($migrate_speed, 1) ."/s"); - } else { - # always set migrate speed as QEMU default to 128 MiBps == 1 Gbps, use 16 GiBps == 128 Gbps - $migrate_speed = (16 << 30); - } - $qemu_migrate_params->{'max-bandwidth'} = int($migrate_speed); - - my $migrate_downtime = $defaults->{migrate_downtime}; - $migrate_downtime = $conf->{migrate_downtime} if defined($conf->{migrate_downtime}); - # migrate-set-parameters expects limit in ms - $migrate_downtime *= 1000; - $self->log('info', "migration downtime limit: $migrate_downtime ms"); - $qemu_migrate_params->{'downtime-limit'} = int($migrate_downtime); - - # set cachesize to 10% of the total memory - my $memory = get_current_memory($conf->{memory}); - my $cachesize = int($memory * 1048576 / 10); - $cachesize = round_powerof2($cachesize); - - $self->log('info', "migration cachesize: " . render_bytes($cachesize, 1)); - $qemu_migrate_params->{'xbzrle-cache-size'} = int($cachesize); - - $self->log('info', "set migration parameters"); - eval { - mon_cmd($vmid, "migrate-set-parameters", %{$qemu_migrate_params}); - }; - $self->log('info', "migrate-set-parameters error: $@") if $@; - - if (PVE::QemuServer::vga_conf_has_spice($conf->{vga}) && !$self->{opts}->{remote}) { - my $rpcenv = PVE::RPCEnvironment::get(); - my $authuser = $rpcenv->get_user(); - - my (undef, $proxyticket) = PVE::AccessControl::assemble_spice_ticket($authuser, $vmid, $self->{node}); - - my $filename = "/etc/pve/nodes/$self->{node}/pve-ssl.pem"; - my $subject = PVE::AccessControl::read_x509_subject_spice($filename); - - $self->log('info', "spice client_migrate_info"); - - eval { - mon_cmd($vmid, "client_migrate_info", protocol => 'spice', - hostname => $proxyticket, 'port' => 0, 'tls-port' => $spice_port, - 'cert-subject' => $subject); - }; - $self->log('info', "client_migrate_info error: $@") if $@; - - } - - my $start = time(); - - $self->log('info', "start migrate command to $migrate_uri"); - eval { - mon_cmd($vmid, "migrate", uri => $migrate_uri); - }; - my $merr = $@; - $self->log('info', "migrate uri => $migrate_uri failed: $merr") if $merr; - - my $last_mem_transferred = 0; - my $usleep = 1000000; - my $i = 0; - my $err_count = 0; - my $lastrem = undef; - my $downtimecounter = 0; - while (1) { - $i++; - my $avglstat = $last_mem_transferred ? $last_mem_transferred / $i : 0; - - usleep($usleep); - - my $stat = eval { mon_cmd($vmid, "query-migrate") }; - if (my $err = $@) { - $err_count++; - warn "query migrate failed: $err\n"; - $self->log('info', "query migrate failed: $err"); - if ($err_count <= 5) { - usleep(1_000_000); - next; - } - die "too many query migrate failures - aborting\n"; - } - - my $status = $stat->{status}; - if (defined($status) && $status =~ m/^(setup)$/im) { - sleep(1); - next; - } - - if (!defined($status) || $status !~ m/^(active|completed|failed|cancelled)$/im) { - die $merr if $merr; - die "unable to parse migration status '$status' - aborting\n"; - } - $merr = undef; - $err_count = 0; - - my $memstat = $stat->{ram}; - - if ($status eq 'completed') { - my $delay = time() - $start; - if ($delay > 0) { - my $total = $memstat->{total} || 0; - my $avg_speed = render_bytes($total / $delay, 1); - my $downtime = $stat->{downtime} || 0; - $self->log('info', "average migration speed: $avg_speed/s - downtime $downtime ms"); - } - } - - if ($status eq 'failed' || $status eq 'cancelled') { - my $message = $stat->{'error-desc'} ? "$status - $stat->{'error-desc'}" : $status; - $self->log('info', "migration status error: $message"); - die "aborting\n" - } - - if ($status ne 'active') { - $self->log('info', "migration status: $status"); - last; - } - - if ($memstat->{transferred} ne $last_mem_transferred) { - my $trans = $memstat->{transferred} || 0; - my $rem = $memstat->{remaining} || 0; - my $total = $memstat->{total} || 0; - my $speed = ($memstat->{'pages-per-second'} // 0) * ($memstat->{'page-size'} // 0); - my $dirty_rate = ($memstat->{'dirty-pages-rate'} // 0) * ($memstat->{'page-size'} // 0); - - # reduce sleep if remainig memory is lower than the average transfer speed - $usleep = 100_000 if $avglstat && $rem < $avglstat; - - # also reduce loggin if we poll more frequent - my $should_log = $usleep > 100_000 ? 1 : ($i % 10) == 0; - - my $total_h = render_bytes($total, 1); - my $transferred_h = render_bytes($trans, 1); - my $speed_h = render_bytes($speed, 1); - - my $progress = "transferred $transferred_h of $total_h VM-state, ${speed_h}/s"; - - if ($dirty_rate > $speed) { - my $dirty_rate_h = render_bytes($dirty_rate, 1); - $progress .= ", VM dirties lots of memory: $dirty_rate_h/s"; - } - - $self->log('info', "migration $status, $progress") if $should_log; - - my $xbzrle = $stat->{"xbzrle-cache"} || {}; - my ($xbzrlebytes, $xbzrlepages) = $xbzrle->@{'bytes', 'pages'}; - if ($xbzrlebytes || $xbzrlepages) { - my $bytes_h = render_bytes($xbzrlebytes, 1); - - my $msg = "send updates to $xbzrlepages pages in $bytes_h encoded memory"; - - $msg .= sprintf(", cache-miss %.2f%%", $xbzrle->{'cache-miss-rate'} * 100) - if $xbzrle->{'cache-miss-rate'}; - - $msg .= ", overflow $xbzrle->{overflow}" if $xbzrle->{overflow}; - - $self->log('info', "xbzrle: $msg") if $should_log; - } - - if (($lastrem && $rem > $lastrem) || ($rem == 0)) { - $downtimecounter++; - } - $lastrem = $rem; - - if ($downtimecounter > 5) { - $downtimecounter = 0; - $migrate_downtime *= 2; - $self->log('info', "auto-increased downtime to continue migration: $migrate_downtime ms"); - eval { - # migrate-set-parameters does not touch values not - # specified, so this only changes downtime-limit - mon_cmd($vmid, "migrate-set-parameters", 'downtime-limit' => int($migrate_downtime)); - }; - $self->log('info', "migrate-set-parameters error: $@") if $@; - } - } - - $last_mem_transferred = $memstat->{transferred}; - } + live_migration($self, $vmid, $migrate_uri, $spice_port); if ($self->{storage_migration}) { # finish block-job with block-job-cancel, to disconnect source VM from NBD -- 2.39.2 ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [pve-devel] [PATCH v4 qemu-server 1/2] migration: move livemigration code in a dedicated sub 2023-09-28 14:45 ` [pve-devel] [PATCH v4 qemu-server 1/2] migration: move livemigration code in a dedicated sub Alexandre Derumier @ 2023-10-09 11:25 ` Fiona Ebner 0 siblings, 0 replies; 15+ messages in thread From: Fiona Ebner @ 2023-10-09 11:25 UTC (permalink / raw) To: Proxmox VE development discussion, Alexandre Derumier Missing your Signed-off-by trailer. Apart from that Reviewed-by: Fiona Ebner <f.ebner@proxmox.com> ^ permalink raw reply [flat|nested] 15+ messages in thread
* [pve-devel] [PATCH v4 qemu-server 2/2] remote-migration: add target-cpu && target-reboot params 2023-09-28 14:45 [pve-devel] [PATCH v4 qemu-server 0/2] remote-migration: migration with different cpu Alexandre Derumier 2023-09-28 14:45 ` [pve-devel] [PATCH v4 qemu-server 1/2] migration: move livemigration code in a dedicated sub Alexandre Derumier @ 2023-09-28 14:45 ` Alexandre Derumier 2023-10-09 12:13 ` Fiona Ebner 1 sibling, 1 reply; 15+ messages in thread From: Alexandre Derumier @ 2023-09-28 14:45 UTC (permalink / raw) To: pve-devel This patch add support for remote migration when target cpu model is different. target-reboot param need to be defined to allow migration whens source vm is online. When defined, only the live storage migration is done, and instead to transfert memory, we cleanly shutdown source vm and restart the target vm. (like a virtual reboot between source/dest) --- PVE/API2/Qemu.pm | 23 ++++++++++++++++++++++- PVE/CLI/qm.pm | 11 +++++++++++ PVE/QemuMigrate.pm | 31 +++++++++++++++++++++++++++++-- 3 files changed, 62 insertions(+), 3 deletions(-) diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm index 774b0c7..38991e9 100644 --- a/PVE/API2/Qemu.pm +++ b/PVE/API2/Qemu.pm @@ -4586,6 +4586,17 @@ __PACKAGE__->register_method({ optional => 1, default => 0, }, + 'target-cpu' => { + optional => 1, + description => "Target Emulated CPU model. For online migration, this require target-reboot option", + type => 'string', + format => 'pve-vm-cpu-conf', + }, + 'target-reboot' => { + type => 'boolean', + description => "For online migration , don't migrate memory, only storage. Then, the source vm is shutdown and the target vm is restarted.", + optional => 1, + }, 'target-storage' => get_standard_option('pve-targetstorage', { completion => \&PVE::QemuServer::complete_migration_storage, optional => 0, @@ -4666,7 +4677,7 @@ __PACKAGE__->register_method({ if (PVE::QemuServer::check_running($source_vmid)) { die "can't migrate running VM without --online\n" if !$param->{online}; - + die "can't migrate running VM without --target-reboot when target cpu is different" if $param->{'target-cpu'} && !$param->{'target-reboot'}; } else { warn "VM isn't running. Doing offline migration instead.\n" if $param->{online}; $param->{online} = 0; @@ -4683,6 +4694,7 @@ __PACKAGE__->register_method({ raise_param_exc({ 'target-bridge' => "failed to parse bridge map: $@" }) if $@; + die "remote migration requires explicit storage mapping!\n" if $storagemap->{identity}; @@ -5732,6 +5744,15 @@ __PACKAGE__->register_method({ PVE::QemuServer::nbd_stop($state->{vmid}); return; }, + 'restart' => sub { + PVE::QemuServer::vm_stop(undef, $state->{vmid}, 1, 1); + my $info = PVE::QemuServer::vm_start_nolock( + $state->{storecfg}, + $state->{vmid}, + $state->{conf}, + ); + return; + }, 'resume' => sub { if (PVE::QemuServer::Helpers::vm_running_locally($state->{vmid})) { PVE::QemuServer::vm_resume($state->{vmid}, 1, 1); diff --git a/PVE/CLI/qm.pm b/PVE/CLI/qm.pm index b17b4fe..9d89cfe 100755 --- a/PVE/CLI/qm.pm +++ b/PVE/CLI/qm.pm @@ -189,6 +189,17 @@ __PACKAGE__->register_method({ optional => 1, default => 0, }, + 'target-cpu' => { + optional => 1, + description => "Target Emulated CPU model. For online migration, this require target-reboot option", + type => 'string', + format => 'pve-vm-cpu-conf', + }, + 'target-reboot' => { + type => 'boolean', + description => "For online migration , don't migrate memory, only storage. Then, the source vm is shutdown and the target vm is restarted.", + optional => 1, + }, 'target-storage' => get_standard_option('pve-targetstorage', { completion => \&PVE::QemuServer::complete_migration_storage, optional => 0, diff --git a/PVE/QemuMigrate.pm b/PVE/QemuMigrate.pm index 5ea78a7..8131b0b 100644 --- a/PVE/QemuMigrate.pm +++ b/PVE/QemuMigrate.pm @@ -729,6 +729,11 @@ sub cleanup_bitmaps { sub live_migration { my ($self, $vmid, $migrate_uri, $spice_port) = @_; + if($self->{opts}->{'target-reboot'}){ + $self->log('info', "target reboot - skip live migration."); + return; + } + my $conf = $self->{vmconf}; $self->log('info', "starting online/live migration on $migrate_uri"); @@ -993,6 +998,7 @@ sub phase1_remote { my $remote_conf = PVE::QemuConfig->load_config($vmid); PVE::QemuConfig->update_volume_ids($remote_conf, $self->{volume_map}); + $remote_conf->{cpu} = $self->{opts}->{'target-cpu'} if $self->{opts}->{'target-cpu'}; my $bridges = map_bridges($remote_conf, $self->{opts}->{bridgemap}); for my $target (keys $bridges->%*) { for my $nic (keys $bridges->{$target}->%*) { @@ -1356,7 +1362,14 @@ sub phase2 { # finish block-job with block-job-cancel, to disconnect source VM from NBD # to avoid it trying to re-establish it. We are in blockjob ready state, # thus, this command changes to it to blockjob complete (see qapi docs) - eval { PVE::QemuServer::qemu_drive_mirror_monitor($vmid, undef, $self->{storage_migration_jobs}, 'cancel'); }; + my $finish_cmd = "cancel"; + if ($self->{opts}->{'target-reboot'}) { + # no live migration. + # finish block-job with block-job-complete, the source will switch to remote NDB + # then we cleanly stop the source vm at phase3 + $finish_cmd = "complete"; + } + eval { PVE::QemuServer::qemu_drive_mirror_monitor($vmid, undef, $self->{storage_migration_jobs}, $finish_cmd); }; if (my $err = $@) { die "Failed to complete storage migration: $err\n"; } @@ -1573,7 +1586,17 @@ sub phase3_cleanup { }; # always stop local VM with nocheck, since config is moved already - eval { PVE::QemuServer::vm_stop($self->{storecfg}, $vmid, 1, 1); }; + my $shutdown_timeout = undef; + my $shutdown = undef; + my $force_stop = undef; + if ($self->{opts}->{'target-reboot'}) { + $shutdown_timeout = 180; + $shutdown = 1; + $force_stop = 1; + $self->log('info', "clean shutdown of source vm."); + } + + eval { PVE::QemuServer::vm_stop($self->{storecfg}, $vmid, 1, 1, $shutdown_timeout, $shutdown, $force_stop); }; if (my $err = $@) { $self->log('err', "stopping vm failed - $err"); $self->{errors} = 1; @@ -1607,6 +1630,10 @@ sub phase3_cleanup { # clear migrate lock if ($tunnel && $tunnel->{version} >= 2) { PVE::Tunnel::write_tunnel($tunnel, 10, "unlock"); + if ($self->{opts}->{'target-reboot'}) { + $self->log('info', "restart target vm."); + PVE::Tunnel::write_tunnel($tunnel, 10, 'restart'); + } PVE::Tunnel::finish_tunnel($tunnel); } else { -- 2.39.2 ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [pve-devel] [PATCH v4 qemu-server 2/2] remote-migration: add target-cpu && target-reboot params 2023-09-28 14:45 ` [pve-devel] [PATCH v4 qemu-server 2/2] remote-migration: add target-cpu && target-reboot params Alexandre Derumier @ 2023-10-09 12:13 ` Fiona Ebner 2023-10-09 13:47 ` DERUMIER, Alexandre 0 siblings, 1 reply; 15+ messages in thread From: Fiona Ebner @ 2023-10-09 12:13 UTC (permalink / raw) To: Proxmox VE development discussion, Alexandre Derumier There can be other reasons to do a restart-migration, see also https://bugzilla.proxmox.com/show_bug.cgi?id=4530, so I feel like this should be split. One for introducing target-reboot and one for introducing target-cpu. For 'target-reboot', the question is if we should call it 'restart' like for container migration for consistency? Could also be introduced for normal migration while we're at it. One could argue that a true 'restart' migration would migrate the volumes also offline, but right now, I don't see a big downside to do it via NBD like in this patch. Still, something we should think about. If it turns out to be really needed, we'd need two different ways to do a restart migration :/ Am 28.09.23 um 16:45 schrieb Alexandre Derumier: > This patch add support for remote migration when target > cpu model is different. > > target-reboot param need to be defined to allow migration > whens source vm is online. > > When defined, only the live storage migration is done, > and instead to transfert memory, we cleanly shutdown source vm > and restart the target vm. (like a virtual reboot between source/dest) Missing your Signed-off-by > --- > PVE/API2/Qemu.pm | 23 ++++++++++++++++++++++- > PVE/CLI/qm.pm | 11 +++++++++++ > PVE/QemuMigrate.pm | 31 +++++++++++++++++++++++++++++-- > 3 files changed, 62 insertions(+), 3 deletions(-) > > diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm > index 774b0c7..38991e9 100644 > --- a/PVE/API2/Qemu.pm > +++ b/PVE/API2/Qemu.pm > @@ -4586,6 +4586,17 @@ __PACKAGE__->register_method({ > optional => 1, > default => 0, > }, > + 'target-cpu' => { > + optional => 1, > + description => "Target Emulated CPU model. For online migration, this require target-reboot option", To enforce it, you can use: requires => 'target-reboot', > + type => 'string', > + format => 'pve-vm-cpu-conf',> + }, > + 'target-reboot' => { > + type => 'boolean', > + description => "For online migration , don't migrate memory, only storage. Then, the source vm is shutdown and the target vm is restarted.", > + optional => 1, > + }, > 'target-storage' => get_standard_option('pve-targetstorage', { > completion => \&PVE::QemuServer::complete_migration_storage, > optional => 0, > @@ -4666,7 +4677,7 @@ __PACKAGE__->register_method({ > > if (PVE::QemuServer::check_running($source_vmid)) { > die "can't migrate running VM without --online\n" if !$param->{online}; > - > + die "can't migrate running VM without --target-reboot when target cpu is different" if $param->{'target-cpu'} && !$param->{'target-reboot'}; > } else { > warn "VM isn't running. Doing offline migration instead.\n" if $param->{online}; > $param->{online} = 0; > @@ -4683,6 +4694,7 @@ __PACKAGE__->register_method({ > raise_param_exc({ 'target-bridge' => "failed to parse bridge map: $@" }) > if $@; > > + > die "remote migration requires explicit storage mapping!\n" > if $storagemap->{identity}; > Nit: unrelated change > @@ -5732,6 +5744,15 @@ __PACKAGE__->register_method({ > PVE::QemuServer::nbd_stop($state->{vmid}); > return; > }, > + 'restart' => sub { > + PVE::QemuServer::vm_stop(undef, $state->{vmid}, 1, 1); The first parameter is $storecfg and is not optional. To avoid deactivating the volumes, use the $keepActive parameter. > + my $info = PVE::QemuServer::vm_start_nolock( > + $state->{storecfg}, > + $state->{vmid}, > + $state->{conf}, > + ); > + return; > + }, > 'resume' => sub { > if (PVE::QemuServer::Helpers::vm_running_locally($state->{vmid})) { > PVE::QemuServer::vm_resume($state->{vmid}, 1, 1); > diff --git a/PVE/CLI/qm.pm b/PVE/CLI/qm.pm > index b17b4fe..9d89cfe 100755 > --- a/PVE/CLI/qm.pm > +++ b/PVE/CLI/qm.pm > @@ -189,6 +189,17 @@ __PACKAGE__->register_method({ > optional => 1, > default => 0, > }, > + 'target-cpu' => { > + optional => 1, > + description => "Target Emulated CPU model. For online migration, this require target-reboot option", Again, can be enforced requires => 'target-reboot', > + type => 'string', > + format => 'pve-vm-cpu-conf', > + }, > + 'target-reboot' => { > + type => 'boolean', > + description => "For online migration , don't migrate memory, only storage. Then, the source vm is shutdown and the target vm is restarted.", > + optional => 1, > + }, > 'target-storage' => get_standard_option('pve-targetstorage', { > completion => \&PVE::QemuServer::complete_migration_storage, > optional => 0, > diff --git a/PVE/QemuMigrate.pm b/PVE/QemuMigrate.pm > index 5ea78a7..8131b0b 100644 > --- a/PVE/QemuMigrate.pm > +++ b/PVE/QemuMigrate.pm > @@ -729,6 +729,11 @@ sub cleanup_bitmaps { > sub live_migration { > my ($self, $vmid, $migrate_uri, $spice_port) = @_; > > + if($self->{opts}->{'target-reboot'}){ > + $self->log('info', "target reboot - skip live migration."); using restart migration - skipping live migration > + return; > + } > + > my $conf = $self->{vmconf}; > > $self->log('info', "starting online/live migration on $migrate_uri"); > @@ -993,6 +998,7 @@ sub phase1_remote { > my $remote_conf = PVE::QemuConfig->load_config($vmid); > PVE::QemuConfig->update_volume_ids($remote_conf, $self->{volume_map}); > > + $remote_conf->{cpu} = $self->{opts}->{'target-cpu'} if $self->{opts}->{'target-cpu'}; > my $bridges = map_bridges($remote_conf, $self->{opts}->{bridgemap}); > for my $target (keys $bridges->%*) { > for my $nic (keys $bridges->{$target}->%*) { > @@ -1356,7 +1362,14 @@ sub phase2 { > # finish block-job with block-job-cancel, to disconnect source VM from NBD > # to avoid it trying to re-establish it. We are in blockjob ready state, > # thus, this command changes to it to blockjob complete (see qapi docs) > - eval { PVE::QemuServer::qemu_drive_mirror_monitor($vmid, undef, $self->{storage_migration_jobs}, 'cancel'); }; > + my $finish_cmd = "cancel"; > + if ($self->{opts}->{'target-reboot'}) { > + # no live migration. > + # finish block-job with block-job-complete, the source will switch to remote NDB > + # then we cleanly stop the source vm at phase3 Nit: "during phase3" or "in phase3" > + $finish_cmd = "complete"; > + } > + eval { PVE::QemuServer::qemu_drive_mirror_monitor($vmid, undef, $self->{storage_migration_jobs}, $finish_cmd); }; > if (my $err = $@) { > die "Failed to complete storage migration: $err\n"; > } > @@ -1573,7 +1586,17 @@ sub phase3_cleanup { > }; > > # always stop local VM with nocheck, since config is moved already > - eval { PVE::QemuServer::vm_stop($self->{storecfg}, $vmid, 1, 1); }; > + my $shutdown_timeout = undef; > + my $shutdown = undef; > + my $force_stop = undef; > + if ($self->{opts}->{'target-reboot'}) { > + $shutdown_timeout = 180; > + $shutdown = 1; > + $force_stop = 1; > + $self->log('info', "clean shutdown of source vm."); Sounds like it already happened and with force_stop=1 it might not be as clean in the worst case ;). Maybe just "shutting down source VM"? > + } > + > + eval { PVE::QemuServer::vm_stop($self->{storecfg}, $vmid, 1, 1, $shutdown_timeout, $shutdown, $force_stop); }; > if (my $err = $@) { > $self->log('err', "stopping vm failed - $err"); > $self->{errors} = 1; > @@ -1607,6 +1630,10 @@ sub phase3_cleanup { > # clear migrate lock > if ($tunnel && $tunnel->{version} >= 2) { > PVE::Tunnel::write_tunnel($tunnel, 10, "unlock"); > + if ($self->{opts}->{'target-reboot'}) { > + $self->log('info', "restart target vm."); > + PVE::Tunnel::write_tunnel($tunnel, 10, 'restart'); > + } > > PVE::Tunnel::finish_tunnel($tunnel); > } else { ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [pve-devel] [PATCH v4 qemu-server 2/2] remote-migration: add target-cpu && target-reboot params 2023-10-09 12:13 ` Fiona Ebner @ 2023-10-09 13:47 ` DERUMIER, Alexandre 2023-10-10 9:19 ` Fiona Ebner 0 siblings, 1 reply; 15+ messages in thread From: DERUMIER, Alexandre @ 2023-10-09 13:47 UTC (permalink / raw) To: pve-devel, aderumier, f.ebner Hi Fiona, Thanks for the review. >>There can be other reasons to do a restart-migration, see also >>is so I feel like this >>should be split. One for introducing target-reboot and one for >>introducing target-cpu. yes, sure it can be split in 2 patch, no problem. (v1 had only targetcpu param, but I have splitted it in 2 differents param, I just forgot to split in 2 patches >>For 'target-reboot', the question is if we should call it 'restart' >>like for container migration for consistency? Could also be >>introduced for normal migration while we're at it. Well, we have pct reboot <vmid> and pct migrate <vmid> --restart ^_^ We can use "restart", no problem, It make sense if we already using it in pct migrate. >>One could argue that a true 'restart' migration would migrate the >>volumes also offline, but right now, I don't see a big downside to do >>it >>via NBD like in this patch. Still, something we should think about. >>If >>it turns out to be really needed, we'd need two different ways to do >>a >>restart migration :/ I think that a true offline migration (without starting any source/target vm) can be done with qemu-storage-daemon running nbd server on target && qemu-img on source. This could be also used for online migration with unused/detached disks. I'll send a v5 next week, as I'm going to begin a 4 days proxmox training tomorrow. ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [pve-devel] [PATCH v4 qemu-server 2/2] remote-migration: add target-cpu && target-reboot params 2023-10-09 13:47 ` DERUMIER, Alexandre @ 2023-10-10 9:19 ` Fiona Ebner 2023-10-10 16:29 ` DERUMIER, Alexandre 2023-10-23 18:03 ` DERUMIER, Alexandre 0 siblings, 2 replies; 15+ messages in thread From: Fiona Ebner @ 2023-10-10 9:19 UTC (permalink / raw) To: DERUMIER, Alexandre, pve-devel, aderumier Am 09.10.23 um 15:47 schrieb DERUMIER, Alexandre: >>> One could argue that a true 'restart' migration would migrate the >>> volumes also offline, but right now, I don't see a big downside to do >>> it >>> via NBD like in this patch. Still, something we should think about. >>> If >>> it turns out to be really needed, we'd need two different ways to do >>> a >>> restart migration :/ > > I think that a true offline migration (without starting any > source/target vm) can be done with qemu-storage-daemon running nbd > server on target && qemu-img on source. > > This could be also used for online migration with unused/detached > disks. > Yes, we could, but would require additional logic. So the question is if there are enough advantages to do it rather than via a full VM. Starting a VM of course requires more resources. In case of 'restart' migration, we do want to start the VM anyways, so it's actually better, because we can catch config issues early :) Now that I think about it, can we also just start the target VM in prelaunch mode (instead of incoming migration mode), do the NBD migration, shut down the source VM, stop the NBD server and then resume the target? That would avoid the need to stop and start the target again. And therefore might be quite a bit less downtime. In case of offline migration, it can make sense to go via the storage daemon instead to avoid using more resources than necessary. But can always be added later. ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [pve-devel] [PATCH v4 qemu-server 2/2] remote-migration: add target-cpu && target-reboot params 2023-10-10 9:19 ` Fiona Ebner @ 2023-10-10 16:29 ` DERUMIER, Alexandre 2023-10-11 7:51 ` Fiona Ebner 2023-10-23 18:03 ` DERUMIER, Alexandre 1 sibling, 1 reply; 15+ messages in thread From: DERUMIER, Alexandre @ 2023-10-10 16:29 UTC (permalink / raw) To: pve-devel, aderumier, f.ebner > > I think that a true offline migration (without starting any > source/target vm) can be done with qemu-storage-daemon running nbd > server on target && qemu-img on source. > > This could be also used for online migration with unused/detached > disks. > >>Yes, we could, but would require additional logic. So the question is >>if >>there are enough advantages to do it rather than via a full VM. >>Starting >>a VM of course requires more resources. I don't known if it's possible to use the ndb server in the targetvm, if the target disk is not attached ? (I really don't known) >>In case of 'restart' migration, we do want to start the VM anyways, >>so >>it's actually better, because we can catch config issues early :) Now >>that I think about it, can we also just start the target VM in >>prelaunch >>mode (instead of incoming migration mode), do the NBD migration, shut >>down the source VM, stop the NBD server and then resume the target? >>That >>would avoid the need to stop and start the target again. And >>therefore >>might be quite a bit less downtime. Yes, indeed ! I'll work on this for next version. ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [pve-devel] [PATCH v4 qemu-server 2/2] remote-migration: add target-cpu && target-reboot params 2023-10-10 16:29 ` DERUMIER, Alexandre @ 2023-10-11 7:51 ` Fiona Ebner 0 siblings, 0 replies; 15+ messages in thread From: Fiona Ebner @ 2023-10-11 7:51 UTC (permalink / raw) To: DERUMIER, Alexandre, pve-devel, aderumier Am 10.10.23 um 18:29 schrieb DERUMIER, Alexandre: >> >> I think that a true offline migration (without starting any >> source/target vm) can be done with qemu-storage-daemon running nbd >> server on target && qemu-img on source. >> >> This could be also used for online migration with unused/detached >> disks. >> > >>> Yes, we could, but would require additional logic. So the question is >>> if >>> there are enough advantages to do it rather than via a full VM. >>> Starting >>> a VM of course requires more resources. > > I don't known if it's possible to use the ndb server in the targetvm, > if the target disk is not attached ? (I really don't known) Yes, I think need to attach it as a blockdev first. But for 'restart' migration, it should be fine to start out with NBD and migrate non-attached disks with our current method. If we (later) want to add logic for migrating non-attached disks via storage-daemon we can always do that too and switch storage_migrate() to use that (maybe not unconditionally, ZFS -> ZFS still makes more sense to do with send/recv for example). ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [pve-devel] [PATCH v4 qemu-server 2/2] remote-migration: add target-cpu && target-reboot params 2023-10-10 9:19 ` Fiona Ebner 2023-10-10 16:29 ` DERUMIER, Alexandre @ 2023-10-23 18:03 ` DERUMIER, Alexandre 2023-10-24 8:11 ` Fiona Ebner 1 sibling, 1 reply; 15+ messages in thread From: DERUMIER, Alexandre @ 2023-10-23 18:03 UTC (permalink / raw) To: pve-devel, aderumier, f.ebner Hi Fiona, >>In case of 'restart' migration, we do want to start the VM anyways, >>so >>it's actually better, because we can catch config issues early :) Now >>that I think about it, can we also just start the target VM in >>prelaunch >>mode (instead of incoming migration mode), do the NBD migration, shut >>down the source VM, stop the NBD server and then resume the target? >>That >>would avoid the need to stop and start the target again. And >>therefore >>might be quite a bit less downtime. I have done some tests, It's not possible currently to write to the remote nbd without the --incoming migration flag and only -S https://lists.gnu.org/archive/html/qemu-devel/2017-11/msg05700.html nbd_add is throwing an error like 2023-10-23 18:45:51 [formationkvm1] VM 111 qmp command 'block-export- add' failed - Permission conflict on node '#block524': permissions 'write' are both required by an unnamed block device (uses node '#block524' as 'root' child) and unshared by block device 'drive-scsi0' (uses node '#block524' as 'root' child). Looking at the qemu code, the are some specific codepath in block when the incoming flag is setup. So I think the best way for now is to restart the target vm. ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [pve-devel] [PATCH v4 qemu-server 2/2] remote-migration: add target-cpu && target-reboot params 2023-10-23 18:03 ` DERUMIER, Alexandre @ 2023-10-24 8:11 ` Fiona Ebner 2023-10-24 12:20 ` DERUMIER, Alexandre 0 siblings, 1 reply; 15+ messages in thread From: Fiona Ebner @ 2023-10-24 8:11 UTC (permalink / raw) To: DERUMIER, Alexandre, pve-devel, aderumier Am 23.10.23 um 20:03 schrieb DERUMIER, Alexandre: > Hi Fiona, > > >>> In case of 'restart' migration, we do want to start the VM anyways, >>> so >>> it's actually better, because we can catch config issues early :) Now >>> that I think about it, can we also just start the target VM in >>> prelaunch >>> mode (instead of incoming migration mode), do the NBD migration, shut >>> down the source VM, stop the NBD server and then resume the target? >>> That >>> would avoid the need to stop and start the target again. And >>> therefore >>> might be quite a bit less downtime. > > > I have done some tests, It's not possible currently to write to the > remote nbd without the --incoming migration flag and only -S > > > > https://lists.gnu.org/archive/html/qemu-devel/2017-11/msg05700.html > > > > nbd_add is throwing an error like > > 2023-10-23 18:45:51 [formationkvm1] VM 111 qmp command 'block-export- > add' failed - Permission conflict on node '#block524': permissions > 'write' are both required by an unnamed block device (uses node > '#block524' as 'root' child) and unshared by block device 'drive-scsi0' > (uses node '#block524' as 'root' child). > > > Looking at the qemu code, the are some specific codepath in block when > the incoming flag is setup. > That is unfortunate. But thanks for giving it a shot! I guess if we'd really wanted to go this route, we'd need to add some kind of "empty" migration type without any state, but would be hard to get right and feels like a hack. > > So I think the best way for now is to restart the target vm. > Sure! Going with that is a much cleaner approach then. ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [pve-devel] [PATCH v4 qemu-server 2/2] remote-migration: add target-cpu && target-reboot params 2023-10-24 8:11 ` Fiona Ebner @ 2023-10-24 12:20 ` DERUMIER, Alexandre 2023-10-25 8:30 ` Fiona Ebner 0 siblings, 1 reply; 15+ messages in thread From: DERUMIER, Alexandre @ 2023-10-24 12:20 UTC (permalink / raw) To: pve-devel, aderumier, f.ebner >>So I think the best way for now is to restart the target vm. >> >>Sure! Going with that is a much cleaner approach then. I'll try to send a v5 today with you're last comments. I don't manage yet the unused disks, I need to test with blockdev, but if it's work, I think we'll need to add config generation in pve- storage for differents blockdriver like: –blockdev driver=file,node-name=file0,filename=vm.img –blockdev driver=rbd,node-name=rbd0,pool=my-pool,image=vm01 So maybe it'll take a little bit more time. (Maybe a second patch serie later to implement it) -------- Message initial -------- De: Fiona Ebner <f.ebner@proxmox.com> À: "DERUMIER, Alexandre" <alexandre.derumier@groupe-cyllene.com>, pve- devel@lists.proxmox.com <pve-devel@lists.proxmox.com>, aderumier@odiso.com <aderumier@odiso.com> Objet: Re: [pve-devel] [PATCH v4 qemu-server 2/2] remote-migration: add target-cpu && target-reboot params Date: 24/10/2023 10:11:09 Am 23.10.23 um 20:03 schrieb DERUMIER, Alexandre: > Hi Fiona, > > > > > In case of 'restart' migration, we do want to start the VM > > > anyways, > > > so > > > it's actually better, because we can catch config issues early :) > > > Now > > > that I think about it, can we also just start the target VM in > > > prelaunch > > > mode (instead of incoming migration mode), do the NBD migration, > > > shut > > > down the source VM, stop the NBD server and then resume the > > > target? > > > That > > > would avoid the need to stop and start the target again. And > > > therefore > > > might be quite a bit less downtime. > > > I have done some tests, It's not possible currently to write to the > remote nbd without the --incoming migration flag and only -S > > > > https://antiphishing.cetsi.fr/proxy/v3?i=SGI0YVJGNmxZNE90Z2thMFYLWSxJ > OfIERJocpmb73Vs&r=SW5LV3JodE9QZkRVZ3JEYaKpfBJeBDlAX9E2aicRCRO3qsFIBX9 > zb4pDqGdxG45MOoGKkZ3R8w3DjSjAvqYgRg&f=bnJjU3hQT3pQSmNQZVE3aOdk6YB- > 6s0kvu35a0_AsxkSltfWi01kMLld3RaPwuBX&u=https%3A//lists.gnu.org/archiv > e/html/qemu-devel/2017-11/msg05700.html&k=dFBm > > > > nbd_add is throwing an error like > > 2023-10-23 18:45:51 [formationkvm1] VM 111 qmp command 'block-export- > add' failed - Permission conflict on node '#block524': permissions > 'write' are both required by an unnamed block device (uses node > '#block524' as 'root' child) and unshared by block device 'drive- > scsi0' > (uses node '#block524' as 'root' child). > > > Looking at the qemu code, the are some specific codepath in block > when > the incoming flag is setup. > That is unfortunate. But thanks for giving it a shot! I guess if we'd really wanted to go this route, we'd need to add some kind of "empty" migration type without any state, but would be hard to get right and feels like a hack. > > So I think the best way for now is to restart the target vm. > Sure! Going with that is a much cleaner approach then. ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [pve-devel] [PATCH v4 qemu-server 2/2] remote-migration: add target-cpu && target-reboot params 2023-10-24 12:20 ` DERUMIER, Alexandre @ 2023-10-25 8:30 ` Fiona Ebner 2023-10-25 16:01 ` DERUMIER, Alexandre 0 siblings, 1 reply; 15+ messages in thread From: Fiona Ebner @ 2023-10-25 8:30 UTC (permalink / raw) To: DERUMIER, Alexandre, pve-devel, aderumier Am 24.10.23 um 14:20 schrieb DERUMIER, Alexandre: >>> So I think the best way for now is to restart the target vm. >>> >>> Sure! Going with that is a much cleaner approach then. > > I'll try to send a v5 today with you're last comments. > > I don't manage yet the unused disks, I need to test with blockdev, > Is it required for this series? Unused disks can just be migrated offline via storage_migrate(), or? If we want to switch to migrating disks offline via QEMU instead of our current storage_migrate(), going for QEMU storage daemon + NBD seems the most natural to me. If it's not too complicated to temporarily attach the disks to the VM, that can be done too, but is less re-usable (e.g. pure offline migration won't benefit from that). > but if it's work, I think we'll need to add config generation in pve- > storage for differents blockdriver > > > like: > > –blockdev driver=file,node-name=file0,filename=vm.img > > –blockdev driver=rbd,node-name=rbd0,pool=my-pool,image=vm01 > What other special cases besides (non-krbd) RBD are there? If it's just that, I'd much rather keep the special handling in QEMU itself then burden all other storage plugins with implementing something specific to VMs. Or is there a way to use the path from the storage plugin somehow like we do at the moment, i.e. "rbd:rbd/vm-111-disk-1:conf=/etc/pve/ceph.conf:id=admin:keyring=/etc/pve/priv/ceph/rbd.keyring"? > So maybe it'll take a little bit more time. > > (Maybe a second patch serie later to implement it) > Yes, I think that makes sense as a dedicated series. ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [pve-devel] [PATCH v4 qemu-server 2/2] remote-migration: add target-cpu && target-reboot params 2023-10-25 8:30 ` Fiona Ebner @ 2023-10-25 16:01 ` DERUMIER, Alexandre 2023-10-27 9:19 ` Fiona Ebner 0 siblings, 1 reply; 15+ messages in thread From: DERUMIER, Alexandre @ 2023-10-25 16:01 UTC (permalink / raw) To: pve-devel, aderumier, f.ebner > >>Is it required for this series? for this series, no. It's only focus on migrating to remote with different cpu without too much downtime. >> Unused disks can just be migrated >>offline via storage_migrate(), or? currently unused disk can't be migrate through the http tunnel for remote-migration 2023-10-25 17:51:38 ERROR: error - tunnel command '{"format":"raw","migration_snapshot":"1","export_formats":"zfs","allow _rename":"1","snapshot":"__migration__","volname":"vm-1112-disk- 1","cmd":"disk-import","storage":"targetstorage","with_snapshots":1}' failed - failed to handle 'disk-import' command - no matching import/export format found for storage 'preprodkvm' 2023-10-25 17:51:38 aborting phase 1 - cleanup resources tunnel: -> sending command "quit" to remote tunnel: <- got reply tunnel: CMD channel closed, shutting down 2023-10-25 17:51:39 ERROR: migration aborted (duration 00:00:01): error - tunnel command '{"format":"raw","migration_snapshot":"1","export_formats":"zfs","allow _rename":"1","snapshot":"__migration__","volname":"vm-1112-disk- 1","cmd":"disk-import","storage":"targetstorage","with_snapshots":1}' failed - failed to handle 'disk-import' command - no matching import/export format found for storage 'preprodkvm' migration aborted >>If we want to switch to migrating >>disks offline via QEMU instead of our current storage_migrate(), >>going >>for QEMU storage daemon + NBD seems the most natural to me. Yes, I more for this solution. >>If it's not too complicated to temporarily attach the disks to the >>VM, >>that can be done too, but is less re-usable (e.g. pure offline >>migration >>won't benefit from that). No sure about attach/detach temporary once by once, or attach all devices (but this need enough controllers slot). qemu storage daemon seem to be a less hacky solution ^_^ > but if it's work, I think we'll need to add config generation in pv > storage for differents blockdriver > > > like: > > –blockdev driver=file,node-name=file0,filename=vm.img > > –blockdev driver=rbd,node-name=rbd0,pool=my-pool,image=vm01 > >>What other special cases besides (non-krbd) RBD are there? If it's >>just >>that, I'd much rather keep the special handling in QEMU itself then >>burden all other storage plugins with implementing something specific >>to >>VMs. not sure, maybe glusterfs, .raw (should works for block device like lvm,zfs), .qcow2 >>Or is there a way to use the path from the storage plugin somehow >>like >>we do at the moment, i.e. >>"rbd:rbd/vm-111-disk- >>1:conf=/etc/pve/ceph.conf:id=admin:keyring=/etc/pve/priv/ceph/rbd.key >>ring"? I don't think it's possible just like this.I need to do more test, looking at libvirt before they are not too much doc about it. > So maybe it'll take a little bit more time. > > (Maybe a second patch serie later to implement it) > >>Yes, I think that makes sense as a dedicated series. ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [pve-devel] [PATCH v4 qemu-server 2/2] remote-migration: add target-cpu && target-reboot params 2023-10-25 16:01 ` DERUMIER, Alexandre @ 2023-10-27 9:19 ` Fiona Ebner 0 siblings, 0 replies; 15+ messages in thread From: Fiona Ebner @ 2023-10-27 9:19 UTC (permalink / raw) To: DERUMIER, Alexandre, pve-devel, aderumier Am 25.10.23 um 18:01 schrieb DERUMIER, Alexandre: >>> Unused disks can just be migrated >>> offline via storage_migrate(), or? > > currently unused disk can't be migrate through the http tunnel for > remote-migration > > 2023-10-25 17:51:38 ERROR: error - tunnel command > '{"format":"raw","migration_snapshot":"1","export_formats":"zfs","allow > _rename":"1","snapshot":"__migration__","volname":"vm-1112-disk- > 1","cmd":"disk-import","storage":"targetstorage","with_snapshots":1}' > failed - failed to handle 'disk-import' command - no matching > import/export format found for storage 'preprodkvm' > 2023-10-25 17:51:38 aborting phase 1 - cleanup resources > tunnel: -> sending command "quit" to remote > tunnel: <- got reply > tunnel: CMD channel closed, shutting down > 2023-10-25 17:51:39 ERROR: migration aborted (duration 00:00:01): error > - tunnel command > '{"format":"raw","migration_snapshot":"1","export_formats":"zfs","allow > _rename":"1","snapshot":"__migration__","volname":"vm-1112-disk- > 1","cmd":"disk-import","storage":"targetstorage","with_snapshots":1}' > failed - failed to handle 'disk-import' command - no matching > import/export format found for storage 'preprodkvm' > migration aborted > Well, yes, they can. But there needs to be a common import/export format between the storage types. Which admittedly is a bit limited for certain storage types, e.g. ZFS only supports ZFS and RBD does not implement import/export at all yet (because in a single cluster it wasn't needed). >>> If we want to switch to migrating >>> disks offline via QEMU instead of our current storage_migrate(), >>> going >>> for QEMU storage daemon + NBD seems the most natural to me. > > Yes, I more for this solution. > >>> If it's not too complicated to temporarily attach the disks to the >>> VM, >>> that can be done too, but is less re-usable (e.g. pure offline >>> migration >>> won't benefit from that). > > No sure about attach/detach temporary once by once, or attach all > devices (but this need enough controllers slot). > I think you can attach them to the VM without attaching to a controller by using QMP blockdev-add, but... > qemu storage daemon seem to be a less hacky solution ^_^ > ...sure, this should be nicer and more re-usable. > >> but if it's work, I think we'll need to add config generation in pv >> storage for differents blockdriver >> >> >> like: >> >> –blockdev driver=file,node-name=file0,filename=vm.img >> >> –blockdev driver=rbd,node-name=rbd0,pool=my-pool,image=vm01 >> > >>> What other special cases besides (non-krbd) RBD are there? If it's >>> just >>> that, I'd much rather keep the special handling in QEMU itself then >>> burden all other storage plugins with implementing something specific >>> to >>> VMs. > > not sure, maybe glusterfs, .raw (should works for block device like > lvm,zfs), .qcow2 > There's a whole lot of drivers https://qemu.readthedocs.io/en/v8.1.0/interop/qemu-qmp-ref.html#qapidoc-883 But e.g. for NFS, we don't necessarily need it and can just use qcow2/raw. Currently, with -drive we also just treat it like any other file. I'd like to keep the logic for how to construct the -blockdev command line option (mostly) in qemu-server itself. But I guess we can't avoid some amount of coupling. Currently, for -drive we have the coupling in path() which can e.g. return rbd: or gluster: and then QEMU will parse what driver to use from that path. Two approaches that make sense to me (no real preference at the moment): 1. Have a storage plugin method which tells qemu-server about the necessary driver and properties for opening the image. E.g. return the properties as a hash and then have qemu-server join them together and then add the generic properties (e.g. aio,node-name) to construct the full -blockdev option. 2. Do everything in qemu-server and special case for certain storage types that have a dedicated driver. Still needs to get the info like pool name from the RBD storage of course, but that should be possible with existing methods. Happy to hear other suggestions/opinions. > >>> Or is there a way to use the path from the storage plugin somehow >>> like >>> we do at the moment, i.e. >>> "rbd:rbd/vm-111-disk- >>> 1:conf=/etc/pve/ceph.conf:id=admin:keyring=/etc/pve/priv/ceph/rbd.key >>> ring"? > > I don't think it's possible just like this.I need to do more test, > looking at libvirt before they are not too much doc about it. > Probably they decided to get rid of this magic for the newer -blockdev variant. I tried to cheat using driver=file and specify the "rbd:"-path as the filename, but it doesn't work :P ^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2023-10-27 9:19 UTC | newest] Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2023-09-28 14:45 [pve-devel] [PATCH v4 qemu-server 0/2] remote-migration: migration with different cpu Alexandre Derumier 2023-09-28 14:45 ` [pve-devel] [PATCH v4 qemu-server 1/2] migration: move livemigration code in a dedicated sub Alexandre Derumier 2023-10-09 11:25 ` Fiona Ebner 2023-09-28 14:45 ` [pve-devel] [PATCH v4 qemu-server 2/2] remote-migration: add target-cpu && target-reboot params Alexandre Derumier 2023-10-09 12:13 ` Fiona Ebner 2023-10-09 13:47 ` DERUMIER, Alexandre 2023-10-10 9:19 ` Fiona Ebner 2023-10-10 16:29 ` DERUMIER, Alexandre 2023-10-11 7:51 ` Fiona Ebner 2023-10-23 18:03 ` DERUMIER, Alexandre 2023-10-24 8:11 ` Fiona Ebner 2023-10-24 12:20 ` DERUMIER, Alexandre 2023-10-25 8:30 ` Fiona Ebner 2023-10-25 16:01 ` DERUMIER, Alexandre 2023-10-27 9:19 ` Fiona Ebner
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox