From patchwork Wed May 15 02:29:51 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Qiao Nuohan X-Patchwork-Id: 243862 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 F19882C00A5 for ; Wed, 15 May 2013 12:31:30 +1000 (EST) Received: from localhost ([::1]:45710 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UcRV3-000595-4o for incoming@patchwork.ozlabs.org; Tue, 14 May 2013 22:31:29 -0400 Received: from eggs.gnu.org ([208.118.235.92]:38190) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UcRU1-000490-3i for qemu-devel@nongnu.org; Tue, 14 May 2013 22:30:30 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UcRTu-0002tf-8Y for qemu-devel@nongnu.org; Tue, 14 May 2013 22:30:25 -0400 Received: from fgwmail6.fujitsu.co.jp ([192.51.44.36]:59301) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UcRTt-0002sz-Lr for qemu-devel@nongnu.org; Tue, 14 May 2013 22:30:18 -0400 Received: from m3.gw.fujitsu.co.jp (unknown [10.0.50.73]) by fgwmail6.fujitsu.co.jp (Postfix) with ESMTP id F39783EE0C7 for ; Wed, 15 May 2013 11:30:16 +0900 (JST) Received: from smail (m3 [127.0.0.1]) by outgoing.m3.gw.fujitsu.co.jp (Postfix) with ESMTP id CEF2445DEBB for ; Wed, 15 May 2013 11:30:16 +0900 (JST) Received: from s3.gw.fujitsu.co.jp (s3.gw.fujitsu.co.jp [10.0.50.93]) by m3.gw.fujitsu.co.jp (Postfix) with ESMTP id B12C545DEB6 for ; Wed, 15 May 2013 11:30:16 +0900 (JST) Received: from s3.gw.fujitsu.co.jp (localhost.localdomain [127.0.0.1]) by s3.gw.fujitsu.co.jp (Postfix) with ESMTP id 9A6501DB803C for ; Wed, 15 May 2013 11:30:16 +0900 (JST) Received: from s00.fujitsu.com (s00.gw.fujitsu.co.jp [133.161.11.15]) by s3.gw.fujitsu.co.jp (Postfix) with ESMTP id 538B3E08003 for ; Wed, 15 May 2013 11:30:16 +0900 (JST) Received: from s00.gw.fujitsu.co.jp (localhost [127.0.0.1]) by s00.fujitsu.com (Postfix) with ESMTP id 2500DAC3BA for ; Wed, 15 May 2013 11:30:12 +0900 (JST) Received: from localhost.localdomain (unknown [10.167.226.41]) by s00.fujitsu.com (Postfix) with ESMTP id C0CABAC3B8 for ; Wed, 15 May 2013 11:30:10 +0900 (JST) Received: by localhost.localdomain (Postfix, from userid 0) id DD7D71417E2; Wed, 15 May 2013 10:30:37 +0800 (CST) From: Qiao Nuohan To: qemu-devel@nongnu.org Date: Wed, 15 May 2013 10:29:51 +0800 Message-Id: <1368584998-20053-3-git-send-email-qiaonuohan@cn.fujitsu.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1368584998-20053-1-git-send-email-qiaonuohan@cn.fujitsu.com> References: <1368584998-20053-1-git-send-email-qiaonuohan@cn.fujitsu.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x X-Received-From: 192.51.44.36 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 2/9 v2] Add API to manipulate cache_data 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 Struct dump_bitmap is associated with a tmp file, and the tmp file can be used to save data of page desc and page data in kdump-compressed format temporarily. The following patch will use these function to get the data of page desc and page data and cache them in tmp files. Signed-off-by: Qiao Nuohan Reviewed-by: Zhang Xiaohe --- Makefile.target | 2 +- cache_data.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++ include/cache_data.h | 56 +++++++++++++++++++++++ 3 files changed, 178 insertions(+), 1 deletions(-) create mode 100644 cache_data.c create mode 100644 include/cache_data.h diff --git a/Makefile.target b/Makefile.target index 00d4f13..b579aff 100644 --- a/Makefile.target +++ b/Makefile.target @@ -112,7 +112,7 @@ obj-$(CONFIG_FDT) += device_tree.o obj-$(CONFIG_KVM) += kvm-all.o obj-y += memory.o savevm.o cputlb.o obj-$(CONFIG_HAVE_GET_MEMORY_MAPPING) += memory_mapping.o -obj-$(CONFIG_HAVE_CORE_DUMP) += dump.o dump_bitmap.o +obj-$(CONFIG_HAVE_CORE_DUMP) += dump.o dump_bitmap.o cache_data.o obj-$(CONFIG_NO_GET_MEMORY_MAPPING) += memory_mapping-stub.o obj-$(CONFIG_NO_CORE_DUMP) += dump-stub.o LIBS+=$(libs_softmmu) diff --git a/cache_data.c b/cache_data.c new file mode 100644 index 0000000..469ed94 --- /dev/null +++ b/cache_data.c @@ -0,0 +1,121 @@ +/* + * QEMU cache data + * + * Copyright Fujitsu, Corp. 2013 + * + * Authors: + * Qiao Nuohan + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#include "qemu-common.h" +#include "cache_data.h" + +int init_cache_data(struct cache_data *cd, const char *filename) +{ + int fd; + char *tmpname; + + /* init the tmp file */ + tmpname = getenv("TMPDIR"); + if (!tmpname) { + tmpname = (char *)P_tmpdir; + } + + cd->file_name = (char *)g_strdup_printf("%s/%s", tmpname, filename); + + fd = mkstemp(cd->file_name); + if (fd < 0) { + return -1; + } + + cd->fd = fd; + unlink(cd->file_name); + + /* init buf */ + cd->buf_size = BUFSIZE_CACHE_DATA; + cd->cache_size = 0; + cd->buf = g_malloc0(BUFSIZE_CACHE_DATA); + + cd->offset = 0; + + return 0; +} + +int write_cache(struct cache_data *cd, void *buf, size_t size) +{ + /* + * check if the space is enough to cache data, if not write cached + * data to the tmp file + */ + if (cd->cache_size + size > cd->buf_size) { + if (lseek(cd->fd, cd->offset, SEEK_SET) < 0) { + return -1; + } + + if (write(cd->fd, cd->buf, cd->cache_size) != cd->cache_size) { + return -1; + } + + cd->offset += cd->cache_size; + cd->cache_size = 0; + } + + memcpy(cd->buf + cd->cache_size, buf, size); + cd->cache_size += size; + + return 0; +} + +int sync_cache(struct cache_data *cd) +{ + /* no data is cached in cache_data */ + if (cd->cache_size == 0) { + return 0; + } + + if (lseek(cd->fd, cd->offset, SEEK_SET) < 0) { + return -1; + } + + if (write(cd->fd, cd->buf, cd->cache_size) != cd->cache_size) { + return -1; + } + + cd->offset += cd->cache_size; + + return 0; +} + +int read_cache(struct cache_data *cd) +{ + if (lseek(cd->fd, cd->offset, SEEK_SET) < 0) { + return -1; + } + + if (read(cd->fd, cd->buf, cd->cache_size) != cd->cache_size) { + return -1; + } + + cd->offset += cd->cache_size; + + return 0; +} + +void free_cache_data(struct cache_data *cd) +{ + if (cd) { + if (cd->file_name) { + g_free(cd->file_name); + } + + if (cd->buf) { + g_free(cd->buf); + } + + g_free(cd); + } +} diff --git a/include/cache_data.h b/include/cache_data.h new file mode 100644 index 0000000..cbce60e --- /dev/null +++ b/include/cache_data.h @@ -0,0 +1,56 @@ +/* + * QEMU cache data + * + * Copyright Fujitsu, Corp. 2013 + * + * Authors: + * Qiao Nuohan + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#ifndef CACHE_DATA_H +#define CACHE_DATA_H + +#define BUFSIZE_CACHE_DATA (4096 * 4) + +struct cache_data { + int fd; /* fd of the tmp file used to store cache data */ + char *file_name; /* name of the tmp file */ + char *buf; /* used to cache data */ + size_t buf_size; /* size of the buf */ + size_t cache_size; /* size of cached data in buf */ + off_t offset; /* offset of the tmp file */ +}; + +/* + * create a tmp file used to store cache data, then init the buf + */ +int init_cache_data(struct cache_data *cd, const char *filename); + +/* + * write data to the tmp file, the data may first be cached in the buf of + * cache_data + */ +int write_cache(struct cache_data *cd, void *buf, size_t size); + +/* + * when cache_data is caching data in the buf, sync_cache is needed to write the + * data back to tmp file + */ +int sync_cache(struct cache_data *cd); + +/* read data from the tmp file to the buf of 'cd', the start place is set by + * cd->offset, and the size is set by cd->cache_size. cd->offset is changed + * automaticlly according to the size of data read this time. + */ +int read_cache(struct cache_data *cd); + +/* + * free the space used by cache_data + */ +void free_cache_data(struct cache_data *cd); + +#endif