]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
tracing: dynamic tracepoint provider helper
authorJason Dillaman <dillaman@redhat.com>
Wed, 30 Sep 2015 19:13:24 +0000 (15:13 -0400)
committerJason Dillaman <dillaman@redhat.com>
Fri, 20 Nov 2015 16:51:20 +0000 (11:51 -0500)
The TracepointProvider class is a configuration observer.  When
tracing is enabled, it will dynamically load the associated
tracepoint provider.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
(cherry picked from commit b3d02cc21b4cc40a194f84a9bbbf82cf9e7956d1)

Conflicts:
src/common/Makefile.am: trivial resolution

src/common/Makefile.am
src/common/TracepointProvider.cc [new file with mode: 0644]
src/common/TracepointProvider.h [new file with mode: 0644]

index 620e550003591eee840ee79d0e69dfe0b936efae..8fa29899c10f9debc8755950e6dce4c3b71a13da 100644 (file)
@@ -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 (file)
index 0000000..7c3d453
--- /dev/null
@@ -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<std::string> &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 (file)
index 0000000..e54a037
--- /dev/null
@@ -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 <dlfcn.h>
+#include <set>
+#include <string>
+#include <boost/noncopyable.hpp>
+
+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 <const Traits &traits>
+  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 <const Traits &traits>
+  static void initialize(CephContext *cct) {
+#if WITH_LTTNG
+    TypedSingleton<traits> *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 <std::string> &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