2 * QEMU Module Infrastructure
4 * Copyright IBM, Corp. 2009
7 * Anthony Liguori <aliguori@us.ibm.com>
9 * This work is licensed under the terms of the GNU GPL, version 2. See
10 * the COPYING file in the top-level directory.
12 * Contributions after 2012-01-13 are licensed under the terms of the
13 * GNU GPL, version 2 or (at your option) any later version.
16 #include "qemu/osdep.h"
20 #include "qemu/queue.h"
21 #include "qemu/module.h"
22 #include "qemu/cutils.h"
23 #include "qemu/config-file.h"
24 #include "qapi/error.h"
25 #ifdef CONFIG_MODULE_UPGRADES
26 #include "qemu-version.h"
30 typedef struct ModuleEntry
33 QTAILQ_ENTRY(ModuleEntry
) node
;
34 module_init_type type
;
37 typedef QTAILQ_HEAD(, ModuleEntry
) ModuleTypeList
;
39 static ModuleTypeList init_type_list
[MODULE_INIT_MAX
];
40 static bool modules_init_done
[MODULE_INIT_MAX
];
42 static ModuleTypeList dso_init_list
;
44 static void init_lists(void)
53 for (i
= 0; i
< MODULE_INIT_MAX
; i
++) {
54 QTAILQ_INIT(&init_type_list
[i
]);
57 QTAILQ_INIT(&dso_init_list
);
63 static ModuleTypeList
*find_type(module_init_type type
)
67 return &init_type_list
[type
];
70 void register_module_init(void (*fn
)(void), module_init_type type
)
75 e
= g_malloc0(sizeof(*e
));
81 QTAILQ_INSERT_TAIL(l
, e
, node
);
84 void register_dso_module_init(void (*fn
)(void), module_init_type type
)
90 e
= g_malloc0(sizeof(*e
));
94 QTAILQ_INSERT_TAIL(&dso_init_list
, e
, node
);
97 void module_call_init(module_init_type type
)
102 if (modules_init_done
[type
]) {
108 QTAILQ_FOREACH(e
, l
, node
) {
112 modules_init_done
[type
] = true;
115 #ifdef CONFIG_MODULES
117 static const QemuModinfo module_info_stub
[] = { {
120 static const QemuModinfo
*module_info
= module_info_stub
;
121 static const char *module_arch
;
123 void module_init_info(const QemuModinfo
*info
)
128 void module_allow_arch(const char *arch
)
133 static bool module_check_arch(const QemuModinfo
*modinfo
)
137 /* no arch set -> ignore all */
140 if (strcmp(module_arch
, modinfo
->arch
) != 0) {
149 * module_load_dso: attempt to load an existing dso file
151 * fname: full pathname of the file to load
152 * export_symbols: if true, add the symbols to the global name space
153 * errp: error to set.
155 * Return value: true on success, false on error, and errp will be set.
157 static bool module_load_dso(const char *fname
, bool export_symbols
,
162 ModuleEntry
*e
, *next
;
165 assert(QTAILQ_EMPTY(&dso_init_list
));
168 if (!export_symbols
) {
169 flags
|= G_MODULE_BIND_LOCAL
;
171 g_module
= g_module_open(fname
, flags
);
173 error_setg(errp
, "failed to open module: %s", g_module_error());
176 if (!g_module_symbol(g_module
, DSO_STAMP_FUN_STR
, (gpointer
*)&sym
)) {
177 error_setg(errp
, "failed to initialize module: %s", fname
);
179 * Print some info if this is a QEMU module (but from different build),
180 * this will make debugging user problems easier.
182 if (g_module_symbol(g_module
, "qemu_module_dummy", (gpointer
*)&sym
)) {
183 error_append_hint(errp
,
184 "Only modules from the same build can be loaded.\n");
186 g_module_close(g_module
);
190 QTAILQ_FOREACH(e
, &dso_init_list
, node
) {
192 register_module_init(e
->init
, e
->type
);
194 trace_module_load_module(fname
);
195 QTAILQ_FOREACH_SAFE(e
, &dso_init_list
, node
, next
) {
196 QTAILQ_REMOVE(&dso_init_list
, e
, node
);
202 int module_load(const char *prefix
, const char *name
, Error
**errp
)
205 #ifdef CONFIG_MODULE_UPGRADES
208 const char *search_dir
;
211 int i
= 0, n_dirs
= 0;
212 bool export_symbols
= false;
213 static GHashTable
*loaded_modules
;
214 const QemuModinfo
*modinfo
;
217 if (!g_module_supported()) {
218 error_setg(errp
, "%s", "this platform does not support GLib modules");
222 if (!loaded_modules
) {
223 loaded_modules
= g_hash_table_new(g_str_hash
, g_str_equal
);
226 /* allocate all resources managed by the out: label here */
227 module_name
= g_strdup_printf("%s%s", prefix
, name
);
229 if (g_hash_table_contains(loaded_modules
, module_name
)) {
231 return 2; /* module already loaded */
233 g_hash_table_add(loaded_modules
, module_name
);
235 search_dir
= getenv("QEMU_MODULE_DIR");
236 if (search_dir
!= NULL
) {
237 dirs
[n_dirs
++] = g_strdup_printf("%s", search_dir
);
239 dirs
[n_dirs
++] = get_relocated_path(CONFIG_QEMU_MODDIR
);
241 #ifdef CONFIG_MODULE_UPGRADES
242 version_dir
= g_strcanon(g_strdup(QEMU_PKGVERSION
),
243 G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS
"+-.~",
245 dirs
[n_dirs
++] = g_strdup_printf("/var/run/qemu/%s", version_dir
);
247 assert(n_dirs
<= ARRAY_SIZE(dirs
));
249 /* end of resources managed by the out: label */
251 for (modinfo
= module_info
; modinfo
->name
!= NULL
; modinfo
++) {
253 if (strcmp(modinfo
->name
, module_name
) == 0) {
254 if (!module_check_arch(modinfo
)) {
255 error_setg(errp
, "module arch does not match: "
256 "expected '%s', got '%s'", module_arch
, modinfo
->arch
);
262 if (strcmp(modinfo
->name
, module_name
) == 0) {
263 /* we depend on other module(s) */
264 for (sl
= modinfo
->deps
; *sl
!= NULL
; sl
++) {
265 int subrv
= module_load("", *sl
, errp
);
272 for (sl
= modinfo
->deps
; *sl
!= NULL
; sl
++) {
273 if (strcmp(module_name
, *sl
) == 0) {
274 /* another module depends on us */
275 export_symbols
= true;
282 for (i
= 0; i
< n_dirs
; i
++) {
283 char *fname
= g_strdup_printf("%s/%s%s",
284 dirs
[i
], module_name
, CONFIG_HOST_DSOSUF
);
285 int ret
= access(fname
, F_OK
);
286 if (ret
!= 0 && (errno
== ENOENT
|| errno
== ENOTDIR
)) {
288 * if we don't find the module in this dir, try the next one.
289 * If we don't find it in any dir, that can be fine too: user
290 * did not install the module. We will return 0 in this case
295 } else if (ret
!= 0) {
296 /* most common is EACCES here */
297 error_setg_errno(errp
, errno
, "error trying to access %s", fname
);
298 } else if (module_load_dso(fname
, export_symbols
, errp
)) {
299 rv
= 1; /* module successfully loaded */
304 rv
= 0; /* module not found */
308 g_hash_table_remove(loaded_modules
, module_name
);
311 for (i
= 0; i
< n_dirs
; i
++) {
317 static bool module_loaded_qom_all
;
319 int module_load_qom(const char *type
, Error
**errp
)
321 const QemuModinfo
*modinfo
;
326 error_setg(errp
, "%s", "type is NULL");
330 trace_module_lookup_object_type(type
);
331 for (modinfo
= module_info
; modinfo
->name
!= NULL
; modinfo
++) {
332 if (!modinfo
->objs
) {
335 if (!module_check_arch(modinfo
)) {
338 for (sl
= modinfo
->objs
; *sl
!= NULL
; sl
++) {
339 if (strcmp(type
, *sl
) == 0) {
341 error_setg(errp
, "multiple modules providing '%s'", type
);
344 rv
= module_load("", modinfo
->name
, errp
);
354 void module_load_qom_all(void)
356 const QemuModinfo
*modinfo
;
357 Error
*local_err
= NULL
;
359 if (module_loaded_qom_all
) {
363 for (modinfo
= module_info
; modinfo
->name
!= NULL
; modinfo
++) {
364 if (!modinfo
->objs
) {
367 if (!module_check_arch(modinfo
)) {
370 if (module_load("", modinfo
->name
, &local_err
) < 0) {
371 error_report_err(local_err
);
374 module_loaded_qom_all
= true;
377 void qemu_load_module_for_opts(const char *group
)
379 const QemuModinfo
*modinfo
;
382 for (modinfo
= module_info
; modinfo
->name
!= NULL
; modinfo
++) {
383 if (!modinfo
->opts
) {
386 for (sl
= modinfo
->opts
; *sl
!= NULL
; sl
++) {
387 if (strcmp(group
, *sl
) == 0) {
388 Error
*local_err
= NULL
;
389 if (module_load("", modinfo
->name
, &local_err
) < 0) {
390 error_report_err(local_err
);
399 void module_allow_arch(const char *arch
) {}
400 void qemu_load_module_for_opts(const char *group
) {}
401 int module_load(const char *prefix
, const char *name
, Error
**errp
) { return 2; }
402 int module_load_qom(const char *type
, Error
**errp
) { return 2; }
403 void module_load_qom_all(void) {}