|
|
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 |
|