Hello!

Today I discovered an interesting issue here: I copied a system-installed
binary into another directory, in order to debug an unrelated issue. Just
to discover it does not work, being unable to find any modules or data
files.

Here's how the strace of typical qemu-system-i386 run looks like (the
relevant parts only):

access("/tmp/qemu-bundle", R_OK) = -1 ENOENT (No such file or directory)
access("/tmp/b/../lib/x86_64-linux-gnu/qemu/accel-tcg-i386.so", F_OK) = -1 
ENOENT (No such file or directory)
access("/var/run/qemu/Debian_1_8.0~rc4+dfsg-3/accel-tcg-i386.so", F_OK) = -1 
ENOENT (No such file or directory)

(the executable in this case is in /tmp, obviously).  And it fails with
error "fatal: could not load module for type 'tcg-accel-ops'".

This is despite the fact that qemu has been configured with proper --libdir
and other --foodir to point to actual dirs such as /usr/lib /usr/share etc.

Looking at the code I see this, in cutil.c:get_relocated_path() (simplified):

char *get_relocated_path(const char *dir)
{
    const char *bindir = CONFIG_BINDIR;
    const char *exec_dir = qemu_get_exec_dir();

    result = concat(exec_dir, "/qemu-bundle");
    if (access(result, R_OK) == 0) {  <== should be X_OK and should be dir, too!
        g_string_append(result, dir);
    } else if (!starts_with_prefix(dir) || !starts_with_prefix(bindir)) {
        g_string_assign(result, dir);
    } else {
        g_string_assign(result, exec_dir);
        .. search in  execdir and its parents ..
    }

This seems to be questionable.  And btw, even when running qemu from
the installed /usr/bin/ location, it does something weird:

access("/usr/bin/qemu-bundle", R_OK)    = -1 ENOENT (No such file or directory)
access("/usr/bin/../lib/x86_64-linux-gnu/qemu/accel-tcg-x86_64.so", F_OK) = 0
openat(AT_FDCWD, "/usr/bin/../lib/x86_64-linux-gnu/qemu/accel-tcg-x86_64.so", 
O_RDONLY|O_CLOEXEC) = 14

so it is not obvious why it skips the full path in this case (the 2nd
choice) and falls into the 3rd variant (search in execdir and parents).

Why it *ever* wants to search in parent dirs relative to executable
path? And why these !starts_with_prefix()?

BTW, the second starts_with_prefix(bindir) condition is just stupid, -
bindir is CONFIG_BINDIR (static), and start_with_prefix() checks for
CONFIG_PREFIX which is also static.

The whole this logic smells.. strange at best :)

How about this: if qemu-bundle exists, use qemu-bundle/dir, instead
use dir directly?  Why do we need all other conditions? Why do we
do different things depending on the place the executable is located?

In the past, qemu tried to look in pc-bios/ and other similar places, -
when run from the build dir.  But since it does not do this anymore,
we can just skip whole thing, no?

/mjt

Reply via email to