On Mon, Feb 17, 2020 at 09:34:12PM -0600, Eric Blake wrote:
In the next patch, we want to get rid of the requirement for the
user
to supply LD_LIBRARY_PATH pointing to vddk libs, if we can derive it
ourselves from libdir. However, VDDK itself requires LD_LIBRARY_PATH
to be set (because it tries to load libraries that in turn depend on a
bare library name, which no manner of dlopen() hacking can work
around, and implementing la_objsearch() is no better for requiring
LD_AUDIT to be set). And since ld.so caches the value of
LD_LIBRARY_PATH at startup (for security reasons), the ONLY way to set
it for loading vddk, while clearing it again before --run spawns a
child process, is to re-exec nbdkit with slight alterations.
Since VDDK only runs on Linux, we can assume the presence of
/proc/self/{exe,cmdline}, and parse off everything we need (provided
nbdkit didn't muck with argv[], which we just fixed) to recursively
exec with a munged environment that still has enough breadcrumbs to
undo the munging.
This patch does not quite set LD_LIBRARY_PATH correctly in all cases
(since vddk expects libdir= to point to vmware-vix-disklib-distrib/,
but LD_LIBRARY_PATH to vmware-vix-disklib-distrib/lib64), but that
will be cleaned up in the next patch; in the meantime, the re-exec in
this patch fires but has no ill effects.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
Compared to v5: patch 1 and 2 are completely dropped, patch 3/4 is the
first one applied as-is, then this patch, then an updated version of
4/4 (which I haven't finished updating yet). Posting this now before
I go to bed.
Still needed: either the testsuite HAS to create its dummy
libvixDiskLib.so.6 under a /lib64 subdirectory, or we should add some
intelligence to probing whether $libdir/*.so or $libdir/lib64/*.so
exists and set prefix accordingly. But that's minor compared to that
fact that I did confirm that re-execing works to temporarily override
LD_LIBRARY_PATH without any modification to nbdkit proper (other than
a one-liner I already pushed to let /proc/NNN/cmdline be correct for
re-exec purposes).
The diffstat is a bit large, but the fact that it is self-contained to
vddk.c is a plus. Parsing /proc/self/cmdline is a pain.
plugins/vddk/vddk.c | 146 +++++++++++++++++++++++++++++++++++++++++---
1 file changed, 139 insertions(+), 7 deletions(-)
diff --git a/plugins/vddk/vddk.c b/plugins/vddk/vddk.c
index 0abec68e..95940b3b 100644
--- a/plugins/vddk/vddk.c
+++ b/plugins/vddk/vddk.c
@@ -1,5 +1,5 @@
/* nbdkit
- * Copyright (C) 2013-2019 Red Hat Inc.
+ * Copyright (C) 2013-2020 Red Hat Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -40,6 +40,7 @@
#include <string.h>
#include <unistd.h>
#include <dlfcn.h>
+#include <fcntl.h>
#define NBDKIT_API_VERSION 2
@@ -72,7 +73,8 @@ int vddk_debug_extents;
#define VDDK_MINOR 1
static void *dl = NULL; /* dlopen handle */
-static int init_called = 0; /* was InitEx called */
+static bool init_called = false; /* was InitEx called */
+static char *reexeced = false; /* did libdir require reexec */
I guess this works, but is "NULL" better than "false"?
+ /* If load_library caused a re-execution with an expanded
+ * LD_LIBRARY_PATH, restore it back to its original contents.
+ * dlopen uses the value of LD_LIBRARY_PATH cached at program
+ * startup; our change is for the sake of child processes (such as
+ * --run) to see the same environment as the original nbdkit saw
+ * before re-exec.
+ */
Could we pass the original LD_LIBRARY_PATH on the command line too?
Rich.
--
Richard Jones, Virtualization Group, Red Hat
http://people.redhat.com/~rjones
Read my programming and virtualization blog:
http://rwmj.wordpress.com
virt-builder quickly builds VMs from scratch
http://libguestfs.org/virt-builder.1.html