diff options
| author | Peter Maydell <peter.maydell@linaro.org> | 2018-02-16 12:51:40 +0000 |
|---|---|---|
| committer | Peter Maydell <peter.maydell@linaro.org> | 2018-02-16 12:51:40 +0000 |
| commit | 648ba915961664ecb4cff0ee847a929c65e4b4b4 (patch) | |
| tree | 4e688224f2bf948000d03c34cff398c44e65bff2 /migration/savevm.c | |
| parent | 0402ca3c70356e09e694fece39256790ff7755f2 (diff) | |
| parent | 3e0c8050ebba3f55dc2d92b3790a3cfb80786d07 (diff) | |
| download | focaccia-qemu-648ba915961664ecb4cff0ee847a929c65e4b4b4.tar.gz focaccia-qemu-648ba915961664ecb4cff0ee847a929c65e4b4b4.zip | |
Merge remote-tracking branch 'remotes/dgilbert/tags/pull-migration-20180214a' into staging
Migration pull 20180214 Note that the 'Add test for migration to bad destination' displays a 'Connection refused' during running, but still gives the correct exit code and OK (It's checking that the source doesn't fail when it can't connect, so that's the right error). If it's particularly disliked that patch can be skipped individually. # gpg: Signature made Wed 14 Feb 2018 15:33:04 GMT # gpg: using RSA key 0516331EBC5BFDE7 # gpg: Good signature from "Dr. David Alan Gilbert (RH2) <dgilbert@redhat.com>" # Primary key fingerprint: 45F5 C71B 4A0C B7FB 977A 9FA9 0516 331E BC5B FDE7 * remotes/dgilbert/tags/pull-migration-20180214a: migration: pass MigrationState to migrate_init() migration: allow send_rq to fail migration: provide postcopy_fault_thread_notify() migration: reuse mis->userfault_quit_fd migration: better error handling with QEMUFile tests/migration: Add test for migration to bad destination migration: Fix early failure cleanup tests/migration: Add source to PC boot block migration: improve documentation of postcopy-ram migration/xen: Check return value of qemu_fclose Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'migration/savevm.c')
| -rw-r--r-- | migration/savevm.c | 48 |
1 files changed, 43 insertions, 5 deletions
diff --git a/migration/savevm.c b/migration/savevm.c index 3f611c02e8..8e6d872452 100644 --- a/migration/savevm.c +++ b/migration/savevm.c @@ -1257,8 +1257,11 @@ void qemu_savevm_state_cleanup(void) static int qemu_savevm_state(QEMUFile *f, Error **errp) { int ret; - MigrationState *ms = migrate_init(); + MigrationState *ms = migrate_get_current(); MigrationStatus status; + + migrate_init(ms); + ms->to_dst_file = f; if (migration_is_blocked(errp)) { @@ -1781,6 +1784,11 @@ static int loadvm_process_command(QEMUFile *f) cmd = qemu_get_be16(f); len = qemu_get_be16(f); + /* Check validity before continue processing of cmds */ + if (qemu_file_get_error(f)) { + return qemu_file_get_error(f); + } + trace_loadvm_process_command(cmd, len); if (cmd >= MIG_CMD_MAX || cmd == MIG_CMD_INVALID) { error_report("MIG_CMD 0x%x unknown (len 0x%x)", cmd, len); @@ -1846,6 +1854,7 @@ static int loadvm_process_command(QEMUFile *f) */ static bool check_section_footer(QEMUFile *f, SaveStateEntry *se) { + int ret; uint8_t read_mark; uint32_t read_section_id; @@ -1856,6 +1865,13 @@ static bool check_section_footer(QEMUFile *f, SaveStateEntry *se) read_mark = qemu_get_byte(f); + ret = qemu_file_get_error(f); + if (ret) { + error_report("%s: Read section footer failed: %d", + __func__, ret); + return false; + } + if (read_mark != QEMU_VM_SECTION_FOOTER) { error_report("Missing section footer for %s", se->idstr); return false; @@ -1891,6 +1907,13 @@ qemu_loadvm_section_start_full(QEMUFile *f, MigrationIncomingState *mis) instance_id = qemu_get_be32(f); version_id = qemu_get_be32(f); + ret = qemu_file_get_error(f); + if (ret) { + error_report("%s: Failed to read instance/version ID: %d", + __func__, ret); + return ret; + } + trace_qemu_loadvm_state_section_startfull(section_id, idstr, instance_id, version_id); /* Find savevm section */ @@ -1938,6 +1961,13 @@ qemu_loadvm_section_part_end(QEMUFile *f, MigrationIncomingState *mis) section_id = qemu_get_be32(f); + ret = qemu_file_get_error(f); + if (ret) { + error_report("%s: Failed to read section ID: %d", + __func__, ret); + return ret; + } + trace_qemu_loadvm_state_section_partend(section_id); QTAILQ_FOREACH(se, &savevm_state.handlers, entry) { if (se->load_section_id == section_id) { @@ -2005,8 +2035,14 @@ static int qemu_loadvm_state_main(QEMUFile *f, MigrationIncomingState *mis) uint8_t section_type; int ret = 0; - while ((section_type = qemu_get_byte(f)) != QEMU_VM_EOF) { - ret = 0; + while (true) { + section_type = qemu_get_byte(f); + + if (qemu_file_get_error(f)) { + ret = qemu_file_get_error(f); + break; + } + trace_qemu_loadvm_state_section(section_type); switch (section_type) { case QEMU_VM_SECTION_START: @@ -2030,6 +2066,9 @@ static int qemu_loadvm_state_main(QEMUFile *f, MigrationIncomingState *mis) goto out; } break; + case QEMU_VM_EOF: + /* This is the end of migration */ + goto out; default: error_report("Unknown savevm section type %d", section_type); ret = -EINVAL; @@ -2284,8 +2323,7 @@ void qmp_xen_save_devices_state(const char *filename, bool has_live, bool live, f = qemu_fopen_channel_output(QIO_CHANNEL(ioc)); object_unref(OBJECT(ioc)); ret = qemu_save_device_state(f); - qemu_fclose(f); - if (ret < 0) { + if (ret < 0 || qemu_fclose(f) < 0) { error_setg(errp, QERR_IO_ERROR); } else { /* libxl calls the QMP command "stop" before calling |