@@ -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
new file mode 100644
@@ -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
@@ -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
@@ -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
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