From: Colin Lord <clord@redhat.com>
To: qemu-devel@nongnu.org
Cc: kwolf@redhat.com, qemu-block@nongnu.org, mreitz@redhat.com,
Marc Mari <markmb@redhat.com>, Colin Lord <clord@redhat.com>
Subject: [Qemu-devel] [PATCH v5 3/3] blockdev: Add dynamic module loading for block drivers
Date: Wed, 20 Jul 2016 10:30:50 -0400 [thread overview]
Message-ID: <1469025050-12715-4-git-send-email-clord@redhat.com> (raw)
In-Reply-To: <1469025050-12715-1-git-send-email-clord@redhat.com>
From: Marc Mari <markmb@redhat.com>
Extend the current module interface to allow for block drivers to be
loaded dynamically on request. The only block drivers that can be
converted into modules are the drivers that don't perform any init
operation except for registering themselves.
In addition, only the protocol drivers are being modularized, as they
are the only ones which see significant performance benefits. The format
drivers do not generally link to external libraries, so modularizing
them is of no benefit from a performance perspective.
All the necessary module information is located in a new structure found in
module_block.h
Signed-off-by: Marc Marí <markmb@redhat.com>
Signed-off-by: Colin Lord <clord@redhat.com>
---
block.c | 37 +++++++++++++++++++++++++++++++------
block/Makefile.objs | 3 +--
include/qemu/module.h | 3 +++
util/module.c | 38 +++++++++++---------------------------
4 files changed, 46 insertions(+), 35 deletions(-)
diff --git a/block.c b/block.c
index d2dac3d..fbcd3cb 100644
--- a/block.c
+++ b/block.c
@@ -26,6 +26,7 @@
#include "block/block_int.h"
#include "block/blockjob.h"
#include "qemu/error-report.h"
+#include "module_block.h"
#include "qemu/module.h"
#include "qapi/qmp/qerror.h"
#include "qapi/qmp/qbool.h"
@@ -460,6 +461,19 @@ static BlockDriver *find_hdev_driver(const char *filename)
return drv;
}
+static BlockDriver *bdrv_do_find_protocol(const char *protocol)
+{
+ BlockDriver *drv1;
+
+ QLIST_FOREACH(drv1, &bdrv_drivers, list) {
+ if (drv1->protocol_name && !strcmp(drv1->protocol_name, protocol)) {
+ return drv1;
+ }
+ }
+
+ return NULL;
+}
+
BlockDriver *bdrv_find_protocol(const char *filename,
bool allow_protocol_prefix,
Error **errp)
@@ -468,6 +482,7 @@ BlockDriver *bdrv_find_protocol(const char *filename,
char protocol[128];
int len;
const char *p;
+ size_t i;
/* TODO Drivers without bdrv_file_open must be specified explicitly */
@@ -494,15 +509,25 @@ BlockDriver *bdrv_find_protocol(const char *filename,
len = sizeof(protocol) - 1;
memcpy(protocol, filename, len);
protocol[len] = '\0';
- QLIST_FOREACH(drv1, &bdrv_drivers, list) {
- if (drv1->protocol_name &&
- !strcmp(drv1->protocol_name, protocol)) {
- return drv1;
+
+ drv1 = bdrv_do_find_protocol(protocol);
+ if (drv1) {
+ return drv1;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(block_driver_modules); ++i) {
+ if (block_driver_modules[i].protocol_name &&
+ !strcmp(block_driver_modules[i].protocol_name, protocol)) {
+ block_module_load_one(block_driver_modules[i].library_name);
+ break;
}
}
- error_setg(errp, "Unknown protocol '%s'", protocol);
- return NULL;
+ drv1 = bdrv_do_find_protocol(protocol);
+ if (!drv1) {
+ error_setg(errp, "Unknown protocol '%s'", protocol);
+ }
+ return drv1;
}
/*
diff --git a/block/Makefile.objs b/block/Makefile.objs
index 2593a2f..595f366 100644
--- a/block/Makefile.objs
+++ b/block/Makefile.objs
@@ -1,4 +1,4 @@
-block-obj-y += raw_bsd.o qcow.o vdi.o vmdk.o cloop.o bochs.o vpc.o vvfat.o
+block-obj-y += raw_bsd.o qcow.o vdi.o vmdk.o cloop.o bochs.o vpc.o vvfat.o dmg.o
block-obj-y += qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2-snapshot.o qcow2-cache.o
block-obj-y += qed.o qed-gencb.o qed-l2-cache.o qed-table.o qed-cluster.o
block-obj-y += qed-check.o
@@ -39,7 +39,6 @@ gluster.o-libs := $(GLUSTERFS_LIBS)
ssh.o-cflags := $(LIBSSH2_CFLAGS)
ssh.o-libs := $(LIBSSH2_LIBS)
archipelago.o-libs := $(ARCHIPELAGO_LIBS)
-block-obj-m += dmg.o
dmg.o-libs := $(BZIP2_LIBS)
qcow.o-libs := -lz
linux-aio.o-libs := -laio
diff --git a/include/qemu/module.h b/include/qemu/module.h
index 2370708..dc2c9d4 100644
--- a/include/qemu/module.h
+++ b/include/qemu/module.h
@@ -52,9 +52,12 @@ typedef enum {
#define qapi_init(function) module_init(function, MODULE_INIT_QAPI)
#define type_init(function) module_init(function, MODULE_INIT_QOM)
+#define block_module_load_one(lib) module_load_one("block-", lib)
+
void register_module_init(void (*fn)(void), module_init_type type);
void register_dso_module_init(void (*fn)(void), module_init_type type);
void module_call_init(module_init_type type);
+void module_load_one(const char *prefix, const char *lib_name);
#endif
diff --git a/util/module.c b/util/module.c
index 86e3f7a..a5f7fbd 100644
--- a/util/module.c
+++ b/util/module.c
@@ -87,14 +87,11 @@ void register_dso_module_init(void (*fn)(void), module_init_type type)
QTAILQ_INSERT_TAIL(&dso_init_list, e, node);
}
-static void module_load(module_init_type type);
-
void module_call_init(module_init_type type)
{
ModuleTypeList *l;
ModuleEntry *e;
- module_load(type);
l = find_type(type);
QTAILQ_FOREACH(e, l, node) {
@@ -145,6 +142,7 @@ static int module_load_file(const char *fname)
ret = -EINVAL;
} else {
QTAILQ_FOREACH(e, &dso_init_list, node) {
+ e->init();
register_module_init(e->init, e->type);
}
ret = 0;
@@ -159,14 +157,10 @@ out:
}
#endif
-static void module_load(module_init_type type)
+void module_load_one(const char *prefix, const char *lib_name)
{
#ifdef CONFIG_MODULES
char *fname = NULL;
- const char **mp;
- static const char *block_modules[] = {
- CONFIG_BLOCK_MODULES
- };
char *exec_dir;
char *dirs[3];
int i = 0;
@@ -177,15 +171,6 @@ static void module_load(module_init_type type)
return;
}
- switch (type) {
- case MODULE_INIT_BLOCK:
- mp = block_modules;
- break;
- default:
- /* no other types have dynamic modules for now*/
- return;
- }
-
exec_dir = qemu_get_exec_dir();
dirs[i++] = g_strdup_printf("%s", CONFIG_QEMU_MODDIR);
dirs[i++] = g_strdup_printf("%s/..", exec_dir ? : "");
@@ -194,16 +179,15 @@ static void module_load(module_init_type type)
g_free(exec_dir);
exec_dir = NULL;
- for ( ; *mp; mp++) {
- for (i = 0; i < ARRAY_SIZE(dirs); i++) {
- fname = g_strdup_printf("%s/%s%s", dirs[i], *mp, HOST_DSOSUF);
- ret = module_load_file(fname);
- g_free(fname);
- fname = NULL;
- /* Try loading until loaded a module file */
- if (!ret) {
- break;
- }
+ for (i = 0; i < ARRAY_SIZE(dirs); i++) {
+ fname = g_strdup_printf("%s/%s%s%s",
+ dirs[i], prefix, lib_name, HOST_DSOSUF);
+ ret = module_load_file(fname);
+ g_free(fname);
+ fname = NULL;
+ /* Try loading until loaded a module file */
+ if (!ret) {
+ break;
}
}
--
2.5.5
next prev parent reply other threads:[~2016-07-20 14:31 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-07-20 14:30 [Qemu-devel] [PATCH v5 0/3] Dynamic module loading for block drivers Colin Lord
2016-07-20 14:30 ` [Qemu-devel] [PATCH v5 1/3] blockdev: prepare iSCSI block driver for dynamic loading Colin Lord
2016-07-20 14:30 ` [Qemu-devel] [PATCH v5 2/3] blockdev: Add dynamic generation of module_block.h Colin Lord
2016-07-20 14:30 ` Colin Lord [this message]
2016-07-23 18:21 ` [Qemu-devel] [PATCH v5 0/3] Dynamic module loading for block drivers Max Reitz
2016-07-25 13:56 ` Colin Lord
2016-07-25 19:38 ` Max Reitz
2016-07-29 6:33 ` Fam Zheng
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1469025050-12715-4-git-send-email-clord@redhat.com \
--to=clord@redhat.com \
--cc=kwolf@redhat.com \
--cc=markmb@redhat.com \
--cc=mreitz@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).