[pve-devel] [RFC guest-common 1/16] Implement update_volume_ids and add required helpers: foreach_volume and print_volume

Fabian Ebner f.ebner at proxmox.com
Wed Jan 29 14:29:59 CET 2020


This function is intened to be used after doing a migration where some
of the volume IDs changed.

Signed-off-by: Fabian Ebner <f.ebner at proxmox.com>
---
 PVE/AbstractConfig.pm | 61 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 61 insertions(+)

diff --git a/PVE/AbstractConfig.pm b/PVE/AbstractConfig.pm
index a94a379..fb833cb 100644
--- a/PVE/AbstractConfig.pm
+++ b/PVE/AbstractConfig.pm
@@ -366,6 +366,67 @@ sub get_replicatable_volumes {
     die "implement me - abstract method\n";
 }
 
+sub foreach_volume {
+    my ($class, $conf, $func, @param) = @_;
+
+    die "abstract method - implement me\n";
+}
+
+sub print_volume {
+    my ($class, $volume) = @_;
+
+    die "abstract method - implement me\n";
+}
+
+# $volume_map is a hash of 'old_volid' => 'new_volid' pairs.
+# This method replaces 'old_volid' by 'new_volid' throughout
+# the config including snapshots, both for volumes appearing in
+# foreach_volume as well as vmstate and unusedN values.
+sub update_volume_ids {
+    my ($class, $conf, $volume_map) = @_;
+
+    my $newconf = {};
+
+    my $do_replace = sub {
+	my ($key, $volume, $newconf, $volume_map) = @_;
+
+	my $old_volid = $volume->{file} // $volume->{volume};
+	if (my $new_volid = $volume_map->{$old_volid}) {
+	    $volume->{file} = $new_volid if defined($volume->{file});
+	    $volume->{volume} = $new_volid if defined($volume->{volume});
+	    $newconf->{$key} = $class->print_volume($volume);
+	}
+    };
+
+    my $replace_volids = sub {
+	my ($conf) = @_;
+
+	my $newconf = {};
+	foreach my $key (keys %{$conf}) {
+	    next if $key =~ m/^snapshots$/;
+	    # these keys are not handled by foreach_volume
+	    if ($key =~ m/^(vmstate)|(unused\d+)$/) {
+		my $old_volid = $conf->{$key};
+		$newconf->{$key} = $volume_map->{$old_volid};
+	    }
+	    $newconf->{$key} = $conf->{$key} if !defined($newconf->{$key});
+	}
+
+	$class->foreach_volume($conf, $do_replace, $newconf, $volume_map);
+	return $newconf;
+    };
+
+    $newconf = $replace_volids->($conf);
+    foreach my $snap (keys %{$conf->{snapshots}}) {
+	my $newsnap = $replace_volids->($conf->{snapshots}->{$snap});
+	foreach my $k (keys %{$newsnap}) {
+	    $newconf->{snapshots}->{$snap}->{$k} = $newsnap->{$k};
+	}
+    }
+
+    return $newconf;
+}
+
 # Internal snapshots
 
 # NOTE: Snapshot create/delete involves several non-atomic
-- 
2.20.1





More information about the pve-devel mailing list