]> git.proxmox.com Git - qemu-server.git/commitdiff
fix #3861: migrate: fix live migration when cloud-init changes storage
authorFabian Ebner <f.ebner@proxmox.com>
Thu, 28 Apr 2022 11:37:37 +0000 (13:37 +0200)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Thu, 28 Apr 2022 16:29:12 +0000 (18:29 +0200)
Generalizes fd95d780 ("migrate: send updated TPM state volid to target
node") to also handle other offline migrated disks appearing in the
VM config, which currently should only be cloud-init.

Breaks migration new -> old under similar (edge-case-)conditions as
fd95d780 did.

Keep sending the 'tpmstate0' STDIN parameter to avoid breaking new ->
old in the scenario fd95d780 fixed.

Keep parsing the vm_start 'tpmstate0' STDIN parameter to avoid
breaking old -> new, and to be able to keep sending it.

Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
PVE/API2/Qemu.pm
PVE/QemuMigrate.pm
PVE/QemuServer.pm

index 6a936f85d910b741a98dd763aafa40a4d8fae8b4..06780918de5a764bcc1508aec1c7a9e614471522 100644 (file)
@@ -2542,7 +2542,7 @@ __PACKAGE__->register_method({
        my $spice_ticket;
        my $nbd_protocol_version = 0;
        my $replicated_volumes = {};
-       my $tpmstate_vol;
+       my $offline_volumes = {};
        if ($stateuri && ($stateuri eq 'tcp' || $stateuri eq 'unix') && $migratedfrom && ($rpcenv->{type} eq 'cli')) {
            while (defined(my $line = <STDIN>)) {
                chomp $line;
@@ -2552,8 +2552,10 @@ __PACKAGE__->register_method({
                    $nbd_protocol_version = $1;
                } elsif ($line =~ m/^replicated_volume: (.*)$/) {
                    $replicated_volumes->{$1} = 1;
-               } elsif ($line =~ m/^tpmstate0: (.*)$/) {
-                   $tpmstate_vol = $1;
+               } elsif ($line =~ m/^tpmstate0: (.*)$/) { # Deprecated, use offline_volume instead
+                   $offline_volumes->{tpmstate0} = $1;
+               } elsif ($line =~ m/^offline_volume: ([^:]+): (.*)$/) {
+                   $offline_volumes->{$1} = $2;
                } elsif (!$spice_ticket) {
                    # fallback for old source node
                    $spice_ticket = $line;
@@ -2595,7 +2597,7 @@ __PACKAGE__->register_method({
                    storagemap => $storagemap,
                    nbd_proto_version => $nbd_protocol_version,
                    replicated_volumes => $replicated_volumes,
-                   tpmstate_vol => $tpmstate_vol,
+                   offline_volumes => $offline_volumes,
                };
 
                my $params = {
index dfe923251219720aa76ff95295db12bb7f86fb21..d52dc8dba3a0b142c0d469504b8b51349cfd0430 100644 (file)
@@ -710,11 +710,20 @@ sub phase2 {
     my $nbd_protocol_version = 1;
     my $input = "nbd_protocol_version: $nbd_protocol_version\n";
 
-    if ($conf->{tpmstate0}) {
-       my $tpmdrive = PVE::QemuServer::parse_drive('tpmstate0', $conf->{tpmstate0});
-       my $tpmvol = $tpmdrive->{file};
-       $input .= "tpmstate0: $self->{volume_map}->{$tpmvol}"
-           if $self->{volume_map}->{$tpmvol} && $tpmvol ne $self->{volume_map}->{$tpmvol};
+    my @offline_local_volumes = $self->filter_local_volumes('offline');
+    for my $volid (@offline_local_volumes) {
+       my $drivename = $local_volumes->{$volid}->{drivename};
+       next if !$drivename || !$conf->{$drivename};
+
+       my $new_volid = $self->{volume_map}->{$volid};
+       next if !$new_volid || $volid eq $new_volid;
+
+       # FIXME PVE 8.x only use offline_volume variant once all targets can handle it
+       if ($drivename eq 'tpmstate0') {
+           $input .= "$drivename: $new_volid\n"
+       } else {
+           $input .= "offline_volume: $drivename: $new_volid\n"
+       }
     }
 
     $input .= "spice_ticket: $spice_ticket\n" if $spice_ticket;
index 5183ab234cdd434a30f4852b3d007dbe3a35a23d..8e7cfb86315913c3741424c12f73875b520a759f 100644 (file)
@@ -5432,7 +5432,8 @@ sub vm_start {
 #   type => secure/insecure - tunnel over encrypted connection or plain-text
 #   nbd_proto_version => int, 0 for TCP, 1 for UNIX
 #   replicated_volumes => which volids should be re-used with bitmaps for nbd migration
-#   tpmstate_vol => new volid of tpmstate0, not yet contained in config
+#   offline_volumes => new volids of offline migrated disks like tpmstate and cloudinit, not yet
+#       contained in config
 sub vm_start_nolock {
     my ($storecfg, $vmid, $conf, $params, $migrate_opts) = @_;
 
@@ -5457,11 +5458,13 @@ sub vm_start_nolock {
     # this way we can reuse the old ISO with the correct config
     PVE::QemuServer::Cloudinit::generate_cloudinitconfig($conf, $vmid) if !$migratedfrom;
 
-    # override TPM state vol if migrated, conf is out of date still
-    if (my $tpmvol = $migrate_opts->{tpmstate_vol}) {
-        my $parsed = parse_drive("tpmstate0", $conf->{tpmstate0});
-        $parsed->{file} = $tpmvol;
-        $conf->{tpmstate0} = print_drive($parsed);
+    # override offline migrated volumes, conf is out of date still
+    if (my $offline_volumes = $migrate_opts->{offline_volumes}) {
+       for my $key (sort keys $offline_volumes->%*) {
+           my $parsed = parse_drive($key, $conf->{$key});
+           $parsed->{file} = $offline_volumes->{$key};
+           $conf->{$key} = print_drive($parsed);
+       }
     }
 
     my $defaults = load_defaults();