[pve-devel] [PATCH v2 qemu-server] fix #2100: skip local cloudinit image on offline migrate

Mira Limbeck m.limbeck at proxmox.com
Thu Mar 7 15:10:30 CET 2019


ignore local cloudinit disks on offline migrate but delete it
afterwards. introduces the 'generated' ref type. delete the old
cloudinit disk on vm start and create a new one with a sized based on
the generated iso. this allows the disk to exceed the original 5MB limit
which might be required for custom cloudinit yaml files supplied via
snippets.

Signed-off-by: Mira Limbeck <m.limbeck at proxmox.com>
---
 PVE/QemuMigrate.pm          | 18 ++++++++++++++++--
 PVE/QemuServer/Cloudinit.pm | 37 ++++++++++++++++++++++++++++---------
 2 files changed, 44 insertions(+), 11 deletions(-)

diff --git a/PVE/QemuMigrate.pm b/PVE/QemuMigrate.pm
index ee605d8..6bb19db 100644
--- a/PVE/QemuMigrate.pm
+++ b/PVE/QemuMigrate.pm
@@ -246,6 +246,7 @@ sub prepare {
 		if !$plugin->check_connection($sid, $scfg);
 	} else {
 	    # only activate if not shared
+	    next if ($volid =~ m/vm-\d+-cloudinit/);
 	    push @$need_activate, $volid;
 	}
     }
@@ -353,7 +354,13 @@ sub sync_disks {
 
 	    $local_volumes->{$volid}->{ref} = $attr->{referenced_in_config} ? 'config' : 'snapshot';
 
-	    die "local cdrom image\n" if $attr->{cdrom};
+	    if ($attr->{cdrom}) {
+		if ($volid =~ /vm-\d+-cloudinit/) {
+		    $local_volumes->{$volid}->{ref} = 'generated';
+		    return;
+		}
+		die "local cdrom image\n";
+	    }
 
 	    my ($path, $owner) = PVE::Storage::path($self->{storecfg}, $volid);
 
@@ -394,6 +401,8 @@ sub sync_disks {
 		$self->log('info', "found local disk '$vol' (in current VM config)\n");
 	    } elsif ($ref eq 'snapshot') {
 		$self->log('info', "found local disk '$vol' (referenced by snapshot(s))\n");
+	    } elsif ($ref eq 'generated') {
+		$self->log('info', "found generated disk '$vol' (in current VM config)\n");
 	    } else {
 		$self->log('info', "found local disk '$vol'\n");
 	    }
@@ -445,8 +454,13 @@ sub sync_disks {
 	foreach my $volid (keys %$local_volumes) {
 	    my ($sid, $volname) = PVE::Storage::parse_volume_id($volid);
 	    my $targetsid = $override_targetsid // $sid;
-	    if ($self->{running} && $local_volumes->{$volid}->{ref} eq 'config') {
+	    my $ref = $local_volumes->{$volid}->{ref};
+	    if ($self->{running} && $ref eq 'config') {
 		push @{$self->{online_local_volumes}}, $volid;
+	    } elsif ($ref eq 'generated') {
+		# skip all generated volumes but queue them for deletion in phase3_cleanup
+		push @{$self->{volumes}}, $volid;
+		next;
 	    } else {
 		next if $rep_volumes->{$volid};
 		push @{$self->{volumes}}, $volid;
diff --git a/PVE/QemuServer/Cloudinit.pm b/PVE/QemuServer/Cloudinit.pm
index 0f8fc7a..eb85b1d 100644
--- a/PVE/QemuServer/Cloudinit.pm
+++ b/PVE/QemuServer/Cloudinit.pm
@@ -26,23 +26,42 @@ sub commit_cloudinit_disk {
 	my $contents = $files->{$filepath};
 	file_set_contents("$path/$filepath", $contents);
     }
+    my $iso_path = "/run/pve/cloudinit/$vmid.iso";
+
+    eval {
+	run_command(['genisoimage', '-R', '-V', $label, '-o', $iso_path, $path]);
+    };
+    my $err = $@;
+    rmtree($path);
+    die $err if $err;
+
+    my $size = PVE::Storage::file_size_info($iso_path);
 
     my $storecfg = PVE::Storage::config();
-    my $iso_path = PVE::Storage::path($storecfg, $drive->{file});
+    my $disk_path = PVE::Storage::path($storecfg, $drive->{file});
+
     my $scfg = PVE::Storage::storage_config($storecfg, $storeid);
-    my $plugin = PVE::Storage::Plugin->lookup($scfg->{type});
-    $plugin->activate_volume($storeid, $scfg, $volname);
     my $format = PVE::QemuServer::qemu_img_format($scfg, $volname);
+    $volname =~ m/(vm-$vmid-cloudinit(.(qcow2|raw))?)/;
+    my $name = $1;
 
-    my $size = PVE::Storage::file_size_info($iso_path);
+    if (-e $disk_path) {
+	print "cloudinit disk exists, deleting it\n";
+	PVE::Storage::vdisk_free($storecfg, $drive->{file});
+    }
+    print "creating cloudinit disk\n";
+    # $size/1024 should always be valid as ISO-9660 has a sector size of 2048 bytes;
+    PVE::Storage::vdisk_alloc($storecfg, $storeid, $vmid, $format, $name, $size/1024);
+
+    my $plugin = PVE::Storage::Plugin->lookup($scfg->{type});
+    $plugin->activate_volume($storeid, $scfg, $volname);
 
     eval {
-	run_command([['genisoimage', '-R', '-V', $label, $path],
-		     ['qemu-img', 'dd', '-n', '-f', 'raw', '-O', $format,
-		      'isize=0', "osize=$size", "of=$iso_path"]]);
+	run_command(['qemu-img', 'dd', '-n', '-f', 'raw', '-O', $format,
+		      'isize=0', "osize=$size", "if=$iso_path", "of=$disk_path"]);
     };
-    my $err = $@;
-    rmtree($path);
+    $err = $@;
+    unlink $iso_path;
     die $err if $err;
 }
 
-- 
2.11.0





More information about the pve-devel mailing list