Patchwork [5/9,v2] Add API to create data of dump bitmap

login
register
mail settings
Submitter Qiao Nuohan
Date May 15, 2013, 2:29 a.m.
Message ID <1368584998-20053-6-git-send-email-qiaonuohan@cn.fujitsu.com>
Download mbox | patch
Permalink /patch/243863/
State New
Headers show

Comments

Qiao Nuohan - May 15, 2013, 2:29 a.m.
Add API to get data of the 1st and 2nd dump bitmap and save them into tmp files.
The following patch will use these functions to gather data of dump bitmap,
then write them into vmcore.

Signed-off-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com>
Reviewed-by: Zhang Xiaohe <zhangxh@cn.fujitsu.com>
---
 dump.c                |   98 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/sysemu/dump.h |   10 +++++
 2 files changed, 108 insertions(+), 0 deletions(-)

Patch

diff --git a/dump.c b/dump.c
index bdebb33..998d71e 100644
--- a/dump.c
+++ b/dump.c
@@ -779,6 +779,104 @@  static int create_header(DumpState *s)
         return create_header64(s);
 }
 
+/*
+ * create two tmpfile and save 1st and 2nd bitmap separately
+ */
+static int prepare_dump_bitmap(DumpState *s)
+{
+    int ret;
+    struct dump_bitmap *db1;
+    struct dump_bitmap *db2;
+
+    db1 = g_malloc0(sizeof(struct dump_bitmap));
+
+    db2 = g_malloc0(sizeof(struct dump_bitmap));
+
+    ret = init_dump_bitmap(db1, FILENAME_BITMAP1);
+    if (ret < 0) {
+        dump_error(s, "dump: failed to init db1.");
+        return -1;
+    }
+    s->dump_bitmap1 = db1;
+
+    ret = init_dump_bitmap(db2, FILENAME_BITMAP2);
+    if (ret < 0) {
+        dump_error(s, "dump: failed to init db1.");
+        return -1;
+    }
+    s->dump_bitmap2 = db2;
+
+    return 0;
+}
+
+static int create_dump_bitmap(DumpState *s)
+{
+    int ret;
+    unsigned long long num_dumpable;
+    MemoryMapping *memory_mapping;
+    unsigned long long pfn_start, pfn_end, pfn;
+
+    ret = prepare_dump_bitmap(s);
+    if (ret < 0) {
+        dump_error(s, "dump: failed to prepare dump_bitmap.\n");
+        return -1;
+    }
+
+    ret = clear_dump_bitmap(s->dump_bitmap1, s->len_dump_bitmap / 2);
+    if (ret < 0) {
+        dump_error(s, "dump: failed to clear dump_bitmap1.\n");
+        return -1;
+    }
+
+    ret = clear_dump_bitmap(s->dump_bitmap2, s->len_dump_bitmap / 2);
+    if (ret < 0) {
+        dump_error(s, "dump: failed to clear dump_bitmap2.\n");
+        return -1;
+    }
+
+    /* write dump bitmap to tmp files */
+    num_dumpable = 0;
+
+    QTAILQ_FOREACH(memory_mapping, &s->list.head, next) {
+        pfn_start = paddr_to_pfn(memory_mapping->phys_addr, s->page_shift);
+        pfn_end = paddr_to_pfn(memory_mapping->phys_addr +
+                    memory_mapping->length, s->page_shift);
+
+        for (pfn = pfn_start; pfn < pfn_end; pfn++) {
+            ret = set_dump_bitmap(s->dump_bitmap1, pfn, 1);
+            if (ret < 0) {
+                dump_error(s, "dump: failed to set dump_bitmap1.\n");
+                return -1;
+            }
+            /* set dump_bitmap2, same as dump_bitmap1 */
+            ret = set_dump_bitmap(s->dump_bitmap2, pfn, 1);
+            if (ret < 0) {
+                dump_error(s, "dump: failed to set dump_bitmap2.\n");
+                return -1;
+            }
+            num_dumpable++;
+        }
+    }
+
+    /* write cached data to tmp files */
+    ret = sync_dump_bitmap(s->dump_bitmap1);
+    if (ret < 0) {
+        dump_error(s, "dump: failed to sync dump_bitmap1.\n");
+        return -1;
+    }
+
+    ret = sync_dump_bitmap(s->dump_bitmap2);
+    if (ret < 0) {
+        dump_error(s, "dump: failed to sync dump_bitmap2.\n");
+        return -1;
+    }
+
+    /* get the number of dumpable page */
+    s->num_dumpable = num_dumpable;
+
+    return 0;
+}
+
 static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
                      int64_t begin, int64_t length, Error **errp)
 {
diff --git a/include/sysemu/dump.h b/include/sysemu/dump.h
index b7846c9..93c35bc 100644
--- a/include/sysemu/dump.h
+++ b/include/sysemu/dump.h
@@ -24,6 +24,7 @@ 
 #include "sysemu/memory_mapping.h"
 #include "qapi/error.h"
 #include "qmp-commands.h"
+#include "dump_bitmap.h"
 
 #include <sys/utsname.h>
 
@@ -32,8 +33,13 @@ 
 #define DISKDUMP_HEADER_BLOCKS      (1)
 #define PHYS_BASE                   (0)
 #define DUMP_LEVEL                  (1)
+#define ARCH_PFN_OFFSET             (0)
+#define FILENAME_BITMAP1            "kdump_bitmap1_XXXXXX"
+#define FILENAME_BITMAP2            "kdump_bitmap2_XXXXXX"
 
 #define divideup(x, y)              (((x) + ((y) - 1)) / (y))
+#define paddr_to_pfn(X, page_shift) \
+    (((unsigned long long)(X) >> (page_shift)) - ARCH_PFN_OFFSET)
 
 typedef struct ArchDumpInfo {
     int d_machine;  /* Architecture */
@@ -133,14 +139,18 @@  typedef struct DumpState {
     Error **errp;
 
     int page_size;
+    int page_shift;
     unsigned long long max_mapnr;
     int nr_cpus;
     void *dh;
     void *kh;
+    unsigned long long num_dumpable;
     off_t offset_sub_header;
 
     off_t offset_dump_bitmap;
     unsigned long len_dump_bitmap;
+    struct dump_bitmap *dump_bitmap1;
+    struct dump_bitmap *dump_bitmap2;
 
     off_t offset_page;
 } DumpState;