[pve-devel] [PATCH v2 qemu-server 02/13] migration: split sync_disks into two functions
Fabian Ebner
f.ebner at proxmox.com
Fri Jan 29 16:11:32 CET 2021
by making local_volumes class-accessible. One functions is for scanning all local
volumes and one is for actually syncing offline volumes via storage_migrate. The
exception is replicated volumes, this still happens during the scan for now.
Also introduce a filter_local_volumes helper, to makes life easier.
Signed-off-by: Fabian Ebner <f.ebner at proxmox.com>
---
Changes from v1:
* rebase (include the deactivate_volumes block that didn't exist back then)
PVE/QemuMigrate.pm | 108 +++++++++++++++++++++++++++++----------------
1 file changed, 69 insertions(+), 39 deletions(-)
diff --git a/PVE/QemuMigrate.pm b/PVE/QemuMigrate.pm
index 5c019fc..0cc13df 100644
--- a/PVE/QemuMigrate.pm
+++ b/PVE/QemuMigrate.pm
@@ -9,6 +9,7 @@ use POSIX qw( WNOHANG );
use Time::HiRes qw( usleep );
use PVE::Cluster;
+use PVE::GuestHelpers qw(safe_string_ne);
use PVE::INotify;
use PVE::RPCEnvironment;
use PVE::Replication;
@@ -357,7 +358,7 @@ sub prepare {
return $running;
}
-sub sync_disks {
+sub scan_local_volumes {
my ($self, $vmid) = @_;
my $conf = $self->{vmconf};
@@ -366,12 +367,13 @@ sub sync_disks {
# and their old_id => new_id pairs
$self->{volumes} = [];
$self->{volume_map} = {};
+ $self->{local_volumes} = {};
my $storecfg = $self->{storecfg};
eval {
# found local volumes and their origin
- my $local_volumes = {};
+ my $local_volumes = $self->{local_volumes};
my $local_volumes_errors = {};
my $other_errors = [];
my $abort = 0;
@@ -608,11 +610,7 @@ sub sync_disks {
PVE::QemuServer::update_efidisk_size($conf);
}
- $self->log('info', "copying local disk images") if scalar(%$local_volumes);
-
foreach my $volid (sort keys %$local_volumes) {
- my ($sid, $volname) = PVE::Storage::parse_volume_id($volid);
- my $targetsid = PVE::QemuServer::map_storage($self->{opts}->{storagemap}, $sid);
my $ref = $local_volumes->{$volid}->{ref};
if ($self->{running} && $ref eq 'config') {
push @{$self->{online_local_volumes}}, $volid;
@@ -624,39 +622,70 @@ sub sync_disks {
} else {
next if $self->{replicated_volumes}->{$volid};
push @{$self->{volumes}}, $volid;
- my $opts = $self->{opts};
- # use 'migrate' limit for transfer to other node
- my $bwlimit = PVE::Storage::get_bandwidth_limit('migration', [$targetsid, $sid], $opts->{bwlimit});
- # JSONSchema and get_bandwidth_limit use kbps - storage_migrate bps
- $bwlimit = $bwlimit * 1024 if defined($bwlimit);
-
- my $storage_migrate_opts = {
- 'ratelimit_bps' => $bwlimit,
- 'insecure' => $opts->{migration_type} eq 'insecure',
- 'with_snapshots' => $local_volumes->{$volid}->{snapshots},
- 'allow_rename' => !$local_volumes->{$volid}->{is_vmstate},
- };
-
- my $logfunc = sub { $self->log('info', $_[0]); };
- my $new_volid = eval {
- PVE::Storage::storage_migrate($storecfg, $volid, $self->{ssh_info},
- $targetsid, $storage_migrate_opts, $logfunc);
- };
- if (my $err = $@) {
- die "storage migration for '$volid' to storage '$targetsid' failed - $err\n";
- }
-
- $self->{volume_map}->{$volid} = $new_volid;
- $self->log('info', "volume '$volid' is '$new_volid' on the target\n");
-
- eval { PVE::Storage::deactivate_volumes($storecfg, [$volid]); };
- if (my $err = $@) {
- $self->log('warn', $err);
- }
+ $local_volumes->{$volid}->{migration_mode} = 'offline';
}
}
};
- die "Failed to sync data - $@" if $@;
+ die "Problem found while scanning volumes - $@" if $@;
+}
+
+sub filter_local_volumes {
+ my ($self, $migration_mode) = @_;
+
+ my $volumes = $self->{local_volumes};
+ my @filtered_volids;
+
+ foreach my $volid (sort keys %{$volumes}) {
+ next if defined($migration_mode) && safe_string_ne($volumes->{$volid}->{migration_mode}, $migration_mode);
+ push @filtered_volids, $volid;
+ }
+
+ return @filtered_volids;
+}
+
+sub sync_offline_local_volumes {
+ my ($self) = @_;
+
+ my $local_volumes = $self->{local_volumes};
+ my @volids = $self->filter_local_volumes('offline');
+
+ my $storecfg = $self->{storecfg};
+ my $opts = $self->{opts};
+
+ $self->log('info', "copying local disk images") if scalar(@volids);
+
+ foreach my $volid (@volids) {
+ my ($sid, $volname) = PVE::Storage::parse_volume_id($volid);
+ my $targetsid = PVE::QemuServer::map_storage($self->{opts}->{storagemap}, $sid);
+ # use 'migration' limit for transfer to other node
+ my $bwlimit = PVE::Storage::get_bandwidth_limit('migration', [$targetsid, $sid], $opts->{bwlimit});
+ # JSONSchema and get_bandwidth_limit use kbps - storage_migrate bps
+ $bwlimit = $bwlimit * 1024 if defined($bwlimit);
+
+ my $storage_migrate_opts = {
+ 'ratelimit_bps' => $bwlimit,
+ 'insecure' => $opts->{migration_type} eq 'insecure',
+ 'with_snapshots' => $local_volumes->{$volid}->{snapshots},
+ 'allow_rename' => !$local_volumes->{$volid}->{is_vmstate},
+ };
+
+ my $logfunc = sub { $self->log('info', $_[0]); };
+ my $new_volid = eval {
+ PVE::Storage::storage_migrate($storecfg, $volid, $self->{ssh_info},
+ $targetsid, $storage_migrate_opts, $logfunc);
+ };
+ if (my $err = $@) {
+ die "storage migration for '$volid' to storage '$targetsid' failed - $err\n";
+ }
+
+ $self->{volume_map}->{$volid} = $new_volid;
+ $self->log('info', "volume '$volid' is '$new_volid' on the target\n");
+
+ eval { PVE::Storage::deactivate_volumes($storecfg, [$volid]); };
+ if (my $err = $@) {
+ $self->log('warn', $err);
+ }
+ }
}
sub cleanup_remotedisks {
@@ -704,11 +733,12 @@ sub phase1 {
$conf->{lock} = 'migrate';
PVE::QemuConfig->write_config($vmid, $conf);
- sync_disks($self, $vmid);
-
- # sync_disks fixes disk sizes to match their actual size, write changes so
+ # scan_local_volumes fixes disk sizes to match their actual size, write changes so
# target allocates correct volumes
+ $self->scan_local_volumes($vmid);
PVE::QemuConfig->write_config($vmid, $conf);
+
+ $self->sync_offline_local_volumes();
};
sub phase1_cleanup {
--
2.20.1
More information about the pve-devel
mailing list