migration: introduce lock for to_dst_file
Let's introduce a lock for that QEMUFile since we are going to operate on it in multiple threads. Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com> Signed-off-by: Peter Xu <peterx@redhat.com> Message-Id: <20180502104740.12123-23-peterx@redhat.com> Signed-off-by: Juan Quintela <quintela@redhat.com>
This commit is contained in:
parent
3b563c4be0
commit
62df066fff
@ -74,8 +74,9 @@ void migration_channel_connect(MigrationState *s,
|
|||||||
} else {
|
} else {
|
||||||
QEMUFile *f = qemu_fopen_channel_output(ioc);
|
QEMUFile *f = qemu_fopen_channel_output(ioc);
|
||||||
|
|
||||||
|
qemu_mutex_lock(&s->qemu_file_lock);
|
||||||
s->to_dst_file = f;
|
s->to_dst_file = f;
|
||||||
|
qemu_mutex_unlock(&s->qemu_file_lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
migrate_fd_connect(s, error);
|
migrate_fd_connect(s, error);
|
||||||
|
@ -1234,6 +1234,7 @@ static void migrate_fd_cleanup(void *opaque)
|
|||||||
|
|
||||||
if (s->to_dst_file) {
|
if (s->to_dst_file) {
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
|
QEMUFile *tmp;
|
||||||
|
|
||||||
trace_migrate_fd_cleanup();
|
trace_migrate_fd_cleanup();
|
||||||
qemu_mutex_unlock_iothread();
|
qemu_mutex_unlock_iothread();
|
||||||
@ -1246,8 +1247,15 @@ static void migrate_fd_cleanup(void *opaque)
|
|||||||
if (multifd_save_cleanup(&local_err) != 0) {
|
if (multifd_save_cleanup(&local_err) != 0) {
|
||||||
error_report_err(local_err);
|
error_report_err(local_err);
|
||||||
}
|
}
|
||||||
qemu_fclose(s->to_dst_file);
|
qemu_mutex_lock(&s->qemu_file_lock);
|
||||||
|
tmp = s->to_dst_file;
|
||||||
s->to_dst_file = NULL;
|
s->to_dst_file = NULL;
|
||||||
|
qemu_mutex_unlock(&s->qemu_file_lock);
|
||||||
|
/*
|
||||||
|
* Close the file handle without the lock to make sure the
|
||||||
|
* critical section won't block for long.
|
||||||
|
*/
|
||||||
|
qemu_fclose(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert((s->state != MIGRATION_STATUS_ACTIVE) &&
|
assert((s->state != MIGRATION_STATUS_ACTIVE) &&
|
||||||
@ -2531,14 +2539,20 @@ static MigThrError postcopy_pause(MigrationState *s)
|
|||||||
assert(s->state == MIGRATION_STATUS_POSTCOPY_ACTIVE);
|
assert(s->state == MIGRATION_STATUS_POSTCOPY_ACTIVE);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
QEMUFile *file;
|
||||||
|
|
||||||
migrate_set_state(&s->state, s->state,
|
migrate_set_state(&s->state, s->state,
|
||||||
MIGRATION_STATUS_POSTCOPY_PAUSED);
|
MIGRATION_STATUS_POSTCOPY_PAUSED);
|
||||||
|
|
||||||
/* Current channel is possibly broken. Release it. */
|
/* Current channel is possibly broken. Release it. */
|
||||||
assert(s->to_dst_file);
|
assert(s->to_dst_file);
|
||||||
qemu_file_shutdown(s->to_dst_file);
|
qemu_mutex_lock(&s->qemu_file_lock);
|
||||||
qemu_fclose(s->to_dst_file);
|
file = s->to_dst_file;
|
||||||
s->to_dst_file = NULL;
|
s->to_dst_file = NULL;
|
||||||
|
qemu_mutex_unlock(&s->qemu_file_lock);
|
||||||
|
|
||||||
|
qemu_file_shutdown(file);
|
||||||
|
qemu_fclose(file);
|
||||||
|
|
||||||
error_report("Detected IO failure for postcopy. "
|
error_report("Detected IO failure for postcopy. "
|
||||||
"Migration paused.");
|
"Migration paused.");
|
||||||
@ -3007,6 +3021,7 @@ static void migration_instance_finalize(Object *obj)
|
|||||||
MigrationParameters *params = &ms->parameters;
|
MigrationParameters *params = &ms->parameters;
|
||||||
|
|
||||||
qemu_mutex_destroy(&ms->error_mutex);
|
qemu_mutex_destroy(&ms->error_mutex);
|
||||||
|
qemu_mutex_destroy(&ms->qemu_file_lock);
|
||||||
g_free(params->tls_hostname);
|
g_free(params->tls_hostname);
|
||||||
g_free(params->tls_creds);
|
g_free(params->tls_creds);
|
||||||
qemu_sem_destroy(&ms->pause_sem);
|
qemu_sem_destroy(&ms->pause_sem);
|
||||||
@ -3046,6 +3061,7 @@ static void migration_instance_init(Object *obj)
|
|||||||
qemu_sem_init(&ms->postcopy_pause_sem, 0);
|
qemu_sem_init(&ms->postcopy_pause_sem, 0);
|
||||||
qemu_sem_init(&ms->postcopy_pause_rp_sem, 0);
|
qemu_sem_init(&ms->postcopy_pause_rp_sem, 0);
|
||||||
qemu_sem_init(&ms->rp_state.rp_sem, 0);
|
qemu_sem_init(&ms->rp_state.rp_sem, 0);
|
||||||
|
qemu_mutex_init(&ms->qemu_file_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -114,6 +114,12 @@ struct MigrationState
|
|||||||
QemuThread thread;
|
QemuThread thread;
|
||||||
QEMUBH *cleanup_bh;
|
QEMUBH *cleanup_bh;
|
||||||
QEMUFile *to_dst_file;
|
QEMUFile *to_dst_file;
|
||||||
|
/*
|
||||||
|
* Protects to_dst_file pointer. We need to make sure we won't
|
||||||
|
* yield or hang during the critical section, since this lock will
|
||||||
|
* be used in OOB command handler.
|
||||||
|
*/
|
||||||
|
QemuMutex qemu_file_lock;
|
||||||
|
|
||||||
/* bytes already send at the beggining of current interation */
|
/* bytes already send at the beggining of current interation */
|
||||||
uint64_t iteration_initial_bytes;
|
uint64_t iteration_initial_bytes;
|
||||||
|
Loading…
Reference in New Issue
Block a user