Functions in this patch are used to gather data of 1st and 2nd dump bitmap in kdump-compressed format. The following patch will use these functions to gather data of dump bitmap, then cache them into tmp files.
Signed-off-by: Qiao Nuohan <qiaonuo...@cn.fujitsu.com> Reviewed-by: Zhang Xiaohe <zhan...@cn.fujitsu.com> --- dump.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++ include/sysemu/dump.h | 10 +++++ 2 files changed, 108 insertions(+), 0 deletions(-) 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 e0047df..597b19e 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; -- 1.7.1