migration: introduce decompress-error-check
authorXiao Guangrong <xiaoguangrong@tencent.com>
Thu, 3 May 2018 08:06:11 +0000 (16:06 +0800)
committerJuan Quintela <quintela@redhat.com>
Mon, 4 Jun 2018 03:46:15 +0000 (05:46 +0200)
QEMU 3.0 enables strict check for compression & decompression to
make the migration more robust, that depends on the source to fix
the internal design which triggers the unexpected error conditions

To make it work for migrating old version QEMU to 2.13 QEMU, we
introduce this parameter to disable the error check on the
destination which is the default behavior of the machine type
which is older than 2.13, alternately, the strict check can be
enabled explicitly as followings:
      -M pc-q35-2.11 -global migration.decompress-error-check=true

Signed-off-by: Xiao Guangrong <xiaoguangrong@tencent.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
hw/arm/virt.c
hw/i386/pc_piix.c
hw/i386/pc_q35.c
include/hw/compat.h
migration/migration.c
migration/migration.h
migration/ram.c

index a3a28e20e8cb92d0c9a5127020d076eb3ae5ea37..b2a67a4c00d50b97a65bd5449f7e2c540b95847d 100644 (file)
@@ -1693,6 +1693,9 @@ static void machvirt_machine_init(void)
 }
 type_init(machvirt_machine_init);
 
+#define VIRT_COMPAT_2_12 \
+    HW_COMPAT_2_12
+
 static void virt_2_12_instance_init(Object *obj)
 {
     VirtMachineState *vms = VIRT_MACHINE(obj);
@@ -1763,6 +1766,7 @@ static void virt_2_12_instance_init(Object *obj)
 
 static void virt_machine_2_12_options(MachineClass *mc)
 {
+    SET_MACHINE_COMPAT(mc, VIRT_COMPAT_2_12);
 }
 DEFINE_VIRT_MACHINE_AS_LATEST(2, 12)
 
index b4c5b032747b78554a341a701c4e41d674c796dd..3d811360659e4f03e106cdda6eaac0106d6eed7d 100644 (file)
@@ -430,6 +430,7 @@ static void pc_i440fx_3_0_machine_options(MachineClass *m)
     pc_i440fx_machine_options(m);
     m->alias = "pc";
     m->is_default = 1;
+    SET_MACHINE_COMPAT(m, PC_COMPAT_2_12);
 }
 
 DEFINE_I440FX_MACHINE(v3_0, "pc-i440fx-3.0", NULL,
index 83d6d75efa82c364c1ebaa83c7da02c46897824b..b60cbb9266475cfb184f0331b83bf54eddc4b304 100644 (file)
@@ -312,6 +312,7 @@ static void pc_q35_3_0_machine_options(MachineClass *m)
 {
     pc_q35_machine_options(m);
     m->alias = "q35";
+    SET_MACHINE_COMPAT(m, PC_COMPAT_2_12);
 }
 
 DEFINE_Q35_MACHINE(v3_0, "pc-q35-3.0", NULL,
index 4681c2719a471de26ca0d429d399cb133f726a14..563908b874c93483a124bcff71dba89089788c24 100644 (file)
@@ -1,7 +1,12 @@
 #ifndef HW_COMPAT_H
 #define HW_COMPAT_H
 
-#define HW_COMPAT_2_12
+#define HW_COMPAT_2_12 \
+    {\
+        .driver   = "migration",\
+        .property = "decompress-error-check",\
+        .value    = "off",\
+    },
 
 #define HW_COMPAT_2_11 \
     {\
index 05aec2c9050039038c99bcb28b99c3f6e66fad40..a5384865ff02f2b269b4e7c1f1b2832e9dfde8da 100644 (file)
@@ -2971,6 +2971,8 @@ void migration_global_dump(Monitor *mon)
                    ms->send_configuration ? "on" : "off");
     monitor_printf(mon, "send-section-footer: %s\n",
                    ms->send_section_footer ? "on" : "off");
+    monitor_printf(mon, "decompress-error-check: %s\n",
+                   ms->decompress_error_check ? "on" : "off");
 }
 
 #define DEFINE_PROP_MIG_CAP(name, x)             \
@@ -2984,6 +2986,8 @@ static Property migration_properties[] = {
                      send_configuration, true),
     DEFINE_PROP_BOOL("send-section-footer", MigrationState,
                      send_section_footer, true),
+    DEFINE_PROP_BOOL("decompress-error-check", MigrationState,
+                      decompress_error_check, true),
 
     /* Migration parameters */
     DEFINE_PROP_UINT8("x-compress-level", MigrationState,
index 8f0c82159b2e5b74ca1af42584a2202d359643d6..5af57d616cf98b550340a53cfdde208ab23674c3 100644 (file)
@@ -212,6 +212,13 @@ struct MigrationState
     /* Needed by postcopy-pause state */
     QemuSemaphore postcopy_pause_sem;
     QemuSemaphore postcopy_pause_rp_sem;
+    /*
+     * Whether we abort the migration if decompression errors are
+     * detected at the destination. It is left at false for qemu
+     * older than 3.0, since only newer qemu sends streams that
+     * do not trigger spurious decompression errors.
+     */
+    bool decompress_error_check;
 };
 
 void migrate_set_state(int *state, int old_state, int new_state);
index c53e8369a3b430db6f2e953941e20e2a3ce4ab8f..090187ca048f61498fe1df2893e994162c2c82b1 100644 (file)
@@ -2881,7 +2881,7 @@ static void *do_data_decompress(void *opaque)
 
             ret = qemu_uncompress_data(&param->stream, des, pagesize,
                                        param->compbuf, len);
-            if (ret < 0) {
+            if (ret < 0 && migrate_get_current()->decompress_error_check) {
                 error_report("decompress data failed");
                 qemu_file_set_error(decomp_file, ret);
             }