Anthony Liguori <anth...@codemonkey.ws> wrote: > On 10/11/2011 05:00 AM, Juan Quintela wrote: >> If migration is not active, just ignore writes. >> >> Signed-off-by: Juan Quintela<quint...@redhat.com> >> --- >> migration.c | 4 ++++ >> 1 files changed, 4 insertions(+), 0 deletions(-) >> >> diff --git a/migration.c b/migration.c >> index 7ac1fc2..090c925 100644 >> --- a/migration.c >> +++ b/migration.c >> @@ -323,6 +323,10 @@ ssize_t migrate_fd_put_buffer(void *opaque, const void >> *data, size_t size) >> FdMigrationState *s = opaque; >> ssize_t ret; >> >> + if (s->state != MIG_STATE_ACTIVE) { >> + return -EIO; >> + } >> + > > Buffered file is buffered. The migration may complete before the > buffer is completely drained. That means additional put_buffer calls > may come after the migration state has moved to complete.
static void migrate_fd_completed(MigrationState *s) { DPRINTF("setting completed state\n"); if (migrate_fd_cleanup(s) < 0) { s->state = MIG_STATE_ERROR; } else { s->state = MIG_STATE_COMPLETED; runstate_set(RUN_STATE_POSTMIGRATE); } notifier_list_notify(&migration_state_notifiers, s); } After all the changes in this thread, that is the only place that can change s->state to "MIG_STATE_COMPLETED", as you can see, we do that after doing a migrate_fd_cleanup(), and that just flush + close the fd. So, I still think that everything is done as expected. (testing confirms that both migrate_cancel after one error don't hang and migration without errors ends as expected. Later, Juan. > Regards, > Anthony Liguori > >> do { >> ret = s->write(s, data, size); >> } while (ret == -1&& ((s->get_error(s)) == EINTR));