mirror of
https://git.proxmox.com/git/qemu-server
synced 2025-08-07 19:37:45 +00:00
fix online migration
This commit is contained in:
parent
72a063e494
commit
e6c3b671bf
@ -243,6 +243,9 @@ sub migrate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# vm is now owned by other node
|
# vm is now owned by other node
|
||||||
|
# Note: there is no VM config file on the local node anymore, so
|
||||||
|
# we need to pass $nocheck = 1 for vm commands
|
||||||
|
|
||||||
my $volids = $rhash->{volumes};
|
my $volids = $rhash->{volumes};
|
||||||
|
|
||||||
if ($running) {
|
if ($running) {
|
||||||
@ -260,10 +263,8 @@ sub migrate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# fixme: ther is no config file, so this will never work
|
|
||||||
# fixme: use kill(9, $running) to make sure it is stopped
|
|
||||||
# always stop local VM - no interrupts possible
|
# always stop local VM - no interrupts possible
|
||||||
eval { PVE::QemuServer::vm_stop($session->{vmid}, 1); };
|
eval { PVE::QemuServer::vm_stop($session->{vmid}, 1, 1); };
|
||||||
if ($@) {
|
if ($@) {
|
||||||
logmsg('err', "stopping vm failed - $@");
|
logmsg('err', "stopping vm failed - $@");
|
||||||
$errors = 1;
|
$errors = 1;
|
||||||
@ -446,7 +447,7 @@ sub phase1 {
|
|||||||
};
|
};
|
||||||
|
|
||||||
sub phase2 {
|
sub phase2 {
|
||||||
my ($session, $conf, $rhash) = shift;
|
my ($session, $conf, $rhash) = @_;
|
||||||
|
|
||||||
logmsg('info', "starting VM on remote node '$session->{node}'");
|
logmsg('info', "starting VM on remote node '$session->{node}'");
|
||||||
|
|
||||||
@ -477,12 +478,12 @@ sub phase2 {
|
|||||||
|
|
||||||
my $start = time();
|
my $start = time();
|
||||||
|
|
||||||
PVE::QemuServer::vm_monitor_command($session->{vmid}, "migrate -d \"tcp:localhost:$lport\"");
|
PVE::QemuServer::vm_monitor_command($session->{vmid}, "migrate -d \"tcp:localhost:$lport\"", 0, 1);
|
||||||
|
|
||||||
my $lstat = '';
|
my $lstat = '';
|
||||||
while (1) {
|
while (1) {
|
||||||
sleep (2);
|
sleep (2);
|
||||||
my $stat = PVE::QemuServer::vm_monitor_command($session->{vmid}, "info migrate", 1);
|
my $stat = PVE::QemuServer::vm_monitor_command($session->{vmid}, "info migrate", 1, 1);
|
||||||
if ($stat =~ m/^Migration status: (active|completed|failed|cancelled)$/im) {
|
if ($stat =~ m/^Migration status: (active|completed|failed|cancelled)$/im) {
|
||||||
my $ms = $1;
|
my $ms = $1;
|
||||||
|
|
||||||
|
@ -1690,12 +1690,12 @@ sub check_cmdline {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub check_running {
|
sub check_running {
|
||||||
my ($vmid) = @_;
|
my ($vmid, $nocheck) = @_;
|
||||||
|
|
||||||
my $filename = config_file($vmid);
|
my $filename = config_file($vmid);
|
||||||
|
|
||||||
die "unable to find configuration file for VM $vmid - no such machine\n"
|
die "unable to find configuration file for VM $vmid - no such machine\n"
|
||||||
if ! -f $filename;
|
if !$nocheck && ! -f $filename;
|
||||||
|
|
||||||
my $pidfile = pidfile_name($vmid);
|
my $pidfile = pidfile_name($vmid);
|
||||||
|
|
||||||
@ -1711,8 +1711,11 @@ sub check_running {
|
|||||||
|
|
||||||
if ($line =~ m/^(\d+)$/) {
|
if ($line =~ m/^(\d+)$/) {
|
||||||
my $pid = $1;
|
my $pid = $1;
|
||||||
|
if (check_cmdline($pidfile, $pid)) {
|
||||||
return $pid if ((-d "/proc/$pid") && check_cmdline ($pidfile, $pid));
|
if (my $pinfo = PVE::ProcFSTools::check_process_running($pid)) {
|
||||||
|
return $pid;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2326,6 +2329,7 @@ sub vm_start {
|
|||||||
my $cmd = "migrate_set_downtime ${migrate_downtime}";
|
my $cmd = "migrate_set_downtime ${migrate_downtime}";
|
||||||
eval { vm_monitor_command ($vmid, $cmd, 1); };
|
eval { vm_monitor_command ($vmid, $cmd, 1); };
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2362,14 +2366,14 @@ sub __read_avail {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub vm_monitor_command {
|
sub vm_monitor_command {
|
||||||
my ($vmid, $cmdstr, $nolog) = @_;
|
my ($vmid, $cmdstr, $nolog, $nocheck) = @_;
|
||||||
|
|
||||||
my $res;
|
my $res;
|
||||||
|
|
||||||
syslog ("info", "VM $vmid monitor command '$cmdstr'") if !$nolog;
|
syslog ("info", "VM $vmid monitor command '$cmdstr'") if !$nolog;
|
||||||
|
|
||||||
eval {
|
eval {
|
||||||
die "VM not running\n" if !check_running ($vmid);
|
die "VM not running\n" if !check_running($vmid, $nocheck);
|
||||||
|
|
||||||
my $sname = monitor_socket($vmid);
|
my $sname = monitor_socket($vmid);
|
||||||
|
|
||||||
@ -2477,25 +2481,28 @@ sub vm_shutdown {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Note: use $nockeck to skip tests if VM configuration file exists.
|
||||||
|
# We need that when migration VMs to other nodes (files already moved)
|
||||||
sub vm_stop {
|
sub vm_stop {
|
||||||
my ($vmid, $skiplock) = @_;
|
my ($vmid, $skiplock, $nocheck) = @_;
|
||||||
|
|
||||||
lock_config($vmid, sub {
|
lock_config($vmid, sub {
|
||||||
|
|
||||||
my $pid = check_running ($vmid);
|
my $pid = check_running($vmid, $nocheck);
|
||||||
|
|
||||||
if (!$pid) {
|
if (!$pid) {
|
||||||
syslog('info', "VM $vmid already stopped");
|
syslog('info', "VM $vmid already stopped");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!$nocheck) {
|
||||||
my $conf = load_config($vmid);
|
my $conf = load_config($vmid);
|
||||||
|
|
||||||
check_lock($conf) if !$skiplock;
|
check_lock($conf) if !$skiplock;
|
||||||
|
}
|
||||||
|
|
||||||
syslog ("info", "VM $vmid stopping");
|
syslog ("info", "VM $vmid stopping");
|
||||||
|
|
||||||
eval { vm_monitor_command ($vmid, "quit", 1); };
|
eval { vm_monitor_command ($vmid, "quit", 1, $nocheck); };
|
||||||
|
|
||||||
my $err = $@;
|
my $err = $@;
|
||||||
|
|
||||||
@ -2504,7 +2511,7 @@ sub vm_stop {
|
|||||||
my $timeout = 50; # fixme: how long?
|
my $timeout = 50; # fixme: how long?
|
||||||
|
|
||||||
my $count = 0;
|
my $count = 0;
|
||||||
while (($count < $timeout) && check_running ($vmid)) {
|
while (($count < $timeout) && check_running($vmid, $nocheck)) {
|
||||||
$count++;
|
$count++;
|
||||||
sleep 1;
|
sleep 1;
|
||||||
}
|
}
|
||||||
@ -2522,7 +2529,7 @@ sub vm_stop {
|
|||||||
my $timeout = 10;
|
my $timeout = 10;
|
||||||
|
|
||||||
my $count = 0;
|
my $count = 0;
|
||||||
while (($count < $timeout) && check_running ($vmid)) {
|
while (($count < $timeout) && check_running($vmid, $nocheck)) {
|
||||||
$count++;
|
$count++;
|
||||||
sleep 1;
|
sleep 1;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user