218e99
From 64d9964fc97fc525b86e12c5f385dea7e646a3b0 Mon Sep 17 00:00:00 2001
218e99
Message-Id: <64d9964fc97fc525b86e12c5f385dea7e646a3b0.1383564115.git.minovotn@redhat.com>
218e99
In-Reply-To: <5575e0aec51f40ebec46e98ec085cda053283aba.1383564115.git.minovotn@redhat.com>
218e99
References: <5575e0aec51f40ebec46e98ec085cda053283aba.1383564115.git.minovotn@redhat.com>
218e99
From: Kevin Wolf <kwolf@redhat.com>
218e99
Date: Thu, 31 Oct 2013 12:13:13 +0100
218e99
Subject: [PATCH 12/14] rbd: link and load librbd dynamically
218e99
218e99
RH-Author: Kevin Wolf <kwolf@redhat.com>
218e99
Message-id: <1383221595-24285-2-git-send-email-kwolf@redhat.com>
218e99
Patchwork-id: 55183
218e99
O-Subject: [RHEL-7.0 qemu-kvm PATCH 1/3] rbd: link and load librbd dynamically
218e99
Bugzilla: 989608
218e99
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
218e99
RH-Acked-by: Fam Zheng <famz@redhat.com>
218e99
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
218e99
218e99
Bugzilla: 989608
218e99
Upstream status: Rejected
218e99
Downstream status: Forward ported from RHEL 6
218e99
218e99
This is the downstream-only part that gets us rid of the build-time
218e99
dependency on librbd and loads it dynamically when using an image.
218e99
It is based on a patch submitted to qemu-devel and archived as
218e99
http://lists.gnu.org/archive/html/qemu-devel/2013-04/msg01814.html
218e99
218e99
For the forward-port to RHEL 7, I decided to implement the review
218e99
suggestions from RHEL 6 to move the function pointers out of a separate
218e99
struct to the top level, so that callers don't have to be changed
218e99
compared to upstream. This should also reduce merge conflicts in future
218e99
forward-ports.
218e99
218e99
Note that this is not much more than compile tested; the real testing
218e99
will be done by Inktank as soon as they can access RHEL 7.
218e99
218e99
Original commit message follows:
218e99
218e99
This allows the rbd block driver to detect symbols in the installed
218e99
version of librbd, and enable or disable features appropriately.  This
218e99
obviates the #ifdefs regarding librbd versions.
218e99
218e99
Loading librbd dynamically also makes the rbd block driver easier to
218e99
install and package, since it removes the dependency on librbd at
218e99
build time.
218e99
218e99
Add structures containing the necessary function pointer signatures
218e99
and types from librbd, and fill them in the first time the rbd module
218e99
is used. Use glib's g_module interface so we don't preclude future
218e99
portability, and don't have to deal with odd dlopen behavior directly.
218e99
218e99
Internally, librbd and some libraries it depends on use C++ templates,
218e99
which mean that they each contain a defined weak symbol for their
218e99
definition.  Due to the way the linker resolves duplicate symbols, the
218e99
libraries loaded by librbd end up using the template definitions from
218e99
librbd, creating a circular dependency. This means that once librbd is
218e99
loaded, it won't be unloaded. Changing this behavior might work with a
218e99
Sun ld, but there doesn't seem to be a portable (or even working with
218e99
GNU ld) way to hide these C++ symbols correctly. Instead, never unload
218e99
librbd, and explicitly make it resident.
218e99
218e99
Signed-off-by: Josh Durgin <josh.durgin@inktank.com>
218e99
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
218e99
---
218e99
 block/Makefile.objs |   2 +-
218e99
 block/rbd.c         | 218 ++++++++++++++++++++++++++++++++++++++++------------
218e99
 block/rbd_types.h   |  91 ++++++++++++++++++++++
218e99
 configure           |  41 +---------
218e99
 4 files changed, 263 insertions(+), 89 deletions(-)
218e99
 create mode 100644 block/rbd_types.h
218e99
218e99
Signed-off-by: Michal Novotny <minovotn@redhat.com>
218e99
---
218e99
 block/Makefile.objs |   2 +-
218e99
 block/rbd.c         | 218 ++++++++++++++++++++++++++++++++++++++++------------
218e99
 block/rbd_types.h   |  91 ++++++++++++++++++++++
218e99
 configure           |  41 +---------
218e99
 4 files changed, 263 insertions(+), 89 deletions(-)
218e99
 create mode 100644 block/rbd_types.h
218e99
218e99
diff --git a/block/Makefile.objs b/block/Makefile.objs
218e99
index 5f0358a..6b8d5ec 100644
218e99
--- a/block/Makefile.objs
218e99
+++ b/block/Makefile.objs
218e99
@@ -12,7 +12,7 @@ ifeq ($(CONFIG_POSIX),y)
218e99
 block-obj-y += nbd.o sheepdog.o
218e99
 block-obj-$(CONFIG_LIBISCSI) += iscsi.o
218e99
 block-obj-$(CONFIG_CURL) += curl.o
218e99
-block-obj-$(CONFIG_RBD) += rbd.o
218e99
+block-obj-y += rbd.o
218e99
 block-obj-$(CONFIG_GLUSTERFS) += gluster.o
218e99
 block-obj-$(CONFIG_LIBSSH2) += ssh.o
218e99
 endif
218e99
diff --git a/block/rbd.c b/block/rbd.c
218e99
index 0f2608b..7f5cfca 100644
218e99
--- a/block/rbd.c
218e99
+++ b/block/rbd.c
218e99
@@ -11,13 +11,14 @@
218e99
  * GNU GPL, version 2 or (at your option) any later version.
218e99
  */
218e99
 
218e99
+#include <gmodule.h>
218e99
 #include <inttypes.h>
218e99
 
218e99
 #include "qemu-common.h"
218e99
 #include "qemu/error-report.h"
218e99
 #include "block/block_int.h"
218e99
 
218e99
-#include <rbd/librbd.h>
218e99
+#include "rbd_types.h"
218e99
 
218e99
 /*
218e99
  * When specifying the image filename use:
218e99
@@ -44,13 +45,6 @@
218e99
  * leading "\".
218e99
  */
218e99
 
218e99
-/* rbd_aio_discard added in 0.1.2 */
218e99
-#if LIBRBD_VERSION_CODE >= LIBRBD_VERSION(0, 1, 2)
218e99
-#define LIBRBD_SUPPORTS_DISCARD
218e99
-#else
218e99
-#undef LIBRBD_SUPPORTS_DISCARD
218e99
-#endif
218e99
-
218e99
 #define OBJ_MAX_SIZE (1UL << OBJ_DEFAULT_OBJ_ORDER)
218e99
 
218e99
 #define RBD_MAX_CONF_NAME_SIZE 128
218e99
@@ -106,6 +100,10 @@ typedef struct BDRVRBDState {
218e99
     RADOSCB *event_rcb;
218e99
 } BDRVRBDState;
218e99
 
218e99
+static bool librbd_loaded;
218e99
+static GModule *librbd_handle;
218e99
+
218e99
+static int qemu_rbd_load_libs(void);
218e99
 static void rbd_aio_bh_cb(void *opaque);
218e99
 
218e99
 static int qemu_rbd_next_tok(char *dst, int dst_len,
218e99
@@ -310,6 +308,10 @@ static int qemu_rbd_create(const char *filename, QEMUOptionParameter *options)
218e99
         return -EINVAL;
218e99
     }
218e99
 
218e99
+    if (qemu_rbd_load_libs() < 0) {
218e99
+        return -EIO;
218e99
+    }
218e99
+
218e99
     /* Read out options */
218e99
     while (options && options->name) {
218e99
         if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
218e99
@@ -487,6 +489,10 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags)
218e99
         goto failed_opts;
218e99
     }
218e99
 
218e99
+    if (qemu_rbd_load_libs() < 0) {
218e99
+        return -EIO;
218e99
+    }
218e99
+
218e99
     clientname = qemu_rbd_parse_clientname(conf, clientname_buf);
218e99
     r = rados_create(&s->cluster, clientname);
218e99
     if (r < 0) {
218e99
@@ -678,28 +684,6 @@ static void rbd_aio_bh_cb(void *opaque)
218e99
     }
218e99
 }
218e99
 
218e99
-static int rbd_aio_discard_wrapper(rbd_image_t image,
218e99
-                                   uint64_t off,
218e99
-                                   uint64_t len,
218e99
-                                   rbd_completion_t comp)
218e99
-{
218e99
-#ifdef LIBRBD_SUPPORTS_DISCARD
218e99
-    return rbd_aio_discard(image, off, len, comp);
218e99
-#else
218e99
-    return -ENOTSUP;
218e99
-#endif
218e99
-}
218e99
-
218e99
-static int rbd_aio_flush_wrapper(rbd_image_t image,
218e99
-                                 rbd_completion_t comp)
218e99
-{
218e99
-#ifdef LIBRBD_SUPPORTS_AIO_FLUSH
218e99
-    return rbd_aio_flush(image, comp);
218e99
-#else
218e99
-    return -ENOTSUP;
218e99
-#endif
218e99
-}
218e99
-
218e99
 static BlockDriverAIOCB *rbd_start_aio(BlockDriverState *bs,
218e99
                                        int64_t sector_num,
218e99
                                        QEMUIOVector *qiov,
218e99
@@ -762,10 +746,10 @@ static BlockDriverAIOCB *rbd_start_aio(BlockDriverState *bs,
218e99
         r = rbd_aio_read(s->image, off, size, buf, c);
218e99
         break;
218e99
     case RBD_AIO_DISCARD:
218e99
-        r = rbd_aio_discard_wrapper(s->image, off, size, c);
218e99
+        r = rbd_aio_discard(s->image, off, size, c);
218e99
         break;
218e99
     case RBD_AIO_FLUSH:
218e99
-        r = rbd_aio_flush_wrapper(s->image, c);
218e99
+        r = rbd_aio_flush(s->image, c);
218e99
         break;
218e99
     default:
218e99
         r = -EINVAL;
218e99
@@ -806,7 +790,6 @@ static BlockDriverAIOCB *qemu_rbd_aio_writev(BlockDriverState *bs,
218e99
                          RBD_AIO_WRITE);
218e99
 }
218e99
 
218e99
-#ifdef LIBRBD_SUPPORTS_AIO_FLUSH
218e99
 static BlockDriverAIOCB *qemu_rbd_aio_flush(BlockDriverState *bs,
218e99
                                             BlockDriverCompletionFunc *cb,
218e99
                                             void *opaque)
218e99
@@ -814,19 +797,14 @@ static BlockDriverAIOCB *qemu_rbd_aio_flush(BlockDriverState *bs,
218e99
     return rbd_start_aio(bs, 0, NULL, 0, cb, opaque, RBD_AIO_FLUSH);
218e99
 }
218e99
 
218e99
-#else
218e99
-
218e99
 static int qemu_rbd_co_flush(BlockDriverState *bs)
218e99
 {
218e99
-#if LIBRBD_VERSION_CODE >= LIBRBD_VERSION(0, 1, 1)
218e99
-    /* rbd_flush added in 0.1.1 */
218e99
     BDRVRBDState *s = bs->opaque;
218e99
-    return rbd_flush(s->image);
218e99
-#else
218e99
+    if (rbd_flush) {
218e99
+        return rbd_flush(s->image);
218e99
+    }
218e99
     return 0;
218e99
-#endif
218e99
 }
218e99
-#endif
218e99
 
218e99
 static int qemu_rbd_getinfo(BlockDriverState *bs, BlockDriverInfo *bdi)
218e99
 {
218e99
@@ -964,7 +942,6 @@ static int qemu_rbd_snap_list(BlockDriverState *bs,
218e99
     return snap_count;
218e99
 }
218e99
 
218e99
-#ifdef LIBRBD_SUPPORTS_DISCARD
218e99
 static BlockDriverAIOCB* qemu_rbd_aio_discard(BlockDriverState *bs,
218e99
                                               int64_t sector_num,
218e99
                                               int nb_sectors,
218e99
@@ -974,7 +951,6 @@ static BlockDriverAIOCB* qemu_rbd_aio_discard(BlockDriverState *bs,
218e99
     return rbd_start_aio(bs, sector_num, NULL, nb_sectors, cb, opaque,
218e99
                          RBD_AIO_DISCARD);
218e99
 }
218e99
-#endif
218e99
 
218e99
 static QEMUOptionParameter qemu_rbd_create_options[] = {
218e99
     {
218e99
@@ -1004,16 +980,9 @@ static BlockDriver bdrv_rbd = {
218e99
 
218e99
     .bdrv_aio_readv         = qemu_rbd_aio_readv,
218e99
     .bdrv_aio_writev        = qemu_rbd_aio_writev,
218e99
-
218e99
-#ifdef LIBRBD_SUPPORTS_AIO_FLUSH
218e99
     .bdrv_aio_flush         = qemu_rbd_aio_flush,
218e99
-#else
218e99
     .bdrv_co_flush_to_disk  = qemu_rbd_co_flush,
218e99
-#endif
218e99
-
218e99
-#ifdef LIBRBD_SUPPORTS_DISCARD
218e99
     .bdrv_aio_discard       = qemu_rbd_aio_discard,
218e99
-#endif
218e99
 
218e99
     .bdrv_snapshot_create   = qemu_rbd_snap_create,
218e99
     .bdrv_snapshot_delete   = qemu_rbd_snap_remove,
218e99
@@ -1026,4 +995,153 @@ static void bdrv_rbd_init(void)
218e99
     bdrv_register(&bdrv_rbd);
218e99
 }
218e99
 
218e99
+typedef struct LibSymbol {
218e99
+    const char *name;
218e99
+    gpointer *addr;
218e99
+} LibSymbol;
218e99
+
218e99
+static int qemu_rbd_set_functions(GModule *lib, const LibSymbol *funcs)
218e99
+{
218e99
+    int i = 0;
218e99
+    while (funcs[i].name) {
218e99
+        const char *name = funcs[i].name;
218e99
+        if (!g_module_symbol(lib, name, funcs[i].addr)) {
218e99
+            error_report("%s could not be loaded from librbd or librados: %s",
218e99
+                         name, g_module_error());
218e99
+            return -1;
218e99
+        }
218e99
+        ++i;
218e99
+    }
218e99
+    return 0;
218e99
+}
218e99
+
218e99
+/*
218e99
+ * Set function pointers for basic librados and librbd
218e99
+ * functions that have always been present in these libraries.
218e99
+ */
218e99
+static int qemu_rbd_set_mandatory_functions(void)
218e99
+{
218e99
+    LibSymbol symbols[] = {
218e99
+        {"rados_create",
218e99
+         (gpointer *) &rados_create},
218e99
+        {"rados_connect",
218e99
+         (gpointer *) &rados_connect},
218e99
+        {"rados_shutdown",
218e99
+         (gpointer *) &rados_shutdown},
218e99
+        {"rados_conf_read_file",
218e99
+         (gpointer *) &rados_conf_read_file},
218e99
+        {"rados_conf_set",
218e99
+         (gpointer *) &rados_conf_set},
218e99
+        {"rados_ioctx_create",
218e99
+         (gpointer *) &rados_ioctx_create},
218e99
+        {"rados_ioctx_destroy",
218e99
+         (gpointer *) &rados_ioctx_destroy},
218e99
+        {"rbd_create",
218e99
+         (gpointer *) &rbd_create},
218e99
+        {"rbd_open",
218e99
+         (gpointer *) &rbd_open},
218e99
+        {"rbd_close",
218e99
+         (gpointer *) &rbd_close},
218e99
+        {"rbd_resize",
218e99
+         (gpointer *) &rbd_resize},
218e99
+        {"rbd_stat",
218e99
+         (gpointer *) &rbd_stat},
218e99
+        {"rbd_snap_list",
218e99
+         (gpointer *) &rbd_snap_list},
218e99
+        {"rbd_snap_list_end",
218e99
+         (gpointer *) &rbd_snap_list_end},
218e99
+        {"rbd_snap_create",
218e99
+         (gpointer *) &rbd_snap_create},
218e99
+        {"rbd_snap_remove",
218e99
+         (gpointer *) &rbd_snap_remove},
218e99
+        {"rbd_snap_rollback",
218e99
+         (gpointer *) &rbd_snap_rollback},
218e99
+        {"rbd_aio_write",
218e99
+         (gpointer *) &rbd_aio_write},
218e99
+        {"rbd_aio_read",
218e99
+         (gpointer *) &rbd_aio_read},
218e99
+        {"rbd_aio_create_completion",
218e99
+         (gpointer *) &rbd_aio_create_completion},
218e99
+        {"rbd_aio_get_return_value",
218e99
+         (gpointer *) &rbd_aio_get_return_value},
218e99
+        {"rbd_aio_release",
218e99
+         (gpointer *) &rbd_aio_release},
218e99
+        {NULL}
218e99
+    };
218e99
+
218e99
+    if (qemu_rbd_set_functions(librbd_handle, symbols) < 0) {
218e99
+        return -1;
218e99
+    }
218e99
+
218e99
+    return 0;
218e99
+}
218e99
+
218e99
+/*
218e99
+ * Detect whether the installed version of librbd
218e99
+ * supports newer functionality, and enable or disable
218e99
+ * it appropriately in bdrv_rbd.
218e99
+ */
218e99
+static void qemu_rbd_set_optional_functions(void)
218e99
+{
218e99
+    if (g_module_symbol(librbd_handle, "rbd_flush",
218e99
+                         (gpointer *) &rbd_flush)) {
218e99
+        bdrv_rbd.bdrv_aio_flush = NULL;
218e99
+        bdrv_rbd.bdrv_co_flush_to_disk = qemu_rbd_co_flush;
218e99
+    } else {
218e99
+        rbd_flush = NULL;
218e99
+        bdrv_rbd.bdrv_co_flush_to_disk = NULL;
218e99
+    }
218e99
+
218e99
+    if (g_module_symbol(librbd_handle, "rbd_aio_flush",
218e99
+                        (gpointer *) &rbd_aio_flush)) {
218e99
+        bdrv_rbd.bdrv_co_flush_to_disk = NULL;
218e99
+        bdrv_rbd.bdrv_aio_flush = qemu_rbd_aio_flush;
218e99
+    } else {
218e99
+        rbd_aio_flush = NULL;
218e99
+        bdrv_rbd.bdrv_aio_flush = NULL;
218e99
+    }
218e99
+
218e99
+    if (g_module_symbol(librbd_handle, "rbd_aio_discard",
218e99
+                        (gpointer *) &rbd_aio_discard)) {
218e99
+        bdrv_rbd.bdrv_aio_discard = qemu_rbd_aio_discard;
218e99
+    } else {
218e99
+        rbd_aio_discard = NULL;
218e99
+        bdrv_rbd.bdrv_aio_discard = NULL;
218e99
+    }
218e99
+}
218e99
+
218e99
+static int qemu_rbd_load_libs(void)
218e99
+{
218e99
+    if (librbd_loaded) {
218e99
+        return 0;
218e99
+    }
218e99
+
218e99
+    if (!g_module_supported()) {
218e99
+        error_report("modules are not supported on this platform: %s",
218e99
+                     g_module_error());
218e99
+        return -1;
218e99
+    }
218e99
+
218e99
+    librbd_handle = g_module_open("librbd.so.1", 0);
218e99
+    if (!librbd_handle) {
218e99
+        error_report("error loading librbd: %s", g_module_error());
218e99
+        return -1;
218e99
+    }
218e99
+
218e99
+    /*
218e99
+     * Due to c++ templates used in librbd/librados and their
218e99
+     * dependencies, and linker duplicate trimming rules, closing
218e99
+     * librbd would leave it mapped. Make this explicit.
218e99
+     */
218e99
+    g_module_make_resident(librbd_handle);
218e99
+
218e99
+    if (qemu_rbd_set_mandatory_functions() < 0) {
218e99
+        return -1;
218e99
+    }
218e99
+    qemu_rbd_set_optional_functions();
218e99
+    librbd_loaded = true;
218e99
+
218e99
+    return 0;
218e99
+}
218e99
+
218e99
 block_init(bdrv_rbd_init);
218e99
diff --git a/block/rbd_types.h b/block/rbd_types.h
218e99
new file mode 100644
218e99
index 0000000..f327cb4
218e99
--- /dev/null
218e99
+++ b/block/rbd_types.h
218e99
@@ -0,0 +1,91 @@
218e99
+/*
218e99
+ * Types and signatures for librados and librbd
218e99
+ *
218e99
+ * Copyright (C) 2013 Inktank Storage Inc.
218e99
+ *
218e99
+ * This library is free software; you can redistribute it and/or
218e99
+ * modify it under the terms of the GNU Lesser General Public
218e99
+ * License as published by the Free Software Foundation; either
218e99
+ * version 2 of the License, or (at your option) any later version.
218e99
+ *
218e99
+ * This library is distributed in the hope that it will be useful,
218e99
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
218e99
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
218e99
+ * Lesser General Public License for more details.
218e99
+ *
218e99
+ * You should have received a copy of the GNU Lesser General Public
218e99
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
218e99
+ */
218e99
+
218e99
+#ifndef QEMU_BLOCK_RBD_TYPES_H
218e99
+#define QEMU_BLOCK_RBD_TYPES_H
218e99
+
218e99
+/* types from librados used by the rbd block driver */
218e99
+
218e99
+typedef void *rados_t;
218e99
+typedef void *rados_ioctx_t;
218e99
+
218e99
+static int   (*rados_create)(rados_t *cluster, const char * const id);
218e99
+static int   (*rados_connect)(rados_t cluster);
218e99
+static void  (*rados_shutdown)(rados_t cluster);
218e99
+static int   (*rados_conf_read_file)(rados_t cluster, const char *path);
218e99
+static int   (*rados_conf_set)(rados_t cluster, const char *option,
218e99
+                               const char *value);
218e99
+static int   (*rados_ioctx_create)(rados_t cluster, const char *pool_name,
218e99
+                                   rados_ioctx_t *ioctx);
218e99
+static void  (*rados_ioctx_destroy)(rados_ioctx_t io);
218e99
+
218e99
+/* types from librbd used by the rbd block driver*/
218e99
+
218e99
+typedef void *rbd_image_t;
218e99
+typedef void *rbd_completion_t;
218e99
+typedef void (*rbd_callback_t)(rbd_completion_t cb, void *arg);
218e99
+
218e99
+typedef struct {
218e99
+    uint64_t id;
218e99
+    uint64_t size;
218e99
+    const char *name;
218e99
+} rbd_snap_info_t;
218e99
+
218e99
+#define RBD_MAX_IMAGE_NAME_SIZE 96
218e99
+#define RBD_MAX_BLOCK_NAME_SIZE 24
218e99
+
218e99
+typedef struct {
218e99
+    uint64_t size;
218e99
+    uint64_t obj_size;
218e99
+    uint64_t num_objs;
218e99
+    int order;
218e99
+    char block_name_prefix[RBD_MAX_BLOCK_NAME_SIZE];
218e99
+    int64_t parent_pool;
218e99
+    char parent_name[RBD_MAX_IMAGE_NAME_SIZE];
218e99
+} rbd_image_info_t;
218e99
+
218e99
+static int      (*rbd_create)(rados_ioctx_t io, const char *name, uint64_t size,
218e99
+                              int *order);
218e99
+static int      (*rbd_open)(rados_ioctx_t io, const char *name, rbd_image_t *image,
218e99
+                            const char *snap_name);
218e99
+static int      (*rbd_close)(rbd_image_t image);
218e99
+static int      (*rbd_resize)(rbd_image_t image, uint64_t size);
218e99
+static int      (*rbd_stat)(rbd_image_t image, rbd_image_info_t *info,
218e99
+                            size_t infosize);
218e99
+static int      (*rbd_snap_list)(rbd_image_t image, rbd_snap_info_t *snaps,
218e99
+                                 int *max_snaps);
218e99
+static void     (*rbd_snap_list_end)(rbd_snap_info_t *snaps);
218e99
+static int      (*rbd_snap_create)(rbd_image_t image, const char *snapname);
218e99
+static int      (*rbd_snap_remove)(rbd_image_t image, const char *snapname);
218e99
+static int      (*rbd_snap_rollback)(rbd_image_t image, const char *snapname);
218e99
+static int      (*rbd_aio_write)(rbd_image_t image, uint64_t off, size_t len,
218e99
+                                 const char *buf, rbd_completion_t c);
218e99
+static int      (*rbd_aio_read)(rbd_image_t image, uint64_t off, size_t len,
218e99
+                                char *buf, rbd_completion_t c);
218e99
+static int      (*rbd_aio_discard)(rbd_image_t image, uint64_t off, uint64_t len,
218e99
+                                   rbd_completion_t c);
218e99
+static int      (*rbd_aio_create_completion)(void *cb_arg,
218e99
+                                             rbd_callback_t complete_cb,
218e99
+                                             rbd_completion_t *c);
218e99
+static ssize_t  (*rbd_aio_get_return_value)(rbd_completion_t c);
218e99
+static void     (*rbd_aio_release)(rbd_completion_t c);
218e99
+static int      (*rbd_flush)(rbd_image_t image);
218e99
+static int      (*rbd_aio_flush)(rbd_image_t image, rbd_completion_t c);
218e99
+
218e99
+#endif
218e99
diff --git a/configure b/configure
218e99
index 4d1bc44..df587d7 100755
218e99
--- a/configure
218e99
+++ b/configure
218e99
@@ -224,7 +224,6 @@ qom_cast_debug="yes"
218e99
 trace_backend="nop"
218e99
 trace_file="trace"
218e99
 spice=""
218e99
-rbd=""
218e99
 smartcard_nss=""
218e99
 libusb=""
218e99
 usb_redir=""
218e99
@@ -880,10 +879,6 @@ for opt do
218e99
   ;;
218e99
   --enable-glx) glx="yes"
218e99
   ;;
218e99
-  --disable-rbd) rbd="no"
218e99
-  ;;
218e99
-  --enable-rbd) rbd="yes"
218e99
-  ;;
218e99
   --disable-xfsctl) xfs="no"
218e99
   ;;
218e99
   --enable-xfsctl) xfs="yes"
218e99
@@ -1181,7 +1176,6 @@ echo "  --with-trace-file=NAME   Full PATH,NAME of file to store traces"
218e99
 echo "                           Default:trace-<pid>"
218e99
 echo "  --disable-spice          disable spice"
218e99
 echo "  --enable-spice           enable spice"
218e99
-echo "  --enable-rbd             enable building the rados block device (rbd)"
218e99
 echo "  --disable-libiscsi       disable iscsi support"
218e99
 echo "  --enable-libiscsi        enable iscsi support"
218e99
 echo "  --disable-smartcard-nss  disable smartcard nss support"
218e99
@@ -2250,10 +2244,10 @@ if test "$mingw32" = yes; then
218e99
 else
218e99
     glib_req_ver=2.12
218e99
 fi
218e99
-if $pkg_config --atleast-version=$glib_req_ver gthread-2.0 > /dev/null 2>&1
218e99
+if $pkg_config --atleast-version=$glib_req_ver gthread-2.0 gmodule-2.0 > /dev/null 2>&1
218e99
 then
218e99
-    glib_cflags=`$pkg_config --cflags gthread-2.0 2>/dev/null`
218e99
-    glib_libs=`$pkg_config --libs gthread-2.0 2>/dev/null`
218e99
+    glib_cflags=`$pkg_config --cflags gthread-2.0 gmodule-2.0 2>/dev/null`
218e99
+    glib_libs=`$pkg_config --libs gthread-2.0 gmodule-2.0 2>/dev/null`
218e99
     LIBS="$glib_libs $LIBS"
218e99
     libs_qga="$glib_libs $libs_qga"
218e99
 else
218e99
@@ -2354,31 +2348,6 @@ if test "$mingw32" != yes -a "$pthread" = no; then
218e99
 fi
218e99
 
218e99
 ##########################################
218e99
-# rbd probe
218e99
-if test "$rbd" != "no" ; then
218e99
-  cat > $TMPC <
218e99
-#include <stdio.h>
218e99
-#include <rbd/librbd.h>
218e99
-int main(void) {
218e99
-    rados_t cluster;
218e99
-    rados_create(&cluster, NULL);
218e99
-    return 0;
218e99
-}
218e99
-EOF
218e99
-  rbd_libs="-lrbd -lrados"
218e99
-  if compile_prog "" "$rbd_libs" ; then
218e99
-    rbd=yes
218e99
-    libs_tools="$rbd_libs $libs_tools"
218e99
-    libs_softmmu="$rbd_libs $libs_softmmu"
218e99
-  else
218e99
-    if test "$rbd" = "yes" ; then
218e99
-      feature_not_found "rados block device"
218e99
-    fi
218e99
-    rbd=no
218e99
-  fi
218e99
-fi
218e99
-
218e99
-##########################################
218e99
 # libssh2 probe
218e99
 min_libssh2_version=1.2.8
218e99
 if test "$libssh2" != "no" ; then
218e99
@@ -3573,7 +3542,6 @@ echo "vhost-scsi support $vhost_scsi"
218e99
 echo "Trace backend     $trace_backend"
218e99
 echo "Trace output file $trace_file-<pid>"
218e99
 echo "spice support     $spice ($spice_protocol_version/$spice_server_version)"
218e99
-echo "rbd support       $rbd"
218e99
 echo "xfsctl support    $xfs"
218e99
 echo "nss used          $smartcard_nss"
218e99
 echo "libusb            $libusb"
218e99
@@ -3928,9 +3896,6 @@ fi
218e99
 if test "$qom_cast_debug" = "yes" ; then
218e99
   echo "CONFIG_QOM_CAST_DEBUG=y" >> $config_host_mak
218e99
 fi
218e99
-if test "$rbd" = "yes" ; then
218e99
-  echo "CONFIG_RBD=y" >> $config_host_mak
218e99
-fi
218e99
 
218e99
 echo "CONFIG_COROUTINE_BACKEND=$coroutine" >> $config_host_mak
218e99
 
218e99
-- 
218e99
1.7.11.7
218e99