[pve-devel] [PATCH v2 qemu-server] update disk size before local disk migration

Stefan Reiter s.reiter at proxmox.com
Mon Dec 9 14:08:09 CET 2019


Split out 'update_disksize' from the renamed 'update_disk_config' to
allow code reuse in QemuMigrate.

Remove dots after messages to keep style consistent for migration log.

After updating in sync_disks (phase1) of migration, write out updated
config. This means that even if migration fails or is aborted in later
stages, we keep the fixed config - this is not an issue, as it would
have been fixed on the next attempt anyway, and it can't hurt to have
the correct size instead of a wrong one either way.

Signed-off-by: Stefan Reiter <s.reiter at proxmox.com>
---

@Thomas: Is this what you had in mind with the local disk migrate bug?

Also, I'm not 100% sure about that last paragraph, if it really doesn't
matter...

v1 -> v2:
* remove $log_fn from update_disksize and return formatted sizes to caller
  instead
* include both volid (local-lvm:vm-100-disk-1) and drive bus (efidisk0) in
  message

 PVE/QemuMigrate.pm | 15 +++++++++++++++
 PVE/QemuServer.pm  | 37 +++++++++++++++++++++++++++++--------
 2 files changed, 44 insertions(+), 8 deletions(-)

diff --git a/PVE/QemuMigrate.pm b/PVE/QemuMigrate.pm
index 27c5b7a..f909873 100644
--- a/PVE/QemuMigrate.pm
+++ b/PVE/QemuMigrate.pm
@@ -447,6 +447,18 @@ sub sync_disks {
 	       'PVE::QemuConfig', $jobcfg, $start_time, $start_time, $logfunc);
 	}
 
+	# sizes in config have to be accurate for remote node to correctly
+	# allocate disks, rescan to be sure
+	my $volid_hash = PVE::QemuServer::scan_volids($self->{storecfg}, $vmid);
+	PVE::QemuServer::foreach_drive($conf, sub {
+	    my ($key, $drive) = @_;
+	    my ($updated, $old_size, $new_size) = PVE::QemuServer::update_disksize($drive, $volid_hash);
+	    if (defined($updated)) {
+		$conf->{$key} = PVE::QemuServer::print_drive($updated);
+		$self->log('info', "size of disk '$updated->{file}' ($key) updated from $old_size to $new_size\n");
+	    }
+	});
+
 	$self->log('info', "copying local disk images") if scalar(%$local_volumes);
 
 	foreach my $volid (keys %$local_volumes) {
@@ -510,6 +522,9 @@ sub phase1 {
 
     sync_disks($self, $vmid);
 
+    # sync_disks fixes disk sizes to match their actual size, write changes so
+    # target allocates correct volumes
+    PVE::QemuConfig->write_config($vmid, $conf);
 };
 
 sub phase1_cleanup {
diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
index c568d37..70ad5bf 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -6059,6 +6059,27 @@ sub is_volume_in_use {
 }
 
 sub update_disksize {
+    my ($drive, $volid_hash) = @_;
+
+    my $volid = $drive->{file};
+    return undef if !defined($volid);
+
+    my $oldsize = $drive->{size};
+    my $newsize = $volid_hash->{$volid}->{size};
+
+    if (defined($newsize) && defined($oldsize) && $newsize != $oldsize) {
+	$drive->{size} = $newsize;
+
+	my $old_fmt = PVE::JSONSchema::format_size($oldsize);
+	my $new_fmt = PVE::JSONSchema::format_size($newsize);
+
+	return wantarray ? ($drive, $old_fmt, $new_fmt) : $drive;
+    }
+
+    return undef;
+}
+
+sub update_disk_config {
     my ($vmid, $conf, $volid_hash) = @_;
 
     my $changes;
@@ -6080,6 +6101,7 @@ sub update_disksize {
 	    my $volid = $drive->{file};
 	    next if !$volid;
 
+	    # mark volid as "in-use" for next step
 	    $referenced->{$volid} = 1;
 	    if ($volid_hash->{$volid} &&
 		(my $path = $volid_hash->{$volid}->{path})) {
@@ -6089,12 +6111,11 @@ sub update_disksize {
 	    next if drive_is_cdrom($drive);
 	    next if !$volid_hash->{$volid};
 
-	    $drive->{size} = $volid_hash->{$volid}->{size};
-	    my $new = print_drive($drive);
-	    if ($new ne $conf->{$opt}) {
+	    my ($updated, $old_size, $new_size) = update_disksize($drive, $volid_hash);
+	    if (defined($updated)) {
 		$changes = 1;
-		$conf->{$opt} = $new;
-		print "$prefix update disk '$opt' information.\n";
+		$conf->{$opt} = print_drive($updated);
+		print "$prefix size of disk '$volid' ($opt) updated from $old_size to $new_size\n";
 	    }
 	}
     }
@@ -6105,7 +6126,7 @@ sub update_disksize {
 	my $volid = $conf->{$opt};
 	my $path = $volid_hash->{$volid}->{path} if $volid_hash->{$volid};
 	if ($referenced->{$volid} || ($path && $referencedpath->{$path})) {
-	    print "$prefix remove entry '$opt', its volume '$volid' is in use.\n";
+	    print "$prefix remove entry '$opt', its volume '$volid' is in use\n";
 	    $changes = 1;
 	    delete $conf->{$opt};
 	}
@@ -6122,7 +6143,7 @@ sub update_disksize {
 	next if $referencedpath->{$path};
 	$changes = 1;
 	my $key = PVE::QemuConfig->add_unused_volume($conf, $volid);
-	print "$prefix add unreferenced volume '$volid' as '$key' to config.\n";
+	print "$prefix add unreferenced volume '$volid' as '$key' to config\n";
 	$referencedpath->{$path} = 1; # avoid to add more than once (aliases)
     }
 
@@ -6156,7 +6177,7 @@ sub rescan {
 	    $vm_volids->{$volid} = $info if $info->{vmid} && $info->{vmid} == $vmid;
 	}
 
-	my $changes = update_disksize($vmid, $conf, $vm_volids);
+	my $changes = update_disk_config($vmid, $conf, $vm_volids);
 
 	PVE::QemuConfig->write_config($vmid, $conf) if $changes && !$dryrun;
     };
-- 
2.20.1





More information about the pve-devel mailing list