From d02beff1cf7650fe6e57cdafe64dcbee2631ed52 Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Wed, 30 Sep 2015 15:13:24 -0400 Subject: [PATCH] tracing: dynamic tracepoint provider helper The TracepointProvider class is a configuration observer. When tracing is enabled, it will dynamically load the associated tracepoint provider. Signed-off-by: Jason Dillaman (cherry picked from commit b3d02cc21b4cc40a194f84a9bbbf82cf9e7956d1) Conflicts: src/common/Makefile.am: trivial resolution --- src/common/Makefile.am | 6 ++- src/common/TracepointProvider.cc | 44 +++++++++++++++++ src/common/TracepointProvider.h | 83 ++++++++++++++++++++++++++++++++ 3 files changed, 131 insertions(+), 2 deletions(-) create mode 100644 src/common/TracepointProvider.cc create mode 100644 src/common/TracepointProvider.h diff --git a/src/common/Makefile.am b/src/common/Makefile.am index 620e550003591..8fa29899c10f9 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -73,7 +73,8 @@ libcommon_internal_la_SOURCES = \ common/module.c \ common/Readahead.cc \ common/Cycles.cc \ - common/ContextCompletion.cc + common/ContextCompletion.cc \ + common/TracepointProvider.cc if WITH_RBD libcommon_internal_la_SOURCES += \ @@ -234,7 +235,8 @@ noinst_HEADERS += \ common/Initialize.h \ common/ContextCompletion.h \ common/bit_vector.hpp \ - common/valgrind.h + common/valgrind.h \ + common/TracepointProvider.h if ENABLE_XIO noinst_HEADERS += \ diff --git a/src/common/TracepointProvider.cc b/src/common/TracepointProvider.cc new file mode 100644 index 0000000000000..7c3d453cdc329 --- /dev/null +++ b/src/common/TracepointProvider.cc @@ -0,0 +1,44 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#include "common/TracepointProvider.h" +#include "common/config.h" + +TracepointProvider::TracepointProvider(CephContext *cct, const char *library, + const char *config_key) + : m_cct(cct), m_library(library), m_config_keys{config_key, NULL}, + m_lock("TracepointProvider::m_lock"), m_enabled(false) { + m_cct->_conf->add_observer(this); + verify_config(m_cct->_conf); +} + +TracepointProvider::~TracepointProvider() { + m_cct->_conf->remove_observer(this); +} + +void TracepointProvider::handle_conf_change( + const struct md_config_t *conf, const std::set &changed) { + if (changed.count(m_config_keys[0])) { + verify_config(conf); + } +} + +void TracepointProvider::verify_config(const struct md_config_t *conf) { + Mutex::Locker locker(m_lock); + if (m_enabled) { + return; + } + + char buf[10]; + char *pbuf = buf; + if (conf->get_val(m_config_keys[0], &pbuf, sizeof(buf)) != 0 || + strncmp(buf, "true", 5) != 0) { + return; + } + + void *handle = dlopen(m_library.c_str(), RTLD_NOW); + if (handle != NULL) { + m_enabled = true; + } +} + diff --git a/src/common/TracepointProvider.h b/src/common/TracepointProvider.h new file mode 100644 index 0000000000000..e54a037f90ecd --- /dev/null +++ b/src/common/TracepointProvider.h @@ -0,0 +1,83 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_TRACEPOINT_PROVIDER_H +#define CEPH_TRACEPOINT_PROVIDER_H + +#include "include/int_types.h" +#include "common/ceph_context.h" +#include "common/config_obs.h" +#include "common/Mutex.h" +#include +#include +#include +#include + +struct md_config_t; + +class TracepointProvider : public md_config_obs_t, boost::noncopyable { +public: + struct Traits { + const char *library; + const char *config_key; + + Traits(const char *library, const char *config_key) + : library(library), config_key(config_key) { + } + }; + + class Singleton { + public: + Singleton(CephContext *cct, const char *library, const char *config_key) + : tracepoint_provider(new TracepointProvider(cct, library, config_key)) { + } + ~Singleton() { + delete tracepoint_provider; + } + + inline bool is_enabled() const { + return tracepoint_provider->m_enabled; + } + private: + TracepointProvider *tracepoint_provider; + }; + + template + class TypedSingleton : public Singleton { + public: + TypedSingleton(CephContext *cct) + : Singleton(cct, traits.library, traits.config_key) { + } + }; + + TracepointProvider(CephContext *cct, const char *library, + const char *config_key); + virtual ~TracepointProvider(); + + template + static void initialize(CephContext *cct) { +#if WITH_LTTNG + TypedSingleton *singleton; + cct->lookup_or_create_singleton_object(singleton, traits.library); +#endif + } + +protected: + virtual const char** get_tracked_conf_keys() const { + return m_config_keys; + } + virtual void handle_conf_change(const struct md_config_t *conf, + const std::set &changed); + +private: + CephContext *m_cct; + std::string m_library; + mutable const char* m_config_keys[2]; + + Mutex m_lock; + bool m_enabled; + + void verify_config(const struct md_config_t *conf); +}; + +#endif // CEPH_TRACEPOINT_PROVIDER_H -- 2.39.5