fix online migration

This commit is contained in:
Dietmar Maurer 2011-09-15 08:21:32 +02:00
parent 72a063e494
commit e6c3b671bf
2 changed files with 37 additions and 29 deletions

View File

@ -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;

View File

@ -1690,17 +1690,17 @@ 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);
if (my $fd = IO::File->new ("<$pidfile")) { if (my $fd = IO::File->new("<$pidfile")) {
my $st = stat ($fd); my $st = stat($fd);
my $line = <$fd>; my $line = <$fd>;
close ($fd); close ($fd);
@ -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;
}
}
} }
} }
@ -2280,7 +2283,7 @@ sub vm_start {
my $defaults = load_defaults(); my $defaults = load_defaults();
my ($cmd, $vollist) = config_to_command ($storecfg, $vmid, $conf, $defaults, $migrate_uri); my ($cmd, $vollist) = config_to_command($storecfg, $vmid, $conf, $defaults, $migrate_uri);
# host pci devices # host pci devices
for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) { for (my $i = 0; $i < $MAX_HOSTPCI_DEVICES; $i++) {
my $d = parse_hostpci($conf->{"hostpci$i"}); my $d = parse_hostpci($conf->{"hostpci$i"});
@ -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,16 +2366,16 @@ 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);
my $sock = IO::Socket::UNIX->new ( Peer => $sname ) || my $sock = IO::Socket::UNIX->new ( Peer => $sname ) ||
die "unable to connect to VM $vmid socket - $!\n"; die "unable to connect to VM $vmid socket - $!\n";
@ -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;
} }
my $conf = load_config ($vmid); if (!$nocheck) {
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;
} }
@ -2532,7 +2539,7 @@ sub vm_stop {
kill 9, $pid; kill 9, $pid;
} }
fairsched_rmnod ($vmid); # try to destroy group fairsched_rmnod($vmid); # try to destroy group
}); });
} }