From ca50bc68ad624046a796ccd3635a38f8e341fb9d Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 15 Jun 2018 14:39:18 -0500 Subject: [PATCH 01/23] debian,rpm: /var/lib/ceph/crash Signed-off-by: Sage Weil (cherry picked from commit e37e6407b9cbac8561e4f79cb9284820b2c508ff) --- ceph.spec.in | 1 + debian/ceph-base.dirs | 1 + 2 files changed, 2 insertions(+) diff --git a/ceph.spec.in b/ceph.spec.in index 19092061a8896..4bd38de91f77b 100644 --- a/ceph.spec.in +++ b/ceph.spec.in @@ -1000,6 +1000,7 @@ mkdir -p %{buildroot}%{_localstatedir}/lib/ceph/bootstrap-mds mkdir -p %{buildroot}%{_localstatedir}/lib/ceph/bootstrap-rgw mkdir -p %{buildroot}%{_localstatedir}/lib/ceph/bootstrap-mgr mkdir -p %{buildroot}%{_localstatedir}/lib/ceph/bootstrap-rbd +mkdir -p %{buildroot}%{_localstatedir}/lib/ceph/crash %if 0%{?suse_version} # create __pycache__ directories and their contents diff --git a/debian/ceph-base.dirs b/debian/ceph-base.dirs index 2ae6860022e03..262e6f6a508e2 100644 --- a/debian/ceph-base.dirs +++ b/debian/ceph-base.dirs @@ -4,3 +4,4 @@ var/lib/ceph/bootstrap-osd var/lib/ceph/bootstrap-rgw var/lib/ceph/bootstrap-rbd var/lib/ceph/tmp +var/lib/ceph/crash From 613eaaa7a2f86cfd6634a2ff6623a6de55d642a2 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 15 Jun 2018 15:57:40 -0500 Subject: [PATCH 02/23] log: do not discard recent after dumping it We want to call dump_recent multiple times without discarding those log events. Just iterate the list; don't discard it! Signed-off-by: Sage Weil (cherry picked from commit 76802af0f8ee2d1a4d9b8b4fee23b9fdfbdf1304) --- src/log/Log.cc | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/src/log/Log.cc b/src/log/Log.cc index 9240751dd1228..018060711fe70 100644 --- a/src/log/Log.cc +++ b/src/log/Log.cc @@ -298,8 +298,31 @@ void Log::flush() void Log::_flush(EntryQueue *t, EntryQueue *requeue, bool crash) { - Entry *e; - while ((e = t->dequeue()) != NULL) { + Entry *e = nullptr; + long len = 0; + if (crash) { + len = t->m_len; + } + if (!requeue) { + e = t->m_head; + if (!e) { + return; + } + } + while (true) { + if (requeue) { + e = t->dequeue(); + if (!e) { + break; + } + requeue->enqueue(e); + } else { + e = e->m_next; + if (!e) { + break; + } + } + unsigned sub = e->m_subsys; bool should_log = crash || m_subs->get_log_level(sub) >= e->m_prio; @@ -323,8 +346,9 @@ void Log::_flush(EntryQueue *t, EntryQueue *requeue, bool crash) buf = buf0; } - if (crash) + if (crash) { buflen += snprintf(buf, buf_size, "%6d> ", -t->m_len); + } buflen += append_time(e->m_stamp, buf + buflen, buf_size - buflen); buflen += snprintf(buf + buflen, buf_size-buflen, " %lx %2d ", (unsigned long)e->m_thread, e->m_prio); @@ -361,7 +385,6 @@ void Log::_flush(EntryQueue *t, EntryQueue *requeue, bool crash) m_graylog->log_entry(e); } - requeue->enqueue(e); } } @@ -401,9 +424,8 @@ void Log::dump_recent() pthread_mutex_unlock(&m_queue_mutex); _flush(&t, &m_recent, false); - EntryQueue old; _log_message("--- begin dump of recent events ---", true); - _flush(&m_recent, &old, true); + _flush(&m_recent, nullptr, true); char buf[4096]; _log_message("--- logging levels ---", true); From 8b3562ad65ff645f5bf0c3aa6376ce025559e054 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 15 Jun 2018 17:54:55 -0500 Subject: [PATCH 03/23] common/BackTrace: add dump() Signed-off-by: Sage Weil (cherry picked from commit 4998b5b584ac57d67ca5ba28d3ec3a3e4fe4486f) --- src/common/BackTrace.cc | 66 +++++++++++++++++++++++++++++++++++++++++ src/common/BackTrace.h | 6 ++++ 2 files changed, 72 insertions(+) diff --git a/src/common/BackTrace.cc b/src/common/BackTrace.cc index c179d1dac1252..90b83df356c1c 100644 --- a/src/common/BackTrace.cc +++ b/src/common/BackTrace.cc @@ -1,9 +1,13 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + #include #include #include #include "BackTrace.h" #include "common/version.h" +#include "common/Formatter.h" #define _STR(x) #x #define STRINGIFY(x) _STR(x) @@ -70,4 +74,66 @@ void BackTrace::print(std::ostream& out) const } } +void BackTrace::dump(Formatter *f) const +{ + f->open_array_section("backtrace"); + for (size_t i = skip; i < size; i++) { + // out << " " << (i-skip+1) << ": " << strings[i] << std::endl; + + size_t sz = 1024; // just a guess, template names will go much wider + char *function = (char *)malloc(sz); + if (!function) + return; + char *begin = 0, *end = 0; + + // find the parentheses and address offset surrounding the mangled name +#ifdef __FreeBSD__ + static constexpr char OPEN = '<'; +#else + static constexpr char OPEN = '('; +#endif + for (char *j = strings[i]; *j; ++j) { + if (*j == OPEN) + begin = j+1; + else if (*j == '+') + end = j; + } + if (begin && end) { + int len = end - begin; + char *foo = (char *)malloc(len+1); + if (!foo) { + free(function); + return; + } + memcpy(foo, begin, len); + foo[len] = 0; + + int status; + char *ret = nullptr; + // only demangle a C++ mangled name + if (foo[0] == '_' && foo[1] == 'Z') + ret = abi::__cxa_demangle(foo, function, &sz, &status); + if (ret) { + // return value may be a realloc() of the input + function = ret; + } + else { + // demangling failed, just pretend it's a C function with no args + strncpy(function, foo, sz); + strncat(function, "()", sz); + function[sz-1] = 0; + } + f->dump_stream("frame") << OPEN << function << end; + //fprintf(out, " %s:%s\n", stack.strings[i], function); + free(foo); + } else { + // didn't find the mangled name, just print the whole line + //out << " " << (i-skip+1) << ": " << strings[i] << std::endl; + f->dump_string("frame", strings[i]); + } + free(function); + } + f->close_section(); +} + } diff --git a/src/common/BackTrace.h b/src/common/BackTrace.h index 372788e6b64e6..5cb73d47bd6c4 100644 --- a/src/common/BackTrace.h +++ b/src/common/BackTrace.h @@ -1,3 +1,6 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + #ifndef CEPH_BACKTRACE_H #define CEPH_BACKTRACE_H @@ -10,6 +13,8 @@ namespace ceph { +class Formatter; + struct BackTrace { const static int max = 100; @@ -36,6 +41,7 @@ struct BackTrace { const BackTrace& operator=(const BackTrace& other); void print(std::ostream& out) const; + void dump(Formatter *f) const; }; inline std::ostream& operator<<(std::ostream& out, const BackTrace& bt) { From 583f5920ea840269101a896455ae047de2a4c591 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 15 Jun 2018 14:40:10 -0500 Subject: [PATCH 04/23] common: add crash_dir option Signed-off-by: Sage Weil (cherry picked from commit 72139f0d23a9173448298c60fd3d3f1c48a97eeb) --- src/common/legacy_config_opts.h | 1 + src/common/options.cc | 4 ++++ src/vstart.sh | 1 + 3 files changed, 6 insertions(+) diff --git a/src/common/legacy_config_opts.h b/src/common/legacy_config_opts.h index 82e81d24a977c..f375e210ce90f 100644 --- a/src/common/legacy_config_opts.h +++ b/src/common/legacy_config_opts.h @@ -34,6 +34,7 @@ OPTION(chdir, OPT_STR) OPTION(restapi_log_level, OPT_STR) // default set by Python code OPTION(restapi_base_url, OPT_STR) // " OPTION(fatal_signal_handlers, OPT_BOOL) +OPTION(crash_dir, OPT_STR) SAFE_OPTION(erasure_code_dir, OPT_STR) // default location for erasure-code plugins OPTION(log_file, OPT_STR) // default changed by common_preinit() diff --git a/src/common/options.cc b/src/common/options.cc index 878f84b71f51a..9e567b6f438a2 100644 --- a/src/common/options.cc +++ b/src/common/options.cc @@ -537,6 +537,10 @@ std::vector