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 <qiaonuo...@cn.fujitsu.com> Reviewed-by: Zhang Xiaohe <zhan...@cn.fujitsu.com> --- Makefile.target | 2 +- cache_data.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++ include/cache_data.h | 52 +++++++++++++++++++++++ 3 files changed, 167 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..8602ef9 --- /dev/null +++ b/cache_data.c @@ -0,0 +1,114 @@ +/* + * QEMU cache data + * + * Copyright Fujitsu, Corp. 2013 + * + * Authors: + * Qiao Nuohan <qiaonuo...@cn.fujitsu.com> + * + * 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 tmpdir[] = TMP_DIR; + char *tmpname; + + /* init the tmp file */ + tmpname = getenv("TMPDIR"); + if (!tmpname) + tmpname = tmpdir; + + cd->file_name = (char *)g_malloc(strlen(filename) + strlen(tmpname) + 1); + + strcpy(cd->file_name, tmpname); + strcat(cd->file_name, "/"); + strcat(cd->file_name, filename); + + if ((fd = mkstemp(cd->file_name)) < 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..4d6656f --- /dev/null +++ b/include/cache_data.h @@ -0,0 +1,52 @@ +/* + * QEMU cache data + * + * Copyright Fujitsu, Corp. 2013 + * + * Authors: + * Qiao Nuohan <qiaonuo...@cn.fujitsu.com> + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#define TMP_DIR "/tmp" +#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); -- 1.7.1