[pve-devel] [PATCH v2 qemu-server] fix #2100: skip local cloudinit image on offline migrate
Mira Limbeck
m.limbeck at proxmox.com
Fri Mar 8 08:57:36 CET 2019
Backup and restore are currently broken with cloudinit and this patch
(restore was already broken before:
https://bugzilla.proxmox.com/show_bug.cgi?id=1807)
* Backup fails if the VM is not started after migration but before the
next backup (cloudinit disk is in config but does not exist).
* Restore does not change the vmid of the cloudinit disk.
On 3/7/19 3:15 PM, Mira Limbeck wrote:
> forgot to add the changes v1 -> v2:
> * complete rework as v1 was not functional
> * cloudinit disk is no longer deleted from $local_volumes but instead
> treated differently ('generated' ref type)
>
> the check for cloudinit could not be moved into the 'if
> ($attr->{cdrom}){} scope (suggested by thomas) as it depends on code
> run later on
>
> On 3/7/19 3:10 PM, Mira Limbeck wrote:
>> 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;
>> }
>
> _______________________________________________
> pve-devel mailing list
> pve-devel at pve.proxmox.com
> https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
More information about the pve-devel
mailing list