Add module_load_all to load all DSO modules under: /usr/lib/qemu/block/ /usr/lib/qemu/net/ /usr/lib/qemu/ui/ when starting process.
Requires gmodule-2.0 from glib. Signed-off-by: Fam Zheng <f...@redhat.com> --- configure | 20 +++++++++++--------- include/qemu/module.h | 2 ++ qemu-img.c | 2 ++ qemu-io.c | 1 + qemu-nbd.c | 1 + scripts/create_config | 3 +++ util/Makefile.objs | 2 ++ util/module.c | 40 ++++++++++++++++++++++++++++++++++++++++ vl.c | 1 + 9 files changed, 63 insertions(+), 9 deletions(-) diff --git a/configure b/configure index 8f0a882..975853e 100755 --- a/configure +++ b/configure @@ -2238,15 +2238,17 @@ if test "$mingw32" = yes; then else glib_req_ver=2.12 fi -if $pkg_config --atleast-version=$glib_req_ver gthread-2.0 > /dev/null 2>&1 -then - glib_cflags=`$pkg_config --cflags gthread-2.0 2>/dev/null` - glib_libs=`$pkg_config --libs gthread-2.0 2>/dev/null` - LIBS="$glib_libs $LIBS" - libs_qga="$glib_libs $libs_qga" -else - error_exit "glib-$glib_req_ver required to compile QEMU" -fi +for i in gthread-2.0 gmodule-2.0; do + if $pkg_config --atleast-version=$glib_req_ver $i > /dev/null 2>&1 + then + glib_cflags=`$pkg_config --cflags $i 2>/dev/null` + glib_libs=`$pkg_config --libs $i 2>/dev/null` + LIBS="$glib_libs $LIBS" + libs_qga="$glib_libs $libs_qga" + else + error_exit "glib-$glib_req_ver required to compile QEMU" + fi +done ########################################## # pixman support probe diff --git a/include/qemu/module.h b/include/qemu/module.h index c4ccd57..d3500be 100644 --- a/include/qemu/module.h +++ b/include/qemu/module.h @@ -37,4 +37,6 @@ void register_module_init(void (*fn)(void), module_init_type type); void module_call_init(module_init_type type); +void module_load_all(void); + #endif diff --git a/qemu-img.c b/qemu-img.c index b9a848d..e761027 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -34,6 +34,7 @@ #include <getopt.h> #include <stdio.h> #include <stdarg.h> +#include "qemu/module.h" #ifdef _WIN32 #include <windows.h> @@ -2328,6 +2329,7 @@ int main(int argc, char **argv) error_set_progname(argv[0]); + module_load_all(); qemu_init_main_loop(); bdrv_init(); if (argc < 2) diff --git a/qemu-io.c b/qemu-io.c index d54dc86..d02e8f5 100644 --- a/qemu-io.c +++ b/qemu-io.c @@ -398,6 +398,7 @@ int main(int argc, char **argv) exit(1); } + module_load_all(); qemu_init_main_loop(); bdrv_init(); diff --git a/qemu-nbd.c b/qemu-nbd.c index f044546..ecea543 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -558,6 +558,7 @@ int main(int argc, char **argv) snprintf(sockpath, 128, SOCKET_PATH, basename(device)); } + module_load_all(); qemu_init_main_loop(); bdrv_init(); atexit(bdrv_close_all); diff --git a/scripts/create_config b/scripts/create_config index b1adbf5..3ecb789 100755 --- a/scripts/create_config +++ b/scripts/create_config @@ -104,6 +104,9 @@ case $line in value=${line#*=} echo "#define $name $value" ;; + DSOSUF=*) + echo "#define HOST_DSOSUF \"${line#*=}\"" + ;; esac done # read diff --git a/util/Makefile.objs b/util/Makefile.objs index dc72ab0..33e56b0 100644 --- a/util/Makefile.objs +++ b/util/Makefile.objs @@ -11,3 +11,5 @@ util-obj-y += iov.o aes.o qemu-config.o qemu-sockets.o uri.o notify.o util-obj-y += qemu-option.o qemu-progress.o util-obj-y += hexdump.o util-obj-y += crc32c.o + +$(obj)/module.o-libs := -lglib diff --git a/util/module.c b/util/module.c index 7acc33d..29d3a4f 100644 --- a/util/module.c +++ b/util/module.c @@ -13,6 +13,8 @@ * GNU GPL, version 2 or (at your option) any later version. */ +#include <gmodule.h> +#include <dirent.h> #include "qemu-common.h" #include "qemu/queue.h" #include "qemu/module.h" @@ -79,3 +81,41 @@ void module_call_init(module_init_type type) e->init(); } } + +void module_load_all(void) +{ + static const char *module_dir_list[] = { + "/usr/lib/qemu/block/", + "/usr/lib/qemu/net/", + "/usr/lib/qemu/ui/", + NULL + }; + const char **path; + const char *dsosuf = HOST_DSOSUF; + char fname[1024]; + int suf_len = strlen(dsosuf); + DIR *dp; + struct dirent *ep = NULL; + GModule *g_module; + for (path = &module_dir_list[0]; *path != NULL; path++) { + dp = opendir(*path); + if (!dp) { + fprintf(stderr, "Failed to open dir %s\n", *path); + } + for (ep = readdir(dp); ep; ep = readdir(dp)) { + int len = strlen(ep->d_name); + if (len > suf_len && + !strcmp(&ep->d_name[len - suf_len], dsosuf)) { + pstrcpy(fname, sizeof(fname), *path); + pstrcat(fname, sizeof(fname), ep->d_name); + g_module = g_module_open(fname, G_MODULE_BIND_LAZY); + if (!g_module) { + fprintf(stderr, "Failed to open module file %s\n", + g_module_error()); + continue; + } + printf("Loaded module %s\n", fname); + } + } + } +} diff --git a/vl.c b/vl.c index dfbc071..c72e5a8 100644 --- a/vl.c +++ b/vl.c @@ -3873,6 +3873,7 @@ int main(int argc, char **argv, char **envp) } loc_set_none(); + module_load_all(); if (qemu_init_main_loop()) { fprintf(stderr, "qemu_init_main_loop failed\n"); exit(1); -- 1.8.3.1