From 6159476e4a432c2f8096d4c93048cec71aec1218 Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Mon, 22 Apr 2019 21:13:03 +0800 Subject: [PATCH] denc: rewrite DENC_DUMP_{PRE,POST} using template * for better readability * for better debugging experience * so we can `friend` it in a class in a follow-up change Signed-off-by: Kefu Chai --- src/include/buffer.h | 3 ++ src/include/denc.h | 79 +++++++++++++++++++++------------ src/os/bluestore/bluefs_types.h | 1 - 3 files changed, 53 insertions(+), 30 deletions(-) diff --git a/src/include/buffer.h b/src/include/buffer.h index 9f35de613564e..6e354b04a5637 100644 --- a/src/include/buffer.h +++ b/src/include/buffer.h @@ -77,6 +77,8 @@ template struct sha_digest_t; using sha1_digest_t = sha_digest_t<20>; +template class DencDumper; + namespace ceph { template @@ -808,6 +810,7 @@ inline namespace v14_2_0 { } friend class list; + template friend class ::DencDumper; public: ~contiguous_appender() { diff --git a/src/include/denc.h b/src/include/denc.h index 7d4839224a557..01ac8e1e88aa3 100644 --- a/src/include/denc.h +++ b/src/include/denc.h @@ -77,37 +77,60 @@ inline constexpr bool denc_supported = denc_traits::supported; # include # include # include + # define ENCODE_STR(x) #x # define ENCODE_STRINGIFY(x) ENCODE_STR(x) -# define DENC_DUMP_PRE(Type) \ - char *__denc_dump_pre = p.get_pos(); - // this hackery with bits below is just to get a semi-reasonable - // distribution across time. it is somewhat exponential but not - // quite. -# define DENC_DUMP_POST(Type) \ - do { \ - static int i = 0; \ - i++; \ - int bits = 0; \ - for (unsigned t = i; t; bits++) \ - t &= t - 1; \ - if (bits > 2) \ - break; \ - char fn[PATH_MAX]; \ - ::snprintf(fn, sizeof(fn), \ - ENCODE_STRINGIFY(ENCODE_DUMP_PATH) "/%s__%d.%x", #Type, \ - getpid(), i++); \ - int fd = ::open(fn, O_WRONLY|O_TRUNC|O_CREAT|O_CLOEXEC, 0644); \ - if (fd >= 0) { \ - size_t len = p.get_pos() - __denc_dump_pre; \ - int r = ::write(fd, __denc_dump_pre, len); \ - (void)r; \ - ::close(fd); \ - } \ - } while (0) + +template +class DencDumper { +public: + DencDumper(const char* name, + ceph::bufferlist::contiguous_appender& appender) + : name{name}, + appender{appender}, + start{appender.get_pos()} + {} + ~DencDumper() { + if (do_sample()) { + dump(); + } + } +private: + static bool do_sample() { + // this hackery with bits below is just to get a semi-reasonable + // distribution across time. it is somewhat exponential but not + // quite. + i++; + int bits = 0; + for (unsigned t = i; t; bits++) + t &= t - 1; + return bits <= 2; + } + void dump() { + char fn[PATH_MAX]; + ::snprintf(fn, sizeof(fn), + ENCODE_STRINGIFY(ENCODE_DUMP_PATH) "/%s__%d.%x", name, + getpid(), i++); + int fd = ::open(fn, O_WRONLY|O_TRUNC|O_CREAT|O_CLOEXEC, 0644); + if (fd < 0) { + return; + } + size_t len = appender.get_pos() - start; + [[maybe_unused]] int r = ::write(fd, start, len); + ::close(fd); + } + const char* name; + ceph::bufferlist::contiguous_appender& appender; + const char* start; + static int i; +}; + +template int DencDumper::i = 0; + +# define DENC_DUMP_PRE(Type) \ + DencDumper _denc_dumper{#Type, p}; #else # define DENC_DUMP_PRE(Type) -# define DENC_DUMP_POST(Type) #endif @@ -1700,7 +1723,6 @@ inline std::enable_if_t decode_nohead( void encode(::ceph::buffer::list::contiguous_appender& p) const { \ DENC_DUMP_PRE(Type); \ _denc_friend(*this, p); \ - DENC_DUMP_POST(Type); \ } \ void decode(::ceph::buffer::ptr::const_iterator& p) { \ _denc_friend(*this, p); \ @@ -1718,7 +1740,6 @@ inline std::enable_if_t decode_nohead( void encode(::ceph::buffer::list::contiguous_appender& p, uint64_t f) const { \ DENC_DUMP_PRE(Type); \ _denc_friend(*this, p, f); \ - DENC_DUMP_POST(Type); \ } \ void decode(::ceph::buffer::ptr::const_iterator& p, uint64_t f=0) { \ _denc_friend(*this, p, f); \ diff --git a/src/os/bluestore/bluefs_types.h b/src/os/bluestore/bluefs_types.h index aad4ade443cab..43246f6419544 100644 --- a/src/os/bluestore/bluefs_types.h +++ b/src/os/bluestore/bluefs_types.h @@ -61,7 +61,6 @@ struct bluefs_fnode_t { void encode(bufferlist::contiguous_appender& p) const { DENC_DUMP_PRE(bluefs_fnode_t); _denc_friend(*this, p); - DENC_DUMP_POST(bluefs_fnode_t); } void decode(buffer::ptr::const_iterator& p) { _denc_friend(*this, p); -- 2.39.5