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