All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/6] libqblock, qemu block layer library
@ 2012-09-03  9:18 Wenchao Xia
  2012-09-03  9:18 ` [Qemu-devel] [PATCH 1/6] libqblock APIs Wenchao Xia
                   ` (5 more replies)
  0 siblings, 6 replies; 46+ messages in thread
From: Wenchao Xia @ 2012-09-03  9:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, aliguori, stefanha, pbonzini, eblake, Wenchao Xia

  This patch intrudce 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.

Wenchao Xia (6):
  libqblock APIs
  libqblock public type defines
  libqblock error handling
  libqblock internal used functions
  libqblock test example
  libqblock building system

 Makefile                         |   22 +-
 Makefile.objs                    |    6 +
 block.c                          |    2 +-
 block.h                          |    1 +
 libqblock/Makefile               |   62 +++
 libqblock/libqblock-error.c      |   44 ++
 libqblock/libqblock-error.h      |   34 ++
 libqblock/libqblock-helper.c     |   92 ++++
 libqblock/libqblock-helper.h     |   57 +++
 libqblock/libqblock-types.h      |  228 ++++++++++
 libqblock/libqblock.c            |  859 ++++++++++++++++++++++++++++++++++++++
 libqblock/libqblock.h            |  251 +++++++++++
 tests/Makefile                   |    3 +
 tests/libqblock/Makefile         |   28 ++
 tests/libqblock/libqblock-test.c |  219 ++++++++++
 15 files changed, 1906 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-helper.c
 create mode 100644 libqblock/libqblock-helper.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] 46+ messages in thread

* [Qemu-devel] [PATCH 1/6] libqblock APIs
  2012-09-03  9:18 [Qemu-devel] [PATCH 0/6] libqblock, qemu block layer library Wenchao Xia
@ 2012-09-03  9:18 ` Wenchao Xia
  2012-09-03 13:18   ` Paolo Bonzini
                     ` (2 more replies)
  2012-09-03  9:18 ` [Qemu-devel] [PATCH 2/6] libqblock public type defines Wenchao Xia
                   ` (4 subsequent siblings)
  5 siblings, 3 replies; 46+ messages in thread
From: Wenchao Xia @ 2012-09-03  9:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, aliguori, stefanha, 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 QBlockInfoImageStatic. Now it is not folded with location and format.
  4 ABI was kept with reserved members.

structure, because it would cause caller more codes to find one member.

Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
---
 libqblock/libqblock.c |  859 +++++++++++++++++++++++++++++++++++++++++++++++++
 libqblock/libqblock.h |  251 ++++++++++++++
 2 files changed, 1110 insertions(+), 0 deletions(-)
 create mode 100644 libqblock/libqblock.c
 create mode 100644 libqblock/libqblock.h

diff --git a/libqblock/libqblock.c b/libqblock/libqblock.c
new file mode 100644
index 0000000..3983802
--- /dev/null
+++ b/libqblock/libqblock.c
@@ -0,0 +1,859 @@
+/*
+ * 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-helper.h"
+
+#include "qemu-aio.h"
+
+void libqblock_init(void)
+{
+    bdrv_init();
+    qemu_init_main_loop();
+}
+
+int qb_broker_new(struct QBroker **broker)
+{
+    *broker = FUNC_CALLOC(1, sizeof(struct QBroker));
+    if (*broker == NULL) {
+        return QB_ERR_MEM_ERR;
+    }
+    return 0;
+}
+
+void qb_broker_delete(struct QBroker **broker)
+{
+    CLEAN_FREE(*broker);
+    return;
+}
+
+int qb_state_new(struct QBroker *broker,
+                 struct QBlockState **qbs)
+{
+    *qbs = FUNC_CALLOC(1, sizeof(struct QBlockState));
+    if (*qbs == NULL) {
+        set_broker_err_nomem(broker);
+        return broker->err_ret;
+    }
+    (*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(struct QBroker *broker,
+                     struct QBlockState **qbs)
+{
+    CLEAN_FREE((*qbs)->filename);
+    if ((*qbs)->bdrvs != NULL) {
+        bdrv_delete((*qbs)->bdrvs);
+        (*qbs)->bdrvs = NULL;
+    }
+    CLEAN_FREE(*qbs);
+    return;
+}
+
+int qb_ol_new(struct QBroker *broker,
+              struct QBlockOptionLoc **op)
+{
+    *op = FUNC_CALLOC(1, sizeof(struct QBlockOptionLoc));
+    if (*op == NULL) {
+        set_broker_err_nomem(broker);
+        return broker->err_ret;
+    }
+    return 0;
+}
+
+void qb_ol_delete(struct QBroker *broker,
+                  struct QBlockOptionLoc **op)
+{
+    CLEAN_FREE(*op);
+}
+
+int qb_of_new(struct QBroker *broker,
+              struct QBlockOptionFormat **op)
+{
+    *op = FUNC_CALLOC(1, sizeof(struct QBlockOptionFormat));
+    if (*op == NULL) {
+        set_broker_err_nomem(broker);
+        return broker->err_ret;
+    }
+    return 0;
+}
+
+void qb_of_delete(struct QBroker *broker,
+                  struct QBlockOptionFormat **op)
+{
+    CLEAN_FREE(*op);
+}
+
+/* return 0 if every thing is fine */
+static int loc_check_params(struct QBroker *broker,
+                            struct QBlockOptionLoc *loc)
+{
+    broker->err_ret = 0;
+
+    switch (loc->prot_type) {
+    case QB_PROTO_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(struct QBroker *broker,
+                        struct QBlockOptionLoc *loc,
+                        char **filename)
+{
+    broker->err_ret = 0;
+
+    if (*filename != NULL) {
+        CLEAN_FREE(*filename);
+    }
+    switch (loc->prot_type) {
+    case QB_PROTO_FILE:
+        *filename = strdup(loc->prot_op.o_file.filename);
+        if (*filename == NULL) {
+            set_broker_err_nomem(broker);
+        }
+        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(struct QBroker *broker,
+                        struct QBlockOptionLoc *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 supportted now.",
+                     filename);
+        goto out;
+    }
+
+    loc->prot_type = QB_PROTO_FILE;
+    switch (loc->prot_type) {
+    case QB_PROTO_FILE:
+        loc->prot_op.o_file.filename = strdup(filename);
+        if (loc->prot_op.o_file.filename == NULL) {
+            set_broker_err_nomem(broker);
+            goto out;
+        }
+        break;
+    default:
+        break;
+    }
+
+ out:
+    return broker->err_ret;
+}
+
+/* return 0 if OK, or qblock error number */
+static int set_backing_file_options(struct QBroker *broker,
+                                    QEMUOptionParameter *param,
+                                    struct QBlockOptionLoc *loc,
+                                    enum QBlockFormat *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 */
+    if (ret == QB_ERR_MEM_ERR) {
+        goto out;
+    }
+    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 = fmt2str(*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(struct QBroker *broker,
+              struct QBlockState *qbs,
+              struct QBlockOptionLoc *loc,
+              struct QBlockOptionFormat *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;
+    struct QBlockOption_fmt_cow *o_cow = NULL;
+    struct QBlockOption_fmt_qed *o_qed = NULL;
+    struct QBlockOption_fmt_qcow *o_qcow = NULL;
+    struct QBlockOption_fmt_qcow2 *o_qcow2 = NULL;
+    struct QBlockOption_fmt_raw *o_raw = NULL;
+    struct QBlockOption_fmt_rbd *o_rbd = NULL;
+    struct QBlockOption_fmt_sheepdog *o_sd = NULL;
+    struct QBlockOption_fmt_vdi *o_vdi = NULL;
+    struct QBlockOption_fmt_vmdk *o_vmdk = NULL;
+    struct QBlockOption_fmt_vpc *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 = fmt2str(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:
+        assert(false);
+        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 *= 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(struct QBroker *broker,
+            struct QBlockState *qbs,
+            struct QBlockOptionLoc *loc,
+            struct QBlockOptionFormat *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 = fmt2str(fmt->fmt_type);
+    }
+
+    if (fmtstr != NULL) {
+        bd = bdrv_find_format(fmtstr);
+        assert(bd != NULL);
+    }
+
+    /* do real openning */
+    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 = strdup(filename);
+    if (qbs->filename == NULL) {
+        set_broker_err_nomem(broker);
+        ret = broker->err_ret;
+        bdrv_close(bs);
+        goto out;
+    }
+
+ out:
+    FUNC_FREE(filename);
+    return ret;
+}
+
+void qb_close(struct QBroker *broker,
+              struct QBlockState *qbs)
+{
+    BlockDriverState *bs;
+
+    bs = qbs->bdrvs;
+
+    if (qbs->filename != NULL) {
+        CLEAN_FREE(qbs->filename);
+        bdrv_close(bs);
+    }
+    return;
+}
+
+int qb_read(struct QBroker *broker,
+            struct QBlockState *qbs,
+            const void *buf,
+            size_t len,
+            off_t offset)
+{
+    int bd_ret;
+    BlockDriverState *bs;
+
+    broker->err_ret = 0;
+    bs = qbs->bdrvs;
+
+    assert((len & SECTOR_SIZE_MASK) == 0);
+    assert((offset & SECTOR_SIZE_MASK) == 0);
+    bd_ret = bdrv_read(bs, offset >> SECTOR_SIZE_BITS_NUM,
+                       (uint8_t *)buf, len >> SECTOR_SIZE_BITS_NUM);
+    if (bd_ret < 0) {
+        if (bd_ret == -EIO) {
+            set_broker_err(broker, QB_ERR_INTERNAL_ERR,
+                           "Generic I/O error.");
+        } else if (bd_ret == -ENOMEDIUM) {
+            set_broker_err(broker, QB_ERR_INTERNAL_ERR,
+                           "No meida inserted.");
+        } else if (bd_ret == -EINVAL) {
+            set_broker_err(broker, QB_ERR_INTERNAL_ERR,
+                          "Sector was not correct.");
+        } else {
+            set_broker_err(broker, QB_ERR_INTERNAL_ERR,
+                          "Internal error.");
+        }
+    }
+    return broker->err_ret;
+}
+
+int qb_write(struct QBroker *broker,
+            struct QBlockState *qbs,
+            const void *buf,
+            size_t len,
+            off_t offset)
+{
+    int bd_ret;
+    BlockDriverState *bs;
+
+    broker->err_ret = 0;
+    bs = qbs->bdrvs;
+
+    assert((len & SECTOR_SIZE_MASK) == 0);
+    assert((offset & SECTOR_SIZE_MASK) == 0);
+    bd_ret = bdrv_write(bs, offset >> SECTOR_SIZE_BITS_NUM,
+                       (uint8_t *)buf, len >> SECTOR_SIZE_BITS_NUM);
+    if (bd_ret < 0) {
+        if (bd_ret == -EIO) {
+            set_broker_err(broker, QB_ERR_INTERNAL_ERR,
+                           "Generic I/O error.");
+        } else if (bd_ret == -ENOMEDIUM) {
+            set_broker_err(broker, QB_ERR_INTERNAL_ERR,
+                           "No meida inserted.");
+        } else if (bd_ret == -EINVAL) {
+            set_broker_err(broker, QB_ERR_INTERNAL_ERR,
+                          "Sector was not correct.");
+        } else {
+            set_broker_err(broker, QB_ERR_INTERNAL_ERR,
+                          "Internal error.");
+        }
+    }
+    return broker->err_ret;
+}
+
+int qb_flush(struct QBroker *broker,
+             struct 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_is_allocated(struct QBroker *broker,
+                    struct QBlockState *qbs,
+                    int64_t sector_num,
+                    int nb_sectors,
+                    int *pnum)
+{
+    int ret;
+    BlockDriverState *bs;
+
+    broker->err_ret = 0;
+    bs = qbs->bdrvs;
+
+    if (qbs->filename == NULL) {
+        set_broker_err(broker, QB_ERR_INVALID_PARAM,
+                       "Image was not opened first.");
+        ret = broker->err_ret;
+        goto out;
+    }
+
+    ret = bdrv_is_allocated(bs, sector_num, nb_sectors, pnum);
+
+ out:
+    return ret;
+}
+
+int qb_info_image_static_get(struct QBroker *broker,
+                             struct QBlockState *qbs,
+                             struct QBlockInfoImageStatic **info)
+{
+    int ret = 0;
+    BlockDriverState *bs;
+    struct QBlockInfoImageStatic *info_tmp;
+    const char *fmt_str;
+    size_t total_sectors;
+    char backing_filename[1024];
+
+    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(struct QBlockInfoImageStatic));
+    if (info_tmp == NULL) {
+        set_broker_err_nomem(broker);
+        ret = broker->err_ret;
+        goto out;
+    }
+
+    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_type = str2fmt(fmt_str);
+
+    bdrv_get_geometry(bs, &total_sectors);
+    info_tmp->virt_size = total_sectors * SECTOR_SIZE;
+
+    info_tmp->allocated_size = bdrv_get_allocated_file_size(bs);
+    info_tmp->encrypt = bdrv_is_encrypted(bs);
+
+    bdrv_get_full_backing_filename(bs, backing_filename,
+                                   sizeof(backing_filename));
+    if (backing_filename[0] != '\0') {
+        ret = filename2loc(broker,
+                           &(info_tmp->backing_loc),
+                           backing_filename);
+        if (ret < 0) {
+            goto free;
+        }
+    }
+
+    *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(struct QBlockOptionLoc *loc)
+{
+    switch (loc->prot_type) {
+    case QB_PROTO_FILE:
+        CLEAN_FREE(loc->prot_op.o_file.filename);
+        break;
+    default:
+        break;
+    }
+}
+
+void qb_info_image_static_delete(struct QBroker *broker,
+                                 struct QBlockInfoImageStatic **info)
+{
+    loc_free(&(*info)->loc);
+    loc_free(&(*info)->backing_loc);
+
+    CLEAN_FREE(*info);
+}
diff --git a/libqblock/libqblock.h b/libqblock/libqblock.h
new file mode 100644
index 0000000..e64e1fd
--- /dev/null
+++ b/libqblock/libqblock.h
@@ -0,0 +1,251 @@
+/*
+ * 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"
+
+
+/**
+ * libqblock_init: Initialize the library
+ */
+void libqblock_init(void);
+
+/**
+ * qb_broker_new: allocate a new broker
+ *
+ * Broker is used to pass operation to libqblock, and got feed back from it.
+ *
+ * Returns 0 on success, negative value on fail.
+ *
+ * @broker: used to receive the created struct.
+ */
+int qb_broker_new(struct QBroker **broker);
+
+/**
+ * qb_broker_delete: delete broker
+ *
+ * Broker will be freed and set to NULL.
+ *
+ * @broker: operation broker to be deleted.
+ */
+void qb_broker_delete(struct QBroker **broker);
+
+/**
+ * qb_state_new: allocate a new QBloctState struct
+ *
+ * Following qblock action were based on this struct
+ *
+ * Returns 0 if succeed, negative value on fail.
+ *
+ * @broker: operation broker.
+ * @qbs: used to receive the created struct.
+ */
+int qb_state_new(struct QBroker *broker,
+                 struct QBlockState **qbs);
+
+/**
+ * qb_state_delete: free a QBloctState struct
+ *
+ * if it is opened, a qb_close must be called before free.
+ *
+ * @broker: operation broker.
+ * @qbs: pointer to the struct's pointer.
+ */
+void qb_state_delete(struct QBroker *broker,
+                     struct QBlockState **qbs);
+
+/**
+ * qb_ol_new: create a new struct QBlockOptionLoc.
+ *
+ * return 0 on success, negative on fail.
+ *
+ * @broker: operation broker.
+ * @op: pointer to receive the new created one.
+ */
+int qb_ol_new(struct QBroker *broker,
+              struct QBlockOptionLoc **op);
+
+/**
+ * qb_ol_delete: free a struct QBlockOptionLoc.
+ *
+ * @broker: operation broker.
+ * @op: pointer to the object, *op would be set to NULL.
+ */
+void qb_ol_delete(struct QBroker *broker,
+                  struct QBlockOptionLoc **op);
+
+/**
+ * qb_of_new: create a new QBlockOptionFormat structure.
+ *
+ * return 0 on success, negative on fail.
+ *
+ * @broker: operation broker.
+ * @op: pointer that will receive created struct.
+ */
+int qb_of_new(struct QBroker *broker,
+              struct QBlockOptionFormat **op);
+
+/**
+ * qb_of_delete: free QBlockOptionFormat structure.
+ *
+ * @broker: operation broker.
+ * @op: pointer to the struct, *op would be set to NULL.
+ */
+void qb_of_delete(struct QBroker *broker,
+                  struct QBlockOptionFormat **op);
+
+
+/**
+ * qb_open: open a block object.
+ *
+ * return 0 on success, negative on fail.
+ *
+ * @broker: operation broker.
+ * @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, set NULL if you want auto discovery the format.
+ * @flag: behavior control flags.
+ */
+int qb_open(struct QBroker *broker,
+            struct QBlockState *qbs,
+            struct QBlockOptionLoc *loc,
+            struct QBlockOptionFormat *fmt,
+            int flag);
+
+/**
+ * qb_close: close a block object.
+ *
+ * qb_flush is automaticlly done inside.
+ *
+ * @broker: operation broker.
+ * @qbs: pointer to struct QBlockState.
+ */
+void qb_close(struct QBroker *broker,
+              struct QBlockState *qbs);
+
+/**
+ * qb_create: create a block image or object.
+ *
+ * Note: Create operation would not open the image automatically.
+ *
+ * return negative on fail, 0 on success.
+ *
+ * @broker: operation broker.
+ * @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 QBroker *broker,
+              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.
+ *
+ * @broker: operation broker.
+ * @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 QBroker *broker,
+            struct QBlockState *qbs,
+            const void *buf,
+            size_t len,
+            off_t offset);
+/**
+ * qb_write: block sync write.
+ *
+ * return negative on fail, 0 on success.
+ *
+ * @broker: operation broker.
+ * @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 QBroker *broker,
+             struct QBlockState *qbs,
+             const void *buf,
+             size_t len,
+             off_t offset);
+
+/**
+ * qb_flush: block sync flush.
+ *
+ * return negative on fail, 0 on success.
+ *
+ * @broker: operation broker.
+ * @qbs: pointer to struct QBlockState.
+ */
+int qb_flush(struct QBroker *broker,
+             struct QBlockState *qbs);
+
+
+/* advance image APIs */
+/**
+ * qb_is_allocated: check if following sectors was allocated on the image.
+ *
+ * return negative on fail, 0 or 1 on success. 0 means unallocated, 1 means
+ *allocated.
+ *
+ * @broker: operation broker.
+ * @qbs: pointer to struct QBlockState.
+ * @sector_num: start sector number. If 'sector_num' is beyond the end of the
+ *disk image the return value is 0 and 'pnum' is set to 0.
+ * @nb_sectors: how many sector would be checked, it is the max value 'pnum'
+ *should be set to.  If nb_sectors goes beyond the end of the disk image it
+ *will be clamped.
+ * @pnum: pointer to receive how many sectors are allocated or unallocated.
+ */
+int qb_is_allocated(struct QBroker *broker,
+                    struct QBlockState *qbs,
+                    int64_t sector_num,
+                    int nb_sectors,
+                    int *pnum);
+
+/* image information */
+/**
+ * qb_get_image_info: get image info.
+ *
+ * return negative on fail, 0 on success.
+ *
+ * @broker: operation broker.
+ * @qbs: pointer to struct QBlockState.
+ * @info: pointer that would receive the information.
+ */
+int qb_info_image_static_get(struct QBroker *broker,
+                             struct QBlockState *qbs,
+                             struct QBlockInfoImageStatic **info);
+
+/**
+ * qb_delete_image_info: free image info.
+ *
+ * @broker: operation broker.
+ * @info: pointer to the information struct.
+ */
+void qb_info_image_static_delete(struct QBroker *broker,
+                                 struct QBlockInfoImageStatic **info);
+
+#endif
-- 
1.7.1

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

* [Qemu-devel] [PATCH 2/6] libqblock public type defines
  2012-09-03  9:18 [Qemu-devel] [PATCH 0/6] libqblock, qemu block layer library Wenchao Xia
  2012-09-03  9:18 ` [Qemu-devel] [PATCH 1/6] libqblock APIs Wenchao Xia
@ 2012-09-03  9:18 ` Wenchao Xia
  2012-09-03 13:13   ` Paolo Bonzini
                     ` (2 more replies)
  2012-09-03  9:18 ` [Qemu-devel] [PATCH 3/6] libqblock error handling Wenchao Xia
                   ` (3 subsequent siblings)
  5 siblings, 3 replies; 46+ messages in thread
From: Wenchao Xia @ 2012-09-03  9:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, aliguori, stefanha, pbonzini, eblake, Wenchao Xia

  This patch contains public type and defines used in APIs.

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

diff --git a/libqblock/libqblock-types.h b/libqblock/libqblock-types.h
new file mode 100644
index 0000000..3389bda
--- /dev/null
+++ b/libqblock/libqblock-types.h
@@ -0,0 +1,228 @@
+#ifndef LIBQBLOCK_TYPES_H
+#define LIBQBLOCK_TYPES_H
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdbool.h>
+
+/* this library is designed around this core struct. */
+struct QBlockState;
+
+/* every thread would have a broker. */
+struct 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)
+
+enum QBlockProtocol {
+    QB_PROTO_NONE = 0,
+    QB_PROTO_FILE,
+    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_t reserved[512];
+};
+
+/* 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_V110,
+};
+
+/* off or metadata */
+enum QBlockOption_fmt_qcow2_prealloc {
+    QBO_FMT_QCOW2_PREALLOC_NONE = 0,
+    QBO_FMT_QCOW2_PREALLOC_OFF,
+    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_NONE = 0,
+    QBO_FMT_SD_PREALLOC_OFF,
+    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_NONE = 0,
+    QBO_FMT_VDI_PREALLOC_FALSE,
+    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_FALSE,
+    QBO_FMT_VMDK_CPT_VMDKV6_TRUE,
+};
+
+/* vmdk flat extent format, values:
+"{monolithicSparse (default) | monolithicFlat | twoGbMaxExtentSparse |
+twoGbMaxExtentFlat | streamOptimized} */
+enum QBlockOption_fmt_vmdk_subfmt {
+    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,
+};
+
+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_NONE = 0,
+    QBO_FMT_VPC_SUBFMT_DYNAMIC,
+    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_t reserved[512];
+};
+
+/**
+ * QBlockInfoImageStatic: information about the block image.
+ *
+ * @loc: location info.
+ * @fmt_type: format type.
+ * @virt_size: virtual size in bytes.
+ * @backing_loc: backing file location, its type is QB_PROT_NONE if not exist.
+ * @allocated_size: allocated size in bytes, negative if not available.
+ * @encrypt: encrypt flag.
+ */
+struct QBlockInfoImageStatic {
+    struct QBlockOptionLoc loc;
+    enum QBlockFormat fmt_type;
+    size_t virt_size;
+    /* advance info */
+    struct QBlockOptionLoc backing_loc;
+    size_t allocated_size;
+    bool encrypt;
+};
+#endif
-- 
1.7.1

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

* [Qemu-devel] [PATCH 3/6] libqblock error handling
  2012-09-03  9:18 [Qemu-devel] [PATCH 0/6] libqblock, qemu block layer library Wenchao Xia
  2012-09-03  9:18 ` [Qemu-devel] [PATCH 1/6] libqblock APIs Wenchao Xia
  2012-09-03  9:18 ` [Qemu-devel] [PATCH 2/6] libqblock public type defines Wenchao Xia
@ 2012-09-03  9:18 ` Wenchao Xia
  2012-09-03 14:22   ` Eric Blake
  2012-09-03  9:18 ` [Qemu-devel] [PATCH 4/6] libqblock internal used functions Wenchao Xia
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 46+ messages in thread
From: Wenchao Xia @ 2012-09-03  9:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, aliguori, stefanha, pbonzini, eblake, Wenchao Xia

  This patch contains error handling APIs.

Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
---
 libqblock/libqblock-error.c |   44 +++++++++++++++++++++++++++++++++++++++++++
 libqblock/libqblock-error.h |   34 +++++++++++++++++++++++++++++++++
 2 files changed, 78 insertions(+), 0 deletions(-)
 create mode 100644 libqblock/libqblock-error.c
 create mode 100644 libqblock/libqblock-error.h

diff --git a/libqblock/libqblock-error.c b/libqblock/libqblock-error.c
new file mode 100644
index 0000000..28d1d77
--- /dev/null
+++ b/libqblock/libqblock-error.c
@@ -0,0 +1,44 @@
+#include "libqblock-error.h"
+#include "libqblock-helper.h"
+
+void qb_error_get_human_str(struct QBroker *broker,
+                            char *buf, int buf_size)
+{
+    const char *err_ret_str;
+    switch (broker->err_ret) {
+    case QB_ERR_MEM_ERR:
+        err_ret_str = "Not enough memory.";
+        break;
+    case QB_ERR_INTERNAL_ERR:
+        err_ret_str = "Internal error.";
+        break;
+    case QB_ERR_INVALID_PARAM:
+        err_ret_str = "Invalid param.";
+        break;
+    default:
+        err_ret_str = "Unknow 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->err_msg,
+                     broker->err_no, strerror(-broker->err_no));
+    } else {
+        snprintf(buf, buf_size, "%s %s",
+                     err_ret_str, broker->err_msg);
+    }
+    return;
+}
+
+int qb_error_get_errno(struct 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..b11df7c
--- /dev/null
+++ b/libqblock/libqblock-error.h
@@ -0,0 +1,34 @@
+#ifndef LIBQBLOCK_ERROR
+#define LIBQBLOCK_ERROR
+
+#include "libqblock-types.h"
+
+#define QB_ERR_MEM_ERR (-1)
+#define QB_ERR_INTERNAL_ERR (-2)
+#define QB_ERR_INVALID_PARAM (-3)
+#define QB_ERR_BLOCK_OUT_OF_RANGE (-100)
+
+/* error handling */
+/**
+ * qb_error_get_human_str: get human readable erro string.
+ *
+ * return a human readable string.
+ *
+ * @broker: operation broker, must be valid.
+ * @buf: buf to receive the string.
+ * @buf_size: the size of the string buf.
+ */
+void qb_error_get_human_str(struct QBroker *broker,
+                            char *buf, int 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.
+ */
+int qb_error_get_errno(struct QBroker *broker);
+
+#endif
-- 
1.7.1

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

* [Qemu-devel] [PATCH 4/6] libqblock internal used functions
  2012-09-03  9:18 [Qemu-devel] [PATCH 0/6] libqblock, qemu block layer library Wenchao Xia
                   ` (2 preceding siblings ...)
  2012-09-03  9:18 ` [Qemu-devel] [PATCH 3/6] libqblock error handling Wenchao Xia
@ 2012-09-03  9:18 ` Wenchao Xia
  2012-09-03 13:18   ` Paolo Bonzini
  2012-09-03 14:28   ` Eric Blake
  2012-09-03  9:18 ` [Qemu-devel] [PATCH 5/6] libqblock test example Wenchao Xia
  2012-09-03  9:18 ` [Qemu-devel] [PATCH 6/6] libqblock building system Wenchao Xia
  5 siblings, 2 replies; 46+ messages in thread
From: Wenchao Xia @ 2012-09-03  9:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, aliguori, stefanha, pbonzini, eblake, Wenchao Xia

  This patch contains internal helper codes.

Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
---
 block.c                      |    2 +-
 block.h                      |    1 +
 libqblock/libqblock-helper.c |   92 ++++++++++++++++++++++++++++++++++++++++++
 libqblock/libqblock-helper.h |   57 ++++++++++++++++++++++++++
 4 files changed, 151 insertions(+), 1 deletions(-)
 create mode 100644 libqblock/libqblock-helper.c
 create mode 100644 libqblock/libqblock-helper.h

diff --git a/block.c b/block.c
index 470bdcc..8b312f8 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-helper.c b/libqblock/libqblock-helper.c
new file mode 100644
index 0000000..f9e8ce9
--- /dev/null
+++ b/libqblock/libqblock-helper.c
@@ -0,0 +1,92 @@
+#include "libqblock-helper.h"
+#include "libqblock-types.h"
+#include "libqblock-error.h"
+
+const char *fmt2str(enum QBlockFormat fmt)
+{
+    const char *ret = NULL;
+    switch (fmt) {
+    case QB_FMT_COW:
+        ret = "cow";
+        break;
+    case QB_FMT_QED:
+        ret = "qed";
+        break;
+    case QB_FMT_QCOW:
+        ret = "qcow";
+        break;
+    case QB_FMT_QCOW2:
+        ret = "qcow2";
+        break;
+    case QB_FMT_RAW:
+        ret = "raw";
+        break;
+    case QB_FMT_RBD:
+        ret = "rbd";
+        break;
+    case QB_FMT_SHEEPDOG:
+        ret = "sheepdog";
+        break;
+    case QB_FMT_VDI:
+        ret = "vdi";
+        break;
+    case QB_FMT_VMDK:
+        ret = "vmdk";
+        break;
+    case QB_FMT_VPC:
+        ret = "vpc";
+        break;
+    default:
+        break;
+    }
+    return ret;
+}
+
+enum QBlockFormat str2fmt(const char *fmt)
+{
+    enum QBlockFormat ret = QB_FMT_NONE;
+    if (0 == strcmp(fmt, "cow")) {
+        ret = QB_FMT_COW;
+    } else if (0 == strcmp(fmt, "qed")) {
+        ret = QB_FMT_QED;
+    } else if (0 == strcmp(fmt, "qcow")) {
+        ret = QB_FMT_QCOW;
+    } else if (0 == strcmp(fmt, "qcow2")) {
+        ret = QB_FMT_QCOW2;
+    } else if (0 == strcmp(fmt, "raw")) {
+        ret = QB_FMT_RAW;
+    } else if (0 == strcmp(fmt, "rbd")) {
+        ret = QB_FMT_RBD;
+    } else if (0 == strcmp(fmt, "sheepdog")) {
+        ret = QB_FMT_SHEEPDOG;
+    } else if (0 == strcmp(fmt, "vdi")) {
+        ret = QB_FMT_VDI;
+    } else if (0 == strcmp(fmt, "vmdk")) {
+        ret = QB_FMT_VMDK;
+    } else if (0 == strcmp(fmt, "vpc")) {
+        ret = QB_FMT_VPC;
+    }
+    return ret;
+}
+
+void set_broker_err(struct QBroker *broker, int err_ret,
+                           const char *fmt, ...)
+{
+    va_list ap;
+
+    broker->err_ret = err_ret;
+    if (err_ret == QB_ERR_INTERNAL_ERR) {
+        broker->err_no = -errno;
+    } else {
+        broker->err_no = 0;
+    }
+
+    va_start(ap, fmt);
+    vsnprintf(broker->err_msg, sizeof(broker->err_msg), fmt, ap);
+    va_end(ap);
+}
+
+void set_broker_err_nomem(struct QBroker *broker)
+{
+    set_broker_err(broker, QB_ERR_MEM_ERR, "No Memory.");
+}
diff --git a/libqblock/libqblock-helper.h b/libqblock/libqblock-helper.h
new file mode 100644
index 0000000..4330472
--- /dev/null
+++ b/libqblock/libqblock-helper.h
@@ -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.
+ *
+ */
+
+#ifndef LIBQBLOCK_HELPER
+#define LIBQBLOCK_HELPER
+
+#include "block.h"
+#include "block_int.h"
+
+#include "libqblock-types.h"
+
+/* this file contains helper function used internally. */
+#define SECTOR_SIZE (512)
+#define SECTOR_SIZE_MASK (0x01ff)
+#define SECTOR_SIZE_BITS_NUM (9)
+#define FUNC_FREE free
+#define FUNC_MALLOC malloc
+#define FUNC_CALLOC calloc
+
+#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;
+};
+
+#define QB_ERR_STRING_SIZE (1024)
+struct QBroker {
+    /* last error */
+    char err_msg[QB_ERR_STRING_SIZE];
+    int err_ret; /* last error return of libqblock. */
+    int err_no; /* 2nd level of error, errno what below reports */
+};
+
+const char *fmt2str(enum QBlockFormat fmt);
+enum QBlockFormat str2fmt(const char *fmt);
+void set_broker_err(struct QBroker *broker, int err_ret,
+                           const char *fmt, ...);
+void set_broker_err_nomem(struct QBroker *broker);
+#endif
-- 
1.7.1

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

* [Qemu-devel] [PATCH 5/6] libqblock test example
  2012-09-03  9:18 [Qemu-devel] [PATCH 0/6] libqblock, qemu block layer library Wenchao Xia
                   ` (3 preceding siblings ...)
  2012-09-03  9:18 ` [Qemu-devel] [PATCH 4/6] libqblock internal used functions Wenchao Xia
@ 2012-09-03  9:18 ` Wenchao Xia
  2012-09-03 19:27   ` Blue Swirl
  2012-09-03  9:18 ` [Qemu-devel] [PATCH 6/6] libqblock building system Wenchao Xia
  5 siblings, 1 reply; 46+ messages in thread
From: Wenchao Xia @ 2012-09-03  9:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, aliguori, stefanha, 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 |  219 ++++++++++++++++++++++++++++++++++++++
 1 files changed, 219 insertions(+), 0 deletions(-)
 create mode 100644 tests/libqblock/libqblock-test.c

diff --git a/tests/libqblock/libqblock-test.c b/tests/libqblock/libqblock-test.c
new file mode 100644
index 0000000..9a1eac5
--- /dev/null
+++ b/tests/libqblock/libqblock-test.c
@@ -0,0 +1,219 @@
+#include <stdarg.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <inttypes.h>
+#include <string.h>
+
+#include "libqblock.h"
+
+static unsigned char buf_r[1024];
+static unsigned char buf_w[1024] = {4, 0, 0, 2};
+
+struct verify_data {
+    unsigned char *buf_r;
+    unsigned char *buf_w;
+    int len;
+};
+
+static void print_loc(struct QBlockOptionLoc *loc)
+{
+    switch (loc->prot_type) {
+    case QB_PROTO_NONE:
+        printf("protocol type [none].");
+        break;
+    case QB_PROTO_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(struct QBlockInfoImageStatic *info)
+{
+    printf("=======image location:\n");
+    print_loc(&info->loc);
+    printf("\nvirtual_size %" PRId64 ", format type %d,",
+           info->virt_size, info->fmt_type);
+    printf("allocated size %" PRId64 ", encrypt %d,",
+           info->allocated_size, info->encrypt);
+    printf("\nbacking image location:\n");
+    print_loc(&info->backing_loc);
+    printf("\n");
+}
+
+static void test_check(struct verify_data *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)
+{
+    char *filename1, *filename2;
+    struct QBroker *broker = NULL;
+    struct QBlockState *qbs = NULL;
+    struct QBlockOptionLoc *ol = NULL;
+    struct QBlockOptionFormat *of = NULL;
+    struct QBlockInfoImageStatic *info_st = NULL;
+    int ret, flag;
+    int test_offset = 0;
+    int test_len = 512;
+    struct verify_data vdata;
+    char err_str[1024];
+
+    vdata.buf_r = buf_r;
+    vdata.buf_w = buf_w;
+    vdata.len = test_len;
+
+    filename1 = (char *)"./qemu_image1";
+    filename2 = (char *)"./qemu_image2";
+    printf("qemu test, filename1 is %s, filename2 is %s.\n",
+                                       filename1, filename2);
+
+    libqblock_init();
+
+    ret = qb_broker_new(&broker);
+    if (ret < 0) {
+        goto free;
+    }
+
+    ret = qb_state_new(broker, &qbs);
+    if (ret < 0) {
+        goto free;
+    }
+
+    ret = qb_ol_new(broker, &ol);
+    if (ret < 0) {
+        goto free;
+    }
+
+    ret = qb_of_new(broker, &of);
+    if (ret < 0) {
+        goto free;
+    }
+
+    /* create a new image */
+
+    ol->prot_type = QB_PROTO_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_PROTO_FILE;
+    ol->prot_op.o_file.filename = filename1;
+    of->fmt_type = QB_FMT_QCOW2;
+    of->fmt_op.o_qcow2.backing_loc.prot_type = QB_PROTO_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_PROTO_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->backing_loc.prot_type == QB_FMT_NONE) {
+            break;
+        }
+        *ol = info_st->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_PROTO_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[24] = 3;
+    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_ol_delete(broker, &ol);
+    }
+    if (of != NULL) {
+        qb_of_delete(broker, &of);
+    }
+    if (broker != NULL) {
+        qb_broker_delete(&broker);
+    }
+    return 0;
+}
-- 
1.7.1

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

* [Qemu-devel] [PATCH 6/6] libqblock building system
  2012-09-03  9:18 [Qemu-devel] [PATCH 0/6] libqblock, qemu block layer library Wenchao Xia
                   ` (4 preceding siblings ...)
  2012-09-03  9:18 ` [Qemu-devel] [PATCH 5/6] libqblock test example Wenchao Xia
@ 2012-09-03  9:18 ` Wenchao Xia
  2012-09-03 13:10   ` [Qemu-devel] xbzrle migration cache size advise for high memory changes workload ? Alexandre DERUMIER
  5 siblings, 1 reply; 46+ messages in thread
From: Wenchao Xia @ 2012-09-03  9:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, aliguori, stefanha, 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.
  Test cases are placed under tests/libqblock/.

Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
---
 Makefile                 |   22 +++++++++++++++-
 Makefile.objs            |    6 ++++
 libqblock/Makefile       |   62 ++++++++++++++++++++++++++++++++++++++++++++++
 tests/Makefile           |    3 ++
 tests/libqblock/Makefile |   28 ++++++++++++++++++++
 5 files changed, 120 insertions(+), 1 deletions(-)
 create mode 100644 libqblock/Makefile
 create mode 100644 tests/libqblock/Makefile

diff --git a/Makefile b/Makefile
index 1cd5bc8..9f3c0a0 100644
--- a/Makefile
+++ b/Makefile
@@ -163,6 +163,25 @@ 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
+
+.PHONY: libqblock.la
+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
+
+#make native test file instead of libtool, as a test for development
+QEMU_CFLAGS+=-I./libqblock
+libqblock-objs=libqblock/libqblock.o libqblock/libqblock-helper.o libqblock/libqblock-error.o
+libqblock-test-native$(EXESUF): $(libqblock-objs) tests/libqblock/libqblock-test.o $(tools-obj-y) $(block-obj-y)
+	$(call quiet-command,$(CC) $(LDFLAGS) -o $@ $^ $(LIBS),"  LINK  $@")
+###########################################################################
+
 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  $@")
 
@@ -226,7 +245,8 @@ clean:
 	rm -rf qapi-generated
 	rm -rf qga/qapi-generated
 	$(MAKE) -C tests/tcg clean
-	for d in $(ALL_SUBDIRS) $(QEMULIBS) libcacard; do \
+	$(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; \
         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..5f16000
--- /dev/null
+++ b/libqblock/Makefile
@@ -0,0 +1,62 @@
+###########################################################################
+# 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-helper.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
+
+#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/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..4b4da2f
--- /dev/null
+++ b/tests/libqblock/Makefile
@@ -0,0 +1,28 @@
+-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)
+	$(call quiet-command,$(LIBTOOL) --mode=link --quiet --tag=CC $(CC) -shared -rpath $(libdir) -o $@ $^ $(libqblock-la-path),"  lt LINK $@")
+endif
+
+check-libqblock: libqblock-test.bin
+	./libqblock-test.bin
+
+clean:
+	rm -f *.lo *.o *.d *.la *.bin
+	rm -rf .libs
-- 
1.7.1

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

* [Qemu-devel] xbzrle migration cache size advise for high memory changes workload ?
  2012-09-03  9:18 ` [Qemu-devel] [PATCH 6/6] libqblock building system Wenchao Xia
@ 2012-09-03 13:10   ` Alexandre DERUMIER
  2012-09-04 14:05     ` Orit Wasserman
  0 siblings, 1 reply; 46+ messages in thread
From: Alexandre DERUMIER @ 2012-09-03 13:10 UTC (permalink / raw)
  To: qemu-devel

Hi,
I'm trying to implement xbzrle live migration,

But i'm having non finishing migration with high memory changes in guest.
(simply playing a youtube video in the guest). 
At the end of the migration, the remaining memory to transfert goes up and down.

I have tried to dynamicaly add memory to cache (max = guest memory), but it doesn't help.


What is the best size recommendation for cache ? (percent of guest memory ?)
Can I tune it based on some values ? (cachemiss, overflow ?)

Can we desactivate xbzrle during the migration ?




Some logs counters of the migration:

Sep 03 15:00:32 migration xbzrle cachesize: 67108864 transferred 0 pages 0 cachemiss 15158 overflow 0 deltacachemiss 15158
Sep 03 15:00:34 migration status: active (transferred 119318244, remaining 1987846144), total 2114387968)
Sep 03 15:00:34 migration xbzrle cachesize: 67108864 transferred 0 pages 0 cachemiss 29130 overflow 0 deltacachemiss 13972
Sep 03 15:00:36 migration status: active (transferred 156261310, remaining 1342005248), total 2114387968)
Sep 03 15:00:36 migration xbzrle cachesize: 67108864 transferred 0 pages 0 cachemiss 38113 overflow 0 deltacachemiss 8983
Sep 03 15:00:38 migration status: active (transferred 195909631, remaining 786370560), total 2114387968)
Sep 03 15:00:38 migration xbzrle cachesize: 67108864 transferred 0 pages 0 cachemiss 47762 overflow 0 deltacachemiss 9649
Sep 03 15:00:40 migration status: active (transferred 264583501, remaining 716410880), total 2114387968)
Sep 03 15:00:40 migration xbzrle cachesize: 67108864 transferred 0 pages 0 cachemiss 64528 overflow 0 deltacachemiss 16766
Sep 03 15:00:42 migration status: active (transferred 336759138, remaining 644227072), total 2114387968)
Sep 03 15:00:42 migration xbzrle cachesize: 67108864 transferred 0 pages 0 cachemiss 82149 overflow 0 deltacachemiss 17621
Sep 03 15:00:44 migration status: active (transferred 399641876, remaining 577712128), total 2114387968)
Sep 03 15:00:44 migration xbzrle cachesize: 67108864 transferred 0 pages 0 cachemiss 97501 overflow 0 deltacachemiss 15352
Sep 03 15:00:46 migration status: active (transferred 446500707, remaining 528441344), total 2114387968)
Sep 03 15:00:46 migration xbzrle cachesize: 67108864 transferred 0 pages 0 cachemiss 108941 overflow 0 deltacachemiss 11440
Sep 03 15:00:48 migration status: active (transferred 501567884, remaining 471134208), total 2114387968)
Sep 03 15:00:48 migration xbzrle cachesize: 67108864 transferred 0 pages 0 cachemiss 122385 overflow 0 deltacachemiss 13444
Sep 03 15:00:50 migration status: active (transferred 566289154, remaining 404901888), total 2114387968)
Sep 03 15:00:50 migration xbzrle cachesize: 67108864 transferred 0 pages 0 cachemiss 138186 overflow 0 deltacachemiss 15801
Sep 03 15:00:52 migration status: active (transferred 631297144, remaining 338370560), total 2114387968)
Sep 03 15:00:52 migration xbzrle cachesize: 67108864 transferred 0 pages 0 cachemiss 154057 overflow 0 deltacachemiss 15871
Sep 03 15:00:54 migration status: active (transferred 695854441, remaining 272830464), total 2114387968)
Sep 03 15:00:54 migration xbzrle cachesize: 67108864 transferred 0 pages 0 cachemiss 169818 overflow 0 deltacachemiss 15761
Sep 03 15:00:56 migration status: active (transferred 763447412, remaining 202059776), total 2114387968)
Sep 03 15:00:56 migration xbzrle cachesize: 67108864 transferred 0 pages 0 cachemiss 186320 overflow 0 deltacachemiss 16502
Sep 03 15:00:58 migration status: active (transferred 828361066, remaining 136142848), total 2114387968)
Sep 03 15:00:58 migration xbzrle cachesize: 67108864 transferred 0 pages 0 cachemiss 202168 overflow 0 deltacachemiss 15848
Sep 03 15:01:00 migration status: active (transferred 879799289, remaining 82030592), total 2114387968)
Sep 03 15:01:00 migration xbzrle cachesize: 67108864 transferred 0 pages 0 cachemiss 214726 overflow 0 deltacachemiss 12558
Sep 03 15:01:02 migration status: active (transferred 940920124, remaining 19603456), total 2114387968)
Sep 03 15:01:02 migration xbzrle cachesize: 67108864 transferred 0 pages 0 cachemiss 229648 overflow 0 deltacachemiss 14922
Sep 03 15:01:03 migration status: active (transferred 949001101, remaining 69087232), total 2114387968)
Sep 03 15:01:03 migration xbzrle cachesize: 67108864 transferred 0 pages 0 cachemiss 231620 overflow 0 deltacachemiss 1972
Sep 03 15:01:03 migration status: active (transferred 959106075, remaining 58187776), total 2114387968)
Sep 03 15:01:03 migration xbzrle cachesize: 67108864 transferred 100 pages 2 cachemiss 234087 overflow 0 deltacachemiss 2467
Sep 03 15:01:03 migration status: active (transferred 969236581, remaining 43577344), total 2114387968)
Sep 03 15:01:03 migration xbzrle cachesize: 67108864 transferred 100 pages 2 cachemiss 236560 overflow 0 deltacachemiss 2473
Sep 03 15:01:04 migration status: active (transferred 979374186, remaining 33427456), total 2114387968)
Sep 03 15:01:04 migration xbzrle cachesize: 67108864 transferred 100 pages 2 cachemiss 239035 overflow 0 deltacachemiss 2475
Sep 03 15:01:04 migration status: active (transferred 989479026, remaining 23302144), total 2114387968)
Sep 03 15:01:04 migration xbzrle cachesize: 67108864 transferred 100 pages 2 cachemiss 241502 overflow 0 deltacachemiss 2467
Sep 03 15:01:04 migration status: active (transferred 999747708, remaining 28950528), total 2114387968)
Sep 03 15:01:04 migration xbzrle cachesize: 67108864 transferred 100 pages 2 cachemiss 244009 overflow 0 deltacachemiss 2507
Sep 03 15:01:04 migration status: active (transferred 1006616716, remaining 22032384), total 2114387968)
Sep 03 15:01:04 migration xbzrle cachesize: 67108864 transferred 100 pages 2 cachemiss 245686 overflow 0 deltacachemiss 1677
Sep 03 15:01:05 migration status: active (transferred 1020085038, remaining 18358272), total 2114387968)
Sep 03 15:01:05 migration xbzrle cachesize: 67108864 transferred 1905397 pages 991 cachemiss 248381 overflow 128 deltacachemiss 2695
Sep 03 15:01:05 migration status: active (transferred 1030213871, remaining 14524416), total 2114387968)
Sep 03 15:01:05 migration xbzrle cachesize: 67108864 transferred 6103206 pages 3227 cachemiss 249646 overflow 311 deltacachemiss 1265
Sep 03 15:01:05 migration status: active (transferred 1040306669, remaining 7348224), total 2114387968)
Sep 03 15:01:05 migration xbzrle cachesize: 67108864 transferred 11579783 pages 6075 cachemiss 250496 overflow 588 deltacachemiss 850
Sep 03 15:01:06 migration status: active (transferred 1047695771, remaining 13287424), total 2114387968)
Sep 03 15:01:06 migration xbzrle cachesize: 67108864 transferred 15286549 pages 9455 cachemiss 251271 overflow 712 deltacachemiss 775
Sep 03 15:01:06 migration status: active (transferred 1054790825, remaining 8896512), total 2114387968)
Sep 03 15:01:06 migration xbzrle cachesize: 67108864 transferred 18600974 pages 12483 cachemiss 252020 overflow 886 deltacachemiss 749
Sep 03 15:01:06 migration status: active (transferred 1064883713, remaining 3870720), total 2114387968)
Sep 03 15:01:06 migration xbzrle cachesize: 67108864 transferred 24180048 pages 15326 cachemiss 252856 overflow 1152 deltacachemiss 836
Sep 03 15:01:07 migration status: active (transferred 1073205318, remaining 13889536), total 2114387968)
Sep 03 15:01:07 migration xbzrle cachesize: 67108864 transferred 28106603 pages 18135 cachemiss 253769 overflow 1312 deltacachemiss 913
Sep 03 15:01:07 migration status: active (transferred 1083269753, remaining 8450048), total 2114387968)
Sep 03 15:01:07 migration xbzrle cachesize: 67108864 transferred 33685887 pages 20865 cachemiss 254445 overflow 1731 deltacachemiss 676
Sep 03 15:01:07 migration status: active (transferred 1093363118, remaining 13656064), total 2114387968)
Sep 03 15:01:07 migration xbzrle cachesize: 67108864 transferred 39318685 pages 23895 cachemiss 255182 overflow 2083 deltacachemiss 737
Sep 03 15:01:08 migration status: active (transferred 1104228774, remaining 3948544), total 2114387968)
Sep 03 15:01:08 migration xbzrle cachesize: 67108864 transferred 45621367 pages 27392 cachemiss 255988 overflow 2391 deltacachemiss 806
Sep 03 15:01:08 migration status: active (transferred 1112828342, remaining 4714496), total 2114387968)
Sep 03 15:01:08 migration xbzrle cachesize: 67108864 transferred 50624630 pages 29895 cachemiss 256597 overflow 2660 deltacachemiss 609
Sep 03 15:01:08 migration status: active (transferred 1121646599, remaining 5951488), total 2114387968)
Sep 03 15:01:08 migration xbzrle cachesize: 67108864 transferred 54638264 pages 32011 cachemiss 257423 overflow 3007 deltacachemiss 826
Sep 03 15:01:09 migration status: active (transferred 1131774276, remaining 14245888), total 2114387968)
Sep 03 15:01:09 migration xbzrle cachesize: 67108864 transferred 59924446 pages 34904 cachemiss 258311 overflow 3301 deltacachemiss 888
Sep 03 15:01:09 migration status: active (transferred 1139357344, remaining 12529664), total 2114387968)
Sep 03 15:01:09 migration xbzrle cachesize: 67108864 transferred 62850320 pages 39537 cachemiss 259385 overflow 3364 deltacachemiss 1074
Sep 03 15:01:09 migration status: active (transferred 1147848486, remaining 12972032), total 2114387968)
Sep 03 15:01:09 migration xbzrle cachesize: 67108864 transferred 67237245 pages 43153 cachemiss 260229 overflow 3522 deltacachemiss 844
Sep 03 15:01:10 migration status: active (transferred 1157968777, remaining 7729152), total 2114387968)
Sep 03 15:01:10 migration xbzrle cachesize: 67108864 transferred 72753611 pages 45998 cachemiss 260890 overflow 3985 deltacachemiss 661
Sep 03 15:01:10 migration status: active (transferred 1168065017, remaining 3137536), total 2114387968)
Sep 03 15:01:10 migration xbzrle cachesize: 67108864 transferred 78000165 pages 48646 cachemiss 261660 overflow 4399 deltacachemiss 770
Sep 03 15:01:10 migration status: active (transferred 1176461216, remaining 5459968), total 2114387968)
Sep 03 15:01:10 migration xbzrle cachesize: 67108864 transferred 81931708 pages 50605 cachemiss 262364 overflow 4785 deltacachemiss 704
Sep 03 15:01:11 migration status: active (transferred 1187721613, remaining 15183872), total 2114387968)
Sep 03 15:01:11 migration xbzrle cachesize: 67108864 transferred 87588758 pages 53584 cachemiss 263313 overflow 5204 deltacachemiss 949
Sep 03 15:01:11 migration status: active (transferred 1196325449, remaining 15134720), total 2114387968)
Sep 03 15:01:11 migration xbzrle cachesize: 67108864 transferred 92063809 pages 55810 cachemiss 263933 overflow 5592 deltacachemiss 620
Sep 03 15:01:11 migration status: active (transferred 1206419175, remaining 7557120), total 2114387968)
Sep 03 15:01:11 migration xbzrle cachesize: 67108864 transferred 97500362 pages 58460 cachemiss 264676 overflow 5986 deltacachemiss 743
Sep 03 15:01:11 migration status: active (transferred 1216510694, remaining 15560704), total 2114387968)
Sep 03 15:01:11 migration xbzrle cachesize: 67108864 transferred 102480030 pages 61212 cachemiss 265552 overflow 6358 deltacachemiss 876
Sep 03 15:01:12 migration status: active (transferred 1225162926, remaining 14811136), total 2114387968)
Sep 03 15:01:12 migration xbzrle cachesize: 67108864 transferred 107155027 pages 63456 cachemiss 266234 overflow 6647 deltacachemiss 682
Sep 03 15:01:12 migration status: active (transferred 1235228927, remaining 12378112), total 2114387968)
Sep 03 15:01:12 migration xbzrle cachesize: 67108864 transferred 112440978 pages 66311 cachemiss 267101 overflow 6947 deltacachemiss 867
Sep 03 15:01:12 migration status: active (transferred 1245060361, remaining 14848000), total 2114387968)
Sep 03 15:01:12 migration xbzrle cachesize: 67108864 transferred 116886157 pages 68943 cachemiss 268239 overflow 7124 deltacachemiss 1138
Sep 03 15:01:13 migration status: active (transferred 1255151722, remaining 14151680), total 2114387968)
Sep 03 15:01:13 migration xbzrle cachesize: 67108864 transferred 121058631 pages 71389 cachemiss 269475 overflow 7333 deltacachemiss 1236
Sep 03 15:01:13 migration status: active (transferred 1265145124, remaining 12636160), total 2114387968)
Sep 03 15:01:13 migration xbzrle cachesize: 67108864 transferred 125804843 pages 74069 cachemiss 270559 overflow 7530 deltacachemiss 1084
Sep 03 15:01:13 migration status: active (transferred 1274160338, remaining 9003008), total 2114387968)
Sep 03 15:01:13 migration xbzrle cachesize: 67108864 transferred 130109480 pages 76352 cachemiss 271460 overflow 7779 deltacachemiss 901
Sep 03 15:01:14 migration status: active (transferred 1285539796, remaining 12382208), total 2114387968)
Sep 03 15:01:14 migration xbzrle cachesize: 67108864 transferred 136704693 pages 79967 cachemiss 272399 overflow 8008 deltacachemiss 939
Sep 03 15:01:14 migration status: active (transferred 1294465950, remaining 10989568), total 2114387968)
Sep 03 15:01:14 migration xbzrle cachesize: 67108864 transferred 141522529 pages 82691 cachemiss 273221 overflow 8189 deltacachemiss 822
Sep 03 15:01:14 migration status: active (transferred 1304111247, remaining 12431360), total 2114387968)
Sep 03 15:01:14 migration xbzrle cachesize: 67108864 transferred 146256619 pages 85117 cachemiss 274137 overflow 8472 deltacachemiss 916
Sep 03 15:01:15 migration status: active (transferred 1313714825, remaining 9031680), total 2114387968)
Sep 03 15:01:15 migration xbzrle cachesize: 67108864 transferred 150961349 pages 87828 cachemiss 275101 overflow 8704 deltacachemiss 964
Sep 03 15:01:15 migration status: active (transferred 1321615036, remaining 8843264), total 2114387968)
Sep 03 15:01:15 migration xbzrle cachesize: 67108864 transferred 155568345 pages 90258 cachemiss 275753 overflow 8856 deltacachemiss 652
Sep 03 15:01:15 migration status: active (transferred 1332266783, remaining 4997120), total 2114387968)
Sep 03 15:01:15 migration xbzrle cachesize: 67108864 transferred 161419460 pages 93534 cachemiss 276690 overflow 9091 deltacachemiss 937
Sep 03 15:01:16 migration status: active (transferred 1340961412, remaining 4333568), total 2114387968)
Sep 03 15:01:16 migration xbzrle cachesize: 67108864 transferred 165833625 pages 96166 cachemiss 277571 overflow 9255 deltacachemiss 881
Sep 03 15:01:16 migration status: active (transferred 1349569887, remaining 4313088), total 2114387968)
Sep 03 15:01:16 migration xbzrle cachesize: 67108864 transferred 170194521 pages 98568 cachemiss 278366 overflow 9497 deltacachemiss 795
Sep 03 15:01:16 migration status: active (transferred 1357212762, remaining 5083136), total 2114387968)
Sep 03 15:01:16 migration xbzrle cachesize: 67108864 transferred 173651067 pages 100693 cachemiss 279206 overflow 9679 deltacachemiss 840
Sep 03 15:01:16 migration status: active (transferred 1362924614, remaining 12259328), total 2114387968)
Sep 03 15:01:16 migration xbzrle cachesize: 67108864 transferred 175983690 pages 102350 cachemiss 279936 overflow 9774 deltacachemiss 730
Sep 03 15:01:17 migration status: active (transferred 1369555421, remaining 17477632), total 2114387968)
Sep 03 15:01:17 migration xbzrle cachesize: 67108864 transferred 178796811 pages 103929 cachemiss 280702 overflow 9940 deltacachemiss 766
Sep 03 15:01:17 migration status: active (transferred 1377394106, remaining 17633280), total 2114387968)
Sep 03 15:01:17 migration xbzrle cachesize: 67108864 transferred 181986406 pages 106134 cachemiss 281646 overflow 10131 deltacachemiss 944
Sep 03 15:01:17 migration status: active (transferred 1383071812, remaining 5853184), total 2114387968)
Sep 03 15:01:17 migration xbzrle cachesize: 67108864 transferred 184276689 pages 107825 cachemiss 282388 overflow 10216 deltacachemiss 742
Sep 03 15:01:18 migration status: active (transferred 1389248230, remaining 12910592), total 2114387968)
Sep 03 15:01:18 migration xbzrle cachesize: 67108864 transferred 187049184 pages 109409 cachemiss 283037 overflow 10398 deltacachemiss 649
Sep 03 15:01:18 migration status: active (transferred 1395386430, remaining 20598784), total 2114387968)
Sep 03 15:01:18 migration xbzrle cachesize: 67108864 transferred 189005134 pages 110884 cachemiss 283908 overflow 10548 deltacachemiss 871
Sep 03 15:01:18 migration status: active (transferred 1402994779, remaining 6443008), total 2114387968)
Sep 03 15:01:18 migration xbzrle cachesize: 67108864 transferred 191456304 pages 112393 cachemiss 284917 overflow 10798 deltacachemiss 1009
Sep 03 15:01:19 migration status: active (transferred 1409267086, remaining 13611008), total 2114387968)
Sep 03 15:01:19 migration xbzrle cachesize: 67108864 transferred 193247446 pages 113783 cachemiss 285846 overflow 10963 deltacachemiss 929
Sep 03 15:01:19 migration status: active (transferred 1420299927, remaining 6414336), total 2114387968)
Sep 03 15:01:19 migration xbzrle cachesize: 67108864 transferred 197795949 pages 116951 cachemiss 287280 overflow 11112 deltacachemiss 1434
Sep 03 15:01:19 migration status: active (transferred 1430776107, remaining 9695232), total 2114387968)
Sep 03 15:01:19 migration xbzrle cachesize: 67108864 transferred 202680859 pages 120761 cachemiss 288557 overflow 11200 deltacachemiss 1277
Sep 03 15:01:20 migration status: active (transferred 1440821167, remaining 2637824), total 2114387968)
Sep 03 15:01:20 migration xbzrle cachesize: 67108864 transferred 208318417 pages 125073 cachemiss 289534 overflow 11299 deltacachemiss 977
Sep 03 15:01:20 migration status: active (transferred 1447117251, remaining 12091392), total 2114387968)
Sep 03 15:01:20 migration xbzrle cachesize: 67108864 transferred 211300697 pages 127309 cachemiss 290244 overflow 11398 deltacachemiss 710
Sep 03 15:01:20 migration status: active (transferred 1456026090, remaining 12906496), total 2114387968)
Sep 03 15:01:20 migration xbzrle cachesize: 67108864 transferred 216105094 pages 131039 cachemiss 291149 overflow 11495 deltacachemiss 905
Sep 03 15:01:21 migration status: active (transferred 1463954394, remaining 2822144), total 2114387968)
Sep 03 15:01:21 migration xbzrle cachesize: 67108864 transferred 220531007 pages 134323 cachemiss 291906 overflow 11593 deltacachemiss 757
Sep 03 15:01:21 migration status: active (transferred 1470931218, remaining 11534336), total 2114387968)
Sep 03 15:01:21 migration xbzrle cachesize: 67108864 transferred 223866256 pages 137986 cachemiss 292723 overflow 11665 deltacachemiss 817
Sep 03 15:01:21 migration status: active (transferred 1477743090, remaining 10235904), total 2114387968)
Sep 03 15:01:21 migration xbzrle cachesize: 67108864 transferred 227683667 pages 141111 cachemiss 293368 overflow 11751 deltacachemiss 645
Sep 03 15:01:21 migration status: active (transferred 1486951605, remaining 10551296), total 2114387968)
Sep 03 15:01:21 migration xbzrle cachesize: 67108864 transferred 232771294 pages 145280 cachemiss 294269 overflow 11856 deltacachemiss 901
Sep 03 15:01:22 migration status: active (transferred 1493416356, remaining 14299136), total 2114387968)
Sep 03 15:01:22 migration xbzrle cachesize: 67108864 transferred 235959068 pages 148181 cachemiss 294953 overflow 11972 deltacachemiss 684
Sep 03 15:01:22 migration status: active (transferred 1502498989, remaining 10592256), total 2114387968)
Sep 03 15:01:22 migration xbzrle cachesize: 67108864 transferred 240400566 pages 151598 cachemiss 295980 overflow 12078 deltacachemiss 1027
Sep 03 15:01:22 migration status: active (transferred 1511006667, remaining 10240000), total 2114387968)
Sep 03 15:01:22 migration xbzrle cachesize: 67108864 transferred 244648073 pages 155655 cachemiss 296923 overflow 12175 deltacachemiss 943
Sep 03 15:01:23 migration status: active (transferred 1521022229, remaining 10424320), total 2114387968)
Sep 03 15:01:23 migration xbzrle cachesize: 67108864 transferred 250362498 pages 159932 cachemiss 297842 overflow 12306 deltacachemiss 919
Sep 03 15:01:23 migration status: active (transferred 1530294933, remaining 9367552), total 2114387968)
Sep 03 15:01:23 migration xbzrle cachesize: 67108864 transferred 255219350 pages 163947 cachemiss 298815 overflow 12411 deltacachemiss 973
Sep 03 15:01:23 migration status: active (transferred 1540134732, remaining 9908224), total 2114387968)
Sep 03 15:01:23 migration xbzrle cachesize: 67108864 transferred 260909578 pages 168294 cachemiss 299727 overflow 12512 deltacachemiss 912
Sep 03 15:01:24 migration status: active (transferred 1547801099, remaining 2134016), total 2114387968)
Sep 03 15:01:24 migration xbzrle cachesize: 67108864 transferred 263844849 pages 171252 cachemiss 300772 overflow 12622 deltacachemiss 1045
Sep 03 15:01:24 migration status: active (transferred 1554064971, remaining 12468224), total 2114387968)
Sep 03 15:01:24 migration xbzrle cachesize: 67108864 transferred 267032335 pages 173533 cachemiss 301438 overflow 12707 deltacachemiss 666
Sep 03 15:01:24 migration status: active (transferred 1565158149, remaining 11444224), total 2114387968)
Sep 03 15:01:24 migration xbzrle cachesize: 67108864 transferred 273009204 pages 178082 cachemiss 302561 overflow 12833 deltacachemiss 1123
Sep 03 15:01:25 migration status: active (transferred 1574725942, remaining 11866112), total 2114387968)
Sep 03 15:01:25 migration xbzrle cachesize: 67108864 transferred 278128445 pages 182505 cachemiss 303555 overflow 12925 deltacachemiss 994
Sep 03 15:01:25 migration status: active (transferred 1584030411, remaining 10473472), total 2114387968)
Sep 03 15:01:25 migration xbzrle cachesize: 67108864 transferred 282722425 pages 187028 cachemiss 304611 overflow 13019 deltacachemiss 1056
Sep 03 15:01:25 migration status: active (transferred 1592843701, remaining 2134016), total 2114387968)
Sep 03 15:01:25 migration xbzrle cachesize: 67108864 transferred 287443772 pages 192031 cachemiss 305549 overflow 13080 deltacachemiss 938
Sep 03 15:01:26 migration status: active (transferred 1601793792, remaining 6676480), total 2114387968)
Sep 03 15:01:26 migration xbzrle cachesize: 67108864 transferred 292445279 pages 196112 cachemiss 306407 overflow 13186 deltacachemiss 858
Sep 03 15:01:26 migration status: active (transferred 1609953585, remaining 12259328), total 2114387968)
Sep 03 15:01:26 migration xbzrle cachesize: 67108864 transferred 296742516 pages 199610 cachemiss 307294 overflow 13242 deltacachemiss 887
Sep 03 15:01:26 migration status: active (transferred 1618150798, remaining 4358144), total 2114387968)
Sep 03 15:01:26 migration xbzrle cachesize: 67108864 transferred 301634218 pages 203248 cachemiss 308022 overflow 13321 deltacachemiss 728
Sep 03 15:01:26 migration status: active (transferred 1625047015, remaining 11665408), total 2114387968)
Sep 03 15:01:26 migration xbzrle cachesize: 67108864 transferred 305642729 pages 206530 cachemiss 308695 overflow 13353 deltacachemiss 673
Sep 03 15:01:27 migration status: active (transferred 1631583544, remaining 8450048), total 2114387968)
Sep 03 15:01:27 migration xbzrle cachesize: 67108864 transferred 309520928 pages 209601 cachemiss 309308 overflow 13389 deltacachemiss 613
Sep 03 15:01:27 migration status: active (transferred 1637654847, remaining 7917568), total 2114387968)
Sep 03 15:01:27 migration xbzrle cachesize: 67108864 transferred 313118229 pages 212178 cachemiss 309876 overflow 13425 deltacachemiss 568
Sep 03 15:01:27 migration status: active (transferred 1644608997, remaining 6324224), total 2114387968)
Sep 03 15:01:27 migration xbzrle cachesize: 67108864 transferred 317303461 pages 215070 cachemiss 310504 overflow 13473 deltacachemiss 628
Sep 03 15:01:28 migration status: active (transferred 1652796103, remaining 4423680), total 2114387968)
Sep 03 15:01:28 migration xbzrle cachesize: 67108864 transferred 321243002 pages 218055 cachemiss 311465 overflow 13549 deltacachemiss 961
Sep 03 15:01:28 migration status: active (transferred 1662238886, remaining 12513280), total 2114387968)
Sep 03 15:01:28 migration xbzrle cachesize: 67108864 transferred 326180167 pages 221148 cachemiss 312524 overflow 13590 deltacachemiss 1059
Sep 03 15:01:28 migration status: active (transferred 1670338088, remaining 5959680), total 2114387968)
Sep 03 15:01:28 migration xbzrle cachesize: 67108864 transferred 330945203 pages 224318 cachemiss 313295 overflow 13633 deltacachemiss 771
Sep 03 15:01:29 migration status: active (transferred 1682607732, remaining 5373952), total 2114387968)
Sep 03 15:01:29 migration xbzrle cachesize: 67108864 transferred 339032796 pages 228942 cachemiss 314248 overflow 13701 deltacachemiss 953
Sep 03 15:01:29 migration status: active (transferred 1691288677, remaining 5660672), total 2114387968)
Sep 03 15:01:29 migration xbzrle cachesize: 67108864 transferred 344379577 pages 232454 cachemiss 315033 overflow 13730 deltacachemiss 785
Sep 03 15:01:29 migration status: active (transferred 1699318970, remaining 13336576), total 2114387968)
Sep 03 15:01:29 migration xbzrle cachesize: 67108864 transferred 349546739 pages 235705 cachemiss 315700 overflow 13762 deltacachemiss 667
Sep 03 15:01:30 migration status: active (transferred 1709411503, remaining 7815168), total 2114387968)
Sep 03 15:01:30 migration xbzrle cachesize: 67108864 transferred 355408081 pages 238683 cachemiss 316531 overflow 13964 deltacachemiss 831
Sep 03 15:01:30 migration status: active (transferred 1719503532, remaining 12898304), total 2114387968)
Sep 03 15:01:30 migration xbzrle cachesize: 67108864 transferred 361350845 pages 241661 cachemiss 317275 overflow 14233 deltacachemiss 744
Sep 03 15:01:30 migration status: active (transferred 1728857886, remaining 6778880), total 2114387968)
Sep 03 15:01:30 migration xbzrle cachesize: 67108864 transferred 366736158 pages 244405 cachemiss 317948 overflow 14529 deltacachemiss 673
Sep 03 15:01:31 migration status: active (transferred 1738122997, remaining 2527232), total 2114387968)
Sep 03 15:01:31 migration xbzrle cachesize: 67108864 transferred 372220641 pages 246999 cachemiss 318550 overflow 14850 deltacachemiss 602
Sep 03 15:01:31 migration status: active (transferred 1745051297, remaining 2850816), total 2114387968)
Sep 03 15:01:31 migration xbzrle cachesize: 67108864 transferred 376056452 pages 248933 cachemiss 319032 overflow 15123 deltacachemiss 482
Sep 03 15:01:31 migration status: active (transferred 1754719918, remaining 12759040), total 2114387968)
Sep 03 15:01:31 migration xbzrle cachesize: 67108864 transferred 381239933 pages 251517 cachemiss 319744 overflow 15506 deltacachemiss 712
Sep 03 15:01:32 migration status: active (transferred 1763103223, remaining 9637888), total 2114387968)
Sep 03 15:01:32 migration xbzrle cachesize: 67108864 transferred 385265065 pages 254298 cachemiss 320538 overflow 15776 deltacachemiss 794
Sep 03 15:01:32 migration status: active (transferred 1771003331, remaining 3596288), total 2114387968)
Sep 03 15:01:32 migration xbzrle cachesize: 67108864 transferred 388708690 pages 257558 cachemiss 321498 overflow 15904 deltacachemiss 960
Sep 03 15:01:32 migration status: active (transferred 1778157089, remaining 12443648), total 2114387968)
Sep 03 15:01:32 migration xbzrle cachesize: 67108864 transferred 392561052 pages 260534 cachemiss 322166 overflow 16042 deltacachemiss 668
Sep 03 15:01:33 migration status: active (transferred 1788495031, remaining 10276864), total 2114387968)
Sep 03 15:01:33 migration xbzrle cachesize: 67108864 transferred 398295061 pages 264848 cachemiss 323101 overflow 16231 deltacachemiss 935
Sep 03 15:01:33 migration status: active (transferred 1794009984, remaining 11046912), total 2114387968)
Sep 03 15:01:33 migration xbzrle cachesize: 67108864 transferred 400795337 pages 266649 cachemiss 323687 overflow 16381 deltacachemiss 586
Sep 03 15:01:33 migration status: active (transferred 1802929181, remaining 5738496), total 2114387968)
Sep 03 15:01:33 migration xbzrle cachesize: 67108864 transferred 406032198 pages 269339 cachemiss 324245 overflow 16722 deltacachemiss 558
Sep 03 15:01:33 migration status: active (transferred 1813019717, remaining 13381632), total 2114387968)
Sep 03 15:01:33 migration xbzrle cachesize: 67108864 transferred 412084058 pages 272447 cachemiss 324891 overflow 17062 deltacachemiss 646
Sep 03 15:01:34 migration status: active (transferred 1822507168, remaining 3809280), total 2114387968)
Sep 03 15:01:34 migration xbzrle cachesize: 67108864 transferred 416672658 pages 275640 cachemiss 325836 overflow 17313 deltacachemiss 945
Sep 03 15:01:34 migration status: active (transferred 1829060930, remaining 10371072), total 2114387968)
Sep 03 15:01:34 migration xbzrle cachesize: 67108864 transferred 418147336 pages 279826 cachemiss 327002 overflow 17387 deltacachemiss 1166
Sep 03 15:01:34 migration status: active (transferred 1835035082, remaining 11374592), total 2114387968)
Sep 03 15:01:34 migration xbzrle cachesize: 67108864 transferred 419374185 pages 284812 cachemiss 328106 overflow 17442 deltacachemiss 1104
Sep 03 15:01:35 migration status: active (transferred 1840925069, remaining 11190272), total 2114387968)
Sep 03 15:01:35 migration xbzrle cachesize: 67108864 transferred 420520965 pages 289916 cachemiss 329221 overflow 17485 deltacachemiss 1115
Sep 03 15:01:35 migration status: active (transferred 1846770014, remaining 9371648), total 2114387968)
Sep 03 15:01:35 migration xbzrle cachesize: 67108864 transferred 421458853 pages 294580 cachemiss 330372 overflow 17532 deltacachemiss 1151
Sep 03 15:01:35 migration status: active (transferred 1853314839, remaining 2514944), total 2114387968)
Sep 03 15:01:35 migration xbzrle cachesize: 67108864 transferred 423964993 pages 298173 cachemiss 331222 overflow 17668 deltacachemiss 850
Sep 03 15:01:36 migration status: active (transferred 1862231519, remaining 15454208), total 2114387968)
Sep 03 15:01:36 migration xbzrle cachesize: 67108864 transferred 428937200 pages 301153 cachemiss 331999 overflow 17854 deltacachemiss 777
Sep 03 15:01:36 migration status: active (transferred 1870584409, remaining 11419648), total 2114387968)
Sep 03 15:01:36 migration xbzrle cachesize: 67108864 transferred 431326236 pages 304655 cachemiss 333333 overflow 17976 deltacachemiss 1334
Sep 03 15:01:36 migration status: active (transferred 1878153329, remaining 4648960), total 2114387968)
Sep 03 15:01:36 migration xbzrle cachesize: 67108864 transferred 434057751 pages 307541 cachemiss 334375 overflow 18115 deltacachemiss 1042
Sep 03 15:01:37 migration status: active (transferred 1885289154, remaining 12533760), total 2114387968)
Sep 03 15:01:37 migration xbzrle cachesize: 67108864 transferred 438228048 pages 310420 cachemiss 334915 overflow 18299 deltacachemiss 540
Sep 03 15:01:37 migration status: active (transferred 1892622878, remaining 4374528), total 2114387968)
Sep 03 15:01:37 migration xbzrle cachesize: 67108864 transferred 441490323 pages 313985 cachemiss 335735 overflow 18473 deltacachemiss 820
Sep 03 15:01:37 migration status: active (transferred 1901073971, remaining 13205504), total 2114387968)
Sep 03 15:01:37 migration xbzrle cachesize: 67108864 transferred 446529428 pages 316687 cachemiss 336305 overflow 18736 deltacachemiss 570
Sep 03 15:01:38 migration status: active (transferred 1910878152, remaining 9048064), total 2114387968)
Sep 03 15:01:38 migration xbzrle cachesize: 67108864 transferred 451586319 pages 319720 cachemiss 337190 overflow 19010 deltacachemiss 885
Sep 03 15:01:38 migration status: active (transferred 1918738540, remaining 10661888), total 2114387968)
Sep 03 15:01:38 migration xbzrle cachesize: 67108864 transferred 455338404 pages 321664 cachemiss 337933 overflow 19270 deltacachemiss 743
Sep 03 15:01:38 migration status: active (transferred 1928827689, remaining 6860800), total 2114387968)
Sep 03 15:01:38 migration xbzrle cachesize: 67108864 transferred 460549198 pages 324277 cachemiss 338738 overflow 19656 deltacachemiss 805
Sep 03 15:01:38 migration status: active (transferred 1937151384, remaining 3428352), total 2114387968)
Sep 03 15:01:38 migration xbzrle cachesize: 67108864 transferred 465043115 pages 326494 cachemiss 339336 overflow 19993 deltacachemiss 598
Sep 03 15:01:39 migration status: active (transferred 1946239164, remaining 13590528), total 2114387968)
Sep 03 15:01:39 migration xbzrle cachesize: 67108864 transferred 469952951 pages 328931 cachemiss 339977 overflow 20372 deltacachemiss 641
Sep 03 15:01:39 migration status: active (transferred 1955868111, remaining 2822144), total 2114387968)
Sep 03 15:01:39 migration xbzrle cachesize: 67108864 transferred 474850991 pages 332609 cachemiss 340857 overflow 20647 deltacachemiss 880
Sep 03 15:01:39 migration status: active (transferred 1965033342, remaining 7884800), total 2114387968)
Sep 03 15:01:39 migration xbzrle cachesize: 67108864 transferred 479064122 pages 336578 cachemiss 341853 overflow 20860 deltacachemiss 996
Sep 03 15:01:40 migration status: active (transferred 1972991062, remaining 8335360), total 2114387968)
Sep 03 15:01:40 migration xbzrle cachesize: 67108864 transferred 482389235 pages 340369 cachemiss 342906 overflow 20938 deltacachemiss 1053
Sep 03 15:01:40 migration status: active (transferred 1978818556, remaining 10371072), total 2114387968)
Sep 03 15:01:40 migration xbzrle cachesize: 67108864 transferred 483760246 pages 344727 cachemiss 343955 overflow 20977 deltacachemiss 1049
Sep 03 15:01:40 migration status: active (transferred 1984832873, remaining 2367488), total 2114387968)
Sep 03 15:01:40 migration xbzrle cachesize: 67108864 transferred 485600711 pages 348240 cachemiss 344922 overflow 21029 deltacachemiss 967
Sep 03 15:01:41 migration status: active (transferred 1992114731, remaining 4120576), total 2114387968)
Sep 03 15:01:41 migration xbzrle cachesize: 67108864 transferred 489704053 pages 351282 cachemiss 345551 overflow 21176 deltacachemiss 629
Sep 03 15:01:41 migration status: active (transferred 2001071596, remaining 12619776), total 2114387968)
Sep 03 15:01:41 migration xbzrle cachesize: 67108864 transferred 495339032 pages 354218 cachemiss 346153 overflow 21385 deltacachemiss 602
Sep 03 15:01:41 migration status: active (transferred 2011152290, remaining 5206016), total 2114387968)
Sep 03 15:01:41 migration xbzrle cachesize: 67108864 transferred 501454775 pages 357298 cachemiss 346854 overflow 21652 deltacachemiss 701
Sep 03 15:01:42 migration status: active (transferred 2019787845, remaining 4804608), total 2114387968)
Sep 03 15:01:42 migration xbzrle cachesize: 67108864 transferred 505945161 pages 359691 cachemiss 347502 overflow 22016 deltacachemiss 648
Sep 03 15:01:42 migration status: active (transferred 2029872444, remaining 12754944), total 2114387968)
Sep 03 15:01:42 migration xbzrle cachesize: 67108864 transferred 510999852 pages 362419 cachemiss 348359 overflow 22387 deltacachemiss 857
Sep 03 15:01:42 migration status: active (transferred 2039963167, remaining 5341184), total 2114387968)
Sep 03 15:01:42 migration xbzrle cachesize: 67108864 transferred 516535788 pages 365431 cachemiss 349089 overflow 22769 deltacachemiss 730
Sep 03 15:01:42 migration status: active (transferred 2046790518, remaining 13049856), total 2114387968)
Sep 03 15:01:42 migration xbzrle cachesize: 67108864 transferred 519742235 pages 368455 cachemiss 349752 overflow 22990 deltacachemiss 663
Sep 03 15:01:43 migration status: active (transferred 2056576433, remaining 6127616), total 2114387968)
Sep 03 15:01:43 migration xbzrle cachesize: 67108864 transferred 524764472 pages 371518 cachemiss 350495 overflow 23410 deltacachemiss 743
Sep 03 15:01:43 migration status: active (transferred 2070030632, remaining 5545984), total 2114387968)
Sep 03 15:01:43 migration xbzrle cachesize: 67108864 transferred 532054161 pages 375458 cachemiss 351436 overflow 23974 deltacachemiss 941
Sep 03 15:01:43 migration status: active (transferred 2080122845, remaining 16842752), total 2114387968)
Sep 03 15:01:43 migration xbzrle cachesize: 67108864 transferred 537186091 pages 378300 cachemiss 352183 overflow 24438 deltacachemiss 747
Sep 03 15:01:44 migration status: active (transferred 2089596231, remaining 19959808), total 2114387968)
Sep 03 15:01:44 migration xbzrle cachesize: 67108864 transferred 541281406 pages 380898 cachemiss 353159 overflow 24775 deltacachemiss 976
Sep 03 15:01:44 migration status: active (transferred 2098744287, remaining 3334144), total 2114387968)
Sep 03 15:01:44 migration xbzrle cachesize: 67108864 transferred 544596639 pages 382825 cachemiss 354171 overflow 25187 deltacachemiss 1012
Sep 03 15:01:44 migration status: active (transferred 2107347747, remaining 8888320), total 2114387968)
Sep 03 15:01:44 migration xbzrle cachesize: 67108864 transferred 547735772 pages 384605 cachemiss 355136 overflow 25556 deltacachemiss 965
Sep 03 15:01:45 migration status: active (transferred 2117427470, remaining 6184960), total 2114387968)
Sep 03 15:01:45 migration xbzrle cachesize: 67108864 transferred 551515759 pages 386875 cachemiss 356245 overflow 25985 deltacachemiss 1109
Sep 03 15:01:45 migration status: active (transferred 2127522180, remaining 6643712), total 2114387968)
Sep 03 15:01:45 migration xbzrle cachesize: 67108864 transferred 555519519 pages 389206 cachemiss 357355 overflow 26362 deltacachemiss 1110
Sep 03 15:01:45 migration status: active (transferred 2137180181, remaining 6840320), total 2114387968)
Sep 03 15:01:45 migration xbzrle cachesize: 67108864 transferred 559197228 pages 391393 cachemiss 358357 overflow 26820 deltacachemiss 1002
Sep 03 15:01:46 migration status: active (transferred 2146653892, remaining 7704576), total 2114387968)
Sep 03 15:01:46 migration xbzrle cachesize: 67108864 transferred 563133130 pages 393677 cachemiss 359363 overflow 27166 deltacachemiss 1006
Sep 03 15:01:46 migration status: active (transferred 2156170786, remaining 8384512), total 2114387968)
Sep 03 15:01:46 migration xbzrle cachesize: 67108864 transferred 566870481 pages 395661 cachemiss 360401 overflow 27539 deltacachemiss 1038
Sep 03 15:01:46 migration status: active (transferred 2162116052, remaining 18784256), total 2114387968)
Sep 03 15:01:46 migration xbzrle cachesize: 67108864 transferred 569030821 pages 396971 cachemiss 361078 overflow 27786 deltacachemiss 677
Sep 03 15:01:47 migration status: active (transferred 2167440600, remaining 10747904), total 2114387968)
Sep 03 15:01:47 migration xbzrle cachesize: 67108864 transferred 570951584 pages 397932 cachemiss 361557 overflow 28138 deltacachemiss 479
Sep 03 15:01:47 migration status: active (transferred 2173189492, remaining 25628672), total 2114387968)
Sep 03 15:01:47 migration xbzrle cachesize: 67108864 transferred 572772376 pages 399193 cachemiss 362323 overflow 28331 deltacachemiss 766
Sep 03 15:01:47 migration status: active (transferred 2181582500, remaining 8200192), total 2114387968)
Sep 03 15:01:47 migration xbzrle cachesize: 67108864 transferred 575605975 pages 400618 cachemiss 363152 overflow 28859 deltacachemiss 829
Sep 03 15:01:47 migration status: active (transferred 2189847788, remaining 11202560), total 2114387968)
Sep 03 15:01:47 migration xbzrle cachesize: 67108864 transferred 578513648 pages 402362 cachemiss 364245 overflow 29074 deltacachemiss 1093
Sep 03 15:01:48 migration status: active (transferred 2195877255, remaining 14094336), total 2114387968)
Sep 03 15:01:48 migration xbzrle cachesize: 67108864 transferred 580246400 pages 404116 cachemiss 365082 overflow 29286 deltacachemiss 837
Sep 03 15:01:48 migration status: active (transferred 2202598243, remaining 12357632), total 2114387968)
Sep 03 15:01:48 migration xbzrle cachesize: 67108864 transferred 581462307 pages 407577 cachemiss 366385 overflow 29327 deltacachemiss 1303
Sep 03 15:01:48 migration status: active (transferred 2210798256, remaining 2859008), total 2114387968)
Sep 03 15:01:48 migration xbzrle cachesize: 67108864 transferred 583350325 pages 413084 cachemiss 367860 overflow 29393 deltacachemiss 1475
Sep 03 15:01:49 migration status: active (transferred 2217322581, remaining 7753728), total 2114387968)
Sep 03 15:01:49 migration xbzrle cachesize: 67108864 transferred 586159554 pages 415753 cachemiss 368500 overflow 29660 deltacachemiss 640
Sep 03 15:01:49 migration status: active (transferred 2222843364, remaining 10366976), total 2114387968)
Sep 03 15:01:49 migration xbzrle cachesize: 67108864 transferred 589009723 pages 417307 cachemiss 368910 overflow 29902 deltacachemiss 410
Sep 03 15:01:49 migration status: active (transferred 2229668707, remaining 12546048), total 2114387968)
Sep 03 15:01:49 migration xbzrle cachesize: 67108864 transferred 592545964 pages 419113 cachemiss 369404 overflow 30211 deltacachemiss 494
Sep 03 15:01:50 migration status: active (transferred 2238229988, remaining 13078528), total 2114387968)

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

* Re: [Qemu-devel] [PATCH 2/6] libqblock public type defines
  2012-09-03  9:18 ` [Qemu-devel] [PATCH 2/6] libqblock public type defines Wenchao Xia
@ 2012-09-03 13:13   ` Paolo Bonzini
  2012-09-04  2:00     ` Wenchao Xia
  2012-09-03 14:20   ` Eric Blake
  2012-09-03 19:31   ` Blue Swirl
  2 siblings, 1 reply; 46+ messages in thread
From: Paolo Bonzini @ 2012-09-03 13:13 UTC (permalink / raw)
  To: Wenchao Xia; +Cc: kwolf, stefanha, aliguori, eblake, qemu-devel

Il 03/09/2012 11:18, Wenchao Xia ha scritto:
> +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_t reserved[512];
> +};

Padding must be in the union not the struct.  For the fourth time.

Paolo

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

* Re: [Qemu-devel] [PATCH 1/6] libqblock APIs
  2012-09-03  9:18 ` [Qemu-devel] [PATCH 1/6] libqblock APIs Wenchao Xia
@ 2012-09-03 13:18   ` Paolo Bonzini
  2012-09-04  3:15     ` Wenchao Xia
  2012-09-03 13:56   ` Eric Blake
  2012-09-03 19:22   ` Blue Swirl
  2 siblings, 1 reply; 46+ messages in thread
From: Paolo Bonzini @ 2012-09-03 13:18 UTC (permalink / raw)
  To: Wenchao Xia; +Cc: kwolf, stefanha, aliguori, eblake, qemu-devel

Il 03/09/2012 11:18, Wenchao Xia ha scritto:
>   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.

Can you use GError instead?

>   3 QBlockInfoImageStatic. Now it is not folded with location and format.

What does "Static" mean?

Paolo

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

* Re: [Qemu-devel] [PATCH 4/6] libqblock internal used functions
  2012-09-03  9:18 ` [Qemu-devel] [PATCH 4/6] libqblock internal used functions Wenchao Xia
@ 2012-09-03 13:18   ` Paolo Bonzini
  2012-09-04  3:19     ` Wenchao Xia
  2012-09-03 14:28   ` Eric Blake
  1 sibling, 1 reply; 46+ messages in thread
From: Paolo Bonzini @ 2012-09-03 13:18 UTC (permalink / raw)
  To: Wenchao Xia; +Cc: kwolf, stefanha, aliguori, eblake, qemu-devel

Il 03/09/2012 11:18, Wenchao Xia ha scritto:
>   This patch contains internal helper codes.
> 
> Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
> ---
>  block.c                      |    2 +-
>  block.h                      |    1 +
>  libqblock/libqblock-helper.c |   92 ++++++++++++++++++++++++++++++++++++++++++
>  libqblock/libqblock-helper.h |   57 ++++++++++++++++++++++++++
>  4 files changed, 151 insertions(+), 1 deletions(-)
>  create mode 100644 libqblock/libqblock-helper.c
>  create mode 100644 libqblock/libqblock-helper.h
> 
> diff --git a/block.c b/block.c
> index 470bdcc..8b312f8 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-helper.c b/libqblock/libqblock-helper.c
> new file mode 100644
> index 0000000..f9e8ce9
> --- /dev/null
> +++ b/libqblock/libqblock-helper.c
> @@ -0,0 +1,92 @@
> +#include "libqblock-helper.h"
> +#include "libqblock-types.h"
> +#include "libqblock-error.h"
> +
> +const char *fmt2str(enum QBlockFormat fmt)
> +{
> +    const char *ret = NULL;
> +    switch (fmt) {
> +    case QB_FMT_COW:
> +        ret = "cow";
> +        break;
> +    case QB_FMT_QED:
> +        ret = "qed";
> +        break;
> +    case QB_FMT_QCOW:
> +        ret = "qcow";
> +        break;
> +    case QB_FMT_QCOW2:
> +        ret = "qcow2";
> +        break;
> +    case QB_FMT_RAW:
> +        ret = "raw";
> +        break;
> +    case QB_FMT_RBD:
> +        ret = "rbd";
> +        break;
> +    case QB_FMT_SHEEPDOG:
> +        ret = "sheepdog";
> +        break;
> +    case QB_FMT_VDI:
> +        ret = "vdi";
> +        break;
> +    case QB_FMT_VMDK:
> +        ret = "vmdk";
> +        break;
> +    case QB_FMT_VPC:
> +        ret = "vpc";
> +        break;
> +    default:
> +        break;
> +    }
> +    return ret;
> +}
> +
> +enum QBlockFormat str2fmt(const char *fmt)
> +{
> +    enum QBlockFormat ret = QB_FMT_NONE;
> +    if (0 == strcmp(fmt, "cow")) {
> +        ret = QB_FMT_COW;
> +    } else if (0 == strcmp(fmt, "qed")) {
> +        ret = QB_FMT_QED;
> +    } else if (0 == strcmp(fmt, "qcow")) {
> +        ret = QB_FMT_QCOW;
> +    } else if (0 == strcmp(fmt, "qcow2")) {
> +        ret = QB_FMT_QCOW2;
> +    } else if (0 == strcmp(fmt, "raw")) {
> +        ret = QB_FMT_RAW;
> +    } else if (0 == strcmp(fmt, "rbd")) {
> +        ret = QB_FMT_RBD;
> +    } else if (0 == strcmp(fmt, "sheepdog")) {
> +        ret = QB_FMT_SHEEPDOG;
> +    } else if (0 == strcmp(fmt, "vdi")) {
> +        ret = QB_FMT_VDI;
> +    } else if (0 == strcmp(fmt, "vmdk")) {
> +        ret = QB_FMT_VMDK;
> +    } else if (0 == strcmp(fmt, "vpc")) {
> +        ret = QB_FMT_VPC;
> +    }
> +    return ret;
> +}
> +
> +void set_broker_err(struct QBroker *broker, int err_ret,
> +                           const char *fmt, ...)
> +{
> +    va_list ap;
> +
> +    broker->err_ret = err_ret;
> +    if (err_ret == QB_ERR_INTERNAL_ERR) {
> +        broker->err_no = -errno;
> +    } else {
> +        broker->err_no = 0;
> +    }
> +
> +    va_start(ap, fmt);
> +    vsnprintf(broker->err_msg, sizeof(broker->err_msg), fmt, ap);
> +    va_end(ap);
> +}
> +
> +void set_broker_err_nomem(struct QBroker *broker)
> +{
> +    set_broker_err(broker, QB_ERR_MEM_ERR, "No Memory.");
> +}
> diff --git a/libqblock/libqblock-helper.h b/libqblock/libqblock-helper.h
> new file mode 100644
> index 0000000..4330472
> --- /dev/null
> +++ b/libqblock/libqblock-helper.h
> @@ -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.
> + *
> + */
> +
> +#ifndef LIBQBLOCK_HELPER
> +#define LIBQBLOCK_HELPER
> +
> +#include "block.h"
> +#include "block_int.h"
> +
> +#include "libqblock-types.h"
> +
> +/* this file contains helper function used internally. */
> +#define SECTOR_SIZE (512)
> +#define SECTOR_SIZE_MASK (0x01ff)
> +#define SECTOR_SIZE_BITS_NUM (9)
> +#define FUNC_FREE free
> +#define FUNC_MALLOC malloc
> +#define FUNC_CALLOC calloc
> +
> +#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;
> +};
> +
> +#define QB_ERR_STRING_SIZE (1024)
> +struct QBroker {
> +    /* last error */
> +    char err_msg[QB_ERR_STRING_SIZE];
> +    int err_ret; /* last error return of libqblock. */
> +    int err_no; /* 2nd level of error, errno what below reports */
> +};
> +
> +const char *fmt2str(enum QBlockFormat fmt);
> +enum QBlockFormat str2fmt(const char *fmt);
> +void set_broker_err(struct QBroker *broker, int err_ret,
> +                           const char *fmt, ...);
> +void set_broker_err_nomem(struct QBroker *broker);
> +#endif
> 

Please squash this into patch 1, there is no need to keep separate files.

Paolo

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

* Re: [Qemu-devel] [PATCH 1/6] libqblock APIs
  2012-09-03  9:18 ` [Qemu-devel] [PATCH 1/6] libqblock APIs Wenchao Xia
  2012-09-03 13:18   ` Paolo Bonzini
@ 2012-09-03 13:56   ` Eric Blake
  2012-09-03 14:05     ` Paolo Bonzini
  2012-09-04  6:42     ` Wenchao Xia
  2012-09-03 19:22   ` Blue Swirl
  2 siblings, 2 replies; 46+ messages in thread
From: Eric Blake @ 2012-09-03 13:56 UTC (permalink / raw)
  To: Wenchao Xia; +Cc: kwolf, pbonzini, aliguori, qemu-devel, stefanha

[-- Attachment #1: Type: text/plain, Size: 6275 bytes --]

On 09/03/2012 03:18 AM, Wenchao Xia wrote:
>   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 QBlockInfoImageStatic. Now it is not folded with location and format.
>   4 ABI was kept with reserved members.
> 
> structure, because it would cause caller more codes to find one member.

Commit message snafu?

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

Is this function safe to call more than once?  Even tighter, is it safe
to call this function simultaneously from multiple threads?

> +
> +/**
> + * qb_broker_new: allocate a new broker
> + *
> + * Broker is used to pass operation to libqblock, and got feed back from it.

s/got feed back/get feedback/

> + *
> + * Returns 0 on success, negative value on fail.

Is there any particular interpretation to this negative value, such as
negative errno constant, or always -1?

> +
> +/**
> + * qb_state_new: allocate a new QBloctState struct

s/Bloct/Block/

> + *
> + * Following qblock action were based on this struct

Didn't read well.  Did you mean:

Subsequent qblock actions will use this struct

> + *
> + * Returns 0 if succeed, negative value on fail.

Again, is there any particular meaning to which negative value is returned?

> +
> +/**
> + * qb_open: open a block object.
> + *
> + * return 0 on success, negative on fail.
> + *
> + * @broker: operation broker.
> + * @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, set NULL if you want auto discovery the format.

set to NULL if you want to auto-discover the format

Maybe also add a warning about the inherent security risks of attempting
format auto-discovery (any raw image must NOT be probed, as the raw
image can emulate any other format and cause qemu to chase down chains
where it should not).

> + * @flag: behavior control flags.

What flags are currently defined?

> + */
> +int qb_open(struct QBroker *broker,
> +            struct QBlockState *qbs,
> +            struct QBlockOptionLoc *loc,
> +            struct QBlockOptionFormat *fmt,
> +            int flag);
> +
> +/**
> + * qb_close: close a block object.
> + *
> + * qb_flush is automaticlly done inside.

s/automaticlly/automatically/

> +/**
> + * qb_create: create a block image or object.
> + *
> + * Note: Create operation would not open the image automatically.
> + *
> + * return negative on fail, 0 on success.
> + *
> + * @broker: operation broker.
> + * @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.

Again, what flags are defined?

> +
> +/* sync access */
> +/**
> + * qb_read: block sync read.
> + *
> + * return negative on fail, 0 on success.

Shouldn't this instead return the number of successfully read bytes, to
allow for short reads if offset exceeds end-of-file?  If so, should it
return ssize_t instead of int?

> + *
> + * @broker: operation broker.
> + * @qbs: pointer to struct QBlockState.
> + * @buf: buffer that receive the content.

s/receive/receives/

> + * @len: length to read.

Is there a magic length for reading the entire file in one go?

> + * @offset: offset in the block data.
> + */
> +int qb_read(struct QBroker *broker,
> +            struct QBlockState *qbs,
> +            const void *buf,
> +            size_t len,
> +            off_t offset);

You do realize that size_t and off_t are not necessarily the same width;
but I'm okay with limiting to size_t reads.

> +/**
> + * qb_write: block sync write.
> + *
> + * return negative on fail, 0 on success.

Again, this should probably return number of successfully written bytes,
as an ssize_t.

> + *
> + * @broker: operation broker.
> + * @qbs: pointer to struct QBlockState.
> + * @buf: buffer that receive the content.

s/receive/supplies/

> +/* advance image APIs */
> +/**
> + * qb_is_allocated: check if following sectors was allocated on the image.
> + *
> + * return negative on fail, 0 or 1 on success. 0 means unallocated, 1 means
> + *allocated.

Formatting is off.

> + *
> + * @broker: operation broker.
> + * @qbs: pointer to struct QBlockState.
> + * @sector_num: start sector number. If 'sector_num' is beyond the end of the
> + *disk image the return value is 0 and 'pnum' is set to 0.
> + * @nb_sectors: how many sector would be checked, it is the max value 'pnum'
> + *should be set to.  If nb_sectors goes beyond the end of the disk image it
> + *will be clamped.
> + * @pnum: pointer to receive how many sectors are allocated or unallocated.

This interface requires the user to know how big a sector is.  Would it
be any more convenient to the user to pass offsets, rather than sector
numbers; and/or have a function for converting between offsets and
sector numbers?

> + */
> +int qb_is_allocated(struct QBroker *broker,
> +                    struct QBlockState *qbs,
> +                    int64_t sector_num,
> +                    int nb_sectors,

Shouldn't nb_sectors be size_t?

> +                    int *pnum);

Exactly how does the *pnum argument work?  This interface looks like it
isn't fully thought out yet.  Either I want to know if a chunk of
sectors is allocated (I supply start and length of sectors to check),
regardless of how many sectors beyond that point are also allocated
(pnum makes no sense); or I want to know how many sectors are allocated
from a given point (I supply start, and the function returns length, so
nb_sectors makes no sense).  Either way, I think you are supplying too
many parameters for how I envision checking for allocated sectors.

-- 
Eric Blake   eblake@redhat.com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 617 bytes --]

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

* Re: [Qemu-devel] [PATCH 1/6] libqblock APIs
  2012-09-03 13:56   ` Eric Blake
@ 2012-09-03 14:05     ` Paolo Bonzini
  2012-09-04  7:05       ` Wenchao Xia
  2012-09-04  6:42     ` Wenchao Xia
  1 sibling, 1 reply; 46+ messages in thread
From: Paolo Bonzini @ 2012-09-03 14:05 UTC (permalink / raw)
  To: Eric Blake; +Cc: kwolf, stefanha, aliguori, Wenchao Xia, qemu-devel

Il 03/09/2012 15:56, Eric Blake ha scritto:
> Exactly how does the *pnum argument work?  This interface looks like it
> isn't fully thought out yet.  Either I want to know if a chunk of
> sectors is allocated (I supply start and length of sectors to check),
> regardless of how many sectors beyond that point are also allocated
> (pnum makes no sense);

pnum makes sense if the [start, start+length) range includes both
allocated and unallocated sectors.

> or I want to know how many sectors are allocated
> from a given point (I supply start, and the function returns length, so
> nb_sectors makes no sense).

This operation could be O(number of blocks in disk) worst case, so it
makes sense to provide nb_sectors as an upper bound.  nb_sectors is
typically dictated by the size of your buffer.

That said, QEMU's internal bdrv_is_allocated function does have one not
entirely appealing property: the block at start + *pnum might have the
same state as the block at start + *pnum - 1, even if *pnum < length.
We may want to work around this in libqblock, but we could also simply
document it.

Paolo

> Either way, I think you are supplying too
> many parameters for how I envision checking for allocated sectors.

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

* Re: [Qemu-devel] [PATCH 2/6] libqblock public type defines
  2012-09-03  9:18 ` [Qemu-devel] [PATCH 2/6] libqblock public type defines Wenchao Xia
  2012-09-03 13:13   ` Paolo Bonzini
@ 2012-09-03 14:20   ` Eric Blake
  2012-09-04  7:10     ` Wenchao Xia
  2012-09-03 19:31   ` Blue Swirl
  2 siblings, 1 reply; 46+ messages in thread
From: Eric Blake @ 2012-09-03 14:20 UTC (permalink / raw)
  To: Wenchao Xia; +Cc: kwolf, pbonzini, aliguori, qemu-devel, stefanha

[-- Attachment #1: Type: text/plain, Size: 1717 bytes --]

On 09/03/2012 03:18 AM, Wenchao Xia wrote:
>   This patch contains public type and defines used in APIs.
> 
> Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
> ---
>  libqblock/libqblock-types.h |  228 +++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 228 insertions(+), 0 deletions(-)
>  create mode 100644 libqblock/libqblock-types.h
> 
> diff --git a/libqblock/libqblock-types.h b/libqblock/libqblock-types.h
> new file mode 100644
> index 0000000..3389bda
> --- /dev/null
> +++ b/libqblock/libqblock-types.h
> @@ -0,0 +1,228 @@
> +#ifndef LIBQBLOCK_TYPES_H

Missing a copyright header.  Shame.

> +#define LIBQBLOCK_TYPES_H
> +
> +#include <stdio.h>
> +#include <stdint.h>
> +#include <stdlib.h>
> +#include <stdbool.h>

I see use of stdint (uint8_t) and stdbool (bool), but isn't
<sys/types.h> better than <stdio.h> and <stdlib.h> for size_t?

> +
> +/**
> + * QBlockInfoImageStatic: information about the block image.
> + *
> + * @loc: location info.
> + * @fmt_type: format type.
> + * @virt_size: virtual size in bytes.
> + * @backing_loc: backing file location, its type is QB_PROT_NONE if not exist.
> + * @allocated_size: allocated size in bytes, negative if not available.

Reading this...

> + * @encrypt: encrypt flag.
> + */
> +struct QBlockInfoImageStatic {
> +    struct QBlockOptionLoc loc;
> +    enum QBlockFormat fmt_type;
> +    size_t virt_size;
> +    /* advance info */
> +    struct QBlockOptionLoc backing_loc;
> +    size_t allocated_size;

...negative is not possible for size_t.  Did you mean ssize_t?

-- 
Eric Blake   eblake@redhat.com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 617 bytes --]

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

* Re: [Qemu-devel] [PATCH 3/6] libqblock error handling
  2012-09-03  9:18 ` [Qemu-devel] [PATCH 3/6] libqblock error handling Wenchao Xia
@ 2012-09-03 14:22   ` Eric Blake
  2012-09-04  7:12     ` Wenchao Xia
  2012-09-10  8:20     ` Wenchao Xia
  0 siblings, 2 replies; 46+ messages in thread
From: Eric Blake @ 2012-09-03 14:22 UTC (permalink / raw)
  To: Wenchao Xia; +Cc: kwolf, pbonzini, aliguori, qemu-devel, stefanha

[-- Attachment #1: Type: text/plain, Size: 1810 bytes --]

On 09/03/2012 03:18 AM, Wenchao Xia wrote:
>   This patch contains error handling APIs.
> 
> Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
> ---
>  libqblock/libqblock-error.c |   44 +++++++++++++++++++++++++++++++++++++++++++
>  libqblock/libqblock-error.h |   34 +++++++++++++++++++++++++++++++++
>  2 files changed, 78 insertions(+), 0 deletions(-)
>  create mode 100644 libqblock/libqblock-error.c
>  create mode 100644 libqblock/libqblock-error.h
> 
> diff --git a/libqblock/libqblock-error.c b/libqblock/libqblock-error.c
> new file mode 100644
> index 0000000..28d1d77
> --- /dev/null
> +++ b/libqblock/libqblock-error.c
> @@ -0,0 +1,44 @@
> +#include "libqblock-error.h"

No copyright.  Shame.

> +++ b/libqblock/libqblock-error.h
> @@ -0,0 +1,34 @@
> +#ifndef LIBQBLOCK_ERROR

No copyright.  Shame.

> +#define LIBQBLOCK_ERROR
> +
> +#include "libqblock-types.h"
> +
> +#define QB_ERR_MEM_ERR (-1)
> +#define QB_ERR_INTERNAL_ERR (-2)
> +#define QB_ERR_INVALID_PARAM (-3)
> +#define QB_ERR_BLOCK_OUT_OF_RANGE (-100)

Would an enum make more sense than #defines?

> +
> +/* error handling */
> +/**
> + * qb_error_get_human_str: get human readable erro string.

s/erro/error/

> + *
> + * return a human readable string.
> + *
> + * @broker: operation broker, must be valid.
> + * @buf: buf to receive the string.
> + * @buf_size: the size of the string buf.
> + */
> +void qb_error_get_human_str(struct QBroker *broker,
> +                            char *buf, int buf_size);

What happens if buf_size is too small to receive the entire error
message?  Should this function return int, with negative value on input
error?

-- 
Eric Blake   eblake@redhat.com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 617 bytes --]

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

* Re: [Qemu-devel] [PATCH 4/6] libqblock internal used functions
  2012-09-03  9:18 ` [Qemu-devel] [PATCH 4/6] libqblock internal used functions Wenchao Xia
  2012-09-03 13:18   ` Paolo Bonzini
@ 2012-09-03 14:28   ` Eric Blake
  2012-09-03 15:18     ` Paolo Bonzini
  1 sibling, 1 reply; 46+ messages in thread
From: Eric Blake @ 2012-09-03 14:28 UTC (permalink / raw)
  To: Wenchao Xia; +Cc: kwolf, pbonzini, aliguori, qemu-devel, stefanha

[-- Attachment #1: Type: text/plain, Size: 2177 bytes --]

On 09/03/2012 03:18 AM, Wenchao Xia wrote:
>   This patch contains internal helper codes.
> 
> Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
> ---
>  block.c                      |    2 +-
>  block.h                      |    1 +
>  libqblock/libqblock-helper.c |   92 ++++++++++++++++++++++++++++++++++++++++++
>  libqblock/libqblock-helper.h |   57 ++++++++++++++++++++++++++
>  4 files changed, 151 insertions(+), 1 deletions(-)
>  create mode 100644 libqblock/libqblock-helper.c
>  create mode 100644 libqblock/libqblock-helper.h
> 

> +++ b/libqblock/libqblock-helper.c
> @@ -0,0 +1,92 @@
> +#include "libqblock-helper.h"

No copyright.  Shame.  I'll quit pointing it out for the rest of the series.

> +++ b/libqblock/libqblock-helper.h

> +
> +/* this file contains helper function used internally. */
> +#define SECTOR_SIZE (512)

Hard-coding this feels wrong, in this day and age of disks with 4096
sectors.  Why isn't this a per-image property?

> +#define SECTOR_SIZE_MASK (0x01ff)
> +#define SECTOR_SIZE_BITS_NUM (9)

and these computed from a dynamic per-image sector size?

> +#define FUNC_FREE free
> +#define FUNC_MALLOC malloc
> +#define FUNC_CALLOC calloc

Is libqblock-helper.h intended to be installed and included in client
applications, or is it internal only?  If clients can ever use this
header, then you need to avoid namespace violations, by using naming
such as QB_SECTOR_SIZE, QB_FUNC_FREE, and so forth.

> +
> +const char *fmt2str(enum QBlockFormat fmt);
> +enum QBlockFormat str2fmt(const char *fmt);

Even if this header is not intended for clients, you STILL need to avoid
namespace pollution, by either ensuring that your library marks
visibility annotations to avoid exporting symbols outside of the public
namespace, or by renaming even your internal functions to comply with
the namespace.  In other words, stomping on the name 'fmt2str' and
'str2fmt' as an external function name is just too likely to clash with
an arbitrary client linking against your library.

-- 
Eric Blake   eblake@redhat.com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 617 bytes --]

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

* Re: [Qemu-devel] [PATCH 4/6] libqblock internal used functions
  2012-09-03 14:28   ` Eric Blake
@ 2012-09-03 15:18     ` Paolo Bonzini
  2012-09-04  7:15       ` Wenchao Xia
  0 siblings, 1 reply; 46+ messages in thread
From: Paolo Bonzini @ 2012-09-03 15:18 UTC (permalink / raw)
  To: Eric Blake; +Cc: kwolf, stefanha, aliguori, Wenchao Xia, qemu-devel

Il 03/09/2012 16:28, Eric Blake ha scritto:
>> > +/* this file contains helper function used internally. */
>> > +#define SECTOR_SIZE (512)
> Hard-coding this feels wrong, in this day and age of disks with 4096
> sectors.  Why isn't this a per-image property?

In this day and age of disks with 4096 sectors, Linux does not provide a
way to query the required alignment for O_DIRECT...

Paolo

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

* Re: [Qemu-devel] [PATCH 1/6] libqblock APIs
  2012-09-03  9:18 ` [Qemu-devel] [PATCH 1/6] libqblock APIs Wenchao Xia
  2012-09-03 13:18   ` Paolo Bonzini
  2012-09-03 13:56   ` Eric Blake
@ 2012-09-03 19:22   ` Blue Swirl
  2 siblings, 0 replies; 46+ messages in thread
From: Blue Swirl @ 2012-09-03 19:22 UTC (permalink / raw)
  To: Wenchao Xia; +Cc: kwolf, aliguori, stefanha, qemu-devel, pbonzini, eblake

On Mon, Sep 3, 2012 at 9:18 AM, Wenchao Xia <xiawenc@linux.vnet.ibm.com> wrote:
>   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 QBlockInfoImageStatic. Now it is not folded with location and format.
>   4 ABI was kept with reserved members.
>
> structure, because it would cause caller more codes to find one member.
>
> Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
> ---
>  libqblock/libqblock.c |  859 +++++++++++++++++++++++++++++++++++++++++++++++++
>  libqblock/libqblock.h |  251 ++++++++++++++
>  2 files changed, 1110 insertions(+), 0 deletions(-)
>  create mode 100644 libqblock/libqblock.c
>  create mode 100644 libqblock/libqblock.h
>
> diff --git a/libqblock/libqblock.c b/libqblock/libqblock.c
> new file mode 100644
> index 0000000..3983802
> --- /dev/null
> +++ b/libqblock/libqblock.c
> @@ -0,0 +1,859 @@
> +/*
> + * 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-helper.h"
> +
> +#include "qemu-aio.h"
> +
> +void libqblock_init(void)
> +{
> +    bdrv_init();
> +    qemu_init_main_loop();
> +}
> +
> +int qb_broker_new(struct QBroker **broker)
> +{
> +    *broker = FUNC_CALLOC(1, sizeof(struct QBroker));
> +    if (*broker == NULL) {
> +        return QB_ERR_MEM_ERR;
> +    }
> +    return 0;
> +}
> +
> +void qb_broker_delete(struct QBroker **broker)
> +{
> +    CLEAN_FREE(*broker);
> +    return;
> +}
> +
> +int qb_state_new(struct QBroker *broker,
> +                 struct QBlockState **qbs)
> +{
> +    *qbs = FUNC_CALLOC(1, sizeof(struct QBlockState));
> +    if (*qbs == NULL) {
> +        set_broker_err_nomem(broker);
> +        return broker->err_ret;
> +    }
> +    (*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(struct QBroker *broker,
> +                     struct QBlockState **qbs)
> +{
> +    CLEAN_FREE((*qbs)->filename);
> +    if ((*qbs)->bdrvs != NULL) {
> +        bdrv_delete((*qbs)->bdrvs);
> +        (*qbs)->bdrvs = NULL;
> +    }
> +    CLEAN_FREE(*qbs);
> +    return;
> +}
> +
> +int qb_ol_new(struct QBroker *broker,
> +              struct QBlockOptionLoc **op)
> +{
> +    *op = FUNC_CALLOC(1, sizeof(struct QBlockOptionLoc));
> +    if (*op == NULL) {
> +        set_broker_err_nomem(broker);
> +        return broker->err_ret;
> +    }
> +    return 0;
> +}
> +
> +void qb_ol_delete(struct QBroker *broker,
> +                  struct QBlockOptionLoc **op)
> +{
> +    CLEAN_FREE(*op);
> +}
> +
> +int qb_of_new(struct QBroker *broker,
> +              struct QBlockOptionFormat **op)
> +{
> +    *op = FUNC_CALLOC(1, sizeof(struct QBlockOptionFormat));
> +    if (*op == NULL) {
> +        set_broker_err_nomem(broker);
> +        return broker->err_ret;
> +    }
> +    return 0;
> +}
> +
> +void qb_of_delete(struct QBroker *broker,
> +                  struct QBlockOptionFormat **op)
> +{
> +    CLEAN_FREE(*op);
> +}
> +
> +/* return 0 if every thing is fine */
> +static int loc_check_params(struct QBroker *broker,
> +                            struct QBlockOptionLoc *loc)
> +{
> +    broker->err_ret = 0;
> +
> +    switch (loc->prot_type) {
> +    case QB_PROTO_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(struct QBroker *broker,
> +                        struct QBlockOptionLoc *loc,
> +                        char **filename)
> +{
> +    broker->err_ret = 0;
> +
> +    if (*filename != NULL) {
> +        CLEAN_FREE(*filename);
> +    }
> +    switch (loc->prot_type) {
> +    case QB_PROTO_FILE:
> +        *filename = strdup(loc->prot_op.o_file.filename);
> +        if (*filename == NULL) {
> +            set_broker_err_nomem(broker);
> +        }
> +        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(struct QBroker *broker,
> +                        struct QBlockOptionLoc *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 supportted now.",

supported

> +                     filename);
> +        goto out;
> +    }
> +
> +    loc->prot_type = QB_PROTO_FILE;
> +    switch (loc->prot_type) {
> +    case QB_PROTO_FILE:
> +        loc->prot_op.o_file.filename = strdup(filename);
> +        if (loc->prot_op.o_file.filename == NULL) {
> +            set_broker_err_nomem(broker);
> +            goto out;
> +        }
> +        break;
> +    default:
> +        break;
> +    }
> +
> + out:
> +    return broker->err_ret;
> +}
> +
> +/* return 0 if OK, or qblock error number */
> +static int set_backing_file_options(struct QBroker *broker,
> +                                    QEMUOptionParameter *param,
> +                                    struct QBlockOptionLoc *loc,
> +                                    enum QBlockFormat *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 */
> +    if (ret == QB_ERR_MEM_ERR) {
> +        goto out;
> +    }
> +    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 = fmt2str(*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(struct QBroker *broker,
> +              struct QBlockState *qbs,
> +              struct QBlockOptionLoc *loc,
> +              struct QBlockOptionFormat *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;
> +    struct QBlockOption_fmt_cow *o_cow = NULL;
> +    struct QBlockOption_fmt_qed *o_qed = NULL;
> +    struct QBlockOption_fmt_qcow *o_qcow = NULL;
> +    struct QBlockOption_fmt_qcow2 *o_qcow2 = NULL;
> +    struct QBlockOption_fmt_raw *o_raw = NULL;
> +    struct QBlockOption_fmt_rbd *o_rbd = NULL;
> +    struct QBlockOption_fmt_sheepdog *o_sd = NULL;
> +    struct QBlockOption_fmt_vdi *o_vdi = NULL;
> +    struct QBlockOption_fmt_vmdk *o_vmdk = NULL;
> +    struct QBlockOption_fmt_vpc *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 = fmt2str(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:
> +        assert(false);
> +        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 *= 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(struct QBroker *broker,
> +            struct QBlockState *qbs,
> +            struct QBlockOptionLoc *loc,
> +            struct QBlockOptionFormat *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 = fmt2str(fmt->fmt_type);
> +    }
> +
> +    if (fmtstr != NULL) {
> +        bd = bdrv_find_format(fmtstr);
> +        assert(bd != NULL);
> +    }
> +
> +    /* do real openning */
> +    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 = strdup(filename);
> +    if (qbs->filename == NULL) {
> +        set_broker_err_nomem(broker);
> +        ret = broker->err_ret;
> +        bdrv_close(bs);
> +        goto out;
> +    }
> +
> + out:
> +    FUNC_FREE(filename);
> +    return ret;
> +}
> +
> +void qb_close(struct QBroker *broker,
> +              struct QBlockState *qbs)
> +{
> +    BlockDriverState *bs;
> +
> +    bs = qbs->bdrvs;
> +
> +    if (qbs->filename != NULL) {
> +        CLEAN_FREE(qbs->filename);
> +        bdrv_close(bs);
> +    }
> +    return;
> +}
> +
> +int qb_read(struct QBroker *broker,
> +            struct QBlockState *qbs,
> +            const void *buf,

We write to 'buf', it can't be const.

> +            size_t len,
> +            off_t offset)
> +{
> +    int bd_ret;
> +    BlockDriverState *bs;
> +
> +    broker->err_ret = 0;
> +    bs = qbs->bdrvs;
> +
> +    assert((len & SECTOR_SIZE_MASK) == 0);
> +    assert((offset & SECTOR_SIZE_MASK) == 0);
> +    bd_ret = bdrv_read(bs, offset >> SECTOR_SIZE_BITS_NUM,
> +                       (uint8_t *)buf, len >> SECTOR_SIZE_BITS_NUM);

With 'const' removed, I think the cast can be omitted.

> +    if (bd_ret < 0) {
> +        if (bd_ret == -EIO) {
> +            set_broker_err(broker, QB_ERR_INTERNAL_ERR,
> +                           "Generic I/O error.");
> +        } else if (bd_ret == -ENOMEDIUM) {
> +            set_broker_err(broker, QB_ERR_INTERNAL_ERR,
> +                           "No meida inserted.");
> +        } else if (bd_ret == -EINVAL) {
> +            set_broker_err(broker, QB_ERR_INTERNAL_ERR,
> +                          "Sector was not correct.");
> +        } else {
> +            set_broker_err(broker, QB_ERR_INTERNAL_ERR,
> +                          "Internal error.");
> +        }
> +    }
> +    return broker->err_ret;
> +}
> +
> +int qb_write(struct QBroker *broker,
> +            struct QBlockState *qbs,
> +            const void *buf,
> +            size_t len,
> +            off_t offset)
> +{
> +    int bd_ret;
> +    BlockDriverState *bs;
> +
> +    broker->err_ret = 0;
> +    bs = qbs->bdrvs;
> +
> +    assert((len & SECTOR_SIZE_MASK) == 0);
> +    assert((offset & SECTOR_SIZE_MASK) == 0);
> +    bd_ret = bdrv_write(bs, offset >> SECTOR_SIZE_BITS_NUM,
> +                       (uint8_t *)buf, len >> SECTOR_SIZE_BITS_NUM);

Also this cast seems useless.

> +    if (bd_ret < 0) {
> +        if (bd_ret == -EIO) {
> +            set_broker_err(broker, QB_ERR_INTERNAL_ERR,
> +                           "Generic I/O error.");
> +        } else if (bd_ret == -ENOMEDIUM) {
> +            set_broker_err(broker, QB_ERR_INTERNAL_ERR,
> +                           "No meida inserted.");
> +        } else if (bd_ret == -EINVAL) {
> +            set_broker_err(broker, QB_ERR_INTERNAL_ERR,
> +                          "Sector was not correct.");
> +        } else {
> +            set_broker_err(broker, QB_ERR_INTERNAL_ERR,
> +                          "Internal error.");
> +        }
> +    }
> +    return broker->err_ret;
> +}
> +
> +int qb_flush(struct QBroker *broker,
> +             struct 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_is_allocated(struct QBroker *broker,
> +                    struct QBlockState *qbs,
> +                    int64_t sector_num,
> +                    int nb_sectors,
> +                    int *pnum)
> +{
> +    int ret;
> +    BlockDriverState *bs;
> +
> +    broker->err_ret = 0;
> +    bs = qbs->bdrvs;
> +
> +    if (qbs->filename == NULL) {
> +        set_broker_err(broker, QB_ERR_INVALID_PARAM,
> +                       "Image was not opened first.");
> +        ret = broker->err_ret;
> +        goto out;
> +    }
> +
> +    ret = bdrv_is_allocated(bs, sector_num, nb_sectors, pnum);
> +
> + out:
> +    return ret;
> +}
> +
> +int qb_info_image_static_get(struct QBroker *broker,
> +                             struct QBlockState *qbs,
> +                             struct QBlockInfoImageStatic **info)
> +{
> +    int ret = 0;
> +    BlockDriverState *bs;
> +    struct QBlockInfoImageStatic *info_tmp;
> +    const char *fmt_str;
> +    size_t total_sectors;
> +    char backing_filename[1024];
> +
> +    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(struct QBlockInfoImageStatic));
> +    if (info_tmp == NULL) {
> +        set_broker_err_nomem(broker);
> +        ret = broker->err_ret;
> +        goto out;
> +    }
> +
> +    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_type = str2fmt(fmt_str);
> +
> +    bdrv_get_geometry(bs, &total_sectors);
> +    info_tmp->virt_size = total_sectors * SECTOR_SIZE;
> +
> +    info_tmp->allocated_size = bdrv_get_allocated_file_size(bs);
> +    info_tmp->encrypt = bdrv_is_encrypted(bs);
> +
> +    bdrv_get_full_backing_filename(bs, backing_filename,
> +                                   sizeof(backing_filename));
> +    if (backing_filename[0] != '\0') {
> +        ret = filename2loc(broker,
> +                           &(info_tmp->backing_loc),
> +                           backing_filename);
> +        if (ret < 0) {
> +            goto free;
> +        }
> +    }
> +
> +    *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(struct QBlockOptionLoc *loc)
> +{
> +    switch (loc->prot_type) {
> +    case QB_PROTO_FILE:
> +        CLEAN_FREE(loc->prot_op.o_file.filename);
> +        break;
> +    default:
> +        break;
> +    }
> +}
> +
> +void qb_info_image_static_delete(struct QBroker *broker,
> +                                 struct QBlockInfoImageStatic **info)
> +{
> +    loc_free(&(*info)->loc);
> +    loc_free(&(*info)->backing_loc);
> +
> +    CLEAN_FREE(*info);
> +}
> diff --git a/libqblock/libqblock.h b/libqblock/libqblock.h
> new file mode 100644
> index 0000000..e64e1fd
> --- /dev/null
> +++ b/libqblock/libqblock.h
> @@ -0,0 +1,251 @@
> +/*
> + * 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"
> +
> +
> +/**
> + * libqblock_init: Initialize the library
> + */
> +void libqblock_init(void);
> +
> +/**
> + * qb_broker_new: allocate a new broker
> + *
> + * Broker is used to pass operation to libqblock, and got feed back from it.
> + *
> + * Returns 0 on success, negative value on fail.
> + *
> + * @broker: used to receive the created struct.
> + */
> +int qb_broker_new(struct QBroker **broker);
> +
> +/**
> + * qb_broker_delete: delete broker
> + *
> + * Broker will be freed and set to NULL.
> + *
> + * @broker: operation broker to be deleted.
> + */
> +void qb_broker_delete(struct QBroker **broker);
> +
> +/**
> + * qb_state_new: allocate a new QBloctState struct
> + *
> + * Following qblock action were based on this struct
> + *
> + * Returns 0 if succeed, negative value on fail.
> + *
> + * @broker: operation broker.
> + * @qbs: used to receive the created struct.
> + */
> +int qb_state_new(struct QBroker *broker,
> +                 struct QBlockState **qbs);
> +
> +/**
> + * qb_state_delete: free a QBloctState struct
> + *
> + * if it is opened, a qb_close must be called before free.
> + *
> + * @broker: operation broker.
> + * @qbs: pointer to the struct's pointer.
> + */
> +void qb_state_delete(struct QBroker *broker,
> +                     struct QBlockState **qbs);
> +
> +/**
> + * qb_ol_new: create a new struct QBlockOptionLoc.
> + *
> + * return 0 on success, negative on fail.
> + *
> + * @broker: operation broker.
> + * @op: pointer to receive the new created one.
> + */
> +int qb_ol_new(struct QBroker *broker,
> +              struct QBlockOptionLoc **op);
> +
> +/**
> + * qb_ol_delete: free a struct QBlockOptionLoc.
> + *
> + * @broker: operation broker.
> + * @op: pointer to the object, *op would be set to NULL.
> + */
> +void qb_ol_delete(struct QBroker *broker,
> +                  struct QBlockOptionLoc **op);
> +
> +/**
> + * qb_of_new: create a new QBlockOptionFormat structure.
> + *
> + * return 0 on success, negative on fail.
> + *
> + * @broker: operation broker.
> + * @op: pointer that will receive created struct.
> + */
> +int qb_of_new(struct QBroker *broker,
> +              struct QBlockOptionFormat **op);
> +
> +/**
> + * qb_of_delete: free QBlockOptionFormat structure.
> + *
> + * @broker: operation broker.
> + * @op: pointer to the struct, *op would be set to NULL.
> + */
> +void qb_of_delete(struct QBroker *broker,
> +                  struct QBlockOptionFormat **op);
> +
> +
> +/**
> + * qb_open: open a block object.
> + *
> + * return 0 on success, negative on fail.
> + *
> + * @broker: operation broker.
> + * @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, set NULL if you want auto discovery the format.
> + * @flag: behavior control flags.
> + */
> +int qb_open(struct QBroker *broker,
> +            struct QBlockState *qbs,
> +            struct QBlockOptionLoc *loc,
> +            struct QBlockOptionFormat *fmt,
> +            int flag);
> +
> +/**
> + * qb_close: close a block object.
> + *
> + * qb_flush is automaticlly done inside.
> + *
> + * @broker: operation broker.
> + * @qbs: pointer to struct QBlockState.
> + */
> +void qb_close(struct QBroker *broker,
> +              struct QBlockState *qbs);
> +
> +/**
> + * qb_create: create a block image or object.
> + *
> + * Note: Create operation would not open the image automatically.
> + *
> + * return negative on fail, 0 on success.
> + *
> + * @broker: operation broker.
> + * @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 QBroker *broker,
> +              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.
> + *
> + * @broker: operation broker.
> + * @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 QBroker *broker,
> +            struct QBlockState *qbs,
> +            const void *buf,
> +            size_t len,
> +            off_t offset);
> +/**
> + * qb_write: block sync write.
> + *
> + * return negative on fail, 0 on success.
> + *
> + * @broker: operation broker.
> + * @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 QBroker *broker,
> +             struct QBlockState *qbs,
> +             const void *buf,
> +             size_t len,
> +             off_t offset);
> +
> +/**
> + * qb_flush: block sync flush.
> + *
> + * return negative on fail, 0 on success.
> + *
> + * @broker: operation broker.
> + * @qbs: pointer to struct QBlockState.
> + */
> +int qb_flush(struct QBroker *broker,
> +             struct QBlockState *qbs);
> +
> +
> +/* advance image APIs */
> +/**
> + * qb_is_allocated: check if following sectors was allocated on the image.
> + *
> + * return negative on fail, 0 or 1 on success. 0 means unallocated, 1 means
> + *allocated.
> + *
> + * @broker: operation broker.
> + * @qbs: pointer to struct QBlockState.
> + * @sector_num: start sector number. If 'sector_num' is beyond the end of the
> + *disk image the return value is 0 and 'pnum' is set to 0.
> + * @nb_sectors: how many sector would be checked, it is the max value 'pnum'
> + *should be set to.  If nb_sectors goes beyond the end of the disk image it
> + *will be clamped.
> + * @pnum: pointer to receive how many sectors are allocated or unallocated.
> + */
> +int qb_is_allocated(struct QBroker *broker,
> +                    struct QBlockState *qbs,
> +                    int64_t sector_num,
> +                    int nb_sectors,
> +                    int *pnum);
> +
> +/* image information */
> +/**
> + * qb_get_image_info: get image info.
> + *
> + * return negative on fail, 0 on success.
> + *
> + * @broker: operation broker.
> + * @qbs: pointer to struct QBlockState.
> + * @info: pointer that would receive the information.
> + */
> +int qb_info_image_static_get(struct QBroker *broker,
> +                             struct QBlockState *qbs,
> +                             struct QBlockInfoImageStatic **info);
> +
> +/**
> + * qb_delete_image_info: free image info.
> + *
> + * @broker: operation broker.
> + * @info: pointer to the information struct.
> + */
> +void qb_info_image_static_delete(struct QBroker *broker,
> +                                 struct QBlockInfoImageStatic **info);
> +
> +#endif
> --
> 1.7.1
>
>
>

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

* Re: [Qemu-devel] [PATCH 5/6] libqblock test example
  2012-09-03  9:18 ` [Qemu-devel] [PATCH 5/6] libqblock test example Wenchao Xia
@ 2012-09-03 19:27   ` Blue Swirl
  0 siblings, 0 replies; 46+ messages in thread
From: Blue Swirl @ 2012-09-03 19:27 UTC (permalink / raw)
  To: Wenchao Xia; +Cc: kwolf, aliguori, stefanha, qemu-devel, pbonzini, eblake

On Mon, Sep 3, 2012 at 9:18 AM, Wenchao Xia <xiawenc@linux.vnet.ibm.com> wrote:
>   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 |  219 ++++++++++++++++++++++++++++++++++++++
>  1 files changed, 219 insertions(+), 0 deletions(-)
>  create mode 100644 tests/libqblock/libqblock-test.c
>
> diff --git a/tests/libqblock/libqblock-test.c b/tests/libqblock/libqblock-test.c
> new file mode 100644
> index 0000000..9a1eac5
> --- /dev/null
> +++ b/tests/libqblock/libqblock-test.c
> @@ -0,0 +1,219 @@
> +#include <stdarg.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +#include <inttypes.h>
> +#include <string.h>
> +
> +#include "libqblock.h"
> +
> +static unsigned char buf_r[1024];
> +static unsigned char buf_w[1024] = {4, 0, 0, 2};
> +
> +struct verify_data {

VerifyData

> +    unsigned char *buf_r;
> +    unsigned char *buf_w;
> +    int len;
> +};
> +
> +static void print_loc(struct QBlockOptionLoc *loc)
> +{
> +    switch (loc->prot_type) {
> +    case QB_PROTO_NONE:
> +        printf("protocol type [none].");
> +        break;
> +    case QB_PROTO_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(struct QBlockInfoImageStatic *info)
> +{
> +    printf("=======image location:\n");
> +    print_loc(&info->loc);
> +    printf("\nvirtual_size %" PRId64 ", format type %d,",
> +           info->virt_size, info->fmt_type);
> +    printf("allocated size %" PRId64 ", encrypt %d,",
> +           info->allocated_size, info->encrypt);
> +    printf("\nbacking image location:\n");
> +    print_loc(&info->backing_loc);
> +    printf("\n");
> +}
> +
> +static void test_check(struct verify_data *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)
> +{
> +    char *filename1, *filename2;
> +    struct QBroker *broker = NULL;
> +    struct QBlockState *qbs = NULL;
> +    struct QBlockOptionLoc *ol = NULL;
> +    struct QBlockOptionFormat *of = NULL;
> +    struct QBlockInfoImageStatic *info_st = NULL;
> +    int ret, flag;
> +    int test_offset = 0;
> +    int test_len = 512;
> +    struct verify_data vdata;
> +    char err_str[1024];
> +
> +    vdata.buf_r = buf_r;
> +    vdata.buf_w = buf_w;
> +    vdata.len = test_len;
> +
> +    filename1 = (char *)"./qemu_image1";
> +    filename2 = (char *)"./qemu_image2";

The casts remove 'const' qualifier, how can that be safe?

> +    printf("qemu test, filename1 is %s, filename2 is %s.\n",
> +                                       filename1, filename2);
> +
> +    libqblock_init();
> +
> +    ret = qb_broker_new(&broker);
> +    if (ret < 0) {
> +        goto free;
> +    }
> +
> +    ret = qb_state_new(broker, &qbs);
> +    if (ret < 0) {
> +        goto free;
> +    }
> +
> +    ret = qb_ol_new(broker, &ol);
> +    if (ret < 0) {
> +        goto free;
> +    }
> +
> +    ret = qb_of_new(broker, &of);
> +    if (ret < 0) {
> +        goto free;
> +    }
> +
> +    /* create a new image */
> +
> +    ol->prot_type = QB_PROTO_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_PROTO_FILE;
> +    ol->prot_op.o_file.filename = filename1;
> +    of->fmt_type = QB_FMT_QCOW2;
> +    of->fmt_op.o_qcow2.backing_loc.prot_type = QB_PROTO_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_PROTO_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->backing_loc.prot_type == QB_FMT_NONE) {
> +            break;
> +        }
> +        *ol = info_st->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_PROTO_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[24] = 3;
> +    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_ol_delete(broker, &ol);
> +    }
> +    if (of != NULL) {
> +        qb_of_delete(broker, &of);
> +    }
> +    if (broker != NULL) {
> +        qb_broker_delete(&broker);
> +    }
> +    return 0;
> +}
> --
> 1.7.1
>
>
>

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

* Re: [Qemu-devel] [PATCH 2/6] libqblock public type defines
  2012-09-03  9:18 ` [Qemu-devel] [PATCH 2/6] libqblock public type defines Wenchao Xia
  2012-09-03 13:13   ` Paolo Bonzini
  2012-09-03 14:20   ` Eric Blake
@ 2012-09-03 19:31   ` Blue Swirl
  2012-09-04  7:19     ` Wenchao Xia
  2 siblings, 1 reply; 46+ messages in thread
From: Blue Swirl @ 2012-09-03 19:31 UTC (permalink / raw)
  To: Wenchao Xia; +Cc: kwolf, aliguori, stefanha, qemu-devel, pbonzini, eblake

On Mon, Sep 3, 2012 at 9:18 AM, Wenchao Xia <xiawenc@linux.vnet.ibm.com> wrote:
>   This patch contains public type and defines used in APIs.
>
> Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
> ---
>  libqblock/libqblock-types.h |  228 +++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 228 insertions(+), 0 deletions(-)
>  create mode 100644 libqblock/libqblock-types.h
>
> diff --git a/libqblock/libqblock-types.h b/libqblock/libqblock-types.h
> new file mode 100644
> index 0000000..3389bda
> --- /dev/null
> +++ b/libqblock/libqblock-types.h
> @@ -0,0 +1,228 @@
> +#ifndef LIBQBLOCK_TYPES_H
> +#define LIBQBLOCK_TYPES_H
> +
> +#include <stdio.h>
> +#include <stdint.h>
> +#include <stdlib.h>
> +#include <stdbool.h>
> +
> +/* this library is designed around this core struct. */
> +struct QBlockState;
> +
> +/* every thread would have a broker. */
> +struct 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)
> +
> +enum QBlockProtocol {
> +    QB_PROTO_NONE = 0,
> +    QB_PROTO_FILE,
> +    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 {

QBlockOptionProtFile

> +    char *filename;

'const'

> +};
> +
> +union QBlockOption_prot {

QBlockOptionProt

> +    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_t reserved[512];
> +};
> +
> +/* format related options */
> +struct QBlockOption_fmt_cow {

QBlockOptionFmtCOW

> +    size_t virt_size;
> +    struct QBlockOptionLoc backing_loc;
> +};
> +
> +struct QBlockOption_fmt_qed {

QBlockOptionFmtQED

etc. for the rest. Don't mix CamelCase with underscore style, struct
names must use CamelCase.

> +    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_V110,
> +};
> +
> +/* off or metadata */
> +enum QBlockOption_fmt_qcow2_prealloc {
> +    QBO_FMT_QCOW2_PREALLOC_NONE = 0,
> +    QBO_FMT_QCOW2_PREALLOC_OFF,
> +    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_NONE = 0,
> +    QBO_FMT_SD_PREALLOC_OFF,
> +    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_NONE = 0,
> +    QBO_FMT_VDI_PREALLOC_FALSE,
> +    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_FALSE,
> +    QBO_FMT_VMDK_CPT_VMDKV6_TRUE,
> +};
> +
> +/* vmdk flat extent format, values:
> +"{monolithicSparse (default) | monolithicFlat | twoGbMaxExtentSparse |
> +twoGbMaxExtentFlat | streamOptimized} */
> +enum QBlockOption_fmt_vmdk_subfmt {
> +    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,
> +};
> +
> +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_NONE = 0,
> +    QBO_FMT_VPC_SUBFMT_DYNAMIC,
> +    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_t reserved[512];
> +};
> +
> +/**
> + * QBlockInfoImageStatic: information about the block image.
> + *
> + * @loc: location info.
> + * @fmt_type: format type.
> + * @virt_size: virtual size in bytes.
> + * @backing_loc: backing file location, its type is QB_PROT_NONE if not exist.
> + * @allocated_size: allocated size in bytes, negative if not available.
> + * @encrypt: encrypt flag.
> + */
> +struct QBlockInfoImageStatic {
> +    struct QBlockOptionLoc loc;
> +    enum QBlockFormat fmt_type;
> +    size_t virt_size;
> +    /* advance info */
> +    struct QBlockOptionLoc backing_loc;
> +    size_t allocated_size;
> +    bool encrypt;
> +};
> +#endif
> --
> 1.7.1
>
>
>

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

* Re: [Qemu-devel] [PATCH 2/6] libqblock public type defines
  2012-09-03 13:13   ` Paolo Bonzini
@ 2012-09-04  2:00     ` Wenchao Xia
  0 siblings, 0 replies; 46+ messages in thread
From: Wenchao Xia @ 2012-09-04  2:00 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kwolf, stefanha, aliguori, eblake, qemu-devel

于 2012-9-3 21:13, Paolo Bonzini 写道:
> Il 03/09/2012 11:18, Wenchao Xia ha scritto:
>> +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_t reserved[512];
>> +};
>
> Padding must be in the union not the struct.  For the fourth time.
>
> Paolo
>
   I must have left it in some other patches, sorry about this key point
missing.



-- 
Best Regards

Wenchao Xia

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

* Re: [Qemu-devel] [PATCH 1/6] libqblock APIs
  2012-09-03 13:18   ` Paolo Bonzini
@ 2012-09-04  3:15     ` Wenchao Xia
  2012-09-04  6:50       ` Paolo Bonzini
  0 siblings, 1 reply; 46+ messages in thread
From: Wenchao Xia @ 2012-09-04  3:15 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kwolf, stefanha, aliguori, eblake, qemu-devel

于 2012-9-3 21:18, Paolo Bonzini 写道:
> Il 03/09/2012 11:18, Wenchao Xia ha scritto:
>>    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.
>
> Can you use GError instead?
>
   read through the GError doc, GError is defined as following:
struct GError {
   GQuark       domain;
   gint         code;
   gchar       *message;
};
   I am worried about the message member, I guess program would be
aborted if OOM, which I was tring to avoid, so I used char err_msg[1024]
in my code, and make things simpler.

>>    3 QBlockInfoImageStatic. Now it is not folded with location and format.
>
> What does "Static" mean?
>
  It is about sorting the information into following kinds:
1) static. It is values that defined at creating time/modifying time,
mostly some settings, and it would not be automatically changed in I/O.
2) dynamic. Some information that would changes in I/O and other
operations, such as allocated_size, snapshots.
3) statistics.
   Now only static one is provided, so I added _static suffix.

> Paolo
>


-- 
Best Regards

Wenchao Xia

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

* Re: [Qemu-devel] [PATCH 4/6] libqblock internal used functions
  2012-09-03 13:18   ` Paolo Bonzini
@ 2012-09-04  3:19     ` Wenchao Xia
  0 siblings, 0 replies; 46+ messages in thread
From: Wenchao Xia @ 2012-09-04  3:19 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kwolf, stefanha, aliguori, eblake, qemu-devel

于 2012-9-3 21:18, Paolo Bonzini 写道:
> Il 03/09/2012 11:18, Wenchao Xia ha scritto:
>>    This patch contains internal helper codes.
>>
>> Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
>> ---
>>   block.c                      |    2 +-
>>   block.h                      |    1 +
>>   libqblock/libqblock-helper.c |   92 ++++++++++++++++++++++++++++++++++++++++++
>>   libqblock/libqblock-helper.h |   57 ++++++++++++++++++++++++++
>>   4 files changed, 151 insertions(+), 1 deletions(-)
>>   create mode 100644 libqblock/libqblock-helper.c
>>   create mode 100644 libqblock/libqblock-helper.h
>>
>> diff --git a/block.c b/block.c
>> index 470bdcc..8b312f8 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-helper.c b/libqblock/libqblock-helper.c
>> new file mode 100644
>> index 0000000..f9e8ce9
>> --- /dev/null
>> +++ b/libqblock/libqblock-helper.c
>> @@ -0,0 +1,92 @@
>> +#include "libqblock-helper.h"
>> +#include "libqblock-types.h"
>> +#include "libqblock-error.h"
>> +
>> +const char *fmt2str(enum QBlockFormat fmt)
>> +{
>> +    const char *ret = NULL;
>> +    switch (fmt) {
>> +    case QB_FMT_COW:
>> +        ret = "cow";
>> +        break;
>> +    case QB_FMT_QED:
>> +        ret = "qed";
>> +        break;
>> +    case QB_FMT_QCOW:
>> +        ret = "qcow";
>> +        break;
>> +    case QB_FMT_QCOW2:
>> +        ret = "qcow2";
>> +        break;
>> +    case QB_FMT_RAW:
>> +        ret = "raw";
>> +        break;
>> +    case QB_FMT_RBD:
>> +        ret = "rbd";
>> +        break;
>> +    case QB_FMT_SHEEPDOG:
>> +        ret = "sheepdog";
>> +        break;
>> +    case QB_FMT_VDI:
>> +        ret = "vdi";
>> +        break;
>> +    case QB_FMT_VMDK:
>> +        ret = "vmdk";
>> +        break;
>> +    case QB_FMT_VPC:
>> +        ret = "vpc";
>> +        break;
>> +    default:
>> +        break;
>> +    }
>> +    return ret;
>> +}
>> +
>> +enum QBlockFormat str2fmt(const char *fmt)
>> +{
>> +    enum QBlockFormat ret = QB_FMT_NONE;
>> +    if (0 == strcmp(fmt, "cow")) {
>> +        ret = QB_FMT_COW;
>> +    } else if (0 == strcmp(fmt, "qed")) {
>> +        ret = QB_FMT_QED;
>> +    } else if (0 == strcmp(fmt, "qcow")) {
>> +        ret = QB_FMT_QCOW;
>> +    } else if (0 == strcmp(fmt, "qcow2")) {
>> +        ret = QB_FMT_QCOW2;
>> +    } else if (0 == strcmp(fmt, "raw")) {
>> +        ret = QB_FMT_RAW;
>> +    } else if (0 == strcmp(fmt, "rbd")) {
>> +        ret = QB_FMT_RBD;
>> +    } else if (0 == strcmp(fmt, "sheepdog")) {
>> +        ret = QB_FMT_SHEEPDOG;
>> +    } else if (0 == strcmp(fmt, "vdi")) {
>> +        ret = QB_FMT_VDI;
>> +    } else if (0 == strcmp(fmt, "vmdk")) {
>> +        ret = QB_FMT_VMDK;
>> +    } else if (0 == strcmp(fmt, "vpc")) {
>> +        ret = QB_FMT_VPC;
>> +    }
>> +    return ret;
>> +}
>> +
>> +void set_broker_err(struct QBroker *broker, int err_ret,
>> +                           const char *fmt, ...)
>> +{
>> +    va_list ap;
>> +
>> +    broker->err_ret = err_ret;
>> +    if (err_ret == QB_ERR_INTERNAL_ERR) {
>> +        broker->err_no = -errno;
>> +    } else {
>> +        broker->err_no = 0;
>> +    }
>> +
>> +    va_start(ap, fmt);
>> +    vsnprintf(broker->err_msg, sizeof(broker->err_msg), fmt, ap);
>> +    va_end(ap);
>> +}
>> +
>> +void set_broker_err_nomem(struct QBroker *broker)
>> +{
>> +    set_broker_err(broker, QB_ERR_MEM_ERR, "No Memory.");
>> +}
>> diff --git a/libqblock/libqblock-helper.h b/libqblock/libqblock-helper.h
>> new file mode 100644
>> index 0000000..4330472
>> --- /dev/null
>> +++ b/libqblock/libqblock-helper.h
>> @@ -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.
>> + *
>> + */
>> +
>> +#ifndef LIBQBLOCK_HELPER
>> +#define LIBQBLOCK_HELPER
>> +
>> +#include "block.h"
>> +#include "block_int.h"
>> +
>> +#include "libqblock-types.h"
>> +
>> +/* this file contains helper function used internally. */
>> +#define SECTOR_SIZE (512)
>> +#define SECTOR_SIZE_MASK (0x01ff)
>> +#define SECTOR_SIZE_BITS_NUM (9)
>> +#define FUNC_FREE free
>> +#define FUNC_MALLOC malloc
>> +#define FUNC_CALLOC calloc
>> +
>> +#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;
>> +};
>> +
>> +#define QB_ERR_STRING_SIZE (1024)
>> +struct QBroker {
>> +    /* last error */
>> +    char err_msg[QB_ERR_STRING_SIZE];
>> +    int err_ret; /* last error return of libqblock. */
>> +    int err_no; /* 2nd level of error, errno what below reports */
>> +};
>> +
>> +const char *fmt2str(enum QBlockFormat fmt);
>> +enum QBlockFormat str2fmt(const char *fmt);
>> +void set_broker_err(struct QBroker *broker, int err_ret,
>> +                           const char *fmt, ...);
>> +void set_broker_err_nomem(struct QBroker *broker);
>> +#endif
>>
>
> Please squash this into patch 1, there is no need to keep separate files.
>
> Paolo
>
   OK. It was done for make a patch smaller to easy reviewing.

-- 
Best Regards

Wenchao Xia

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

* Re: [Qemu-devel] [PATCH 1/6] libqblock APIs
  2012-09-03 13:56   ` Eric Blake
  2012-09-03 14:05     ` Paolo Bonzini
@ 2012-09-04  6:42     ` Wenchao Xia
  2012-09-04 11:35       ` Eric Blake
  1 sibling, 1 reply; 46+ messages in thread
From: Wenchao Xia @ 2012-09-04  6:42 UTC (permalink / raw)
  To: Eric Blake; +Cc: kwolf, pbonzini, aliguori, qemu-devel, stefanha

     Thank u for the careful reviewing of my codes, I will write down
the typo errors you mentioned on a note.

> On 09/03/2012 03:18 AM, Wenchao Xia wrote:
>>    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 QBlockInfoImageStatic. Now it is not folded with location and format.
>>    4 ABI was kept with reserved members.
>>
>> structure, because it would cause caller more codes to find one member.
>
> Commit message snafu?
>
  a wrong paste, sorry.

>> +/**
>> + * libqblock_init: Initialize the library
>> + */
>> +void libqblock_init(void);
>
> Is this function safe to call more than once?  Even tighter, is it safe
> to call this function simultaneously from multiple threads?
>
   No, it should be only called once, any other thread should not call
it again, will document it. About the multiple thread user case, qemu
block layer can't support that now, will fix that later.

>> +
>> +/**
>> + * qb_broker_new: allocate a new broker
>> + *
>> + * Broker is used to pass operation to libqblock, and got feed back from it.
>
> s/got feed back/get feedback/
>
>> + *
>> + * Returns 0 on success, negative value on fail.
>
> Is there any particular interpretation to this negative value, such as
> negative errno constant, or always -1?
>
   Yes, negative values are defined with macros in the header file.

>> +
>> +/**
>> + * qb_state_new: allocate a new QBloctState struct
>
> s/Bloct/Block/
>
>> + *
>> + * Following qblock action were based on this struct
>
> Didn't read well.  Did you mean:
>
> Subsequent qblock actions will use this struct
>
   Yes.

>> + *
>> + * Returns 0 if succeed, negative value on fail.
>
> Again, is there any particular meaning to which negative value is returned?
>
>> +
>> +/**
>> + * qb_open: open a block object.
>> + *
>> + * return 0 on success, negative on fail.
>> + *
>> + * @broker: operation broker.
>> + * @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, set NULL if you want auto discovery the format.
>
> set to NULL if you want to auto-discover the format
>
> Maybe also add a warning about the inherent security risks of attempting
> format auto-discovery (any raw image must NOT be probed, as the raw
> image can emulate any other format and cause qemu to chase down chains
> where it should not).
>
   it seems qemu-img could find out that an image is raw correctly by
probing, do you mean give a warning saying that this image is probably
some formats that qemu do not supported, such as virtual box's image?

>> + * @flag: behavior control flags.
>
> What flags are currently defined?
>
   It is the flags defined in the header file, such as LIBQBLOCK_O_RDWR,
will document it.

>> + */
>> +int qb_open(struct QBroker *broker,
>> +            struct QBlockState *qbs,
>> +            struct QBlockOptionLoc *loc,
>> +            struct QBlockOptionFormat *fmt,
>> +            int flag);
>> +
>> +/**
>> + * qb_close: close a block object.
>> + *
>> + * qb_flush is automaticlly done inside.
>
> s/automaticlly/automatically/
>
>> +/**
>> + * qb_create: create a block image or object.
>> + *
>> + * Note: Create operation would not open the image automatically.
>> + *
>> + * return negative on fail, 0 on success.
>> + *
>> + * @broker: operation broker.
>> + * @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.
>
> Again, what flags are defined?
>
>> +
>> +/* sync access */
>> +/**
>> + * qb_read: block sync read.
>> + *
>> + * return negative on fail, 0 on success.
>
> Shouldn't this instead return the number of successfully read bytes, to
> allow for short reads if offset exceeds end-of-file?  If so, should it
> return ssize_t instead of int?
>
   I had this idea before too, let'me check if qemu block layer can
provide this functionality,

>> + *
>> + * @broker: operation broker.
>> + * @qbs: pointer to struct QBlockState.
>> + * @buf: buffer that receive the content.
>
> s/receive/receives/
>
>> + * @len: length to read.
>
> Is there a magic length for reading the entire file in one go?
>
   no, if so where should I put with the result.

>> + * @offset: offset in the block data.
>> + */
>> +int qb_read(struct QBroker *broker,
>> +            struct QBlockState *qbs,
>> +            const void *buf,
>> +            size_t len,
>> +            off_t offset);
>
> You do realize that size_t and off_t are not necessarily the same width;
> but I'm okay with limiting to size_t reads.
>
>> +/**
>> + * qb_write: block sync write.
>> + *
>> + * return negative on fail, 0 on success.
>
> Again, this should probably return number of successfully written bytes,
> as an ssize_t.
>
>> + *
>> + * @broker: operation broker.
>> + * @qbs: pointer to struct QBlockState.
>> + * @buf: buffer that receive the content.
>
> s/receive/supplies/
>
>> +/* advance image APIs */
>> +/**
>> + * qb_is_allocated: check if following sectors was allocated on the image.
>> + *
>> + * return negative on fail, 0 or 1 on success. 0 means unallocated, 1 means
>> + *allocated.
>
> Formatting is off.
>
   coming later.

>> + *
>> + * @broker: operation broker.
>> + * @qbs: pointer to struct QBlockState.
>> + * @sector_num: start sector number. If 'sector_num' is beyond the end of the
>> + *disk image the return value is 0 and 'pnum' is set to 0.
>> + * @nb_sectors: how many sector would be checked, it is the max value 'pnum'
>> + *should be set to.  If nb_sectors goes beyond the end of the disk image it
>> + *will be clamped.
>> + * @pnum: pointer to receive how many sectors are allocated or unallocated.
>
> This interface requires the user to know how big a sector is.  Would it
> be any more convenient to the user to pass offsets, rather than sector
> numbers; and/or have a function for converting between offsets and
> sector numbers?
>
   OK, I need a function returning how big a sector is in an image.

>> + */
>> +int qb_is_allocated(struct QBroker *broker,
>> +                    struct QBlockState *qbs,
>> +                    int64_t sector_num,
>> +                    int nb_sectors,
>
> Shouldn't nb_sectors be size_t?
>
>> +                    int *pnum);
>
> Exactly how does the *pnum argument work?  This interface looks like it
> isn't fully thought out yet.  Either I want to know if a chunk of
> sectors is allocated (I supply start and length of sectors to check),
> regardless of how many sectors beyond that point are also allocated
> (pnum makes no sense); or I want to know how many sectors are allocated
> from a given point (I supply start, and the function returns length, so
> nb_sectors makes no sense).  Either way, I think you are supplying too
> many parameters for how I envision checking for allocated sectors.
>


-- 
Best Regards

Wenchao Xia

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

* Re: [Qemu-devel] [PATCH 1/6] libqblock APIs
  2012-09-04  3:15     ` Wenchao Xia
@ 2012-09-04  6:50       ` Paolo Bonzini
  2012-09-04  9:05         ` Wenchao Xia
  2012-09-10  8:10         ` Wenchao Xia
  0 siblings, 2 replies; 46+ messages in thread
From: Paolo Bonzini @ 2012-09-04  6:50 UTC (permalink / raw)
  To: Wenchao Xia; +Cc: kwolf, stefanha, aliguori, eblake, qemu-devel

Il 04/09/2012 05:15, Wenchao Xia ha scritto:
>>
>> Can you use GError instead?
>>
>   read through the GError doc, GError is defined as following:
> struct GError {
>   GQuark       domain;
>   gint         code;
>   gchar       *message;
> };
>   I am worried about the message member, I guess program would be
> aborted if OOM, which I was tring to avoid, so I used char err_msg[1024]
> in my code, and make things simpler.

That's true.  On the other hand, and IMHO, not aborting in the library
code is a non-goal as long as the rest of the block layer still does.

>>>    3 QBlockInfoImageStatic. Now it is not folded with location and
>>> format.
>>
>> What does "Static" mean?
>>
>  It is about sorting the information into following kinds:
> 1) static. It is values that defined at creating time/modifying time,
> mostly some settings, and it would not be automatically changed in I/O.
> 2) dynamic. Some information that would changes in I/O and other
> operations, such as allocated_size, snapshots.
> 3) statistics.
>   Now only static one is provided, so I added _static suffix.

Makes sense, thanks for the clarification.  Perhaps QBlockStaticInfo is
a shorter and simpler name?

Paolo

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

* Re: [Qemu-devel] [PATCH 1/6] libqblock APIs
  2012-09-03 14:05     ` Paolo Bonzini
@ 2012-09-04  7:05       ` Wenchao Xia
  2012-09-04  7:29         ` Paolo Bonzini
  0 siblings, 1 reply; 46+ messages in thread
From: Wenchao Xia @ 2012-09-04  7:05 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kwolf, stefanha, aliguori, Eric Blake, qemu-devel

于 2012-9-3 22:05, Paolo Bonzini 写道:
> Il 03/09/2012 15:56, Eric Blake ha scritto:
>> Exactly how does the *pnum argument work?  This interface looks like it
>> isn't fully thought out yet.  Either I want to know if a chunk of
>> sectors is allocated (I supply start and length of sectors to check),
>> regardless of how many sectors beyond that point are also allocated
>> (pnum makes no sense);
>
> pnum makes sense if the [start, start+length) range includes both
> allocated and unallocated sectors.
>
>> or I want to know how many sectors are allocated
>> from a given point (I supply start, and the function returns length, so
>> nb_sectors makes no sense).
>
   About using byte offset instead of sector, I think sector is better,
because the allocation status is based on sector, all bytes data in a
sector would have the same status.

> This operation could be O(number of blocks in disk) worst case, so it
> makes sense to provide nb_sectors as an upper bound.  nb_sectors is
> typically dictated by the size of your buffer.
>
> That said, QEMU's internal bdrv_is_allocated function does have one not
> entirely appealing property: the block at start + *pnum might have the
> same state as the block at start + *pnum - 1, even if *pnum < length.
> We may want to work around this in libqblock, but we could also simply
> document it.
>
> Paolo
>
int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num,
                       int nb_sectors,int *pnum)
will the issue happen when nb_sectors > *pnum? if so it seems a bug,
because caller is asking a range of sectors's allocation status, and
*pnum did not reflect the real status.

>> Either way, I think you are supplying too
>> many parameters for how I envision checking for allocated sectors.
>
   yes, it is a bit confusing, how about:

int qb_check_allocate_status(struct QBroker *broker,
                              struct QBlockState *qbs,
                              offset sector_start,
                              size_t sector_number,
                              size_t *pnum,
                              int *status)
user input sector_start and sector_number to ask check it in this range,
following parameter receive the status, return indicate exception.

>


-- 
Best Regards

Wenchao Xia

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

* Re: [Qemu-devel] [PATCH 2/6] libqblock public type defines
  2012-09-03 14:20   ` Eric Blake
@ 2012-09-04  7:10     ` Wenchao Xia
  2012-09-04  7:37       ` Paolo Bonzini
  0 siblings, 1 reply; 46+ messages in thread
From: Wenchao Xia @ 2012-09-04  7:10 UTC (permalink / raw)
  To: Eric Blake; +Cc: kwolf, pbonzini, aliguori, qemu-devel, stefanha

于 2012-9-3 22:20, Eric Blake 写道:
> On 09/03/2012 03:18 AM, Wenchao Xia wrote:
>>    This patch contains public type and defines used in APIs.
>>
>> Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
>> ---
>>   libqblock/libqblock-types.h |  228 +++++++++++++++++++++++++++++++++++++++++++
>>   1 files changed, 228 insertions(+), 0 deletions(-)
>>   create mode 100644 libqblock/libqblock-types.h
>>
>> diff --git a/libqblock/libqblock-types.h b/libqblock/libqblock-types.h
>> new file mode 100644
>> index 0000000..3389bda
>> --- /dev/null
>> +++ b/libqblock/libqblock-types.h
>> @@ -0,0 +1,228 @@
>> +#ifndef LIBQBLOCK_TYPES_H
>
> Missing a copyright header.  Shame.
>
>> +#define LIBQBLOCK_TYPES_H
>> +
>> +#include <stdio.h>
>> +#include <stdint.h>
>> +#include <stdlib.h>
>> +#include <stdbool.h>
>
> I see use of stdint (uint8_t) and stdbool (bool), but isn't
> <sys/types.h> better than <stdio.h> and <stdlib.h> for size_t?
>
   right, thanks.

>> +
>> +/**
>> + * QBlockInfoImageStatic: information about the block image.
>> + *
>> + * @loc: location info.
>> + * @fmt_type: format type.
>> + * @virt_size: virtual size in bytes.
>> + * @backing_loc: backing file location, its type is QB_PROT_NONE if not exist.
>> + * @allocated_size: allocated size in bytes, negative if not available.
>
> Reading this...
>
>> + * @encrypt: encrypt flag.
>> + */
>> +struct QBlockInfoImageStatic {
>> +    struct QBlockOptionLoc loc;
>> +    enum QBlockFormat fmt_type;
>> +    size_t virt_size;
>> +    /* advance info */
>> +    struct QBlockOptionLoc backing_loc;
>> +    size_t allocated_size;
>
> ...negative is not possible for size_t.  Did you mean ssize_t?
>
   you are right.


-- 
Best Regards

Wenchao Xia

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

* Re: [Qemu-devel] [PATCH 3/6] libqblock error handling
  2012-09-03 14:22   ` Eric Blake
@ 2012-09-04  7:12     ` Wenchao Xia
  2012-09-10  8:20     ` Wenchao Xia
  1 sibling, 0 replies; 46+ messages in thread
From: Wenchao Xia @ 2012-09-04  7:12 UTC (permalink / raw)
  To: Eric Blake; +Cc: kwolf, pbonzini, aliguori, qemu-devel, stefanha

于 2012-9-3 22:22, Eric Blake 写道:
> On 09/03/2012 03:18 AM, Wenchao Xia wrote:
>>    This patch contains error handling APIs.
>>
>> Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
>> ---
>>   libqblock/libqblock-error.c |   44 +++++++++++++++++++++++++++++++++++++++++++
>>   libqblock/libqblock-error.h |   34 +++++++++++++++++++++++++++++++++
>>   2 files changed, 78 insertions(+), 0 deletions(-)
>>   create mode 100644 libqblock/libqblock-error.c
>>   create mode 100644 libqblock/libqblock-error.h
>>
>> diff --git a/libqblock/libqblock-error.c b/libqblock/libqblock-error.c
>> new file mode 100644
>> index 0000000..28d1d77
>> --- /dev/null
>> +++ b/libqblock/libqblock-error.c
>> @@ -0,0 +1,44 @@
>> +#include "libqblock-error.h"
>
> No copyright.  Shame.
>
>> +++ b/libqblock/libqblock-error.h
>> @@ -0,0 +1,34 @@
>> +#ifndef LIBQBLOCK_ERROR
>
> No copyright.  Shame.
>
>> +#define LIBQBLOCK_ERROR
>> +
>> +#include "libqblock-types.h"
>> +
>> +#define QB_ERR_MEM_ERR (-1)
>> +#define QB_ERR_INTERNAL_ERR (-2)
>> +#define QB_ERR_INVALID_PARAM (-3)
>> +#define QB_ERR_BLOCK_OUT_OF_RANGE (-100)
>
> Would an enum make more sense than #defines?
>
>> +
>> +/* error handling */
>> +/**
>> + * qb_error_get_human_str: get human readable erro string.
>
> s/erro/error/
>
>> + *
>> + * return a human readable string.
>> + *
>> + * @broker: operation broker, must be valid.
>> + * @buf: buf to receive the string.
>> + * @buf_size: the size of the string buf.
>> + */
>> +void qb_error_get_human_str(struct QBroker *broker,
>> +                            char *buf, int buf_size);
>
> What happens if buf_size is too small to receive the entire error
> message?  Should this function return int, with negative value on input
> error?
>
   if so, the string is truncated. Give negative value resulting an error
check for an error check, I guess user would not like it, so provide
error check functions which never fail.

-- 
Best Regards

Wenchao Xia

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

* Re: [Qemu-devel] [PATCH 4/6] libqblock internal used functions
  2012-09-03 15:18     ` Paolo Bonzini
@ 2012-09-04  7:15       ` Wenchao Xia
  2012-09-04  7:38         ` Paolo Bonzini
  2012-09-04 11:38         ` Eric Blake
  0 siblings, 2 replies; 46+ messages in thread
From: Wenchao Xia @ 2012-09-04  7:15 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kwolf, stefanha, aliguori, Eric Blake, qemu-devel

于 2012-9-3 23:18, Paolo Bonzini 写道:
> Il 03/09/2012 16:28, Eric Blake ha scritto:
>>>> +/* this file contains helper function used internally. */
>>>> +#define SECTOR_SIZE (512)
>> Hard-coding this feels wrong, in this day and age of disks with 4096
>> sectors.  Why isn't this a per-image property?
>
> In this day and age of disks with 4096 sectors, Linux does not provide a
> way to query the required alignment for O_DIRECT...
>
> Paolo
>
in block.h:
#define BDRV_SECTOR_BITS   9
#define BDRV_SECTOR_SIZE   (1ULL << BDRV_SECTOR_BITS)
#define BDRV_SECTOR_MASK   ~(BDRV_SECTOR_SIZE - 1)
   it seems block size is always 512 in qemu block layer, so I can
ignore the 4096 case, do you think so?
-- 
Best Regards

Wenchao Xia

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

* Re: [Qemu-devel] [PATCH 2/6] libqblock public type defines
  2012-09-03 19:31   ` Blue Swirl
@ 2012-09-04  7:19     ` Wenchao Xia
  2012-09-04  7:38       ` Paolo Bonzini
  0 siblings, 1 reply; 46+ messages in thread
From: Wenchao Xia @ 2012-09-04  7:19 UTC (permalink / raw)
  To: Blue Swirl; +Cc: kwolf, aliguori, stefanha, qemu-devel, pbonzini, eblake


> On Mon, Sep 3, 2012 at 9:18 AM, Wenchao Xia <xiawenc@linux.vnet.ibm.com> wrote:
>>    This patch contains public type and defines used in APIs.
>>
>> Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
>> ---
>>   libqblock/libqblock-types.h |  228 +++++++++++++++++++++++++++++++++++++++++++
>>   1 files changed, 228 insertions(+), 0 deletions(-)
>>   create mode 100644 libqblock/libqblock-types.h
>>
>> diff --git a/libqblock/libqblock-types.h b/libqblock/libqblock-types.h
>> new file mode 100644
>> index 0000000..3389bda
>> --- /dev/null
>> +++ b/libqblock/libqblock-types.h
>> @@ -0,0 +1,228 @@
>> +#ifndef LIBQBLOCK_TYPES_H
>> +#define LIBQBLOCK_TYPES_H
>> +
>> +#include <stdio.h>
>> +#include <stdint.h>
>> +#include <stdlib.h>
>> +#include <stdbool.h>
>> +
>> +/* this library is designed around this core struct. */
>> +struct QBlockState;
>> +
>> +/* every thread would have a broker. */
>> +struct 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)
>> +
>> +enum QBlockProtocol {
>> +    QB_PROTO_NONE = 0,
>> +    QB_PROTO_FILE,
>> +    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 {
>
> QBlockOptionProtFile
>
>> +    char *filename;
>
> 'const'
>
   There is a problem, this member would be used in information
retrieving, so it will be set to a pointer to a string allocated
at runtime, and later be freed. I am not sure if const fits for this
situation, let me check.

>> +};
>> +
>> +union QBlockOption_prot {
>
> QBlockOptionProt
>
>> +    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_t reserved[512];
>> +};
>> +
>> +/* format related options */
>> +struct QBlockOption_fmt_cow {
>
> QBlockOptionFmtCOW
>
>> +    size_t virt_size;
>> +    struct QBlockOptionLoc backing_loc;
>> +};
>> +
>> +struct QBlockOption_fmt_qed {
>
> QBlockOptionFmtQED
>
> etc. for the rest. Don't mix CamelCase with underscore style, struct
> names must use CamelCase.
>
>> +    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_V110,
>> +};
>> +
>> +/* off or metadata */
>> +enum QBlockOption_fmt_qcow2_prealloc {
>> +    QBO_FMT_QCOW2_PREALLOC_NONE = 0,
>> +    QBO_FMT_QCOW2_PREALLOC_OFF,
>> +    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_NONE = 0,
>> +    QBO_FMT_SD_PREALLOC_OFF,
>> +    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_NONE = 0,
>> +    QBO_FMT_VDI_PREALLOC_FALSE,
>> +    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_FALSE,
>> +    QBO_FMT_VMDK_CPT_VMDKV6_TRUE,
>> +};
>> +
>> +/* vmdk flat extent format, values:
>> +"{monolithicSparse (default) | monolithicFlat | twoGbMaxExtentSparse |
>> +twoGbMaxExtentFlat | streamOptimized} */
>> +enum QBlockOption_fmt_vmdk_subfmt {
>> +    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,
>> +};
>> +
>> +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_NONE = 0,
>> +    QBO_FMT_VPC_SUBFMT_DYNAMIC,
>> +    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_t reserved[512];
>> +};
>> +
>> +/**
>> + * QBlockInfoImageStatic: information about the block image.
>> + *
>> + * @loc: location info.
>> + * @fmt_type: format type.
>> + * @virt_size: virtual size in bytes.
>> + * @backing_loc: backing file location, its type is QB_PROT_NONE if not exist.
>> + * @allocated_size: allocated size in bytes, negative if not available.
>> + * @encrypt: encrypt flag.
>> + */
>> +struct QBlockInfoImageStatic {
>> +    struct QBlockOptionLoc loc;
>> +    enum QBlockFormat fmt_type;
>> +    size_t virt_size;
>> +    /* advance info */
>> +    struct QBlockOptionLoc backing_loc;
>> +    size_t allocated_size;
>> +    bool encrypt;
>> +};
>> +#endif
>> --
>> 1.7.1
>>
>>
>>
>


-- 
Best Regards

Wenchao Xia

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

* Re: [Qemu-devel] [PATCH 1/6] libqblock APIs
  2012-09-04  7:05       ` Wenchao Xia
@ 2012-09-04  7:29         ` Paolo Bonzini
  0 siblings, 0 replies; 46+ messages in thread
From: Paolo Bonzini @ 2012-09-04  7:29 UTC (permalink / raw)
  To: Wenchao Xia; +Cc: kwolf, stefanha, aliguori, Eric Blake, qemu-devel

Il 04/09/2012 09:05, Wenchao Xia ha scritto:
>> That said, QEMU's internal bdrv_is_allocated function does have one not
>> entirely appealing property: the block at start + *pnum might have the
>> same state as the block at start + *pnum - 1, even if *pnum < length.
>> We may want to work around this in libqblock, but we could also simply
>> document it.
>>
>> Paolo
>>
> int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num,
>                       int nb_sectors,int *pnum)
> will the issue happen when nb_sectors > *pnum? if so it seems a bug,
> because caller is asking a range of sectors's allocation status, and
> *pnum did not reflect the real status.

Actually it does.

bdrv_is_allocated says it didn't find out anything about sector start +
*pnum and later.

>>> Either way, I think you are supplying too
>>> many parameters for how I envision checking for allocated sectors.
>>
>   yes, it is a bit confusing, how about:
> 
> int qb_check_allocate_status(struct QBroker *broker,
>                              struct QBlockState *qbs,
>                              offset sector_start,
>                              size_t sector_number,
>                              size_t *pnum,
>                              int *status)
> user input sector_start and sector_number to ask check it in this range,
> following parameter receive the status, return indicate exception.

That's ok too.

But do not use size_t for sectors.  Testing, or reading, or writing 2 TB
with a single call is more than enough.

Paolo

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

* Re: [Qemu-devel] [PATCH 2/6] libqblock public type defines
  2012-09-04  7:10     ` Wenchao Xia
@ 2012-09-04  7:37       ` Paolo Bonzini
  0 siblings, 0 replies; 46+ messages in thread
From: Paolo Bonzini @ 2012-09-04  7:37 UTC (permalink / raw)
  To: Wenchao Xia; +Cc: kwolf, stefanha, aliguori, Eric Blake, qemu-devel

Il 04/09/2012 09:10, Wenchao Xia ha scritto:
> 
>>> +
>>> +/**
>>> + * QBlockInfoImageStatic: information about the block image.
>>> + *
>>> + * @loc: location info.
>>> + * @fmt_type: format type.
>>> + * @virt_size: virtual size in bytes.
>>> + * @backing_loc: backing file location, its type is QB_PROT_NONE if
>>> not exist.
>>> + * @allocated_size: allocated size in bytes, negative if not available.
>>
>> Reading this...
>>
>>> + * @encrypt: encrypt flag.
>>> + */
>>> +struct QBlockInfoImageStatic {
>>> +    struct QBlockOptionLoc loc;
>>> +    enum QBlockFormat fmt_type;
>>> +    size_t virt_size;
>>> +    /* advance info */
>>> +    struct QBlockOptionLoc backing_loc;
>>> +    size_t allocated_size;
>>
>> ...negative is not possible for size_t.  Did you mean ssize_t?
>>
>   you are right.

size_t is a *pointer* size.  It is 32-bits on

Use int64_t or uint64_t always when dealing with file sizes and offsets.

In particular, do not use off_t, it is a recipe for pain and ABI
incompatibilities.

Paolo

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

* Re: [Qemu-devel] [PATCH 2/6] libqblock public type defines
  2012-09-04  7:19     ` Wenchao Xia
@ 2012-09-04  7:38       ` Paolo Bonzini
  2012-09-04 19:22         ` Blue Swirl
  0 siblings, 1 reply; 46+ messages in thread
From: Paolo Bonzini @ 2012-09-04  7:38 UTC (permalink / raw)
  To: Wenchao Xia; +Cc: kwolf, aliguori, stefanha, qemu-devel, Blue Swirl, eblake

Il 04/09/2012 09:19, Wenchao Xia ha scritto:
>>>
>>> +struct QBlockOption_prot_file {
>>
>> QBlockOptionProtFile
>>
>>> +    char *filename;
>>
>> 'const'
>>
>   There is a problem, this member would be used in information
> retrieving, so it will be set to a pointer to a string allocated
> at runtime, and later be freed. I am not sure if const fits for this
> situation, let me check.

No, const would add useless complication.  In C++ it is different
because you have constructors.

Paolo

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

* Re: [Qemu-devel] [PATCH 4/6] libqblock internal used functions
  2012-09-04  7:15       ` Wenchao Xia
@ 2012-09-04  7:38         ` Paolo Bonzini
  2012-09-04 11:38         ` Eric Blake
  1 sibling, 0 replies; 46+ messages in thread
From: Paolo Bonzini @ 2012-09-04  7:38 UTC (permalink / raw)
  To: Wenchao Xia; +Cc: kwolf, stefanha, aliguori, Eric Blake, qemu-devel

Il 04/09/2012 09:15, Wenchao Xia ha scritto:
>>>>> +/* this file contains helper function used internally. */
>>>>> +#define SECTOR_SIZE (512)
>>> Hard-coding this feels wrong, in this day and age of disks with 4096
>>> sectors.  Why isn't this a per-image property?
>>
>> In this day and age of disks with 4096 sectors, Linux does not provide a
>> way to query the required alignment for O_DIRECT...
>>
>> Paolo
>>
> in block.h:
> #define BDRV_SECTOR_BITS   9
> #define BDRV_SECTOR_SIZE   (1ULL << BDRV_SECTOR_BITS)
> #define BDRV_SECTOR_MASK   ~(BDRV_SECTOR_SIZE - 1)
>   it seems block size is always 512 in qemu block layer, so I can
> ignore the 4096 case, do you think so?

Yes.  It is not well supported yet by QEMU, either.

Paolo

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

* Re: [Qemu-devel] [PATCH 1/6] libqblock APIs
  2012-09-04  6:50       ` Paolo Bonzini
@ 2012-09-04  9:05         ` Wenchao Xia
  2012-09-10  8:10         ` Wenchao Xia
  1 sibling, 0 replies; 46+ messages in thread
From: Wenchao Xia @ 2012-09-04  9:05 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kwolf, stefanha, aliguori, eblake, qemu-devel

于 2012-9-4 14:50, Paolo Bonzini 写道:
> Il 04/09/2012 05:15, Wenchao Xia ha scritto:
>>>
>>> Can you use GError instead?
>>>
>>    read through the GError doc, GError is defined as following:
>> struct GError {
>>    GQuark       domain;
>>    gint         code;
>>    gchar       *message;
>> };
>>    I am worried about the message member, I guess program would be
>> aborted if OOM, which I was tring to avoid, so I used char err_msg[1024]
>> in my code, and make things simpler.
>
> That's true.  On the other hand, and IMHO, not aborting in the library
> code is a non-goal as long as the rest of the block layer still does.
>
   Hard problem for me, do you have some suggestion about OOM issue?
Using GLib's more functions, such as GError and Gsource main event
loop, would cause this issue more difficult to solve later.
   Do we have an alternative robust lib as glib but reports OOM instead
exit on Linux?

>>>>     3 QBlockInfoImageStatic. Now it is not folded with location and
>>>> format.
>>>
>>> What does "Static" mean?
>>>
>>   It is about sorting the information into following kinds:
>> 1) static. It is values that defined at creating time/modifying time,
>> mostly some settings, and it would not be automatically changed in I/O.
>> 2) dynamic. Some information that would changes in I/O and other
>> operations, such as allocated_size, snapshots.
>> 3) statistics.
>>    Now only static one is provided, so I added _static suffix.
>
> Makes sense, thanks for the clarification.  Perhaps QBlockStaticInfo is
> a shorter and simpler name?
>
   OK.

> Paolo
>


-- 
Best Regards

Wenchao Xia

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

* Re: [Qemu-devel] [PATCH 1/6] libqblock APIs
  2012-09-04  6:42     ` Wenchao Xia
@ 2012-09-04 11:35       ` Eric Blake
  2012-09-04 13:47         ` Paolo Bonzini
  0 siblings, 1 reply; 46+ messages in thread
From: Eric Blake @ 2012-09-04 11:35 UTC (permalink / raw)
  To: Wenchao Xia; +Cc: kwolf, pbonzini, aliguori, qemu-devel, stefanha

[-- Attachment #1: Type: text/plain, Size: 2444 bytes --]

On 09/04/2012 12:42 AM, Wenchao Xia wrote:
>>> +/**
>>> + * libqblock_init: Initialize the library
>>> + */
>>> +void libqblock_init(void);
>>
>> Is this function safe to call more than once?  Even tighter, is it safe
>> to call this function simultaneously from multiple threads?
>>
>   No, it should be only called once, any other thread should not call
> it again, will document it. About the multiple thread user case, qemu
> block layer can't support that now, will fix that later.

What a shame.  That makes libraries much harder to use.  It is much
nicer to design a library where the initialization is idempotent and
thread-safe, to be called from multiple threads.  Consider:

app links against liba and libb;
liba links against libqb
libb links against libqb

How am I supposed to write liba and libb to guarantee only one single
race-free call to libqblock_init, unless libqblock_init() is idempotent?

Also, should there be a counterpart function for tearing down the
resources used by the library when it is no longer needed?  If so, then
that implies reference counting - each call to init atomically increases
the refcount, and the library frees resources only when the refcount
atomically goes back to 0.


>>> + * @fmt: format options, how to extract the data, only valid member
>>> now is
>>> +     fmt->fmt_type, set NULL if you want auto discovery the format.
>>
>> set to NULL if you want to auto-discover the format
>>
>> Maybe also add a warning about the inherent security risks of attempting
>> format auto-discovery (any raw image must NOT be probed, as the raw
>> image can emulate any other format and cause qemu to chase down chains
>> where it should not).
>>
>   it seems qemu-img could find out that an image is raw correctly by
> probing, do you mean give a warning saying that this image is probably
> some formats that qemu do not supported, such as virtual box's image?

No, you got it backwards.  For all non-raw images, qemu can correctly
probe the image.  But for raw images, the guest may have set enough
information in the image to make a probe _think_ that the image is
non-raw, and therefore cause qemu to misbehave.  That is, the security
hole is choosing to probe a raw image, because the probe will not always
successfully return raw.

-- 
Eric Blake   eblake@redhat.com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 617 bytes --]

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

* Re: [Qemu-devel] [PATCH 4/6] libqblock internal used functions
  2012-09-04  7:15       ` Wenchao Xia
  2012-09-04  7:38         ` Paolo Bonzini
@ 2012-09-04 11:38         ` Eric Blake
  2012-09-04 13:49           ` Paolo Bonzini
  1 sibling, 1 reply; 46+ messages in thread
From: Eric Blake @ 2012-09-04 11:38 UTC (permalink / raw)
  To: Wenchao Xia; +Cc: kwolf, Paolo Bonzini, aliguori, qemu-devel, stefanha

[-- Attachment #1: Type: text/plain, Size: 1298 bytes --]

On 09/04/2012 01:15 AM, Wenchao Xia wrote:
> 于 2012-9-3 23:18, Paolo Bonzini 写道:
>> Il 03/09/2012 16:28, Eric Blake ha scritto:
>>>>> +/* this file contains helper function used internally. */
>>>>> +#define SECTOR_SIZE (512)
>>> Hard-coding this feels wrong, in this day and age of disks with 4096
>>> sectors.  Why isn't this a per-image property?
>>
>> In this day and age of disks with 4096 sectors, Linux does not provide a
>> way to query the required alignment for O_DIRECT...
>>
>> Paolo
>>
> in block.h:
> #define BDRV_SECTOR_BITS   9
> #define BDRV_SECTOR_SIZE   (1ULL << BDRV_SECTOR_BITS)
> #define BDRV_SECTOR_MASK   ~(BDRV_SECTOR_SIZE - 1)
>   it seems block size is always 512 in qemu block layer, so I can
> ignore the 4096 case, do you think so?

Since qemu does not support it now, yes, you can ignore it for now.  But
please make sure that you aren't hard-coding it into the API - that is,
make sure that the API can someday grow to support larger sector sizes
with minimal impact to library clients (that is, that new clients aware
of the new API can target larger sector size once qemu has been patched
to support larger sector size).

-- 
Eric Blake   eblake@redhat.com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 617 bytes --]

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

* Re: [Qemu-devel] [PATCH 1/6] libqblock APIs
  2012-09-04 11:35       ` Eric Blake
@ 2012-09-04 13:47         ` Paolo Bonzini
  0 siblings, 0 replies; 46+ messages in thread
From: Paolo Bonzini @ 2012-09-04 13:47 UTC (permalink / raw)
  To: Eric Blake; +Cc: kwolf, stefanha, aliguori, Wenchao Xia, qemu-devel

Il 04/09/2012 13:35, Eric Blake ha scritto:
>> >   No, it should be only called once, any other thread should not call
>> > it again, will document it. About the multiple thread user case, qemu
>> > block layer can't support that now, will fix that later.
> What a shame.  That makes libraries much harder to use.  It is much
> nicer to design a library where the initialization is idempotent and
> thread-safe, to be called from multiple threads.  Consider:
> 
> app links against liba and libb;
> liba links against libqb
> libb links against libqb
> 
> How am I supposed to write liba and libb to guarantee only one single
> race-free call to libqblock_init, unless libqblock_init() is idempotent?

I agree, libqblock_init should use pthread_once (or we can add QemuOnce
to qemu-thread-*.c).

Paolo

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

* Re: [Qemu-devel] [PATCH 4/6] libqblock internal used functions
  2012-09-04 11:38         ` Eric Blake
@ 2012-09-04 13:49           ` Paolo Bonzini
  2012-09-04 13:51             ` Kevin Wolf
  0 siblings, 1 reply; 46+ messages in thread
From: Paolo Bonzini @ 2012-09-04 13:49 UTC (permalink / raw)
  To: Eric Blake; +Cc: kwolf, stefanha, aliguori, Wenchao Xia, qemu-devel

Il 04/09/2012 13:38, Eric Blake ha scritto:
> Since qemu does not support it now, yes, you can ignore it for now.  But
> please make sure that you aren't hard-coding it into the API - that is,
> make sure that the API can someday grow to support larger sector sizes
> with minimal impact to library clients (that is, that new clients aware
> of the new API can target larger sector size once qemu has been patched
> to support larger sector size).

We can support 4k sector disks even if the addressing unit remains 512
bytes, just like in the Linux kernel.

Wenchao, you can add a logical_block_size item to the image info and
make it always return 512.

Paolo

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

* Re: [Qemu-devel] [PATCH 4/6] libqblock internal used functions
  2012-09-04 13:49           ` Paolo Bonzini
@ 2012-09-04 13:51             ` Kevin Wolf
  2012-09-10  8:23               ` Wenchao Xia
  0 siblings, 1 reply; 46+ messages in thread
From: Kevin Wolf @ 2012-09-04 13:51 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: stefanha, aliguori, Eric Blake, Wenchao Xia, qemu-devel

Am 04.09.2012 15:49, schrieb Paolo Bonzini:
> Il 04/09/2012 13:38, Eric Blake ha scritto:
>> Since qemu does not support it now, yes, you can ignore it for now.  But
>> please make sure that you aren't hard-coding it into the API - that is,
>> make sure that the API can someday grow to support larger sector sizes
>> with minimal impact to library clients (that is, that new clients aware
>> of the new API can target larger sector size once qemu has been patched
>> to support larger sector size).
> 
> We can support 4k sector disks even if the addressing unit remains 512
> bytes, just like in the Linux kernel.

Why should we even use an arbitrary unit like 512 bytes for addressing?
To me using byte granularity everywhere makes more sense and is clearer.

Kevin

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

* Re: [Qemu-devel] xbzrle migration cache size advise for high memory changes workload ?
  2012-09-03 13:10   ` [Qemu-devel] xbzrle migration cache size advise for high memory changes workload ? Alexandre DERUMIER
@ 2012-09-04 14:05     ` Orit Wasserman
  0 siblings, 0 replies; 46+ messages in thread
From: Orit Wasserman @ 2012-09-04 14:05 UTC (permalink / raw)
  To: Alexandre DERUMIER; +Cc: qemu-devel

On 09/03/2012 04:10 PM, Alexandre DERUMIER wrote:
> Hi,
> I'm trying to implement xbzrle live migration,
> 
> But i'm having non finishing migration with high memory changes in guest.
> (simply playing a youtube video in the guest). 
> At the end of the migration, the remaining memory to transfert goes up and down.
XBZRLE can't always help migration to converge, for some workload you need to increase migration speed and
migration downtime. What values are you using for those ? 
> 
> I have tried to dynamicaly add memory to cache (max = guest memory), but it doesn't help.
> 
> 
> What is the best size recommendation for cache ? (percent of guest memory ?)
It depends on the guest workload , XBZRLE is good for guest that dirties the same memory pages over and
over. so if you notice that the number of cache misses is growing increasing the cache size can help.
> Can I tune it based on some values ? (cachemiss, overflow ?)
if you have lots of overflow this means the pages are not suitable for compression so increasing the cache size
won't help.
> 
> Can we desactivate xbzrle during the migration ?
not at the moment , I plan to add support to it.

Cheers,
Orit
> 
> 
> 
> 
> Some logs counters of the migration:
> 
> Sep 03 15:00:32 migration xbzrle cachesize: 67108864 transferred 0 pages 0 cachemiss 15158 overflow 0 deltacachemiss 15158
> Sep 03 15:00:34 migration status: active (transferred 119318244, remaining 1987846144), total 2114387968)
> Sep 03 15:00:34 migration xbzrle cachesize: 67108864 transferred 0 pages 0 cachemiss 29130 overflow 0 deltacachemiss 13972
> Sep 03 15:00:36 migration status: active (transferred 156261310, remaining 1342005248), total 2114387968)
> Sep 03 15:00:36 migration xbzrle cachesize: 67108864 transferred 0 pages 0 cachemiss 38113 overflow 0 deltacachemiss 8983
> Sep 03 15:00:38 migration status: active (transferred 195909631, remaining 786370560), total 2114387968)
> Sep 03 15:00:38 migration xbzrle cachesize: 67108864 transferred 0 pages 0 cachemiss 47762 overflow 0 deltacachemiss 9649
> Sep 03 15:00:40 migration status: active (transferred 264583501, remaining 716410880), total 2114387968)
> Sep 03 15:00:40 migration xbzrle cachesize: 67108864 transferred 0 pages 0 cachemiss 64528 overflow 0 deltacachemiss 16766
> Sep 03 15:00:42 migration status: active (transferred 336759138, remaining 644227072), total 2114387968)
> Sep 03 15:00:42 migration xbzrle cachesize: 67108864 transferred 0 pages 0 cachemiss 82149 overflow 0 deltacachemiss 17621
> Sep 03 15:00:44 migration status: active (transferred 399641876, remaining 577712128), total 2114387968)
> Sep 03 15:00:44 migration xbzrle cachesize: 67108864 transferred 0 pages 0 cachemiss 97501 overflow 0 deltacachemiss 15352
> Sep 03 15:00:46 migration status: active (transferred 446500707, remaining 528441344), total 2114387968)
> Sep 03 15:00:46 migration xbzrle cachesize: 67108864 transferred 0 pages 0 cachemiss 108941 overflow 0 deltacachemiss 11440
> Sep 03 15:00:48 migration status: active (transferred 501567884, remaining 471134208), total 2114387968)
> Sep 03 15:00:48 migration xbzrle cachesize: 67108864 transferred 0 pages 0 cachemiss 122385 overflow 0 deltacachemiss 13444
> Sep 03 15:00:50 migration status: active (transferred 566289154, remaining 404901888), total 2114387968)
> Sep 03 15:00:50 migration xbzrle cachesize: 67108864 transferred 0 pages 0 cachemiss 138186 overflow 0 deltacachemiss 15801
> Sep 03 15:00:52 migration status: active (transferred 631297144, remaining 338370560), total 2114387968)
> Sep 03 15:00:52 migration xbzrle cachesize: 67108864 transferred 0 pages 0 cachemiss 154057 overflow 0 deltacachemiss 15871
> Sep 03 15:00:54 migration status: active (transferred 695854441, remaining 272830464), total 2114387968)
> Sep 03 15:00:54 migration xbzrle cachesize: 67108864 transferred 0 pages 0 cachemiss 169818 overflow 0 deltacachemiss 15761
> Sep 03 15:00:56 migration status: active (transferred 763447412, remaining 202059776), total 2114387968)
> Sep 03 15:00:56 migration xbzrle cachesize: 67108864 transferred 0 pages 0 cachemiss 186320 overflow 0 deltacachemiss 16502
> Sep 03 15:00:58 migration status: active (transferred 828361066, remaining 136142848), total 2114387968)
> Sep 03 15:00:58 migration xbzrle cachesize: 67108864 transferred 0 pages 0 cachemiss 202168 overflow 0 deltacachemiss 15848
> Sep 03 15:01:00 migration status: active (transferred 879799289, remaining 82030592), total 2114387968)
> Sep 03 15:01:00 migration xbzrle cachesize: 67108864 transferred 0 pages 0 cachemiss 214726 overflow 0 deltacachemiss 12558
> Sep 03 15:01:02 migration status: active (transferred 940920124, remaining 19603456), total 2114387968)
> Sep 03 15:01:02 migration xbzrle cachesize: 67108864 transferred 0 pages 0 cachemiss 229648 overflow 0 deltacachemiss 14922
> Sep 03 15:01:03 migration status: active (transferred 949001101, remaining 69087232), total 2114387968)
> Sep 03 15:01:03 migration xbzrle cachesize: 67108864 transferred 0 pages 0 cachemiss 231620 overflow 0 deltacachemiss 1972
> Sep 03 15:01:03 migration status: active (transferred 959106075, remaining 58187776), total 2114387968)
> Sep 03 15:01:03 migration xbzrle cachesize: 67108864 transferred 100 pages 2 cachemiss 234087 overflow 0 deltacachemiss 2467
> Sep 03 15:01:03 migration status: active (transferred 969236581, remaining 43577344), total 2114387968)
> Sep 03 15:01:03 migration xbzrle cachesize: 67108864 transferred 100 pages 2 cachemiss 236560 overflow 0 deltacachemiss 2473
> Sep 03 15:01:04 migration status: active (transferred 979374186, remaining 33427456), total 2114387968)
> Sep 03 15:01:04 migration xbzrle cachesize: 67108864 transferred 100 pages 2 cachemiss 239035 overflow 0 deltacachemiss 2475
> Sep 03 15:01:04 migration status: active (transferred 989479026, remaining 23302144), total 2114387968)
> Sep 03 15:01:04 migration xbzrle cachesize: 67108864 transferred 100 pages 2 cachemiss 241502 overflow 0 deltacachemiss 2467
> Sep 03 15:01:04 migration status: active (transferred 999747708, remaining 28950528), total 2114387968)
> Sep 03 15:01:04 migration xbzrle cachesize: 67108864 transferred 100 pages 2 cachemiss 244009 overflow 0 deltacachemiss 2507
> Sep 03 15:01:04 migration status: active (transferred 1006616716, remaining 22032384), total 2114387968)
> Sep 03 15:01:04 migration xbzrle cachesize: 67108864 transferred 100 pages 2 cachemiss 245686 overflow 0 deltacachemiss 1677
> Sep 03 15:01:05 migration status: active (transferred 1020085038, remaining 18358272), total 2114387968)
> Sep 03 15:01:05 migration xbzrle cachesize: 67108864 transferred 1905397 pages 991 cachemiss 248381 overflow 128 deltacachemiss 2695
> Sep 03 15:01:05 migration status: active (transferred 1030213871, remaining 14524416), total 2114387968)
> Sep 03 15:01:05 migration xbzrle cachesize: 67108864 transferred 6103206 pages 3227 cachemiss 249646 overflow 311 deltacachemiss 1265
> Sep 03 15:01:05 migration status: active (transferred 1040306669, remaining 7348224), total 2114387968)
> Sep 03 15:01:05 migration xbzrle cachesize: 67108864 transferred 11579783 pages 6075 cachemiss 250496 overflow 588 deltacachemiss 850
> Sep 03 15:01:06 migration status: active (transferred 1047695771, remaining 13287424), total 2114387968)
> Sep 03 15:01:06 migration xbzrle cachesize: 67108864 transferred 15286549 pages 9455 cachemiss 251271 overflow 712 deltacachemiss 775
> Sep 03 15:01:06 migration status: active (transferred 1054790825, remaining 8896512), total 2114387968)
> Sep 03 15:01:06 migration xbzrle cachesize: 67108864 transferred 18600974 pages 12483 cachemiss 252020 overflow 886 deltacachemiss 749
> Sep 03 15:01:06 migration status: active (transferred 1064883713, remaining 3870720), total 2114387968)
> Sep 03 15:01:06 migration xbzrle cachesize: 67108864 transferred 24180048 pages 15326 cachemiss 252856 overflow 1152 deltacachemiss 836
> Sep 03 15:01:07 migration status: active (transferred 1073205318, remaining 13889536), total 2114387968)
> Sep 03 15:01:07 migration xbzrle cachesize: 67108864 transferred 28106603 pages 18135 cachemiss 253769 overflow 1312 deltacachemiss 913
> Sep 03 15:01:07 migration status: active (transferred 1083269753, remaining 8450048), total 2114387968)
> Sep 03 15:01:07 migration xbzrle cachesize: 67108864 transferred 33685887 pages 20865 cachemiss 254445 overflow 1731 deltacachemiss 676
> Sep 03 15:01:07 migration status: active (transferred 1093363118, remaining 13656064), total 2114387968)
> Sep 03 15:01:07 migration xbzrle cachesize: 67108864 transferred 39318685 pages 23895 cachemiss 255182 overflow 2083 deltacachemiss 737
> Sep 03 15:01:08 migration status: active (transferred 1104228774, remaining 3948544), total 2114387968)
> Sep 03 15:01:08 migration xbzrle cachesize: 67108864 transferred 45621367 pages 27392 cachemiss 255988 overflow 2391 deltacachemiss 806
> Sep 03 15:01:08 migration status: active (transferred 1112828342, remaining 4714496), total 2114387968)
> Sep 03 15:01:08 migration xbzrle cachesize: 67108864 transferred 50624630 pages 29895 cachemiss 256597 overflow 2660 deltacachemiss 609
> Sep 03 15:01:08 migration status: active (transferred 1121646599, remaining 5951488), total 2114387968)
> Sep 03 15:01:08 migration xbzrle cachesize: 67108864 transferred 54638264 pages 32011 cachemiss 257423 overflow 3007 deltacachemiss 826
> Sep 03 15:01:09 migration status: active (transferred 1131774276, remaining 14245888), total 2114387968)
> Sep 03 15:01:09 migration xbzrle cachesize: 67108864 transferred 59924446 pages 34904 cachemiss 258311 overflow 3301 deltacachemiss 888
> Sep 03 15:01:09 migration status: active (transferred 1139357344, remaining 12529664), total 2114387968)
> Sep 03 15:01:09 migration xbzrle cachesize: 67108864 transferred 62850320 pages 39537 cachemiss 259385 overflow 3364 deltacachemiss 1074
> Sep 03 15:01:09 migration status: active (transferred 1147848486, remaining 12972032), total 2114387968)
> Sep 03 15:01:09 migration xbzrle cachesize: 67108864 transferred 67237245 pages 43153 cachemiss 260229 overflow 3522 deltacachemiss 844
> Sep 03 15:01:10 migration status: active (transferred 1157968777, remaining 7729152), total 2114387968)
> Sep 03 15:01:10 migration xbzrle cachesize: 67108864 transferred 72753611 pages 45998 cachemiss 260890 overflow 3985 deltacachemiss 661
> Sep 03 15:01:10 migration status: active (transferred 1168065017, remaining 3137536), total 2114387968)
> Sep 03 15:01:10 migration xbzrle cachesize: 67108864 transferred 78000165 pages 48646 cachemiss 261660 overflow 4399 deltacachemiss 770
> Sep 03 15:01:10 migration status: active (transferred 1176461216, remaining 5459968), total 2114387968)
> Sep 03 15:01:10 migration xbzrle cachesize: 67108864 transferred 81931708 pages 50605 cachemiss 262364 overflow 4785 deltacachemiss 704
> Sep 03 15:01:11 migration status: active (transferred 1187721613, remaining 15183872), total 2114387968)
> Sep 03 15:01:11 migration xbzrle cachesize: 67108864 transferred 87588758 pages 53584 cachemiss 263313 overflow 5204 deltacachemiss 949
> Sep 03 15:01:11 migration status: active (transferred 1196325449, remaining 15134720), total 2114387968)
> Sep 03 15:01:11 migration xbzrle cachesize: 67108864 transferred 92063809 pages 55810 cachemiss 263933 overflow 5592 deltacachemiss 620
> Sep 03 15:01:11 migration status: active (transferred 1206419175, remaining 7557120), total 2114387968)
> Sep 03 15:01:11 migration xbzrle cachesize: 67108864 transferred 97500362 pages 58460 cachemiss 264676 overflow 5986 deltacachemiss 743
> Sep 03 15:01:11 migration status: active (transferred 1216510694, remaining 15560704), total 2114387968)
> Sep 03 15:01:11 migration xbzrle cachesize: 67108864 transferred 102480030 pages 61212 cachemiss 265552 overflow 6358 deltacachemiss 876
> Sep 03 15:01:12 migration status: active (transferred 1225162926, remaining 14811136), total 2114387968)
> Sep 03 15:01:12 migration xbzrle cachesize: 67108864 transferred 107155027 pages 63456 cachemiss 266234 overflow 6647 deltacachemiss 682
> Sep 03 15:01:12 migration status: active (transferred 1235228927, remaining 12378112), total 2114387968)
> Sep 03 15:01:12 migration xbzrle cachesize: 67108864 transferred 112440978 pages 66311 cachemiss 267101 overflow 6947 deltacachemiss 867
> Sep 03 15:01:12 migration status: active (transferred 1245060361, remaining 14848000), total 2114387968)
> Sep 03 15:01:12 migration xbzrle cachesize: 67108864 transferred 116886157 pages 68943 cachemiss 268239 overflow 7124 deltacachemiss 1138
> Sep 03 15:01:13 migration status: active (transferred 1255151722, remaining 14151680), total 2114387968)
> Sep 03 15:01:13 migration xbzrle cachesize: 67108864 transferred 121058631 pages 71389 cachemiss 269475 overflow 7333 deltacachemiss 1236
> Sep 03 15:01:13 migration status: active (transferred 1265145124, remaining 12636160), total 2114387968)
> Sep 03 15:01:13 migration xbzrle cachesize: 67108864 transferred 125804843 pages 74069 cachemiss 270559 overflow 7530 deltacachemiss 1084
> Sep 03 15:01:13 migration status: active (transferred 1274160338, remaining 9003008), total 2114387968)
> Sep 03 15:01:13 migration xbzrle cachesize: 67108864 transferred 130109480 pages 76352 cachemiss 271460 overflow 7779 deltacachemiss 901
> Sep 03 15:01:14 migration status: active (transferred 1285539796, remaining 12382208), total 2114387968)
> Sep 03 15:01:14 migration xbzrle cachesize: 67108864 transferred 136704693 pages 79967 cachemiss 272399 overflow 8008 deltacachemiss 939
> Sep 03 15:01:14 migration status: active (transferred 1294465950, remaining 10989568), total 2114387968)
> Sep 03 15:01:14 migration xbzrle cachesize: 67108864 transferred 141522529 pages 82691 cachemiss 273221 overflow 8189 deltacachemiss 822
> Sep 03 15:01:14 migration status: active (transferred 1304111247, remaining 12431360), total 2114387968)
> Sep 03 15:01:14 migration xbzrle cachesize: 67108864 transferred 146256619 pages 85117 cachemiss 274137 overflow 8472 deltacachemiss 916
> Sep 03 15:01:15 migration status: active (transferred 1313714825, remaining 9031680), total 2114387968)
> Sep 03 15:01:15 migration xbzrle cachesize: 67108864 transferred 150961349 pages 87828 cachemiss 275101 overflow 8704 deltacachemiss 964
> Sep 03 15:01:15 migration status: active (transferred 1321615036, remaining 8843264), total 2114387968)
> Sep 03 15:01:15 migration xbzrle cachesize: 67108864 transferred 155568345 pages 90258 cachemiss 275753 overflow 8856 deltacachemiss 652
> Sep 03 15:01:15 migration status: active (transferred 1332266783, remaining 4997120), total 2114387968)
> Sep 03 15:01:15 migration xbzrle cachesize: 67108864 transferred 161419460 pages 93534 cachemiss 276690 overflow 9091 deltacachemiss 937
> Sep 03 15:01:16 migration status: active (transferred 1340961412, remaining 4333568), total 2114387968)
> Sep 03 15:01:16 migration xbzrle cachesize: 67108864 transferred 165833625 pages 96166 cachemiss 277571 overflow 9255 deltacachemiss 881
> Sep 03 15:01:16 migration status: active (transferred 1349569887, remaining 4313088), total 2114387968)
> Sep 03 15:01:16 migration xbzrle cachesize: 67108864 transferred 170194521 pages 98568 cachemiss 278366 overflow 9497 deltacachemiss 795
> Sep 03 15:01:16 migration status: active (transferred 1357212762, remaining 5083136), total 2114387968)
> Sep 03 15:01:16 migration xbzrle cachesize: 67108864 transferred 173651067 pages 100693 cachemiss 279206 overflow 9679 deltacachemiss 840
> Sep 03 15:01:16 migration status: active (transferred 1362924614, remaining 12259328), total 2114387968)
> Sep 03 15:01:16 migration xbzrle cachesize: 67108864 transferred 175983690 pages 102350 cachemiss 279936 overflow 9774 deltacachemiss 730
> Sep 03 15:01:17 migration status: active (transferred 1369555421, remaining 17477632), total 2114387968)
> Sep 03 15:01:17 migration xbzrle cachesize: 67108864 transferred 178796811 pages 103929 cachemiss 280702 overflow 9940 deltacachemiss 766
> Sep 03 15:01:17 migration status: active (transferred 1377394106, remaining 17633280), total 2114387968)
> Sep 03 15:01:17 migration xbzrle cachesize: 67108864 transferred 181986406 pages 106134 cachemiss 281646 overflow 10131 deltacachemiss 944
> Sep 03 15:01:17 migration status: active (transferred 1383071812, remaining 5853184), total 2114387968)
> Sep 03 15:01:17 migration xbzrle cachesize: 67108864 transferred 184276689 pages 107825 cachemiss 282388 overflow 10216 deltacachemiss 742
> Sep 03 15:01:18 migration status: active (transferred 1389248230, remaining 12910592), total 2114387968)
> Sep 03 15:01:18 migration xbzrle cachesize: 67108864 transferred 187049184 pages 109409 cachemiss 283037 overflow 10398 deltacachemiss 649
> Sep 03 15:01:18 migration status: active (transferred 1395386430, remaining 20598784), total 2114387968)
> Sep 03 15:01:18 migration xbzrle cachesize: 67108864 transferred 189005134 pages 110884 cachemiss 283908 overflow 10548 deltacachemiss 871
> Sep 03 15:01:18 migration status: active (transferred 1402994779, remaining 6443008), total 2114387968)
> Sep 03 15:01:18 migration xbzrle cachesize: 67108864 transferred 191456304 pages 112393 cachemiss 284917 overflow 10798 deltacachemiss 1009
> Sep 03 15:01:19 migration status: active (transferred 1409267086, remaining 13611008), total 2114387968)
> Sep 03 15:01:19 migration xbzrle cachesize: 67108864 transferred 193247446 pages 113783 cachemiss 285846 overflow 10963 deltacachemiss 929
> Sep 03 15:01:19 migration status: active (transferred 1420299927, remaining 6414336), total 2114387968)
> Sep 03 15:01:19 migration xbzrle cachesize: 67108864 transferred 197795949 pages 116951 cachemiss 287280 overflow 11112 deltacachemiss 1434
> Sep 03 15:01:19 migration status: active (transferred 1430776107, remaining 9695232), total 2114387968)
> Sep 03 15:01:19 migration xbzrle cachesize: 67108864 transferred 202680859 pages 120761 cachemiss 288557 overflow 11200 deltacachemiss 1277
> Sep 03 15:01:20 migration status: active (transferred 1440821167, remaining 2637824), total 2114387968)
> Sep 03 15:01:20 migration xbzrle cachesize: 67108864 transferred 208318417 pages 125073 cachemiss 289534 overflow 11299 deltacachemiss 977
> Sep 03 15:01:20 migration status: active (transferred 1447117251, remaining 12091392), total 2114387968)
> Sep 03 15:01:20 migration xbzrle cachesize: 67108864 transferred 211300697 pages 127309 cachemiss 290244 overflow 11398 deltacachemiss 710
> Sep 03 15:01:20 migration status: active (transferred 1456026090, remaining 12906496), total 2114387968)
> Sep 03 15:01:20 migration xbzrle cachesize: 67108864 transferred 216105094 pages 131039 cachemiss 291149 overflow 11495 deltacachemiss 905
> Sep 03 15:01:21 migration status: active (transferred 1463954394, remaining 2822144), total 2114387968)
> Sep 03 15:01:21 migration xbzrle cachesize: 67108864 transferred 220531007 pages 134323 cachemiss 291906 overflow 11593 deltacachemiss 757
> Sep 03 15:01:21 migration status: active (transferred 1470931218, remaining 11534336), total 2114387968)
> Sep 03 15:01:21 migration xbzrle cachesize: 67108864 transferred 223866256 pages 137986 cachemiss 292723 overflow 11665 deltacachemiss 817
> Sep 03 15:01:21 migration status: active (transferred 1477743090, remaining 10235904), total 2114387968)
> Sep 03 15:01:21 migration xbzrle cachesize: 67108864 transferred 227683667 pages 141111 cachemiss 293368 overflow 11751 deltacachemiss 645
> Sep 03 15:01:21 migration status: active (transferred 1486951605, remaining 10551296), total 2114387968)
> Sep 03 15:01:21 migration xbzrle cachesize: 67108864 transferred 232771294 pages 145280 cachemiss 294269 overflow 11856 deltacachemiss 901
> Sep 03 15:01:22 migration status: active (transferred 1493416356, remaining 14299136), total 2114387968)
> Sep 03 15:01:22 migration xbzrle cachesize: 67108864 transferred 235959068 pages 148181 cachemiss 294953 overflow 11972 deltacachemiss 684
> Sep 03 15:01:22 migration status: active (transferred 1502498989, remaining 10592256), total 2114387968)
> Sep 03 15:01:22 migration xbzrle cachesize: 67108864 transferred 240400566 pages 151598 cachemiss 295980 overflow 12078 deltacachemiss 1027
> Sep 03 15:01:22 migration status: active (transferred 1511006667, remaining 10240000), total 2114387968)
> Sep 03 15:01:22 migration xbzrle cachesize: 67108864 transferred 244648073 pages 155655 cachemiss 296923 overflow 12175 deltacachemiss 943
> Sep 03 15:01:23 migration status: active (transferred 1521022229, remaining 10424320), total 2114387968)
> Sep 03 15:01:23 migration xbzrle cachesize: 67108864 transferred 250362498 pages 159932 cachemiss 297842 overflow 12306 deltacachemiss 919
> Sep 03 15:01:23 migration status: active (transferred 1530294933, remaining 9367552), total 2114387968)
> Sep 03 15:01:23 migration xbzrle cachesize: 67108864 transferred 255219350 pages 163947 cachemiss 298815 overflow 12411 deltacachemiss 973
> Sep 03 15:01:23 migration status: active (transferred 1540134732, remaining 9908224), total 2114387968)
> Sep 03 15:01:23 migration xbzrle cachesize: 67108864 transferred 260909578 pages 168294 cachemiss 299727 overflow 12512 deltacachemiss 912
> Sep 03 15:01:24 migration status: active (transferred 1547801099, remaining 2134016), total 2114387968)
> Sep 03 15:01:24 migration xbzrle cachesize: 67108864 transferred 263844849 pages 171252 cachemiss 300772 overflow 12622 deltacachemiss 1045
> Sep 03 15:01:24 migration status: active (transferred 1554064971, remaining 12468224), total 2114387968)
> Sep 03 15:01:24 migration xbzrle cachesize: 67108864 transferred 267032335 pages 173533 cachemiss 301438 overflow 12707 deltacachemiss 666
> Sep 03 15:01:24 migration status: active (transferred 1565158149, remaining 11444224), total 2114387968)
> Sep 03 15:01:24 migration xbzrle cachesize: 67108864 transferred 273009204 pages 178082 cachemiss 302561 overflow 12833 deltacachemiss 1123
> Sep 03 15:01:25 migration status: active (transferred 1574725942, remaining 11866112), total 2114387968)
> Sep 03 15:01:25 migration xbzrle cachesize: 67108864 transferred 278128445 pages 182505 cachemiss 303555 overflow 12925 deltacachemiss 994
> Sep 03 15:01:25 migration status: active (transferred 1584030411, remaining 10473472), total 2114387968)
> Sep 03 15:01:25 migration xbzrle cachesize: 67108864 transferred 282722425 pages 187028 cachemiss 304611 overflow 13019 deltacachemiss 1056
> Sep 03 15:01:25 migration status: active (transferred 1592843701, remaining 2134016), total 2114387968)
> Sep 03 15:01:25 migration xbzrle cachesize: 67108864 transferred 287443772 pages 192031 cachemiss 305549 overflow 13080 deltacachemiss 938
> Sep 03 15:01:26 migration status: active (transferred 1601793792, remaining 6676480), total 2114387968)
> Sep 03 15:01:26 migration xbzrle cachesize: 67108864 transferred 292445279 pages 196112 cachemiss 306407 overflow 13186 deltacachemiss 858
> Sep 03 15:01:26 migration status: active (transferred 1609953585, remaining 12259328), total 2114387968)
> Sep 03 15:01:26 migration xbzrle cachesize: 67108864 transferred 296742516 pages 199610 cachemiss 307294 overflow 13242 deltacachemiss 887
> Sep 03 15:01:26 migration status: active (transferred 1618150798, remaining 4358144), total 2114387968)
> Sep 03 15:01:26 migration xbzrle cachesize: 67108864 transferred 301634218 pages 203248 cachemiss 308022 overflow 13321 deltacachemiss 728
> Sep 03 15:01:26 migration status: active (transferred 1625047015, remaining 11665408), total 2114387968)
> Sep 03 15:01:26 migration xbzrle cachesize: 67108864 transferred 305642729 pages 206530 cachemiss 308695 overflow 13353 deltacachemiss 673
> Sep 03 15:01:27 migration status: active (transferred 1631583544, remaining 8450048), total 2114387968)
> Sep 03 15:01:27 migration xbzrle cachesize: 67108864 transferred 309520928 pages 209601 cachemiss 309308 overflow 13389 deltacachemiss 613
> Sep 03 15:01:27 migration status: active (transferred 1637654847, remaining 7917568), total 2114387968)
> Sep 03 15:01:27 migration xbzrle cachesize: 67108864 transferred 313118229 pages 212178 cachemiss 309876 overflow 13425 deltacachemiss 568
> Sep 03 15:01:27 migration status: active (transferred 1644608997, remaining 6324224), total 2114387968)
> Sep 03 15:01:27 migration xbzrle cachesize: 67108864 transferred 317303461 pages 215070 cachemiss 310504 overflow 13473 deltacachemiss 628
> Sep 03 15:01:28 migration status: active (transferred 1652796103, remaining 4423680), total 2114387968)
> Sep 03 15:01:28 migration xbzrle cachesize: 67108864 transferred 321243002 pages 218055 cachemiss 311465 overflow 13549 deltacachemiss 961
> Sep 03 15:01:28 migration status: active (transferred 1662238886, remaining 12513280), total 2114387968)
> Sep 03 15:01:28 migration xbzrle cachesize: 67108864 transferred 326180167 pages 221148 cachemiss 312524 overflow 13590 deltacachemiss 1059
> Sep 03 15:01:28 migration status: active (transferred 1670338088, remaining 5959680), total 2114387968)
> Sep 03 15:01:28 migration xbzrle cachesize: 67108864 transferred 330945203 pages 224318 cachemiss 313295 overflow 13633 deltacachemiss 771
> Sep 03 15:01:29 migration status: active (transferred 1682607732, remaining 5373952), total 2114387968)
> Sep 03 15:01:29 migration xbzrle cachesize: 67108864 transferred 339032796 pages 228942 cachemiss 314248 overflow 13701 deltacachemiss 953
> Sep 03 15:01:29 migration status: active (transferred 1691288677, remaining 5660672), total 2114387968)
> Sep 03 15:01:29 migration xbzrle cachesize: 67108864 transferred 344379577 pages 232454 cachemiss 315033 overflow 13730 deltacachemiss 785
> Sep 03 15:01:29 migration status: active (transferred 1699318970, remaining 13336576), total 2114387968)
> Sep 03 15:01:29 migration xbzrle cachesize: 67108864 transferred 349546739 pages 235705 cachemiss 315700 overflow 13762 deltacachemiss 667
> Sep 03 15:01:30 migration status: active (transferred 1709411503, remaining 7815168), total 2114387968)
> Sep 03 15:01:30 migration xbzrle cachesize: 67108864 transferred 355408081 pages 238683 cachemiss 316531 overflow 13964 deltacachemiss 831
> Sep 03 15:01:30 migration status: active (transferred 1719503532, remaining 12898304), total 2114387968)
> Sep 03 15:01:30 migration xbzrle cachesize: 67108864 transferred 361350845 pages 241661 cachemiss 317275 overflow 14233 deltacachemiss 744
> Sep 03 15:01:30 migration status: active (transferred 1728857886, remaining 6778880), total 2114387968)
> Sep 03 15:01:30 migration xbzrle cachesize: 67108864 transferred 366736158 pages 244405 cachemiss 317948 overflow 14529 deltacachemiss 673
> Sep 03 15:01:31 migration status: active (transferred 1738122997, remaining 2527232), total 2114387968)
> Sep 03 15:01:31 migration xbzrle cachesize: 67108864 transferred 372220641 pages 246999 cachemiss 318550 overflow 14850 deltacachemiss 602
> Sep 03 15:01:31 migration status: active (transferred 1745051297, remaining 2850816), total 2114387968)
> Sep 03 15:01:31 migration xbzrle cachesize: 67108864 transferred 376056452 pages 248933 cachemiss 319032 overflow 15123 deltacachemiss 482
> Sep 03 15:01:31 migration status: active (transferred 1754719918, remaining 12759040), total 2114387968)
> Sep 03 15:01:31 migration xbzrle cachesize: 67108864 transferred 381239933 pages 251517 cachemiss 319744 overflow 15506 deltacachemiss 712
> Sep 03 15:01:32 migration status: active (transferred 1763103223, remaining 9637888), total 2114387968)
> Sep 03 15:01:32 migration xbzrle cachesize: 67108864 transferred 385265065 pages 254298 cachemiss 320538 overflow 15776 deltacachemiss 794
> Sep 03 15:01:32 migration status: active (transferred 1771003331, remaining 3596288), total 2114387968)
> Sep 03 15:01:32 migration xbzrle cachesize: 67108864 transferred 388708690 pages 257558 cachemiss 321498 overflow 15904 deltacachemiss 960
> Sep 03 15:01:32 migration status: active (transferred 1778157089, remaining 12443648), total 2114387968)
> Sep 03 15:01:32 migration xbzrle cachesize: 67108864 transferred 392561052 pages 260534 cachemiss 322166 overflow 16042 deltacachemiss 668
> Sep 03 15:01:33 migration status: active (transferred 1788495031, remaining 10276864), total 2114387968)
> Sep 03 15:01:33 migration xbzrle cachesize: 67108864 transferred 398295061 pages 264848 cachemiss 323101 overflow 16231 deltacachemiss 935
> Sep 03 15:01:33 migration status: active (transferred 1794009984, remaining 11046912), total 2114387968)
> Sep 03 15:01:33 migration xbzrle cachesize: 67108864 transferred 400795337 pages 266649 cachemiss 323687 overflow 16381 deltacachemiss 586
> Sep 03 15:01:33 migration status: active (transferred 1802929181, remaining 5738496), total 2114387968)
> Sep 03 15:01:33 migration xbzrle cachesize: 67108864 transferred 406032198 pages 269339 cachemiss 324245 overflow 16722 deltacachemiss 558
> Sep 03 15:01:33 migration status: active (transferred 1813019717, remaining 13381632), total 2114387968)
> Sep 03 15:01:33 migration xbzrle cachesize: 67108864 transferred 412084058 pages 272447 cachemiss 324891 overflow 17062 deltacachemiss 646
> Sep 03 15:01:34 migration status: active (transferred 1822507168, remaining 3809280), total 2114387968)
> Sep 03 15:01:34 migration xbzrle cachesize: 67108864 transferred 416672658 pages 275640 cachemiss 325836 overflow 17313 deltacachemiss 945
> Sep 03 15:01:34 migration status: active (transferred 1829060930, remaining 10371072), total 2114387968)
> Sep 03 15:01:34 migration xbzrle cachesize: 67108864 transferred 418147336 pages 279826 cachemiss 327002 overflow 17387 deltacachemiss 1166
> Sep 03 15:01:34 migration status: active (transferred 1835035082, remaining 11374592), total 2114387968)
> Sep 03 15:01:34 migration xbzrle cachesize: 67108864 transferred 419374185 pages 284812 cachemiss 328106 overflow 17442 deltacachemiss 1104
> Sep 03 15:01:35 migration status: active (transferred 1840925069, remaining 11190272), total 2114387968)
> Sep 03 15:01:35 migration xbzrle cachesize: 67108864 transferred 420520965 pages 289916 cachemiss 329221 overflow 17485 deltacachemiss 1115
> Sep 03 15:01:35 migration status: active (transferred 1846770014, remaining 9371648), total 2114387968)
> Sep 03 15:01:35 migration xbzrle cachesize: 67108864 transferred 421458853 pages 294580 cachemiss 330372 overflow 17532 deltacachemiss 1151
> Sep 03 15:01:35 migration status: active (transferred 1853314839, remaining 2514944), total 2114387968)
> Sep 03 15:01:35 migration xbzrle cachesize: 67108864 transferred 423964993 pages 298173 cachemiss 331222 overflow 17668 deltacachemiss 850
> Sep 03 15:01:36 migration status: active (transferred 1862231519, remaining 15454208), total 2114387968)
> Sep 03 15:01:36 migration xbzrle cachesize: 67108864 transferred 428937200 pages 301153 cachemiss 331999 overflow 17854 deltacachemiss 777
> Sep 03 15:01:36 migration status: active (transferred 1870584409, remaining 11419648), total 2114387968)
> Sep 03 15:01:36 migration xbzrle cachesize: 67108864 transferred 431326236 pages 304655 cachemiss 333333 overflow 17976 deltacachemiss 1334
> Sep 03 15:01:36 migration status: active (transferred 1878153329, remaining 4648960), total 2114387968)
> Sep 03 15:01:36 migration xbzrle cachesize: 67108864 transferred 434057751 pages 307541 cachemiss 334375 overflow 18115 deltacachemiss 1042
> Sep 03 15:01:37 migration status: active (transferred 1885289154, remaining 12533760), total 2114387968)
> Sep 03 15:01:37 migration xbzrle cachesize: 67108864 transferred 438228048 pages 310420 cachemiss 334915 overflow 18299 deltacachemiss 540
> Sep 03 15:01:37 migration status: active (transferred 1892622878, remaining 4374528), total 2114387968)
> Sep 03 15:01:37 migration xbzrle cachesize: 67108864 transferred 441490323 pages 313985 cachemiss 335735 overflow 18473 deltacachemiss 820
> Sep 03 15:01:37 migration status: active (transferred 1901073971, remaining 13205504), total 2114387968)
> Sep 03 15:01:37 migration xbzrle cachesize: 67108864 transferred 446529428 pages 316687 cachemiss 336305 overflow 18736 deltacachemiss 570
> Sep 03 15:01:38 migration status: active (transferred 1910878152, remaining 9048064), total 2114387968)
> Sep 03 15:01:38 migration xbzrle cachesize: 67108864 transferred 451586319 pages 319720 cachemiss 337190 overflow 19010 deltacachemiss 885
> Sep 03 15:01:38 migration status: active (transferred 1918738540, remaining 10661888), total 2114387968)
> Sep 03 15:01:38 migration xbzrle cachesize: 67108864 transferred 455338404 pages 321664 cachemiss 337933 overflow 19270 deltacachemiss 743
> Sep 03 15:01:38 migration status: active (transferred 1928827689, remaining 6860800), total 2114387968)
> Sep 03 15:01:38 migration xbzrle cachesize: 67108864 transferred 460549198 pages 324277 cachemiss 338738 overflow 19656 deltacachemiss 805
> Sep 03 15:01:38 migration status: active (transferred 1937151384, remaining 3428352), total 2114387968)
> Sep 03 15:01:38 migration xbzrle cachesize: 67108864 transferred 465043115 pages 326494 cachemiss 339336 overflow 19993 deltacachemiss 598
> Sep 03 15:01:39 migration status: active (transferred 1946239164, remaining 13590528), total 2114387968)
> Sep 03 15:01:39 migration xbzrle cachesize: 67108864 transferred 469952951 pages 328931 cachemiss 339977 overflow 20372 deltacachemiss 641
> Sep 03 15:01:39 migration status: active (transferred 1955868111, remaining 2822144), total 2114387968)
> Sep 03 15:01:39 migration xbzrle cachesize: 67108864 transferred 474850991 pages 332609 cachemiss 340857 overflow 20647 deltacachemiss 880
> Sep 03 15:01:39 migration status: active (transferred 1965033342, remaining 7884800), total 2114387968)
> Sep 03 15:01:39 migration xbzrle cachesize: 67108864 transferred 479064122 pages 336578 cachemiss 341853 overflow 20860 deltacachemiss 996
> Sep 03 15:01:40 migration status: active (transferred 1972991062, remaining 8335360), total 2114387968)
> Sep 03 15:01:40 migration xbzrle cachesize: 67108864 transferred 482389235 pages 340369 cachemiss 342906 overflow 20938 deltacachemiss 1053
> Sep 03 15:01:40 migration status: active (transferred 1978818556, remaining 10371072), total 2114387968)
> Sep 03 15:01:40 migration xbzrle cachesize: 67108864 transferred 483760246 pages 344727 cachemiss 343955 overflow 20977 deltacachemiss 1049
> Sep 03 15:01:40 migration status: active (transferred 1984832873, remaining 2367488), total 2114387968)
> Sep 03 15:01:40 migration xbzrle cachesize: 67108864 transferred 485600711 pages 348240 cachemiss 344922 overflow 21029 deltacachemiss 967
> Sep 03 15:01:41 migration status: active (transferred 1992114731, remaining 4120576), total 2114387968)
> Sep 03 15:01:41 migration xbzrle cachesize: 67108864 transferred 489704053 pages 351282 cachemiss 345551 overflow 21176 deltacachemiss 629
> Sep 03 15:01:41 migration status: active (transferred 2001071596, remaining 12619776), total 2114387968)
> Sep 03 15:01:41 migration xbzrle cachesize: 67108864 transferred 495339032 pages 354218 cachemiss 346153 overflow 21385 deltacachemiss 602
> Sep 03 15:01:41 migration status: active (transferred 2011152290, remaining 5206016), total 2114387968)
> Sep 03 15:01:41 migration xbzrle cachesize: 67108864 transferred 501454775 pages 357298 cachemiss 346854 overflow 21652 deltacachemiss 701
> Sep 03 15:01:42 migration status: active (transferred 2019787845, remaining 4804608), total 2114387968)
> Sep 03 15:01:42 migration xbzrle cachesize: 67108864 transferred 505945161 pages 359691 cachemiss 347502 overflow 22016 deltacachemiss 648
> Sep 03 15:01:42 migration status: active (transferred 2029872444, remaining 12754944), total 2114387968)
> Sep 03 15:01:42 migration xbzrle cachesize: 67108864 transferred 510999852 pages 362419 cachemiss 348359 overflow 22387 deltacachemiss 857
> Sep 03 15:01:42 migration status: active (transferred 2039963167, remaining 5341184), total 2114387968)
> Sep 03 15:01:42 migration xbzrle cachesize: 67108864 transferred 516535788 pages 365431 cachemiss 349089 overflow 22769 deltacachemiss 730
> Sep 03 15:01:42 migration status: active (transferred 2046790518, remaining 13049856), total 2114387968)
> Sep 03 15:01:42 migration xbzrle cachesize: 67108864 transferred 519742235 pages 368455 cachemiss 349752 overflow 22990 deltacachemiss 663
> Sep 03 15:01:43 migration status: active (transferred 2056576433, remaining 6127616), total 2114387968)
> Sep 03 15:01:43 migration xbzrle cachesize: 67108864 transferred 524764472 pages 371518 cachemiss 350495 overflow 23410 deltacachemiss 743
> Sep 03 15:01:43 migration status: active (transferred 2070030632, remaining 5545984), total 2114387968)
> Sep 03 15:01:43 migration xbzrle cachesize: 67108864 transferred 532054161 pages 375458 cachemiss 351436 overflow 23974 deltacachemiss 941
> Sep 03 15:01:43 migration status: active (transferred 2080122845, remaining 16842752), total 2114387968)
> Sep 03 15:01:43 migration xbzrle cachesize: 67108864 transferred 537186091 pages 378300 cachemiss 352183 overflow 24438 deltacachemiss 747
> Sep 03 15:01:44 migration status: active (transferred 2089596231, remaining 19959808), total 2114387968)
> Sep 03 15:01:44 migration xbzrle cachesize: 67108864 transferred 541281406 pages 380898 cachemiss 353159 overflow 24775 deltacachemiss 976
> Sep 03 15:01:44 migration status: active (transferred 2098744287, remaining 3334144), total 2114387968)
> Sep 03 15:01:44 migration xbzrle cachesize: 67108864 transferred 544596639 pages 382825 cachemiss 354171 overflow 25187 deltacachemiss 1012
> Sep 03 15:01:44 migration status: active (transferred 2107347747, remaining 8888320), total 2114387968)
> Sep 03 15:01:44 migration xbzrle cachesize: 67108864 transferred 547735772 pages 384605 cachemiss 355136 overflow 25556 deltacachemiss 965
> Sep 03 15:01:45 migration status: active (transferred 2117427470, remaining 6184960), total 2114387968)
> Sep 03 15:01:45 migration xbzrle cachesize: 67108864 transferred 551515759 pages 386875 cachemiss 356245 overflow 25985 deltacachemiss 1109
> Sep 03 15:01:45 migration status: active (transferred 2127522180, remaining 6643712), total 2114387968)
> Sep 03 15:01:45 migration xbzrle cachesize: 67108864 transferred 555519519 pages 389206 cachemiss 357355 overflow 26362 deltacachemiss 1110
> Sep 03 15:01:45 migration status: active (transferred 2137180181, remaining 6840320), total 2114387968)
> Sep 03 15:01:45 migration xbzrle cachesize: 67108864 transferred 559197228 pages 391393 cachemiss 358357 overflow 26820 deltacachemiss 1002
> Sep 03 15:01:46 migration status: active (transferred 2146653892, remaining 7704576), total 2114387968)
> Sep 03 15:01:46 migration xbzrle cachesize: 67108864 transferred 563133130 pages 393677 cachemiss 359363 overflow 27166 deltacachemiss 1006
> Sep 03 15:01:46 migration status: active (transferred 2156170786, remaining 8384512), total 2114387968)
> Sep 03 15:01:46 migration xbzrle cachesize: 67108864 transferred 566870481 pages 395661 cachemiss 360401 overflow 27539 deltacachemiss 1038
> Sep 03 15:01:46 migration status: active (transferred 2162116052, remaining 18784256), total 2114387968)
> Sep 03 15:01:46 migration xbzrle cachesize: 67108864 transferred 569030821 pages 396971 cachemiss 361078 overflow 27786 deltacachemiss 677
> Sep 03 15:01:47 migration status: active (transferred 2167440600, remaining 10747904), total 2114387968)
> Sep 03 15:01:47 migration xbzrle cachesize: 67108864 transferred 570951584 pages 397932 cachemiss 361557 overflow 28138 deltacachemiss 479
> Sep 03 15:01:47 migration status: active (transferred 2173189492, remaining 25628672), total 2114387968)
> Sep 03 15:01:47 migration xbzrle cachesize: 67108864 transferred 572772376 pages 399193 cachemiss 362323 overflow 28331 deltacachemiss 766
> Sep 03 15:01:47 migration status: active (transferred 2181582500, remaining 8200192), total 2114387968)
> Sep 03 15:01:47 migration xbzrle cachesize: 67108864 transferred 575605975 pages 400618 cachemiss 363152 overflow 28859 deltacachemiss 829
> Sep 03 15:01:47 migration status: active (transferred 2189847788, remaining 11202560), total 2114387968)
> Sep 03 15:01:47 migration xbzrle cachesize: 67108864 transferred 578513648 pages 402362 cachemiss 364245 overflow 29074 deltacachemiss 1093
> Sep 03 15:01:48 migration status: active (transferred 2195877255, remaining 14094336), total 2114387968)
> Sep 03 15:01:48 migration xbzrle cachesize: 67108864 transferred 580246400 pages 404116 cachemiss 365082 overflow 29286 deltacachemiss 837
> Sep 03 15:01:48 migration status: active (transferred 2202598243, remaining 12357632), total 2114387968)
> Sep 03 15:01:48 migration xbzrle cachesize: 67108864 transferred 581462307 pages 407577 cachemiss 366385 overflow 29327 deltacachemiss 1303
> Sep 03 15:01:48 migration status: active (transferred 2210798256, remaining 2859008), total 2114387968)
> Sep 03 15:01:48 migration xbzrle cachesize: 67108864 transferred 583350325 pages 413084 cachemiss 367860 overflow 29393 deltacachemiss 1475
> Sep 03 15:01:49 migration status: active (transferred 2217322581, remaining 7753728), total 2114387968)
> Sep 03 15:01:49 migration xbzrle cachesize: 67108864 transferred 586159554 pages 415753 cachemiss 368500 overflow 29660 deltacachemiss 640
> Sep 03 15:01:49 migration status: active (transferred 2222843364, remaining 10366976), total 2114387968)
> Sep 03 15:01:49 migration xbzrle cachesize: 67108864 transferred 589009723 pages 417307 cachemiss 368910 overflow 29902 deltacachemiss 410
> Sep 03 15:01:49 migration status: active (transferred 2229668707, remaining 12546048), total 2114387968)
> Sep 03 15:01:49 migration xbzrle cachesize: 67108864 transferred 592545964 pages 419113 cachemiss 369404 overflow 30211 deltacachemiss 494
> Sep 03 15:01:50 migration status: active (transferred 2238229988, remaining 13078528), total 2114387968)
> 

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

* Re: [Qemu-devel] [PATCH 2/6] libqblock public type defines
  2012-09-04  7:38       ` Paolo Bonzini
@ 2012-09-04 19:22         ` Blue Swirl
  2012-09-10  8:22           ` Wenchao Xia
  0 siblings, 1 reply; 46+ messages in thread
From: Blue Swirl @ 2012-09-04 19:22 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: kwolf, aliguori, stefanha, qemu-devel, eblake, Wenchao Xia

On Tue, Sep 4, 2012 at 7:38 AM, Paolo Bonzini <pbonzini@redhat.com> wrote:
> Il 04/09/2012 09:19, Wenchao Xia ha scritto:
>>>>
>>>> +struct QBlockOption_prot_file {
>>>
>>> QBlockOptionProtFile
>>>
>>>> +    char *filename;
>>>
>>> 'const'
>>>
>>   There is a problem, this member would be used in information
>> retrieving, so it will be set to a pointer to a string allocated
>> at runtime, and later be freed. I am not sure if const fits for this
>> situation, let me check.
>
> No, const would add useless complication.  In C++ it is different
> because you have constructors.

Using 'const' would mean that it's also possible for the client to use
constant strings without casts which remove 'const' qualifier. This
will be important if the client code is compiled with -Wcast-qual.
QEMU does not use it ATM, but we also don't control what compiler
flags are used for the client.

'const' also tells the developer that the library will not modify or
free the string, so there's documentation value.

>
> Paolo

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

* Re: [Qemu-devel] [PATCH 1/6] libqblock APIs
  2012-09-04  6:50       ` Paolo Bonzini
  2012-09-04  9:05         ` Wenchao Xia
@ 2012-09-10  8:10         ` Wenchao Xia
  1 sibling, 0 replies; 46+ messages in thread
From: Wenchao Xia @ 2012-09-10  8:10 UTC (permalink / raw)
  To: qemu-devel, Paolo Bonzini

 > Il 04/09/2012 05:15, Wenchao Xia ha scritto:
>>>
>>> Can you use GError instead?
>>>
>>    read through the GError doc, GError is defined as following:
>> struct GError {
>>    GQuark       domain;
>>    gint         code;
>>    gchar       *message;
>> };
>>    I am worried about the message member, I guess program would be
>> aborted if OOM, which I was tring to avoid, so I used char err_msg[1024]
>> in my code, and make things simpler.
>
> That's true.  On the other hand, and IMHO, not aborting in the library
> code is a non-goal as long as the rest of the block layer still does.
>
   About the Gerror lib, with a look at its doc, I think it provides
similar capabilities with my implement, no key feature provided.
Considering the memory issue, I hope to drop Gerror now.

>>>>     3 QBlockInfoImageStatic. Now it is not folded with location and
>>>> format.
>>>
>>> What does "Static" mean?
>>>
>>   It is about sorting the information into following kinds:
>> 1) static. It is values that defined at creating time/modifying time,
>> mostly some settings, and it would not be automatically changed in I/O.
>> 2) dynamic. Some information that would changes in I/O and other
>> operations, such as allocated_size, snapshots.
>> 3) statistics.
>>    Now only static one is provided, so I added _static suffix.
>
> Makes sense, thanks for the clarification.  Perhaps QBlockStaticInfo is
> a shorter and simpler name?
>
> Paolo
>


-- 
Best Regards

Wenchao Xia

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

* Re: [Qemu-devel] [PATCH 3/6] libqblock error handling
  2012-09-03 14:22   ` Eric Blake
  2012-09-04  7:12     ` Wenchao Xia
@ 2012-09-10  8:20     ` Wenchao Xia
  1 sibling, 0 replies; 46+ messages in thread
From: Wenchao Xia @ 2012-09-10  8:20 UTC (permalink / raw)
  To: Eric Blake; +Cc: kwolf, pbonzini, aliguori, qemu-devel, stefanha

   about the error number defines, I think using union instead of macro
will cause additional trouble:
int64_t qb_read()
   In this case return is type int64_t, and it may return the error
number, so using unions for error number would not provide much help.
   Other issues you mentioned have been fixed in next version.

> On 09/03/2012 03:18 AM, Wenchao Xia wrote:
>>    This patch contains error handling APIs.
>>
>> Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
>> ---
>>   libqblock/libqblock-error.c |   44 +++++++++++++++++++++++++++++++++++++++++++
>>   libqblock/libqblock-error.h |   34 +++++++++++++++++++++++++++++++++
>>   2 files changed, 78 insertions(+), 0 deletions(-)
>>   create mode 100644 libqblock/libqblock-error.c
>>   create mode 100644 libqblock/libqblock-error.h
>>
>> diff --git a/libqblock/libqblock-error.c b/libqblock/libqblock-error.c
>> new file mode 100644
>> index 0000000..28d1d77
>> --- /dev/null
>> +++ b/libqblock/libqblock-error.c
>> @@ -0,0 +1,44 @@
>> +#include "libqblock-error.h"
>
> No copyright.  Shame.
>
>> +++ b/libqblock/libqblock-error.h
>> @@ -0,0 +1,34 @@
>> +#ifndef LIBQBLOCK_ERROR
>
> No copyright.  Shame.
>
>> +#define LIBQBLOCK_ERROR
>> +
>> +#include "libqblock-types.h"
>> +
>> +#define QB_ERR_MEM_ERR (-1)
>> +#define QB_ERR_INTERNAL_ERR (-2)
>> +#define QB_ERR_INVALID_PARAM (-3)
>> +#define QB_ERR_BLOCK_OUT_OF_RANGE (-100)
>
> Would an enum make more sense than #defines?
>
>> +
>> +/* error handling */
>> +/**
>> + * qb_error_get_human_str: get human readable erro string.
>
> s/erro/error/
>
>> + *
>> + * return a human readable string.
>> + *
>> + * @broker: operation broker, must be valid.
>> + * @buf: buf to receive the string.
>> + * @buf_size: the size of the string buf.
>> + */
>> +void qb_error_get_human_str(struct QBroker *broker,
>> +                            char *buf, int buf_size);
>
> What happens if buf_size is too small to receive the entire error
> message?  Should this function return int, with negative value on input
> error?
>


-- 
Best Regards

Wenchao Xia

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

* Re: [Qemu-devel] [PATCH 2/6] libqblock public type defines
  2012-09-04 19:22         ` Blue Swirl
@ 2012-09-10  8:22           ` Wenchao Xia
  0 siblings, 0 replies; 46+ messages in thread
From: Wenchao Xia @ 2012-09-10  8:22 UTC (permalink / raw)
  To: Blue Swirl; +Cc: kwolf, aliguori, stefanha, qemu-devel, Paolo Bonzini, eblake

changed to const, thanks.

> On Tue, Sep 4, 2012 at 7:38 AM, Paolo Bonzini <pbonzini@redhat.com> wrote:
>> Il 04/09/2012 09:19, Wenchao Xia ha scritto:
>>>>>
>>>>> +struct QBlockOption_prot_file {
>>>>
>>>> QBlockOptionProtFile
>>>>
>>>>> +    char *filename;
>>>>
>>>> 'const'
>>>>
>>>    There is a problem, this member would be used in information
>>> retrieving, so it will be set to a pointer to a string allocated
>>> at runtime, and later be freed. I am not sure if const fits for this
>>> situation, let me check.
>>
>> No, const would add useless complication.  In C++ it is different
>> because you have constructors.
>
> Using 'const' would mean that it's also possible for the client to use
> constant strings without casts which remove 'const' qualifier. This
> will be important if the client code is compiled with -Wcast-qual.
> QEMU does not use it ATM, but we also don't control what compiler
> flags are used for the client.
>
> 'const' also tells the developer that the library will not modify or
> free the string, so there's documentation value.
>
>>
>> Paolo
>


-- 
Best Regards

Wenchao Xia

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

* Re: [Qemu-devel] [PATCH 4/6] libqblock internal used functions
  2012-09-04 13:51             ` Kevin Wolf
@ 2012-09-10  8:23               ` Wenchao Xia
  0 siblings, 0 replies; 46+ messages in thread
From: Wenchao Xia @ 2012-09-10  8:23 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: Paolo Bonzini, aliguori, Eric Blake, qemu-devel, stefanha

Using unit byte now, thanks.

> Am 04.09.2012 15:49, schrieb Paolo Bonzini:
>> Il 04/09/2012 13:38, Eric Blake ha scritto:
>>> Since qemu does not support it now, yes, you can ignore it for now.  But
>>> please make sure that you aren't hard-coding it into the API - that is,
>>> make sure that the API can someday grow to support larger sector sizes
>>> with minimal impact to library clients (that is, that new clients aware
>>> of the new API can target larger sector size once qemu has been patched
>>> to support larger sector size).
>>
>> We can support 4k sector disks even if the addressing unit remains 512
>> bytes, just like in the Linux kernel.
>
> Why should we even use an arbitrary unit like 512 bytes for addressing?
> To me using byte granularity everywhere makes more sense and is clearer.
>
> Kevin
>


-- 
Best Regards

Wenchao Xia

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

end of thread, other threads:[~2012-09-10  8:23 UTC | newest]

Thread overview: 46+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-09-03  9:18 [Qemu-devel] [PATCH 0/6] libqblock, qemu block layer library Wenchao Xia
2012-09-03  9:18 ` [Qemu-devel] [PATCH 1/6] libqblock APIs Wenchao Xia
2012-09-03 13:18   ` Paolo Bonzini
2012-09-04  3:15     ` Wenchao Xia
2012-09-04  6:50       ` Paolo Bonzini
2012-09-04  9:05         ` Wenchao Xia
2012-09-10  8:10         ` Wenchao Xia
2012-09-03 13:56   ` Eric Blake
2012-09-03 14:05     ` Paolo Bonzini
2012-09-04  7:05       ` Wenchao Xia
2012-09-04  7:29         ` Paolo Bonzini
2012-09-04  6:42     ` Wenchao Xia
2012-09-04 11:35       ` Eric Blake
2012-09-04 13:47         ` Paolo Bonzini
2012-09-03 19:22   ` Blue Swirl
2012-09-03  9:18 ` [Qemu-devel] [PATCH 2/6] libqblock public type defines Wenchao Xia
2012-09-03 13:13   ` Paolo Bonzini
2012-09-04  2:00     ` Wenchao Xia
2012-09-03 14:20   ` Eric Blake
2012-09-04  7:10     ` Wenchao Xia
2012-09-04  7:37       ` Paolo Bonzini
2012-09-03 19:31   ` Blue Swirl
2012-09-04  7:19     ` Wenchao Xia
2012-09-04  7:38       ` Paolo Bonzini
2012-09-04 19:22         ` Blue Swirl
2012-09-10  8:22           ` Wenchao Xia
2012-09-03  9:18 ` [Qemu-devel] [PATCH 3/6] libqblock error handling Wenchao Xia
2012-09-03 14:22   ` Eric Blake
2012-09-04  7:12     ` Wenchao Xia
2012-09-10  8:20     ` Wenchao Xia
2012-09-03  9:18 ` [Qemu-devel] [PATCH 4/6] libqblock internal used functions Wenchao Xia
2012-09-03 13:18   ` Paolo Bonzini
2012-09-04  3:19     ` Wenchao Xia
2012-09-03 14:28   ` Eric Blake
2012-09-03 15:18     ` Paolo Bonzini
2012-09-04  7:15       ` Wenchao Xia
2012-09-04  7:38         ` Paolo Bonzini
2012-09-04 11:38         ` Eric Blake
2012-09-04 13:49           ` Paolo Bonzini
2012-09-04 13:51             ` Kevin Wolf
2012-09-10  8:23               ` Wenchao Xia
2012-09-03  9:18 ` [Qemu-devel] [PATCH 5/6] libqblock test example Wenchao Xia
2012-09-03 19:27   ` Blue Swirl
2012-09-03  9:18 ` [Qemu-devel] [PATCH 6/6] libqblock building system Wenchao Xia
2012-09-03 13:10   ` [Qemu-devel] xbzrle migration cache size advise for high memory changes workload ? Alexandre DERUMIER
2012-09-04 14:05     ` Orit Wasserman

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.