diff mbox

[V19,07/10] libqblock: libqblock API design and type defines

Message ID 1360982897-16063-8-git-send-email-xiawenc@linux.vnet.ibm.com
State New
Headers show

Commit Message

Wayne Xia Feb. 16, 2013, 2:48 a.m. UTC
Public API design header files: libqblock.h, libqblock-error.h.
Public type define header files: libqblock-types.h. Private internal used
header files: libqblock-internal. For ABI some reserved bytes are used in
structure defines. Macro QEMU_DLL_PUBLIC is used to mark exported function.

Important APIs:
  1 QBlockImage. It stands for an block image object.
  2 QBlockStaticInfo. It contains static information such as location, backing
file, size.
  3 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>
---
 libqblock/libqblock-error.h    |   35 ++++++
 libqblock/libqblock-internal.h |   62 ++++++++++
 libqblock/libqblock-types.h    |  264 ++++++++++++++++++++++++++++++++++++++++
 libqblock/libqblock.h          |  246 +++++++++++++++++++++++++++++++++++++
 4 files changed, 607 insertions(+), 0 deletions(-)
 create mode 100644 libqblock/libqblock-internal.h

Comments

Eric Blake Feb. 20, 2013, 11:52 p.m. UTC | #1
On 02/15/2013 07:48 PM, Wenchao Xia wrote:
>   Public API design header files: libqblock.h, libqblock-error.h.
> Public type define header files: libqblock-types.h. Private internal used
> header files: libqblock-internal. For ABI some reserved bytes are used in
> structure defines. Macro QEMU_DLL_PUBLIC is used to mark exported function.
> 
> Important APIs:
>   1 QBlockImage. It stands for an block image object.
>   2 QBlockStaticInfo. It contains static information such as location, backing
> file, size.
>   3 Sync I/O. It is similar to C file open, read, write and close operations.
> 
> + */
> +#define QBLOCK_PROT_OPTIONS_UNION_SIZE (512/sizeof(QBlockReserved))
> +typedef struct QBlockLocationInfo {
> +    QBlockProtocol prot_type;
> +    union {
> +        QBlockProtocolOptionsFile o_file;
> +        QBlockReserved union_reserved[QBLOCK_PROT_OPTIONS_UNION_SIZE];
> +    };
> +    QBlockReserved reserved[LIBQBLOCK_RESERVED_SIZE];

Do you really mean to reserve trailing bytes after what you have already
reserved as part of the union?  Theoretically, the reserved space in the
union seems like it would be enough.


> +
> +typedef struct QBlockFormatOptionsQCOW2 {
> +    QBlockLocationInfo backing_loc;
> +    QBlockFormat backing_fmt;
> +    bool encrypt;
> +    uint64_t cluster_size; /* unit is bytes */
> +    QBlockFormatOptionsQCOW2CompatLv cpt_lv;
> +    QBlockFormatOptionsQCOW2PreAlloc pre_mode;
> +    QBlockReserved reserved[LIBQBLOCK_RESERVED_SIZE];
> +} QBlockFormatOptionsQCOW2;

Side note: Libvirt is leaning towards presenting compat-level 1.1 to the
user via the name 'qcow3', than it is to try and teach the users about
the difference between qcow2 (compat 1.0) and qcow2v3 (compat 1.1) all
under the name qcow2.  Even though the qcow2 code is able to handle both
compatibility levels under the hood in qemu source code, it seems less
confusing if the user interface separates things with a 'qcow3' naming
convention.  I don't know how much that should impact your design, though.


> +
> +#define QBLOCK_FMT_OPTIONS_UNION_SIZE (QBLOCK_PROT_OPTIONS_UNION_SIZE*2)

Spaces around binary operators.


> +/**
> + * QBlockStaticInfo: information about the block image.
> + *
> + * @loc: location information.
> + * @fmt: format information.
> + * @sector_size: how many bytes in a sector, it is 512 usually.

I'd drop ', it is 512 usually', since in the future, we might want to
default to 4096 in new images.


> +/**
> + * 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.
> + *
> + * @qbi: pointer to QBlockImage, used to get error message.
> + * @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, it is used if
> + *  backing file need to be opened..

s/.././


> +
> +/* advance image APIs */
> +/**
> + * qb_check_allocation: check if [start, start+length-1] was allocated on the
> + *  image.
> + *
> + * return 0 on success, libqblock negative error value on fail.
> + *
> + * @qbi: pointer to QBlockImage.
> + * @start: start position, unit is byte.
> + * @length: length to check, unit is byte, max is (INTMAX-1)*sector_size. If it

INT_MAX, not INTMAX.

Might be worth pointing to the API for determining sector_size, since it
is not a parameter in this function call.  Furthermore, since all the
relevant parameters are uint64_t, why is there an INT_MAX limitation in
the first place?  Even if underlying qemu code has a limitation at 2
gigabytes per iteration, can't the libqblock interface iterate as many
times as needed to reach the user's desired 64-bit length?

> + *   is too big, QB_ERR_INVALID_PARAM will be returned.
> + * @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.
> + */
> +QEMU_DLL_PUBLIC
> +int qb_check_allocation(QBlockImage *qbi,
> +                        uint64_t start,
> +                        uint64_t length,
> +                        int *pstatus,
> +                        uint64_t *plength);
Wayne Xia Feb. 21, 2013, 1:17 p.m. UTC | #2
>> + */
>> +#define QBLOCK_PROT_OPTIONS_UNION_SIZE (512/sizeof(QBlockReserved))
>> +typedef struct QBlockLocationInfo {
>> +    QBlockProtocol prot_type;
>> +    union {
>> +        QBlockProtocolOptionsFile o_file;
>> +        QBlockReserved union_reserved[QBLOCK_PROT_OPTIONS_UNION_SIZE];
>> +    };
>> +    QBlockReserved reserved[LIBQBLOCK_RESERVED_SIZE];
>
> Do you really mean to reserve trailing bytes after what you have already
> reserved as part of the union?  Theoretically, the reserved space in the
> union seems like it would be enough.
>
>
   I think it is necessary to reserve space for every layer in the public
structure, to make sure ABI is OK.

>> +
>> +typedef struct QBlockFormatOptionsQCOW2 {
>> +    QBlockLocationInfo backing_loc;
>> +    QBlockFormat backing_fmt;
>> +    bool encrypt;
>> +    uint64_t cluster_size; /* unit is bytes */
>> +    QBlockFormatOptionsQCOW2CompatLv cpt_lv;
>> +    QBlockFormatOptionsQCOW2PreAlloc pre_mode;
>> +    QBlockReserved reserved[LIBQBLOCK_RESERVED_SIZE];
>> +} QBlockFormatOptionsQCOW2;
>
> Side note: Libvirt is leaning towards presenting compat-level 1.1 to the
> user via the name 'qcow3', than it is to try and teach the users about
> the difference between qcow2 (compat 1.0) and qcow2v3 (compat 1.1) all
> under the name qcow2.  Even though the qcow2 code is able to handle both
> compatibility levels under the hood in qemu source code, it seems less
> confusing if the user interface separates things with a 'qcow3' naming
> convention.  I don't know how much that should impact your design, though.
>
>
  thanks for tipping that. I am not sure whether qcow2V3 equals qcow3, I
hope keep it as option of qcow2 for this version, and add QCOW3 if it is
finally decided as a new version later, just to make things simpler.

>> +
>> +#define QBLOCK_FMT_OPTIONS_UNION_SIZE (QBLOCK_PROT_OPTIONS_UNION_SIZE*2)
>
> Spaces around binary operators.
>
OK.

>
>> +/**
>> + * QBlockStaticInfo: information about the block image.
>> + *
>> + * @loc: location information.
>> + * @fmt: format information.
>> + * @sector_size: how many bytes in a sector, it is 512 usually.
>
> I'd drop ', it is 512 usually', since in the future, we might want to
> default to 4096 in new images.
>
   OK.

>
>> +/**
>> + * 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.
>> + *
>> + * @qbi: pointer to QBlockImage, used to get error message.
>> + * @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, it is used if
>> + *  backing file need to be opened..
>
> s/.././
>
OK.

>
>> +
>> +/* advance image APIs */
>> +/**
>> + * qb_check_allocation: check if [start, start+length-1] was allocated on the
>> + *  image.
>> + *
>> + * return 0 on success, libqblock negative error value on fail.
>> + *
>> + * @qbi: pointer to QBlockImage.
>> + * @start: start position, unit is byte.
>> + * @length: length to check, unit is byte, max is (INTMAX-1)*sector_size. If it
>
> INT_MAX, not INTMAX.
>
> Might be worth pointing to the API for determining sector_size, since it
> is not a parameter in this function call.  Furthermore, since all the
> relevant parameters are uint64_t, why is there an INT_MAX limitation in
> the first place?  Even if underlying qemu code has a limitation at 2
> gigabytes per iteration, can't the libqblock interface iterate as many
> times as needed to reach the user's desired 64-bit length?
>
   make sense.

>> + *   is too big, QB_ERR_INVALID_PARAM will be returned.
>> + * @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.
>> + */
>> +QEMU_DLL_PUBLIC
>> +int qb_check_allocation(QBlockImage *qbi,
>> +                        uint64_t start,
>> +                        uint64_t length,
>> +                        int *pstatus,
>> +                        uint64_t *plength);
>
diff mbox

Patch

diff --git a/libqblock/libqblock-error.h b/libqblock/libqblock-error.h
index e69de29..967f2e0 100644
--- a/libqblock/libqblock-error.h
+++ b/libqblock/libqblock-error.h
@@ -0,0 +1,35 @@ 
+/*
+ * QEMU block layer library
+ *
+ * Copyright IBM, Corp. 2013
+ *
+ * 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_FATAL_ERR (-2)
+#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, caller must free it later.
+ *
+ * @image: the image opened, must not be NULL.
+ */
+QEMU_DLL_PUBLIC
+char *qb_error_get_human_str(QBlockImage *image);
+
+#endif
diff --git a/libqblock/libqblock-internal.h b/libqblock/libqblock-internal.h
new file mode 100644
index 0000000..d09f9c1
--- /dev/null
+++ b/libqblock/libqblock-internal.h
@@ -0,0 +1,62 @@ 
+/*
+ * QEMU block layer library
+ *
+ * Copyright IBM, Corp. 2013
+ *
+ * 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/block.h"
+#include "libqblock-types.h"
+
+/* this file contains defines and types used inside the library. */
+
+typedef struct QBlockContext {
+    /* 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 */
+} QBlockContext;
+
+/* details should be hidden to user */
+struct QBlockImage {
+    BlockDriverState *bdrvs;
+    /* internal used file name now, if it is not NULL, it means
+       image was opened.
+    */
+    char *filename;
+    int ref_count;
+    QBlockContext *ctx;
+};
+
+/**
+ * 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 properties directly.
+ *
+ *  @backing_loc: backing file location.
+ *  @encrypt: encryption flag.
+*/
+
+typedef struct QBlockStaticInfoAddr {
+    QBlockLocationInfo *backing_loc;
+    bool *encrypt;
+} QBlockStaticInfoAddr;
+
+static inline GQuark qb_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
index e69de29..93a3aaf 100644
--- a/libqblock/libqblock-types.h
+++ b/libqblock/libqblock-types.h
@@ -0,0 +1,264 @@ 
+/*
+ * QEMU block layer library
+ *
+ * Copyright IBM, Corp. 2013
+ *
+ * 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>
+
+/*
+ * In case libqblock is used by other project which have not defined
+ * QEMU_DLL_PUBLIC.
+ */
+#ifndef QEMU_DLL_PUBLIC
+#define QEMU_DLL_PUBLIC
+#endif
+
+typedef void (*QBlockReserved)(void);
+#define LIBQBLOCK_RESERVED_SIZE (128/sizeof(QBlockReserved))
+
+/* this library is designed around this core struct. */
+typedef struct QBlockImage QBlockImage;
+
+/* 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
+
+/*
+ * The host page cache is always used.
+ * Flush operations are required to ensure writes reach the disk.
+ */
+#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 QBlockProtocol {
+    QB_PROTO_NONE = 0,
+    QB_PROTO_FILE,
+    QB_PROTO_MAX
+} QBlockProtocol;
+
+typedef struct QBlockProtocolOptionsFile {
+    /* in information retrieving function it will receive an allocated string,
+       which need to be freed later, so can't be const. */
+    char *filename;
+    QBlockReserved reserved[LIBQBLOCK_RESERVED_SIZE];
+} QBlockProtocolOptionsFile;
+
+/**
+ * struct QBlockLocationInfo: contains information about how to find the image
+ *
+ * @prot_type: protocol type, now only support FILE.
+ * @o_file: file protocol related attributes.
+ * @reserved: reserved bytes for ABI.
+ */
+#define QBLOCK_PROT_OPTIONS_UNION_SIZE (512/sizeof(QBlockReserved))
+typedef struct QBlockLocationInfo {
+    QBlockProtocol prot_type;
+    union {
+        QBlockProtocolOptionsFile o_file;
+        QBlockReserved union_reserved[QBLOCK_PROT_OPTIONS_UNION_SIZE];
+    };
+    QBlockReserved reserved[LIBQBLOCK_RESERVED_SIZE];
+} QBlockLocationInfo;
+
+
+/* format related options */
+typedef enum QBlockFormat {
+    QB_FORMAT_NONE = 0,
+    QB_FORMAT_COW,
+    QB_FORMAT_QED,
+    QB_FORMAT_QCOW,
+    QB_FORMAT_QCOW2,
+    QB_FORMAT_RAW,
+    QB_FORMAT_RBD,
+    QB_FORMAT_SHEEPDOG,
+    QB_FORMAT_VDI,
+    QB_FORMAT_VMDK,
+    QB_FORMAT_VPC,
+    QB_FORMAT_MAX
+} QBlockFormat;
+
+typedef struct QBlockFormatOptionsCOW {
+    QBlockLocationInfo backing_loc;
+    QBlockReserved reserved[LIBQBLOCK_RESERVED_SIZE];
+} QBlockFormatOptionsCOW;
+
+typedef struct QBlockFormatOptionsQED {
+    QBlockLocationInfo backing_loc;
+    QBlockFormat backing_fmt;
+    uint64_t cluster_size; /* unit is bytes */
+    uint64_t table_size; /* unit is clusters */
+    QBlockReserved reserved[LIBQBLOCK_RESERVED_SIZE];
+} QBlockFormatOptionsQED;
+
+typedef struct QBlockFormatOptionsQCOW {
+    QBlockLocationInfo backing_loc;
+    bool encrypt;
+    QBlockReserved reserved[LIBQBLOCK_RESERVED_SIZE];
+} QBlockFormatOptionsQCOW;
+
+/* "Compatibility level (0.10 or 1.1)" */
+typedef enum QBlockFormatOptionsQCOW2CompatLv {
+    QB_FORMAT_QCOW2_COMPAT_DEFAULT = 0,
+    QB_FORMAT_QCOW2_COMPAT_V0_10,
+    QB_FORMAT_QCOW2_COMPAT_V1_10,
+} QBlockFormatOptionsQCOW2CompatLv;
+
+/* off or metadata */
+typedef enum QBlockFormatOptionsQCOW2PreAlloc {
+    QB_FORMAT_QCOW2_PREALLOC_DEFAULT = 0,
+    QB_FORMAT_QCOW2_PREALLOC_OFF,
+    QB_FORMAT_QCOW2_PREALLOC_METADATA,
+} QBlockFormatOptionsQCOW2PreAlloc;
+
+typedef struct QBlockFormatOptionsQCOW2 {
+    QBlockLocationInfo backing_loc;
+    QBlockFormat backing_fmt;
+    bool encrypt;
+    uint64_t cluster_size; /* unit is bytes */
+    QBlockFormatOptionsQCOW2CompatLv cpt_lv;
+    QBlockFormatOptionsQCOW2PreAlloc pre_mode;
+    QBlockReserved reserved[LIBQBLOCK_RESERVED_SIZE];
+} QBlockFormatOptionsQCOW2;
+
+typedef struct QBlockFormatOptionsRAW {
+    QBlockReserved reserved[LIBQBLOCK_RESERVED_SIZE];
+} QBlockFormatOptionsRAW;
+
+typedef struct QBlockFormatOptionsRBD {
+    uint64_t cluster_size;
+    QBlockReserved reserved[LIBQBLOCK_RESERVED_SIZE];
+} QBlockFormatOptionsRBD;
+
+/* off or full */
+typedef enum QBlockFormatOptionsSDPreAlloc {
+    QB_FORMAT_SD_PREALLOC_DEFAULT = 0,
+    QB_FORMAT_SD_PREALLOC_OFF,
+    QB_FORMAT_SD_PREALLOC_FULL,
+} QBlockFormatOptionsSDPreAlloc;
+
+typedef struct QBlockFormatOptionsSD {
+    QBlockLocationInfo backing_loc;
+    QBlockFormatOptionsSDPreAlloc pre_mode;
+    QBlockReserved reserved[LIBQBLOCK_RESERVED_SIZE];
+} QBlockFormatOptionsSD;
+
+typedef enum QBlockFormatOptionsVDIPreAlloc {
+    QB_FORMAT_VDI_PREALLOC_DEFAULT = 0,
+    QB_FORMAT_VDI_PREALLOC_OFF,
+    QB_FORMAT_VDI_PREALLOC_METADATA,
+} QBlockFormatOptionsVDIPreAlloc;
+
+typedef struct QBlockFormatOptionsVDI {
+    uint64_t cluster_size;
+    QBlockFormatOptionsVDIPreAlloc pre_mode;
+    QBlockReserved reserved[LIBQBLOCK_RESERVED_SIZE];
+} QBlockFormatOptionsVDI;
+
+/* whether compact to vmdk version 6 */
+typedef enum QBlockFormatOptionsVMDKCompatLv {
+    QB_FORMAT_VMDK_COMPAT_DEFAULT = 0,
+    QB_FORMAT_VMDK_COMPAT_VMDKV6_FALSE,
+    QB_FORMAT_VMDK_COMPAT_VMDKV6_TRUE,
+} QBlockFormatOptionsVMDKCompatLv;
+
+/* vmdk flat extent format, values:
+"{monolithicSparse (default) | monolithicFlat | twoGbMaxExtentSparse |
+twoGbMaxExtentFlat | streamOptimized} */
+typedef enum QBlockFormatOptionsVMDKSubfmt {
+    QB_FORMAT_VMDK_SUBFMT_DEFAULT = 0,
+    QB_FORMAT_VMDK_SUBFMT_MONOLITHIC_SPARSE,
+    QB_FORMAT_VMDK_SUBFMT_MONOLITHIC_FLAT,
+    QB_FORMAT_VMDK_SUBFMT_TWOGBMAX_EXTENT_SPARSE,
+    QB_FORMAT_VMDK_SUBFMT_TWOGBMAX_EXTENT_FLAT,
+    QB_FORMAT_VMDK_SUBFMT_STREAM_OPTIMIZED,
+} QBlockFormatOptionsVMDKSubfmt;
+
+typedef struct QBlockFormatOptionsVMDK {
+    QBlockLocationInfo backing_loc;
+    QBlockFormatOptionsVMDKCompatLv cpt_lv;
+    QBlockFormatOptionsVMDKSubfmt subfmt;
+    QBlockReserved reserved[LIBQBLOCK_RESERVED_SIZE];
+} QBlockFormatOptionsVMDK;
+
+/* "{dynamic (default) | fixed} " */
+typedef enum QBlockFormatOptionsVPCSubfmt {
+    QB_FORMAT_VPC_SUBFMT_DEFAULT = 0,
+    QB_FORMAT_VPC_SUBFMT_DYNAMIC,
+    QB_FORMAT_VPC_SUBFMT_FIXED,
+} QBlockFormatOptionsVPCSubfmt;
+
+typedef struct QBlockFormatOptionsVPC {
+    QBlockFormatOptionsVPCSubfmt subfmt;
+    QBlockReserved reserved[LIBQBLOCK_RESERVED_SIZE];
+} QBlockFormatOptionsVPC;
+
+#define QBLOCK_FMT_OPTIONS_UNION_SIZE (QBLOCK_PROT_OPTIONS_UNION_SIZE*2)
+
+/**
+ * struct QBlockFormatInfo: contains information about how to retrieve data
+ *  from the image
+ *
+ * @virt_size: image virtual size.
+ * @fmt_type: format type.
+ * @o_cow~@o_vdi: format related attributes.
+ * @reserved: reserved bytes for ABI.
+ */
+typedef struct QBlockFormatInfo {
+    uint64_t virt_size;
+    QBlockFormat fmt_type;
+    union {
+        QBlockFormatOptionsCOW       o_cow;
+        QBlockFormatOptionsQED       o_qed;
+        QBlockFormatOptionsQCOW      o_qcow;
+        QBlockFormatOptionsQCOW2     o_qcow2;
+        QBlockFormatOptionsRAW       o_raw;
+        QBlockFormatOptionsRBD       o_rbd;
+        QBlockFormatOptionsSD        o_sd;
+        QBlockFormatOptionsVDI       o_vdi;
+        QBlockFormatOptionsVMDK      o_vmdk;
+        QBlockFormatOptionsVPC       o_vpc;
+        QBlockReserved union_reserved[QBLOCK_FMT_OPTIONS_UNION_SIZE];
+    };
+    QBlockReserved reserved[LIBQBLOCK_RESERVED_SIZE];
+} QBlockFormatInfo;
+
+/**
+ * QBlockStaticInfo: information about the block image.
+ *
+ * @loc: location information.
+ * @fmt: format information.
+ * @sector_size: how many bytes in a sector, it is 512 usually.
+ */
+typedef struct QBlockStaticInfo {
+    QBlockLocationInfo loc;
+    QBlockFormatInfo fmt;
+    int sector_size;
+    QBlockReserved reserved[LIBQBLOCK_RESERVED_SIZE];
+} QBlockStaticInfo;
+
+
+#endif
diff --git a/libqblock/libqblock.h b/libqblock/libqblock.h
index e69de29..2202998 100644
--- a/libqblock/libqblock.h
+++ b/libqblock/libqblock.h
@@ -0,0 +1,246 @@ 
+/*
+ * QEMU block layer library
+ *
+ * Copyright IBM, Corp. 2013
+ *
+ * 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.
+ *
+ */
+
+/* Note: This library is not thread safe yet. */
+
+#ifndef LIBQBLOCK_H
+#define LIBQBLOCK_H
+
+#include "libqblock-types.h"
+#include "libqblock-error.h"
+
+/**
+ * qb_image_new: allocate a new QBlockImage struct.
+ *
+ * Subsequent qblock actions will use this struct, ref is set to 1.
+ *
+ * Returns 0 if succeed, libqblock negative error value on fail, if fail call
+ *  qb_image_unref() to free it.
+ *
+ * @p_qbi: used to receive the created struct.
+ */
+QEMU_DLL_PUBLIC
+int qb_image_new(QBlockImage **p_qbi);
+
+/**
+ * qb_image_ref: increase the ref of QBlockImage.
+ *
+ * @qbi: pointer to the image structure.
+ */
+QEMU_DLL_PUBLIC
+void qb_image_ref(QBlockImage *qbi);
+
+/**
+ * qb_image_unref: decrease the ref of QBlockImage.
+ *
+ * if ref is reduced to 0, p_qbi would be freed and set to NULL, at which time
+ *  if image was opened and qb_close was not called before, it would be
+ *  automatically closed.
+ *
+ * @p_qbi: pointer to the struct's pointer.
+ */
+QEMU_DLL_PUBLIC
+void qb_image_unref(QBlockImage **p_qbi);
+
+/**
+ * qb_open: open a block object.
+ *
+ * return 0 on success, libqblock negative error value on fail.
+ *
+ * @qbi: pointer to QBlockImage.
+ * @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.
+ */
+QEMU_DLL_PUBLIC
+int qb_open(QBlockImage *qbi,
+            QBlockLocationInfo *loc,
+            QBlockFormatInfo *fmt,
+            int flag);
+
+/**
+ * qb_close: close a block object.
+ *
+ * qb_flush is automatically done inside.
+ *
+ * @qbi: pointer to QBlockImage.
+ */
+QEMU_DLL_PUBLIC
+void qb_close(QBlockImage *qbi);
+
+/**
+ * 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.
+ *
+ * @qbi: pointer to QBlockImage, used to get error message.
+ * @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, it is used if
+ *  backing file need to be opened..
+ */
+QEMU_DLL_PUBLIC
+int qb_create(QBlockImage *qbi,
+              QBlockLocationInfo *loc,
+              QBlockFormatInfo *fmt,
+              int flag);
+
+
+/* sync access */
+/**
+ * qb_read: block sync read.
+ *
+ * return 0 on success, libqblock negative error value on fail.
+ *
+ * @qbi: pointer to QBlockImage.
+ * @buf: buffer that receive the content.
+ * @len: length to read.
+ * @offset: offset in the block data.
+ */
+QEMU_DLL_PUBLIC
+int32_t qb_read(QBlockImage *qbi,
+                uint8_t *buf,
+                uint32_t len,
+                uint64_t offset);
+
+/**
+ * qb_write: block sync write.
+ *
+ * return 0 on success, libqblock negative error value on fail.
+ *
+ * @qbi: pointer to QBlockImage.
+ * @buf: buffer that receive the content.
+ * @len: length to write.
+ * @offset: offset in the block data.
+ */
+QEMU_DLL_PUBLIC
+int32_t qb_write(QBlockImage *qbi,
+                 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.
+ *
+ * @qbi: pointer to QBlockImage.
+ */
+QEMU_DLL_PUBLIC
+int qb_flush(QBlockImage *qbi);
+
+
+/* advance image APIs */
+/**
+ * qb_check_allocation: check if [start, start+length-1] was allocated on the
+ *  image.
+ *
+ * return 0 on success, libqblock negative error value on fail.
+ *
+ * @qbi: pointer to QBlockImage.
+ * @start: start position, unit is byte.
+ * @length: length to check, unit is byte, max is (INTMAX-1)*sector_size. If it
+ *   is too big, QB_ERR_INVALID_PARAM will be returned.
+ * @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.
+ */
+QEMU_DLL_PUBLIC
+int qb_check_allocation(QBlockImage *qbi,
+                        uint64_t start,
+                        uint64_t length,
+                        int *pstatus,
+                        uint64_t *plength);
+
+/* image information */
+/**
+ * qb_get_image_info: get image info.
+ *
+ * return 0 on success, libqblock negative error value on fail.
+ *
+ * @qbi: pointer to QBlockImage.
+ * @info: pointer that would receive the information.
+ *
+ * all char* in info must be freed later by g_free().
+ */
+QEMU_DLL_PUBLIC
+int qb_info_image_static_get(QBlockImage *qbi,
+                             QBlockStaticInfo *info);
+
+/* helper functions */
+/**
+ * qb_str2fmttype: translate format string to libqblock format enum type.
+ *
+ * return the type, or QB_FORMAT_NONE if string matches none of supported types,
+ *  never return invalid value or QB_FORMAT_MAX.
+ *
+ * @fmt: the format string, if NULL it will return QB_FORMAT_NONE.
+ */
+QEMU_DLL_PUBLIC
+QBlockFormat qb_str2fmttype(const char *fmt_str);
+
+/**
+ * qb_formattype2str: 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.
+ */
+QEMU_DLL_PUBLIC
+const char *qb_formattype2str(QBlockFormat fmt_type);
+
+/**
+ * qb_get_virt_size: get virtual size.
+ *
+ * return a pointer, which pointer to a member in info, or NULL if info is
+ *  not valid.
+ *
+ * @info: pointer to the QBlockStaticInfo structure.
+ */
+QEMU_DLL_PUBLIC
+const uint64_t *qb_get_virt_size(const QBlockStaticInfo *info);
+
+/**
+ * qb_get_backing_loc: get backing file location.
+ *
+ * return a pointer, which pointer to a member in info, or NULL if info is
+ *  not valid, or image have no such property.
+ *
+ * @info: pointer to the QBlockStaticInfo structure.
+ */
+QEMU_DLL_PUBLIC
+const QBlockLocationInfo *qb_get_backing_loc(const QBlockStaticInfo *info);
+
+/**
+ * qb_get_encrypt: get encrytion flag.
+ *
+ * return a pointer, which pointer to a member in info, or NULL if info is
+ *  not valid, or image have no such property.
+ *
+ * @info: pointer to the QBlockStaticInfo structure.
+ */
+QEMU_DLL_PUBLIC
+const bool *qb_get_encrypt(const QBlockStaticInfo *info);
+#endif