From patchwork Fri May 17 03:24:59 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qiao Nuohan X-Patchwork-Id: 244474 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 8287B2C00A8 for ; Fri, 17 May 2013 13:29:39 +1000 (EST) Received: from localhost ([::1]:60621 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UdBMP-0003S9-OA for incoming@patchwork.ozlabs.org; Thu, 16 May 2013 23:29:37 -0400 Received: from eggs.gnu.org ([208.118.235.92]:49306) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UdBIc-0005zB-In for qemu-devel@nongnu.org; Thu, 16 May 2013 23:25:51 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UdBIN-00072Q-Ib for qemu-devel@nongnu.org; Thu, 16 May 2013 23:25:42 -0400 Received: from [222.73.24.84] (port=41393 helo=song.cn.fujitsu.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UdBIM-0006vs-Jg for qemu-devel@nongnu.org; Thu, 16 May 2013 23:25:27 -0400 X-IronPort-AV: E=Sophos;i="4.87,689,1363104000"; d="scan'208";a="7291127" Received: from unknown (HELO tang.cn.fujitsu.com) ([10.167.250.3]) by song.cn.fujitsu.com with ESMTP; 17 May 2013 11:22:20 +0800 Received: from fnstmail02.fnst.cn.fujitsu.com (tang.cn.fujitsu.com [127.0.0.1]) by tang.cn.fujitsu.com (8.14.3/8.13.1) with ESMTP id r4H3P7dF031979; Fri, 17 May 2013 11:25:08 +0800 Received: from localhost.localdomain ([10.167.226.41]) by fnstmail02.fnst.cn.fujitsu.com (Lotus Domino Release 8.5.3) with ESMTP id 2013051711235768-1299834 ; Fri, 17 May 2013 11:23:57 +0800 From: Qiao Nuohan To: qemu-devel@nongnu.org Date: Fri, 17 May 2013 11:24:59 +0800 Message-Id: <1368761104-20105-5-git-send-email-qiaonuohan@cn.fujitsu.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1368761104-20105-1-git-send-email-qiaonuohan@cn.fujitsu.com> References: <1368761104-20105-1-git-send-email-qiaonuohan@cn.fujitsu.com> X-MIMETrack: Itemize by SMTP Server on mailserver/fnst(Release 8.5.3|September 15, 2011) at 2013/05/17 11:23:57, Serialize by Router on mailserver/fnst(Release 8.5.3|September 15, 2011) at 2013/05/17 11:23:59, Serialize complete at 2013/05/17 11:23:59 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 222.73.24.84 Cc: Qiao Nuohan , d.hatayama@jp.fujitsu.com, zhangxh@cn.fujitsu.com, kumagai-atsushi@mxc.nes.nec.co.jp, anderson@redhat.com, afaerber@suse.de Subject: [Qemu-devel] [PATCH 4/9 v3] Add API to create header of vmcore X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Functions in this patch are used to gather data of header and sub header in kdump-compressed format. The following patch will use these functions to gather data of header, then cache them into struct DumpState. Signed-off-by: Qiao Nuohan Reviewed-by: Zhang Xiaohe --- dump.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++ include/sysemu/dump.h | 95 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 202 insertions(+), 0 deletions(-) diff --git a/dump.c b/dump.c index 705c978..bdebb33 100644 --- a/dump.c +++ b/dump.c @@ -672,6 +672,113 @@ static ram_addr_t get_start_block(DumpState *s) return -1; } +static int create_header32(DumpState *s) +{ + struct disk_dump_header32 *dh; + struct kdump_sub_header32 *kh; + + /* create common header, the version of kdump-compressed format is 5th */ + dh = g_malloc0(sizeof(struct disk_dump_header32)); + + strncpy(dh->signature, KDUMP_SIGNATURE, strlen(KDUMP_SIGNATURE)); + dh->header_version = 5; + dh->block_size = s->page_size; + dh->sub_hdr_size = sizeof(struct kdump_sub_header32) + s->note_size; + dh->sub_hdr_size = divideup(dh->sub_hdr_size, dh->block_size); + dh->max_mapnr = s->max_mapnr; + dh->nr_cpus = s->nr_cpus; + dh->bitmap_blocks = divideup(s->len_dump_bitmap, s->page_size); + + memcpy(&(dh->utsname.machine), "i686", 4); + + s->dh = dh; + + /* create sub header */ + kh = g_malloc0(sizeof(struct kdump_sub_header32)); + + kh->phys_base = PHYS_BASE; + kh->dump_level = DUMP_LEVEL; + + kh->offset_note = DISKDUMP_HEADER_BLOCKS * dh->block_size + + sizeof(struct kdump_sub_header32); + kh->note_size = s->note_size; + + s->kh = kh; + + /* get gap between header and sub header */ + s->offset_sub_header = DISKDUMP_HEADER_BLOCKS * dh->block_size - + sizeof(struct disk_dump_header32); + + /* get gap between header and dump_bitmap */ + s->offset_dump_bitmap = dh->sub_hdr_size * dh->block_size - + (sizeof(struct kdump_sub_header32) + s->note_size); + + /* get offset of page desc */ + s->offset_page = (DISKDUMP_HEADER_BLOCKS + dh->sub_hdr_size + + dh->bitmap_blocks) * dh->block_size; + + return 0; +} + +static int create_header64(DumpState *s) +{ + struct disk_dump_header64 *dh; + struct kdump_sub_header64 *kh; + + /* create common header, the version of kdump-compressed format is 5th */ + dh = g_malloc0(sizeof(struct disk_dump_header64)); + + strncpy(dh->signature, KDUMP_SIGNATURE, strlen(KDUMP_SIGNATURE)); + dh->header_version = 5; + dh->block_size = s->page_size; + dh->sub_hdr_size = sizeof(struct kdump_sub_header64) + s->note_size; + dh->sub_hdr_size = divideup(dh->sub_hdr_size, dh->block_size); + dh->max_mapnr = s->max_mapnr; + dh->nr_cpus = s->nr_cpus; + dh->bitmap_blocks = divideup(s->len_dump_bitmap, s->page_size); + + memcpy(&(dh->utsname.machine), "x86_64", 6); + + s->dh = dh; + + /* create sub header */ + kh = g_malloc0(sizeof(struct kdump_sub_header64)); + + kh->phys_base = PHYS_BASE; + kh->dump_level = DUMP_LEVEL; + + kh->offset_note = DISKDUMP_HEADER_BLOCKS * dh->block_size + + sizeof(struct kdump_sub_header64); + kh->note_size = s->note_size; + + s->kh = kh; + + /* get gap between header and sub header */ + s->offset_sub_header = DISKDUMP_HEADER_BLOCKS * dh->block_size - + sizeof(struct disk_dump_header64); + + /* get gap between header and dump_bitmap */ + s->offset_dump_bitmap = dh->sub_hdr_size * dh->block_size - + (sizeof(struct kdump_sub_header64) + s->note_size); + + /* get offset of page desc */ + s->offset_page = (DISKDUMP_HEADER_BLOCKS + dh->sub_hdr_size + + dh->bitmap_blocks) * dh->block_size; + + return 0; +} + +/* + * gather data of header and sub header + */ +static int create_header(DumpState *s) +{ + if (s->dump_info.d_machine == EM_386) + return create_header32(s); + else + return create_header64(s); +} + 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 b41469a..e0047df 100644 --- a/include/sysemu/dump.h +++ b/include/sysemu/dump.h @@ -25,12 +25,95 @@ #include "qapi/error.h" #include "qmp-commands.h" +#include + +#define KDUMP_SIGNATURE "KDUMP " +#define SIG_LEN (sizeof(KDUMP_SIGNATURE) - 1) +#define DISKDUMP_HEADER_BLOCKS (1) +#define PHYS_BASE (0) +#define DUMP_LEVEL (1) + +#define divideup(x, y) (((x) + ((y) - 1)) / (y)) + typedef struct ArchDumpInfo { int d_machine; /* Architecture */ int d_endian; /* ELFDATA2LSB or ELFDATA2MSB */ int d_class; /* ELFCLASS32 or ELFCLASS64 */ } ArchDumpInfo; +struct new_utsname { + char sysname[65]; + char nodename[65]; + char release[65]; + char version[65]; + char machine[65]; + char domainname[65]; +}; + +struct disk_dump_header32 { + char signature[SIG_LEN]; /* = "KDUMP " */ + int header_version; /* Dump header version */ + struct new_utsname utsname; /* copy of system_utsname */ + char timestamp[8]; /* Time stamp */ + unsigned int status; /* Above flags */ + int block_size; /* Size of a block in byte */ + int sub_hdr_size; /* Size of arch dependent header in block */ + unsigned int bitmap_blocks; /* Size of Memory bitmap in block */ + unsigned int max_mapnr; /* = max_mapnr */ + unsigned int total_ram_blocks; /* Number of blocks should be written */ + unsigned int device_blocks; /* Number of total blocks in dump device */ + unsigned int written_blocks; /* Number of written blocks */ + unsigned int current_cpu; /* CPU# which handles dump */ + int nr_cpus; /* Number of CPUs */ + struct task_struct *tasks[0]; +}; + +struct disk_dump_header64 { + char signature[SIG_LEN]; /* = "KDUMP " */ + int header_version; /* Dump header version */ + struct new_utsname utsname; /* copy of system_utsname */ + char timestamp[20]; /* Time stamp */ + unsigned int status; /* Above flags */ + int block_size; /* Size of a block in byte */ + int sub_hdr_size; /* Size of arch dependent header in block */ + unsigned int bitmap_blocks; /* Size of Memory bitmap in block */ + unsigned int max_mapnr; /* = max_mapnr */ + unsigned int total_ram_blocks; /* Number of blocks should be written */ + unsigned int device_blocks; /* Number of total blocks in dump device */ + unsigned int written_blocks; /* Number of written blocks */ + unsigned int current_cpu; /* CPU# which handles dump */ + int nr_cpus; /* Number of CPUs */ + struct task_struct *tasks[0]; +}; + +struct kdump_sub_header32 { + uint32_t phys_base; + uint32_t dump_level; /* header_version 1 and later */ + uint32_t split; /* header_version 2 and later */ + uint32_t start_pfn; /* header_version 2 and later */ + uint32_t end_pfn; /* header_version 2 and later */ + uint32_t offset_vmcoreinfo; /* header_version 3 and later */ + uint32_t size_vmcoreinfo; /* header_version 3 and later */ + uint32_t offset_note; /* header_version 4 and later */ + uint32_t note_size; /* header_version 4 and later */ + uint32_t offset_eraseinfo; /* header_version 5 and later */ + uint32_t size_eraseinfo; /* header_version 5 and later */ +}; + +struct kdump_sub_header64 { + uint64_t phys_base; + uint32_t dump_level; /* header_version 1 and later */ + uint32_t split; /* header_version 2 and later */ + uint64_t start_pfn; /* header_version 2 and later */ + uint64_t end_pfn; /* header_version 2 and later */ + uint64_t offset_vmcoreinfo; /* header_version 3 and later */ + uint64_t size_vmcoreinfo; /* header_version 3 and later */ + uint64_t offset_note; /* header_version 4 and later */ + uint64_t note_size; /* header_version 4 and later */ + uint64_t offset_eraseinfo; /* header_version 5 and later */ + uint64_t size_eraseinfo; /* header_version 5 and later */ +}; + typedef struct DumpState { ArchDumpInfo dump_info; MemoryMappingList list; @@ -48,6 +131,18 @@ typedef struct DumpState { int64_t begin; int64_t length; Error **errp; + + int page_size; + unsigned long long max_mapnr; + int nr_cpus; + void *dh; + void *kh; + off_t offset_sub_header; + + off_t offset_dump_bitmap; + unsigned long len_dump_bitmap; + + off_t offset_page; } DumpState; int cpu_get_dump_info(ArchDumpInfo *info);