The libc.so library requires certainly functionality to be provided by the ld-linux.so library. The ld-linux.so is loaded by the kernel based on the PT_INTERP ELF section, and as such LD_LIBRARY_PATH has no effect. So, although libvirt-sandbox-init-{qemu,lxc} set LD_LIBRARY_PATH to force use of the libs from the host OS image, the common init program was stil using the ld-linux.so from the guest OS image. Sometimes this works, sometimes it breaks. When trying to run Fedora 19 as the root filesystem from a Fedora 22 host, it would break thus: /etc/libvirt-sandbox/scratch/.libs/libvirt-sandbox-init-common: relocation error: /etc/libvirt-sandbox/scratch/.libs/libc.so.6: symbol _dl_find_dso_for_object, version GLIBC_PRIVATE not defined in file ld-linux-x86-64.so.2 with link time reference To deal with this we must ensure that we always invoke the libvirt-sandbox-init-common program using the ld-linux that was provided by the host OS image. The sandbox builder is tweaked so that it always copies the host ld-linux.so into the libs scratch directory, and gives it a predictable name 'ld.so', since every architecture seems to have a different name. The libvirt-sandbox-init-{lxc,qemu} files are changed so that instead of exec'ing libvirt-sandbox-init-common directly, they will load it via the ld.so file. --- libvirt-sandbox/libvirt-sandbox-builder.c | 28 +++++++++++++++++++++++----- libvirt-sandbox/libvirt-sandbox-init-lxc.c | 1 + libvirt-sandbox/libvirt-sandbox-init-qemu.c | 1 + 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/libvirt-sandbox/libvirt-sandbox-builder.c b/libvirt-sandbox/libvirt-sandbox-builder.c index 2726868..e615606 100644 --- a/libvirt-sandbox/libvirt-sandbox-builder.c +++ b/libvirt-sandbox/libvirt-sandbox-builder.c @@ -252,10 +252,11 @@ GVirConnection *gvir_sandbox_builder_get_connection(GVirSandboxBuilder *builder) static gboolean gvir_sandbox_builder_copy_file(const char *path, const char *libsdir, + const char *newname, GError **error) { gchar *name = g_path_get_basename(path); - gchar *target = g_build_filename(libsdir, name, NULL); + gchar *target = g_build_filename(libsdir, newname ? newname : name, NULL); GFile *srcFile = g_file_new_for_path(path); GFile *tgtFile = g_file_new_for_path(target); gboolean result = FALSE; @@ -285,7 +286,7 @@ static gboolean gvir_sandbox_builder_copy_program(const char *program, const gchar *argv[] = {LDD_PATH, program, NULL}; gboolean result = FALSE; - if (!gvir_sandbox_builder_copy_file(program, dest, error)) + if (!gvir_sandbox_builder_copy_file(program, dest, NULL, error)) goto cleanup; @@ -301,14 +302,31 @@ static gboolean gvir_sandbox_builder_copy_program(const char *program, *tmp = '\0'; /* Search the line for the library path */ - start = strstr(line, " => "); + start = strstr(line, "/"); end = strstr(line, " ("); if (start && end) { - start = start + 4; + const gchar *newname = NULL; *end = '\0'; - if (!gvir_sandbox_builder_copy_file(start, dest, error)) + /* There are countless different naming schemes for + * the ld-linux.so library across architectures. Pretty + * much the only thing in common is they start with + * the two letters 'ld'. The LDD program prints it + * out differently too - it doesn't include " => " + * as this library is special - its actually a static + * linked executable not a library. + * + * To make life easier for libvirt-sandbox-init-{qemu,lxc} + * we just call the file 'ld.so' when we copy it into our + * scratch dir, no matter what it was called on the host. + */ + if (!strstr(line, " => ") && + strstr(start, "/ld")) { + newname = "ld.so"; + } + + if (!gvir_sandbox_builder_copy_file(start, dest, newname, error)) goto cleanup; } diff --git a/libvirt-sandbox/libvirt-sandbox-init-lxc.c b/libvirt-sandbox/libvirt-sandbox-init-lxc.c index e2fe7f0..d1e4a79 100644 --- a/libvirt-sandbox/libvirt-sandbox-init-lxc.c +++ b/libvirt-sandbox/libvirt-sandbox-init-lxc.c @@ -77,6 +77,7 @@ main(int argc, char **argv) args[narg++] = "1000"; } + args[narg++] = SANDBOXCONFIGDIR "/.libs/ld.so"; args[narg++] = SANDBOXCONFIGDIR "/.libs/libvirt-sandbox-init-common"; if (debug) args[narg++] = "-d"; diff --git a/libvirt-sandbox/libvirt-sandbox-init-qemu.c b/libvirt-sandbox/libvirt-sandbox-init-qemu.c index 09580da..cd6055a 100644 --- a/libvirt-sandbox/libvirt-sandbox-init-qemu.c +++ b/libvirt-sandbox/libvirt-sandbox-init-qemu.c @@ -422,6 +422,7 @@ main(int argc ATTR_UNUSED, char **argv ATTR_UNUSED) args[narg++] = "1000"; } + args[narg++] = SANDBOXCONFIGDIR "/.libs/ld.so"; args[narg++] = SANDBOXCONFIGDIR "/.libs/libvirt-sandbox-init-common"; if (debug) args[narg++] = "-d"; -- 2.4.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list