diff mbox series

[v1,2/4] migration/debug: Implement migration memory consistency check

Message ID 1603720725-81206-3-git-send-email-zhengchuan@huawei.com (mailing list archive)
State New, archived
Headers show
Series migration/debug: Add migration ram consistency check | expand

Commit Message

Zheng Chuan Oct. 26, 2020, 1:58 p.m. UTC
Traverse all migratable ramblocks, calculate sha256 for memory consistency check

Signed-off-by: Chuan Zheng <zhengchuan@huawei.com>
---
 migration/ram.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 migration/ram.h |  7 ++++++
 2 files changed, 80 insertions(+)
diff mbox series

Patch

diff --git a/migration/ram.c b/migration/ram.c
index aa39908..f04594e 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -55,6 +55,8 @@ 
 #include "sysemu/cpu-throttle.h"
 #include "savevm.h"
 #include "qemu/iov.h"
+#include "crypto/hash.h"
+#include "qemu/typedefs.h"
 #include "multifd.h"
 
 /***********************************************************/
@@ -198,6 +200,77 @@  int foreach_not_ignored_block(RAMBlockIterFunc func, void *opaque)
     return ret;
 }
 
+#define SHA256_DIGEST_LENGTH 32
+#define SHA256_CHUNK_SIZE 0x80000000
+
+static void ram_debug_dump_sha256(uint8_t *md, const char *idstr,
+                                  const char *prefix)
+{
+    int i;
+    char buf[2 * SHA256_DIGEST_LENGTH + 1] = { 0 };
+
+    for (i = 0; i < SHA256_DIGEST_LENGTH; i++) {
+        sprintf(&buf[2 * i], "%02x", md[i]);
+    }
+
+    fprintf(stderr, "CheckPoint: %s, Ramblock: %s, CheckValue: %s\n",
+            prefix, idstr, buf);
+}
+
+static void ram_debug_calc_sha256(RAMBlock *block, const char *idstr,
+                                  const char *prefix)
+{
+    uint8_t *md = NULL;
+    size_t sha256_len;
+    size_t i, niov;
+    void *addr = NULL;
+    ram_addr_t remaining = 0;
+    size_t resultlen = 0;
+    struct iovec *iov_array = NULL;
+
+    sha256_len = qcrypto_hash_digest_len(QCRYPTO_HASH_ALG_SHA256);
+    assert(sha256_len == SHA256_DIGEST_LENGTH);
+
+    niov = DIV_ROUND_UP(qemu_ram_get_used_length(block), SHA256_CHUNK_SIZE);
+    iov_array = g_malloc0_n(niov, sizeof(struct iovec));
+
+    addr = qemu_ram_get_host_addr(block);
+    remaining = qemu_ram_get_used_length(block);
+    for (i = 0; i < niov; i++) {
+        iov_array[i].iov_base = addr;
+        iov_array[i].iov_len = MIN(SHA256_CHUNK_SIZE, remaining);
+        addr += SHA256_CHUNK_SIZE;
+        remaining -= SHA256_CHUNK_SIZE;
+    }
+
+    if (qcrypto_hash_bytesv(QCRYPTO_HASH_ALG_SHA256,
+                            iov_array, niov,
+                            &md, &resultlen, NULL) || !md) {
+        fprintf(stderr, "Consistency check(%s) calc failed.\n", prefix);
+        goto out;
+    }
+
+    ram_debug_dump_sha256(md, idstr, prefix);
+
+out:
+    g_free(iov_array);
+}
+
+static int ram_debug_consistency(RAMBlock *block, void *opaque)
+{
+    const char *prefix = opaque;
+    const char *idstr = qemu_ram_get_idstr(block);
+
+    ram_debug_calc_sha256(block, idstr, prefix);
+
+    return 0;
+}
+
+void migration_debug_ram_consistency(const char *prefix)
+{
+    foreach_migratable_block(ram_debug_consistency, (void *)prefix);
+}
+
 static void ramblock_recv_map_init(void)
 {
     RAMBlock *rb;
diff --git a/migration/ram.h b/migration/ram.h
index 011e854..d73de6e 100644
--- a/migration/ram.h
+++ b/migration/ram.h
@@ -47,6 +47,13 @@  bool ramblock_is_ignored(RAMBlock *block);
     INTERNAL_RAMBLOCK_FOREACH(block)                   \
         if (!qemu_ram_is_migratable(block)) {} else
 
+void migration_debug_ram_consistency(const char *prefix);
+
+#define MIGRATION_RAM_CONSISTENCY_CHECK()              \
+do {                                              \
+        migration_debug_ram_consistency(__func__);      \
+} while (0)
+
 int xbzrle_cache_resize(int64_t new_size, Error **errp);
 uint64_t ram_bytes_remaining(void);
 uint64_t ram_bytes_total(void);