Resolves the issue of restoring a VM that has a cloudinit drive
configured to a new VMID. The VMID of the disk name gets now remapped
correctly and in the process the cloudinit disk is created with the same size
as in PVE/API2/Qemu.pm create_disks and in PVE/QemuServer/Cloudinit
commit_cloudinit_disk as the same constant is used.

This is done by matching any line starting with either 'ide', 'sata' or
'scsi' and then check if it is a cloudinit drive. As cloudinit drives
are attached as cdrom, only those 3 are possible. For the cloudinit
check we use 'parse_drive' followed by 'drive_is_cloudinit' so no custom
regex is necessary.

'--targetstorage' is also taken into account on restore now for
cloudinit disks. If a target storage is specified the format is either
kept if possible, or changed to the default of that storage.

This should fix #1807 completely. The restore error was already resolved
with commit 7e8ab2a, but the vmid of the disk might not have matched the new
one.

Signed-off-by: Mira Limbeck <m.limb...@proxmox.com>
---
v3:
 - ',' instead of ';' in hash $d
v2:
 - hash $d creation cleanup
 - removed unnecessary '// undef'

 PVE/QemuServer.pm | 30 +++++++++++++++++++++++++++---
 1 file changed, 27 insertions(+), 3 deletions(-)

diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
index 9d560ec..244d74a 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -6264,6 +6264,23 @@ sub restore_vma_archive {
                $storage_limits{$storeid} = $bwlimit;
 
                $virtdev_hash->{$virtdev} = $devinfo->{$devname};
+           } elsif ($line =~ m/^((?:ide|sata|scsi)\d+):\s*(.*)\s*$/) {
+               my $virtdev = $1;
+               my $drive = parse_drive($virtdev, $2);
+               if (drive_is_cloudinit($drive)) {
+                   my ($storeid, $volname) = 
PVE::Storage::parse_volume_id($drive->{file});
+                   my $scfg = PVE::Storage::storage_config($cfg, $storeid);
+                   my $format = qemu_img_format($scfg, $volname); # has 'raw' 
fallback
+
+                   my $d = {
+                       format => $format,
+                       storeid => $opts->{storage} // $storeid,
+                       size => PVE::QemuServer::Cloudinit::CLOUDINIT_DISK_SIZE,
+                       file => $drive->{file}, # to make drive_is_cloudinit 
check possible
+                       name => "vm-$vmid-cloudinit",
+                   };
+                   $virtdev_hash->{$virtdev} = $d;
+               }
            }
        }
 
@@ -6334,8 +6351,12 @@ sub restore_vma_archive {
            my $supported = grep { $_ eq $d->{format} } @$validFormats;
            $d->{format} = $defFormat if !$supported;
 
+           my $name = $d->{name};
+           if ($name && $d->{format} ne 'raw') {
+               $name .= ".$d->{format}";
+           }
            my $volid = PVE::Storage::vdisk_alloc($cfg, $storeid, $vmid,
-                                                 $d->{format}, undef, 
$alloc_size);
+                                                 $d->{format}, $name, 
$alloc_size);
            print STDERR "new volume ID is '$volid'\n";
            $d->{volid} = $volid;
            my $path = PVE::Storage::path($cfg, $volid);
@@ -6347,9 +6368,12 @@ sub restore_vma_archive {
                $write_zeros = 0;
            }
 
-           print $fifofh 
"${map_opts}format=$d->{format}:${write_zeros}:$d->{devname}=$path\n";
+           my $is_cloudinit = defined($d->{file}) && drive_is_cloudinit($d);
+           if (!$is_cloudinit) {
+               print $fifofh 
"${map_opts}format=$d->{format}:${write_zeros}:$d->{devname}=$path\n";
 
-           print "map '$d->{devname}' to '$path' (write zeros = 
${write_zeros})\n";
+               print "map '$d->{devname}' to '$path' (write zeros = 
${write_zeros})\n";
+           }
            $map->{$virtdev} = $volid;
        }
 
-- 
2.11.0


_______________________________________________
pve-devel mailing list
pve-devel@pve.proxmox.com
https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to