Reorganize and fix monitor resume after migration

If migration failed in migrate_fd_put_buffer, the monitor may have been
resumed not only in the error path of that function but also once again
in migrate_fd_put_ready which is called unconditionally by
migrate_fd_connect.

Fix this by establishing a cleaner policy: the monitor shall be resumed
when the migration file is closed, either via callback
(migrate_fd_close) or in migrate_fd_cleanup if no file is open (i.e. no
callback invoked).

Reported-By: Michael Tokarev <mjt@tls.msk.ru>
Tested-By: Michael Tokarev <mjt@tls.msk.ru>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
Jan Kiszka 2011-08-05 09:11:26 +02:00 committed by Anthony Liguori
parent 2da8bb92fb
commit 84ec65520b
1 changed files with 9 additions and 10 deletions

View File

@ -292,18 +292,17 @@ int migrate_fd_cleanup(FdMigrationState *s)
ret = -1;
}
s->file = NULL;
} else {
if (s->mon) {
monitor_resume(s->mon);
}
}
if (s->fd != -1)
if (s->fd != -1) {
close(s->fd);
/* Don't resume monitor until we've flushed all of the buffers */
if (s->mon) {
monitor_resume(s->mon);
s->fd = -1;
}
s->fd = -1;
return ret;
}
@ -330,9 +329,6 @@ ssize_t migrate_fd_put_buffer(void *opaque, const void *data, size_t size)
if (ret == -EAGAIN) {
qemu_set_fd_handler2(s->fd, NULL, NULL, migrate_fd_put_notify, s);
} else if (ret < 0) {
if (s->mon) {
monitor_resume(s->mon);
}
s->state = MIG_STATE_ERROR;
notifier_list_notify(&migration_state_notifiers, NULL);
}
@ -458,6 +454,9 @@ int migrate_fd_close(void *opaque)
{
FdMigrationState *s = opaque;
if (s->mon) {
monitor_resume(s->mon);
}
qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
return s->close(s);
}