aboutsummaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2020-10-19 09:52:20 +0200
committerGerd Hoffmann <kraxel@redhat.com>2020-10-21 15:46:14 +0200
commit6f13fa7a9825e85e35927cbb51a992e158798424 (patch)
tree64fbe8eae1cafb1a1c58bb0c5a7272bff1281e54 /util
parent9ed345a14ed3cfa2345cabfe8759e62463c356a1 (diff)
downloadqemu-6f13fa7a9825e85e35927cbb51a992e158798424.zip
qemu-6f13fa7a9825e85e35927cbb51a992e158798424.tar.gz
qemu-6f13fa7a9825e85e35927cbb51a992e158798424.tar.bz2
modules: dependencies infrastructure
Allow modules depending on other modules. module_load_file() gets the option to export symbols (by not adding the G_MODULE_BIND_LOCAL flag). module_load_one() will check the module dependency list to figure (a) whenever are other modules must be loaded first, or (b) the module should export the symbols. The dependencies are specificed as static list in the source code for now as I expect the list will stay small. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-id: 20201019075224.14803-11-kraxel@redhat.com
Diffstat (limited to 'util')
-rw-r--r--util/module.c32
1 files changed, 27 insertions, 5 deletions
diff --git a/util/module.c b/util/module.c
index f0ed05f..0c0f258 100644
--- a/util/module.c
+++ b/util/module.c
@@ -110,7 +110,7 @@ void module_call_init(module_init_type type)
}
#ifdef CONFIG_MODULES
-static int module_load_file(const char *fname, bool mayfail)
+static int module_load_file(const char *fname, bool mayfail, bool export_symbols)
{
GModule *g_module;
void (*sym)(void);
@@ -118,7 +118,7 @@ static int module_load_file(const char *fname, bool mayfail)
int len = strlen(fname);
int suf_len = strlen(dsosuf);
ModuleEntry *e, *next;
- int ret;
+ int ret, flags;
if (len <= suf_len || strcmp(&fname[len - suf_len], dsosuf)) {
/* wrong suffix */
@@ -132,7 +132,11 @@ static int module_load_file(const char *fname, bool mayfail)
assert(QTAILQ_EMPTY(&dso_init_list));
- g_module = g_module_open(fname, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
+ flags = G_MODULE_BIND_LAZY;
+ if (!export_symbols) {
+ flags |= G_MODULE_BIND_LOCAL;
+ }
+ g_module = g_module_open(fname, flags);
if (!g_module) {
if (!mayfail) {
fprintf(stderr, "Failed to open module: %s\n",
@@ -167,6 +171,12 @@ static int module_load_file(const char *fname, bool mayfail)
out:
return ret;
}
+
+static const struct {
+ const char *name;
+ const char *dep;
+} module_deps[] = {
+};
#endif
bool module_load_one(const char *prefix, const char *lib_name, bool mayfail)
@@ -182,7 +192,8 @@ bool module_load_one(const char *prefix, const char *lib_name, bool mayfail)
char *dirs[5];
char *module_name;
int i = 0, n_dirs = 0;
- int ret;
+ int ret, dep;
+ bool export_symbols = false;
static GHashTable *loaded_modules;
if (!g_module_supported()) {
@@ -196,6 +207,17 @@ bool module_load_one(const char *prefix, const char *lib_name, bool mayfail)
module_name = g_strdup_printf("%s%s", prefix, lib_name);
+ for (dep = 0; dep < ARRAY_SIZE(module_deps); dep++) {
+ if (strcmp(module_name, module_deps[dep].name) == 0) {
+ /* we depend on another module */
+ module_load_one("", module_deps[dep].dep, false);
+ }
+ if (strcmp(module_name, module_deps[dep].dep) == 0) {
+ /* another module depends on us */
+ export_symbols = true;
+ }
+ }
+
if (!g_hash_table_add(loaded_modules, module_name)) {
g_free(module_name);
return true;
@@ -220,7 +242,7 @@ bool module_load_one(const char *prefix, const char *lib_name, bool mayfail)
for (i = 0; i < n_dirs; i++) {
fname = g_strdup_printf("%s/%s%s",
dirs[i], module_name, CONFIG_HOST_DSOSUF);
- ret = module_load_file(fname, mayfail);
+ ret = module_load_file(fname, mayfail, export_symbols);
g_free(fname);
fname = NULL;
/* Try loading until loaded a module file */