qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [RFC] libqblock-API v2, re-designed


From: Wenchao Xia
Subject: [Qemu-devel] [RFC] libqblock-API v2, re-designed
Date: Wed, 15 Aug 2012 16:12:23 +0800
User-agent: Mozilla/5.0 (Windows NT 5.1; rv:14.0) Gecko/20120713 Thunderbird/14.0

Hi,
  according to the comments, the header files were adjusted as
following:
  1 info are sorted into two kinds of structure: location and format,
which are both union + structure type.
  2 removed size_struct. Although it is suggested to use pointer to
make embbed struct easier, but with union it requires memory allocated
at create time, for eg:
struct QBlockOption_fmt_qed {
    size_t virt_size;
    struct QBlockOptionLoc *backing_loc;
};
union QBlockOption_fmt {
    struct QBlockOption_fmt_cow       o_cow;
    struct QBlockOption_fmt_qed       o_qed;
};
  when user create union QBlockOption_fmt, he must set format type
first so we can malloc that memory regions to the pointer. This also
bring risk that at free time the format type is also need to be set
correctly to free the correct pointer. So this version using reserved
space and the structures are created with xx_new functions internally.
  3 Balanced the parameters extension and folder depth, More than one
parameters were used in APIs.
  4 advanced information that only some format have, will get -1 to
indicate it do not exist.

/*
 * QEMU block layer library
 *
 * Copyright IBM, Corp. 2012
 *
 * Authors:
 *  Wenchao Xia   <address@hidden>
 *
* 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 <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>

#define QB_ERR_MEM_ERR (-1)
#define QB_ERR_INTERNAL_ERR (-2)
#define QB_ERR_INVALID_PARAM (-3)

/* this library is designed around this core struct. */
struct QBlockState;

/**
 * libqblock_init: Initialize the library
 */
void libqblock_init(void);

/**
 * qb_state_new: allocate a new QBloctState struct
 *
 * Following qblock action were based on this struct
 *
 * Returns 0 if succeed, negative value on fail.
 *
 * @qbs: used to receive the created struct.
 */
int qb_state_new(struct QBlockState **qbs);

/**
 * qb_state_free: free a QBloctState struct
 *
 * if it is opened, a qb_close must be called before free.
 *
 * @qbs: pointer to the struct's pointer.
 */
void qb_state_free(struct QBlockState **qbs);


/* 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)

enum QBlockProtocol {
    QB_PROTO_FILE = 0,
    QB_PROTO_MAX
};

enum QBlockFormat {
    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
};

struct QBlockOption_prot_file {
    char *filename;
};

union QBlockOption_prot {
    struct QBlockOption_prot_file       o_file;
};

/**
 * struct QBlockOptionLoc: contains information about how to find the image
 *
 * @prot_type: protocol type, now only support FILE.
 * @prot_op: protocol related options.
 */
struct QBlockOptionLoc {
    enum QBlockProtocol prot_type;
    union QBlockOption_prot prot_op;
    uint8 reserved[512];
};

/**
 * qb_ol_new: create a new struct QBlockOptionLoc.
 *
 * return 0 on success, negative on fail.
 *
 * @op: pointer to receive the new created one.
 */
int qb_ol_new(struct QBlockOptionLoc **op);

/**
 * qb_ol_free: free a struct QBlockOptionLoc.
 *
 * @op: pointer to the object, *op would be set to NULL.
 */
void qb_ol_free(struct QBlockOptionLoc **op);


/* format related options */
struct QBlockOption_fmt_cow {
    size_t virt_size;
    struct QBlockOptionLoc backing_loc;
};

struct QBlockOption_fmt_qed {
    size_t virt_size;
    struct QBlockOptionLoc backing_loc;
    enum QBlockFormat backing_fmt;
    size_t cluster_size; /* unit is bytes */
    size_t table_size; /* unit is clusters */
};

struct QBlockOption_fmt_qcow {
    size_t virt_size;
    struct QBlockOptionLoc backing_loc;
    bool encrypt;
};

/* "Compatibility level (0.10 or 1.1)" */
enum QBlockOption_fmt_qcow2_cpt {
    QBO_FMT_QCOW2_CPT_None = 0,
    QBO_FMT_QCOW2_CPT_V010,
    QBO_FMT_QCOW2_CPT_V011,
};

/* off or metadata */
enum QBlockOption_fmt_qcow2_prealloc {
    QBO_FMT_QCOW2_PREALLOC_OFF = 0,
    QBO_FMT_QCOW2_PREALLOC_METADATA,
};

struct QBlockOption_fmt_qcow2 {
    size_t virt_size;
    struct QBlockOptionLoc backing_loc;
    enum QBlockFormat backing_fmt;
    bool encrypt;
    size_t cluster_size; /* unit is bytes */
    enum QBlockOption_fmt_qcow2_cpt cpt_lv;
    enum QBlockOption_fmt_qcow2_prealloc pre_mode;
};

struct QBlockOption_fmt_raw {
    size_t virt_size;
};

struct QBlockOption_fmt_rbd {
    size_t virt_size;
    size_t cluster_size;
};

/* off or full */
enum QBlockOption_fmt_sheepdog_prealloc {
    QBO_FMT_SD_PREALLOC_OFF = 0,
    QBO_FMT_SD_PREALLOC_FULL,
};

struct QBlockOption_fmt_sheepdog {
    size_t virt_size;
    struct QBlockOptionLoc backing_loc;
    enum QBlockOption_fmt_sheepdog_prealloc pre_mode;
};

enum QBlockOption_fmt_vdi_prealloc {
    QBO_FMT_VDI_PREALLOC_FALSE = 0,
    QBO_FMT_VDI_PREALLOC_TRUE,
};

struct QBlockOption_fmt_vdi {
    size_t virt_size;
    size_t cluster_size;
    enum QBlockOption_fmt_vdi_prealloc pre_mode;
};

/* whether compact to vmdk verion 6 */
enum QBlockOption_fmt_vmdk_cpt {
    QBO_FMT_VMDK_CPT_NONE = 0,
    QBO_FMT_VMDK_CPT_VMDKV6,
};

/* vmdk flat extent format, values:
"{monolithicSparse (default) | monolithicFlat | twoGbMaxExtentSparse |
twoGbMaxExtentFlat | streamOptimized} */
enum QBlockOption_fmt_vmdk_subfmt {
    QBO_FMT_VMDK_SUBFMT_MONOLITHIC_SPARSE = 0,
    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,
};

struct QBlockOption_fmt_vmdk {
    size_t virt_size;
    struct QBlockOptionLoc backing_loc;
    enum QBlockOption_fmt_vmdk_cpt cpt_lv;
    enum QBlockOption_fmt_vmdk_subfmt subfmt;
};

/* "{dynamic (default) | fixed} " */
enum QBlockOption_fmt_vpc_subfmt {
    QBO_FMT_VPC_SUBFMT_DYNAMIC = 0,
    QBO_FMT_VPC_SUBFMT_FIXED,
};

struct QBlockOption_fmt_vpc {
    size_t virt_size;
    enum QBlockOption_fmt_vpc_subfmt subfmt;
};

union QBlockOption_fmt {
    struct QBlockOption_fmt_cow       o_cow;
    struct QBlockOption_fmt_qed       o_qed;
    struct QBlockOption_fmt_qcow      o_qcow;
    struct QBlockOption_fmt_qcow2     o_qcow2;
    struct QBlockOption_fmt_raw       o_raw;
    struct QBlockOption_fmt_rbd       o_rbd;
    struct QBlockOption_fmt_sheepdog  o_sheepdog;
    struct QBlockOption_fmt_vdi       o_vdi;
    struct QBlockOption_fmt_vmdk      o_vmdk;
    struct QBlockOption_fmt_vpc       o_vpc;
};

struct QBlockOptionFormat {
    enum QBlockFormat fmt_type;
    union QBlockOption_fmt fmt_op;
    uint8 reserved[512];
};

/**
 * qb_of_new: create a new QBlockOptionFormat structure.
 *
 * return 0 on success, negative on fail.
 *
 * @op: pointer that will receive created struct.
 */
int qb_of_new(struct QBlockOptionFormat **op);

/**
 * qb_of_free: free QBlockOptionFormat structure.
 *
 * @op: pointer to the struct, *op would be set to NULL.
 */
void qb_of_free(struct QBlockOptionFormat **op);


/**
 * qb_open: open a block object.
 *
 * return 0 on success, negative on fail.
 *
 * @qbs: pointer to struct 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.
 * @flag: behavior control flags.
 */
int qb_open(struct QBlockState *qbs, struct QBlockOptionLoc *loc,
                                 struct QBlockOptionFormat *fmt, int flag);

/**
 * qb_close: close a block object.
 *
 * qb_flush is automaticlly done inside.
 *
 * @qbs: pointer to struct QBlockState.
 */
void qb_close(struct QBlockState *qbs);

/**
 * qb_create: create a block image or object.
 *
 * return negative on fail, 0 on success.
 *
 * @qbs: pointer to struct QBlockState.
 * @loc: location options for open, how to find the image.
 * @fmt: format options, how to extract the data.
 * @flag: behavior control flags.
 */
int qb_create(struct QBlockState *qbs, struct QBlockOptionLoc *loc,
struct QBlockOptionFormat *fmt, int flag);


/* sync access */
/**
 * qb_read: block sync read.
 *
 * return negative on fail, 0 on success.
 *
 * @qbs: pointer to struct QBlockState.
 * @buf: buffer that receive the content.
 * @len: length to read.
 * @offset: offset in the block data.
 */
int qb_read(struct QBlockState *qbs, const void *buf, size_t len,
                                                      off_t offset);
/**
 * qb_write: block sync write.
 *
 * return negative on fail, 0 on success.
 *
 * @qbs: pointer to struct QBlockState.
 * @buf: buffer that receive the content.
 * @len: length to write.
 * @offset: offset in the block data.
 */
int qb_write(struct QBlockState *qbs, const void *buf, size_t len,
                                                       off_t offset);
/**
 * qb_flush: block sync flush.
 *
 * return negative on fail, 0 on success.
 *
 * @qbs: pointer to struct QBlockState.
 */
int qb_flush(struct QBlockState *qbs);


/* image information */
/**
 * QBlockInfoImage: information about the block image.
 *
 * @i_loc: location info.
 * @i_fmt: format info.
 * @i_virt_size: virtual size.
 * @i_alloc_size: allocated size, -1 if not available.
 * @i_dirty: dirty status, -1 if not available.
 */
struct QBlockInfoImage {
    struct QBlockOptionLoc i_loc;
    struct QBlockOptionFormat i_fmt;
    size_t i_virt_size;
    /* advance info */
    size_t i_allocated_size;
    int i_dirty;
};

/**
 * qb_get_image_info: get image info.
 *
 * return negative on fail, 0 on success.
 *
 * @qbs: pointer to struct QBlockState.
 * @info: pointer that would receive the information.
 */
int qb_get_image_info(struct QBlockState *qbs, struct QBlockInfoImage **info);

/**
 * qb_free_image_info: free image info.
 *
 * @info: pointer to the information struct.
 */
void qb_free_image_info(struct QBlockInfoImage **info);

/* misc */
bool qb_supports_format(enum QBlockFormat fmt);
bool qb_supports_protocol(enum QBlockProtocol proto);

/**
 * qb_error_get_detail: get erro details.
 *
 * return a human readable string.
 *
 * @qbs: pointer to struct QBlockState.
 * @err_ret: negative value last qblock API returned.
* @err_num: pointer that will receive errno, it is valid only when err_ret is
 *     QB_ERR_INTERNAL_ERR.
 */
const char *qb_error_get_detail(struct QBlockState *qbs, int err_ret,
                                                         int *err_num);
#endif




reply via email to

[Prev in Thread] Current Thread [Next in Thread]