aboutsummaryrefslogtreecommitdiff
path: root/migration/savevm.c
diff options
context:
space:
mode:
Diffstat (limited to 'migration/savevm.c')
-rw-r--r--migration/savevm.c96
1 files changed, 59 insertions, 37 deletions
diff --git a/migration/savevm.c b/migration/savevm.c
index fd3c39dc39..4a86128ac4 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -128,7 +128,7 @@ static struct mig_cmd_args {
/* savevm/loadvm support */
static ssize_t block_writev_buffer(void *opaque, struct iovec *iov, int iovcnt,
- int64_t pos)
+ int64_t pos, Error **errp)
{
int ret;
QEMUIOVector qiov;
@@ -143,12 +143,12 @@ static ssize_t block_writev_buffer(void *opaque, struct iovec *iov, int iovcnt,
}
static ssize_t block_get_buffer(void *opaque, uint8_t *buf, int64_t pos,
- size_t size)
+ size_t size, Error **errp)
{
return bdrv_load_vmstate(opaque, buf, pos, size);
}
-static int bdrv_fclose(void *opaque)
+static int bdrv_fclose(void *opaque, Error **errp)
{
return bdrv_flush(opaque);
}
@@ -1250,29 +1250,16 @@ void qemu_savevm_state_complete_postcopy(QEMUFile *f)
qemu_fflush(f);
}
-int qemu_savevm_state_complete_precopy(QEMUFile *f, bool iterable_only,
- bool inactivate_disks)
+static
+int qemu_savevm_state_complete_precopy_iterable(QEMUFile *f, bool in_postcopy)
{
- QJSON *vmdesc;
- int vmdesc_len;
SaveStateEntry *se;
int ret;
- bool in_postcopy = migration_in_postcopy();
- Error *local_err = NULL;
-
- if (precopy_notify(PRECOPY_NOTIFY_COMPLETE, &local_err)) {
- error_report_err(local_err);
- }
-
- trace_savevm_state_complete_precopy();
-
- cpu_synchronize_all_states();
QTAILQ_FOREACH(se, &savevm_state.handlers, entry) {
if (!se->ops ||
(in_postcopy && se->ops->has_postcopy &&
se->ops->has_postcopy(se->opaque)) ||
- (in_postcopy && !iterable_only) ||
!se->ops->save_live_complete_precopy) {
continue;
}
@@ -1295,9 +1282,18 @@ int qemu_savevm_state_complete_precopy(QEMUFile *f, bool iterable_only,
}
}
- if (iterable_only) {
- return 0;
- }
+ return 0;
+}
+
+static
+int qemu_savevm_state_complete_precopy_non_iterable(QEMUFile *f,
+ bool in_postcopy,
+ bool inactivate_disks)
+{
+ QJSON *vmdesc;
+ int vmdesc_len;
+ SaveStateEntry *se;
+ int ret;
vmdesc = qjson_new();
json_prop_int(vmdesc, "page_size", qemu_target_page_size());
@@ -1357,6 +1353,42 @@ int qemu_savevm_state_complete_precopy(QEMUFile *f, bool iterable_only,
}
qjson_destroy(vmdesc);
+ return 0;
+}
+
+int qemu_savevm_state_complete_precopy(QEMUFile *f, bool iterable_only,
+ bool inactivate_disks)
+{
+ int ret;
+ Error *local_err = NULL;
+ bool in_postcopy = migration_in_postcopy();
+
+ if (precopy_notify(PRECOPY_NOTIFY_COMPLETE, &local_err)) {
+ error_report_err(local_err);
+ }
+
+ trace_savevm_state_complete_precopy();
+
+ cpu_synchronize_all_states();
+
+ if (!in_postcopy || iterable_only) {
+ ret = qemu_savevm_state_complete_precopy_iterable(f, in_postcopy);
+ if (ret) {
+ return ret;
+ }
+ }
+
+ if (iterable_only) {
+ goto flush;
+ }
+
+ ret = qemu_savevm_state_complete_precopy_non_iterable(f, in_postcopy,
+ inactivate_disks);
+ if (ret) {
+ return ret;
+ }
+
+flush:
qemu_fflush(f);
return 0;
}
@@ -1428,6 +1460,7 @@ static int qemu_savevm_state(QEMUFile *f, Error **errp)
}
migrate_init(ms);
+ memset(&ram_counters, 0, sizeof(ram_counters));
ms->to_dst_file = f;
qemu_mutex_unlock_iothread();
@@ -1620,8 +1653,6 @@ static int loadvm_postcopy_handle_advise(MigrationIncomingState *mis,
return -1;
}
- postcopy_state_set(POSTCOPY_INCOMING_ADVISE);
-
return 0;
}
@@ -1839,16 +1870,10 @@ static int loadvm_postcopy_handle_listen(MigrationIncomingState *mis)
return 0;
}
-
-typedef struct {
- QEMUBH *bh;
-} HandleRunBhData;
-
static void loadvm_postcopy_handle_run_bh(void *opaque)
{
Error *local_err = NULL;
- HandleRunBhData *data = opaque;
- MigrationIncomingState *mis = migration_incoming_get_current();
+ MigrationIncomingState *mis = opaque;
/* TODO we should move all of this lot into postcopy_ram.c or a shared code
* in migration.c
@@ -1880,15 +1905,13 @@ static void loadvm_postcopy_handle_run_bh(void *opaque)
runstate_set(RUN_STATE_PAUSED);
}
- qemu_bh_delete(data->bh);
- g_free(data);
+ qemu_bh_delete(mis->bh);
}
/* After all discards we can start running and asking for pages */
static int loadvm_postcopy_handle_run(MigrationIncomingState *mis)
{
PostcopyState ps = postcopy_state_set(POSTCOPY_INCOMING_RUNNING);
- HandleRunBhData *data;
trace_loadvm_postcopy_handle_run();
if (ps != POSTCOPY_INCOMING_LISTENING) {
@@ -1896,9 +1919,8 @@ static int loadvm_postcopy_handle_run(MigrationIncomingState *mis)
return -1;
}
- data = g_new(HandleRunBhData, 1);
- data->bh = qemu_bh_new(loadvm_postcopy_handle_run_bh, data);
- qemu_bh_schedule(data->bh);
+ mis->bh = qemu_bh_new(loadvm_postcopy_handle_run_bh, mis);
+ qemu_bh_schedule(mis->bh);
/* We need to finish reading the stream from the package
* and also stop reading anything more from the stream that loaded the
@@ -2411,7 +2433,7 @@ retry:
case QEMU_VM_COMMAND:
ret = loadvm_process_command(f);
trace_qemu_loadvm_state_section_command(ret);
- if ((ret < 0) || (ret & LOADVM_QUIT)) {
+ if ((ret < 0) || (ret == LOADVM_QUIT)) {
goto out;
}
break;