migration: Replace migration's JSON writer by the general one

Commit 8118f0950f "migration: Append JSON description of migration
stream" needs a JSON writer.  The existing qobject_to_json() wasn't a
good fit, because it requires building a QObject to convert.  Instead,
migration got its very own JSON writer, in commit 190c882ce2 "QJSON:
Add JSON writer".  It tacitly limits numbers to int64_t, and strings
contents to characters that don't need escaping, unlike
qobject_to_json().

The previous commit factored the JSON writer out of qobject_to_json().
Replace migration's JSON writer by it.

Cc: Juan Quintela <quintela@redhat.com>
Cc: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <20201211171152.146877-17-armbru@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
This commit is contained in:
Markus Armbruster 2020-12-11 18:11:48 +01:00
parent 998da0b158
commit 3ddba9a9e9
29 changed files with 114 additions and 253 deletions

View file

@ -14,14 +14,14 @@
#include "migration.h"
#include "migration/vmstate.h"
#include "savevm.h"
#include "qapi/qmp/json-writer.h"
#include "qemu-file.h"
#include "qemu/bitops.h"
#include "qemu/error-report.h"
#include "trace.h"
#include "qjson.h"
static int vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd,
void *opaque, QJSON *vmdesc);
void *opaque, JSONWriter *vmdesc);
static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd,
void *opaque);
@ -249,7 +249,8 @@ static bool vmsd_can_compress(const VMStateField *field)
return true;
}
static void vmsd_desc_field_start(const VMStateDescription *vmsd, QJSON *vmdesc,
static void vmsd_desc_field_start(const VMStateDescription *vmsd,
JSONWriter *vmdesc,
const VMStateField *field, int i, int max)
{
char *name, *old_name;
@ -270,25 +271,26 @@ static void vmsd_desc_field_start(const VMStateDescription *vmsd, QJSON *vmdesc,
g_free(old_name);
}
json_start_object(vmdesc, NULL);
json_prop_str(vmdesc, "name", name);
json_writer_start_object(vmdesc, NULL);
json_writer_str(vmdesc, "name", name);
if (is_array) {
if (can_compress) {
json_prop_int(vmdesc, "array_len", max);
json_writer_int64(vmdesc, "array_len", max);
} else {
json_prop_int(vmdesc, "index", i);
json_writer_int64(vmdesc, "index", i);
}
}
json_prop_str(vmdesc, "type", vmfield_get_type_name(field));
json_writer_str(vmdesc, "type", vmfield_get_type_name(field));
if (field->flags & VMS_STRUCT) {
json_start_object(vmdesc, "struct");
json_writer_start_object(vmdesc, "struct");
}
g_free(name);
}
static void vmsd_desc_field_end(const VMStateDescription *vmsd, QJSON *vmdesc,
static void vmsd_desc_field_end(const VMStateDescription *vmsd,
JSONWriter *vmdesc,
const VMStateField *field, size_t size, int i)
{
if (!vmdesc) {
@ -297,11 +299,11 @@ static void vmsd_desc_field_end(const VMStateDescription *vmsd, QJSON *vmdesc,
if (field->flags & VMS_STRUCT) {
/* We printed a struct in between, close its child object */
json_end_object(vmdesc);
json_writer_end_object(vmdesc);
}
json_prop_int(vmdesc, "size", size);
json_end_object(vmdesc);
json_writer_int64(vmdesc, "size", size);
json_writer_end_object(vmdesc);
}
@ -316,13 +318,13 @@ bool vmstate_save_needed(const VMStateDescription *vmsd, void *opaque)
int vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
void *opaque, QJSON *vmdesc_id)
void *opaque, JSONWriter *vmdesc_id)
{
return vmstate_save_state_v(f, vmsd, opaque, vmdesc_id, vmsd->version_id);
}
int vmstate_save_state_v(QEMUFile *f, const VMStateDescription *vmsd,
void *opaque, QJSON *vmdesc, int version_id)
void *opaque, JSONWriter *vmdesc, int version_id)
{
int ret = 0;
const VMStateField *field = vmsd->fields;
@ -339,9 +341,9 @@ int vmstate_save_state_v(QEMUFile *f, const VMStateDescription *vmsd,
}
if (vmdesc) {
json_prop_str(vmdesc, "vmsd_name", vmsd->name);
json_prop_int(vmdesc, "version", version_id);
json_start_array(vmdesc, "fields");
json_writer_str(vmdesc, "vmsd_name", vmsd->name);
json_writer_int64(vmdesc, "version", version_id);
json_writer_start_array(vmdesc, "fields");
}
while (field->name) {
@ -353,7 +355,7 @@ int vmstate_save_state_v(QEMUFile *f, const VMStateDescription *vmsd,
int i, n_elems = vmstate_n_elems(opaque, field);
int size = vmstate_size(opaque, field);
int64_t old_offset, written_bytes;
QJSON *vmdesc_loop = vmdesc;
JSONWriter *vmdesc_loop = vmdesc;
trace_vmstate_save_state_loop(vmsd->name, field->name, n_elems);
if (field->flags & VMS_POINTER) {
@ -413,7 +415,7 @@ int vmstate_save_state_v(QEMUFile *f, const VMStateDescription *vmsd,
}
if (vmdesc) {
json_end_array(vmdesc);
json_writer_end_array(vmdesc);
}
ret = vmstate_subsection_save(f, vmsd, opaque, vmdesc);
@ -491,7 +493,7 @@ static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd,
}
static int vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd,
void *opaque, QJSON *vmdesc)
void *opaque, JSONWriter *vmdesc)
{
const VMStateDescription **sub = vmsd->subsections;
bool vmdesc_has_subsections = false;
@ -507,11 +509,11 @@ static int vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd,
if (vmdesc) {
/* Only create subsection array when we have any */
if (!vmdesc_has_subsections) {
json_start_array(vmdesc, "subsections");
json_writer_start_array(vmdesc, "subsections");
vmdesc_has_subsections = true;
}
json_start_object(vmdesc, NULL);
json_writer_start_object(vmdesc, NULL);
}
qemu_put_byte(f, QEMU_VM_SUBSECTION);
@ -525,14 +527,14 @@ static int vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd,
}
if (vmdesc) {
json_end_object(vmdesc);
json_writer_end_object(vmdesc);
}
}
sub++;
}
if (vmdesc_has_subsections) {
json_end_array(vmdesc);
json_writer_end_array(vmdesc);
}
return ret;