[collectd] [PATCH] Use libc's dlopen/dlsym instead of libtool's ones when available

Bruno Prémont bonbons at linux-vserver.org
Sat Jul 23 12:14:27 CEST 2011


Patch below changes collectd's plugin.c to use dlopen/dlsym/dlerror
from libc when dlfcn.h is available instead of using libtool equivalents.

This reduces libtool to a build-dependency only instead of also being a
runtime dependency.

Signed-off-by: Bruno Prémont <bonbons at linux-vserver.org>
---
Patch is against 4.10 branch.

 configure.in    |    4 ++++
 src/Makefile.am |    3 +++
 src/plugin.c    |   40 +++++++++++++++++++++++++++++++++++++++-
 3 files changed, 46 insertions(+), 1 deletions(-)

diff --git a/configure.in b/configure.in
index 88cdb50..8581d43 100644
--- a/configure.in
+++ b/configure.in
@@ -258,6 +258,9 @@ AC_CHECK_HEADERS(netinet/udp.h, [], [],
 #endif
 ])
 
+# For plugin
+AC_CHECK_HEADERS(dlfcn.h, [have_dlfcn_h="yes"], [have_dlfcn_h="no"])
+
 # For cpu modules
 AC_CHECK_HEADERS(sys/dkstat.h)
 if test "x$ac_system" = "xDarwin"
@@ -577,6 +580,7 @@ AC_CHECK_FUNCS(nanosleep,
         AC_CHECK_LIB(posix4, nanosleep,
             [nanosleep_needs_posix4="yes"],
             AC_MSG_ERROR(cannot find nanosleep))))
+AM_CONDITIONAL(BUILD_WITH_LIBDL, test "x$have_dlfcn_h" = "xyes")
 AM_CONDITIONAL(BUILD_WITH_LIBRT, test "x$nanosleep_needs_rt" = "xyes")
 AM_CONDITIONAL(BUILD_WITH_LIBPOSIX4, test "x$nanosleep_needs_posix4" = "xyes")
 
diff --git a/src/Makefile.am b/src/Makefile.am
index c6b0538..e5c953d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -50,6 +50,9 @@ collectd_LDADD =
 collectd_DEPENDENCIES =
 
 # Link to these libraries..
+if BUILD_WITH_LIBDL
+collectd_LDADD += -ldl
+endif
 if BUILD_WITH_LIBRT
 collectd_LDADD += -lrt
 endif
diff --git a/src/plugin.c b/src/plugin.c
index a3f10ae..2221e2e 100644
--- a/src/plugin.c
+++ b/src/plugin.c
@@ -23,7 +23,11 @@
 #include "collectd.h"
 #include "utils_complain.h"
 
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#else
 #include <ltdl.h>
+#endif
 
 #if HAVE_PTHREAD_H
 # include <pthread.h>
@@ -277,8 +281,41 @@ static int plugin_unregister (llist_t *list, const char *name) /* {{{ */
  */
 static int plugin_load_file (char *file, uint32_t flags)
 {
-	lt_dlhandle dlh;
 	void (*reg_handle) (void);
+#if HAVE_DLFCN_H
+	void *dlh;
+
+	dlh = dlopen(file, RTLD_NOW | (flags & PLUGIN_FLAGS_GLOBAL ? RTLD_GLOBAL : RTLD_LOCAL));
+	if (dlh == NULL)
+	{
+		char errbuf[1024] = "";
+
+		ssnprintf (errbuf, sizeof (errbuf),
+				"dlopen (\"%s\") failed: %s. "
+				"The most common cause for this problem are "
+				"missing dependencies. Use ldd(1) to check "
+				"the dependencies of the plugin "
+				"/ shared object.",
+				file, dlerror ());
+
+		ERROR ("%s", errbuf);
+		/* Make sure this is printed to STDERR in any case, but also
+		 * make sure it's printed only once. */
+		if (list_log != NULL)
+			fprintf (stderr, "ERROR: %s\n", errbuf);
+
+		return (1);
+	}
+
+	if ((reg_handle = (void (*) (void)) dlsym(dlh, "module_register")) == NULL)
+	{
+		WARNING ("Couldn't find symbol \"module_register\" in \"%s\": %s\n",
+				file, dlerror ());
+		dlclose(dlh);
+		return (-1);
+	}
+#else
+	lt_dlhandle dlh;
 
 	lt_dlinit ();
 	lt_dlerror (); /* clear errors */
@@ -328,6 +365,7 @@ static int plugin_load_file (char *file, uint32_t flags)
 		lt_dlclose (dlh);
 		return (-1);
 	}
+#endif
 
 	(*reg_handle) ();
 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://mailman.verplant.org/pipermail/collectd/attachments/20110723/6b016eeb/attachment.pgp>


More information about the collectd mailing list