@@ -1896,6 +1896,8 @@ static void migrate_fd_cleanup(MigrationState *s)
g_free(s->hostname);
s->hostname = NULL;
+ json_writer_free(s->vmdesc);
+
qemu_savevm_state_cleanup();
if (s->to_dst_file) {
@@ -2154,6 +2156,7 @@ void migrate_init(MigrationState *s)
error_free(s->error);
s->error = NULL;
s->hostname = NULL;
+ s->vmdesc = NULL;
migrate_set_state(&s->state, MIGRATION_STATUS_NONE, MIGRATION_STATUS_SETUP);
@@ -4269,6 +4272,8 @@ void migrate_fd_connect(MigrationState *s, Error *error_in)
return;
}
+ s->vmdesc = json_writer_new(false);
+
if (multifd_save_setup(&local_err) != 0) {
error_report_err(local_err);
migrate_set_state(&s->state, MIGRATION_STATUS_SETUP,
@@ -17,6 +17,7 @@
#include "exec/cpu-common.h"
#include "hw/qdev-core.h"
#include "qapi/qapi-types-migration.h"
+#include "qapi/qmp/json-writer.h"
#include "qemu/thread.h"
#include "qemu/coroutine_int.h"
#include "io/channel.h"
@@ -261,6 +262,8 @@ struct MigrationState {
int state;
+ JSONWriter *vmdesc;
+
/* State related to return path */
struct {
/* Protected by qemu_file_lock */
@@ -1137,13 +1137,18 @@ void qemu_savevm_non_migratable_list(strList **reasons)
void qemu_savevm_state_header(QEMUFile *f)
{
+ MigrationState *s = migrate_get_current();
trace_savevm_state_header();
qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
qemu_put_be32(f, QEMU_VM_FILE_VERSION);
- if (migrate_get_current()->send_configuration) {
+ if (s->send_configuration) {
qemu_put_byte(f, QEMU_VM_CONFIGURATION);
- vmstate_save_state(f, &vmstate_configuration, &savevm_state, 0);
+ json_writer_start_object(s->vmdesc, NULL);
+ json_writer_start_object(s->vmdesc, "configuration");
+ vmstate_save_state(f, &vmstate_configuration, &savevm_state, s->vmdesc);
+ json_writer_end_object(s->vmdesc);
+
}
}
@@ -1364,15 +1369,16 @@ int qemu_savevm_state_complete_precopy_non_iterable(QEMUFile *f,
bool in_postcopy,
bool inactivate_disks)
{
- g_autoptr(JSONWriter) vmdesc = NULL;
+ MigrationState *s = migrate_get_current();
int vmdesc_len;
SaveStateEntry *se;
int ret;
- vmdesc = json_writer_new(false);
- json_writer_start_object(vmdesc, NULL);
- json_writer_int64(vmdesc, "page_size", qemu_target_page_size());
- json_writer_start_array(vmdesc, "devices");
+ if (!s->send_configuration) {
+ json_writer_start_object(s->vmdesc, NULL);
+ }
+ json_writer_int64(s->vmdesc, "page_size", qemu_target_page_size());
+ json_writer_start_array(s->vmdesc, "devices");
QTAILQ_FOREACH(se, &savevm_state.handlers, entry) {
if ((!se->ops || !se->ops->save_state) && !se->vmsd) {
@@ -1385,12 +1391,12 @@ int qemu_savevm_state_complete_precopy_non_iterable(QEMUFile *f,
trace_savevm_section_start(se->idstr, se->section_id);
- json_writer_start_object(vmdesc, NULL);
- json_writer_str(vmdesc, "name", se->idstr);
- json_writer_int64(vmdesc, "instance_id", se->instance_id);
+ json_writer_start_object(s->vmdesc, NULL);
+ json_writer_str(s->vmdesc, "name", se->idstr);
+ json_writer_int64(s->vmdesc, "instance_id", se->instance_id);
save_section_header(f, se, QEMU_VM_SECTION_FULL);
- ret = vmstate_save(f, se, vmdesc);
+ ret = vmstate_save(f, se, s->vmdesc);
if (ret) {
qemu_file_set_error(f, ret);
return ret;
@@ -1398,7 +1404,7 @@ int qemu_savevm_state_complete_precopy_non_iterable(QEMUFile *f,
trace_savevm_section_end(se->idstr, se->section_id, 0);
save_section_footer(f, se);
- json_writer_end_object(vmdesc);
+ json_writer_end_object(s->vmdesc);
}
if (inactivate_disks) {
@@ -1417,14 +1423,14 @@ int qemu_savevm_state_complete_precopy_non_iterable(QEMUFile *f,
qemu_put_byte(f, QEMU_VM_EOF);
}
- json_writer_end_array(vmdesc);
- json_writer_end_object(vmdesc);
- vmdesc_len = strlen(json_writer_get(vmdesc));
+ json_writer_end_array(s->vmdesc);
+ json_writer_end_object(s->vmdesc);
+ vmdesc_len = strlen(json_writer_get(s->vmdesc));
if (should_send_vmdesc()) {
qemu_put_byte(f, QEMU_VM_VMDESCRIPTION);
qemu_put_be32(f, vmdesc_len);
- qemu_put_buffer(f, (uint8_t *)json_writer_get(vmdesc), vmdesc_len);
+ qemu_put_buffer(f, (uint8_t *)json_writer_get(s->vmdesc), vmdesc_len);
}
return 0;
This is required so that migration stream configuration is written to the migration stream. This would allow analyze-migration to parse enabled capabilities for the migration and adjust its behavior accordingly. This is in preparation for analyze-migration.py to support 'fixed-ram' capability format changes. Signed-off-by: Nikolay Borisov <nborisov@suse.com> --- migration/migration.c | 5 +++++ migration/migration.h | 3 +++ migration/savevm.c | 38 ++++++++++++++++++++++---------------- 3 files changed, 30 insertions(+), 16 deletions(-)