[libvirt] [PATCH sandbox] Ensure libvirt-sandbox-init-common uses correct ld-linux

Cedric Bosdonnat cbosdonnat at suse.com
Wed Jul 1 08:12:34 UTC 2015


On Tue, 2015-06-30 at 17:51 +0100, Daniel P. Berrange wrote:
> 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";

ACK. Tested it with a sles11 sp3 guest on openSUSE 13.2: works like a
charm.

--
Cedric




More information about the libvir-list mailing list