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.
Signed-off-by: Fabian Ebner <f.eb...@proxmox.com> --- PVE/QemuMigrate.pm | 98 ++++++++++++++++++++++++++++++---------------- 1 file changed, 64 insertions(+), 34 deletions(-) diff --git a/PVE/QemuMigrate.pm b/PVE/QemuMigrate.pm index 96de0db..e65b28f 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; @@ -284,7 +285,7 @@ sub prepare { return $running; } -sub sync_disks { +sub scan_local_volumes { my ($self, $vmid) = @_; my $conf = $self->{vmconf}; @@ -293,12 +294,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; @@ -537,11 +539,7 @@ sub sync_disks { PVE::QemuServer::update_efidisk_size($conf); } - $self->log('info', "copying local disk images") if scalar(%$local_volumes); - foreach my $volid (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; @@ -553,34 +551,65 @@ 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 = { - 'bwlimit' => $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"); + $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 (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 = { + 'bwlimit' => $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"); + } } sub cleanup_remotedisks { @@ -628,11 +657,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 _______________________________________________ pve-devel mailing list pve-devel@pve.proxmox.com https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel