/aclocal.m4
/autom4te.cache
/autom4te.cache
+/build-aux/
/compile
/config.guess
/config.sub
/install-sh
/libltdl/
/ltmain.sh
+/m4/libtool.m4
+/m4/ltargz.m4
+/m4/ltdl.m4
+/m4/lt~obsolete.m4
+/m4/ltoptions.m4
+/m4/ltsugar.m4
+/m4/ltversion.m4
/missing
-src/config.h.in
+/src/config.h.in
# configure stuff:
Makefile
-ACLOCAL_AMFLAGS = -I libltdl/m4
+ACLOCAL_AMFLAGS = -I m4
-SUBDIRS =
-
-if BUILD_INCLUDED_LTDL
-SUBDIRS += libltdl
-endif
-
-SUBDIRS += proto src bindings .
-
-AM_CPPFLAGS = $(LTDLINCL)
+SUBDIRS = proto src bindings .
EXTRA_DIST = contrib version-gen.sh testwrapper.sh
$(mkinstalldirs) $(DESTDIR)$(localstatedir)/log
maintainer-clean-local:
- -rm -f -r libltdl
-rm -f INSTALL
-rm -f aclocal.m4
- flex
- bison
- libtool
-- libtool-ltdl
- pkg-config
The `build.sh' script takes no arguments.
autoheader \
&& aclocal \
-&& $libtoolize --ltdl --copy --force \
+&& $libtoolize --copy --force \
&& automake --add-missing --copy \
&& autoconf
&& rm -f configure \
&& rm -f depcomp \
&& rm -f install-sh \
-&& rm -f -r libltdl \
&& rm -f libtool \
&& rm -f ltmain.sh \
&& rm -f Makefile \
AC_INIT([collectd],[m4_esyscmd(./version-gen.sh)])
AC_CONFIG_SRCDIR(src/target_set.c)
AC_CONFIG_HEADERS(src/config.h)
-AC_CONFIG_AUX_DIR([libltdl/config])
+AC_CONFIG_AUX_DIR([build-aux])
+AC_CONFIG_MACRO_DIR([m4])
dnl older automake's default of ARFLAGS=cru is noisy on newer binutils;
dnl we don't really need the 'u' even in older toolchains. Then there is
dnl older libtool, which spelled it AR_FLAGS
m4_divert_text([DEFAULTS], [: "${ARFLAGS=cr} ${AR_FLAGS=cr}"])
-m4_ifdef([LT_PACKAGE_VERSION],
- # libtool >= 2.2
- [
- LT_CONFIG_LTDL_DIR([libltdl])
- LT_INIT([dlopen])
- LTDL_INIT([convenience])
- AC_DEFINE(LIBTOOL_VERSION, 2, [Define to used libtool version.])
- ]
-,
- # libtool <= 1.5
- [
- AC_LIBLTDL_CONVENIENCE
- AC_SUBST(LTDLINCL)
- AC_SUBST(LIBLTDL)
- AC_LIBTOOL_DLOPEN
- AC_CONFIG_SUBDIRS(libltdl)
- AC_DEFINE(LIBTOOL_VERSION, 1, [Define to used libtool version.])
- ]
-)
-
-AM_CONDITIONAL([BUILD_INCLUDED_LTDL], [test "x$LTDLDEPS" != "x"])
+LT_INIT([dlopen])
AM_INIT_AUTOMAKE([subdir-objects tar-pax dist-bzip2 no-dist-gzip foreign])
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
AM_CONDITIONAL(COMPILER_IS_GCC, test "x$GCC" = "xyes")
AC_DISABLE_STATIC
-AC_PROG_LIBTOOL
AC_PROG_LEX
AC_PROG_YACC
AC_MSG_ERROR([bison is missing and you do not have ${srcdir}/src/liboconfig/parser.c. Please install bison])
fi
+AS_IF([test "x$lt_cv_dlopen" = "xno"],
+ [AC_MSG_ERROR([Your system does not support dlopen])]
+)
+
+AC_SUBST([DLOPEN_LIBS], [$lt_cv_dlopen_libs])
+
AC_ARG_VAR([PROTOC], [path to the protoc binary])
AC_PATH_PROG([PROTOC], [protoc])
have_protoc3="no"
datadir: "/var/lib/collectd/rrd/"
libdir: "/usr/lib/collectd/"
+docker/
+-------
+Sample docker setup using an LD_PRELOAD wrapper to redirect system calls
+accessing /proc and /sys to prefixed bind-mounts inside the container.
+
+Drop your collectd configuration snippets in the
+contrib/docker/collectd.conf.d/ directory, and build an image including them:
+ $ docker build -t my_collectd ./contrib/docker/
+
+Then run it with the required bind-mounts:
+ $ docker run -it --rm \
+ -v /proc:/rootfs/proc:ro -v /sys:/rootfs/sys:ro \
+ --name collectd my_collectd
+ $ docker exec -it collectd collectdctl listval
+
exec-munin.px
-------------
Script to be used with the exec-plugin (see collectd-exec(5) for details)
--- /dev/null
+APT::Install-Recommends "0";
+APT::Install-Suggests "0";
+APT::Get::Assume-Yes "1";
+APT::Get::AutomaticRemove "1";
--- /dev/null
+FROM debian:stable
+
+ENV DEBIAN_FRONTEND noninteractive
+COPY 50docker-apt-conf /etc/apt/apt.conf.d/
+
+COPY rootfs_prefix/ /usr/src/rootfs_prefix/
+
+RUN apt-get update \
+ && apt-get upgrade \
+ && apt-get install \
+ collectd-core \
+ collectd-utils \
+ build-essential \
+ && make -C /usr/src/rootfs_prefix/ \
+ && apt-get --purge remove build-essential \
+ && apt-get clean \
+ && rm -rf /var/lib/apt/lists/*
+
+COPY collectd.conf /etc/collectd/collectd.conf
+COPY collectd.conf.d /etc/collectd/collectd.conf.d
+
+ENV LD_PRELOAD /usr/src/rootfs_prefix/rootfs_prefix.so
+
+CMD [ "/usr/sbin/collectd", "-f"]
--- /dev/null
+LoadPlugin logfile
+<Plugin logfile>
+ LogLevel "info"
+ File STDOUT
+ Timestamp true
+ PrintSeverity true
+</Plugin>
+
+LoadPlugin unixsock
+<Plugin unixsock>
+ SocketGroup "nogroup"
+</Plugin>
+
+<Include "/etc/collectd/collectd.conf.d">
+ Filter "*.conf"
+</Include>
--- /dev/null
+LoadPlugin cpu
+LoadPlugin memory
+LoadPlugin disk
+LoadPlugin df
--- /dev/null
+rootfs_prefix.so: rootfs_prefix.c
+ $(CC) -Wall -Werror -fPIC -shared -o rootfs_prefix.so rootfs_prefix.c -ldl
--- /dev/null
+#define _GNU_SOURCE
+
+#include <dirent.h>
+#include <dlfcn.h>
+#include <errno.h>
+#include <error.h>
+#include <stdio.h>
+#include <string.h>
+
+#define PREFIX "/rootfs"
+#define BUFSIZE 256
+
+const char *add_prefix(const char *orig, char *prefixed) {
+ int status;
+ int errno;
+
+ if ((strncmp(orig, "/proc", 5) == 0) || (strncmp(orig, "/sys", 4) == 0)) {
+
+ status = snprintf(prefixed, BUFSIZE, "%s%s", PREFIX, orig);
+ if ((unsigned int)status >= BUFSIZE) {
+ error(status, ENAMETOOLONG,
+ "'%s' got truncated when adding '%s' prefix: '%s'", orig, PREFIX,
+ prefixed);
+ return orig;
+ } else if (status < 1) {
+ error(status, errno,
+ "adding '%s' prefix to file path failed: '%s' -> '%s'", PREFIX,
+ orig, prefixed);
+ return orig;
+ } else {
+ return (const char *)prefixed;
+ }
+
+ } else {
+ return orig;
+ }
+}
+
+FILE *fopen(const char *path, const char *mode) {
+ char filename[BUFSIZE] = "\0";
+
+ FILE *(*original_fopen)(const char *, const char *);
+ original_fopen = dlsym(RTLD_NEXT, "fopen");
+
+ return (*original_fopen)(add_prefix(path, filename), mode);
+}
+
+DIR *opendir(const char *name) {
+ char filename[BUFSIZE] = "\0";
+
+ DIR *(*original_opendir)(const char *);
+ original_opendir = dlsym(RTLD_NEXT, "opendir");
+
+ return (*original_opendir)(add_prefix(name, filename));
+}
+
+int *open(const char *pathname, int flags) {
+ char filename[BUFSIZE] = "\0";
+
+ int *(*original_open)(const char *, int);
+ original_open = dlsym(RTLD_NEXT, "open");
+
+ return (*original_open)(add_prefix(pathname, filename), flags);
+}
License: GPLv2
Group: System Environment/Daemons
BuildRoot: %{_tmppath}/%{name}-%{version}-root
-BuildRequires: libgcrypt-devel, kernel-headers, libtool-ltdl-devel, libcap-devel, which
+BuildRequires: libgcrypt-devel, kernel-headers, libcap-devel, which
Vendor: collectd development team <collectd@verplant.org>
%if 0%{?fedora} || 0%{?rhel} >= 7
%configure CFLAGS="%{optflags} -DLT_LAZY_OR_NOW=\"RTLD_LAZY|RTLD_GLOBAL\"" \
%{?_python_config} \
--disable-static \
- --without-included-ltdl \
--enable-all-plugins=yes \
--enable-match_empty_counter \
--enable-match_hashed \
}
struct {
- char *path;
- char *type;
- char *type_instance;
+ const char *path;
+ const char *type;
+ const char *type_instance;
gauge_t factor;
} metrics[] = {
{STATEFS_ROOT "Current", "current", NULL, 1e-6}, // from uA to A
utils_threshold.c utils_threshold.h
-collectd_CPPFLAGS = $(AM_CPPFLAGS) $(LTDLINCL)
collectd_CFLAGS = $(AM_CFLAGS)
collectd_LDFLAGS = -export-dynamic
-collectd_LDADD = libavltree.la libcommon.la libheap.la -lm $(COMMON_LIBS)
+collectd_LDADD = libavltree.la libcommon.la libheap.la -lm $(COMMON_LIBS) $(DLOPEN_LIBS)
collectd_DEPENDENCIES = libavltree.la libcommon.la libheap.la libmetadata.la
# The daemon needs to call sg_init, so we need to link it against libstatgrab,
endif
if BUILD_WITH_OWN_LIBOCONFIG
-collectd_LDADD += $(LIBLTDL) $(top_builddir)/src/liboconfig/liboconfig.la
+collectd_LDADD += $(top_builddir)/src/liboconfig/liboconfig.la
collectd_DEPENDENCIES += $(top_builddir)/src/liboconfig/liboconfig.la
else
collectd_LDADD += -loconfig
static int dispatch_loadplugin(oconfig_item_t *ci) {
const char *name;
- unsigned int flags = 0;
+ _Bool global = 0;
plugin_ctx_t ctx = {0};
plugin_ctx_t old_ctx;
int ret_val;
oconfig_item_t *child = ci->children + i;
if (strcasecmp("Globals", child->key) == 0)
- cf_util_get_flag(child, &flags, PLUGIN_FLAGS_GLOBAL);
+ cf_util_get_boolean(child, &global);
else if (strcasecmp("Interval", child->key) == 0)
cf_util_get_cdtime(child, &ctx.interval);
else if (strcasecmp("FlushInterval", child->key) == 0)
}
old_ctx = plugin_set_ctx(ctx);
- ret_val = plugin_load(name, (uint32_t)flags);
+ ret_val = plugin_load(name, global);
/* reset to the "global" context */
plugin_set_ctx(old_ctx);
int meta_data_as_string(meta_data_t *md, /* {{{ */
const char *key, char **value) {
meta_entry_t *e;
- char *actual;
+ const char *actual;
char buffer[MD_MAX_NONSTRING_CHARS]; /* For non-string types. */
char *temp;
int type;
#include <pthread_np.h> /* for pthread_set_name_np(3) */
#endif
-#include <ltdl.h>
+#include <dlfcn.h>
/*
* Private structures
* object, but it will bitch about a shared object not having a
* ``module_register'' symbol..
*/
-static int plugin_load_file(char *file, uint32_t flags) {
- lt_dlhandle dlh;
+static int plugin_load_file(const char *file, _Bool global) {
void (*reg_handle)(void);
- lt_dlinit();
- lt_dlerror(); /* clear errors */
+ int flags = RTLD_NOW;
+ if (global)
+ flags |= RTLD_GLOBAL;
-#if LIBTOOL_VERSION == 2
- if (flags & PLUGIN_FLAGS_GLOBAL) {
- lt_dladvise advise;
- lt_dladvise_init(&advise);
- lt_dladvise_global(&advise);
- dlh = lt_dlopenadvise(file, advise);
- lt_dladvise_destroy(&advise);
- } else {
- dlh = lt_dlopen(file);
- }
-#else /* if LIBTOOL_VERSION == 1 */
- if (flags & PLUGIN_FLAGS_GLOBAL)
- WARNING("plugin_load_file: The global flag is not supported, "
- "libtool 2 is required for this.");
- dlh = lt_dlopen(file);
-#endif
+ void *dlh = dlopen(file, flags);
if (dlh == NULL) {
char errbuf[1024] = "";
ssnprintf(errbuf, sizeof(errbuf),
- "lt_dlopen (\"%s\") failed: %s. "
+ "dlopen (\"%s\") failed: %s. "
"The most common cause for this problem is "
"missing dependencies. Use ldd(1) to check "
"the dependencies of the plugin "
"/ shared object.",
- file, lt_dlerror());
+ file, dlerror());
ERROR("%s", errbuf);
/* Make sure this is printed to STDERR in any case, but also
return (1);
}
- if ((reg_handle = (void (*)(void))lt_dlsym(dlh, "module_register")) == NULL) {
+ reg_handle = (void (*)(void))dlsym(dlh, "module_register");
+ if (reg_handle == NULL) {
WARNING("Couldn't find symbol \"module_register\" in \"%s\": %s\n", file,
- lt_dlerror());
- lt_dlclose(dlh);
+ dlerror());
+ dlclose(dlh);
return (-1);
}
}
#define BUFSIZE 512
-int plugin_load(char const *plugin_name, uint32_t flags) {
+int plugin_load(char const *plugin_name, _Bool global) {
DIR *dh;
const char *dir;
char filename[BUFSIZE] = "";
*/
if ((strcasecmp("perl", plugin_name) == 0) ||
(strcasecmp("python", plugin_name) == 0))
- flags |= PLUGIN_FLAGS_GLOBAL;
+ global = 1;
/* `cpu' should not match `cpufreq'. To solve this we add `.so' to the
* type when matching the filename */
continue;
}
- status = plugin_load_file(filename, flags);
+ status = plugin_load_file(filename, global);
if (status == 0) {
/* success */
plugin_mark_loaded(plugin_name);
#include <pthread.h>
-#define PLUGIN_FLAGS_GLOBAL 0x0001
-
#ifndef DATA_MAX_NAME_LEN
#define DATA_MAX_NAME_LEN 128
#endif
*
* ARGUMENTS
* `name' Name of the plugin to load.
- * `flags' Hints on how to handle this plugin.
+ * `global' Make this plugins symbols available for other shared libraries.
*
* RETURN VALUE
* Returns zero upon success, a value greater than zero if no plugin was found
* Re-loading an already loaded module is detected and zero is returned in
* this case.
*/
-int plugin_load(const char *name, uint32_t flags);
+int plugin_load(const char *name, _Bool global);
int plugin_init_all(void);
void plugin_read_all(void);
DEF_TEST(metric_name) {
struct {
- char *plugin_instance;
- char *type_instance;
- char *prefix;
- char *suffix;
+ const char *plugin_instance;
+ const char *type_instance;
+ const char *prefix;
+ const char *suffix;
unsigned int flags;
- char *want_name;
+ const char *want_name;
} cases[] = {
{
.want_name = "example@com.test.single",
return 0;
}
+DEF_TEST(null_termination) {
+ value_list_t vl = {
+ .values = &(value_t){.gauge = 1337},
+ .values_len = 1,
+ .time = TIME_T_TO_CDTIME_T_STATIC(1480063672),
+ .interval = TIME_T_TO_CDTIME_T_STATIC(10),
+ .host = "example.com",
+ .plugin = "test",
+ .type = "single",
+ };
+ char const *want = "example_com.test.single 1337 1480063672\r\n";
+
+ char buffer[128];
+ for (size_t i = 0; i < sizeof(buffer); i++)
+ buffer[i] = (char)i;
+
+ EXPECT_EQ_INT(0, format_graphite(buffer, sizeof(buffer), &ds_single, &vl,
+ NULL, NULL, '_', 0));
+ EXPECT_EQ_STR(want, buffer);
+ EXPECT_EQ_INT(0, buffer[strlen(want)]);
+ for (size_t i = strlen(want) + 1; i < sizeof(buffer); i++)
+ EXPECT_EQ_INT((int)i, (int)buffer[i]);
+
+ return 0;
+}
+
int main(void) {
RUN_TEST(metric_name);
+ RUN_TEST(null_termination);
END_TEST;
}