9ae3a8
From 33af2fc0d1fd87e26c9ed15a3ce07a61cbbaa490 Mon Sep 17 00:00:00 2001
9ae3a8
From: Laszlo Ersek <lersek@redhat.com>
9ae3a8
Date: Fri, 7 Nov 2014 17:18:00 +0100
9ae3a8
Subject: [PATCH 13/41] dump: add APIs to operate DataCache
9ae3a8
9ae3a8
Message-id: <1415380693-16593-14-git-send-email-lersek@redhat.com>
9ae3a8
Patchwork-id: 62199
9ae3a8
O-Subject: [RHEL-7.1 qemu-kvm PATCH 13/26] dump: add APIs to operate DataCache
9ae3a8
Bugzilla: 1157798
9ae3a8
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
9ae3a8
RH-Acked-by: Luiz Capitulino <lcapitulino@redhat.com>
9ae3a8
RH-Acked-by: dgibson <dgibson@redhat.com>
9ae3a8
9ae3a8
From: qiaonuohan <qiaonuohan@cn.fujitsu.com>
9ae3a8
9ae3a8
DataCache is used to store data temporarily, then the data will be written to
9ae3a8
vmcore. These functions will be called later when writing data of page to
9ae3a8
vmcore.
9ae3a8
9ae3a8
Signed-off-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com>
9ae3a8
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
9ae3a8
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
9ae3a8
(cherry picked from commit 64cfba6a47411092c941c8d17256fb5673cc8cbf)
9ae3a8
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
9ae3a8
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
9ae3a8
---
9ae3a8
 dump.c                | 47 +++++++++++++++++++++++++++++++++++++++++++++++
9ae3a8
 include/sysemu/dump.h |  9 +++++++++
9ae3a8
 2 files changed, 56 insertions(+)
9ae3a8
9ae3a8
diff --git a/dump.c b/dump.c
9ae3a8
index f416093..926ab84 100644
9ae3a8
--- a/dump.c
9ae3a8
+++ b/dump.c
9ae3a8
@@ -1171,6 +1171,53 @@ out:
9ae3a8
     return ret;
9ae3a8
 }
9ae3a8
 
9ae3a8
+static void prepare_data_cache(DataCache *data_cache, DumpState *s,
9ae3a8
+                               off_t offset)
9ae3a8
+{
9ae3a8
+    data_cache->fd = s->fd;
9ae3a8
+    data_cache->data_size = 0;
9ae3a8
+    data_cache->buf_size = BUFSIZE_DATA_CACHE;
9ae3a8
+    data_cache->buf = g_malloc0(BUFSIZE_DATA_CACHE);
9ae3a8
+    data_cache->offset = offset;
9ae3a8
+}
9ae3a8
+
9ae3a8
+static int write_cache(DataCache *dc, const void *buf, size_t size,
9ae3a8
+                       bool flag_sync)
9ae3a8
+{
9ae3a8
+    /*
9ae3a8
+     * dc->buf_size should not be less than size, otherwise dc will never be
9ae3a8
+     * enough
9ae3a8
+     */
9ae3a8
+    assert(size <= dc->buf_size);
9ae3a8
+
9ae3a8
+    /*
9ae3a8
+     * if flag_sync is set, synchronize data in dc->buf into vmcore.
9ae3a8
+     * otherwise check if the space is enough for caching data in buf, if not,
9ae3a8
+     * write the data in dc->buf to dc->fd and reset dc->buf
9ae3a8
+     */
9ae3a8
+    if ((!flag_sync && dc->data_size + size > dc->buf_size) ||
9ae3a8
+        (flag_sync && dc->data_size > 0)) {
9ae3a8
+        if (write_buffer(dc->fd, dc->offset, dc->buf, dc->data_size) < 0) {
9ae3a8
+            return -1;
9ae3a8
+        }
9ae3a8
+
9ae3a8
+        dc->offset += dc->data_size;
9ae3a8
+        dc->data_size = 0;
9ae3a8
+    }
9ae3a8
+
9ae3a8
+    if (!flag_sync) {
9ae3a8
+        memcpy(dc->buf + dc->data_size, buf, size);
9ae3a8
+        dc->data_size += size;
9ae3a8
+    }
9ae3a8
+
9ae3a8
+    return 0;
9ae3a8
+}
9ae3a8
+
9ae3a8
+static void free_data_cache(DataCache *data_cache)
9ae3a8
+{
9ae3a8
+    g_free(data_cache->buf);
9ae3a8
+}
9ae3a8
+
9ae3a8
 static ram_addr_t get_start_block(DumpState *s)
9ae3a8
 {
9ae3a8
     GuestPhysBlock *block;
9ae3a8
diff --git a/include/sysemu/dump.h b/include/sysemu/dump.h
9ae3a8
index 6d4d0bc..92a95e4 100644
9ae3a8
--- a/include/sysemu/dump.h
9ae3a8
+++ b/include/sysemu/dump.h
9ae3a8
@@ -41,6 +41,7 @@
9ae3a8
 #define DISKDUMP_HEADER_BLOCKS      (1)
9ae3a8
 #define BUFSIZE_BITMAP              (TARGET_PAGE_SIZE)
9ae3a8
 #define PFN_BUFBITMAP               (CHAR_BIT * BUFSIZE_BITMAP)
9ae3a8
+#define BUFSIZE_DATA_CACHE          (TARGET_PAGE_SIZE * 4)
9ae3a8
 
9ae3a8
 typedef struct ArchDumpInfo {
9ae3a8
     int d_machine;  /* Architecture */
9ae3a8
@@ -142,6 +143,14 @@ typedef struct QEMU_PACKED KdumpSubHeader64 {
9ae3a8
     uint64_t max_mapnr_64;          /* header_version 6 and later */
9ae3a8
 } KdumpSubHeader64;
9ae3a8
 
9ae3a8
+typedef struct DataCache {
9ae3a8
+    int fd;             /* fd of the file where to write the cached data */
9ae3a8
+    uint8_t *buf;       /* buffer for cached data */
9ae3a8
+    size_t buf_size;    /* size of the buf */
9ae3a8
+    size_t data_size;   /* size of cached data in buf */
9ae3a8
+    off_t offset;       /* offset of the file */
9ae3a8
+} DataCache;
9ae3a8
+
9ae3a8
 struct GuestPhysBlockList; /* memory_mapping.h */
9ae3a8
 int cpu_get_dump_info(ArchDumpInfo *info,
9ae3a8
                       const struct GuestPhysBlockList *guest_phys_blocks);
9ae3a8
-- 
9ae3a8
1.8.3.1
9ae3a8