mirror of
https://github.com/ceph/ceph
synced 2025-04-01 00:26:47 +00:00
Merge pull request #27704 from tchaikov/wip-denc-dump
denc: allow DencDumper to dump OOB buffer Reviewed-by: Radoslaw Zarzynski <rzarzyns@redhat.com> Reviewed-by: Sage Weil <sage@redhat.com>
This commit is contained in:
commit
b4040f09dd
@ -968,7 +968,7 @@ public:
|
||||
|
||||
int validate_weightf(float weight) {
|
||||
uint64_t iweight = weight * 0x10000;
|
||||
if (iweight > std::numeric_limits<int>::max()) {
|
||||
if (iweight > static_cast<uint64_t>(std::numeric_limits<int>::max())) {
|
||||
return -EOVERFLOW;
|
||||
}
|
||||
return 0;
|
||||
|
@ -77,6 +77,8 @@ template<uint8_t S>
|
||||
struct sha_digest_t;
|
||||
using sha1_digest_t = sha_digest_t<20>;
|
||||
|
||||
template<typename T> class DencDumper;
|
||||
|
||||
namespace ceph {
|
||||
|
||||
template <class T>
|
||||
@ -808,6 +810,7 @@ inline namespace v14_2_0 {
|
||||
}
|
||||
|
||||
friend class list;
|
||||
template<typename Type> friend class ::DencDumper;
|
||||
|
||||
public:
|
||||
~contiguous_appender() {
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include "include/ceph_assert.h" // boost clobbers this
|
||||
#include "include/intarith.h"
|
||||
#include "include/int_types.h"
|
||||
#include "include/scope_guard.h"
|
||||
|
||||
#include "buffer.h"
|
||||
#include "byteorder.h"
|
||||
@ -77,37 +78,75 @@ inline constexpr bool denc_supported = denc_traits<T>::supported;
|
||||
# include <sys/types.h>
|
||||
# include <sys/stat.h>
|
||||
# include <fcntl.h>
|
||||
|
||||
# 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<typename T>
|
||||
class DencDumper {
|
||||
public:
|
||||
DencDumper(const char* name,
|
||||
ceph::bufferlist::contiguous_appender& appender)
|
||||
: name{name},
|
||||
appender{appender},
|
||||
bl_offset{appender.bl.length()},
|
||||
space_offset{space_size()},
|
||||
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;
|
||||
}
|
||||
size_t space_size() {
|
||||
return appender.get_logical_offset() - appender.get_out_of_band_offset();
|
||||
}
|
||||
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;
|
||||
}
|
||||
auto close_fd = make_scope_guard([fd] { ::close(fd); });
|
||||
if (auto bl_delta = appender.bl.length() - bl_offset; bl_delta > 0) {
|
||||
ceph::bufferlist dump_bl;
|
||||
appender.bl.copy(bl_offset + space_offset, bl_delta - space_offset, dump_bl);
|
||||
const size_t space_len = space_size();
|
||||
dump_bl.append(appender.get_pos() - space_len, space_len);
|
||||
dump_bl.write_fd(fd);
|
||||
} else {
|
||||
size_t len = appender.get_pos() - start;
|
||||
[[maybe_unused]] int r = ::write(fd, start, len);
|
||||
}
|
||||
}
|
||||
const char* name;
|
||||
ceph::bufferlist::contiguous_appender& appender;
|
||||
const size_t bl_offset;
|
||||
const size_t space_offset;
|
||||
const char* start;
|
||||
static int i;
|
||||
};
|
||||
|
||||
template<typename T> int DencDumper<T>::i = 0;
|
||||
|
||||
# define DENC_DUMP_PRE(Type) \
|
||||
DencDumper<Type> _denc_dumper{#Type, p};
|
||||
#else
|
||||
# define DENC_DUMP_PRE(Type)
|
||||
# define DENC_DUMP_POST(Type)
|
||||
#endif
|
||||
|
||||
|
||||
@ -1700,7 +1739,6 @@ inline std::enable_if_t<traits::supported && !traits::featured> 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 +1756,6 @@ inline std::enable_if_t<traits::supported && !traits::featured> 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); \
|
||||
|
@ -863,7 +863,8 @@ CtPtr ProtocolV1::handle_message_data(char *buffer, int r) {
|
||||
|
||||
bufferptr bp = data_blp.get_current_ptr();
|
||||
unsigned read_len = std::min(bp.length(), msg_left);
|
||||
ceph_assert(read_len < std::numeric_limits<int>::max());
|
||||
ceph_assert(read_len <
|
||||
static_cast<unsigned>(std::numeric_limits<int>::max()));
|
||||
data_blp.advance(read_len);
|
||||
data.append(bp, 0, read_len);
|
||||
msg_left -= read_len;
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user