summary refs log tree commit diff stats
path: root/migration
diff options
context:
space:
mode:
Diffstat (limited to 'migration')
-rw-r--r--migration/Makefile.objs1
-rw-r--r--migration/migration.c94
-rw-r--r--migration/qjson.c113
-rw-r--r--migration/ram.c4
-rw-r--r--migration/savevm.c4
-rw-r--r--migration/vmstate.c1
6 files changed, 176 insertions, 41 deletions
diff --git a/migration/Makefile.objs b/migration/Makefile.objs
index 0cac6d707a..d25ff483eb 100644
--- a/migration/Makefile.objs
+++ b/migration/Makefile.objs
@@ -2,6 +2,7 @@ common-obj-y += migration.o tcp.o
 common-obj-y += vmstate.o
 common-obj-y += qemu-file.o qemu-file-buf.o qemu-file-unix.o qemu-file-stdio.o
 common-obj-y += xbzrle.o postcopy-ram.o
+common-obj-y += qjson.o
 
 common-obj-$(CONFIG_RDMA) += rdma.o
 common-obj-$(CONFIG_POSIX) += exec.o unix.o fd.o
diff --git a/migration/migration.c b/migration/migration.c
index c08d9a69b0..f5327e8c0a 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -50,8 +50,8 @@
 /*0: means nocompress, 1: best speed, ... 9: best compress ratio */
 #define DEFAULT_MIGRATE_COMPRESS_LEVEL 1
 /* Define default autoconverge cpu throttle migration parameters */
-#define DEFAULT_MIGRATE_X_CPU_THROTTLE_INITIAL 20
-#define DEFAULT_MIGRATE_X_CPU_THROTTLE_INCREMENT 10
+#define DEFAULT_MIGRATE_CPU_THROTTLE_INITIAL 20
+#define DEFAULT_MIGRATE_CPU_THROTTLE_INCREMENT 10
 
 /* Migration XBZRLE default cache size */
 #define DEFAULT_MIGRATE_CACHE_SIZE (64 * 1024 * 1024)
@@ -87,10 +87,10 @@ MigrationState *migrate_get_current(void)
                 DEFAULT_MIGRATE_COMPRESS_THREAD_COUNT,
         .parameters[MIGRATION_PARAMETER_DECOMPRESS_THREADS] =
                 DEFAULT_MIGRATE_DECOMPRESS_THREAD_COUNT,
-        .parameters[MIGRATION_PARAMETER_X_CPU_THROTTLE_INITIAL] =
-                DEFAULT_MIGRATE_X_CPU_THROTTLE_INITIAL,
-        .parameters[MIGRATION_PARAMETER_X_CPU_THROTTLE_INCREMENT] =
-                DEFAULT_MIGRATE_X_CPU_THROTTLE_INCREMENT,
+        .parameters[MIGRATION_PARAMETER_CPU_THROTTLE_INITIAL] =
+                DEFAULT_MIGRATE_CPU_THROTTLE_INITIAL,
+        .parameters[MIGRATION_PARAMETER_CPU_THROTTLE_INCREMENT] =
+                DEFAULT_MIGRATE_CPU_THROTTLE_INCREMENT,
     };
 
     if (!once) {
@@ -521,10 +521,10 @@ MigrationParameters *qmp_query_migrate_parameters(Error **errp)
             s->parameters[MIGRATION_PARAMETER_COMPRESS_THREADS];
     params->decompress_threads =
             s->parameters[MIGRATION_PARAMETER_DECOMPRESS_THREADS];
-    params->x_cpu_throttle_initial =
-            s->parameters[MIGRATION_PARAMETER_X_CPU_THROTTLE_INITIAL];
-    params->x_cpu_throttle_increment =
-            s->parameters[MIGRATION_PARAMETER_X_CPU_THROTTLE_INCREMENT];
+    params->cpu_throttle_initial =
+            s->parameters[MIGRATION_PARAMETER_CPU_THROTTLE_INITIAL];
+    params->cpu_throttle_increment =
+            s->parameters[MIGRATION_PARAMETER_CPU_THROTTLE_INCREMENT];
 
     return params;
 }
@@ -607,8 +607,8 @@ MigrationInfo *qmp_query_migrate(Error **errp)
         }
 
         if (cpu_throttle_active()) {
-            info->has_x_cpu_throttle_percentage = true;
-            info->x_cpu_throttle_percentage = cpu_throttle_get_percentage();
+            info->has_cpu_throttle_percentage = true;
+            info->cpu_throttle_percentage = cpu_throttle_get_percentage();
         }
 
         get_xbzrle_cache_stats(info);
@@ -718,10 +718,10 @@ void qmp_migrate_set_parameters(bool has_compress_level,
                                 int64_t compress_threads,
                                 bool has_decompress_threads,
                                 int64_t decompress_threads,
-                                bool has_x_cpu_throttle_initial,
-                                int64_t x_cpu_throttle_initial,
-                                bool has_x_cpu_throttle_increment,
-                                int64_t x_cpu_throttle_increment, Error **errp)
+                                bool has_cpu_throttle_initial,
+                                int64_t cpu_throttle_initial,
+                                bool has_cpu_throttle_increment,
+                                int64_t cpu_throttle_increment, Error **errp)
 {
     MigrationState *s = migrate_get_current();
 
@@ -744,16 +744,16 @@ void qmp_migrate_set_parameters(bool has_compress_level,
                    "is invalid, it should be in the range of 1 to 255");
         return;
     }
-    if (has_x_cpu_throttle_initial &&
-            (x_cpu_throttle_initial < 1 || x_cpu_throttle_initial > 99)) {
+    if (has_cpu_throttle_initial &&
+            (cpu_throttle_initial < 1 || cpu_throttle_initial > 99)) {
         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
-                   "x_cpu_throttle_initial",
+                   "cpu_throttle_initial",
                    "an integer in the range of 1 to 99");
     }
-    if (has_x_cpu_throttle_increment &&
-            (x_cpu_throttle_increment < 1 || x_cpu_throttle_increment > 99)) {
+    if (has_cpu_throttle_increment &&
+            (cpu_throttle_increment < 1 || cpu_throttle_increment > 99)) {
         error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
-                   "x_cpu_throttle_increment",
+                   "cpu_throttle_increment",
                    "an integer in the range of 1 to 99");
     }
 
@@ -767,14 +767,14 @@ void qmp_migrate_set_parameters(bool has_compress_level,
         s->parameters[MIGRATION_PARAMETER_DECOMPRESS_THREADS] =
                                                     decompress_threads;
     }
-    if (has_x_cpu_throttle_initial) {
-        s->parameters[MIGRATION_PARAMETER_X_CPU_THROTTLE_INITIAL] =
-                                                    x_cpu_throttle_initial;
+    if (has_cpu_throttle_initial) {
+        s->parameters[MIGRATION_PARAMETER_CPU_THROTTLE_INITIAL] =
+                                                    cpu_throttle_initial;
     }
 
-    if (has_x_cpu_throttle_increment) {
-        s->parameters[MIGRATION_PARAMETER_X_CPU_THROTTLE_INCREMENT] =
-                                                    x_cpu_throttle_increment;
+    if (has_cpu_throttle_increment) {
+        s->parameters[MIGRATION_PARAMETER_CPU_THROTTLE_INCREMENT] =
+                                                    cpu_throttle_increment;
     }
 }
 
@@ -992,6 +992,20 @@ void qmp_migrate_incoming(const char *uri, Error **errp)
     once = false;
 }
 
+bool migration_is_blocked(Error **errp)
+{
+    if (qemu_savevm_state_blocked(errp)) {
+        return true;
+    }
+
+    if (migration_blockers) {
+        *errp = error_copy(migration_blockers->data);
+        return true;
+    }
+
+    return false;
+}
+
 void qmp_migrate(const char *uri, bool has_blk, bool blk,
                  bool has_inc, bool inc, bool has_detach, bool detach,
                  Error **errp)
@@ -1014,12 +1028,7 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk,
         return;
     }
 
-    if (qemu_savevm_state_blocked(errp)) {
-        return;
-    }
-
-    if (migration_blockers) {
-        *errp = error_copy(migration_blockers->data);
+    if (migration_is_blocked(errp)) {
         return;
     }
 
@@ -1597,19 +1606,32 @@ static void migration_completion(MigrationState *s, int current_active_state,
         rp_error = await_return_path_close_on_source(s);
         trace_migration_completion_postcopy_end_after_rp(rp_error);
         if (rp_error) {
-            goto fail;
+            goto fail_invalidate;
         }
     }
 
     if (qemu_file_get_error(s->to_dst_file)) {
         trace_migration_completion_file_err();
-        goto fail;
+        goto fail_invalidate;
     }
 
     migrate_set_state(&s->state, current_active_state,
                       MIGRATION_STATUS_COMPLETED);
     return;
 
+fail_invalidate:
+    /* If not doing postcopy, vm_start() will be called: let's regain
+     * control on images.
+     */
+    if (s->state == MIGRATION_STATUS_ACTIVE) {
+        Error *local_err = NULL;
+
+        bdrv_invalidate_cache_all(&local_err);
+        if (local_err) {
+            error_report_err(local_err);
+        }
+    }
+
 fail:
     migrate_set_state(&s->state, current_active_state,
                       MIGRATION_STATUS_FAILED);
diff --git a/migration/qjson.c b/migration/qjson.c
new file mode 100644
index 0000000000..5cae55af07
--- /dev/null
+++ b/migration/qjson.c
@@ -0,0 +1,113 @@
+/*
+ * A simple JSON writer
+ *
+ * Copyright Alexander Graf
+ *
+ * Authors:
+ *  Alexander Graf <agraf@suse.de>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+/*
+ * Type QJSON lets you build JSON text.  Its interface mirrors (a
+ * subset of) abstract JSON syntax.
+ *
+ * It does *not* detect incorrect use.  It happily produces invalid
+ * JSON then.  This is what migration wants.
+ *
+ * QAPI output visitors also produce JSON text.  However, they do
+ * assert their preconditions and invariants, and therefore abort on
+ * incorrect use.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/qmp/qstring.h"
+#include "migration/qjson.h"
+
+struct QJSON {
+    QString *str;
+    bool omit_comma;
+};
+
+static void json_emit_element(QJSON *json, const char *name)
+{
+    /* Check whether we need to print a , before an element */
+    if (json->omit_comma) {
+        json->omit_comma = false;
+    } else {
+        qstring_append(json->str, ", ");
+    }
+
+    if (name) {
+        qstring_append(json->str, "\"");
+        qstring_append(json->str, name);
+        qstring_append(json->str, "\" : ");
+    }
+}
+
+void json_start_object(QJSON *json, const char *name)
+{
+    json_emit_element(json, name);
+    qstring_append(json->str, "{ ");
+    json->omit_comma = true;
+}
+
+void json_end_object(QJSON *json)
+{
+    qstring_append(json->str, " }");
+    json->omit_comma = false;
+}
+
+void json_start_array(QJSON *json, const char *name)
+{
+    json_emit_element(json, name);
+    qstring_append(json->str, "[ ");
+    json->omit_comma = true;
+}
+
+void json_end_array(QJSON *json)
+{
+    qstring_append(json->str, " ]");
+    json->omit_comma = false;
+}
+
+void json_prop_int(QJSON *json, const char *name, int64_t val)
+{
+    json_emit_element(json, name);
+    qstring_append_int(json->str, val);
+}
+
+void json_prop_str(QJSON *json, const char *name, const char *str)
+{
+    json_emit_element(json, name);
+    qstring_append_chr(json->str, '"');
+    qstring_append(json->str, str);
+    qstring_append_chr(json->str, '"');
+}
+
+const char *qjson_get_str(QJSON *json)
+{
+    return qstring_get_str(json->str);
+}
+
+QJSON *qjson_new(void)
+{
+    QJSON *json = g_new0(QJSON, 1);
+
+    json->str = qstring_from_str("{ ");
+    json->omit_comma = true;
+    return json;
+}
+
+void qjson_finish(QJSON *json)
+{
+    json_end_object(json);
+}
+
+void qjson_destroy(QJSON *json)
+{
+    g_free(json);
+}
diff --git a/migration/ram.c b/migration/ram.c
index 6b6900e4c1..54e215128c 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -430,9 +430,9 @@ static void mig_throttle_guest_down(void)
 {
     MigrationState *s = migrate_get_current();
     uint64_t pct_initial =
-            s->parameters[MIGRATION_PARAMETER_X_CPU_THROTTLE_INITIAL];
+            s->parameters[MIGRATION_PARAMETER_CPU_THROTTLE_INITIAL];
     uint64_t pct_icrement =
-            s->parameters[MIGRATION_PARAMETER_X_CPU_THROTTLE_INCREMENT];
+            s->parameters[MIGRATION_PARAMETER_CPU_THROTTLE_INCREMENT];
 
     /* We have not started throttling yet. Let's start it. */
     if (!cpu_throttle_active()) {
diff --git a/migration/savevm.c b/migration/savevm.c
index 9bc362a1d3..65ce0c61a3 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -1115,7 +1115,7 @@ void qemu_savevm_state_complete_precopy(QEMUFile *f, bool iterable_only)
         qemu_put_be32(f, vmdesc_len);
         qemu_put_buffer(f, (uint8_t *)qjson_get_str(vmdesc), vmdesc_len);
     }
-    object_unref(OBJECT(vmdesc));
+    qjson_destroy(vmdesc);
 
     qemu_fflush(f);
 }
@@ -1170,7 +1170,7 @@ static int qemu_savevm_state(QEMUFile *f, Error **errp)
     MigrationState *ms = migrate_init(&params);
     ms->to_dst_file = f;
 
-    if (qemu_savevm_state_blocked(errp)) {
+    if (migration_is_blocked(errp)) {
         return -EINVAL;
     }
 
diff --git a/migration/vmstate.c b/migration/vmstate.c
index bf3d5db301..46dc55ea40 100644
--- a/migration/vmstate.c
+++ b/migration/vmstate.c
@@ -6,7 +6,6 @@
 #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);