---
 src/PVE/LXC/Migrate.pm | 76 ++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 70 insertions(+), 6 deletions(-)

diff --git a/src/PVE/LXC/Migrate.pm b/src/PVE/LXC/Migrate.pm
index 2f0244b..cfca82c 100644
--- a/src/PVE/LXC/Migrate.pm
+++ b/src/PVE/LXC/Migrate.pm
@@ -10,6 +10,10 @@ use PVE::INotify;
 use PVE::Cluster;
 use PVE::Storage;
 use PVE::LXC;
+use PVE::LXC::Config;
+use PVE::ReplicationConfig;
+use PVE::ReplicationState;
+use JSON;
 
 use base qw(PVE::AbstractMigrate);
 
@@ -264,12 +268,42 @@ sub phase1 {
        die "can't migrate CT - check log\n";
     }
 
+
+    my $rep_cfg = PVE::ReplicationConfig->new();
+    my $jobid;
+    my $last_replica;
+
+    if ($jobid = PVE::ReplicationConfig::get_jobid($rep_cfg, $vmid, 
$self->{node}) ) {
+       my $stateobj = PVE::ReplicationState::read_state();
+       my $state = PVE::ReplicationState::extract_job_state($stateobj, 
$rep_cfg->{ids}->{$jobid});
+       $last_replica = 
PVE::ReplicationState::replication_snapshot_name($jobid, $state->{last_sync});
+    }
+
     foreach my $volid (keys %$volhash) {
        my ($sid, $volname) = PVE::Storage::parse_volume_id($volid);
        push @{$self->{volumes}}, $volid;
-       PVE::Storage::storage_migrate($self->{storecfg}, $volid, 
$self->{ssh_info}, $sid);
+       PVE::Storage::storage_migrate($self->{storecfg}, $volid, 
$self->{ssh_info}, $sid, undef, $last_replica);
+    }
+
+
+    # set new replica_target if we migrate to replica target.
+
+    if ($jobid) {
+
+       my $update_target = sub {
+
+           if ($rep_cfg->{ids}->{$jobid}->{target} eq $self->{node}) {
+               $self->log('info', "change replica target to Node: 
$self->{opts}->{node}");
+               $rep_cfg->{ids}->{$jobid}->{target} = $self->{opts}->{node};
+               $rep_cfg->write();
+           }
+
+       };
+
+       PVE::ReplicationConfig::lock($update_target);
     }
 
+
     my $conffile = PVE::LXC::Config->config_file($vmid);
     my $newconffile = PVE::LXC::Config->config_file($vmid, $self->{node});
 
@@ -312,13 +346,19 @@ sub phase3 {
 
     my $volids = $self->{volumes};
 
+    my $rep_cfg = PVE::ReplicationConfig->new();
+    my $replica = PVE::ReplicationConfig::check_for_existing_jobs($rep_cfg, 
$vmid, 1);
+    my $jobid =  PVE::ReplicationConfig::get_jobid($rep_cfg, $vmid, 
$self->{opts}->{node});
     # destroy local copies
     foreach my $volid (@$volids) {
-       eval { PVE::Storage::vdisk_free($self->{storecfg}, $volid); };
-       if (my $err = $@) {
-           $self->log('err', "removing local copy of '$volid' failed - $err");
-           $self->{errors} = 1;
-           last if $err =~ /^interrupted by signal$/;
+       # do not destroy if new target is local_host
+       if (!$jobid) {
+           eval { PVE::Storage::vdisk_free($self->{storecfg}, $volid); };
+           if (my $err = $@) {
+               $self->log('err', "removing local copy of '$volid' failed - 
$err");
+               $self->{errors} = 1;
+               last if $err =~ /^interrupted by signal$/;
+           }
        }
     }
 }
@@ -341,6 +381,30 @@ sub final_cleanup {
        $self->cmd_logerr($cmd, errmsg => "failed to clear migrate lock");      
     }
 
+    # transfer replication state to migration target node.
+    my $rep_cfg = PVE::ReplicationConfig->new();
+    my $new_target = $self->{opts}->{node};
+    if (PVE::ReplicationConfig::get_jobid($rep_cfg, $vmid, $new_target)) {
+       my $stateobj = PVE::ReplicationState::read_state();
+
+       my $old_target =  $self->{node};
+
+       my $vm_state = {};
+       foreach my $key (keys %{$stateobj->{$vmid}}) {
+           if ($key =~ /^(.*\/)\Q$old_target\E$/) {
+               $vm_state->{"$1$new_target"} = $stateobj->{$vmid}->{$key};
+           } else {
+               $vm_state->{$key} = $stateobj->{$vmid}->{$key};
+           }
+       }
+
+       # This have to be double quoted when it run it over ssh.
+       my $state = PVE::Tools::shellquote(encode_json $vm_state);
+
+       my $cmd = [ @{$self->{rem_ssh}}, 'pvesr', 'set-state', $vmid, $state];
+       $self->cmd_logerr($cmd, errmsg => "failed to activate replica");
+    }
+
     # in restart mode, we start the container on the target node
     # after migration
     if ($self->{opts}->{restart} && $self->{was_running}) {
-- 
2.11.0


_______________________________________________
pve-devel mailing list
pve-devel@pve.proxmox.com
https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to