From c4ab3c558454a21e60b706f10d5eb0a1f513016c Mon Sep 17 00:00:00 2001 From: Mira Limbeck Date: Thu, 16 May 2019 14:07:01 +0200 Subject: [PATCH] map cloudinit disk to new vmid on restore 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 --- PVE/QemuServer.pm | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm index 919c562c..ecfd1ac1 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.39.5