mirror of https://github.com/xemu-project/xemu.git
* Longstanding chardev race condition fix (Berto)
* Cleanups and tests from the Meson POC (Marc-André, myself) * Coalesced range cleanup (Peter) -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQEcBAABAgAGBQJdXX8PAAoJEL/70l94x66DkR4H/1Phk6zuTQfHISBXGACjDkFS kbVq2WE6gQXwqmbf/04mM/DZzsi9bCsHFlGhf7mFQoq9g2ywm7kgtjF7kiRewlqh YZYSLLEoEVKpZRxC8kQbbbZ/tfYDM7ejnKMPFK6ibNiiN7acuKJuY8z18OLg4PEA V5LfuaGPjsx98NUAuU6bHRs5ZDCL25DzBQ9pdcE5wkJ2pVJXpP6UBafN55l8Clzq PzuuNnP18QyuqbdRVm5YrY+0nUeDCdlU2clCC3/H9rS57Ts/z3gocs71VT8GKqIa ppNRg3wVADXtfql3MkpnmvZefx+QK6DguAAiKR4CtPax7Xx6WoA4DwtMKfsLHsY= =RwuS -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging * Longstanding chardev race condition fix (Berto) * Cleanups and tests from the Meson POC (Marc-André, myself) * Coalesced range cleanup (Peter) # gpg: Signature made Wed 21 Aug 2019 18:27:43 BST # gpg: using RSA key BFFBD25F78C7AE83 # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full] # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" [full] # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * remotes/bonzini/tags/for-upstream: char-socket: Lock tcp_chr_disconnect() and socket_reconnect_timeout() main-loop: Fix GSource leak in qio_task_thread_worker() memory: Fix up memory_region_{add|del}_coalescing memory: Remove has_coalesced_range counter memory: Split zones when do coalesced_io_del() memory: Refactor memory_region_clear_coalescing minikconf: don't print CONFIG_FOO=n lines configure: remove AUTOCONF_HOST tests: add module loading test module: return success on module load module: use g_hash_table_add() configure: define CONFIG_TOOLS here qemu-ga: clean up TOOLS variable Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
8109234808
9
Makefile
9
Makefile
|
@ -84,8 +84,7 @@ endif
|
|||
|
||||
include $(SRC_PATH)/rules.mak
|
||||
|
||||
# notempy and lor are defined in rules.mak
|
||||
CONFIG_TOOLS := $(call notempty,$(TOOLS))
|
||||
# lor is defined in rules.mak
|
||||
CONFIG_BLOCK := $(call lor,$(CONFIG_SOFTMMU),$(CONFIG_TOOLS))
|
||||
|
||||
# Create QEMU_PKGVERSION and FULL_VERSION strings
|
||||
|
@ -681,7 +680,7 @@ clean: recurse-clean
|
|||
! -path ./roms/edk2/BaseTools/Source/Python/UPT/Dll/sqlite3.dll \
|
||||
-exec rm {} +
|
||||
rm -f $(edk2-decompressed)
|
||||
rm -f $(filter-out %.tlb,$(TOOLS)) $(HELPERS-y) qemu-ga$(EXESUF) TAGS cscope.* *.pod *~ */*~
|
||||
rm -f $(filter-out %.tlb,$(TOOLS)) $(HELPERS-y) TAGS cscope.* *.pod *~ */*~
|
||||
rm -f fsdev/*.pod scsi/*.pod
|
||||
rm -f qemu-img-cmds.h
|
||||
rm -f ui/shader/*-vert.h ui/shader/*-frag.h
|
||||
|
@ -809,7 +808,7 @@ ifdef CONFIG_POSIX
|
|||
$(INSTALL_DATA) docs/interop/qemu-qmp-ref.7 "$(DESTDIR)$(mandir)/man7"
|
||||
$(INSTALL_DATA) docs/qemu-block-drivers.7 "$(DESTDIR)$(mandir)/man7"
|
||||
$(INSTALL_DATA) docs/qemu-cpu-models.7 "$(DESTDIR)$(mandir)/man7"
|
||||
ifneq ($(TOOLS),)
|
||||
ifeq ($(CONFIG_TOOLS),y)
|
||||
$(INSTALL_DATA) qemu-img.1 "$(DESTDIR)$(mandir)/man1"
|
||||
$(INSTALL_DIR) "$(DESTDIR)$(mandir)/man8"
|
||||
$(INSTALL_DATA) qemu-nbd.8 "$(DESTDIR)$(mandir)/man8"
|
||||
|
@ -845,7 +844,7 @@ install: all $(if $(BUILD_DOCS),install-doc) install-datadir install-localstated
|
|||
$(if $(INSTALL_BLOBS),$(edk2-decompressed)) \
|
||||
recurse-install
|
||||
ifneq ($(TOOLS),)
|
||||
$(call install-prog,$(subst qemu-ga,qemu-ga$(EXESUF),$(TOOLS)),$(DESTDIR)$(bindir))
|
||||
$(call install-prog,$(TOOLS),$(DESTDIR)$(bindir))
|
||||
endif
|
||||
ifneq ($(CONFIG_MODULES),)
|
||||
$(INSTALL_DIR) "$(DESTDIR)$(qemu_moddir)"
|
||||
|
|
|
@ -150,7 +150,7 @@ static void tcp_chr_accept(QIONetListener *listener,
|
|||
void *opaque);
|
||||
|
||||
static int tcp_chr_read_poll(void *opaque);
|
||||
static void tcp_chr_disconnect(Chardev *chr);
|
||||
static void tcp_chr_disconnect_locked(Chardev *chr);
|
||||
|
||||
/* Called with chr_write_lock held. */
|
||||
static int tcp_chr_write(Chardev *chr, const uint8_t *buf, int len)
|
||||
|
@ -174,7 +174,7 @@ static int tcp_chr_write(Chardev *chr, const uint8_t *buf, int len)
|
|||
|
||||
if (ret < 0 && errno != EAGAIN) {
|
||||
if (tcp_chr_read_poll(chr) <= 0) {
|
||||
tcp_chr_disconnect(chr);
|
||||
tcp_chr_disconnect_locked(chr);
|
||||
return len;
|
||||
} /* else let the read handler finish it properly */
|
||||
}
|
||||
|
@ -469,8 +469,9 @@ static void update_disconnected_filename(SocketChardev *s)
|
|||
/* NB may be called even if tcp_chr_connect has not been
|
||||
* reached, due to TLS or telnet initialization failure,
|
||||
* so can *not* assume s->state == TCP_CHARDEV_STATE_CONNECTED
|
||||
* This must be called with chr->chr_write_lock held.
|
||||
*/
|
||||
static void tcp_chr_disconnect(Chardev *chr)
|
||||
static void tcp_chr_disconnect_locked(Chardev *chr)
|
||||
{
|
||||
SocketChardev *s = SOCKET_CHARDEV(chr);
|
||||
bool emit_close = s->state == TCP_CHARDEV_STATE_CONNECTED;
|
||||
|
@ -490,6 +491,13 @@ static void tcp_chr_disconnect(Chardev *chr)
|
|||
}
|
||||
}
|
||||
|
||||
static void tcp_chr_disconnect(Chardev *chr)
|
||||
{
|
||||
qemu_mutex_lock(&chr->chr_write_lock);
|
||||
tcp_chr_disconnect_locked(chr);
|
||||
qemu_mutex_unlock(&chr->chr_write_lock);
|
||||
}
|
||||
|
||||
static gboolean tcp_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
|
||||
{
|
||||
Chardev *chr = CHARDEV(opaque);
|
||||
|
@ -1131,8 +1139,10 @@ static gboolean socket_reconnect_timeout(gpointer opaque)
|
|||
Chardev *chr = CHARDEV(opaque);
|
||||
SocketChardev *s = SOCKET_CHARDEV(opaque);
|
||||
|
||||
qemu_mutex_lock(&chr->chr_write_lock);
|
||||
g_source_unref(s->reconnect_timer);
|
||||
s->reconnect_timer = NULL;
|
||||
qemu_mutex_unlock(&chr->chr_write_lock);
|
||||
|
||||
if (chr->be_open) {
|
||||
return false;
|
||||
|
|
|
@ -6129,7 +6129,7 @@ if [ "$guest_agent" != "no" ]; then
|
|||
if [ "$softmmu" = no -a "$want_tools" = no ] ; then
|
||||
guest_agent=no
|
||||
elif [ "$linux" = "yes" -o "$bsd" = "yes" -o "$solaris" = "yes" -o "$mingw32" = "yes" ] ; then
|
||||
tools="qemu-ga $tools"
|
||||
tools="qemu-ga\$(EXESUF) $tools"
|
||||
guest_agent=yes
|
||||
elif [ "$guest_agent" != yes ]; then
|
||||
guest_agent=no
|
||||
|
@ -6614,6 +6614,9 @@ fi
|
|||
if test "$profiler" = "yes" ; then
|
||||
echo "CONFIG_PROFILER=y" >> $config_host_mak
|
||||
fi
|
||||
if test "$want_tools" = "yes" ; then
|
||||
echo "CONFIG_TOOLS=y" >> $config_host_mak
|
||||
fi
|
||||
if test "$slirp" != "no"; then
|
||||
echo "CONFIG_SLIRP=y" >> $config_host_mak
|
||||
echo "CONFIG_SMBD_COMMAND=\"$smbd\"" >> $config_host_mak
|
||||
|
@ -7360,11 +7363,6 @@ if test "$sparse" = "yes" ; then
|
|||
echo "HOST_CC := REAL_CC=\"\$(HOST_CC)\" cgcc" >> $config_host_mak
|
||||
echo "QEMU_CFLAGS += -Wbitwise -Wno-transparent-union -Wno-old-initializer -Wno-non-pointer-null" >> $config_host_mak
|
||||
fi
|
||||
if test "$cross_prefix" != ""; then
|
||||
echo "AUTOCONF_HOST := --host=${cross_prefix%-}" >> $config_host_mak
|
||||
else
|
||||
echo "AUTOCONF_HOST := " >> $config_host_mak
|
||||
fi
|
||||
echo "LDFLAGS=$LDFLAGS" >> $config_host_mak
|
||||
echo "LDFLAGS_NOPIE=$LDFLAGS_NOPIE" >> $config_host_mak
|
||||
echo "QEMU_LDFLAGS=$QEMU_LDFLAGS" >> $config_host_mak
|
||||
|
|
|
@ -65,6 +65,6 @@ 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);
|
||||
bool module_load_one(const char *prefix, const char *lib_name);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -136,6 +136,7 @@ static gpointer qio_task_thread_worker(gpointer opaque)
|
|||
qio_task_thread_result, task, NULL);
|
||||
g_source_attach(task->thread->completion,
|
||||
task->thread->context);
|
||||
g_source_unref(task->thread->completion);
|
||||
trace_qio_task_thread_source_attach(task, task->thread->completion);
|
||||
|
||||
qemu_cond_signal(&task->thread_cond);
|
||||
|
|
103
memory.c
103
memory.c
|
@ -217,7 +217,6 @@ struct FlatRange {
|
|||
bool romd_mode;
|
||||
bool readonly;
|
||||
bool nonvolatile;
|
||||
int has_coalesced_range;
|
||||
};
|
||||
|
||||
#define FOR_EACH_FLAT_RANGE(var, view) \
|
||||
|
@ -654,7 +653,6 @@ static void render_memory_region(FlatView *view,
|
|||
fr.romd_mode = mr->romd_mode;
|
||||
fr.readonly = readonly;
|
||||
fr.nonvolatile = nonvolatile;
|
||||
fr.has_coalesced_range = 0;
|
||||
|
||||
/* Render the region itself into any gaps left by the current view. */
|
||||
for (i = 0; i < view->nr && int128_nz(remain); ++i) {
|
||||
|
@ -855,46 +853,55 @@ static void address_space_update_ioeventfds(AddressSpace *as)
|
|||
flatview_unref(view);
|
||||
}
|
||||
|
||||
/*
|
||||
* Notify the memory listeners about the coalesced IO change events of
|
||||
* range `cmr'. Only the part that has intersection of the specified
|
||||
* FlatRange will be sent.
|
||||
*/
|
||||
static void flat_range_coalesced_io_notify(FlatRange *fr, AddressSpace *as,
|
||||
CoalescedMemoryRange *cmr, bool add)
|
||||
{
|
||||
AddrRange tmp;
|
||||
|
||||
tmp = addrrange_shift(cmr->addr,
|
||||
int128_sub(fr->addr.start,
|
||||
int128_make64(fr->offset_in_region)));
|
||||
if (!addrrange_intersects(tmp, fr->addr)) {
|
||||
return;
|
||||
}
|
||||
tmp = addrrange_intersection(tmp, fr->addr);
|
||||
|
||||
if (add) {
|
||||
MEMORY_LISTENER_UPDATE_REGION(fr, as, Forward, coalesced_io_add,
|
||||
int128_get64(tmp.start),
|
||||
int128_get64(tmp.size));
|
||||
} else {
|
||||
MEMORY_LISTENER_UPDATE_REGION(fr, as, Reverse, coalesced_io_del,
|
||||
int128_get64(tmp.start),
|
||||
int128_get64(tmp.size));
|
||||
}
|
||||
}
|
||||
|
||||
static void flat_range_coalesced_io_del(FlatRange *fr, AddressSpace *as)
|
||||
{
|
||||
if (!fr->has_coalesced_range) {
|
||||
return;
|
||||
}
|
||||
CoalescedMemoryRange *cmr;
|
||||
|
||||
if (--fr->has_coalesced_range > 0) {
|
||||
return;
|
||||
QTAILQ_FOREACH(cmr, &fr->mr->coalesced, link) {
|
||||
flat_range_coalesced_io_notify(fr, as, cmr, false);
|
||||
}
|
||||
|
||||
MEMORY_LISTENER_UPDATE_REGION(fr, as, Reverse, coalesced_io_del,
|
||||
int128_get64(fr->addr.start),
|
||||
int128_get64(fr->addr.size));
|
||||
}
|
||||
|
||||
static void flat_range_coalesced_io_add(FlatRange *fr, AddressSpace *as)
|
||||
{
|
||||
MemoryRegion *mr = fr->mr;
|
||||
CoalescedMemoryRange *cmr;
|
||||
AddrRange tmp;
|
||||
|
||||
if (QTAILQ_EMPTY(&mr->coalesced)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (fr->has_coalesced_range++) {
|
||||
return;
|
||||
}
|
||||
|
||||
QTAILQ_FOREACH(cmr, &mr->coalesced, link) {
|
||||
tmp = addrrange_shift(cmr->addr,
|
||||
int128_sub(fr->addr.start,
|
||||
int128_make64(fr->offset_in_region)));
|
||||
if (!addrrange_intersects(tmp, fr->addr)) {
|
||||
continue;
|
||||
}
|
||||
tmp = addrrange_intersection(tmp, fr->addr);
|
||||
MEMORY_LISTENER_UPDATE_REGION(fr, as, Forward, coalesced_io_add,
|
||||
int128_get64(tmp.start),
|
||||
int128_get64(tmp.size));
|
||||
flat_range_coalesced_io_notify(fr, as, cmr, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2236,27 +2243,26 @@ void memory_region_ram_resize(MemoryRegion *mr, ram_addr_t newsize, Error **errp
|
|||
qemu_ram_resize(mr->ram_block, newsize, errp);
|
||||
}
|
||||
|
||||
static void memory_region_update_coalesced_range_as(MemoryRegion *mr, AddressSpace *as)
|
||||
/*
|
||||
* Call proper memory listeners about the change on the newly
|
||||
* added/removed CoalescedMemoryRange.
|
||||
*/
|
||||
static void memory_region_update_coalesced_range(MemoryRegion *mr,
|
||||
CoalescedMemoryRange *cmr,
|
||||
bool add)
|
||||
{
|
||||
AddressSpace *as;
|
||||
FlatView *view;
|
||||
FlatRange *fr;
|
||||
|
||||
view = address_space_get_flatview(as);
|
||||
FOR_EACH_FLAT_RANGE(fr, view) {
|
||||
if (fr->mr == mr) {
|
||||
flat_range_coalesced_io_del(fr, as);
|
||||
flat_range_coalesced_io_add(fr, as);
|
||||
}
|
||||
}
|
||||
flatview_unref(view);
|
||||
}
|
||||
|
||||
static void memory_region_update_coalesced_range(MemoryRegion *mr)
|
||||
{
|
||||
AddressSpace *as;
|
||||
|
||||
QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
|
||||
memory_region_update_coalesced_range_as(mr, as);
|
||||
view = address_space_get_flatview(as);
|
||||
FOR_EACH_FLAT_RANGE(fr, view) {
|
||||
if (fr->mr == mr) {
|
||||
flat_range_coalesced_io_notify(fr, as, cmr, add);
|
||||
}
|
||||
}
|
||||
flatview_unref(view);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2274,14 +2280,17 @@ void memory_region_add_coalescing(MemoryRegion *mr,
|
|||
|
||||
cmr->addr = addrrange_make(int128_make64(offset), int128_make64(size));
|
||||
QTAILQ_INSERT_TAIL(&mr->coalesced, cmr, link);
|
||||
memory_region_update_coalesced_range(mr);
|
||||
memory_region_update_coalesced_range(mr, cmr, true);
|
||||
memory_region_set_flush_coalesced(mr);
|
||||
}
|
||||
|
||||
void memory_region_clear_coalescing(MemoryRegion *mr)
|
||||
{
|
||||
CoalescedMemoryRange *cmr;
|
||||
bool updated = false;
|
||||
|
||||
if (QTAILQ_EMPTY(&mr->coalesced)) {
|
||||
return;
|
||||
}
|
||||
|
||||
qemu_flush_coalesced_mmio_buffer();
|
||||
mr->flush_coalesced_mmio = false;
|
||||
|
@ -2289,12 +2298,8 @@ void memory_region_clear_coalescing(MemoryRegion *mr)
|
|||
while (!QTAILQ_EMPTY(&mr->coalesced)) {
|
||||
cmr = QTAILQ_FIRST(&mr->coalesced);
|
||||
QTAILQ_REMOVE(&mr->coalesced, cmr, link);
|
||||
memory_region_update_coalesced_range(mr, cmr, false);
|
||||
g_free(cmr);
|
||||
updated = true;
|
||||
}
|
||||
|
||||
if (updated) {
|
||||
memory_region_update_coalesced_range(mr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
9
qtest.c
9
qtest.c
|
@ -661,6 +661,15 @@ static void qtest_process_command(CharBackend *chr, gchar **words)
|
|||
qtest_send_prefix(chr);
|
||||
qtest_sendf(chr, "OK %"PRIi64"\n",
|
||||
(int64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
|
||||
} else if (strcmp(words[0], "module_load") == 0) {
|
||||
g_assert(words[1] && words[2]);
|
||||
|
||||
qtest_send_prefix(chr);
|
||||
if (module_load_one(words[1], words[2])) {
|
||||
qtest_sendf(chr, "OK\n");
|
||||
} else {
|
||||
qtest_sendf(chr, "FAIL\n");
|
||||
}
|
||||
} else if (qtest_enabled() && strcmp(words[0], "clock_set") == 0) {
|
||||
int64_t ns;
|
||||
int ret;
|
||||
|
|
|
@ -702,8 +702,8 @@ if __name__ == '__main__':
|
|||
|
||||
config = data.compute_config()
|
||||
for key in sorted(config.keys()):
|
||||
if key not in external_vars:
|
||||
print ('CONFIG_%s=%s' % (key, ('y' if config[key] else 'n')))
|
||||
if key not in external_vars and config[key]:
|
||||
print ('CONFIG_%s=y' % key)
|
||||
|
||||
deps = open(argv[2], 'w')
|
||||
for fname in data.previously_included:
|
||||
|
|
|
@ -149,6 +149,7 @@ check-block-$(call land,$(CONFIG_POSIX),$(CONFIG_SOFTMMU)) += tests/check-block.
|
|||
|
||||
check-qtest-generic-y += tests/qmp-test$(EXESUF)
|
||||
check-qtest-generic-y += tests/qmp-cmd-test$(EXESUF)
|
||||
check-qtest-generic-$(CONFIG_MODULES) += tests/modules-test$(EXESUF)
|
||||
|
||||
check-qtest-generic-y += tests/device-introspect-test$(EXESUF)
|
||||
check-qtest-generic-y += tests/cdrom-test$(EXESUF)
|
||||
|
|
|
@ -811,6 +811,12 @@ bool qtest_get_irq(QTestState *s, int num)
|
|||
return s->irq_level[num];
|
||||
}
|
||||
|
||||
void qtest_module_load(QTestState *s, const char *prefix, const char *libname)
|
||||
{
|
||||
qtest_sendf(s, "module_load %s %s\n", prefix, libname);
|
||||
qtest_rsp(s, 0);
|
||||
}
|
||||
|
||||
static int64_t qtest_clock_rsp(QTestState *s)
|
||||
{
|
||||
gchar **words;
|
||||
|
|
|
@ -262,6 +262,8 @@ char *qtest_hmp(QTestState *s, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
|
|||
char *qtest_vhmp(QTestState *s, const char *fmt, va_list ap)
|
||||
GCC_FMT_ATTR(2, 0);
|
||||
|
||||
void qtest_module_load(QTestState *s, const char *prefix, const char *libname);
|
||||
|
||||
/**
|
||||
* qtest_get_irq:
|
||||
* @s: #QTestState instance to operate on.
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
#include "qemu/osdep.h"
|
||||
#include "libqtest.h"
|
||||
|
||||
static void test_modules_load(const void *data)
|
||||
{
|
||||
QTestState *qts;
|
||||
const char **args = data;
|
||||
|
||||
qts = qtest_init(NULL);
|
||||
qtest_module_load(qts, args[0], args[1]);
|
||||
qtest_quit(qts);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
const char *modules[] = {
|
||||
#ifdef CONFIG_CURL
|
||||
"block-", "curl",
|
||||
#endif
|
||||
#ifdef CONFIG_GLUSTERFS
|
||||
"block-", "gluster",
|
||||
#endif
|
||||
#ifdef CONFIG_LIBISCSI
|
||||
"block-", "iscsi",
|
||||
#endif
|
||||
#ifdef CONFIG_LIBNFS
|
||||
"block-", "nfs",
|
||||
#endif
|
||||
#ifdef CONFIG_LIBSSH
|
||||
"block-", "ssh",
|
||||
#endif
|
||||
#ifdef CONFIG_RBD
|
||||
"block-", "rbd",
|
||||
#endif
|
||||
#ifdef CONFIG_AUDIO_ALSA
|
||||
"audio-", "alsa",
|
||||
#endif
|
||||
#ifdef CONFIG_AUDIO_OSS
|
||||
"audio-", "oss",
|
||||
#endif
|
||||
#ifdef CONFIG_AUDIO_PA
|
||||
"audio-", "pa",
|
||||
#endif
|
||||
#ifdef CONFIG_AUDIO_SDL
|
||||
"audio-", "sdl",
|
||||
#endif
|
||||
#ifdef CONFIG_CURSES
|
||||
"ui-", "curses",
|
||||
#endif
|
||||
#if defined(CONFIG_GTK) && defined(CONFIG_VTE)
|
||||
"ui-", "gtk",
|
||||
#endif
|
||||
#ifdef CONFIG_SDL
|
||||
"ui-", "sdl",
|
||||
#endif
|
||||
#if defined(CONFIG_SPICE) && defined(CONFIG_GIO)
|
||||
"ui-", "spice-app",
|
||||
#endif
|
||||
};
|
||||
int i;
|
||||
|
||||
g_test_init(&argc, &argv, NULL);
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS(modules); i += 2) {
|
||||
char *testname = g_strdup_printf("/module/load/%s", modules[i + 1]);
|
||||
qtest_add_data_func(testname, modules + i, test_modules_load);
|
||||
g_free(testname);
|
||||
}
|
||||
|
||||
return g_test_run();
|
||||
}
|
|
@ -156,8 +156,10 @@ out:
|
|||
}
|
||||
#endif
|
||||
|
||||
void module_load_one(const char *prefix, const char *lib_name)
|
||||
bool module_load_one(const char *prefix, const char *lib_name)
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
#ifdef CONFIG_MODULES
|
||||
char *fname = NULL;
|
||||
char *exec_dir;
|
||||
|
@ -170,7 +172,7 @@ void module_load_one(const char *prefix, const char *lib_name)
|
|||
|
||||
if (!g_module_supported()) {
|
||||
fprintf(stderr, "Module is not supported by system.\n");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!loaded_modules) {
|
||||
|
@ -179,11 +181,10 @@ void module_load_one(const char *prefix, const char *lib_name)
|
|||
|
||||
module_name = g_strdup_printf("%s%s", prefix, lib_name);
|
||||
|
||||
if (g_hash_table_lookup(loaded_modules, module_name)) {
|
||||
if (!g_hash_table_add(loaded_modules, module_name)) {
|
||||
g_free(module_name);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
g_hash_table_insert(loaded_modules, module_name, module_name);
|
||||
|
||||
exec_dir = qemu_get_exec_dir();
|
||||
search_dir = getenv("QEMU_MODULE_DIR");
|
||||
|
@ -206,13 +207,19 @@ void module_load_one(const char *prefix, const char *lib_name)
|
|||
fname = NULL;
|
||||
/* Try loading until loaded a module file */
|
||||
if (!ret) {
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
g_hash_table_remove(loaded_modules, module_name);
|
||||
}
|
||||
|
||||
for (i = 0; i < n_dirs; i++) {
|
||||
g_free(dirs[i]);
|
||||
}
|
||||
|
||||
#endif
|
||||
return success;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue