]> git.proxmox.com Git - pve-container.git/blobdiff - src/PVE/LXC/Migrate.pm
Use new storage_migrate interface
[pve-container.git] / src / PVE / LXC / Migrate.pm
index 2f0244b945fefe7f0f91cfe367b710a092d9e004..d0be6d43dd1b931a4f070745b5dae3d9277055c7 100644 (file)
@@ -9,7 +9,11 @@ use PVE::Tools;
 use PVE::INotify;
 use PVE::Cluster;
 use PVE::Storage;
+use PVE::LXC::Config;
 use PVE::LXC;
+use PVE::ReplicationConfig;
+use PVE::ReplicationState;
+use PVE::Replication;
 
 use base qw(PVE::AbstractMigrate);
 
@@ -43,7 +47,7 @@ sub prepare {
     my $force = $self->{opts}->{force} // 0;
     my $need_activate = [];
 
-    PVE::LXC::Config->foreach_mountpoint($conf, sub {
+    PVE::LXC::Config->foreach_volume($conf, sub {
        my ($ms, $mountpoint) = @_;
 
        my $volid = $mountpoint->{volume};
@@ -101,12 +105,7 @@ sub prepare {
 
        $self->log('info', "shutdown CT $vmid\n");
 
-       my $cmd = ['lxc-stop', '-n', $vmid, '--timeout', $timeout];
-       $self->cmd($cmd, timeout => $timeout + 5);
-
-       # make sure container is stopped
-       $cmd = ['lxc-wait',  '-n', $vmid, '-t', 5, '-s', 'STOPPED'];
-       $self->cmd($cmd);
+       PVE::LXC::vm_stop($vmid, 0, $timeout);
 
        $running = 0;
     }
@@ -156,7 +155,8 @@ sub phase1 {
            return;
        }
 
-       $volhash->{$volid} = defined($snapname) ? 'snapshot' : 'config';
+       $volhash->{$volid}->{ref} = defined($snapname) ? 'snapshot' : 'config';
+       $volhash->{$volid}->{snapshots} = defined($snapname);
 
        my ($path, $owner) = PVE::Storage::path($self->{storecfg}, $volid);
 
@@ -209,7 +209,7 @@ sub phase1 {
        PVE::Storage::foreach_volid($dl, sub {
            my ($volid, $sid, $volname) = @_;
 
-           $volhash->{$volid} = 'storage';
+           $volhash->{$volid}->{ref} = 'storage';
        });
     }
 
@@ -217,11 +217,11 @@ sub phase1 {
     foreach my $snapname (keys %{$conf->{snapshots}}) {
        &$test_volid($conf->{snapshots}->{$snapname}->{'vmstate'}, 0, undef)
            if defined($conf->{snapshots}->{$snapname}->{'vmstate'});
-       PVE::LXC::Config->foreach_mountpoint($conf->{snapshots}->{$snapname}, $test_mp, $snapname);
+       PVE::LXC::Config->foreach_volume($conf->{snapshots}->{$snapname}, $test_mp, $snapname);
     }
 
     # finally all currently used volumes
-    PVE::LXC::Config->foreach_mountpoint($conf, $test_mp);
+    PVE::LXC::Config->foreach_volume($conf, $test_mp);
 
 
     # additional checks for local storage
@@ -245,11 +245,12 @@ sub phase1 {
     }
 
     foreach my $volid (sort keys %$volhash) {
-       if ($volhash->{$volid} eq 'storage') {
+       my $ref = $volhash->{$volid}->{ref};
+       if ($ref eq 'storage') {
            $self->log('info', "found local volume '$volid' (via storage)\n");
-       } elsif ($volhash->{$volid} eq 'config') {
+       } elsif ($ref eq 'config') {
            $self->log('info', "found local volume '$volid' (in current VM config)\n");
-       } elsif ($volhash->{$volid} eq 'snapshot') {
+       } elsif ($ref eq 'snapshot') {
            $self->log('info', "found local volume '$volid' (referenced by snapshot(s))\n");
        } else {
            $self->log('info', "found local volume '$volid'\n");
@@ -264,10 +265,34 @@ sub phase1 {
        die "can't migrate CT - check log\n";
     }
 
+    my $rep_volumes;
+
+    my $rep_cfg = PVE::ReplicationConfig->new();
+
+    if (my $jobcfg = $rep_cfg->find_local_replication_job($vmid, $self->{node})) {
+       die "can't live migrate VM with replicated volumes\n" if $self->{running};
+       my $start_time = time();
+       my $logfunc = sub { my ($msg) = @_;  $self->log('info', $msg); };
+       $rep_volumes = PVE::Replication::run_replication(
+           'PVE::LXC::Config', $jobcfg, $start_time, $start_time, $logfunc);
+    }
+
+    my $opts = $self->{opts};
     foreach my $volid (keys %$volhash) {
+       next if $rep_volumes->{$volid};
        my ($sid, $volname) = PVE::Storage::parse_volume_id($volid);
        push @{$self->{volumes}}, $volid;
-       PVE::Storage::storage_migrate($self->{storecfg}, $volid, $self->{ssh_info}, $sid);
+       my $bwlimit = PVE::Storage::get_bandwidth_limit('migration', [$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' => $volhash->{$volid}->{snapshots},
+       };
+
+       PVE::Storage::storage_migrate($self->{storecfg}, $volid, $self->{ssh_info}, $sid, $storage_migrate_opts);
     }
 
     my $conffile = PVE::LXC::Config->config_file($vmid);
@@ -287,11 +312,16 @@ sub phase1 {
     my $vollist = PVE::LXC::Config->get_vm_volumes($conf);
     PVE::Storage::deactivate_volumes($self->{storecfg}, $vollist);
 
+   # transfer replication state before move config
+    $self->transfer_replication_state() if $rep_volumes;
+
     # move config
     die "Failed to move config to node '$self->{node}' - rename failed: $!\n"
        if !rename($conffile, $newconffile);
 
     $self->{conf_migrated} = 1;
+
+    $self->switch_replication_job_target() if $rep_volumes;
 }
 
 sub phase1_cleanup {
@@ -329,25 +359,30 @@ sub final_cleanup {
     $self->log('info', "start final cleanup");
 
     if (!$self->{conf_migrated}) {
-       my $conf = $self->{vmconf};
-       delete $conf->{lock};
-
-       eval { PVE::LXC::Config->write_config($vmid, $conf); };
+       eval { PVE::LXC::Config->remove_lock($vmid, 'migrate'); };
        if (my $err = $@) {
            $self->log('err', $err);
        }
+       # in restart mode, we start the container on the source node
+       # on migration error
+       if ($self->{opts}->{restart} && $self->{was_running}) {
+           $self->log('info', "start container on source node");
+           my $skiplock = 1;
+           PVE::LXC::vm_start($vmid, $self->{vmconf}, $skiplock);
+       }
     } else {
        my $cmd = [ @{$self->{rem_ssh}}, 'pct', 'unlock', $vmid ];
-       $self->cmd_logerr($cmd, errmsg => "failed to clear migrate lock");      
+       $self->cmd_logerr($cmd, errmsg => "failed to clear migrate lock");
+
+       # in restart mode, we start the container on the target node
+       # after migration
+       if ($self->{opts}->{restart} && $self->{was_running}) {
+           $self->log('info', "start container on target node");
+           my $cmd = [ @{$self->{rem_ssh}}, 'pct', 'start', $vmid];
+           $self->cmd($cmd);
+       }
     }
 
-    # in restart mode, we start the container on the target node
-    # after migration
-    if ($self->{opts}->{restart} && $self->{was_running}) {
-       $self->log('info', "start container on target node");
-       my $cmd = [ @{$self->{rem_ssh}}, 'pct', 'start', $vmid];
-       $self->cmd($cmd);
-    }
 }
 
 1;