qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH V3 0/5] libqblock qemu block layer library
@ 2012-09-18  9:01 Wenchao Xia
  2012-09-18  9:01 ` [Qemu-devel] [PATCH V3 1/5] libqblock build system Wenchao Xia
                   ` (4 more replies)
  0 siblings, 5 replies; 18+ messages in thread
From: Wenchao Xia @ 2012-09-18  9:01 UTC (permalink / raw)
  To: qemu-devel
  Cc: kwolf, aliguori, stefanha, blauwirbel, pbonzini, eblake,
	Wenchao Xia

  This patch introduce libqblock API, make libqblock.la and make check-libqblock
could build this library.
Functionalities:
 1 create a new image.
 2 sync access of an image.
 3 basic image information retrieving such as backing file.
 4 detect if a sector is allocated in an image.
Supported Formats:
 ALL using file protocols.

v2:
  Insert reserved bytes into union.
  Use uint64_t instead of size_t, offset.
  Use const char * in filename pointer.
  Initialization function removed and it was automatically executed when
library is loaded.
  Added compile flag visibility=hidden, to avoid name space pollution.
  Structure naming style changed.
  Using byte unit instead of sector for every API.
  Added a member in image static information structure, to report logical
sector size, which is always 512 now.
  Read and write API can take request not aligned to 512 now. It returns the
byte number that have succeed in operation, but now either negative value
or the number requested would be returned, because qemu block sync I/O API
would not return such number.
  Typo fix due to comments and improved documents.

v3:
  Removed the code about OOM error, introduced GError.
  Used a table to map from string to enum types about format.
  Use typedef for every structure.
  Improved the gcc compiler macro to warn if gcc was not used.
  Global variable name changed with prefix libqb_.
  The struct QBlockStaticInfo was changed to folder full format related
information inside, and a new member with pointers pointing to the mostly used
members, such as backing file, virt size, was added. This would allow the user
to get full information about how it is created in the future.
  Each patch in the serial can work with qemu now.
  Typo fixes.

Wenchao Xia (5):
  libqblock build system
  libqblock type defines
  libqblock API
  libqblock test build system
  libqblock test example code

 .gitignore                       |    1 +
 Makefile                         |   14 +-
 Makefile.objs                    |    6 +
 block.c                          |    2 +-
 block.h                          |    1 +
 libqblock/Makefile               |   64 +++
 libqblock/libqblock-error.c      |   57 ++
 libqblock/libqblock-error.h      |   49 ++
 libqblock/libqblock-internal.h   |   56 ++
 libqblock/libqblock-types.h      |  268 +++++++++
 libqblock/libqblock.c            | 1140 ++++++++++++++++++++++++++++++++++++++
 libqblock/libqblock.h            |  297 ++++++++++
 tests/Makefile                   |    3 +
 tests/libqblock/Makefile         |   32 ++
 tests/libqblock/libqblock-test.c |  237 ++++++++
 15 files changed, 2225 insertions(+), 2 deletions(-)
 create mode 100644 libqblock/Makefile
 create mode 100644 libqblock/libqblock-error.c
 create mode 100644 libqblock/libqblock-error.h
 create mode 100644 libqblock/libqblock-internal.h
 create mode 100644 libqblock/libqblock-types.h
 create mode 100644 libqblock/libqblock.c
 create mode 100644 libqblock/libqblock.h
 create mode 100644 tests/libqblock/Makefile
 create mode 100644 tests/libqblock/libqblock-test.c

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [Qemu-devel] [PATCH V3 1/5] libqblock build system
  2012-09-18  9:01 [Qemu-devel] [PATCH V3 0/5] libqblock qemu block layer library Wenchao Xia
@ 2012-09-18  9:01 ` Wenchao Xia
  2012-09-18 10:05   ` Paolo Bonzini
  2012-09-18 10:31   ` Paolo Bonzini
  2012-09-18  9:01 ` [Qemu-devel] [PATCH V3 2/5] libqblock type defines Wenchao Xia
                   ` (3 subsequent siblings)
  4 siblings, 2 replies; 18+ messages in thread
From: Wenchao Xia @ 2012-09-18  9:01 UTC (permalink / raw)
  To: qemu-devel
  Cc: kwolf, aliguori, stefanha, blauwirbel, pbonzini, eblake,
	Wenchao Xia

  Libqblock was placed in new directory ./libqblock, libtool will build
dynamic library there, source files of block layer remains in ./block.
So block related source code will generate 3 sets of binary, first is old
ones used in qemu, second and third are non PIC and PIC ones in ./libqblock.
  GCC compiler flag visibility=hidden was used with special macro, to export
only symbols that was marked as PUBLIC.

Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
---
 Makefile                    |   13 ++++++++-
 Makefile.objs               |    6 ++++
 libqblock/Makefile          |   64 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 82 insertions(+), 1 deletions(-)
 create mode 100644 libqblock/Makefile
 create mode 100644 libqblock/libqblock-error.c
 create mode 100644 libqblock/libqblock.c

diff --git a/Makefile b/Makefile
index 971e92f..b0b9b8d 100644
--- a/Makefile
+++ b/Makefile
@@ -164,6 +164,17 @@ qemu-io$(EXESUF): qemu-io.o cmd.o $(tools-obj-y) $(block-obj-y)
 
 qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o
 
+######################################################################
+# Support building shared library libqblock
+ifeq ($(LIBTOOL),)
+$(libqblock-lib-la):
+	@echo "libtool is missing, please install and rerun configure"; exit 1
+else
+$(libqblock-lib-la):
+	$(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C libqblock V="$(V)" TARGET_DIR="$*/" $(libqblock-lib-la),)
+endif
+###########################################################################
+
 vscclient$(EXESUF): $(libcacard-y) $(oslib-obj-y) $(trace-obj-y) $(tools-obj-y) qemu-timer-common.o libcacard/vscclient.o
 	$(call quiet-command,$(CC) $(LDFLAGS) -o $@ $^ $(libcacard_libs) $(LIBS),"  LINK  $@")
 
@@ -227,7 +238,7 @@ clean:
 	rm -rf qapi-generated
 	rm -rf qga/qapi-generated
 	$(MAKE) -C tests/tcg clean
-	for d in $(ALL_SUBDIRS) $(QEMULIBS) libcacard; do \
+	for d in $(ALL_SUBDIRS) $(QEMULIBS) libcacard libqblock; do \
 	if test -d $$d; then $(MAKE) -C $$d $@ || exit 1; fi; \
 	rm -f $$d/qemu-options.def; \
         done
diff --git a/Makefile.objs b/Makefile.objs
index 4412757..8a4c9fc 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -248,3 +248,9 @@ nested-vars += \
 	common-obj-y \
 	extra-obj-y
 dummy := $(call unnest-vars)
+
+#############################################################################
+# libqblock
+
+libqblock-lib-la = libqblock.la
+libqblock-lib-path = libqblock
diff --git a/libqblock/Makefile b/libqblock/Makefile
new file mode 100644
index 0000000..bf7abcc
--- /dev/null
+++ b/libqblock/Makefile
@@ -0,0 +1,64 @@
+###########################################################################
+# libqblock Makefile
+# Todo:
+#    1 trace related files is generated in this directory, move
+#  them to the root directory.
+##########################################################################
+-include ../config-host.mak
+-include $(SRC_PATH)/Makefile.objs
+-include $(SRC_PATH)/rules.mak
+
+#############################################################################
+# Library settings
+#############################################################################
+$(call set-vpath, $(SRC_PATH))
+
+#expand the foldered vars,especially ./block
+dummy := $(call unnest-vars-1)
+
+#library objects
+tools-obj-y = $(oslib-obj-y) $(trace-obj-y) qemu-tool.o qemu-timer.o \
+	qemu-timer-common.o main-loop.o notify.o \
+	iohandler.o cutils.o iov.o async.o
+tools-obj-$(CONFIG_POSIX) += compatfd.o
+
+libqblock-y=libqblock.o libqblock-error.o
+libqblock-lib-y=$(patsubst %.o,%.lo,$(libqblock-y))
+
+QEMU_OBJS=$(tools-obj-y) $(block-obj-y)
+QEMU_OBJS_FILTERED=$(filter %.o,$(QEMU_OBJS))
+QEMU_OBJS_LIB=$(patsubst %.o, %.lo,$(QEMU_OBJS_FILTERED))
+
+QEMU_CFLAGS+= -I../ -I../include
+#adding magic macro define for symbol hiding and exposing
+QEMU_CFLAGS+= -fvisibility=hidden -D LIBQB_BUILD
+
+#dependency libraries
+LIBS+=-lz $(LIBS_TOOLS)
+
+#################################################################
+# Runtime rules
+#################################################################
+clean:
+	rm -f *.lo *.o *.d *.la libqblock-test trace.c trace.c-timestamp
+	rm -rf .libs block trace
+
+all: libqblock-test
+	@true
+
+help:
+	@echo type make libqblock-test at root dirtory, libtool is required
+
+#make dir block at runtime which would hold the output of block/*.c
+block:
+	@mkdir block
+
+ifeq ($(LIBTOOL),)
+$(libqblock-lib-la):
+	@echo "libtool is missing, please install and rerun configure"; exit 1
+else
+$(libqblock-lib-la): $(libqblock-lib-y) $(QEMU_OBJS_LIB)
+	$(call quiet-command,$(LIBTOOL) --mode=link --quiet --tag=CC $(CC) -rpath $(libdir) -o $@ $^ $(LIBS),"  lt LINK $@")
+endif
+
+.PHONY: libqblock.la
diff --git a/libqblock/libqblock-error.c b/libqblock/libqblock-error.c
new file mode 100644
index 0000000..e69de29
diff --git a/libqblock/libqblock.c b/libqblock/libqblock.c
new file mode 100644
index 0000000..e69de29
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Qemu-devel] [PATCH V3 2/5] libqblock type defines
  2012-09-18  9:01 [Qemu-devel] [PATCH V3 0/5] libqblock qemu block layer library Wenchao Xia
  2012-09-18  9:01 ` [Qemu-devel] [PATCH V3 1/5] libqblock build system Wenchao Xia
@ 2012-09-18  9:01 ` Wenchao Xia
  2012-09-18 10:05   ` Paolo Bonzini
  2012-09-18  9:01 ` [Qemu-devel] [PATCH V3 3/5] libqblock API Wenchao Xia
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 18+ messages in thread
From: Wenchao Xia @ 2012-09-18  9:01 UTC (permalink / raw)
  To: qemu-devel
  Cc: kwolf, aliguori, stefanha, blauwirbel, pbonzini, eblake,
	Wenchao Xia

  This patch contains type and defines used in APIs, one file for public usage
by user, one for libqblock internal usage.

Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
---
 libqblock/libqblock-internal.h |   56 +++++++++
 libqblock/libqblock-types.h    |  268 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 324 insertions(+), 0 deletions(-)
 create mode 100644 libqblock/libqblock-internal.h
 create mode 100644 libqblock/libqblock-types.h

diff --git a/libqblock/libqblock-internal.h b/libqblock/libqblock-internal.h
new file mode 100644
index 0000000..87f32be
--- /dev/null
+++ b/libqblock/libqblock-internal.h
@@ -0,0 +1,56 @@
+/*
+ * QEMU block layer library
+ *
+ * Copyright IBM, Corp. 2012
+ *
+ * Authors:
+ *  Wenchao Xia   <xiawenc@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#ifndef LIBQBLOCK_INTERNAL
+#define LIBQBLOCK_INTERNAL
+
+#include "glib.h"
+
+#include "block.h"
+#include "block_int.h"
+#include "libqblock-types.h"
+
+/* this file contains defines and types used inside the library. */
+
+#define FUNC_FREE(p) g_free((p))
+#define FUNC_MALLOC(size) g_malloc((size))
+#define FUNC_CALLOC(nmemb, size) g_malloc0((nmemb)*(size))
+
+#define CLEAN_FREE(p) { \
+        FUNC_FREE(p); \
+        (p) = NULL; \
+}
+
+/* details should be hidden to user */
+struct QBlockState {
+    BlockDriverState *bdrvs;
+    /* internal used file name now, if it is not NULL, it means
+       image was opened.
+    */
+    char *filename;
+} ;
+
+struct QBroker {
+    /* last error */
+    GError *g_error;
+    int err_ret; /* 1st level of error, the libqblock error number */
+    int err_no; /* 2nd level of error, errno what below reports */
+};
+
+#define G_LIBQBLOCK_ERROR g_libqbock_error_quark()
+
+static inline GQuark g_libqbock_error_quark(void)
+{
+    return g_quark_from_static_string("g-libqblock-error-quark");
+}
+#endif
diff --git a/libqblock/libqblock-types.h b/libqblock/libqblock-types.h
new file mode 100644
index 0000000..3c548b8
--- /dev/null
+++ b/libqblock/libqblock-types.h
@@ -0,0 +1,268 @@
+/*
+ * QEMU block layer library
+ *
+ * Copyright IBM, Corp. 2012
+ *
+ * Authors:
+ *  Wenchao Xia   <xiawenc@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#ifndef LIBQBLOCK_TYPES_H
+#define LIBQBLOCK_TYPES_H
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#if defined(__GNUC__) && __GNUC__ >= 4
+    #ifdef LIBQB_BUILD
+        #define DLL_PUBLIC __attribute__((visibility("default")))
+    #else
+        #define DLL_PUBLIC
+    #endif
+#else
+    #warning : gcc compiler version < 4, symbols can not be hidden.
+#endif
+
+/* this library is designed around this core struct. */
+typedef struct QBlockState QBlockState;
+
+/* every thread should have a broker. */
+typedef struct QBroker QBroker;
+
+/* flag used in open and create */
+#define LIBQBLOCK_O_RDWR        0x0002
+/* do not use the host page cache */
+#define LIBQBLOCK_O_NOCACHE     0x0020
+/* use write-back caching */
+#define LIBQBLOCK_O_CACHE_WB    0x0040
+/* don't open the backing file */
+#define LIBQBLOCK_O_NO_BACKING  0x0100
+/* disable flushing on this disk */
+#define LIBQBLOCK_O_NO_FLUSH    0x0200
+
+#define LIBQBLOCK_O_CACHE_MASK \
+   (LIBQBLOCK_O_NOCACHE | LIBQBLOCK_O_CACHE_WB | LIBQBLOCK_O_NO_FLUSH)
+
+#define LIBQBLOCK_O_VALID_MASK \
+   (LIBQBLOCK_O_RDWR | LIBQBLOCK_O_NOCACHE | LIBQBLOCK_O_CACHE_WB | \
+    LIBQBLOCK_O_NO_BACKING | LIBQBLOCK_O_NO_FLUSH)
+
+typedef enum QBlockProtType {
+    QB_PROT_NONE = 0,
+    QB_PROT_FILE,
+    QB_PROT_MAX
+} QBlockProtType;
+
+typedef struct QBlockProtOptionFile {
+    const char *filename;
+} QBlockProtOptionFile;
+
+#define QBLOCK_PROT_OPTIONS_UNION_SIZE (512)
+typedef union QBlockProtOptionsUnion {
+    QBlockProtOptionFile o_file;
+    uint8_t reserved[QBLOCK_PROT_OPTIONS_UNION_SIZE];
+} QBlockProtOptionsUnion;
+
+/**
+ * struct QBlockProtInfo: contains information about how to find the image
+ *
+ * @prot_type: protocol type, now only support FILE.
+ * @prot_op: protocol related options.
+ */
+typedef struct QBlockProtInfo {
+    QBlockProtType prot_type;
+    QBlockProtOptionsUnion prot_op;
+} QBlockProtInfo;
+
+
+/* format related options */
+typedef enum QBlockFmtType {
+    QB_FMT_NONE = 0,
+    QB_FMT_COW,
+    QB_FMT_QED,
+    QB_FMT_QCOW,
+    QB_FMT_QCOW2,
+    QB_FMT_RAW,
+    QB_FMT_RBD,
+    QB_FMT_SHEEPDOG,
+    QB_FMT_VDI,
+    QB_FMT_VMDK,
+    QB_FMT_VPC,
+    QB_FMT_MAX
+} QBlockFmtType;
+
+typedef struct QBlockFmtOptionCow {
+    uint64_t virt_size;
+    QBlockProtInfo backing_loc;
+} QBlockFmtOptionCow;
+
+typedef struct QBlockFmtOptionQed {
+    uint64_t virt_size;
+    QBlockProtInfo backing_loc;
+    QBlockFmtType backing_fmt;
+    uint64_t cluster_size; /* unit is bytes */
+    uint64_t table_size; /* unit is clusters */
+} QBlockFmtOptionQed;
+
+typedef struct QBlockFmtOptionQcow {
+    uint64_t virt_size;
+    QBlockProtInfo backing_loc;
+    bool encrypt;
+} QBlockFmtOptionQcow;
+
+/* "Compatibility level (0.10 or 1.1)" */
+typedef enum QBlockFmtOptionQcow2CptLv {
+    QBO_FMT_QCOW2_CPT_NONE = 0,
+    QBO_FMT_QCOW2_CPT_V010,
+    QBO_FMT_QCOW2_CPT_V110,
+} QBlockFmtOptionQcow2CptLv;
+
+/* off or metadata */
+typedef enum QBlockFmtOptionQcow2PreAllocType {
+    QBO_FMT_QCOW2_PREALLOC_NONE = 0,
+    QBO_FMT_QCOW2_PREALLOC_OFF,
+    QBO_FMT_QCOW2_PREALLOC_METADATA,
+} QBlockFmtOptionQcow2PreAllocType;
+
+typedef struct QBlockFmtOptionQcow2 {
+    uint64_t virt_size;
+    QBlockProtInfo backing_loc;
+    QBlockFmtType backing_fmt;
+    bool encrypt;
+    uint64_t cluster_size; /* unit is bytes */
+    QBlockFmtOptionQcow2CptLv cpt_lv;
+    QBlockFmtOptionQcow2PreAllocType pre_mode;
+} QBlockFmtOptionQcow2;
+
+typedef struct QBlockFmtOptionRaw {
+    uint64_t virt_size;
+} QBlockFmtOptionRaw;
+
+typedef struct QBlockFmtOptionRbd {
+    uint64_t virt_size;
+    uint64_t cluster_size;
+} QBlockFmtOptionRbd;
+
+/* off or full */
+typedef enum QBlockFmtOptionSheepdogPreAllocType {
+    QBO_FMT_SD_PREALLOC_NONE = 0,
+    QBO_FMT_SD_PREALLOC_OFF,
+    QBO_FMT_SD_PREALLOC_FULL,
+} QBlockFmtOptionSheepdogPreAllocType;
+
+typedef struct QBlockFmtOptionSheepdog {
+    uint64_t virt_size;
+    QBlockProtInfo backing_loc;
+    QBlockFmtOptionSheepdogPreAllocType pre_mode;
+} QBlockFmtOptionSheepdog;
+
+typedef enum QBlockFmtOptionVdiPreAllocType {
+    QBO_FMT_VDI_PREALLOC_NONE = 0,
+    QBO_FMT_VDI_PREALLOC_FALSE,
+    QBO_FMT_VDI_PREALLOC_TRUE,
+} QBlockFmtOptionVdiPreAllocType;
+
+typedef struct QBlockFmtOptionVdi {
+    uint64_t virt_size;
+    uint64_t cluster_size;
+    QBlockFmtOptionVdiPreAllocType pre_mode;
+} QBlockFmtOptionVdi;
+
+/* whether compact to vmdk verion 6 */
+typedef enum QBlockFmtOptionVmdkCptLv {
+    QBO_FMT_VMDK_CPT_NONE = 0,
+    QBO_FMT_VMDK_CPT_VMDKV6_FALSE,
+    QBO_FMT_VMDK_CPT_VMDKV6_TRUE,
+} QBlockFmtOptionVmdkCptLv;
+
+/* vmdk flat extent format, values:
+"{monolithicSparse (default) | monolithicFlat | twoGbMaxExtentSparse |
+twoGbMaxExtentFlat | streamOptimized} */
+typedef enum QBlockFmtOptionVmdkSubfmtType {
+    QBO_FMT_VMDK_SUBFMT_MONOLITHIC_NONE = 0,
+    QBO_FMT_VMDK_SUBFMT_MONOLITHIC_SPARSE,
+    QBO_FMT_VMDK_SUBFMT_MONOLITHIC_FLAT,
+    QBO_FMT_VMDK_SUBFMT_TWOGBMAX_EXTENT_SPARSE,
+    QBO_FMT_VMDK_SUBFMT_TWOGBMAX_EXTENT_FLAT,
+    QBO_FMT_VMDK_SUBFMT_STREAM_OPTIMIZED,
+} QBlockFmtOptionVmdkSubfmtType;
+
+typedef struct QBlockFmtOptionVmdk {
+    uint64_t virt_size;
+    QBlockProtInfo backing_loc;
+    QBlockFmtOptionVmdkCptLv cpt_lv;
+    QBlockFmtOptionVmdkSubfmtType subfmt;
+} QBlockFmtOptionVmdk;
+
+/* "{dynamic (default) | fixed} " */
+typedef enum QBlockFmtOptionVpcSubfmtType {
+    QBO_FMT_VPC_SUBFMT_NONE = 0,
+    QBO_FMT_VPC_SUBFMT_DYNAMIC,
+    QBO_FMT_VPC_SUBFMT_FIXED,
+} QBlockFmtOptionVpcSubfmtType;
+
+typedef struct QBlockFmtOptionVpc {
+    uint64_t virt_size;
+    QBlockFmtOptionVpcSubfmtType subfmt;
+} QBlockFmtOptionVpc;
+
+#define QBLOCK_FMT_OPTIONS_UNION_SIZE (QBLOCK_PROT_OPTIONS_UNION_SIZE*2)
+typedef union QBlockFmtOptionsUnion {
+    QBlockFmtOptionCow       o_cow;
+    QBlockFmtOptionQed       o_qed;
+    QBlockFmtOptionQcow      o_qcow;
+    QBlockFmtOptionQcow2     o_qcow2;
+    QBlockFmtOptionRaw       o_raw;
+    QBlockFmtOptionRbd       o_rbd;
+    QBlockFmtOptionSheepdog  o_sheepdog;
+    QBlockFmtOptionVdi       o_vdi;
+    QBlockFmtOptionVmdk      o_vmdk;
+    QBlockFmtOptionVpc       o_vpc;
+    uint8_t reserved[QBLOCK_FMT_OPTIONS_UNION_SIZE];
+} QBlockFmtOptionsUnion;
+
+typedef struct QBlockFmtInfo {
+    QBlockFmtType fmt_type;
+    QBlockFmtOptionsUnion fmt_op;
+} QBlockFmtInfo;
+
+/**
+ * QBlockStaticInfoAddr: a structure contains a set of pointer.
+ *
+ *    this struct contains a set of pointer pointing to some
+ *  property related to format or protocol. If a property is not available,
+ *  it will be set as NULL. User could use this to get property directly.
+ *
+ *  @virt_size: virtual size, it is always not NULL.
+ *  @backing_loc: backing file location.
+ *  @encrypt: encryption flag.
+*/
+
+typedef struct QBlockStaticInfoAddr {
+    uint64_t *virt_size;
+    QBlockProtInfo *backing_loc;
+    bool *encrypt;
+} QBlockStaticInfoAddr;
+
+/**
+ * QBlockStaticInfo: information about the block image.
+ *
+ * @member_addr: contains pointer which can be used to access the structure.
+ * @loc: location information.
+ * @fmt: format information.
+ * @sector_size: how many bytes in a sector, it is 512 usually.
+ */
+typedef struct QBlockStaticInfo {
+    QBlockStaticInfoAddr *member_addr;
+    QBlockProtInfo loc;
+    QBlockFmtInfo fmt;
+    int sector_size;
+} QBlockStaticInfo;
+
+
+#endif
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Qemu-devel] [PATCH V3 3/5] libqblock API
  2012-09-18  9:01 [Qemu-devel] [PATCH V3 0/5] libqblock qemu block layer library Wenchao Xia
  2012-09-18  9:01 ` [Qemu-devel] [PATCH V3 1/5] libqblock build system Wenchao Xia
  2012-09-18  9:01 ` [Qemu-devel] [PATCH V3 2/5] libqblock type defines Wenchao Xia
@ 2012-09-18  9:01 ` Wenchao Xia
  2012-09-18  9:01 ` [Qemu-devel] [PATCH V3 4/5] libqblock test build system Wenchao Xia
  2012-09-18  9:01 ` [Qemu-devel] [PATCH V3 5/5] libqblock test example code Wenchao Xia
  4 siblings, 0 replies; 18+ messages in thread
From: Wenchao Xia @ 2012-09-18  9:01 UTC (permalink / raw)
  To: qemu-devel
  Cc: kwolf, aliguori, stefanha, blauwirbel, pbonzini, eblake,
	Wenchao Xia

  This patch contains the major APIs in the library.
Important APIs:
  1 QBroker. These structure was used to retrieve errors, every thread must
create one first, later maybe thread related staff could be added into it.
  2 QBlockState. It stands for an block image object.
  3 QBlockStaticInfo. It contains static information such as location, backing
file, size.
  4 ABI was kept with reserved members.
  5 Sync I/O. It is similar to C file open, read, write and close operations.

Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
---
 block.c                     |    2 +-
 block.h                     |    1 +
 libqblock/libqblock-error.c |   57 +++
 libqblock/libqblock-error.h |   49 ++
 libqblock/libqblock.c       | 1140 +++++++++++++++++++++++++++++++++++++++++++
 libqblock/libqblock.h       |  297 +++++++++++
 6 files changed, 1545 insertions(+), 1 deletions(-)
 create mode 100644 libqblock/libqblock-error.h
 create mode 100644 libqblock/libqblock.h

diff --git a/block.c b/block.c
index e78039b..d5321d3 100644
--- a/block.c
+++ b/block.c
@@ -196,7 +196,7 @@ static void bdrv_io_limits_intercept(BlockDriverState *bs,
 }
 
 /* check if the path starts with "<protocol>:" */
-static int path_has_protocol(const char *path)
+int path_has_protocol(const char *path)
 {
     const char *p;
 
diff --git a/block.h b/block.h
index 2e2be11..e7da711 100644
--- a/block.h
+++ b/block.h
@@ -405,4 +405,5 @@ typedef enum {
 #define BLKDBG_EVENT(bs, evt) bdrv_debug_event(bs, evt)
 void bdrv_debug_event(BlockDriverState *bs, BlkDebugEvent event);
 
+int path_has_protocol(const char *path);
 #endif
diff --git a/libqblock/libqblock-error.c b/libqblock/libqblock-error.c
index e69de29..9000e3e 100644
--- a/libqblock/libqblock-error.c
+++ b/libqblock/libqblock-error.c
@@ -0,0 +1,57 @@
+/*
+ * QEMU block layer library
+ *
+ * Copyright IBM, Corp. 2012
+ *
+ * Authors:
+ *  Wenchao Xia   <xiawenc@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#include "libqblock-error.h"
+#include "libqblock-internal.h"
+
+void qb_error_get_human_str(QBroker *broker,
+                            char *buf, size_t buf_size)
+{
+    const char *err_ret_str;
+    switch (broker->err_ret) {
+    case QB_ERR_INTERNAL_ERR:
+        err_ret_str = "Internal error.";
+        break;
+    case QB_ERR_INVALID_PARAM:
+        err_ret_str = "Invalid param.";
+        break;
+    case QB_ERR_BLOCK_OUT_OF_RANGE:
+        err_ret_str = "request is out of image's range.";
+        break;
+    default:
+        err_ret_str = "Unknown error.";
+        break;
+    }
+    if (broker == NULL) {
+        snprintf(buf, buf_size, "%s", err_ret_str);
+        return;
+    }
+
+    if (broker->err_ret == QB_ERR_INTERNAL_ERR) {
+        snprintf(buf, buf_size, "%s %s errno [%d]. strerror [%s].",
+                     err_ret_str, broker->g_error->message,
+                     broker->err_no, strerror(-broker->err_no));
+    } else {
+        snprintf(buf, buf_size, "%s %s",
+                     err_ret_str, broker->g_error->message);
+    }
+    return;
+}
+
+int qb_error_get_errno(QBroker *broker)
+{
+    if (broker->err_ret == QB_ERR_INTERNAL_ERR) {
+        return broker->err_no;
+    }
+    return 0;
+}
diff --git a/libqblock/libqblock-error.h b/libqblock/libqblock-error.h
new file mode 100644
index 0000000..83d6d98
--- /dev/null
+++ b/libqblock/libqblock-error.h
@@ -0,0 +1,49 @@
+/*
+ * QEMU block layer library
+ *
+ * Copyright IBM, Corp. 2012
+ *
+ * Authors:
+ *  Wenchao Xia   <xiawenc@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#ifndef LIBQBLOCK_ERROR
+#define LIBQBLOCK_ERROR
+
+#include "libqblock-types.h"
+
+#define QB_ERR_INTERNAL_ERR (-1)
+#define QB_ERR_INVALID_PARAM (-100)
+#define QB_ERR_BLOCK_OUT_OF_RANGE (-101)
+
+/* error handling */
+/**
+ * qb_error_get_human_str: get human readable error string.
+ *
+ * return a human readable string, it would be truncated if buf is not big
+ *  enough.
+ *
+ * @broker: operation broker, must be valid.
+ * @buf: buf to receive the string.
+ * @buf_size: the size of the string buf.
+ */
+DLL_PUBLIC
+void qb_error_get_human_str(QBroker *broker,
+                            char *buf, size_t buf_size);
+
+/**
+ * qb_error_get_errno: get error number, only valid when err_ret is
+ *   QB_ERR_INTERNAL_ERR.
+ *
+ * return negative errno or 0 if last error is not QB_ERR_INTERNAL_ERR.
+ *
+ * @broker: operation broker.
+ */
+DLL_PUBLIC
+int qb_error_get_errno(QBroker *broker);
+
+#endif
diff --git a/libqblock/libqblock.c b/libqblock/libqblock.c
index e69de29..2d9b351 100644
--- a/libqblock/libqblock.c
+++ b/libqblock/libqblock.c
@@ -0,0 +1,1140 @@
+/*
+ * QEMU block layer library
+ *
+ * Copyright IBM, Corp. 2012
+ *
+ * Authors:
+ *  Wenchao Xia   <xiawenc@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#include <unistd.h>
+#include <stdarg.h>
+
+#include "libqblock.h"
+#include "libqblock-internal.h"
+
+#include "qemu-aio.h"
+
+#define LIBQB_FILENAME_MAX 4096
+
+typedef struct LibqblockGlobalData {
+    int init_flag;
+} LibqblockGlobalData;
+
+LibqblockGlobalData libqb_global_data;
+
+typedef struct LibqbFmtStrMapping {
+    const char *fmt_str;
+    QBlockFmtType fmt_type;
+} LibqbFmtStrMapping;
+
+LibqbFmtStrMapping libqb_fmtstr_table[] = {
+    {"cow", QB_FMT_COW},
+    {"qed", QB_FMT_QED},
+    {"qcow", QB_FMT_QCOW},
+    {"qcow2", QB_FMT_QCOW2},
+    {"raw", QB_FMT_RAW},
+    {"rbd", QB_FMT_RBD},
+    {"sheepdog", QB_FMT_SHEEPDOG},
+    {"vdi", QB_FMT_VDI},
+    {"vmdk", QB_FMT_VMDK},
+    {"vpc", QB_FMT_VPC},
+    {NULL, 0},
+};
+
+__attribute__((constructor))
+static void libqblock_init(void)
+{
+    if (libqb_global_data.init_flag == 0) {
+        bdrv_init();
+        qemu_init_main_loop();
+    }
+    libqb_global_data.init_flag = 1;
+}
+
+const char *qb_fmttype2str(QBlockFmtType fmt_type)
+{
+    int i = 0;
+    LibqbFmtStrMapping *tb = libqb_fmtstr_table;
+
+    while (tb[i].fmt_str != NULL) {
+        if (tb[i].fmt_type == fmt_type) {
+            return tb[i].fmt_str;
+        }
+        i++;
+    }
+    return NULL;
+}
+
+QBlockFmtType qb_str2fmttype(const char *fmt_str)
+{
+    int i = 0;
+    LibqbFmtStrMapping *tb = libqb_fmtstr_table;
+
+    while (tb[i].fmt_str != NULL) {
+        if ((strcmp(fmt_str, tb[i].fmt_str) == 0)) {
+            return tb[i].fmt_type;
+        }
+        i++;
+    }
+    return QB_FMT_NONE;
+}
+
+static void set_broker_err(QBroker *broker, int err_ret,
+                           const char *fmt, ...)
+{
+    va_list ap;
+
+    if (broker->g_error != NULL) {
+        g_error_free(broker->g_error);
+    }
+
+    va_start(ap, fmt);
+    broker->g_error = g_error_new_valist(G_LIBQBLOCK_ERROR, err_ret, fmt, ap);
+    va_end(ap);
+
+    broker->err_ret = err_ret;
+    if (err_ret == QB_ERR_INTERNAL_ERR) {
+        broker->err_no = -errno;
+    } else {
+        broker->err_no = 0;
+    }
+}
+
+int qb_broker_new(QBroker **broker)
+{
+    *broker = FUNC_CALLOC(1, sizeof(QBroker));
+    return 0;
+}
+
+void qb_broker_delete(QBroker **broker)
+{
+    if ((*broker)->g_error != NULL) {
+        g_error_free((*broker)->g_error);
+    }
+    CLEAN_FREE(*broker);
+    return;
+}
+
+int qb_state_new(QBroker *broker,
+                 QBlockState **qbs)
+{
+    *qbs = FUNC_CALLOC(1, sizeof(QBlockState));
+    (*qbs)->bdrvs = bdrv_new("hda");
+    if ((*qbs)->bdrvs == NULL) {
+        CLEAN_FREE(*qbs);
+        set_broker_err(broker, QB_ERR_INTERNAL_ERR,
+                       "failed to create the driver.");
+        return broker->err_ret;
+    }
+    return 0;
+}
+
+void qb_state_delete(QBroker *broker,
+                     QBlockState **qbs)
+{
+    if ((*qbs)->filename != NULL) {
+        qb_close(broker, *qbs);
+    }
+    if ((*qbs)->bdrvs != NULL) {
+        bdrv_delete((*qbs)->bdrvs);
+        (*qbs)->bdrvs = NULL;
+    }
+    CLEAN_FREE(*qbs);
+    return;
+}
+
+int qb_prot_info_new(QBroker *broker,
+                     QBlockProtInfo **op)
+{
+    *op = FUNC_CALLOC(1, sizeof(QBlockProtInfo));
+    return 0;
+}
+
+void qb_prot_info_delete(QBroker *broker,
+                         QBlockProtInfo **op)
+{
+    CLEAN_FREE(*op);
+}
+
+int qb_fmt_info_new(QBroker *broker,
+                    QBlockFmtInfo **op)
+{
+    *op = FUNC_CALLOC(1, sizeof(QBlockFmtInfo));
+    return 0;
+}
+
+void qb_fmt_info_delete(QBroker *broker,
+                        QBlockFmtInfo **op)
+{
+    CLEAN_FREE(*op);
+}
+
+/* return 0 if every thing is fine */
+static int loc_check_params(QBroker *broker,
+                            QBlockProtInfo *loc)
+{
+    broker->err_ret = 0;
+
+    switch (loc->prot_type) {
+    case QB_PROT_FILE:
+        if (loc->prot_op.o_file.filename == NULL) {
+            set_broker_err(broker, QB_ERR_INVALID_PARAM,
+                           "Filename was not set.");
+            goto out;
+        }
+        if (path_has_protocol(loc->prot_op.o_file.filename) > 0) {
+            set_broker_err(broker, QB_ERR_INVALID_PARAM,
+                           "filename [%s] had protocol.",
+                           loc->prot_op.o_file.filename);
+            goto out;
+        }
+        break;
+    default:
+        set_broker_err(broker, QB_ERR_INVALID_PARAM,
+                       "Protocol type [%d] was not valid.",
+                       loc->prot_type);
+        break;
+    }
+
+ out:
+    return broker->err_ret;
+}
+
+/* translate loc structure to internal filename, returned char* need free,
+ * assuming filename is not NULL. *filename would be set to NULL if no valid
+ * filename found. *filename must be freed later.
+ * return 0 if no error with *filename set.
+ */
+static int loc2filename(QBroker *broker,
+                        QBlockProtInfo *loc,
+                        char **filename)
+{
+    broker->err_ret = 0;
+
+    if (*filename != NULL) {
+        CLEAN_FREE(*filename);
+    }
+    switch (loc->prot_type) {
+    case QB_PROT_FILE:
+        *filename = g_strdup(loc->prot_op.o_file.filename);
+        break;
+    default:
+        set_broker_err(broker, QB_ERR_INVALID_PARAM,
+                 "protocol type [%d] is not supported.",
+                  loc->prot_type);
+        break;
+    }
+
+    return broker->err_ret;
+}
+
+/* translate filename to location, loc->prot_type = NONE if fail, filename
+   must be valid. loc internal char pointer must be freed later.
+ * return 0 if no error.
+ */
+static int filename2loc(QBroker *broker,
+                        QBlockProtInfo *loc,
+                        const char *filename)
+{
+    broker->err_ret = 0;
+
+    if (path_has_protocol(filename) > 0) {
+        set_broker_err(broker, QB_ERR_INVALID_PARAM,
+                     "Filename [%s] had protocol, not supported now.",
+                     filename);
+        goto out;
+    }
+
+    loc->prot_type = QB_PROT_FILE;
+    switch (loc->prot_type) {
+    case QB_PROT_FILE:
+        loc->prot_op.o_file.filename = g_strdup(filename);
+        break;
+    default:
+        break;
+    }
+
+ out:
+    return broker->err_ret;
+}
+
+/* return 0 if OK, or qblock error number */
+static int set_backing_file_options(QBroker *broker,
+                                    QEMUOptionParameter *param,
+                                    QBlockProtInfo *loc,
+                                    QBlockFmtType *fmt)
+{
+    char *backing_filename = NULL;
+    const char *fmtstr_backing = NULL;
+    int ret = 0;
+
+    if (loc == NULL) {
+        goto out;
+    }
+
+    ret = loc2filename(broker, loc, &backing_filename);
+    /* ret can < 0 if loc have not been set, mean user did not specify backing
+       file, so need to check return value */
+
+    ret = 0;
+
+    if (backing_filename) {
+        ret = set_option_parameter(param,
+                            BLOCK_OPT_BACKING_FILE, backing_filename);
+        assert(ret == 0);
+        if (fmt == NULL) {
+            goto out;
+        }
+        fmtstr_backing = qb_fmttype2str(*fmt);
+        if (fmtstr_backing) {
+            ret = set_option_parameter(param,
+                                BLOCK_OPT_BACKING_FMT, fmtstr_backing);
+            assert(ret == 0);
+        }
+    }
+
+ out:
+    FUNC_FREE(backing_filename);
+    return ret;
+}
+
+int qb_create(QBroker *broker,
+              QBlockState *qbs,
+              QBlockProtInfo *loc,
+              QBlockFmtInfo *fmt,
+              int flag)
+{
+    int ret = 0, bd_ret;
+    char *filename = NULL;
+    BlockDriverState *bs = NULL;
+    BlockDriver *drv = NULL, *backing_drv = NULL;
+    bool tmp_bool;
+
+    const char *fmtstr = NULL, *tmp = NULL;
+    QEMUOptionParameter *param = NULL, *create_options = NULL;
+    QEMUOptionParameter *backing_fmt, *backing_file, *size;
+    QBlockFmtOptionCow *o_cow = NULL;
+    QBlockFmtOptionQed *o_qed = NULL;
+    QBlockFmtOptionQcow *o_qcow = NULL;
+    QBlockFmtOptionQcow2 *o_qcow2 = NULL;
+    QBlockFmtOptionRaw *o_raw = NULL;
+    QBlockFmtOptionRbd *o_rbd = NULL;
+    QBlockFmtOptionSheepdog *o_sd = NULL;
+    QBlockFmtOptionVdi *o_vdi = NULL;
+    QBlockFmtOptionVmdk *o_vmdk = NULL;
+    QBlockFmtOptionVpc *o_vpc = NULL;
+
+
+    /* check parameters */
+    if (flag & (~LIBQBLOCK_O_VALID_MASK)) {
+        set_broker_err(broker, QB_ERR_INVALID_PARAM,
+                           "invalid flag was set.");
+        ret = broker->err_ret;
+        goto out;
+    }
+
+    if ((loc == NULL) || (qbs == NULL) || (fmt == NULL)) {
+        set_broker_err(broker, QB_ERR_INVALID_PARAM,
+                          "Got unexpected NULL pointer in parameters.");
+        ret = broker->err_ret;
+        goto out;
+    }
+
+    ret = loc_check_params(broker, loc);
+    if (ret != 0) {
+        goto out;
+    }
+
+    /* internal translate */
+    ret = loc2filename(broker, loc, &filename);
+    if (ret != 0) {
+        goto out;
+    }
+
+    fmtstr = qb_fmttype2str(fmt->fmt_type);
+    if (fmtstr == NULL) {
+        set_broker_err(broker, QB_ERR_INVALID_PARAM,
+                 "Got unexpected NULL pointer in parameters.");
+        ret = broker->err_ret;
+        goto out;
+    }
+
+    drv = bdrv_find_format(fmtstr);
+    assert(drv != NULL);
+
+    create_options = append_option_parameters(create_options,
+                                              drv->create_options);
+    param = parse_option_parameters("", create_options, param);
+
+    switch (fmt->fmt_type) {
+    case QB_FMT_COW:
+        o_cow = &(fmt->fmt_op.o_cow);
+        bd_ret = set_option_parameter_int(param,
+                                BLOCK_OPT_SIZE, o_cow->virt_size);
+        assert(bd_ret == 0);
+        /* do not need to check loc, it may be not set */
+        ret = set_backing_file_options(broker, param,
+                                       &o_cow->backing_loc, NULL);
+        if (ret != 0) {
+            goto out;
+        }
+        break;
+    case QB_FMT_QED:
+        o_qed = &(fmt->fmt_op.o_qed);
+        bd_ret = set_option_parameter_int(param,
+                                BLOCK_OPT_SIZE, o_qed->virt_size);
+        assert(bd_ret == 0);
+        ret = set_backing_file_options(broker, param,
+                                 &o_qed->backing_loc, &o_qed->backing_fmt);
+        if (ret != 0) {
+            goto out;
+        }
+        bd_ret = set_option_parameter_int(param,
+                                BLOCK_OPT_CLUSTER_SIZE, o_qed->cluster_size);
+        assert(bd_ret == 0);
+        bd_ret = set_option_parameter_int(param,
+                                BLOCK_OPT_TABLE_SIZE, o_qed->table_size);
+        assert(bd_ret == 0);
+        break;
+    case QB_FMT_QCOW:
+        o_qcow = &(fmt->fmt_op.o_qcow);
+        bd_ret = set_option_parameter_int(param,
+                                BLOCK_OPT_SIZE, o_qcow->virt_size);
+        assert(bd_ret == 0);
+        ret = set_backing_file_options(broker, param,
+                                       &o_qcow->backing_loc, NULL);
+        if (ret != 0) {
+            goto out;
+        }
+        tmp = o_qcow->encrypt ? "on" : "off";
+        bd_ret = set_option_parameter(param, BLOCK_OPT_ENCRYPT, tmp);
+        assert(bd_ret == 0);
+        break;
+    case QB_FMT_QCOW2:
+        o_qcow2 = &(fmt->fmt_op.o_qcow2);
+        bd_ret = set_option_parameter_int(param,
+                              BLOCK_OPT_SIZE, o_qcow2->virt_size);
+        assert(bd_ret == 0);
+        ret = set_backing_file_options(broker, param,
+                              &o_qcow2->backing_loc, &o_qcow2->backing_fmt);
+        if (ret != 0) {
+            goto out;
+        }
+        tmp = o_qcow2->encrypt ? "on" : "off";
+        bd_ret = set_option_parameter(param, BLOCK_OPT_ENCRYPT, tmp);
+        assert(bd_ret == 0);
+        bd_ret = set_option_parameter_int(param,
+                              BLOCK_OPT_CLUSTER_SIZE, o_qcow2->cluster_size);
+        assert(bd_ret == 0);
+
+        if (o_qcow2->cpt_lv != QBO_FMT_QCOW2_CPT_NONE) {
+            tmp = o_qcow2->cpt_lv == QBO_FMT_QCOW2_CPT_V010 ? "0.10" : "1.1";
+            bd_ret = set_option_parameter(param,
+                              BLOCK_OPT_COMPAT_LEVEL, tmp);
+            assert(bd_ret == 0);
+        }
+
+        if (o_qcow2->pre_mode != QBO_FMT_QCOW2_PREALLOC_NONE) {
+            tmp = o_qcow2->pre_mode == QBO_FMT_QCOW2_PREALLOC_OFF ?
+                                         "off" : "metadata";
+            bd_ret = set_option_parameter(param,
+                              BLOCK_OPT_PREALLOC, tmp);
+            assert(bd_ret == 0);
+        }
+        break;
+
+    case QB_FMT_RAW:
+        o_raw = &(fmt->fmt_op.o_raw);
+        bd_ret = set_option_parameter_int(param,
+                              BLOCK_OPT_SIZE, o_raw->virt_size);
+        assert(bd_ret == 0);
+        break;
+    case QB_FMT_RBD:
+        o_rbd = &(fmt->fmt_op.o_rbd);
+        bd_ret = set_option_parameter_int(param,
+                              BLOCK_OPT_SIZE, o_rbd->virt_size);
+        assert(bd_ret == 0);
+        bd_ret = set_option_parameter_int(param,
+                              BLOCK_OPT_CLUSTER_SIZE, o_rbd->cluster_size);
+        assert(bd_ret == 0);
+        break;
+    case QB_FMT_SHEEPDOG:
+        o_sd = &(fmt->fmt_op.o_sheepdog);
+        bd_ret = set_option_parameter_int(param,
+                              BLOCK_OPT_SIZE, o_sd->virt_size);
+        assert(bd_ret == 0);
+        ret = set_backing_file_options(broker, param,
+                                       &o_sd->backing_loc, NULL);
+        if (ret != 0) {
+            goto out;
+        }
+        if (o_sd->pre_mode != QBO_FMT_SD_PREALLOC_NONE) {
+            tmp = o_sd->pre_mode == QBO_FMT_SD_PREALLOC_OFF ? "off" : "full";
+            bd_ret = set_option_parameter(param,
+                              BLOCK_OPT_PREALLOC, tmp);
+            assert(bd_ret == 0);
+        }
+        break;
+    case QB_FMT_VDI:
+        o_vdi = &(fmt->fmt_op.o_vdi);
+        bd_ret = set_option_parameter_int(param,
+                              BLOCK_OPT_SIZE, o_vdi->virt_size);
+        assert(bd_ret == 0);
+        /* following option is not always valid depends on configuration */
+        set_option_parameter_int(param,
+                              BLOCK_OPT_CLUSTER_SIZE, o_vdi->cluster_size);
+        if (o_vdi->pre_mode != QBO_FMT_VDI_PREALLOC_NONE) {
+            tmp_bool = o_sd->pre_mode == QBO_FMT_VDI_PREALLOC_TRUE ?
+                                                     true : false;
+            set_option_parameter_int(param, "static", tmp_bool);
+        }
+        break;
+    case QB_FMT_VMDK:
+        o_vmdk = &(fmt->fmt_op.o_vmdk);
+        bd_ret = set_option_parameter_int(param,
+                              BLOCK_OPT_SIZE, o_vmdk->virt_size);
+        assert(bd_ret == 0);
+        ret = set_backing_file_options(broker, param,
+                                       &o_vmdk->backing_loc, NULL);
+        if (ret != 0) {
+            goto out;
+        }
+
+        if (o_vmdk->cpt_lv != QBO_FMT_VMDK_CPT_NONE) {
+            tmp_bool = o_vmdk->cpt_lv == QBO_FMT_VMDK_CPT_VMDKV6_TRUE ?
+                                                     true : false;
+            bd_ret = set_option_parameter_int(param, BLOCK_OPT_COMPAT6,
+                                                     tmp_bool);
+            assert(bd_ret == 0);
+        }
+        if (o_vmdk->subfmt != QBO_FMT_VMDK_SUBFMT_MONOLITHIC_NONE) {
+            switch (o_vmdk->subfmt) {
+            case QBO_FMT_VMDK_SUBFMT_MONOLITHIC_SPARSE:
+                tmp = "monolithicSparse";
+                break;
+            case QBO_FMT_VMDK_SUBFMT_MONOLITHIC_FLAT:
+                tmp = "monolithicFlat";
+                break;
+            case QBO_FMT_VMDK_SUBFMT_TWOGBMAX_EXTENT_SPARSE:
+                tmp = "twoGbMaxExtentSparse";
+                break;
+            case QBO_FMT_VMDK_SUBFMT_TWOGBMAX_EXTENT_FLAT:
+                tmp = "twoGbMaxExtentFlat";
+                break;
+            case QBO_FMT_VMDK_SUBFMT_STREAM_OPTIMIZED:
+                tmp = "streamOptimized";
+                break;
+            default:
+                assert(false);
+                break;
+            }
+            bd_ret = set_option_parameter(param,
+                              BLOCK_OPT_SUBFMT, tmp);
+            assert(bd_ret == 0);
+        }
+        break;
+    case QB_FMT_VPC:
+        o_vpc = &(fmt->fmt_op.o_vpc);
+        bd_ret = set_option_parameter_int(param,
+                               BLOCK_OPT_SIZE, o_vpc->virt_size);
+        assert(bd_ret == 0);
+        if (o_vpc->subfmt != QBO_FMT_VPC_SUBFMT_NONE) {
+            tmp = o_vpc->subfmt == QBO_FMT_VPC_SUBFMT_DYNAMIC ?
+                                               "dynamic" : "fixed";
+            bd_ret = set_option_parameter(param,
+                               BLOCK_OPT_SUBFMT, tmp);
+            assert(bd_ret == 0);
+        }
+        break;
+    default:
+        abort();
+        break;
+    }
+
+    backing_file = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
+    if (backing_file && backing_file->value.s) {
+        if (!strcmp(filename, backing_file->value.s)) {
+            set_broker_err(broker, QB_ERR_INVALID_PARAM,
+                          "Backing file is the same with new file.");
+            ret = broker->err_ret;
+            goto out;
+        }
+    }
+
+    backing_fmt = get_option_parameter(param, BLOCK_OPT_BACKING_FMT);
+    if (backing_fmt && backing_fmt->value.s) {
+        backing_drv = bdrv_find_format(backing_fmt->value.s);
+        assert(backing_drv != NULL);
+    }
+
+    size = get_option_parameter(param, BLOCK_OPT_SIZE);
+    if (size && size->value.n <= 0) {
+        if (backing_file && backing_file->value.s) {
+            uint64_t size;
+            char buf[32];
+            int back_flags;
+
+            /* backing files always opened read-only */
+            back_flags =
+                flag &
+                ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
+
+            bs = bdrv_new("");
+
+            ret = bdrv_open(bs, backing_file->value.s,
+                                back_flags, backing_drv);
+            if (ret < 0) {
+                set_broker_err(broker, QB_ERR_INVALID_PARAM,
+                               "Failed to open the backing file.");
+                ret = broker->err_ret;
+                goto out;
+            }
+            bdrv_get_geometry(bs, &size);
+            size *= BDRV_SECTOR_SIZE;
+
+            snprintf(buf, sizeof(buf), "%" PRId64, size);
+            set_option_parameter(param, BLOCK_OPT_SIZE, buf);
+        } else {
+            set_broker_err(broker, QB_ERR_INTERNAL_ERR,
+                           "Neither size or backing file was not set.");
+            ret = broker->err_ret;
+            goto out;
+        }
+    }
+
+    bd_ret = bdrv_create(drv, filename, param);
+
+
+    if (bd_ret < 0) {
+        const char *errstr;
+        if (bd_ret == -ENOTSUP) {
+            errstr = "formatting option not supported.";
+        } else if (bd_ret == -EFBIG) {
+            errstr = "The image size is too large.";
+        } else {
+            errstr = "Error in creating the image.";
+        }
+        set_broker_err(broker, QB_ERR_INTERNAL_ERR, errstr);
+        ret = broker->err_ret;
+    }
+
+out:
+    free_option_parameters(create_options);
+    free_option_parameters(param);
+    FUNC_FREE(filename);
+    if (bs) {
+        bdrv_delete(bs);
+    }
+
+    return ret;
+}
+
+int qb_open(QBroker *broker,
+            QBlockState *qbs,
+            QBlockProtInfo *loc,
+            QBlockFmtInfo *fmt,
+            int flag)
+{
+    int ret = 0, bd_ret;
+    BlockDriverState *bs;
+    BlockDriver *bd;
+    const char *fmtstr;
+    char *filename = NULL;
+
+    /* take care of user settings */
+    /* do nothing now */
+
+    /* check parameters */
+    if (flag & (~LIBQBLOCK_O_VALID_MASK)) {
+        set_broker_err(broker, QB_ERR_INVALID_PARAM,
+                      "Invalid flag was set.");
+        ret = broker->err_ret;
+        goto out;
+    }
+
+    if ((loc == NULL) || (qbs == NULL)) {
+        set_broker_err(broker, QB_ERR_INVALID_PARAM,
+                      "Got unexpected NULL pointer in parameters.");
+        ret = broker->err_ret;
+        goto out;
+    }
+
+    ret = loc_check_params(broker, loc);
+    if (ret != 0) {
+        goto out;
+    }
+
+    /* internal translate */
+    ret = loc2filename(broker, loc, &filename);
+    if (ret != 0) {
+        goto out;
+    }
+
+    fmtstr = NULL;
+    bd = NULL;
+    if (fmt != NULL) {
+        fmtstr = qb_fmttype2str(fmt->fmt_type);
+    }
+
+    if (fmtstr != NULL) {
+        bd = bdrv_find_format(fmtstr);
+        assert(bd != NULL);
+    }
+
+    /* do real opening */
+    bs = qbs->bdrvs;
+    bd_ret = bdrv_open(bs, filename, flag, bd);
+    if (bd_ret < 0) {
+        set_broker_err(broker, QB_ERR_INTERNAL_ERR,
+                      "Failed in opening with driver, bd_ret is %d.", bd_ret);
+        ret = broker->err_ret;
+        goto out;
+    }
+
+    if (qbs->filename != NULL) {
+        FUNC_FREE(qbs->filename);
+    }
+    qbs->filename = g_strdup(filename);
+
+ out:
+    FUNC_FREE(filename);
+    return ret;
+}
+
+void qb_close(QBroker *broker,
+              QBlockState *qbs)
+{
+    BlockDriverState *bs;
+
+    bs = qbs->bdrvs;
+
+    if (qbs->filename != NULL) {
+        CLEAN_FREE(qbs->filename);
+        bdrv_close(bs);
+    }
+    return;
+}
+
+int32_t qb_read(QBroker *broker,
+                QBlockState *qbs,
+                uint8_t *buf,
+                uint32_t len,
+                uint64_t offset)
+{
+    int bd_ret;
+    BlockDriverState *bs;
+    uint8_t temp_buf[BDRV_SECTOR_SIZE], *p;
+    uint64_t sector_start;
+    int sector_num, byte_offset, cp_len;
+    int remains;
+
+    broker->err_ret = 0;
+    bs = qbs->bdrvs;
+
+    if (len <= 0) {
+        set_broker_err(broker, QB_ERR_INVALID_PARAM,
+                      "Param len is less or equal to zero.");
+        return broker->err_ret;
+    }
+
+    p = buf;
+    remains = len;
+
+    sector_start = offset >> BDRV_SECTOR_BITS;
+
+    byte_offset = offset & (~BDRV_SECTOR_MASK);
+    if (byte_offset != 0) {
+        /* the start sector is not alligned, need to read/write this sector. */
+        bd_ret = bdrv_read(bs, sector_start, temp_buf, 1);
+        if (bd_ret < 0) {
+            set_broker_err(broker, QB_ERR_INTERNAL_ERR,
+                           "QEMU internal block error.");
+            return broker->err_ret;
+        }
+        cp_len = BDRV_SECTOR_SIZE - byte_offset;
+        memcpy(p, temp_buf + byte_offset, cp_len);
+
+        remains -= cp_len;
+        p += cp_len;
+        sector_start++;
+    }
+
+    /* now start position is alligned. */
+    if (remains >= BDRV_SECTOR_SIZE) {
+        sector_num = len >> BDRV_SECTOR_BITS;
+        bd_ret = bdrv_read(bs, sector_start, p, sector_num);
+        if (bd_ret < 0) {
+            set_broker_err(broker, QB_ERR_INTERNAL_ERR,
+                           "QEMU internal block error.");
+            return broker->err_ret;
+        }
+        remains -= sector_num << BDRV_SECTOR_BITS;
+        p += sector_num << BDRV_SECTOR_BITS;
+        sector_start += sector_num;
+    }
+
+    if (remains > 0) {
+        /* there is some request remains, less than 1 sector */
+        bd_ret = bdrv_read(bs, sector_start, temp_buf, 1);
+        if (bd_ret < 0) {
+            set_broker_err(broker, QB_ERR_INTERNAL_ERR,
+                           "QEMU internal block error.");
+            return broker->err_ret;
+        }
+        memcpy(p, temp_buf, remains);
+        remains -= remains;
+    }
+
+    return len-remains;
+}
+
+int32_t qb_write(QBroker *broker,
+                 QBlockState *qbs,
+                 const uint8_t *buf,
+                 uint32_t len,
+                 uint64_t offset)
+{
+    int bd_ret;
+    BlockDriverState *bs;
+    uint8_t temp_buf[BDRV_SECTOR_SIZE];
+    const uint8_t *p;
+    uint64_t sector_start;
+    int sector_num, byte_offset, cp_len;
+    int remains;
+
+    broker->err_ret = 0;
+    bs = qbs->bdrvs;
+
+    if (len <= 0) {
+        set_broker_err(broker, QB_ERR_INVALID_PARAM,
+                      "Param len is less or equal to zero.");
+        return broker->err_ret;
+    }
+
+    p = buf;
+    remains = len;
+
+    sector_start = offset >> BDRV_SECTOR_BITS;
+
+    byte_offset = offset & (~BDRV_SECTOR_MASK);
+    if (byte_offset != 0) {
+        /* the start sector is not alligned, need to read/write this sector. */
+        bd_ret = bdrv_read(bs, sector_start, temp_buf, 1);
+        if (bd_ret < 0) {
+            set_broker_err(broker, QB_ERR_INTERNAL_ERR,
+                           "QEMU internal block error.");
+            return broker->err_ret;
+        }
+        cp_len = BDRV_SECTOR_SIZE - byte_offset;
+        memcpy(temp_buf + byte_offset, p, cp_len);
+        bd_ret = bdrv_write(bs, sector_start, temp_buf, 1);
+        if (bd_ret < 0) {
+            set_broker_err(broker, QB_ERR_INTERNAL_ERR,
+                           "QEMU internal block error.");
+            return broker->err_ret;
+        }
+        remains -= cp_len;
+        p += cp_len;
+        sector_start++;
+    }
+
+    /* now start position is alligned. */
+    if (remains >= BDRV_SECTOR_SIZE) {
+        sector_num = len >> BDRV_SECTOR_BITS;
+        bd_ret = bdrv_write(bs, sector_start, p, sector_num);
+        if (bd_ret < 0) {
+            set_broker_err(broker, QB_ERR_INTERNAL_ERR,
+                           "QEMU internal block error.");
+            return broker->err_ret;
+        }
+        remains -= sector_num << BDRV_SECTOR_BITS;
+        p += sector_num << BDRV_SECTOR_BITS;
+        sector_start += sector_num;
+    }
+
+    if (remains > 0) {
+        /* there is some request remains, less than 1 sector */
+        bd_ret = bdrv_read(bs, sector_start, temp_buf, 1);
+        if (bd_ret < 0) {
+            set_broker_err(broker, QB_ERR_INTERNAL_ERR,
+                           "QEMU internal block error.");
+            return broker->err_ret;
+        }
+        memcpy(temp_buf, p, remains);
+        bd_ret = bdrv_write(bs, sector_start, temp_buf, 1);
+        if (bd_ret < 0) {
+            set_broker_err(broker, QB_ERR_INTERNAL_ERR,
+                           "QEMU internal block error.");
+            return broker->err_ret;
+        }
+        remains -= remains;
+    }
+
+    return len-remains;
+}
+
+int qb_flush(QBroker *broker,
+             QBlockState *qbs)
+{
+    int bd_ret;
+    BlockDriverState *bs;
+
+    broker->err_ret = 0;
+    bs = qbs->bdrvs;
+    bd_ret = bdrv_flush(bs);
+    if (bd_ret < 0) {
+        set_broker_err(broker, QB_ERR_INTERNAL_ERR,
+                       "Internal error.");
+    }
+    return broker->err_ret;
+}
+
+int qb_check_allocation(QBroker *broker,
+                        QBlockState *qbs,
+                        uint64_t start,
+                        int64_t length,
+                        int *pstatus,
+                        int64_t *plength)
+{
+    int ret;
+    int sector_start, sector_num, num;
+    BlockDriverState *bs;
+    unsigned int real_len, ret_len;
+
+    broker->err_ret = 0;
+    bs = qbs->bdrvs;
+
+    if (length > 0x1000000000000) {
+        set_broker_err(broker, QB_ERR_INVALID_PARAM,
+                       "length is too big.");
+        goto out;
+    }
+
+    if (qbs->filename == NULL) {
+        set_broker_err(broker, QB_ERR_INVALID_PARAM,
+                       "Image was not opened first.");
+        goto out;
+    }
+
+    if (length <= 0) {
+        set_broker_err(broker, QB_ERR_INVALID_PARAM,
+                       "length is not valid.");
+        goto out;
+    }
+
+    /* translate to sector */
+    sector_start = start >> BDRV_SECTOR_BITS;
+    real_len = (start & (~BDRV_SECTOR_MASK)) + length;
+    sector_num = real_len >> BDRV_SECTOR_BITS;
+    if ((real_len & (~BDRV_SECTOR_MASK)) != 0) {
+        sector_num++;
+    }
+
+    ret = bdrv_is_allocated(bs, sector_start, sector_num, &num);
+    if ((ret == 0) && (num == 0)) {
+        set_broker_err(broker, QB_ERR_BLOCK_OUT_OF_RANGE,
+                       "Start position was bigger than the image's size.");
+        goto out;
+    }
+
+    *pstatus = ret;
+    ret_len = (num << BDRV_SECTOR_BITS) - (start & (~BDRV_SECTOR_MASK));
+    if (ret_len > length) {
+        ret_len = length;
+    }
+    *plength = ret_len;
+
+ out:
+    return broker->err_ret;
+}
+
+static void qb_setup_info_addr(QBlockStaticInfo *info,
+                               QBlockStaticInfoAddr *info_addr)
+{
+    uint64_t *virt_size = NULL;
+    QBlockProtInfo *backing_loc = NULL;
+    bool *encrypt = NULL;
+    QBlockFmtInfo *fmt = &(info->fmt);
+
+    switch (fmt->fmt_type) {
+    case QB_FMT_COW:
+        virt_size = &(fmt->fmt_op.o_cow.virt_size);
+        backing_loc = &(fmt->fmt_op.o_cow.backing_loc);
+        break;
+    case QB_FMT_QED:
+        virt_size = &(fmt->fmt_op.o_qed.virt_size);
+        backing_loc = &(fmt->fmt_op.o_qed.backing_loc);
+        break;
+    case QB_FMT_QCOW:
+        virt_size = &(fmt->fmt_op.o_qcow.virt_size);
+        backing_loc = &(fmt->fmt_op.o_qcow.backing_loc);
+        encrypt = &(fmt->fmt_op.o_qcow.encrypt);
+        break;
+    case QB_FMT_QCOW2:
+        virt_size = &(fmt->fmt_op.o_qcow2.virt_size);
+        backing_loc = &(fmt->fmt_op.o_qcow2.backing_loc);
+        encrypt = &(fmt->fmt_op.o_qcow2.encrypt);
+        break;
+    case QB_FMT_RAW:
+        virt_size = &(fmt->fmt_op.o_raw.virt_size);
+        break;
+    case QB_FMT_RBD:
+        virt_size = &(fmt->fmt_op.o_rbd.virt_size);
+        break;
+    case QB_FMT_SHEEPDOG:
+        virt_size = &(fmt->fmt_op.o_sheepdog.virt_size);
+        backing_loc = &(fmt->fmt_op.o_sheepdog.backing_loc);
+        break;
+    case QB_FMT_VDI:
+        virt_size = &(fmt->fmt_op.o_vdi.virt_size);
+        break;
+    case QB_FMT_VMDK:
+        virt_size = &(fmt->fmt_op.o_vmdk.virt_size);
+        backing_loc = &(fmt->fmt_op.o_vmdk.backing_loc);
+        break;
+    case QB_FMT_VPC:
+        virt_size = &(fmt->fmt_op.o_vpc.virt_size);
+        break;
+    default:
+        break;
+    }
+
+    info_addr->virt_size = virt_size;
+    info_addr->backing_loc = backing_loc;
+    info_addr->encrypt = encrypt;
+    return;
+}
+
+int qb_info_image_static_get(QBroker *broker,
+                             QBlockState *qbs,
+                             QBlockStaticInfo **info)
+{
+    int ret = 0;
+    BlockDriverState *bs;
+    QBlockStaticInfo *info_tmp;
+    QBlockStaticInfoAddr *member_addr;
+    const char *fmt_str;
+    uint64_t total_sectors;
+    char backing_filename[LIBQB_FILENAME_MAX];
+
+    if (qbs->filename == NULL) {
+        set_broker_err(broker, QB_ERR_INVALID_PARAM,
+                       "Block Image was not openned.");
+        ret = broker->err_ret;
+        goto out;
+    }
+
+    info_tmp = FUNC_CALLOC(1, sizeof(QBlockStaticInfo));
+
+    bs = qbs->bdrvs;
+
+    ret = filename2loc(broker,
+                       &(info_tmp->loc),
+                       qbs->filename);
+    if (ret < 0) {
+        goto free;
+    }
+
+    fmt_str = bdrv_get_format_name(bs);
+    info_tmp->fmt.fmt_type = qb_str2fmttype(fmt_str);
+    /* we got the format type and basic location info now, setup the struct
+    pointer to the internal members */
+    member_addr = FUNC_CALLOC(1, sizeof(QBlockStaticInfoAddr));
+    qb_setup_info_addr(info_tmp, member_addr);
+    info_tmp->member_addr = member_addr;
+
+    assert(member_addr->virt_size != NULL);
+    bdrv_get_geometry(bs, &total_sectors);
+    *(member_addr->virt_size) = total_sectors * BDRV_SECTOR_SIZE;
+
+    if (member_addr->encrypt != NULL) {
+        *(member_addr->encrypt) = bdrv_is_encrypted(bs);
+    }
+
+    bdrv_get_full_backing_filename(bs, backing_filename,
+                                   sizeof(backing_filename));
+    if (backing_filename[0] != '\0') {
+        assert(member_addr->backing_loc != NULL);
+        ret = filename2loc(broker,
+                           member_addr->backing_loc,
+                           backing_filename);
+        if (ret < 0) {
+            goto free;
+        }
+    }
+
+    info_tmp->sector_size = BDRV_SECTOR_SIZE;
+    *info = info_tmp;
+
+ out:
+    return ret;
+ free:
+    qb_info_image_static_delete(broker, &info_tmp);
+    return ret;
+}
+
+/* free locations if it has string allocated on heap. */
+static void loc_free(QBlockProtInfo *loc)
+{
+    switch (loc->prot_type) {
+    case QB_PROT_FILE:
+        FUNC_FREE((void *)(loc->prot_op.o_file.filename));
+        loc->prot_op.o_file.filename = NULL;
+        break;
+    default:
+        break;
+    }
+}
+
+/* free fmt related resoure. */
+static void fmt_free(QBlockFmtInfo *fmt)
+{
+    switch (fmt->fmt_type) {
+    case QB_FMT_COW:
+        loc_free(&(fmt->fmt_op.o_cow.backing_loc));
+        break;
+    case QB_FMT_QED:
+        loc_free(&(fmt->fmt_op.o_qed.backing_loc));
+        break;
+    case QB_FMT_QCOW:
+        loc_free(&(fmt->fmt_op.o_qcow.backing_loc));
+        break;
+    case QB_FMT_QCOW2:
+        loc_free(&(fmt->fmt_op.o_qcow2.backing_loc));
+        break;
+    case QB_FMT_RAW:
+        break;
+    case QB_FMT_RBD:
+        break;
+    case QB_FMT_SHEEPDOG:
+        loc_free(&(fmt->fmt_op.o_sheepdog.backing_loc));
+        break;
+    case QB_FMT_VDI:
+        break;
+    case QB_FMT_VMDK:
+        loc_free(&(fmt->fmt_op.o_vmdk.backing_loc));
+        break;
+    case QB_FMT_VPC:
+        break;
+    default:
+        break;
+    }
+    return;
+}
+
+
+void qb_info_image_static_delete(QBroker *broker,
+                                 QBlockStaticInfo **info)
+{
+    if ((*info)->member_addr != NULL) {
+        FUNC_FREE((*info)->member_addr);
+    }
+    loc_free(&(*info)->loc);
+    fmt_free(&(*info)->fmt);
+    CLEAN_FREE(*info);
+}
diff --git a/libqblock/libqblock.h b/libqblock/libqblock.h
new file mode 100644
index 0000000..3791346
--- /dev/null
+++ b/libqblock/libqblock.h
@@ -0,0 +1,297 @@
+/*
+ * QEMU block layer library
+ *
+ * Copyright IBM, Corp. 2012
+ *
+ * Authors:
+ *  Wenchao Xia   <xiawenc@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#ifndef LIBQBLOCK_H
+#define LIBQBLOCK_H
+
+#include "libqblock-types.h"
+#include "libqblock-error.h"
+
+/**
+ * qb_broker_new: allocate a new broker
+ *
+ * Broker is used to pass operation to libqblock, and get feedback from it.
+ *
+ * Returns 0 on success, libqblock negative error value on fail.
+ *
+ * @broker: used to receive the created struct.
+ */
+DLL_PUBLIC
+int qb_broker_new(QBroker **broker);
+
+/**
+ * qb_broker_delete: delete broker
+ *
+ * Broker will be freed and set to NULL.
+ *
+ * @broker: operation broker to be deleted.
+ */
+DLL_PUBLIC
+void qb_broker_delete(QBroker **broker);
+
+/**
+ * qb_state_new: allocate a new QBlockState struct
+ *
+ * Subsequent qblock actions will use this struct
+ *
+ * Returns 0 if succeed, libqblock negative error value on fail.
+ *
+ * @broker: operation broker.
+ * @qbs: used to receive the created struct.
+ */
+DLL_PUBLIC
+int qb_state_new(QBroker *broker,
+                 QBlockState **qbs);
+
+/**
+ * qb_state_delete: free a QBlockState struct
+ *
+ * if image was opened, qb_close should be called before delete, otherwise
+ *  it would be automatically closed.
+ *
+ * @broker: operation broker.
+ * @qbs: pointer to the struct's pointer.
+ */
+DLL_PUBLIC
+void qb_state_delete(QBroker *broker,
+                     QBlockState **qbs);
+
+/**
+ * qb_prot_info_new: create a new QBlockProtInfo object.
+ *
+ * return 0 on success, libqblock negative error value on fail.
+ *
+ * @broker: operation broker.
+ * @op: pointer to receive the new created one.
+ */
+DLL_PUBLIC
+int qb_prot_info_new(QBroker *broker,
+                     QBlockProtInfo **op);
+
+/**
+ * qb_prot_info_delete: free a QBlockProtInfo.
+ *
+ * @broker: operation broker.
+ * @op: pointer to the object, *op would be set to NULL.
+ */
+DLL_PUBLIC
+void qb_prot_info_delete(QBroker *broker,
+                         QBlockProtInfo **op);
+
+/**
+ * qb_fmt_info_new: create a new QBlockFmtInfo structure.
+ *
+ * return 0 on success, libqblock negative error value on fail.
+ *
+ * @broker: operation broker.
+ * @op: pointer that will receive created struct.
+ */
+DLL_PUBLIC
+int qb_fmt_info_new(QBroker *broker,
+                    QBlockFmtInfo **op);
+
+/**
+ * qb_fmt_info_delete: free QBlockFmtInfo structure.
+ *
+ * @broker: operation broker.
+ * @op: pointer to the struct, *op would be set to NULL.
+ */
+DLL_PUBLIC
+void qb_fmt_info_delete(QBroker *broker,
+                        QBlockFmtInfo **op);
+
+
+/**
+ * qb_open: open a block object.
+ *
+ * return 0 on success, libqblock negative error value on fail.
+ *
+ * @broker: operation broker.
+ * @qbs: pointer to QBlockState.
+ * @loc: location options for open, how to find the image.
+ * @fmt: format options, how to extract the data, only valid member now is
+ *    fmt->fmt_type, set to NULL if you want to auto discovery the format.
+ * @flag: behavior control flags, it is LIBQBLOCK_O_XXX's combination.
+ *
+ * Note: For raw image, there is a risk that it's content is changed to some
+ *  magic value resulting a wrong probing done by libqblock, so don't do
+ * probing on raw images.
+ */
+DLL_PUBLIC
+int qb_open(QBroker *broker,
+            QBlockState *qbs,
+            QBlockProtInfo *loc,
+            QBlockFmtInfo *fmt,
+            int flag);
+
+/**
+ * qb_close: close a block object.
+ *
+ * qb_flush is automatically done inside.
+ *
+ * @broker: operation broker.
+ * @qbs: pointer to QBlockState.
+ */
+DLL_PUBLIC
+void qb_close(QBroker *broker,
+              QBlockState *qbs);
+
+/**
+ * qb_create: create a block image or object.
+ *
+ * Note: Create operation would not open the image automatically.
+ *
+ * return 0 on success, libqblock negative error value on fail.
+ *
+ * @broker: operation broker.
+ * @qbs: pointer to QBlockState.
+ * @loc: location options for open, how to find the image.
+ * @fmt: format options, how to extract the data.
+ * @flag: behavior control flags, LIBQBLOCK_O_XXX's combination.
+ */
+DLL_PUBLIC
+int qb_create(QBroker *broker,
+              QBlockState *qbs,
+              QBlockProtInfo *loc,
+              QBlockFmtInfo *fmt,
+              int flag);
+
+
+/* sync access */
+/**
+ * qb_read: block sync read.
+ *
+ * return number of bytes read, libqblock negative error value on fail.
+ *
+ * @broker: operation broker.
+ * @qbs: pointer to QBlockState.
+ * @buf: buffer that receive the content.
+ * @len: length to read.
+ * @offset: offset in the block data.
+ */
+DLL_PUBLIC
+int32_t qb_read(QBroker *broker,
+                QBlockState *qbs,
+                uint8_t *buf,
+                uint32_t len,
+                uint64_t offset);
+
+/**
+ * qb_write: block sync write.
+ *
+ * return number of bytes written, libqblock negative error value on fail.
+ *
+ * @broker: operation broker.
+ * @qbs: pointer to QBlockState.
+ * @buf: buffer that receive the content.
+ * @len: length to write.
+ * @offset: offset in the block data.
+ */
+DLL_PUBLIC
+int32_t qb_write(QBroker *broker,
+                 QBlockState *qbs,
+                 const uint8_t *buf,
+                 uint32_t len,
+                 uint64_t offset);
+
+/**
+ * qb_flush: block sync flush.
+ *
+ * return 0 on success, libqblock negative error value on fail.
+ *
+ * @broker: operation broker.
+ * @qbs: pointer to QBlockState.
+ */
+DLL_PUBLIC
+int qb_flush(QBroker *broker,
+             QBlockState *qbs);
+
+
+/* advance image APIs */
+/**
+ * qb_check_allocation: check if [start, start+lenth-1] was allocated on the
+ *  image.
+ *
+ * return 0 on success, libqblock negative error value on fail.
+ *
+ * @broker: operation broker.
+ * @qbs: pointer to QBlockState.
+ * @start: start position, unit is byte.
+ * @length: length to check, unit is byte, max is 1TB, otherwise will return
+ *   QB_ERR_INVALID_PARAM.
+ * @pstatus: pointer to receive the status, 1 means allocated,
+ *  0 means unallocated.
+ * @plength: pointer to receive the length that all have the same status as
+ *  *pstatus.
+ *
+ * Note: after return, start+*plength may have the same status as
+ *  start+*plength-1.
+ */
+DLL_PUBLIC
+int qb_check_allocation(QBroker *broker,
+                        QBlockState *qbs,
+                        uint64_t start,
+                        int64_t length,
+                        int *pstatus,
+                        int64_t *plength);
+
+/* image information */
+/**
+ * qb_get_image_info: get image info.
+ *
+ * return 0 on success, libqblock negative error value on fail.
+ *
+ * @broker: operation broker.
+ * @qbs: pointer to QBlockState.
+ * @info: pointer that would receive the information.
+ *
+ * *info must be not modified after return, qb_info_image_static_delete will
+ *   use the information in it.
+ */
+DLL_PUBLIC
+int qb_info_image_static_get(QBroker *broker,
+                             QBlockState *qbs,
+                             QBlockStaticInfo **info);
+
+/**
+ * qb_delete_image_info: free image info.
+ *
+ * @broker: operation broker.
+ * @info: pointer to the information struct.
+ */
+DLL_PUBLIC
+void qb_info_image_static_delete(QBroker *broker,
+                                 QBlockStaticInfo **info);
+
+/* helper functions */
+/**
+ * qb_str2fmttype: translate format string to libqblock format enum type.
+ *
+ * return the type, or QB_FMT_NONE if string matches none of supported types.
+ *
+ * @fmt: the format string.
+ */
+DLL_PUBLIC
+QBlockFmtType qb_str2fmttype(const char *fmt_str);
+
+/**
+ * qb_fmttype2str: translate libqblock format enum type to a string.
+ *
+ * return a pointer to the string, or NULL if type is not supported, and
+ *  returned pointer must NOT be freed.
+ *
+ * @fmt: the format enum type.
+ */
+DLL_PUBLIC
+const char *qb_fmttype2str(QBlockFmtType fmt_type);
+#endif
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Qemu-devel] [PATCH V3 4/5] libqblock test build system
  2012-09-18  9:01 [Qemu-devel] [PATCH V3 0/5] libqblock qemu block layer library Wenchao Xia
                   ` (2 preceding siblings ...)
  2012-09-18  9:01 ` [Qemu-devel] [PATCH V3 3/5] libqblock API Wenchao Xia
@ 2012-09-18  9:01 ` Wenchao Xia
  2012-09-18 10:10   ` Paolo Bonzini
  2012-09-18  9:01 ` [Qemu-devel] [PATCH V3 5/5] libqblock test example code Wenchao Xia
  4 siblings, 1 reply; 18+ messages in thread
From: Wenchao Xia @ 2012-09-18  9:01 UTC (permalink / raw)
  To: qemu-devel
  Cc: kwolf, aliguori, stefanha, blauwirbel, pbonzini, eblake,
	Wenchao Xia

  Created a new directory in tests, make chekc-libqblock will build an
executable binrary, make clean will delete it.

Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
---
 .gitignore                       |    1 +
 Makefile                         |    1 +
 tests/Makefile                   |    3 +++
 tests/libqblock/Makefile         |   32 ++++++++++++++++++++++++++++++++
 tests/libqblock/libqblock-test.c |    4 ++++
 5 files changed, 41 insertions(+), 0 deletions(-)
 create mode 100644 tests/libqblock/Makefile
 create mode 100644 tests/libqblock/libqblock-test.c

diff --git a/.gitignore b/.gitignore
index 824c0d2..eccb637 100644
--- a/.gitignore
+++ b/.gitignore
@@ -95,3 +95,4 @@ cscope.*
 tags
 TAGS
 *~
+tests/libqblock/*.bin
diff --git a/Makefile b/Makefile
index b0b9b8d..de8ea17 100644
--- a/Makefile
+++ b/Makefile
@@ -238,6 +238,7 @@ clean:
 	rm -rf qapi-generated
 	rm -rf qga/qapi-generated
 	$(MAKE) -C tests/tcg clean
+	$(MAKE) -C tests/libqblock clean
 	for d in $(ALL_SUBDIRS) $(QEMULIBS) libcacard libqblock; do \
 	if test -d $$d; then $(MAKE) -C $$d $@ || exit 1; fi; \
 	rm -f $$d/qemu-options.def; \
diff --git a/tests/Makefile b/tests/Makefile
index 26a67ce..69af1e2 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -148,4 +148,7 @@ check-unit: $(patsubst %,check-%, $(check-unit-y))
 check-block: $(patsubst %,check-%, $(check-block-y))
 check: check-unit check-qtest
 
+check-libqblock:
+	$(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C tests/libqblock V="$(V)" TARGET_DIR="$*/" check-libqblock,)
+
 -include $(wildcard tests/*.d)
diff --git a/tests/libqblock/Makefile b/tests/libqblock/Makefile
new file mode 100644
index 0000000..eb6947b
--- /dev/null
+++ b/tests/libqblock/Makefile
@@ -0,0 +1,32 @@
+-include ../../config-host.mak
+-include $(SRC_PATH)/Makefile.objs
+-include $(SRC_PATH)/rules.mak
+
+$(call set-vpath, $(SRC_PATH))
+
+#library test case objects
+libqblock-test-objs=libqblock-test.lo
+
+QEMU_CFLAGS+=-I $(SRC_PATH)/$(libqblock-lib-path)
+libqblock-la-path = $(SRC_PATH)/$(libqblock-lib-path)/$(libqblock-lib-la)
+
+##########################################################################
+#runtime rules:
+ifeq ($(LIBTOOL),)
+libqblock-test.bin:
+	@echo "libtool is missing, please install and rerun configure"; exit 1
+else
+libqblock-test.bin: $(libqblock-test-objs) $(libqblock-la-path)
+	$(call quiet-command,$(LIBTOOL) --mode=link --quiet --tag=CC $(CC) -shared -rpath $(libdir) -o $@ $^,"  lt LINK $@")
+endif
+
+check-libqblock:
+	@echo "Building libqblock.la..."
+	$(call quiet-command,$(MAKE) -C $(SRC_PATH) $(libqblock-lib-la),)
+	@make libqblock-test.bin
+	@echo "Executing test binary..."
+	./libqblock-test.bin
+
+clean:
+	rm -f *.lo *.o *.d *.la *.bin
+	rm -rf .libs
diff --git a/tests/libqblock/libqblock-test.c b/tests/libqblock/libqblock-test.c
new file mode 100644
index 0000000..c05c0c4
--- /dev/null
+++ b/tests/libqblock/libqblock-test.c
@@ -0,0 +1,4 @@
+int main(int argc, char **argv)
+{
+    return 0;
+}
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Qemu-devel] [PATCH V3 5/5] libqblock test example code
  2012-09-18  9:01 [Qemu-devel] [PATCH V3 0/5] libqblock qemu block layer library Wenchao Xia
                   ` (3 preceding siblings ...)
  2012-09-18  9:01 ` [Qemu-devel] [PATCH V3 4/5] libqblock test build system Wenchao Xia
@ 2012-09-18  9:01 ` Wenchao Xia
  2012-09-18 10:10   ` Paolo Bonzini
  4 siblings, 1 reply; 18+ messages in thread
From: Wenchao Xia @ 2012-09-18  9:01 UTC (permalink / raw)
  To: qemu-devel
  Cc: kwolf, aliguori, stefanha, blauwirbel, pbonzini, eblake,
	Wenchao Xia

  In this example, user first create two qcow2 images, and then get the
backing file relationship information of them. Then does write and read
sync IO on them.

Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
---
 tests/libqblock/libqblock-test.c |  233 ++++++++++++++++++++++++++++++++++++++
 1 files changed, 233 insertions(+), 0 deletions(-)

diff --git a/tests/libqblock/libqblock-test.c b/tests/libqblock/libqblock-test.c
index c05c0c4..c0b7963 100644
--- a/tests/libqblock/libqblock-test.c
+++ b/tests/libqblock/libqblock-test.c
@@ -1,4 +1,237 @@
+/*
+ * QEMU block layer library test
+ *
+ * Copyright IBM, Corp. 2012
+ *
+ * Authors:
+ *  Wenchao Xia   <xiawenc@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ *
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <inttypes.h>
+#include <string.h>
+#include <stdlib.h>
+#include "libqblock.h"
+
+#define TEST_BUF_SIZE 1024
+static unsigned char buf_r[TEST_BUF_SIZE];
+static unsigned char buf_w[TEST_BUF_SIZE] = {0, 0, 0, 0};
+
+typedef struct VerifyData {
+    unsigned char *buf_r;
+    unsigned char *buf_w;
+    int len;
+} VerifyData;
+
+static void print_loc(QBlockProtInfo *loc)
+{
+    if (loc == NULL) {
+        printf("backing file is NULL.");
+        return;
+    }
+    switch (loc->prot_type) {
+    case QB_PROT_NONE:
+        printf("protocol type [none].");
+        break;
+    case QB_PROT_FILE:
+        printf("protocol type [file], filename [%s].",
+               loc->prot_op.o_file.filename);
+        break;
+    default:
+        printf("protocol type not supported.");
+        break;
+    }
+}
+
+static void print_info_image_static(QBlockStaticInfo *info)
+{
+    printf("=======image location:\n");
+    print_loc(&info->loc);
+    printf("\nvirtual_size %" PRId64 ", format type %d [%s]",
+           *(info->member_addr->virt_size),
+           info->fmt.fmt_type, qb_fmttype2str(info->fmt.fmt_type));
+    printf("\nbacking image location:\n");
+    print_loc(info->member_addr->backing_loc);
+    printf("\n");
+}
+
+static void test_check(VerifyData *vdata)
+{
+    int cmp;
+    cmp = memcmp(vdata->buf_r, vdata->buf_w, vdata->len);
+    if (cmp == 0) {
+        printf("compare succeed, %d.\n", vdata->buf_r[24]);
+    } else {
+        printf("!!! compare fail, %d.\n", vdata->buf_r[24]);
+        exit(1);
+    }
+}
+
 int main(int argc, char **argv)
 {
+    const char *filename1, *filename2;
+    QBroker *broker = NULL;
+    QBlockState *qbs = NULL;
+    QBlockProtInfo *ol = NULL;
+    QBlockFmtInfo *of = NULL;
+    QBlockStaticInfo *info_st = NULL;
+    int ret, flag;
+    int test_offset = 510;
+    int test_len = 520;
+    VerifyData vdata;
+    char err_str[1024];
+
+    vdata.buf_r = buf_r;
+    vdata.buf_w = buf_w;
+    vdata.len = test_len;
+
+    filename1 = "./qemu_image1";
+    filename2 = "./qemu_image2";
+    printf("qemu test, filename1 is %s, filename2 is %s.\n",
+                                       filename1, filename2);
+
+    ret = qb_broker_new(&broker);
+    if (ret < 0) {
+        goto free;
+    }
+
+    ret = qb_state_new(broker, &qbs);
+    if (ret < 0) {
+        goto free;
+    }
+
+    ret = qb_prot_info_new(broker, &ol);
+    if (ret < 0) {
+        goto free;
+    }
+
+    ret = qb_fmt_info_new(broker, &of);
+    if (ret < 0) {
+        goto free;
+    }
+
+    /* create a new image */
+
+    ol->prot_type = QB_PROT_FILE;
+    ol->prot_op.o_file.filename = filename2;
+    of->fmt_type = QB_FMT_QCOW2;
+    of->fmt_op.o_qcow2.virt_size = 100 * 1024;
+    flag = 0;
+
+    ret = qb_create(broker, qbs, ol, of, flag);
+    if (ret < 0) {
+        qb_error_get_human_str(broker, err_str, sizeof(err_str));
+        printf("create fail 1. %s.\n", err_str);
+        goto unlink;
+    }
+
+    ol->prot_type = QB_PROT_FILE;
+    ol->prot_op.o_file.filename = filename1;
+    of->fmt_type = QB_FMT_QCOW2;
+    of->fmt_op.o_qcow2.backing_loc.prot_type = QB_PROT_FILE;
+    of->fmt_op.o_qcow2.backing_loc.prot_op.o_file.filename = filename2;
+    flag = 0;
+    ret = qb_create(broker, qbs, ol, of, flag);
+    if (ret < 0) {
+        qb_error_get_human_str(broker, err_str, sizeof(err_str));
+        printf("create fail 2. %s.\n", err_str);
+        goto unlink;
+    }
+
+    /* get informations */
+    ol->prot_type = QB_PROT_FILE;
+    ol->prot_op.o_file.filename = filename1;
+    of->fmt_type = QB_FMT_NONE;
+    flag = LIBQBLOCK_O_NO_BACKING;
+    ret = qb_open(broker, qbs, ol, of, flag);
+    if (ret < 0) {
+        qb_error_get_human_str(broker, err_str, sizeof(err_str));
+        printf("info getting, open failed. %s.\n", err_str);
+        goto free;
+    }
+
+    while (1) {
+        ret = qb_info_image_static_get(broker, qbs, &info_st);
+        if (ret < 0) {
+            qb_error_get_human_str(broker, err_str, sizeof(err_str));
+            printf("info get error. %s.\n", err_str);
+            goto close;
+        }
+        print_info_image_static(info_st);
+        qb_close(broker, qbs);
+        if ((info_st->member_addr->backing_loc == NULL) ||
+            (info_st->member_addr->backing_loc->prot_type == QB_FMT_NONE)) {
+            break;
+        }
+        *ol = *(info_st->member_addr->backing_loc);
+        ret = qb_open(broker, qbs, ol, of, flag);
+        if (ret < 0) {
+            qb_error_get_human_str(broker, err_str, sizeof(err_str));
+            printf("info getting, open failed in backing file. %s.\n",
+                                                       err_str);
+            goto free;
+        }
+        qb_info_image_static_delete(broker, &info_st);
+    }
+    /* read and write the image */
+    ol->prot_type = QB_PROT_FILE;
+    ol->prot_op.o_file.filename = filename1;
+    of->fmt_type = QB_FMT_NONE;
+    flag = LIBQBLOCK_O_RDWR;
+    ret = qb_open(broker, qbs, ol, of, flag);
+    if (ret < 0) {
+        qb_error_get_human_str(broker, err_str, sizeof(err_str));
+        printf("open failed. %s.\n", err_str);
+        goto free;
+    }
+
+    buf_w[1] = 1;
+    buf_w[2] = 2;
+    buf_w[514] = 4;
+    memset(buf_r, 0, sizeof(buf_r));
+
+    ret = qb_write(broker, qbs, buf_w, test_len, test_offset);
+    if (ret < 0) {
+        qb_error_get_human_str(broker, err_str, sizeof(err_str));
+        printf("%s.\n", err_str);
+        goto close;
+    }
+
+    ret = qb_read(broker, qbs, buf_r, test_len, test_offset);
+    if (ret < 0) {
+        qb_error_get_human_str(broker, err_str, sizeof(err_str));
+        printf("%s.\n", err_str);
+        goto close;
+    }
+
+    test_check(&vdata);
+
+ close:
+    qb_close(broker, qbs);
+ unlink:
+    unlink(filename1);
+    unlink(filename2);
+ free:
+    if (info_st != NULL) {
+        qb_info_image_static_delete(broker, &info_st);
+    }
+    if (qbs != NULL) {
+        qb_state_delete(broker, &qbs);
+    }
+    if (ol != NULL) {
+        qb_prot_info_delete(broker, &ol);
+    }
+    if (of != NULL) {
+        qb_fmt_info_delete(broker, &of);
+    }
+    if (broker != NULL) {
+        qb_broker_delete(&broker);
+    }
     return 0;
 }
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH V3 2/5] libqblock type defines
  2012-09-18  9:01 ` [Qemu-devel] [PATCH V3 2/5] libqblock type defines Wenchao Xia
@ 2012-09-18 10:05   ` Paolo Bonzini
  2012-09-19  3:23     ` Wenchao Xia
  0 siblings, 1 reply; 18+ messages in thread
From: Paolo Bonzini @ 2012-09-18 10:05 UTC (permalink / raw)
  To: Wenchao Xia; +Cc: kwolf, aliguori, stefanha, qemu-devel, blauwirbel, eblake

Il 18/09/2012 11:01, Wenchao Xia ha scritto:
>   This patch contains type and defines used in APIs, one file for public usage
> by user, one for libqblock internal usage.
> 
> Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
> ---
>  libqblock/libqblock-internal.h |   56 +++++++++
>  libqblock/libqblock-types.h    |  268 ++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 324 insertions(+), 0 deletions(-)
>  create mode 100644 libqblock/libqblock-internal.h
>  create mode 100644 libqblock/libqblock-types.h
> 
> diff --git a/libqblock/libqblock-internal.h b/libqblock/libqblock-internal.h
> new file mode 100644
> index 0000000..87f32be
> --- /dev/null
> +++ b/libqblock/libqblock-internal.h
> @@ -0,0 +1,56 @@
> +/*
> + * QEMU block layer library
> + *
> + * Copyright IBM, Corp. 2012
> + *
> + * Authors:
> + *  Wenchao Xia   <xiawenc@linux.vnet.ibm.com>
> + *
> + * This work is licensed under the terms of the GNU LGPL, version 2 or later.
> + * See the COPYING.LIB file in the top-level directory.
> + *
> + */
> +
> +#ifndef LIBQBLOCK_INTERNAL
> +#define LIBQBLOCK_INTERNAL
> +
> +#include "glib.h"
> +
> +#include "block.h"
> +#include "block_int.h"
> +#include "libqblock-types.h"
> +
> +/* this file contains defines and types used inside the library. */
> +
> +#define FUNC_FREE(p) g_free((p))
> +#define FUNC_MALLOC(size) g_malloc((size))
> +#define FUNC_CALLOC(nmemb, size) g_malloc0((nmemb)*(size))
> +
> +#define CLEAN_FREE(p) { \
> +        FUNC_FREE(p); \
> +        (p) = NULL; \
> +}
> +
> +/* details should be hidden to user */
> +struct QBlockState {
> +    BlockDriverState *bdrvs;
> +    /* internal used file name now, if it is not NULL, it means
> +       image was opened.
> +    */
> +    char *filename;
> +} ;
> +
> +struct QBroker {
> +    /* last error */
> +    GError *g_error;
> +    int err_ret; /* 1st level of error, the libqblock error number */
> +    int err_no; /* 2nd level of error, errno what below reports */
> +};

Sorry for keeping on bikeshedding---a better name for this is
QBlockContext.  "Context" is a well-known name for this kind of global
object.

Otherwise looks good---thanks for putting up with us! :)

Paolo

> +#define G_LIBQBLOCK_ERROR g_libqbock_error_quark()
> +
> +static inline GQuark g_libqbock_error_quark(void)
> +{
> +    return g_quark_from_static_string("g-libqblock-error-quark");
> +}
> +#endif
> diff --git a/libqblock/libqblock-types.h b/libqblock/libqblock-types.h
> new file mode 100644
> index 0000000..3c548b8
> --- /dev/null
> +++ b/libqblock/libqblock-types.h
> @@ -0,0 +1,268 @@
> +/*
> + * QEMU block layer library
> + *
> + * Copyright IBM, Corp. 2012
> + *
> + * Authors:
> + *  Wenchao Xia   <xiawenc@linux.vnet.ibm.com>
> + *
> + * This work is licensed under the terms of the GNU LGPL, version 2 or later.
> + * See the COPYING.LIB file in the top-level directory.
> + *
> + */
> +
> +#ifndef LIBQBLOCK_TYPES_H
> +#define LIBQBLOCK_TYPES_H
> +
> +#include <sys/types.h>
> +#include <stdint.h>
> +#include <stdbool.h>
> +
> +#if defined(__GNUC__) && __GNUC__ >= 4
> +    #ifdef LIBQB_BUILD
> +        #define DLL_PUBLIC __attribute__((visibility("default")))
> +    #else
> +        #define DLL_PUBLIC
> +    #endif
> +#else
> +    #warning : gcc compiler version < 4, symbols can not be hidden.
> +#endif
> +
> +/* this library is designed around this core struct. */
> +typedef struct QBlockState QBlockState;
> +
> +/* every thread should have a broker. */
> +typedef struct QBroker QBroker;
> +
> +/* flag used in open and create */
> +#define LIBQBLOCK_O_RDWR        0x0002
> +/* do not use the host page cache */
> +#define LIBQBLOCK_O_NOCACHE     0x0020
> +/* use write-back caching */
> +#define LIBQBLOCK_O_CACHE_WB    0x0040
> +/* don't open the backing file */
> +#define LIBQBLOCK_O_NO_BACKING  0x0100
> +/* disable flushing on this disk */
> +#define LIBQBLOCK_O_NO_FLUSH    0x0200
> +
> +#define LIBQBLOCK_O_CACHE_MASK \
> +   (LIBQBLOCK_O_NOCACHE | LIBQBLOCK_O_CACHE_WB | LIBQBLOCK_O_NO_FLUSH)
> +
> +#define LIBQBLOCK_O_VALID_MASK \
> +   (LIBQBLOCK_O_RDWR | LIBQBLOCK_O_NOCACHE | LIBQBLOCK_O_CACHE_WB | \
> +    LIBQBLOCK_O_NO_BACKING | LIBQBLOCK_O_NO_FLUSH)
> +
> +typedef enum QBlockProtType {
> +    QB_PROT_NONE = 0,
> +    QB_PROT_FILE,
> +    QB_PROT_MAX
> +} QBlockProtType;
> +
> +typedef struct QBlockProtOptionFile {
> +    const char *filename;
> +} QBlockProtOptionFile;
> +
> +#define QBLOCK_PROT_OPTIONS_UNION_SIZE (512)
> +typedef union QBlockProtOptionsUnion {
> +    QBlockProtOptionFile o_file;
> +    uint8_t reserved[QBLOCK_PROT_OPTIONS_UNION_SIZE];
> +} QBlockProtOptionsUnion;
> +
> +/**
> + * struct QBlockProtInfo: contains information about how to find the image
> + *
> + * @prot_type: protocol type, now only support FILE.
> + * @prot_op: protocol related options.
> + */
> +typedef struct QBlockProtInfo {
> +    QBlockProtType prot_type;
> +    QBlockProtOptionsUnion prot_op;
> +} QBlockProtInfo;
> +
> +
> +/* format related options */
> +typedef enum QBlockFmtType {
> +    QB_FMT_NONE = 0,
> +    QB_FMT_COW,
> +    QB_FMT_QED,
> +    QB_FMT_QCOW,
> +    QB_FMT_QCOW2,
> +    QB_FMT_RAW,
> +    QB_FMT_RBD,
> +    QB_FMT_SHEEPDOG,
> +    QB_FMT_VDI,
> +    QB_FMT_VMDK,
> +    QB_FMT_VPC,
> +    QB_FMT_MAX
> +} QBlockFmtType;
> +
> +typedef struct QBlockFmtOptionCow {
> +    uint64_t virt_size;
> +    QBlockProtInfo backing_loc;
> +} QBlockFmtOptionCow;
> +
> +typedef struct QBlockFmtOptionQed {
> +    uint64_t virt_size;
> +    QBlockProtInfo backing_loc;
> +    QBlockFmtType backing_fmt;
> +    uint64_t cluster_size; /* unit is bytes */
> +    uint64_t table_size; /* unit is clusters */
> +} QBlockFmtOptionQed;
> +
> +typedef struct QBlockFmtOptionQcow {
> +    uint64_t virt_size;
> +    QBlockProtInfo backing_loc;
> +    bool encrypt;
> +} QBlockFmtOptionQcow;
> +
> +/* "Compatibility level (0.10 or 1.1)" */
> +typedef enum QBlockFmtOptionQcow2CptLv {
> +    QBO_FMT_QCOW2_CPT_NONE = 0,
> +    QBO_FMT_QCOW2_CPT_V010,
> +    QBO_FMT_QCOW2_CPT_V110,
> +} QBlockFmtOptionQcow2CptLv;
> +
> +/* off or metadata */
> +typedef enum QBlockFmtOptionQcow2PreAllocType {
> +    QBO_FMT_QCOW2_PREALLOC_NONE = 0,
> +    QBO_FMT_QCOW2_PREALLOC_OFF,
> +    QBO_FMT_QCOW2_PREALLOC_METADATA,
> +} QBlockFmtOptionQcow2PreAllocType;
> +
> +typedef struct QBlockFmtOptionQcow2 {
> +    uint64_t virt_size;
> +    QBlockProtInfo backing_loc;
> +    QBlockFmtType backing_fmt;
> +    bool encrypt;
> +    uint64_t cluster_size; /* unit is bytes */
> +    QBlockFmtOptionQcow2CptLv cpt_lv;
> +    QBlockFmtOptionQcow2PreAllocType pre_mode;
> +} QBlockFmtOptionQcow2;
> +
> +typedef struct QBlockFmtOptionRaw {
> +    uint64_t virt_size;
> +} QBlockFmtOptionRaw;
> +
> +typedef struct QBlockFmtOptionRbd {
> +    uint64_t virt_size;
> +    uint64_t cluster_size;
> +} QBlockFmtOptionRbd;
> +
> +/* off or full */
> +typedef enum QBlockFmtOptionSheepdogPreAllocType {
> +    QBO_FMT_SD_PREALLOC_NONE = 0,
> +    QBO_FMT_SD_PREALLOC_OFF,
> +    QBO_FMT_SD_PREALLOC_FULL,
> +} QBlockFmtOptionSheepdogPreAllocType;
> +
> +typedef struct QBlockFmtOptionSheepdog {
> +    uint64_t virt_size;
> +    QBlockProtInfo backing_loc;
> +    QBlockFmtOptionSheepdogPreAllocType pre_mode;
> +} QBlockFmtOptionSheepdog;
> +
> +typedef enum QBlockFmtOptionVdiPreAllocType {
> +    QBO_FMT_VDI_PREALLOC_NONE = 0,
> +    QBO_FMT_VDI_PREALLOC_FALSE,
> +    QBO_FMT_VDI_PREALLOC_TRUE,
> +} QBlockFmtOptionVdiPreAllocType;
> +
> +typedef struct QBlockFmtOptionVdi {
> +    uint64_t virt_size;
> +    uint64_t cluster_size;
> +    QBlockFmtOptionVdiPreAllocType pre_mode;
> +} QBlockFmtOptionVdi;
> +
> +/* whether compact to vmdk verion 6 */
> +typedef enum QBlockFmtOptionVmdkCptLv {
> +    QBO_FMT_VMDK_CPT_NONE = 0,
> +    QBO_FMT_VMDK_CPT_VMDKV6_FALSE,
> +    QBO_FMT_VMDK_CPT_VMDKV6_TRUE,
> +} QBlockFmtOptionVmdkCptLv;
> +
> +/* vmdk flat extent format, values:
> +"{monolithicSparse (default) | monolithicFlat | twoGbMaxExtentSparse |
> +twoGbMaxExtentFlat | streamOptimized} */
> +typedef enum QBlockFmtOptionVmdkSubfmtType {
> +    QBO_FMT_VMDK_SUBFMT_MONOLITHIC_NONE = 0,
> +    QBO_FMT_VMDK_SUBFMT_MONOLITHIC_SPARSE,
> +    QBO_FMT_VMDK_SUBFMT_MONOLITHIC_FLAT,
> +    QBO_FMT_VMDK_SUBFMT_TWOGBMAX_EXTENT_SPARSE,
> +    QBO_FMT_VMDK_SUBFMT_TWOGBMAX_EXTENT_FLAT,
> +    QBO_FMT_VMDK_SUBFMT_STREAM_OPTIMIZED,
> +} QBlockFmtOptionVmdkSubfmtType;
> +
> +typedef struct QBlockFmtOptionVmdk {
> +    uint64_t virt_size;
> +    QBlockProtInfo backing_loc;
> +    QBlockFmtOptionVmdkCptLv cpt_lv;
> +    QBlockFmtOptionVmdkSubfmtType subfmt;
> +} QBlockFmtOptionVmdk;
> +
> +/* "{dynamic (default) | fixed} " */
> +typedef enum QBlockFmtOptionVpcSubfmtType {
> +    QBO_FMT_VPC_SUBFMT_NONE = 0,
> +    QBO_FMT_VPC_SUBFMT_DYNAMIC,
> +    QBO_FMT_VPC_SUBFMT_FIXED,
> +} QBlockFmtOptionVpcSubfmtType;
> +
> +typedef struct QBlockFmtOptionVpc {
> +    uint64_t virt_size;
> +    QBlockFmtOptionVpcSubfmtType subfmt;
> +} QBlockFmtOptionVpc;
> +
> +#define QBLOCK_FMT_OPTIONS_UNION_SIZE (QBLOCK_PROT_OPTIONS_UNION_SIZE*2)
> +typedef union QBlockFmtOptionsUnion {
> +    QBlockFmtOptionCow       o_cow;
> +    QBlockFmtOptionQed       o_qed;
> +    QBlockFmtOptionQcow      o_qcow;
> +    QBlockFmtOptionQcow2     o_qcow2;
> +    QBlockFmtOptionRaw       o_raw;
> +    QBlockFmtOptionRbd       o_rbd;
> +    QBlockFmtOptionSheepdog  o_sheepdog;
> +    QBlockFmtOptionVdi       o_vdi;
> +    QBlockFmtOptionVmdk      o_vmdk;
> +    QBlockFmtOptionVpc       o_vpc;
> +    uint8_t reserved[QBLOCK_FMT_OPTIONS_UNION_SIZE];
> +} QBlockFmtOptionsUnion;
> +
> +typedef struct QBlockFmtInfo {
> +    QBlockFmtType fmt_type;
> +    QBlockFmtOptionsUnion fmt_op;
> +} QBlockFmtInfo;
> +
> +/**
> + * QBlockStaticInfoAddr: a structure contains a set of pointer.
> + *
> + *    this struct contains a set of pointer pointing to some
> + *  property related to format or protocol. If a property is not available,
> + *  it will be set as NULL. User could use this to get property directly.
> + *
> + *  @virt_size: virtual size, it is always not NULL.
> + *  @backing_loc: backing file location.
> + *  @encrypt: encryption flag.
> +*/
> +
> +typedef struct QBlockStaticInfoAddr {
> +    uint64_t *virt_size;
> +    QBlockProtInfo *backing_loc;
> +    bool *encrypt;
> +} QBlockStaticInfoAddr;
> +
> +/**
> + * QBlockStaticInfo: information about the block image.
> + *
> + * @member_addr: contains pointer which can be used to access the structure.
> + * @loc: location information.
> + * @fmt: format information.
> + * @sector_size: how many bytes in a sector, it is 512 usually.
> + */
> +typedef struct QBlockStaticInfo {
> +    QBlockStaticInfoAddr *member_addr;
> +    QBlockProtInfo loc;
> +    QBlockFmtInfo fmt;
> +    int sector_size;
> +} QBlockStaticInfo;
> +
> +
> +#endif
> 

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH V3 1/5] libqblock build system
  2012-09-18  9:01 ` [Qemu-devel] [PATCH V3 1/5] libqblock build system Wenchao Xia
@ 2012-09-18 10:05   ` Paolo Bonzini
  2012-09-19  6:35     ` Wenchao Xia
  2012-09-18 10:31   ` Paolo Bonzini
  1 sibling, 1 reply; 18+ messages in thread
From: Paolo Bonzini @ 2012-09-18 10:05 UTC (permalink / raw)
  To: Wenchao Xia; +Cc: kwolf, aliguori, stefanha, qemu-devel, blauwirbel, eblake

Il 18/09/2012 11:01, Wenchao Xia ha scritto:
>   Libqblock was placed in new directory ./libqblock, libtool will build
> dynamic library there, source files of block layer remains in ./block.
> So block related source code will generate 3 sets of binary, first is old
> ones used in qemu, second and third are non PIC and PIC ones in ./libqblock.
>   GCC compiler flag visibility=hidden was used with special macro, to export
> only symbols that was marked as PUBLIC.
> 
> Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
> ---
>  Makefile                    |   13 ++++++++-
>  Makefile.objs               |    6 ++++
>  libqblock/Makefile          |   64 +++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 82 insertions(+), 1 deletions(-)
>  create mode 100644 libqblock/Makefile
>  create mode 100644 libqblock/libqblock-error.c
>  create mode 100644 libqblock/libqblock.c
> 
> diff --git a/Makefile b/Makefile
> index 971e92f..b0b9b8d 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -164,6 +164,17 @@ qemu-io$(EXESUF): qemu-io.o cmd.o $(tools-obj-y) $(block-obj-y)
>  
>  qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o
>  
> +######################################################################
> +# Support building shared library libqblock
> +ifeq ($(LIBTOOL),)
> +$(libqblock-lib-la):
> +	@echo "libtool is missing, please install and rerun configure"; exit 1
> +else
> +$(libqblock-lib-la):
> +	$(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C libqblock V="$(V)" TARGET_DIR="$*/" $(libqblock-lib-la),)
> +endif
> +###########################################################################
> +
>  vscclient$(EXESUF): $(libcacard-y) $(oslib-obj-y) $(trace-obj-y) $(tools-obj-y) qemu-timer-common.o libcacard/vscclient.o
>  	$(call quiet-command,$(CC) $(LDFLAGS) -o $@ $^ $(libcacard_libs) $(LIBS),"  LINK  $@")
>  
> @@ -227,7 +238,7 @@ clean:
>  	rm -rf qapi-generated
>  	rm -rf qga/qapi-generated
>  	$(MAKE) -C tests/tcg clean
> -	for d in $(ALL_SUBDIRS) $(QEMULIBS) libcacard; do \
> +	for d in $(ALL_SUBDIRS) $(QEMULIBS) libcacard libqblock; do \
>  	if test -d $$d; then $(MAKE) -C $$d $@ || exit 1; fi; \
>  	rm -f $$d/qemu-options.def; \
>          done
> diff --git a/Makefile.objs b/Makefile.objs
> index 4412757..8a4c9fc 100644
> --- a/Makefile.objs
> +++ b/Makefile.objs
> @@ -248,3 +248,9 @@ nested-vars += \
>  	common-obj-y \
>  	extra-obj-y
>  dummy := $(call unnest-vars)
> +
> +#############################################################################
> +# libqblock
> +
> +libqblock-lib-la = libqblock.la
> +libqblock-lib-path = libqblock
> diff --git a/libqblock/Makefile b/libqblock/Makefile
> new file mode 100644
> index 0000000..bf7abcc
> --- /dev/null
> +++ b/libqblock/Makefile
> @@ -0,0 +1,64 @@
> +###########################################################################
> +# libqblock Makefile
> +# Todo:
> +#    1 trace related files is generated in this directory, move
> +#  them to the root directory.
> +##########################################################################
> +-include ../config-host.mak
> +-include $(SRC_PATH)/Makefile.objs
> +-include $(SRC_PATH)/rules.mak
> +
> +#############################################################################
> +# Library settings
> +#############################################################################
> +$(call set-vpath, $(SRC_PATH))
> +
> +#expand the foldered vars,especially ./block
> +dummy := $(call unnest-vars-1)
> +
> +#library objects
> +tools-obj-y = $(oslib-obj-y) $(trace-obj-y) qemu-tool.o qemu-timer.o \
> +	qemu-timer-common.o main-loop.o notify.o \
> +	iohandler.o cutils.o iov.o async.o
> +tools-obj-$(CONFIG_POSIX) += compatfd.o

Do you really need all of these?

(BTW, I posted recently a patch to move tools-obj-y to Makefile.objs.
It doesn't apply anymore, I'll repost---but the conflicts are trivial).

> +libqblock-y=libqblock.o libqblock-error.o
> +libqblock-lib-y=$(patsubst %.o,%.lo,$(libqblock-y))
> +
> +QEMU_OBJS=$(tools-obj-y) $(block-obj-y)
> +QEMU_OBJS_FILTERED=$(filter %.o,$(QEMU_OBJS))

What does this filter out?

Paolo

> +QEMU_OBJS_LIB=$(patsubst %.o, %.lo,$(QEMU_OBJS_FILTERED))
> +
> +QEMU_CFLAGS+= -I../ -I../include
> +#adding magic macro define for symbol hiding and exposing
> +QEMU_CFLAGS+= -fvisibility=hidden -D LIBQB_BUILD
> +
> +#dependency libraries
> +LIBS+=-lz $(LIBS_TOOLS)
> +
> +#################################################################
> +# Runtime rules
> +#################################################################
> +clean:
> +	rm -f *.lo *.o *.d *.la libqblock-test trace.c trace.c-timestamp
> +	rm -rf .libs block trace
> +
> +all: libqblock-test
> +	@true
> +
> +help:
> +	@echo type make libqblock-test at root dirtory, libtool is required
> +
> +#make dir block at runtime which would hold the output of block/*.c
> +block:
> +	@mkdir block
> +
> +ifeq ($(LIBTOOL),)
> +$(libqblock-lib-la):
> +	@echo "libtool is missing, please install and rerun configure"; exit 1
> +else
> +$(libqblock-lib-la): $(libqblock-lib-y) $(QEMU_OBJS_LIB)
> +	$(call quiet-command,$(LIBTOOL) --mode=link --quiet --tag=CC $(CC) -rpath $(libdir) -o $@ $^ $(LIBS),"  lt LINK $@")
> +endif
> +
> +.PHONY: libqblock.la
> diff --git a/libqblock/libqblock-error.c b/libqblock/libqblock-error.c
> new file mode 100644
> index 0000000..e69de29
> diff --git a/libqblock/libqblock.c b/libqblock/libqblock.c
> new file mode 100644
> index 0000000..e69de29
> 

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH V3 4/5] libqblock test build system
  2012-09-18  9:01 ` [Qemu-devel] [PATCH V3 4/5] libqblock test build system Wenchao Xia
@ 2012-09-18 10:10   ` Paolo Bonzini
  2012-09-19  6:39     ` Wenchao Xia
  0 siblings, 1 reply; 18+ messages in thread
From: Paolo Bonzini @ 2012-09-18 10:10 UTC (permalink / raw)
  To: Wenchao Xia; +Cc: kwolf, aliguori, stefanha, qemu-devel, blauwirbel, eblake

Il 18/09/2012 11:01, Wenchao Xia ha scritto:
>   Created a new directory in tests, make chekc-libqblock will build an
> executable binrary, make clean will delete it.
> 
> Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
> ---
>  .gitignore                       |    1 +
>  Makefile                         |    1 +
>  tests/Makefile                   |    3 +++
>  tests/libqblock/Makefile         |   32 ++++++++++++++++++++++++++++++++
>  tests/libqblock/libqblock-test.c |    4 ++++
>  5 files changed, 41 insertions(+), 0 deletions(-)
>  create mode 100644 tests/libqblock/Makefile
>  create mode 100644 tests/libqblock/libqblock-test.c
> 
> diff --git a/.gitignore b/.gitignore
> index 824c0d2..eccb637 100644
> --- a/.gitignore
> +++ b/.gitignore
> @@ -95,3 +95,4 @@ cscope.*
>  tags
>  TAGS
>  *~
> +tests/libqblock/*.bin
> diff --git a/Makefile b/Makefile
> index b0b9b8d..de8ea17 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -238,6 +238,7 @@ clean:
>  	rm -rf qapi-generated
>  	rm -rf qga/qapi-generated
>  	$(MAKE) -C tests/tcg clean
> +	$(MAKE) -C tests/libqblock clean
>  	for d in $(ALL_SUBDIRS) $(QEMULIBS) libcacard libqblock; do \
>  	if test -d $$d; then $(MAKE) -C $$d $@ || exit 1; fi; \
>  	rm -f $$d/qemu-options.def; \
> diff --git a/tests/Makefile b/tests/Makefile
> index 26a67ce..69af1e2 100644
> --- a/tests/Makefile
> +++ b/tests/Makefile
> @@ -148,4 +148,7 @@ check-unit: $(patsubst %,check-%, $(check-unit-y))
>  check-block: $(patsubst %,check-%, $(check-block-y))
>  check: check-unit check-qtest
>  
> +check-libqblock:
> +	$(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C tests/libqblock V="$(V)" TARGET_DIR="$*/" check-libqblock,)

Please just put everything in tests/Makefile. "make check" should run it
if LIBTOOL is available.

> +libqblock-test.bin: $(libqblock-test-objs) $(libqblock-la-path)
> +	$(call quiet-command,$(LIBTOOL) --mode=link --quiet --tag=CC $(CC) -shared -rpath $(libdir) -o $@ $^,"  lt LINK $@")

.bin looks so MS-DOS. :)

Paolo

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH V3 5/5] libqblock test example code
  2012-09-18  9:01 ` [Qemu-devel] [PATCH V3 5/5] libqblock test example code Wenchao Xia
@ 2012-09-18 10:10   ` Paolo Bonzini
  2012-09-19  6:40     ` Wenchao Xia
  0 siblings, 1 reply; 18+ messages in thread
From: Paolo Bonzini @ 2012-09-18 10:10 UTC (permalink / raw)
  To: Wenchao Xia; +Cc: kwolf, aliguori, stefanha, qemu-devel, blauwirbel, eblake

Il 18/09/2012 11:01, Wenchao Xia ha scritto:
>   In this example, user first create two qcow2 images, and then get the
> backing file relationship information of them. Then does write and read
> sync IO on them.

Please use gtest so that this can be easily extensible.

Paolo

> Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
> ---
>  tests/libqblock/libqblock-test.c |  233 ++++++++++++++++++++++++++++++++++++++
>  1 files changed, 233 insertions(+), 0 deletions(-)
> 
> diff --git a/tests/libqblock/libqblock-test.c b/tests/libqblock/libqblock-test.c
> index c05c0c4..c0b7963 100644
> --- a/tests/libqblock/libqblock-test.c
> +++ b/tests/libqblock/libqblock-test.c
> @@ -1,4 +1,237 @@
> +/*
> + * QEMU block layer library test
> + *
> + * Copyright IBM, Corp. 2012
> + *
> + * Authors:
> + *  Wenchao Xia   <xiawenc@linux.vnet.ibm.com>
> + *
> + * This work is licensed under the terms of the GNU LGPL, version 2 or later.
> + * See the COPYING.LIB file in the top-level directory.
> + *
> + */
> +
> +#include <stdarg.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +#include <inttypes.h>
> +#include <string.h>
> +#include <stdlib.h>
> +#include "libqblock.h"
> +
> +#define TEST_BUF_SIZE 1024
> +static unsigned char buf_r[TEST_BUF_SIZE];
> +static unsigned char buf_w[TEST_BUF_SIZE] = {0, 0, 0, 0};
> +
> +typedef struct VerifyData {
> +    unsigned char *buf_r;
> +    unsigned char *buf_w;
> +    int len;
> +} VerifyData;
> +
> +static void print_loc(QBlockProtInfo *loc)
> +{
> +    if (loc == NULL) {
> +        printf("backing file is NULL.");
> +        return;
> +    }
> +    switch (loc->prot_type) {
> +    case QB_PROT_NONE:
> +        printf("protocol type [none].");
> +        break;
> +    case QB_PROT_FILE:
> +        printf("protocol type [file], filename [%s].",
> +               loc->prot_op.o_file.filename);
> +        break;
> +    default:
> +        printf("protocol type not supported.");
> +        break;
> +    }
> +}
> +
> +static void print_info_image_static(QBlockStaticInfo *info)
> +{
> +    printf("=======image location:\n");
> +    print_loc(&info->loc);
> +    printf("\nvirtual_size %" PRId64 ", format type %d [%s]",
> +           *(info->member_addr->virt_size),
> +           info->fmt.fmt_type, qb_fmttype2str(info->fmt.fmt_type));
> +    printf("\nbacking image location:\n");
> +    print_loc(info->member_addr->backing_loc);
> +    printf("\n");
> +}
> +
> +static void test_check(VerifyData *vdata)
> +{
> +    int cmp;
> +    cmp = memcmp(vdata->buf_r, vdata->buf_w, vdata->len);
> +    if (cmp == 0) {
> +        printf("compare succeed, %d.\n", vdata->buf_r[24]);
> +    } else {
> +        printf("!!! compare fail, %d.\n", vdata->buf_r[24]);
> +        exit(1);
> +    }
> +}
> +
>  int main(int argc, char **argv)
>  {
> +    const char *filename1, *filename2;
> +    QBroker *broker = NULL;
> +    QBlockState *qbs = NULL;
> +    QBlockProtInfo *ol = NULL;
> +    QBlockFmtInfo *of = NULL;
> +    QBlockStaticInfo *info_st = NULL;
> +    int ret, flag;
> +    int test_offset = 510;
> +    int test_len = 520;
> +    VerifyData vdata;
> +    char err_str[1024];
> +
> +    vdata.buf_r = buf_r;
> +    vdata.buf_w = buf_w;
> +    vdata.len = test_len;
> +
> +    filename1 = "./qemu_image1";
> +    filename2 = "./qemu_image2";
> +    printf("qemu test, filename1 is %s, filename2 is %s.\n",
> +                                       filename1, filename2);
> +
> +    ret = qb_broker_new(&broker);
> +    if (ret < 0) {
> +        goto free;
> +    }
> +
> +    ret = qb_state_new(broker, &qbs);
> +    if (ret < 0) {
> +        goto free;
> +    }
> +
> +    ret = qb_prot_info_new(broker, &ol);
> +    if (ret < 0) {
> +        goto free;
> +    }
> +
> +    ret = qb_fmt_info_new(broker, &of);
> +    if (ret < 0) {
> +        goto free;
> +    }
> +
> +    /* create a new image */
> +
> +    ol->prot_type = QB_PROT_FILE;
> +    ol->prot_op.o_file.filename = filename2;
> +    of->fmt_type = QB_FMT_QCOW2;
> +    of->fmt_op.o_qcow2.virt_size = 100 * 1024;
> +    flag = 0;
> +
> +    ret = qb_create(broker, qbs, ol, of, flag);
> +    if (ret < 0) {
> +        qb_error_get_human_str(broker, err_str, sizeof(err_str));
> +        printf("create fail 1. %s.\n", err_str);
> +        goto unlink;
> +    }
> +
> +    ol->prot_type = QB_PROT_FILE;
> +    ol->prot_op.o_file.filename = filename1;
> +    of->fmt_type = QB_FMT_QCOW2;
> +    of->fmt_op.o_qcow2.backing_loc.prot_type = QB_PROT_FILE;
> +    of->fmt_op.o_qcow2.backing_loc.prot_op.o_file.filename = filename2;
> +    flag = 0;
> +    ret = qb_create(broker, qbs, ol, of, flag);
> +    if (ret < 0) {
> +        qb_error_get_human_str(broker, err_str, sizeof(err_str));
> +        printf("create fail 2. %s.\n", err_str);
> +        goto unlink;
> +    }
> +
> +    /* get informations */
> +    ol->prot_type = QB_PROT_FILE;
> +    ol->prot_op.o_file.filename = filename1;
> +    of->fmt_type = QB_FMT_NONE;
> +    flag = LIBQBLOCK_O_NO_BACKING;
> +    ret = qb_open(broker, qbs, ol, of, flag);
> +    if (ret < 0) {
> +        qb_error_get_human_str(broker, err_str, sizeof(err_str));
> +        printf("info getting, open failed. %s.\n", err_str);
> +        goto free;
> +    }
> +
> +    while (1) {
> +        ret = qb_info_image_static_get(broker, qbs, &info_st);
> +        if (ret < 0) {
> +            qb_error_get_human_str(broker, err_str, sizeof(err_str));
> +            printf("info get error. %s.\n", err_str);
> +            goto close;
> +        }
> +        print_info_image_static(info_st);
> +        qb_close(broker, qbs);
> +        if ((info_st->member_addr->backing_loc == NULL) ||
> +            (info_st->member_addr->backing_loc->prot_type == QB_FMT_NONE)) {
> +            break;
> +        }
> +        *ol = *(info_st->member_addr->backing_loc);
> +        ret = qb_open(broker, qbs, ol, of, flag);
> +        if (ret < 0) {
> +            qb_error_get_human_str(broker, err_str, sizeof(err_str));
> +            printf("info getting, open failed in backing file. %s.\n",
> +                                                       err_str);
> +            goto free;
> +        }
> +        qb_info_image_static_delete(broker, &info_st);
> +    }
> +    /* read and write the image */
> +    ol->prot_type = QB_PROT_FILE;
> +    ol->prot_op.o_file.filename = filename1;
> +    of->fmt_type = QB_FMT_NONE;
> +    flag = LIBQBLOCK_O_RDWR;
> +    ret = qb_open(broker, qbs, ol, of, flag);
> +    if (ret < 0) {
> +        qb_error_get_human_str(broker, err_str, sizeof(err_str));
> +        printf("open failed. %s.\n", err_str);
> +        goto free;
> +    }
> +
> +    buf_w[1] = 1;
> +    buf_w[2] = 2;
> +    buf_w[514] = 4;
> +    memset(buf_r, 0, sizeof(buf_r));
> +
> +    ret = qb_write(broker, qbs, buf_w, test_len, test_offset);
> +    if (ret < 0) {
> +        qb_error_get_human_str(broker, err_str, sizeof(err_str));
> +        printf("%s.\n", err_str);
> +        goto close;
> +    }
> +
> +    ret = qb_read(broker, qbs, buf_r, test_len, test_offset);
> +    if (ret < 0) {
> +        qb_error_get_human_str(broker, err_str, sizeof(err_str));
> +        printf("%s.\n", err_str);
> +        goto close;
> +    }
> +
> +    test_check(&vdata);
> +
> + close:
> +    qb_close(broker, qbs);
> + unlink:
> +    unlink(filename1);
> +    unlink(filename2);
> + free:
> +    if (info_st != NULL) {
> +        qb_info_image_static_delete(broker, &info_st);
> +    }
> +    if (qbs != NULL) {
> +        qb_state_delete(broker, &qbs);
> +    }
> +    if (ol != NULL) {
> +        qb_prot_info_delete(broker, &ol);
> +    }
> +    if (of != NULL) {
> +        qb_fmt_info_delete(broker, &of);
> +    }
> +    if (broker != NULL) {
> +        qb_broker_delete(&broker);
> +    }
>      return 0;
>  }
> 

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH V3 1/5] libqblock build system
  2012-09-18  9:01 ` [Qemu-devel] [PATCH V3 1/5] libqblock build system Wenchao Xia
  2012-09-18 10:05   ` Paolo Bonzini
@ 2012-09-18 10:31   ` Paolo Bonzini
  1 sibling, 0 replies; 18+ messages in thread
From: Paolo Bonzini @ 2012-09-18 10:31 UTC (permalink / raw)
  To: Wenchao Xia; +Cc: kwolf, aliguori, stefanha, qemu-devel, blauwirbel, eblake

Il 18/09/2012 11:01, Wenchao Xia ha scritto:
>   Libqblock was placed in new directory ./libqblock, libtool will build
> dynamic library there, source files of block layer remains in ./block.
> So block related source code will generate 3 sets of binary, first is old
> ones used in qemu, second and third are non PIC and PIC ones in ./libqblock.
>   GCC compiler flag visibility=hidden was used with special macro, to export
> only symbols that was marked as PUBLIC.
> 
> Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
> ---
>  Makefile                    |   13 ++++++++-
>  Makefile.objs               |    6 ++++
>  libqblock/Makefile          |   64 +++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 82 insertions(+), 1 deletions(-)
>  create mode 100644 libqblock/Makefile
>  create mode 100644 libqblock/libqblock-error.c
>  create mode 100644 libqblock/libqblock.c
> 
> diff --git a/Makefile b/Makefile
> index 971e92f..b0b9b8d 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -164,6 +164,17 @@ qemu-io$(EXESUF): qemu-io.o cmd.o $(tools-obj-y) $(block-obj-y)
>  
>  qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o
>  
> +######################################################################
> +# Support building shared library libqblock
> +ifeq ($(LIBTOOL),)
> +$(libqblock-lib-la):
> +	@echo "libtool is missing, please install and rerun configure"; exit 1
> +else
> +$(libqblock-lib-la):
> +	$(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C libqblock V="$(V)" TARGET_DIR="$*/" $(libqblock-lib-la),)
> +endif
> +###########################################################################
> +
>  vscclient$(EXESUF): $(libcacard-y) $(oslib-obj-y) $(trace-obj-y) $(tools-obj-y) qemu-timer-common.o libcacard/vscclient.o
>  	$(call quiet-command,$(CC) $(LDFLAGS) -o $@ $^ $(libcacard_libs) $(LIBS),"  LINK  $@")
>  
> @@ -227,7 +238,7 @@ clean:
>  	rm -rf qapi-generated
>  	rm -rf qga/qapi-generated
>  	$(MAKE) -C tests/tcg clean
> -	for d in $(ALL_SUBDIRS) $(QEMULIBS) libcacard; do \
> +	for d in $(ALL_SUBDIRS) $(QEMULIBS) libcacard libqblock; do \
>  	if test -d $$d; then $(MAKE) -C $$d $@ || exit 1; fi; \
>  	rm -f $$d/qemu-options.def; \
>          done
> diff --git a/Makefile.objs b/Makefile.objs
> index 4412757..8a4c9fc 100644
> --- a/Makefile.objs
> +++ b/Makefile.objs
> @@ -248,3 +248,9 @@ nested-vars += \
>  	common-obj-y \
>  	extra-obj-y
>  dummy := $(call unnest-vars)
> +
> +#############################################################################
> +# libqblock
> +
> +libqblock-lib-la = libqblock.la
> +libqblock-lib-path = libqblock
> diff --git a/libqblock/Makefile b/libqblock/Makefile
> new file mode 100644
> index 0000000..bf7abcc
> --- /dev/null
> +++ b/libqblock/Makefile
> @@ -0,0 +1,64 @@
> +###########################################################################
> +# libqblock Makefile
> +# Todo:
> +#    1 trace related files is generated in this directory, move
> +#  them to the root directory.
> +##########################################################################
> +-include ../config-host.mak
> +-include $(SRC_PATH)/Makefile.objs
> +-include $(SRC_PATH)/rules.mak
> +
> +#############################################################################
> +# Library settings
> +#############################################################################
> +$(call set-vpath, $(SRC_PATH))
> +
> +#expand the foldered vars,especially ./block
> +dummy := $(call unnest-vars-1)
> +
> +#library objects
> +tools-obj-y = $(oslib-obj-y) $(trace-obj-y) qemu-tool.o qemu-timer.o \
> +	qemu-timer-common.o main-loop.o notify.o \
> +	iohandler.o cutils.o iov.o async.o
> +tools-obj-$(CONFIG_POSIX) += compatfd.o

Do you really need all of these?

(BTW, I posted recently a patch to move tools-obj-y to Makefile.objs.
It doesn't apply anymore, I'll repost---but the conflicts are trivial).

> +libqblock-y=libqblock.o libqblock-error.o
> +libqblock-lib-y=$(patsubst %.o,%.lo,$(libqblock-y))
> +
> +QEMU_OBJS=$(tools-obj-y) $(block-obj-y)
> +QEMU_OBJS_FILTERED=$(filter %.o,$(QEMU_OBJS))

What does this filter out?

> +QEMU_OBJS_LIB=$(patsubst %.o, %.lo,$(QEMU_OBJS_FILTERED))
> +
> +QEMU_CFLAGS+= -I../ -I../include
> +#adding magic macro define for symbol hiding and exposing
> +QEMU_CFLAGS+= -fvisibility=hidden -D LIBQB_BUILD
> +
> +#dependency libraries
> +LIBS+=-lz $(LIBS_TOOLS)
> +
> +#################################################################
> +# Runtime rules
> +#################################################################
> +clean:
> +	rm -f *.lo *.o *.d *.la libqblock-test trace.c trace.c-timestamp
> +	rm -rf .libs block trace
> +
> +all: libqblock-test

Do not put yet the libqblock-test rules in here, please.

Paolo

> +	@true
> +
> +help:
> +	@echo type make libqblock-test at root dirtory, libtool is required
> +
> +#make dir block at runtime which would hold the output of block/*.c
> +block:
> +	@mkdir block
> +
> +ifeq ($(LIBTOOL),)
> +$(libqblock-lib-la):
> +	@echo "libtool is missing, please install and rerun configure"; exit 1
> +else
> +$(libqblock-lib-la): $(libqblock-lib-y) $(QEMU_OBJS_LIB)
> +	$(call quiet-command,$(LIBTOOL) --mode=link --quiet --tag=CC $(CC) -rpath $(libdir) -o $@ $^ $(LIBS),"  lt LINK $@")
> +endif
> +
> +.PHONY: libqblock.la
> diff --git a/libqblock/libqblock-error.c b/libqblock/libqblock-error.c
> new file mode 100644
> index 0000000..e69de29
> diff --git a/libqblock/libqblock.c b/libqblock/libqblock.c
> new file mode 100644
> index 0000000..e69de29
> 

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH V3 2/5] libqblock type defines
  2012-09-18 10:05   ` Paolo Bonzini
@ 2012-09-19  3:23     ` Wenchao Xia
  0 siblings, 0 replies; 18+ messages in thread
From: Wenchao Xia @ 2012-09-19  3:23 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kwolf, aliguori, stefanha, qemu-devel, blauwirbel, eblake


> Il 18/09/2012 11:01, Wenchao Xia ha scritto:
>>    This patch contains type and defines used in APIs, one file for public usage
>> by user, one for libqblock internal usage.
>>
>> Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
>> ---
>>   libqblock/libqblock-internal.h |   56 +++++++++
>>   libqblock/libqblock-types.h    |  268 ++++++++++++++++++++++++++++++++++++++++
>>   2 files changed, 324 insertions(+), 0 deletions(-)
>>   create mode 100644 libqblock/libqblock-internal.h
>>   create mode 100644 libqblock/libqblock-types.h
>>
>> diff --git a/libqblock/libqblock-internal.h b/libqblock/libqblock-internal.h
>> new file mode 100644
>> index 0000000..87f32be
>> --- /dev/null
>> +++ b/libqblock/libqblock-internal.h
>> @@ -0,0 +1,56 @@
>> +/*
>> + * QEMU block layer library
>> + *
>> + * Copyright IBM, Corp. 2012
>> + *
>> + * Authors:
>> + *  Wenchao Xia   <xiawenc@linux.vnet.ibm.com>
>> + *
>> + * This work is licensed under the terms of the GNU LGPL, version 2 or later.
>> + * See the COPYING.LIB file in the top-level directory.
>> + *
>> + */
>> +
>> +#ifndef LIBQBLOCK_INTERNAL
>> +#define LIBQBLOCK_INTERNAL
>> +
>> +#include "glib.h"
>> +
>> +#include "block.h"
>> +#include "block_int.h"
>> +#include "libqblock-types.h"
>> +
>> +/* this file contains defines and types used inside the library. */
>> +
>> +#define FUNC_FREE(p) g_free((p))
>> +#define FUNC_MALLOC(size) g_malloc((size))
>> +#define FUNC_CALLOC(nmemb, size) g_malloc0((nmemb)*(size))
>> +
>> +#define CLEAN_FREE(p) { \
>> +        FUNC_FREE(p); \
>> +        (p) = NULL; \
>> +}
>> +
>> +/* details should be hidden to user */
>> +struct QBlockState {
>> +    BlockDriverState *bdrvs;
>> +    /* internal used file name now, if it is not NULL, it means
>> +       image was opened.
>> +    */
>> +    char *filename;
>> +} ;
>> +
>> +struct QBroker {
>> +    /* last error */
>> +    GError *g_error;
>> +    int err_ret; /* 1st level of error, the libqblock error number */
>> +    int err_no; /* 2nd level of error, errno what below reports */
>> +};
>
> Sorry for keeping on bikeshedding---a better name for this is
> QBlockContext.  "Context" is a well-known name for this kind of global
> object.
>
> Otherwise looks good---thanks for putting up with us! :)
>
> Paolo
>

   OK, will change the name to better ones, thank you for reviewing.

>> +#define G_LIBQBLOCK_ERROR g_libqbock_error_quark()
>> +
>> +static inline GQuark g_libqbock_error_quark(void)
>> +{
>> +    return g_quark_from_static_string("g-libqblock-error-quark");
>> +}
>> +#endif
>> diff --git a/libqblock/libqblock-types.h b/libqblock/libqblock-types.h
>> new file mode 100644
>> index 0000000..3c548b8
>> --- /dev/null
>> +++ b/libqblock/libqblock-types.h
>> @@ -0,0 +1,268 @@
>> +/*
>> + * QEMU block layer library
>> + *
>> + * Copyright IBM, Corp. 2012
>> + *
>> + * Authors:
>> + *  Wenchao Xia   <xiawenc@linux.vnet.ibm.com>
>> + *
>> + * This work is licensed under the terms of the GNU LGPL, version 2 or later.
>> + * See the COPYING.LIB file in the top-level directory.
>> + *
>> + */
>> +
>> +#ifndef LIBQBLOCK_TYPES_H
>> +#define LIBQBLOCK_TYPES_H
>> +
>> +#include <sys/types.h>
>> +#include <stdint.h>
>> +#include <stdbool.h>
>> +
>> +#if defined(__GNUC__) && __GNUC__ >= 4
>> +    #ifdef LIBQB_BUILD
>> +        #define DLL_PUBLIC __attribute__((visibility("default")))
>> +    #else
>> +        #define DLL_PUBLIC
>> +    #endif
>> +#else
>> +    #warning : gcc compiler version < 4, symbols can not be hidden.
>> +#endif
>> +
>> +/* this library is designed around this core struct. */
>> +typedef struct QBlockState QBlockState;
>> +
>> +/* every thread should have a broker. */
>> +typedef struct QBroker QBroker;
>> +
>> +/* flag used in open and create */
>> +#define LIBQBLOCK_O_RDWR        0x0002
>> +/* do not use the host page cache */
>> +#define LIBQBLOCK_O_NOCACHE     0x0020
>> +/* use write-back caching */
>> +#define LIBQBLOCK_O_CACHE_WB    0x0040
>> +/* don't open the backing file */
>> +#define LIBQBLOCK_O_NO_BACKING  0x0100
>> +/* disable flushing on this disk */
>> +#define LIBQBLOCK_O_NO_FLUSH    0x0200
>> +
>> +#define LIBQBLOCK_O_CACHE_MASK \
>> +   (LIBQBLOCK_O_NOCACHE | LIBQBLOCK_O_CACHE_WB | LIBQBLOCK_O_NO_FLUSH)
>> +
>> +#define LIBQBLOCK_O_VALID_MASK \
>> +   (LIBQBLOCK_O_RDWR | LIBQBLOCK_O_NOCACHE | LIBQBLOCK_O_CACHE_WB | \
>> +    LIBQBLOCK_O_NO_BACKING | LIBQBLOCK_O_NO_FLUSH)
>> +
>> +typedef enum QBlockProtType {
>> +    QB_PROT_NONE = 0,
>> +    QB_PROT_FILE,
>> +    QB_PROT_MAX
>> +} QBlockProtType;
>> +
>> +typedef struct QBlockProtOptionFile {
>> +    const char *filename;
>> +} QBlockProtOptionFile;
>> +
>> +#define QBLOCK_PROT_OPTIONS_UNION_SIZE (512)
>> +typedef union QBlockProtOptionsUnion {
>> +    QBlockProtOptionFile o_file;
>> +    uint8_t reserved[QBLOCK_PROT_OPTIONS_UNION_SIZE];
>> +} QBlockProtOptionsUnion;
>> +
>> +/**
>> + * struct QBlockProtInfo: contains information about how to find the image
>> + *
>> + * @prot_type: protocol type, now only support FILE.
>> + * @prot_op: protocol related options.
>> + */
>> +typedef struct QBlockProtInfo {
>> +    QBlockProtType prot_type;
>> +    QBlockProtOptionsUnion prot_op;
>> +} QBlockProtInfo;
>> +
>> +
>> +/* format related options */
>> +typedef enum QBlockFmtType {
>> +    QB_FMT_NONE = 0,
>> +    QB_FMT_COW,
>> +    QB_FMT_QED,
>> +    QB_FMT_QCOW,
>> +    QB_FMT_QCOW2,
>> +    QB_FMT_RAW,
>> +    QB_FMT_RBD,
>> +    QB_FMT_SHEEPDOG,
>> +    QB_FMT_VDI,
>> +    QB_FMT_VMDK,
>> +    QB_FMT_VPC,
>> +    QB_FMT_MAX
>> +} QBlockFmtType;
>> +
>> +typedef struct QBlockFmtOptionCow {
>> +    uint64_t virt_size;
>> +    QBlockProtInfo backing_loc;
>> +} QBlockFmtOptionCow;
>> +
>> +typedef struct QBlockFmtOptionQed {
>> +    uint64_t virt_size;
>> +    QBlockProtInfo backing_loc;
>> +    QBlockFmtType backing_fmt;
>> +    uint64_t cluster_size; /* unit is bytes */
>> +    uint64_t table_size; /* unit is clusters */
>> +} QBlockFmtOptionQed;
>> +
>> +typedef struct QBlockFmtOptionQcow {
>> +    uint64_t virt_size;
>> +    QBlockProtInfo backing_loc;
>> +    bool encrypt;
>> +} QBlockFmtOptionQcow;
>> +
>> +/* "Compatibility level (0.10 or 1.1)" */
>> +typedef enum QBlockFmtOptionQcow2CptLv {
>> +    QBO_FMT_QCOW2_CPT_NONE = 0,
>> +    QBO_FMT_QCOW2_CPT_V010,
>> +    QBO_FMT_QCOW2_CPT_V110,
>> +} QBlockFmtOptionQcow2CptLv;
>> +
>> +/* off or metadata */
>> +typedef enum QBlockFmtOptionQcow2PreAllocType {
>> +    QBO_FMT_QCOW2_PREALLOC_NONE = 0,
>> +    QBO_FMT_QCOW2_PREALLOC_OFF,
>> +    QBO_FMT_QCOW2_PREALLOC_METADATA,
>> +} QBlockFmtOptionQcow2PreAllocType;
>> +
>> +typedef struct QBlockFmtOptionQcow2 {
>> +    uint64_t virt_size;
>> +    QBlockProtInfo backing_loc;
>> +    QBlockFmtType backing_fmt;
>> +    bool encrypt;
>> +    uint64_t cluster_size; /* unit is bytes */
>> +    QBlockFmtOptionQcow2CptLv cpt_lv;
>> +    QBlockFmtOptionQcow2PreAllocType pre_mode;
>> +} QBlockFmtOptionQcow2;
>> +
>> +typedef struct QBlockFmtOptionRaw {
>> +    uint64_t virt_size;
>> +} QBlockFmtOptionRaw;
>> +
>> +typedef struct QBlockFmtOptionRbd {
>> +    uint64_t virt_size;
>> +    uint64_t cluster_size;
>> +} QBlockFmtOptionRbd;
>> +
>> +/* off or full */
>> +typedef enum QBlockFmtOptionSheepdogPreAllocType {
>> +    QBO_FMT_SD_PREALLOC_NONE = 0,
>> +    QBO_FMT_SD_PREALLOC_OFF,
>> +    QBO_FMT_SD_PREALLOC_FULL,
>> +} QBlockFmtOptionSheepdogPreAllocType;
>> +
>> +typedef struct QBlockFmtOptionSheepdog {
>> +    uint64_t virt_size;
>> +    QBlockProtInfo backing_loc;
>> +    QBlockFmtOptionSheepdogPreAllocType pre_mode;
>> +} QBlockFmtOptionSheepdog;
>> +
>> +typedef enum QBlockFmtOptionVdiPreAllocType {
>> +    QBO_FMT_VDI_PREALLOC_NONE = 0,
>> +    QBO_FMT_VDI_PREALLOC_FALSE,
>> +    QBO_FMT_VDI_PREALLOC_TRUE,
>> +} QBlockFmtOptionVdiPreAllocType;
>> +
>> +typedef struct QBlockFmtOptionVdi {
>> +    uint64_t virt_size;
>> +    uint64_t cluster_size;
>> +    QBlockFmtOptionVdiPreAllocType pre_mode;
>> +} QBlockFmtOptionVdi;
>> +
>> +/* whether compact to vmdk verion 6 */
>> +typedef enum QBlockFmtOptionVmdkCptLv {
>> +    QBO_FMT_VMDK_CPT_NONE = 0,
>> +    QBO_FMT_VMDK_CPT_VMDKV6_FALSE,
>> +    QBO_FMT_VMDK_CPT_VMDKV6_TRUE,
>> +} QBlockFmtOptionVmdkCptLv;
>> +
>> +/* vmdk flat extent format, values:
>> +"{monolithicSparse (default) | monolithicFlat | twoGbMaxExtentSparse |
>> +twoGbMaxExtentFlat | streamOptimized} */
>> +typedef enum QBlockFmtOptionVmdkSubfmtType {
>> +    QBO_FMT_VMDK_SUBFMT_MONOLITHIC_NONE = 0,
>> +    QBO_FMT_VMDK_SUBFMT_MONOLITHIC_SPARSE,
>> +    QBO_FMT_VMDK_SUBFMT_MONOLITHIC_FLAT,
>> +    QBO_FMT_VMDK_SUBFMT_TWOGBMAX_EXTENT_SPARSE,
>> +    QBO_FMT_VMDK_SUBFMT_TWOGBMAX_EXTENT_FLAT,
>> +    QBO_FMT_VMDK_SUBFMT_STREAM_OPTIMIZED,
>> +} QBlockFmtOptionVmdkSubfmtType;
>> +
>> +typedef struct QBlockFmtOptionVmdk {
>> +    uint64_t virt_size;
>> +    QBlockProtInfo backing_loc;
>> +    QBlockFmtOptionVmdkCptLv cpt_lv;
>> +    QBlockFmtOptionVmdkSubfmtType subfmt;
>> +} QBlockFmtOptionVmdk;
>> +
>> +/* "{dynamic (default) | fixed} " */
>> +typedef enum QBlockFmtOptionVpcSubfmtType {
>> +    QBO_FMT_VPC_SUBFMT_NONE = 0,
>> +    QBO_FMT_VPC_SUBFMT_DYNAMIC,
>> +    QBO_FMT_VPC_SUBFMT_FIXED,
>> +} QBlockFmtOptionVpcSubfmtType;
>> +
>> +typedef struct QBlockFmtOptionVpc {
>> +    uint64_t virt_size;
>> +    QBlockFmtOptionVpcSubfmtType subfmt;
>> +} QBlockFmtOptionVpc;
>> +
>> +#define QBLOCK_FMT_OPTIONS_UNION_SIZE (QBLOCK_PROT_OPTIONS_UNION_SIZE*2)
>> +typedef union QBlockFmtOptionsUnion {
>> +    QBlockFmtOptionCow       o_cow;
>> +    QBlockFmtOptionQed       o_qed;
>> +    QBlockFmtOptionQcow      o_qcow;
>> +    QBlockFmtOptionQcow2     o_qcow2;
>> +    QBlockFmtOptionRaw       o_raw;
>> +    QBlockFmtOptionRbd       o_rbd;
>> +    QBlockFmtOptionSheepdog  o_sheepdog;
>> +    QBlockFmtOptionVdi       o_vdi;
>> +    QBlockFmtOptionVmdk      o_vmdk;
>> +    QBlockFmtOptionVpc       o_vpc;
>> +    uint8_t reserved[QBLOCK_FMT_OPTIONS_UNION_SIZE];
>> +} QBlockFmtOptionsUnion;
>> +
>> +typedef struct QBlockFmtInfo {
>> +    QBlockFmtType fmt_type;
>> +    QBlockFmtOptionsUnion fmt_op;
>> +} QBlockFmtInfo;
>> +
>> +/**
>> + * QBlockStaticInfoAddr: a structure contains a set of pointer.
>> + *
>> + *    this struct contains a set of pointer pointing to some
>> + *  property related to format or protocol. If a property is not available,
>> + *  it will be set as NULL. User could use this to get property directly.
>> + *
>> + *  @virt_size: virtual size, it is always not NULL.
>> + *  @backing_loc: backing file location.
>> + *  @encrypt: encryption flag.
>> +*/
>> +
>> +typedef struct QBlockStaticInfoAddr {
>> +    uint64_t *virt_size;
>> +    QBlockProtInfo *backing_loc;
>> +    bool *encrypt;
>> +} QBlockStaticInfoAddr;
>> +
>> +/**
>> + * QBlockStaticInfo: information about the block image.
>> + *
>> + * @member_addr: contains pointer which can be used to access the structure.
>> + * @loc: location information.
>> + * @fmt: format information.
>> + * @sector_size: how many bytes in a sector, it is 512 usually.
>> + */
>> +typedef struct QBlockStaticInfo {
>> +    QBlockStaticInfoAddr *member_addr;
>> +    QBlockProtInfo loc;
>> +    QBlockFmtInfo fmt;
>> +    int sector_size;
>> +} QBlockStaticInfo;
>> +
>> +
>> +#endif
>>
>
>


-- 
Best Regards

Wenchao Xia

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH V3 1/5] libqblock build system
  2012-09-18 10:05   ` Paolo Bonzini
@ 2012-09-19  6:35     ` Wenchao Xia
  2012-09-19  9:57       ` Paolo Bonzini
  0 siblings, 1 reply; 18+ messages in thread
From: Wenchao Xia @ 2012-09-19  6:35 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kwolf, aliguori, stefanha, qemu-devel, blauwirbel, eblake

于 2012-9-18 18:05, Paolo Bonzini 写道:
> Il 18/09/2012 11:01, Wenchao Xia ha scritto:
>>    Libqblock was placed in new directory ./libqblock, libtool will build
>> dynamic library there, source files of block layer remains in ./block.
>> So block related source code will generate 3 sets of binary, first is old
>> ones used in qemu, second and third are non PIC and PIC ones in ./libqblock.
>>    GCC compiler flag visibility=hidden was used with special macro, to export
>> only symbols that was marked as PUBLIC.
>>
>> Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
>> ---
>>   Makefile                    |   13 ++++++++-
>>   Makefile.objs               |    6 ++++
>>   libqblock/Makefile          |   64 +++++++++++++++++++++++++++++++++++++++++++
>>   3 files changed, 82 insertions(+), 1 deletions(-)
>>   create mode 100644 libqblock/Makefile
>>   create mode 100644 libqblock/libqblock-error.c
>>   create mode 100644 libqblock/libqblock.c
>>
>> diff --git a/Makefile b/Makefile
>> index 971e92f..b0b9b8d 100644
>> --- a/Makefile
>> +++ b/Makefile
>> @@ -164,6 +164,17 @@ qemu-io$(EXESUF): qemu-io.o cmd.o $(tools-obj-y) $(block-obj-y)
>>
>>   qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o
>>
>> +######################################################################
>> +# Support building shared library libqblock
>> +ifeq ($(LIBTOOL),)
>> +$(libqblock-lib-la):
>> +	@echo "libtool is missing, please install and rerun configure"; exit 1
>> +else
>> +$(libqblock-lib-la):
>> +	$(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C libqblock V="$(V)" TARGET_DIR="$*/" $(libqblock-lib-la),)
>> +endif
>> +###########################################################################
>> +
>>   vscclient$(EXESUF): $(libcacard-y) $(oslib-obj-y) $(trace-obj-y) $(tools-obj-y) qemu-timer-common.o libcacard/vscclient.o
>>   	$(call quiet-command,$(CC) $(LDFLAGS) -o $@ $^ $(libcacard_libs) $(LIBS),"  LINK  $@")
>>
>> @@ -227,7 +238,7 @@ clean:
>>   	rm -rf qapi-generated
>>   	rm -rf qga/qapi-generated
>>   	$(MAKE) -C tests/tcg clean
>> -	for d in $(ALL_SUBDIRS) $(QEMULIBS) libcacard; do \
>> +	for d in $(ALL_SUBDIRS) $(QEMULIBS) libcacard libqblock; do \
>>   	if test -d $$d; then $(MAKE) -C $$d $@ || exit 1; fi; \
>>   	rm -f $$d/qemu-options.def; \
>>           done
>> diff --git a/Makefile.objs b/Makefile.objs
>> index 4412757..8a4c9fc 100644
>> --- a/Makefile.objs
>> +++ b/Makefile.objs
>> @@ -248,3 +248,9 @@ nested-vars += \
>>   	common-obj-y \
>>   	extra-obj-y
>>   dummy := $(call unnest-vars)
>> +
>> +#############################################################################
>> +# libqblock
>> +
>> +libqblock-lib-la = libqblock.la
>> +libqblock-lib-path = libqblock
>> diff --git a/libqblock/Makefile b/libqblock/Makefile
>> new file mode 100644
>> index 0000000..bf7abcc
>> --- /dev/null
>> +++ b/libqblock/Makefile
>> @@ -0,0 +1,64 @@
>> +###########################################################################
>> +# libqblock Makefile
>> +# Todo:
>> +#    1 trace related files is generated in this directory, move
>> +#  them to the root directory.
>> +##########################################################################
>> +-include ../config-host.mak
>> +-include $(SRC_PATH)/Makefile.objs
>> +-include $(SRC_PATH)/rules.mak
>> +
>> +#############################################################################
>> +# Library settings
>> +#############################################################################
>> +$(call set-vpath, $(SRC_PATH))
>> +
>> +#expand the foldered vars,especially ./block
>> +dummy := $(call unnest-vars-1)
>> +
>> +#library objects
>> +tools-obj-y = $(oslib-obj-y) $(trace-obj-y) qemu-tool.o qemu-timer.o \
>> +	qemu-timer-common.o main-loop.o notify.o \
>> +	iohandler.o cutils.o iov.o async.o
>> +tools-obj-$(CONFIG_POSIX) += compatfd.o
>
> Do you really need all of these?
>
   I guess only some .o are needed, but not sure how to pick them out, 
is there some tools which can help detect which object files are needed
in final linkage?

> (BTW, I posted recently a patch to move tools-obj-y to Makefile.objs.
> It doesn't apply anymore, I'll repost---but the conflicts are trivial).
>
   greate, then I can use tools-obj-y directly.

>> +libqblock-y=libqblock.o libqblock-error.o
>> +libqblock-lib-y=$(patsubst %.o,%.lo,$(libqblock-y))
>> +
>> +QEMU_OBJS=$(tools-obj-y) $(block-obj-y)
>> +QEMU_OBJS_FILTERED=$(filter %.o,$(QEMU_OBJS))
>
> What does this filter out?
>
   $(block-obj-y) contains /block, which would cause trouble in building,
so filtered it out.

> Paolo
>
>> +QEMU_OBJS_LIB=$(patsubst %.o, %.lo,$(QEMU_OBJS_FILTERED))
>> +
>> +QEMU_CFLAGS+= -I../ -I../include
>> +#adding magic macro define for symbol hiding and exposing
>> +QEMU_CFLAGS+= -fvisibility=hidden -D LIBQB_BUILD
>> +
>> +#dependency libraries
>> +LIBS+=-lz $(LIBS_TOOLS)
>> +
>> +#################################################################
>> +# Runtime rules
>> +#################################################################
>> +clean:
>> +	rm -f *.lo *.o *.d *.la libqblock-test trace.c trace.c-timestamp
>> +	rm -rf .libs block trace
>> +
>> +all: libqblock-test
>> +	@true
>> +
>> +help:
>> +	@echo type make libqblock-test at root dirtory, libtool is required
>> +
>> +#make dir block at runtime which would hold the output of block/*.c
>> +block:
>> +	@mkdir block
>> +
>> +ifeq ($(LIBTOOL),)
>> +$(libqblock-lib-la):
>> +	@echo "libtool is missing, please install and rerun configure"; exit 1
>> +else
>> +$(libqblock-lib-la): $(libqblock-lib-y) $(QEMU_OBJS_LIB)
>> +	$(call quiet-command,$(LIBTOOL) --mode=link --quiet --tag=CC $(CC) -rpath $(libdir) -o $@ $^ $(LIBS),"  lt LINK $@")
>> +endif
>> +
>> +.PHONY: libqblock.la
>> diff --git a/libqblock/libqblock-error.c b/libqblock/libqblock-error.c
>> new file mode 100644
>> index 0000000..e69de29
>> diff --git a/libqblock/libqblock.c b/libqblock/libqblock.c
>> new file mode 100644
>> index 0000000..e69de29
>>
>


-- 
Best Regards

Wenchao Xia

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH V3 4/5] libqblock test build system
  2012-09-18 10:10   ` Paolo Bonzini
@ 2012-09-19  6:39     ` Wenchao Xia
  0 siblings, 0 replies; 18+ messages in thread
From: Wenchao Xia @ 2012-09-19  6:39 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kwolf, aliguori, stefanha, qemu-devel, blauwirbel, eblake

于 2012-9-18 18:10, Paolo Bonzini 写道:
> Il 18/09/2012 11:01, Wenchao Xia ha scritto:
>>    Created a new directory in tests, make chekc-libqblock will build an
>> executable binrary, make clean will delete it.
>>
>> Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
>> ---
>>   .gitignore                       |    1 +
>>   Makefile                         |    1 +
>>   tests/Makefile                   |    3 +++
>>   tests/libqblock/Makefile         |   32 ++++++++++++++++++++++++++++++++
>>   tests/libqblock/libqblock-test.c |    4 ++++
>>   5 files changed, 41 insertions(+), 0 deletions(-)
>>   create mode 100644 tests/libqblock/Makefile
>>   create mode 100644 tests/libqblock/libqblock-test.c
>>
>> diff --git a/.gitignore b/.gitignore
>> index 824c0d2..eccb637 100644
>> --- a/.gitignore
>> +++ b/.gitignore
>> @@ -95,3 +95,4 @@ cscope.*
>>   tags
>>   TAGS
>>   *~
>> +tests/libqblock/*.bin
>> diff --git a/Makefile b/Makefile
>> index b0b9b8d..de8ea17 100644
>> --- a/Makefile
>> +++ b/Makefile
>> @@ -238,6 +238,7 @@ clean:
>>   	rm -rf qapi-generated
>>   	rm -rf qga/qapi-generated
>>   	$(MAKE) -C tests/tcg clean
>> +	$(MAKE) -C tests/libqblock clean
>>   	for d in $(ALL_SUBDIRS) $(QEMULIBS) libcacard libqblock; do \
>>   	if test -d $$d; then $(MAKE) -C $$d $@ || exit 1; fi; \
>>   	rm -f $$d/qemu-options.def; \
>> diff --git a/tests/Makefile b/tests/Makefile
>> index 26a67ce..69af1e2 100644
>> --- a/tests/Makefile
>> +++ b/tests/Makefile
>> @@ -148,4 +148,7 @@ check-unit: $(patsubst %,check-%, $(check-unit-y))
>>   check-block: $(patsubst %,check-%, $(check-block-y))
>>   check: check-unit check-qtest
>>
>> +check-libqblock:
>> +	$(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C tests/libqblock V="$(V)" TARGET_DIR="$*/" check-libqblock,)
>
> Please just put everything in tests/Makefile. "make check" should run it
> if LIBTOOL is available.
>
   OK.

>> +libqblock-test.bin: $(libqblock-test-objs) $(libqblock-la-path)
>> +	$(call quiet-command,$(LIBTOOL) --mode=link --quiet --tag=CC $(CC) -shared -rpath $(libdir) -o $@ $^,"  lt LINK $@")
>
> .bin looks so MS-DOS. :)
>

> Paolo
>


-- 
Best Regards

Wenchao Xia

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH V3 5/5] libqblock test example code
  2012-09-18 10:10   ` Paolo Bonzini
@ 2012-09-19  6:40     ` Wenchao Xia
  0 siblings, 0 replies; 18+ messages in thread
From: Wenchao Xia @ 2012-09-19  6:40 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kwolf, aliguori, stefanha, qemu-devel, blauwirbel, eblake

于 2012-9-18 18:10, Paolo Bonzini 写道:
> Il 18/09/2012 11:01, Wenchao Xia ha scritto:
>>    In this example, user first create two qcow2 images, and then get the
>> backing file relationship information of them. Then does write and read
>> sync IO on them.
>
> Please use gtest so that this can be easily extensible.
>
> Paolo
>
   OK.

>> Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
>> ---
>>   tests/libqblock/libqblock-test.c |  233 ++++++++++++++++++++++++++++++++++++++
>>   1 files changed, 233 insertions(+), 0 deletions(-)
>>
>> diff --git a/tests/libqblock/libqblock-test.c b/tests/libqblock/libqblock-test.c
>> index c05c0c4..c0b7963 100644
>> --- a/tests/libqblock/libqblock-test.c
>> +++ b/tests/libqblock/libqblock-test.c
>> @@ -1,4 +1,237 @@
>> +/*
>> + * QEMU block layer library test
>> + *
>> + * Copyright IBM, Corp. 2012
>> + *
>> + * Authors:
>> + *  Wenchao Xia   <xiawenc@linux.vnet.ibm.com>
>> + *
>> + * This work is licensed under the terms of the GNU LGPL, version 2 or later.
>> + * See the COPYING.LIB file in the top-level directory.
>> + *
>> + */
>> +
>> +#include <stdarg.h>
>> +#include <stdio.h>
>> +#include <unistd.h>
>> +#include <inttypes.h>
>> +#include <string.h>
>> +#include <stdlib.h>
>> +#include "libqblock.h"
>> +
>> +#define TEST_BUF_SIZE 1024
>> +static unsigned char buf_r[TEST_BUF_SIZE];
>> +static unsigned char buf_w[TEST_BUF_SIZE] = {0, 0, 0, 0};
>> +
>> +typedef struct VerifyData {
>> +    unsigned char *buf_r;
>> +    unsigned char *buf_w;
>> +    int len;
>> +} VerifyData;
>> +
>> +static void print_loc(QBlockProtInfo *loc)
>> +{
>> +    if (loc == NULL) {
>> +        printf("backing file is NULL.");
>> +        return;
>> +    }
>> +    switch (loc->prot_type) {
>> +    case QB_PROT_NONE:
>> +        printf("protocol type [none].");
>> +        break;
>> +    case QB_PROT_FILE:
>> +        printf("protocol type [file], filename [%s].",
>> +               loc->prot_op.o_file.filename);
>> +        break;
>> +    default:
>> +        printf("protocol type not supported.");
>> +        break;
>> +    }
>> +}
>> +
>> +static void print_info_image_static(QBlockStaticInfo *info)
>> +{
>> +    printf("=======image location:\n");
>> +    print_loc(&info->loc);
>> +    printf("\nvirtual_size %" PRId64 ", format type %d [%s]",
>> +           *(info->member_addr->virt_size),
>> +           info->fmt.fmt_type, qb_fmttype2str(info->fmt.fmt_type));
>> +    printf("\nbacking image location:\n");
>> +    print_loc(info->member_addr->backing_loc);
>> +    printf("\n");
>> +}
>> +
>> +static void test_check(VerifyData *vdata)
>> +{
>> +    int cmp;
>> +    cmp = memcmp(vdata->buf_r, vdata->buf_w, vdata->len);
>> +    if (cmp == 0) {
>> +        printf("compare succeed, %d.\n", vdata->buf_r[24]);
>> +    } else {
>> +        printf("!!! compare fail, %d.\n", vdata->buf_r[24]);
>> +        exit(1);
>> +    }
>> +}
>> +
>>   int main(int argc, char **argv)
>>   {
>> +    const char *filename1, *filename2;
>> +    QBroker *broker = NULL;
>> +    QBlockState *qbs = NULL;
>> +    QBlockProtInfo *ol = NULL;
>> +    QBlockFmtInfo *of = NULL;
>> +    QBlockStaticInfo *info_st = NULL;
>> +    int ret, flag;
>> +    int test_offset = 510;
>> +    int test_len = 520;
>> +    VerifyData vdata;
>> +    char err_str[1024];
>> +
>> +    vdata.buf_r = buf_r;
>> +    vdata.buf_w = buf_w;
>> +    vdata.len = test_len;
>> +
>> +    filename1 = "./qemu_image1";
>> +    filename2 = "./qemu_image2";
>> +    printf("qemu test, filename1 is %s, filename2 is %s.\n",
>> +                                       filename1, filename2);
>> +
>> +    ret = qb_broker_new(&broker);
>> +    if (ret < 0) {
>> +        goto free;
>> +    }
>> +
>> +    ret = qb_state_new(broker, &qbs);
>> +    if (ret < 0) {
>> +        goto free;
>> +    }
>> +
>> +    ret = qb_prot_info_new(broker, &ol);
>> +    if (ret < 0) {
>> +        goto free;
>> +    }
>> +
>> +    ret = qb_fmt_info_new(broker, &of);
>> +    if (ret < 0) {
>> +        goto free;
>> +    }
>> +
>> +    /* create a new image */
>> +
>> +    ol->prot_type = QB_PROT_FILE;
>> +    ol->prot_op.o_file.filename = filename2;
>> +    of->fmt_type = QB_FMT_QCOW2;
>> +    of->fmt_op.o_qcow2.virt_size = 100 * 1024;
>> +    flag = 0;
>> +
>> +    ret = qb_create(broker, qbs, ol, of, flag);
>> +    if (ret < 0) {
>> +        qb_error_get_human_str(broker, err_str, sizeof(err_str));
>> +        printf("create fail 1. %s.\n", err_str);
>> +        goto unlink;
>> +    }
>> +
>> +    ol->prot_type = QB_PROT_FILE;
>> +    ol->prot_op.o_file.filename = filename1;
>> +    of->fmt_type = QB_FMT_QCOW2;
>> +    of->fmt_op.o_qcow2.backing_loc.prot_type = QB_PROT_FILE;
>> +    of->fmt_op.o_qcow2.backing_loc.prot_op.o_file.filename = filename2;
>> +    flag = 0;
>> +    ret = qb_create(broker, qbs, ol, of, flag);
>> +    if (ret < 0) {
>> +        qb_error_get_human_str(broker, err_str, sizeof(err_str));
>> +        printf("create fail 2. %s.\n", err_str);
>> +        goto unlink;
>> +    }
>> +
>> +    /* get informations */
>> +    ol->prot_type = QB_PROT_FILE;
>> +    ol->prot_op.o_file.filename = filename1;
>> +    of->fmt_type = QB_FMT_NONE;
>> +    flag = LIBQBLOCK_O_NO_BACKING;
>> +    ret = qb_open(broker, qbs, ol, of, flag);
>> +    if (ret < 0) {
>> +        qb_error_get_human_str(broker, err_str, sizeof(err_str));
>> +        printf("info getting, open failed. %s.\n", err_str);
>> +        goto free;
>> +    }
>> +
>> +    while (1) {
>> +        ret = qb_info_image_static_get(broker, qbs, &info_st);
>> +        if (ret < 0) {
>> +            qb_error_get_human_str(broker, err_str, sizeof(err_str));
>> +            printf("info get error. %s.\n", err_str);
>> +            goto close;
>> +        }
>> +        print_info_image_static(info_st);
>> +        qb_close(broker, qbs);
>> +        if ((info_st->member_addr->backing_loc == NULL) ||
>> +            (info_st->member_addr->backing_loc->prot_type == QB_FMT_NONE)) {
>> +            break;
>> +        }
>> +        *ol = *(info_st->member_addr->backing_loc);
>> +        ret = qb_open(broker, qbs, ol, of, flag);
>> +        if (ret < 0) {
>> +            qb_error_get_human_str(broker, err_str, sizeof(err_str));
>> +            printf("info getting, open failed in backing file. %s.\n",
>> +                                                       err_str);
>> +            goto free;
>> +        }
>> +        qb_info_image_static_delete(broker, &info_st);
>> +    }
>> +    /* read and write the image */
>> +    ol->prot_type = QB_PROT_FILE;
>> +    ol->prot_op.o_file.filename = filename1;
>> +    of->fmt_type = QB_FMT_NONE;
>> +    flag = LIBQBLOCK_O_RDWR;
>> +    ret = qb_open(broker, qbs, ol, of, flag);
>> +    if (ret < 0) {
>> +        qb_error_get_human_str(broker, err_str, sizeof(err_str));
>> +        printf("open failed. %s.\n", err_str);
>> +        goto free;
>> +    }
>> +
>> +    buf_w[1] = 1;
>> +    buf_w[2] = 2;
>> +    buf_w[514] = 4;
>> +    memset(buf_r, 0, sizeof(buf_r));
>> +
>> +    ret = qb_write(broker, qbs, buf_w, test_len, test_offset);
>> +    if (ret < 0) {
>> +        qb_error_get_human_str(broker, err_str, sizeof(err_str));
>> +        printf("%s.\n", err_str);
>> +        goto close;
>> +    }
>> +
>> +    ret = qb_read(broker, qbs, buf_r, test_len, test_offset);
>> +    if (ret < 0) {
>> +        qb_error_get_human_str(broker, err_str, sizeof(err_str));
>> +        printf("%s.\n", err_str);
>> +        goto close;
>> +    }
>> +
>> +    test_check(&vdata);
>> +
>> + close:
>> +    qb_close(broker, qbs);
>> + unlink:
>> +    unlink(filename1);
>> +    unlink(filename2);
>> + free:
>> +    if (info_st != NULL) {
>> +        qb_info_image_static_delete(broker, &info_st);
>> +    }
>> +    if (qbs != NULL) {
>> +        qb_state_delete(broker, &qbs);
>> +    }
>> +    if (ol != NULL) {
>> +        qb_prot_info_delete(broker, &ol);
>> +    }
>> +    if (of != NULL) {
>> +        qb_fmt_info_delete(broker, &of);
>> +    }
>> +    if (broker != NULL) {
>> +        qb_broker_delete(&broker);
>> +    }
>>       return 0;
>>   }
>>
>
>


-- 
Best Regards

Wenchao Xia

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH V3 1/5] libqblock build system
  2012-09-19  6:35     ` Wenchao Xia
@ 2012-09-19  9:57       ` Paolo Bonzini
  2012-09-27  2:15         ` Wenchao Xia
  0 siblings, 1 reply; 18+ messages in thread
From: Paolo Bonzini @ 2012-09-19  9:57 UTC (permalink / raw)
  To: Wenchao Xia; +Cc: kwolf, aliguori, stefanha, qemu-devel, blauwirbel, eblake

Il 19/09/2012 08:35, Wenchao Xia ha scritto:
>>>
>>> +QEMU_OBJS=$(tools-obj-y) $(block-obj-y)
>>> +QEMU_OBJS_FILTERED=$(filter %.o,$(QEMU_OBJS))
>>
>> What does this filter out?
>>
>   $(block-obj-y) contains /block, which would cause trouble in building,
> so filtered it out.

I think that's because you have to call unnest-vars, not unnest-vars-1.

Paolo

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH V3 1/5] libqblock build system
  2012-09-19  9:57       ` Paolo Bonzini
@ 2012-09-27  2:15         ` Wenchao Xia
  2012-09-27  7:14           ` Paolo Bonzini
  0 siblings, 1 reply; 18+ messages in thread
From: Wenchao Xia @ 2012-09-27  2:15 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kwolf, aliguori, stefanha, qemu-devel, blauwirbel, eblake

于 2012-9-19 17:57, Paolo Bonzini 写道:
> Il 19/09/2012 08:35, Wenchao Xia ha scritto:
>>>>
>>>> +QEMU_OBJS=$(tools-obj-y) $(block-obj-y)
>>>> +QEMU_OBJS_FILTERED=$(filter %.o,$(QEMU_OBJS))
>>>
>>> What does this filter out?
>>>
>>    $(block-obj-y) contains /block, which would cause trouble in building,
>> so filtered it out.
>
> I think that's because you have to call unnest-vars, not unnest-vars-1.
>
> Paolo
>
   Tried with unnest-vars, it will create some unnessary directories in
./libqblock, unnest-vars-1 seems more reasonable.


-- 
Best Regards

Wenchao Xia

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH V3 1/5] libqblock build system
  2012-09-27  2:15         ` Wenchao Xia
@ 2012-09-27  7:14           ` Paolo Bonzini
  0 siblings, 0 replies; 18+ messages in thread
From: Paolo Bonzini @ 2012-09-27  7:14 UTC (permalink / raw)
  To: Wenchao Xia; +Cc: kwolf, aliguori, stefanha, qemu-devel, blauwirbel, eblake

Il 27/09/2012 04:15, Wenchao Xia ha scritto:
> 于 2012-9-19 17:57, Paolo Bonzini 写道:
>> Il 19/09/2012 08:35, Wenchao Xia ha scritto:
>>>>>
>>>>> +QEMU_OBJS=$(tools-obj-y) $(block-obj-y)
>>>>> +QEMU_OBJS_FILTERED=$(filter %.o,$(QEMU_OBJS))
>>>>
>>>> What does this filter out?
>>>>
>>>    $(block-obj-y) contains /block, which would cause trouble in
>>> building,
>>> so filtered it out.
>>
>> I think that's because you have to call unnest-vars, not unnest-vars-1.
>>
>> Paolo
>>
>   Tried with unnest-vars, it will create some unnessary directories in
> ./libqblock, unnest-vars-1 seems more reasonable.

Don't worry about unnecessary directories, worry about correctness.

Paolo

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2012-09-27  7:14 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-09-18  9:01 [Qemu-devel] [PATCH V3 0/5] libqblock qemu block layer library Wenchao Xia
2012-09-18  9:01 ` [Qemu-devel] [PATCH V3 1/5] libqblock build system Wenchao Xia
2012-09-18 10:05   ` Paolo Bonzini
2012-09-19  6:35     ` Wenchao Xia
2012-09-19  9:57       ` Paolo Bonzini
2012-09-27  2:15         ` Wenchao Xia
2012-09-27  7:14           ` Paolo Bonzini
2012-09-18 10:31   ` Paolo Bonzini
2012-09-18  9:01 ` [Qemu-devel] [PATCH V3 2/5] libqblock type defines Wenchao Xia
2012-09-18 10:05   ` Paolo Bonzini
2012-09-19  3:23     ` Wenchao Xia
2012-09-18  9:01 ` [Qemu-devel] [PATCH V3 3/5] libqblock API Wenchao Xia
2012-09-18  9:01 ` [Qemu-devel] [PATCH V3 4/5] libqblock test build system Wenchao Xia
2012-09-18 10:10   ` Paolo Bonzini
2012-09-19  6:39     ` Wenchao Xia
2012-09-18  9:01 ` [Qemu-devel] [PATCH V3 5/5] libqblock test example code Wenchao Xia
2012-09-18 10:10   ` Paolo Bonzini
2012-09-19  6:40     ` Wenchao Xia

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).