qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH v2 10/14] vmstate: use new JSON output visitor


From: Eric Blake
Subject: [Qemu-devel] [PATCH v2 10/14] vmstate: use new JSON output visitor
Date: Mon, 21 Dec 2015 17:31:04 -0700

Rather than using a QJSON object and converting the QString result
to a char *, we can use the new JSON output visitor and get directly
to a char *.

The conversions are a bit tricky in place (in places, we have to
copy an integer to an int64_t temporary to get the right pointer for
visit_type_int(); and for several strings, we have to copy to a
temporary variable so we can take an address (&char[] is not the
same as &char*) and cast away const), but overall still fairly
mechanical.

Suggested-by: Paolo Bonzini <address@hidden>
Signed-off-by: Eric Blake <address@hidden>

---
v2: new patch

This is part of alternative 2, along with patch 11.  See also patch 8
for alternative 1.
---
 include/migration/vmstate.h |  4 +--
 migration/savevm.c          | 66 ++++++++++++++++++++++++++++-----------------
 migration/vmstate.c         | 63 ++++++++++++++++++++++++++-----------------
 tests/Makefile              |  2 +-
 4 files changed, 84 insertions(+), 51 deletions(-)

diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
index 7267e38..101742e 100644
--- a/include/migration/vmstate.h
+++ b/include/migration/vmstate.h
@@ -29,7 +29,7 @@
 #ifndef CONFIG_USER_ONLY
 #include <migration/qemu-file.h>
 #endif
-#include <qjson.h>
+#include "qapi/json-output-visitor.h"

 typedef void SaveStateHandler(QEMUFile *f, void *opaque);
 typedef int LoadStateHandler(QEMUFile *f, void *opaque, int version_id);
@@ -814,7 +814,7 @@ void loadvm_free_handlers(MigrationIncomingState *mis);
 int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
                        void *opaque, int version_id);
 void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
-                        void *opaque, QJSON *vmdesc);
+                        void *opaque, Visitor *vmdesc);

 bool vmstate_save_needed(const VMStateDescription *vmsd, void *opaque);

diff --git a/migration/savevm.c b/migration/savevm.c
index 0ad1b93..a739b8b 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -646,27 +646,32 @@ static int vmstate_load(QEMUFile *f, SaveStateEntry *se, 
int version_id)
     return vmstate_load_state(f, se->vmsd, se->opaque, version_id);
 }

-static void vmstate_save_old_style(QEMUFile *f, SaveStateEntry *se, QJSON 
*vmdesc)
+static void vmstate_save_old_style(QEMUFile *f, SaveStateEntry *se,
+                                   Visitor *vmdesc)
 {
     int64_t old_offset, size;
+    const char *tmp;

     old_offset = qemu_ftell_fast(f);
     se->ops->save_state(f, se->opaque);
     size = qemu_ftell_fast(f) - old_offset;

     if (vmdesc) {
-        json_prop_int(vmdesc, "size", size);
-        json_start_array(vmdesc, "fields");
-        json_start_object(vmdesc, NULL);
-        json_prop_str(vmdesc, "name", "data");
-        json_prop_int(vmdesc, "size", size);
-        json_prop_str(vmdesc, "type", "buffer");
-        json_end_object(vmdesc);
-        json_end_array(vmdesc);
+        visit_type_int(vmdesc, "size", &size, &error_abort);
+        visit_start_list(vmdesc, "fields", NULL, 0, &error_abort);
+        visit_start_struct(vmdesc, NULL, NULL, 0, &error_abort);
+        tmp = "data";
+        visit_type_str(vmdesc, "name", (char **)&tmp, &error_abort);
+        visit_type_int(vmdesc, "size", &size, &error_abort);
+        tmp = "buffer";
+        visit_type_str(vmdesc, "type", (char **)&tmp, &error_abort);
+        visit_check_struct(vmdesc, &error_abort);
+        visit_end_struct(vmdesc);
+        visit_end_list(vmdesc);
     }
 }

-static void vmstate_save(QEMUFile *f, SaveStateEntry *se, QJSON *vmdesc)
+static void vmstate_save(QEMUFile *f, SaveStateEntry *se, Visitor *vmdesc)
 {
     trace_vmstate_save(se->idstr, se->vmsd ? se->vmsd->name : "(old)");
     if (!se->vmsd) {
@@ -886,7 +891,7 @@ void qemu_savevm_state_header(QEMUFile *f)

     if (!savevm_state.skip_configuration) {
         qemu_put_byte(f, QEMU_VM_CONFIGURATION);
-        vmstate_save_state(f, &vmstate_configuration, &savevm_state, 0);
+        vmstate_save_state(f, &vmstate_configuration, &savevm_state, NULL);
     }

 }
@@ -1028,11 +1033,15 @@ void qemu_savevm_state_complete_postcopy(QEMUFile *f)

 void qemu_savevm_state_complete_precopy(QEMUFile *f, bool iterable_only)
 {
-    QJSON *vmdesc;
+    JsonOutputVisitor *vmdesc_jov;
+    Visitor *vmdesc;
+    char *vmdesc_str;
     int vmdesc_len;
     SaveStateEntry *se;
     int ret;
     bool in_postcopy = migration_in_postcopy(migrate_get_current());
+    int64_t tmp_i;
+    char *tmp_s;

     trace_savevm_state_complete_precopy();

@@ -1068,9 +1077,12 @@ void qemu_savevm_state_complete_precopy(QEMUFile *f, 
bool iterable_only)
         return;
     }

-    vmdesc = qjson_new();
-    json_prop_int(vmdesc, "page_size", TARGET_PAGE_SIZE);
-    json_start_array(vmdesc, "devices");
+    vmdesc_jov = json_output_visitor_new();
+    vmdesc = json_output_get_visitor(vmdesc_jov);
+    visit_start_struct(vmdesc, NULL, NULL, 0, &error_abort);
+    tmp_i = TARGET_PAGE_SIZE;
+    visit_type_int(vmdesc, "page_size", &tmp_i, &error_abort);
+    visit_start_list(vmdesc, "devices", NULL, 0, &error_abort);
     QTAILQ_FOREACH(se, &savevm_state.handlers, entry) {

         if ((!se->ops || !se->ops->save_state) && !se->vmsd) {
@@ -1083,15 +1095,18 @@ void qemu_savevm_state_complete_precopy(QEMUFile *f, 
bool iterable_only)

         trace_savevm_section_start(se->idstr, se->section_id);

-        json_start_object(vmdesc, NULL);
-        json_prop_str(vmdesc, "name", se->idstr);
-        json_prop_int(vmdesc, "instance_id", se->instance_id);
+        visit_start_struct(vmdesc, NULL, NULL, 0, &error_abort);
+        tmp_s = se->idstr;
+        visit_type_str(vmdesc, "name", &tmp_s, &error_abort);
+        tmp_i = se->instance_id;
+        visit_type_int(vmdesc, "instance_id", &tmp_i, &error_abort);

         save_section_header(f, se, QEMU_VM_SECTION_FULL);

         vmstate_save(f, se, vmdesc);

-        json_end_object(vmdesc);
+        visit_check_struct(vmdesc, &error_abort);
+        visit_end_struct(vmdesc);
         trace_savevm_section_end(se->idstr, se->section_id, 0);
         save_section_footer(f, se);
     }
@@ -1101,16 +1116,19 @@ void qemu_savevm_state_complete_precopy(QEMUFile *f, 
bool iterable_only)
         qemu_put_byte(f, QEMU_VM_EOF);
     }

-    json_end_array(vmdesc);
-    qjson_finish(vmdesc);
-    vmdesc_len = strlen(qjson_get_str(vmdesc));
+    visit_end_list(vmdesc);
+    visit_check_struct(vmdesc, &error_abort);
+    visit_end_struct(vmdesc);
+    vmdesc_str = json_output_get_string(vmdesc_jov);
+    vmdesc_len = strlen(vmdesc_str);

     if (should_send_vmdesc()) {
         qemu_put_byte(f, QEMU_VM_VMDESCRIPTION);
         qemu_put_be32(f, vmdesc_len);
-        qemu_put_buffer(f, (uint8_t *)qjson_get_str(vmdesc), vmdesc_len);
+        qemu_put_buffer(f, (uint8_t *)vmdesc_str, vmdesc_len);
     }
-    object_unref(OBJECT(vmdesc));
+    g_free(vmdesc_str);
+    json_output_visitor_cleanup(vmdesc_jov);

     qemu_fflush(f);
 }
diff --git a/migration/vmstate.c b/migration/vmstate.c
index e8ccf22..9491171 100644
--- a/migration/vmstate.c
+++ b/migration/vmstate.c
@@ -5,10 +5,9 @@
 #include "qemu/bitops.h"
 #include "qemu/error-report.h"
 #include "trace.h"
-#include "qjson.h"

 static void vmstate_subsection_save(QEMUFile *f, const VMStateDescription 
*vmsd,
-                                    void *opaque, QJSON *vmdesc);
+                                    void *opaque, Visitor *vmdesc);
 static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd,
                                    void *opaque);

@@ -221,12 +220,15 @@ static bool vmsd_can_compress(VMStateField *field)
     return true;
 }

-static void vmsd_desc_field_start(const VMStateDescription *vmsd, QJSON 
*vmdesc,
+static void vmsd_desc_field_start(const VMStateDescription *vmsd,
+                                  Visitor *vmdesc,
                                   VMStateField *field, int i, int max)
 {
     char *name, *old_name;
     bool is_array = max > 1;
     bool can_compress = vmsd_can_compress(field);
+    int64_t tmp;
+    const char *type;

     if (!vmdesc) {
         return;
@@ -242,38 +244,47 @@ 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);
+    visit_start_struct(vmdesc, NULL, NULL, 0, &error_abort);
+    visit_type_str(vmdesc, "name", &name, &error_abort);
     if (is_array) {
         if (can_compress) {
-            json_prop_int(vmdesc, "array_len", max);
+            tmp = max;
+            visit_type_int(vmdesc, "array_len", &tmp, &error_abort);
         } else {
-            json_prop_int(vmdesc, "index", i);
+            tmp = i;
+            visit_type_int(vmdesc, "index", &tmp, &error_abort);
         }
     }
-    json_prop_str(vmdesc, "type", vmfield_get_type_name(field));
+    type = vmfield_get_type_name(field);
+    visit_type_str(vmdesc, "type", (char **)&type, &error_abort);

     if (field->flags & VMS_STRUCT) {
-        json_start_object(vmdesc, "struct");
+        visit_start_struct(vmdesc, "struct", NULL, 0, &error_abort);
     }

     g_free(name);
 }

-static void vmsd_desc_field_end(const VMStateDescription *vmsd, QJSON *vmdesc,
+static void vmsd_desc_field_end(const VMStateDescription *vmsd,
+                                Visitor *vmdesc,
                                 VMStateField *field, size_t size, int i)
 {
+    int64_t tmp;
+
     if (!vmdesc) {
         return;
     }

     if (field->flags & VMS_STRUCT) {
         /* We printed a struct in between, close its child object */
-        json_end_object(vmdesc);
+        visit_check_struct(vmdesc, &error_abort);
+        visit_end_struct(vmdesc);
     }

-    json_prop_int(vmdesc, "size", size);
-    json_end_object(vmdesc);
+    tmp = size;
+    visit_type_int(vmdesc, "size", &tmp, &error_abort);
+    visit_check_struct(vmdesc, &error_abort);
+    visit_end_struct(vmdesc);
 }


@@ -288,7 +299,7 @@ bool vmstate_save_needed(const VMStateDescription *vmsd, 
void *opaque)


 void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
-                        void *opaque, QJSON *vmdesc)
+                        void *opaque, Visitor *vmdesc)
 {
     VMStateField *field = vmsd->fields;

@@ -297,9 +308,11 @@ void vmstate_save_state(QEMUFile *f, const 
VMStateDescription *vmsd,
     }

     if (vmdesc) {
-        json_prop_str(vmdesc, "vmsd_name", vmsd->name);
-        json_prop_int(vmdesc, "version", vmsd->version_id);
-        json_start_array(vmdesc, "fields");
+        const char *tmp_s = vmsd->name;
+        int64_t tmp_i = vmsd->version_id;
+        visit_type_str(vmdesc, "vmsd_name", (char **)&tmp_s, &error_abort);
+        visit_type_int(vmdesc, "version", &tmp_i, &error_abort);
+        visit_start_list(vmdesc, "fields", NULL, 0, &error_abort);
     }

     while (field->name) {
@@ -309,7 +322,7 @@ void vmstate_save_state(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;
+            Visitor *vmdesc_loop = vmdesc;

             for (i = 0; i < n_elems; i++) {
                 void *addr = base_addr + size * i;
@@ -345,7 +358,7 @@ void vmstate_save_state(QEMUFile *f, const 
VMStateDescription *vmsd,
     }

     if (vmdesc) {
-        json_end_array(vmdesc);
+        visit_end_list(vmdesc);
     }

     vmstate_subsection_save(f, vmsd, opaque, vmdesc);
@@ -415,7 +428,7 @@ static int vmstate_subsection_load(QEMUFile *f, const 
VMStateDescription *vmsd,
 }

 static void vmstate_subsection_save(QEMUFile *f, const VMStateDescription 
*vmsd,
-                                    void *opaque, QJSON *vmdesc)
+                                    void *opaque, Visitor *vmdesc)
 {
     const VMStateDescription **sub = vmsd->subsections;
     bool subsection_found = false;
@@ -428,11 +441,12 @@ static void vmstate_subsection_save(QEMUFile *f, const 
VMStateDescription *vmsd,
             if (vmdesc) {
                 /* Only create subsection array when we have any */
                 if (!subsection_found) {
-                    json_start_array(vmdesc, "subsections");
+                    visit_start_list(vmdesc, "subsections", NULL, 0,
+                                     &error_abort);
                     subsection_found = true;
                 }

-                json_start_object(vmdesc, NULL);
+                visit_start_struct(vmdesc, NULL, NULL, 0, &error_abort);
             }

             qemu_put_byte(f, QEMU_VM_SUBSECTION);
@@ -443,14 +457,15 @@ static void vmstate_subsection_save(QEMUFile *f, const 
VMStateDescription *vmsd,
             vmstate_save_state(f, vmsd, opaque, vmdesc);

             if (vmdesc) {
-                json_end_object(vmdesc);
+                visit_check_struct(vmdesc, &error_abort);
+                visit_end_struct(vmdesc);
             }
         }
         sub++;
     }

     if (vmdesc && subsection_found) {
-        json_end_array(vmdesc);
+        visit_end_list(vmdesc);
     }
 }

diff --git a/tests/Makefile b/tests/Makefile
index 19a9ee0..e363720 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -424,7 +424,7 @@ tests/test-qdev-global-props$(EXESUF): 
tests/test-qdev-global-props.o \
        $(test-qapi-obj-y)
 tests/test-vmstate$(EXESUF): tests/test-vmstate.o \
        migration/vmstate.o migration/qemu-file.o migration/qemu-file-buf.o \
-        migration/qemu-file-unix.o qjson.o \
+        migration/qemu-file-unix.o qapi/json-output-visitor.o \
        $(test-qom-obj-y)
 tests/test-timed-average$(EXESUF): tests/test-timed-average.o qemu-timer.o \
        $(test-util-obj-y)
-- 
2.4.3




reply via email to

[Prev in Thread] Current Thread [Next in Thread]