From: Ruben Kerkhof Date: Fri, 2 Dec 2016 13:01:27 +0000 (+0100) Subject: Merge branch 'collectd-5.7' X-Git-Tag: collectd-5.8.0~295 X-Git-Url: https://git.octo.it/?p=collectd.git;a=commitdiff_plain;h=2e79fb47c10ffd9efc9532c68fc18a1ad8eaaf61;hp=d5569bf266133d0bef3a1d3f805d72713ceb84cf Merge branch 'collectd-5.7' --- diff --git a/.gitignore b/.gitignore index 8154d733..6927e511 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ Makefile.in /aclocal.m4 /autom4te.cache /autom4te.cache +/build-aux/ /compile /config.guess /config.sub @@ -12,8 +13,15 @@ Makefile.in /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 diff --git a/Makefile.am b/Makefile.am index 03bdd39a..83b0d647 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,14 +1,6 @@ -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 @@ -18,6 +10,5 @@ install-exec-hook: $(mkinstalldirs) $(DESTDIR)$(localstatedir)/log maintainer-clean-local: - -rm -f -r libltdl -rm -f INSTALL -rm -f aclocal.m4 diff --git a/README b/README index 0989312f..7754d87c 100644 --- a/README +++ b/README @@ -973,7 +973,6 @@ To generate the `configure` script, you'll need the following dependencies: - flex - bison - libtool -- libtool-ltdl - pkg-config The `build.sh' script takes no arguments. diff --git a/build.sh b/build.sh index 57f3d444..465eff9d 100755 --- a/build.sh +++ b/build.sh @@ -54,6 +54,6 @@ set -x autoheader \ && aclocal \ -&& $libtoolize --ltdl --copy --force \ +&& $libtoolize --copy --force \ && automake --add-missing --copy \ && autoconf diff --git a/clean.sh b/clean.sh index 6780cdab..ac3c3105 100755 --- a/clean.sh +++ b/clean.sh @@ -15,7 +15,6 @@ true \ && rm -f configure \ && rm -f depcomp \ && rm -f install-sh \ -&& rm -f -r libltdl \ && rm -f libtool \ && rm -f ltmain.sh \ && rm -f Makefile \ diff --git a/configure.ac b/configure.ac index 7f0dd5ca..c66ff7d5 100644 --- a/configure.ac +++ b/configure.ac @@ -3,34 +3,15 @@ AC_PREREQ([2.60]) 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])]) @@ -56,7 +37,6 @@ AM_PROG_CC_C_O AM_CONDITIONAL(COMPILER_IS_GCC, test "x$GCC" = "xyes") AC_DISABLE_STATIC -AC_PROG_LIBTOOL AC_PROG_LEX AC_PROG_YACC @@ -79,6 +59,12 @@ then 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" diff --git a/contrib/README b/contrib/README index 5f401f09..6e2ea19e 100644 --- a/contrib/README +++ b/contrib/README @@ -49,6 +49,21 @@ should look something like this: 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) diff --git a/contrib/docker/50docker-apt-conf b/contrib/docker/50docker-apt-conf new file mode 100644 index 00000000..3f898b3b --- /dev/null +++ b/contrib/docker/50docker-apt-conf @@ -0,0 +1,4 @@ +APT::Install-Recommends "0"; +APT::Install-Suggests "0"; +APT::Get::Assume-Yes "1"; +APT::Get::AutomaticRemove "1"; diff --git a/contrib/docker/Dockerfile b/contrib/docker/Dockerfile new file mode 100644 index 00000000..a691f2e6 --- /dev/null +++ b/contrib/docker/Dockerfile @@ -0,0 +1,24 @@ +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"] diff --git a/contrib/docker/collectd.conf b/contrib/docker/collectd.conf new file mode 100644 index 00000000..bbcd0791 --- /dev/null +++ b/contrib/docker/collectd.conf @@ -0,0 +1,16 @@ +LoadPlugin logfile + + LogLevel "info" + File STDOUT + Timestamp true + PrintSeverity true + + +LoadPlugin unixsock + + SocketGroup "nogroup" + + + + Filter "*.conf" + diff --git a/contrib/docker/collectd.conf.d/sample.conf b/contrib/docker/collectd.conf.d/sample.conf new file mode 100644 index 00000000..cbd7ce15 --- /dev/null +++ b/contrib/docker/collectd.conf.d/sample.conf @@ -0,0 +1,4 @@ +LoadPlugin cpu +LoadPlugin memory +LoadPlugin disk +LoadPlugin df diff --git a/contrib/docker/rootfs_prefix/Makefile b/contrib/docker/rootfs_prefix/Makefile new file mode 100644 index 00000000..f26bebd0 --- /dev/null +++ b/contrib/docker/rootfs_prefix/Makefile @@ -0,0 +1,2 @@ +rootfs_prefix.so: rootfs_prefix.c + $(CC) -Wall -Werror -fPIC -shared -o rootfs_prefix.so rootfs_prefix.c -ldl diff --git a/contrib/docker/rootfs_prefix/rootfs_prefix.c b/contrib/docker/rootfs_prefix/rootfs_prefix.c new file mode 100644 index 00000000..c27a67af --- /dev/null +++ b/contrib/docker/rootfs_prefix/rootfs_prefix.c @@ -0,0 +1,64 @@ +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include + +#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); +} diff --git a/contrib/redhat/collectd.spec b/contrib/redhat/collectd.spec index 4fc76e11..09cc3b18 100644 --- a/contrib/redhat/collectd.spec +++ b/contrib/redhat/collectd.spec @@ -242,7 +242,7 @@ Source: https://collectd.org/files/%{name}-%{version}.tar.bz2 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 %if 0%{?fedora} || 0%{?rhel} >= 7 @@ -1767,7 +1767,6 @@ Collectd utilities %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 \ diff --git a/src/daemon/Makefile.am b/src/daemon/Makefile.am index 52079438..74af5196 100644 --- a/src/daemon/Makefile.am +++ b/src/daemon/Makefile.am @@ -67,10 +67,9 @@ collectd_SOURCES = collectd.c collectd.h \ 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, @@ -81,7 +80,7 @@ collectd_LDADD += $(BUILD_WITH_LIBSTATGRAB_LDFLAGS) 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 diff --git a/src/daemon/configfile.c b/src/daemon/configfile.c index d5f01e07..b57aadc8 100644 --- a/src/daemon/configfile.c +++ b/src/daemon/configfile.c @@ -245,7 +245,7 @@ static int dispatch_value_plugindir(oconfig_item_t *ci) { 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; @@ -270,7 +270,7 @@ static int dispatch_loadplugin(oconfig_item_t *ci) { 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) @@ -285,7 +285,7 @@ static int dispatch_loadplugin(oconfig_item_t *ci) { } 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); diff --git a/src/daemon/plugin.c b/src/daemon/plugin.c index f313f368..c89f1ed1 100644 --- a/src/daemon/plugin.c +++ b/src/daemon/plugin.c @@ -46,7 +46,7 @@ #include /* for pthread_set_name_np(3) */ #endif -#include +#include /* * Private structures @@ -389,40 +389,25 @@ static int plugin_unregister(llist_t *list, const char *name) /* {{{ */ * 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 @@ -433,10 +418,11 @@ static int plugin_load_file(char *file, uint32_t flags) { 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); } @@ -973,7 +959,7 @@ static void plugin_free_loaded(void) { } #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] = ""; @@ -1007,7 +993,7 @@ int plugin_load(char const *plugin_name, uint32_t flags) { */ 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 */ @@ -1045,7 +1031,7 @@ int plugin_load(char const *plugin_name, uint32_t flags) { continue; } - status = plugin_load_file(filename, flags); + status = plugin_load_file(filename, global); if (status == 0) { /* success */ plugin_mark_loaded(plugin_name); diff --git a/src/daemon/plugin.h b/src/daemon/plugin.h index f6448a58..4f877e0e 100644 --- a/src/daemon/plugin.h +++ b/src/daemon/plugin.h @@ -36,8 +36,6 @@ #include -#define PLUGIN_FLAGS_GLOBAL 0x0001 - #ifndef DATA_MAX_NAME_LEN #define DATA_MAX_NAME_LEN 128 #endif @@ -226,7 +224,7 @@ void plugin_set_dir(const char *dir); * * 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 @@ -236,7 +234,7 @@ void plugin_set_dir(const char *dir); * 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); diff --git a/src/utils_format_graphite_test.c b/src/utils_format_graphite_test.c index 415a283e..a395683a 100644 --- a/src/utils_format_graphite_test.c +++ b/src/utils_format_graphite_test.c @@ -157,8 +157,35 @@ DEF_TEST(metric_name) { 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; }