Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1347350
  • 博文数量: 488
  • 博客积分: 161
  • 博客等级: 入伍新兵
  • 技术积分: 5054
  • 用 户 组: 普通用户
  • 注册时间: 2011-07-01 07:37
个人简介

只有偏执狂才能生存

文章分类

全部博文(488)

文章存档

2016年(10)

2015年(112)

2014年(66)

2013年(272)

2012年(28)

分类: LINUX

2014-04-24 08:59:02

我们已经将HLFS移植到QEMU环境下,从而支持在KVM等虚拟环境下使用其。

下载和编译

  1. 下载 qemu - git clone git://git.qemu.org/qemu.git
  2. 注意:HLFS driver patch for QEMU V1.3.0, clonemailinegit tree,还需执行下面命令,回滚到 QEMU V1.3.0.       git reset --hard v1.3.0
  3. 下载patch for qemu - http://cloudxy.googlecode.com/svn/trunk/hlfs/patches/hlfs_driver_for_qemu_1.3.0.patch
  4. patch it - 在qemu目录中执行 :git apply hlfs_driver_for_qemu.patch
  5. 在qemu目录下的configure文件中修改如下内容
  6. GLIB_DIR1_INC=/usr/lib/glib-2.0/include
    GLIB_DIR2_INC=/usr/include/glib-2.0 HLFS_DIR=/home/kanghua/workshop3.bak/hlfs
    JVM_DIR=/usr/lib/jvm/java-6-sun/ 注意:以上几个变量所指的位置为你系统环境的实际地址
  7. 编译安装QEMU
  8. $./configure --enable-hlfs --with-coroutine=gthread 这里必须特别说明一下 coroutineqemu中提高并发效率新机制(默认coroutine使用的backenducontext),但可惜因为我们使用libhdfs,其使用jni创建jvm. 调试中发现ucontext机制的stack管理和jvmstack似乎有冲突,具体原因未明(如果那位有识之士帮忙调查清楚,则感激不尽)。所以qemucoroutine请配置为传统的thread模式;另外如果你要用kvm 别忘了加上--enable-kvm 选项;如果不用vnc,而使用sdl,那别忘了加选项--enable-sdl. $make
    $sudo make install
    $ldd ./qemu-img 执行这个命令是为了查看qemu-img所指向的库是否都存在!

支持操作

注意: 1.目前尚不支持prealloc操作 2.确保ldd ./qemu-img 所显示的库(hlfs,hdfs,jvm,log4c等)处于动态库搜索路径,如果不再,则要自己手动添加到路径中。
  • 创建网络磁盘操作
  • mkdir /tmp/testenv ./qemu-img create -f hlfs hlfs:local:///tmp/testenv/testfs 10G 或 ./qemu-img create -f hlfs hlfs:hdfs:///tmp/testenv/testfs 10G
  • 状态查询
  • ./qemu-img info -f hlfs hlfs:local:///tmp/testenv/testfs 或 ./qemu-img info -f hlfs hlfs:hdfs:///tmp/testenv/testfs 
  • 快照相关操作
  • 生成快照 ./qemu-img snapshot -c snapshot1 hlfs:local:///tmp/testenv/testfs 或 ./qemu-img snapshot -c snapshot1 hlfs:hdfs:///tmp/testenv/testfs 查询快照 ./qemu-img snapshot -l hlfs:local:///tmp/testenv/testfs 或 ./qemu-img snapshot -l hdfs:local:///tmp/testenv/testfs 删除快照 ./qemu-img snapshot -d snapshot1 hlfs:local:///tmp/testenv/testfs 或 ./qemu-img snapshot -d snapshot1 hlfs:hdfs:///tmp/testenv/testfs
  • 格式转换操作
  • ./qemu-img convert raw.img  hlfs:local:///tmp/testenv/testfs 或 ./qemu-img convert raw.img  hlfs:hdfs:///tmp/testenv/testfs
  • KVM启动
  • qemu-system-x86_64 -enable-kvm -m 1024 -smp 2 -drive file=hlfs:local:///tmp/testenv/testfs,if=virtio -boot d -vnc :7 或  qemu-system-x86_64 -enable-kvm -m 1024 -smp 2 -drive file=hlfs:hdfs:///tmp/testenv/testfs,if=virtio -boot d -vnc :7 从某个快照上启动 qemu-system-x86_64 -enable-kvm -m 1024 -smp 2 -drive file=hlfs:local:///tmp/testenv/testfs%snapshot1,if=virtio -boot d -vnc :7 或  qemu-system-x86_64 -enable-kvm -m 1024 -smp 2 -drive file=hlfs:hdfs:///tmp/testenv/testfs%shopshot1,if=virtio -boot d -vnc :7 %后为快照名称
  • Qemu 安装系统盘和启动 - 有的朋友说自己没有kvm环境,那么我们就用qemu好了!
  • 1.创建10G虚拟盘:qemu-img create -f hlfs hlfs:local:///tmp/testenv/testfs 10G。 2.通过iso安装系统:qemu-system-x86_64 -hda hlfs:local:///tmp/testenv/testfs  -cdrom /home/kanghua/ubuntu-12.04.1-server-i386.iso -boot d -m 512 -no-acpi (漫长的等待...,直到完毕;我是通过本机上执行vncviewer 127.0.0.1 5900 去操作的,没有vncviewer的话,sudo apt-get install tightvnc-java去安装一个小客户端吧,登陆时密码为空!) 3.启动新安装系统 qemu-system-x86_64 -m 512 -drive file=hlfs:local:///tmp/testenv/testfs
  • Clone 操作
  • 1.首先给base hlfs系统打个快照 - ./qemu-img snapshot -c snapshot1 hlfs:local:///tmp/testenv/testfs 2.创建新的hlfs系统 - ./qemu-img create -f hlfs hlfs:local:///tmp/testenv/testfs2 10G 3.执行clone操作 -./qemu-img create -b hlfs:local:///tmp/testenv/testfs%snapshot1 hlfs:local:///tmp/testenv/testfs2 (快照和base系统之间使用%区分!) 4.试试看hlfs:local:///tmp/testenv/testfs2啦。 -------------------------------------------- 不用qemu的情况下,在我们output/bin下也有快照和clone命令,类似用法为 ./output/bin/snapshot.hlfs -u local:///tmp/testenv/testfs -s snapshot1 ./output/bin/clone.hlfs -f local:///tmp/testenv/testfs%snapshot1 -s local:///tmp/testenv/testfs2  -------------------------------------------- CLONE行为用在那里? A 一个hdfs之上的系统盘镜像,可以作为无数新系统的base系统,从而提高系统新系统生产速度和解决存储空间。 B 为了减少本网络传输压力,提高系统响应速度,可考虑利用本地文件系统作为Base数据宿主:比如一些场景中——我们可以将标准的镜像或某系通用软件做到工具盘中,并置于到本地hlfs上,即local方式挂载的hlfs系统上,然后再在集群的hdfs上做一个新hlfs系统,并将其base到本地上述hlfs上。从而只有变化的增量数据需要途径网络io,这样很大程度上会提高系统性能。
    
    From 169e1c93de2a4babdcafe4602c0edfd7643e1a58 Mon Sep 17 00:00:00 2001
    From: Harry Wei 
    Date: Sat, 16 Feb 2013 01:59:36 +0800
    Subject: [PATCH] HLFS driver for QEMU
    
    ---
     block/Makefile.objs |    2 +-
     block/hlfs.c        |  514 +++++++++++++++++++++++++++++++++++++++++++++++++++
     configure           |   59 ++++--
     3 files changed, 562 insertions(+), 13 deletions(-)
     create mode 100644 block/hlfs.c
    
    diff --git a/block/Makefile.objs b/block/Makefile.objs
    index 7f01510..da06c37 100644
    --- a/block/Makefile.objs
    +++ b/block/Makefile.objs
    @@ -8,7 +8,7 @@ block-obj-$(CONFIG_POSIX) += raw-posix.o
     block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o
     
     ifeq ($(CONFIG_POSIX),y)
    -block-obj-y += nbd.o sheepdog.o
    +block-obj-y += nbd.o sheepdog.o hlfs.o
     block-obj-$(CONFIG_LIBISCSI) += iscsi.o
     block-obj-$(CONFIG_CURL) += curl.o
     block-obj-$(CONFIG_RBD) += rbd.o
    diff --git a/block/hlfs.c b/block/hlfs.c
    new file mode 100644
    index 0000000..0283bd6
    --- /dev/null
    +++ b/block/hlfs.c
    @@ -0,0 +1,514 @@
    +/*
    + * Block driver for HLFS(HDFS-based Log-structured File System)
    + *
    + * Copyright (c) 2012, Kang Hua 
    + * Copyright (c) 2012, Wang Sen 
    + *
    + * This program is free software. You can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 as published by
    + * the Free Software Foundation.
    + *
    + * Reference:
    + * http://code.google.com/p/cloudxy
    + */
    +
    +#include "qemu-common.h"
    +#include "qemu-error.h"
    +#include "qemu_socket.h"
    +#include "block_int.h"
    +#include "bitops.h"
    +#include "api/hlfs.h"
    +#include "storage_helper.h"
    +#include "comm_define.h"
    +#include "snapshot_helper.h"
    +#include "address.h"
    +
    +#define DEBUG_HLBS
    +#undef dprintf
    +#ifdef DEBUG_HLBS
    +#define dprintf(fmt, args...) \
    +	do {	\
    +		fprintf(stdout, "%s %d: " fmt, __func__, __LINE__, ##args); \
    +	} while (0)
    +#else
    +#define dprintf(fmt, args...)
    +#endif
    +
    +#define HLBS_MAX_VDI_SIZE 8192ULL*8192ULL*8192ULL*8192ULL
    +#define SECTOR_SIZE 512
    +
    +typedef struct BDRVHLBSState {
    +	struct hlfs_ctrl *hctrl;
    +	char *snapshot;
    +	char *uri;
    +} BDRVHLBSState;
    +
    +/*
    + * Parse a filename.
    + *
    + * file name format must be one of the following:
    + *	1. [vdiname]
    + *	2. [vdiname]%[snapshot]
    + *	* vdiname format --
    + *	* local:///tmp/testenv/testfs
    + *	* hdfs:///tmp/testenv/testfs
    + *	* hdfs://localhost:8020/tmp/testenv/testfs
    + *	* hdfs://localhost/tmp/testenv/testfs
    + *	* hdfs://192.168.0.1:8020/tmp/testenv/testfs
    + */
    +
    +static int parse_vdiname(BDRVHLBSState *s, const char *filename, char *vdi,
    +		char *snapshot)
    +{
    +	if (!filename) {
    +		return -1;
    +	}
    +
    +	gchar **v = g_strsplit(filename, "%", 2);
    +	if (g_strv_length(v) == 1) {
    +		strcpy(vdi, v[0]);
    +		s->uri = g_strdup(vdi);
    +	} else if (g_strv_length(v) == 2) {
    +		strcpy(vdi, v[0]);
    +		strcpy(snapshot, v[1]);
    +		s->uri = g_strdup(vdi);
    +		s->snapshot = g_strdup(snapshot);
    +	} else {
    +		goto out;
    +	}
    +
    +	return 0;
    +out:
    +	g_strfreev(v);
    +	return -1;
    +}
    +
    +static int hlbs_open(BlockDriverState *bs, const char *filename, int flags)
    +{
    +	int ret = 0;
    +	BDRVHLBSState *s = bs->opaque;
    +	char vdi[256];
    +	char snapshot[HLFS_FILE_NAME_MAX];
    +
    +	strstart(filename, "hlfs:", (const char **)&filename);
    +	memset(snapshot, 0, sizeof(snapshot));
    +	memset(vdi, 0, sizeof(vdi));
    +
    +	if (parse_vdiname(s, filename, vdi, snapshot) < 0) {
    +		goto out;
    +	}
    +
    +	HLFS_CTRL *ctrl = init_hlfs(vdi);
    +	if (strlen(snapshot)) {
    +		dprintf("snapshot:%s was open.\n", snapshot);
    +		ret = hlfs_open_by_snapshot(ctrl, snapshot, 1);
    +	} else {
    +		ret = hlfs_open(ctrl, 1);
    +	}
    +	g_assert(ret == 0);
    +	s->hctrl = ctrl;
    +	bs->total_sectors = ctrl->sb.max_fs_size * 1024 * 1024 / SECTOR_SIZE;
    +	return 0;
    +out:
    +	if (s->hctrl) {
    +		hlfs_close(s->hctrl);
    +		deinit_hlfs(s->hctrl);
    +	}
    +	return -1;
    +}
    +
    +static int hlbs_create(const char *filename, QEMUOptionParameter *options)
    +{
    +	int64_t vdi_size = 0;
    +	char *backing_file = NULL;
    +	BDRVHLBSState s;
    +	char vdi[256];
    +	char snapshot[256];
    +	const char *vdiname;
    +	int prealloc = 0;
    +	uint32_t is_compress = 0;
    +	strstart(filename, "hlfs:", &vdiname);
    +
    +	memset(&s, 0, sizeof(s));
    +	memset(vdi, 0, sizeof(vdi));
    +	memset(snapshot, 0, sizeof(snapshot));
    +
    +	if (parse_vdiname(&s, vdiname, vdi, (char *)&snapshot) < 0) {
    +		error_report("invailid filename");
    +		return -EINVAL;
    +	}
    +
    +	while (options && options->name) {
    +		if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
    +			vdi_size = options->value.n;
    +		} else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
    +			backing_file = options->value.s;
    +		} else if (!strcmp(options->name, BLOCK_OPT_PREALLOC)) {
    +			if (!options->value.s || !strcmp(options->value.s, "off")) {
    +				prealloc = 0;
    +			} else if (!strcmp(options->value.s, "full")) {
    +				prealloc = 1;
    +			} else {
    +				error_report("Invalid preallocation mode: '%s'", options->value.s);
    +				return -EINVAL;
    +			}
    +		}
    +		options++;
    +	}
    +
    +	if (vdi_size > HLBS_MAX_VDI_SIZE) {
    +		g_message("vdi_size: %llu  Max: %llu", vdi_size, HLBS_MAX_VDI_SIZE);
    +		error_report("too big image size");
    +		return -EINVAL;
    +	}
    +
    +	if (backing_file) {
    +		const char *father_uri_with_snapshot;
    +		strstart(backing_file, "hlfs:", &father_uri_with_snapshot);
    +		char *son_uri = vdi;
    +		char *father_uri=NULL;
    +		char *father_snapshot = NULL;
    +		gchar **v=NULL;
    +		v = g_strsplit(father_uri_with_snapshot, "%", 2);
    +		if (g_strv_length(v) != 2) {
    +			g_strfreev(v);
    +			return -1;
    +		}
    +		father_uri = g_strdup(v[0]);
    +		father_snapshot = g_strdup(v[1]);
    +		g_strfreev(v);
    +		if (0 == strcmp(father_uri,son_uri)) {
    +			g_message("father uri can not equal son uri");
    +			return -1;
    +		}
    +		struct back_storage *father_storage = init_storage_handler(father_uri);
    +		if (!father_storage) {
    +			g_message("can not get storage handler for father_uri:%s",father_uri);
    +			return -1;
    +		}
    +		struct back_storage *son_storage = init_storage_handler(son_uri);
    +		if (!son_storage) {
    +			g_message("can not get storage handler for son_uri:%s",son_uri);
    +			return -1;
    +		}
    +		/*  check son is exist and empty must  */
    +		if ((0 != son_storage->bs_file_is_exist(son_storage, NULL)) || (0 !=
    +					son_storage->bs_file_is_exist(son_storage, "superblock"))) {
    +			g_message("hlfs with uri:%s has not exist,please mkfs it first!",son_uri);
    +			return -1;
    +		}
    +
    +		uint32_t segno = 0;
    +		uint32_t offset = 0;
    +		if (0 != get_cur_latest_segment_info(son_storage, &segno, &offset)) {
    +			g_message("can not get latest seg info for son ");
    +		} else {
    +		if (segno != 0 || offset != 0) {
    +			g_message("son hlfs must empty");
    +			return -1;
    +		}
    +		}
    +       /* check son is not clone already */
    +		char *content =NULL;
    +		uint32_t size = 0;
    +		if (0 != file_get_contents(son_storage, "superblock", &content,&size)) {
    +			g_message("can not read superblock");
    +		}
    +		GKeyFile *sb_keyfile = g_key_file_new();
    +		if (FALSE == g_key_file_load_from_data(sb_keyfile, content, size,
    +					G_KEY_FILE_NONE, NULL)) {
    +			g_message("superblock file format is not key value pairs");
    +			return -1;
    +		}
    +		gchar *_father_uri = g_key_file_get_string(sb_keyfile, "METADATA",
    +				"father_uri", NULL);
    +		printf("father uri: %s\n", _father_uri);
    +		if (_father_uri != NULL) {
    +			g_message("uri:%s has clone :%s", son_uri, _father_uri);
    +			return -1;
    +		}
    +		g_free(content);
    +		/*  read father's snapshot 's inode */
    +		uint64_t inode_addr;
    +		struct snapshot *ss = NULL;
    +		if (0 > load_snapshot_by_name(father_storage, SNAPSHOT_FILE, &ss, \
    +					father_snapshot)) {
    +			g_message("load uri:%s ss by name:%s error",father_uri, \
    +					father_snapshot);
    +			g_free(ss);
    +			return -1;
    +		}
    +		inode_addr = ss->inode_addr;
    +		g_free(ss);
    +
    +		uint32_t father_seg_size = 0;
    +		uint32_t father_block_size = 0;
    +		uint64_t father_max_fs_size = 0;
    +
    +		if (0 != read_fs_meta(father_storage, &father_seg_size,
    +					&father_block_size, &father_max_fs_size, &is_compress)) {
    +			g_message("can not read father uri meta");
    +			return -1;
    +		}
    +		segno = get_segno(inode_addr);
    +		uint32_t son_block_size = g_key_file_get_integer(sb_keyfile,
    +				"METADATA", "block_size", NULL);
    +		uint32_t son_seg_size = g_key_file_get_integer(sb_keyfile, "METADATA",
    +				"segment_size", NULL);
    +		if (son_block_size != father_block_size || father_seg_size !=
    +				son_seg_size) {
    +			g_message("sorry , now father segsize and block sizee must same as \
    +					son!!!");
    +			return -1;
    +		}
    +		g_key_file_set_uint64(sb_keyfile, "METADATA", "from_segno", segno + 1);
    +		g_key_file_set_string(sb_keyfile, "METADATA", "father_uri", father_uri);
    +		g_key_file_set_integer(sb_keyfile, "METADATA", "is_compress", is_compress);
    +		g_key_file_set_string(sb_keyfile, "METADATA", "father_ss",
    +				father_snapshot);
    +		g_key_file_set_uint64(sb_keyfile, "METADATA", "snapshot_inode",
    +				inode_addr);
    +		g_key_file_set_uint64(sb_keyfile, "METADATA", "max_fs_size",
    +				father_max_fs_size);
    +		gchar *data = g_key_file_to_data(sb_keyfile, NULL, NULL);
    +		if (0 != son_storage->bs_file_delete(son_storage, "superblock")) {
    +			g_message("can not delete old superblock file");
    +			return -1;
    +		}
    +		if (0 != file_append_contents(son_storage, "superblock", (char*)data,
    +					strlen(data) + 1)) {
    +			g_message("can not write superblock file");
    +			return -1;
    +		}
    +		deinit_storage_handler(son_storage);
    +		deinit_storage_handler(father_storage);
    +	} else {
    +		struct back_storage *storage = init_storage_handler(vdi);
    +		if (NULL == storage) {
    +			g_message("can not get storage handler for uri:%s", vdi);
    +			return -1;
    +		}
    +		if ((0 == storage->bs_file_is_exist(storage, NULL)) && (0 ==
    +					storage->bs_file_is_exist(storage, "superblock"))) {
    +			g_message("hlfs with uri:%s has exist",vdi);
    +			return 1;
    +		}
    +		if (0 != storage->bs_file_mkdir(storage, NULL)) {
    +			g_message("can not mkdir for our fs %s", vdi);
    +		}
    +		GKeyFile *sb_keyfile = g_key_file_new();
    +		g_key_file_set_string(sb_keyfile, "METADATA", "uri", vdi);
    +		g_key_file_set_integer(sb_keyfile, "METADATA", "block_size", 8192);
    +		g_key_file_set_integer(sb_keyfile, "METADATA", "is_compress", is_compress);
    +		g_key_file_set_integer(sb_keyfile, "METADATA", "segment_size",
    +				67108864);
    +		g_key_file_set_integer(sb_keyfile, "METADATA", "max_fs_size",
    +				vdi_size/(1024 * 1024));
    +		gchar *data = g_key_file_to_data(sb_keyfile, NULL, NULL);
    +		char *head, *hostname, *dir, *fs_name;
    +		int port;
    +		parse_from_uri(vdi, &head, &hostname, &dir, &fs_name, &port);
    +		char *sb_file_path = g_build_filename(dir, fs_name, "superblock", NULL);
    +		bs_file_t file = storage->bs_file_create(storage, "superblock");
    +		if (NULL == file) {
    +			g_message("open file :superblock failed");
    +			g_free(sb_file_path);
    +			return -1;
    +		}
    +		int size = storage->bs_file_append(storage, file, (char*)data,
    +				strlen(data) + 1);
    +		if (size != strlen(data) + 1) {
    +			g_message("can not write superblock file");
    +			g_free(sb_file_path);
    +		}
    +		storage->bs_file_flush(storage, file);
    +		storage->bs_file_close(storage, file);
    +		deinit_storage_handler(storage);
    +	}
    +	return 0;
    +}
    +
    +static void hlbs_close(BlockDriverState *bs)
    +{
    +	BDRVHLBSState *s = bs->opaque;
    +	if (s->hctrl) {
    +		hlfs_close(s->hctrl);
    +		deinit_hlfs(s->hctrl);
    +	}
    +}
    +
    +static int64_t hlbs_getlength(BlockDriverState *bs)
    +{
    +	BDRVHLBSState *s = bs->opaque;
    +	return s->hctrl->sb.max_fs_size*1024*1024;
    +}
    +
    +static int64_t hlbs_get_allocated_file_size(BlockDriverState *bs)
    +{
    +	BDRVHLBSState *s = bs->opaque;
    +	return s->hctrl->inode.length;
    +}
    +
    +static int hlbs_write(BlockDriverState *bs, int64_t sector_num, const uint8_t
    +		*buf, int nb_sectors)
    +{
    +	int ret;
    +	BDRVHLBSState *s = bs->opaque;
    +	uint32_t write_size = nb_sectors * 512;
    +	uint64_t offset = sector_num * 512;
    +	ret = hlfs_write(s->hctrl, (char *)buf, write_size, offset);
    +	if (ret != write_size) {
    +		return -EIO;
    +	}
    +	return 0;
    +}
    +
    +static int hlbs_read(BlockDriverState *bs, int64_t sector_num, uint8_t *buf,
    +		int nb_sectors)
    +{
    +	int ret;
    +	BDRVHLBSState *s = bs->opaque;
    +	uint32_t read_size = nb_sectors * 512;
    +	uint64_t offset = sector_num * 512;
    +	ret = hlfs_read(s->hctrl, (char *)buf, read_size, offset);
    +	if (ret != read_size) {
    +		return -EIO;
    +	}
    +	return 0;
    +}
    +
    +static int hlbs_flush(BlockDriverState *bs)
    +{
    +	int ret;
    +	BDRVHLBSState *s = bs->opaque;
    +	ret = hlfs_flush(s->hctrl);
    +	return ret;
    +}
    +
    +static int hlbs_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
    +{
    +	int ret = 0;
    +	BDRVHLBSState *s = bs->opaque;
    +	dprintf("sn_info: name %s id_str %s vm_state_size %llu\n", sn_info->name,
    +			sn_info->id_str, sn_info->vm_state_size);
    +	dprintf("%s %s\n", sn_info->name, sn_info->id_str);
    +	ret = hlfs_take_snapshot(s->hctrl, sn_info->name);
    +	return ret;
    +}
    +
    +static int hlbs_snapshot_goto(BlockDriverState *bs, const char *snapshot)
    +{
    +	int ret;
    +	BDRVHLBSState *s = bs->opaque;
    +	char vdi[265];
    +
    +	memset(vdi, 0, sizeof(vdi));
    +	strncpy(vdi, s->hctrl->storage->uri, sizeof(vdi));
    +	hlfs_close(s->hctrl);
    +	deinit_hlfs(s->hctrl);
    +	HLFS_CTRL *ctrl = init_hlfs(vdi);
    +	s->hctrl = ctrl;
    +	ret = hlfs_open_by_snapshot(ctrl, snapshot, 1);
    +	if (ret != 0) {
    +		goto out;
    +	}
    +	s->hctrl = ctrl;
    +	s->uri = g_strdup(vdi);
    +	s->snapshot = g_strdup(vdi);
    +	bs->total_sectors = ctrl->sb.max_fs_size * 1024 * 1024 / SECTOR_SIZE;
    +	return 0;
    +out:
    +	if (s->hctrl!=NULL) {
    +		hlfs_close(s->hctrl);
    +		deinit_hlfs(s->hctrl);
    +	}
    +	return -1;
    +}
    +
    +static int hlbs_snapshot_delete(BlockDriverState *bs, const char *snapshot)
    +{
    +	/* FIXME: Delete specified snapshot id.  */
    +	BDRVHLBSState *s = bs->opaque;
    +	int ret = 0;
    +	ret = hlfs_rm_snapshot(s->hctrl->storage->uri, snapshot);
    +	return ret;
    +}
    +
    +static int hlbs_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)
    +{
    +	BDRVHLBSState *s = bs->opaque;
    +	/*Fixed: num_entries must be inited 0*/
    +	int num_entries = 0;
    +	struct snapshot *snapshots = hlfs_get_all_snapshots(s->hctrl->storage->uri,
    +		&num_entries);
    +	dprintf("snapshot count:%d\n",num_entries);
    +	/*Fixed: snapshots is NULL condition*/
    +	if (NULL == snapshots) {
    +		dprintf("snapshots is NULL, may be no snapshots, check it please!\n");
    +		return num_entries;
    +	}
    +	QEMUSnapshotInfo *sn_tab = NULL;
    +	struct snapshot * snapshot = snapshots;
    +	sn_tab = g_malloc0(num_entries * sizeof(*sn_tab));
    +	int i;
    +	for (i = 0; i < num_entries; i++) {
    +		printf("---snapshot:%s----",snapshot->sname);
    +		sn_tab[i].date_sec = snapshot->timestamp * 1000;
    +		sn_tab[i].date_nsec = 0;
    +		sn_tab[i].vm_state_size = 0;
    +		sn_tab[i].vm_clock_nsec = 0;
    +		snprintf(sn_tab[i].id_str, sizeof(sn_tab[i].id_str), "%u",0);
    +		strncpy(sn_tab[i].name, snapshot->sname, MIN(sizeof(sn_tab[i].name),
    +					strlen(snapshot->sname)));
    +		snapshot++;
    +	}
    +	*psn_tab = sn_tab;
    +	if (snapshots != NULL) {
    +		g_free(snapshots);
    +	}
    +	return num_entries;
    +}
    +
    +static QEMUOptionParameter hlbs_create_options[] = {
    +	{
    +		.name = BLOCK_OPT_SIZE,
    +		.type = OPT_SIZE,
    +		.help = "Virtual disk size"
    +	}, {
    +		.name = BLOCK_OPT_BACKING_FILE,
    +		.type = OPT_STRING,
    +		.help = "File name of a base image"
    +	}, {
    +		.name = BLOCK_OPT_PREALLOC,
    +		.type = OPT_STRING,
    +		.help = "Preallocation mode (allowed values: off, full)"
    +	}, { NULL }
    +};
    +
    +static BlockDriver bdrv_hlbs = {
    +	.format_name    = "hlfs",
    +	.protocol_name  = "hlfs",
    +	.instance_size  = sizeof(BDRVHLBSState),
    +	.bdrv_file_open = hlbs_open,
    +	.bdrv_close     = hlbs_close,
    +	.bdrv_create    = hlbs_create,
    +	.bdrv_getlength = hlbs_getlength,
    +	.bdrv_read  = hlbs_read,
    +	.bdrv_write = hlbs_write,
    +	.bdrv_get_allocated_file_size  = hlbs_get_allocated_file_size,
    +	.bdrv_snapshot_create   = hlbs_snapshot_create,
    +	.bdrv_snapshot_goto     = hlbs_snapshot_goto,
    +	.bdrv_snapshot_delete   = hlbs_snapshot_delete,
    +	.bdrv_snapshot_list     = hlbs_snapshot_list,
    +	.create_options = hlbs_create_options,
    +};
    +
    +static void bdrv_hlbs_init(void)
    +{
    +	if (log4c_init()) {
    +		g_message("log4c_init error!");
    +	}
    +	bdrv_register(&bdrv_hlbs);
    +}
    +
    +block_init(bdrv_hlbs_init);
    diff --git a/configure b/configure
    index 994f731..b99c6da 100755
    --- a/configure
    +++ b/configure
    @@ -223,6 +223,7 @@ libiscsi=""
     coroutine=""
     seccomp=""
     glusterfs=""
    +hlfs=""
     
     # parse CC options first
     for opt do
    @@ -871,6 +872,10 @@ for opt do
       ;;
       --enable-glusterfs) glusterfs="yes"
       ;;
    +  --disable-hlfs) hlfs="no"
    +  ;;
    +  --enable-hlfs) hlfs="yes"
    +  ;;
       *) echo "ERROR: unknown option $opt"; show_help="yes"
       ;;
       esac
    @@ -1119,6 +1124,8 @@ echo "  --with-coroutine=BACKEND coroutine backend. Supported options:"
     echo "                           gthread, ucontext, sigaltstack, windows"
     echo "  --enable-glusterfs       enable GlusterFS backend"
     echo "  --disable-glusterfs      disable GlusterFS backend"
    +echo "  --enable-hlfs			 enable HLFS backend"
    +echo "  --disable-hlfs		 disable HLFS backend"
     echo ""
     echo "NOTE: The object files are built at the place where configure is launched"
     exit 1
    @@ -2819,24 +2826,47 @@ fi
     ##########################################
     
     ##########################################
    -# check if we have fdatasync
    -
    -fdatasync=no
    -cat > $TMPC << EOF
    -#include 
    +# hlfs probe
    +if test "$hlfs" != "no" ; then
    +	cat > $TMPC <
    +#include 
     int main(void) {
    -#if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
    -return fdatasync(0);
    -#else
    -#error Not supported
    -#endif
    +	return 0;
     }
     EOF
    -if compile_prog "" "" ; then
    -    fdatasync=yes
    +	INC_GLIB_DIR=`pkg-config --cflags glib-2.0`
    +	HLFS_DIR=`echo $HLFS_INSTALL_PATH`
    +	JVM_DIR=`echo $JAVA_HOME`
    +
    +	if [ `getconf LONG_BIT` -eq "64" ];then
    +		CLIBS="-L$JVM_DIR/jre/lib/amd64/server/ $CLIBS"
    +	fi
    +
    +	if [ `getconf LONG_BIT` -eq "32" ];then
    +		CLIBS="-L$JVM_DIR/jre/lib/i386/server $CLIBS"
    +	fi
    +
    +	CLIBS="-L$HLFS_DIR/lib $CLIBS"
    +	CFLAGS="-I$HLFS_DIR/include $CFLAGS"
    +	CFLAGS="$INC_GLIB_DIR $CFLAGS"
    +
    +	hlfs_libs="$CLIBS -lhlfs -llog4c -lglib-2.0 -lgthread-2.0 -lrt -lhdfs -ljvm"
    +	if compile_prog "$CFLAGS" "$CLIBS $hlfs_libs" ; then
    +		hlfs=yes
    +		libs_tools="$hlfs_libs $libs_tools"
    +		libs_softmmu="$hlfs_libs $libs_softmmu"
    +	else
    +		if test "$hlfs" = "yes" ; then
    +			feature_not_found "hlfs block device"
    +		fi
    +		hlfs=no
    +	fi
     fi
     
     ##########################################
    +
    +##########################################
     # check if we have madvise
     
     madvise=no
    @@ -3250,6 +3280,7 @@ echo "build guest agent $guest_agent"
     echo "seccomp support   $seccomp"
     echo "coroutine backend $coroutine_backend"
     echo "GlusterFS support $glusterfs"
    +echo "HLFS support		$hlfs"
     
     if test "$sdl_too_old" = "yes"; then
     echo "-> Your SDL version is too old - please upgrade to have SDL support"
    @@ -4149,6 +4180,10 @@ if test "$gprof" = "yes" ; then
       fi
     fi
     
    +if test "$hlfs" = "yes" ; then
    +	echo "CONFIG_HLFS=y" >> $config_target_mak
    +fi
    +
     if test "$ARCH" = "tci"; then
       linker_script=""
     else
    -- 
    1.7.9.5
    

阅读(1741) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~
评论热议
请登录后评论。

登录 注册