Skip to content

Commit da6ce70

Browse files
authored
Merge pull request ceph#56499 from adamemerson/wip-rgw-close-datalog-write-hole
rgw: Close datalog write hole Reviewed-by: Casey Bodley <[email protected]>
2 parents 1f05dee + 9203771 commit da6ce70

File tree

99 files changed

+11688
-6218
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

99 files changed

+11688
-6218
lines changed

qa/suites/rgw/verify/tasks/cls.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ tasks:
1616
- cls/test_cls_cmpomap.sh
1717
- cls/test_cls_2pc_queue.sh
1818
- cls/test_cls_user.sh
19+
- cls/test_cls_sem_set.sh
1920
- rgw/test_rgw_gc_log.sh
2021
- rgw/test_rgw_obj.sh
22+
- rgw/test_rgw_datalog.sh
2123
- rgw/test_librgw_file.sh
2224
- rgw/test_awssdkv4_sig.sh

qa/valgrind.supp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1123,3 +1123,19 @@
11231123
obj:/usr/lib64/libicuuc.so.67.1
11241124
...
11251125
}
1126+
{
1127+
rgw unclean shutdown one-time leak
1128+
Memcheck:Leak
1129+
match-leak-kinds: definite
1130+
fun:_Znam
1131+
fun:_ZN8Objecter15linger_registerERK8object_tRK16object_locator_ti
1132+
fun:_ZN8neorados5RADOS6watch_ENS_6ObjectENS_9IOContextESt8optionalINSt6chrono8durationIlSt5ratioILl1ELl1EEEEEN3fu27abi_3106detail8functionINSC_6configILb1ELb0ELm16EEENSC_8propertyILb1ELb0EJFvN5boost6system10error_codeEmmmON4ceph6buffer7v15_2_04listEEEEEEENSH_4asio22any_completion_handlerIJFvSJ_mEEEE
1133+
fun:_ZZZN5boost4asio6detail20awaitable_frame_baseINS0_15any_io_executorEE15await_transformIZNS0_12async_resultINS0_15use_awaitable_tIS3_EEJFvNS_6system10error_codeEmEEE8initiateINS6_INS0_9consign_tIS8_JNS0_19executor_work_guardINS0_10io_context19basic_executor_typeISaIvELm0EEEvvEEEEEJSB_EE12init_wrapperIZN8neorados5RADOS5watchIRKS8_EEDaNSO_6ObjectENSO_9IOContextESt8optionalINSt6chrono8durationIlSt5ratioILl1ELl1EEEEEN3fu27abi_3106detail8functionINS14_6configILb1ELb0ELm16EEENS14_8propertyILb1ELb0EJFvSA_mmmON4ceph6buffer7v15_2_04listEEEEEEEOT_EUlS1I_ST_SU_S1G_E_EEJSt5tupleIJSK_EEST_SU_S1G_EEENS0_9awaitableImS3_EES1H_S8_DpT0_EUlPS1H_E_EEDaS1H_PNSt9enable_ifIXsrSt14is_convertibleINS0_9result_ofIFS1H_PS4_EE4typeEPNS1_16awaitable_threadIS3_EEE5valueEvE4typeEEN6result13await_suspendENSt7__n486116coroutine_handleIvEEENUlPvE_4_FUNES2B_
1134+
...
1135+
}
1136+
{
1137+
co_compose bug manifesting under Ubuntu only
1138+
Memcheck:Free
1139+
fun:_ZdaPvm
1140+
...
1141+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/bin/sh -e
2+
3+
ceph_test_cls_sem_set
4+
5+
exit 0
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/bin/sh -e
2+
3+
ceph_test_datalog
4+
5+
exit 0

src/cls/CMakeLists.txt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,4 +358,12 @@ set_target_properties(cls_fifo PROPERTIES
358358
target_link_libraries(cls_fifo ${FMT_LIB})
359359
install(TARGETS cls_fifo DESTINATION ${cls_dir})
360360

361-
361+
# cls_sem_set
362+
set(cls_sem_set_srcs sem_set/module.cc)
363+
add_library(cls_sem_set SHARED ${cls_sem_set_srcs})
364+
set_target_properties(cls_sem_set PROPERTIES
365+
VERSION "1.0.0"
366+
SOVERSION "1"
367+
INSTALL_RPATH ""
368+
CXX_VISIBILITY_PRESET hidden)
369+
install(TARGETS cls_sem_set DESTINATION ${cls_dir})

src/cls/log/cls_log.cc

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
// vim: ts=8 sw=2 smarttab
33

44
#include "include/types.h"
5-
#include "include/utime.h"
5+
6+
#include "common/ceph_time.h"
7+
68
#include "objclass/objclass.h"
79

810
#include "cls_log_types.h"
@@ -15,14 +17,15 @@ using std::map;
1517
using std::string;
1618

1719
using ceph::bufferlist;
20+
using namespace std::literals;
1821

1922
CLS_VER(1,0)
2023
CLS_NAME(log)
2124

2225
static string log_index_prefix = "1_";
2326

2427

25-
static int write_log_entry(cls_method_context_t hctx, string& index, cls_log_entry& entry)
28+
static int write_log_entry(cls_method_context_t hctx, string& index, cls::log::entry& entry)
2629
{
2730
bufferlist bl;
2831
encode(entry, bl);
@@ -34,15 +37,16 @@ static int write_log_entry(cls_method_context_t hctx, string& index, cls_log_ent
3437
return 0;
3538
}
3639

37-
static void get_index_time_prefix(utime_t& ts, string& index)
40+
static void get_index_time_prefix(ceph::real_time ts, string& index)
3841
{
42+
auto tv = ceph::real_clock::to_timeval(ts);
3943
char buf[32];
40-
snprintf(buf, sizeof(buf), "%010ld.%06ld_", (long)ts.sec(), (long)ts.usec());
44+
snprintf(buf, sizeof(buf), "%010ld.%06ld_", (long)tv.tv_sec, (long)tv.tv_usec);
4145

4246
index = log_index_prefix + buf;
4347
}
4448

45-
static int read_header(cls_method_context_t hctx, cls_log_header& header)
49+
static int read_header(cls_method_context_t hctx, cls::log::header& header)
4650
{
4751
bufferlist header_bl;
4852

@@ -51,7 +55,7 @@ static int read_header(cls_method_context_t hctx, cls_log_header& header)
5155
return ret;
5256

5357
if (header_bl.length() == 0) {
54-
header = cls_log_header();
58+
header = cls::log::header();
5559
return 0;
5660
}
5761

@@ -65,7 +69,7 @@ static int read_header(cls_method_context_t hctx, cls_log_header& header)
6569
return 0;
6670
}
6771

68-
static int write_header(cls_method_context_t hctx, cls_log_header& header)
72+
static int write_header(cls_method_context_t hctx, cls::log::header& header)
6973
{
7074
bufferlist header_bl;
7175
encode(header, header_bl);
@@ -77,7 +81,7 @@ static int write_header(cls_method_context_t hctx, cls_log_header& header)
7781
return 0;
7882
}
7983

80-
static void get_index(cls_method_context_t hctx, utime_t& ts, string& index)
84+
static void get_index(cls_method_context_t hctx, ceph::real_time ts, string& index)
8185
{
8286
get_index_time_prefix(ts, index);
8387

@@ -92,26 +96,26 @@ static int cls_log_add(cls_method_context_t hctx, bufferlist *in, bufferlist *ou
9296
{
9397
auto in_iter = in->cbegin();
9498

95-
cls_log_add_op op;
99+
cls::log::ops::add_op op;
96100
try {
97101
decode(op, in_iter);
98102
} catch (ceph::buffer::error& err) {
99-
CLS_LOG(1, "ERROR: cls_log_add_op(): failed to decode op");
103+
CLS_LOG(1, "ERROR: cls::log::ops::add_op(): failed to decode op");
100104
return -EINVAL;
101105
}
102106

103-
cls_log_header header;
107+
cls::log::header header;
104108

105109
int ret = read_header(hctx, header);
106110
if (ret < 0)
107111
return ret;
108112

109113
for (auto iter = op.entries.begin(); iter != op.entries.end(); ++iter) {
110-
cls_log_entry& entry = *iter;
114+
cls::log::entry& entry = *iter;
111115

112116
string index;
113117

114-
utime_t timestamp = entry.timestamp;
118+
auto timestamp = entry.timestamp;
115119
if (op.monotonic_inc && timestamp < header.max_time)
116120
timestamp = header.max_time;
117121
else if (timestamp > header.max_time)
@@ -146,11 +150,11 @@ static int cls_log_list(cls_method_context_t hctx, bufferlist *in, bufferlist *o
146150
{
147151
auto in_iter = in->cbegin();
148152

149-
cls_log_list_op op;
153+
cls::log::ops::list_op op;
150154
try {
151155
decode(op, in_iter);
152156
} catch (ceph::buffer::error& err) {
153-
CLS_LOG(1, "ERROR: cls_log_list_op(): failed to decode op");
157+
CLS_LOG(1, "ERROR: cls::log::ops::list_op(): failed to decode op");
154158
return -EINVAL;
155159
}
156160

@@ -164,17 +168,17 @@ static int cls_log_list(cls_method_context_t hctx, bufferlist *in, bufferlist *o
164168
} else {
165169
from_index = op.marker;
166170
}
167-
bool use_time_boundary = (!op.from_time.is_zero() && (op.to_time >= op.from_time));
171+
bool use_time_boundary = (!ceph::real_clock::is_zero(op.from_time) && (op.to_time >= op.from_time));
168172

169173
if (use_time_boundary)
170174
get_index_time_prefix(op.to_time, to_index);
171175

172-
#define MAX_ENTRIES 1000
176+
static constexpr auto MAX_ENTRIES = 1000u;
173177
size_t max_entries = op.max_entries;
174178
if (!max_entries || max_entries > MAX_ENTRIES)
175179
max_entries = MAX_ENTRIES;
176180

177-
cls_log_list_ret ret;
181+
cls::log::ops::list_ret ret;
178182

179183
int rc = cls_cxx_map_get_vals(hctx, from_index, log_index_prefix, max_entries, &keys, &ret.truncated);
180184
if (rc < 0)
@@ -196,7 +200,7 @@ static int cls_log_list(cls_method_context_t hctx, bufferlist *in, bufferlist *o
196200
bufferlist& bl = iter->second;
197201
auto biter = bl.cbegin();
198202
try {
199-
cls_log_entry e;
203+
cls::log::entry e;
200204
decode(e, biter);
201205
entries.push_back(e);
202206
} catch (ceph::buffer::error& err) {
@@ -216,7 +220,7 @@ static int cls_log_trim(cls_method_context_t hctx, bufferlist *in, bufferlist *o
216220
{
217221
auto in_iter = in->cbegin();
218222

219-
cls_log_trim_op op;
223+
cls::log::ops::trim_op op;
220224
try {
221225
decode(op, in_iter);
222226
} catch (ceph::buffer::error& err) {
@@ -236,8 +240,7 @@ static int cls_log_trim(cls_method_context_t hctx, bufferlist *in, bufferlist *o
236240
// cls_cxx_map_remove_range() expects one-past-end
237241
if (op.to_marker.empty()) {
238242
auto t = op.to_time;
239-
t.nsec_ref() += 1000; // equivalent to usec() += 1
240-
t.normalize();
243+
t += 1000us; // equivalent to usec() += 1
241244
get_index_time_prefix(t, to_index);
242245
} else {
243246
to_index = op.to_marker;
@@ -281,15 +284,15 @@ static int cls_log_info(cls_method_context_t hctx, bufferlist *in, bufferlist *o
281284
{
282285
auto in_iter = in->cbegin();
283286

284-
cls_log_info_op op;
287+
cls::log::ops::info_op op;
285288
try {
286289
decode(op, in_iter);
287290
} catch (ceph::buffer::error& err) {
288-
CLS_LOG(1, "ERROR: cls_log_add_op(): failed to decode op");
291+
CLS_LOG(1, "ERROR: cls::log::ops::add_op(): failed to decode op");
289292
return -EINVAL;
290293
}
291294

292-
cls_log_info_ret ret;
295+
cls::log::ops::info_ret ret;
293296

294297
int rc = read_header(hctx, ret.header);
295298
if (rc < 0)

src/cls/log/cls_log_client.cc

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#include "include/compat.h"
88

99

10-
using std::list;
10+
using std::vector;
1111
using std::string;
1212

1313
using ceph::bufferlist;
@@ -16,47 +16,47 @@ using namespace librados;
1616

1717

1818

19-
void cls_log_add(librados::ObjectWriteOperation& op, list<cls_log_entry>& entries, bool monotonic_inc)
19+
void cls_log_add(librados::ObjectWriteOperation& op, vector<cls::log::entry>& entries, bool monotonic_inc)
2020
{
2121
bufferlist in;
22-
cls_log_add_op call;
22+
cls::log::ops::add_op call;
2323
call.entries = entries;
2424
encode(call, in);
2525
op.exec("log", "add", in);
2626
}
2727

28-
void cls_log_add(librados::ObjectWriteOperation& op, cls_log_entry& entry)
28+
void cls_log_add(librados::ObjectWriteOperation& op, cls::log::entry& entry)
2929
{
3030
bufferlist in;
31-
cls_log_add_op call;
31+
cls::log::ops::add_op call;
3232
call.entries.push_back(entry);
3333
encode(call, in);
3434
op.exec("log", "add", in);
3535
}
3636

37-
void cls_log_add_prepare_entry(cls_log_entry& entry, const utime_t& timestamp,
38-
const string& section, const string& name, bufferlist& bl)
37+
void cls_log_add_prepare_entry(cls::log::entry& entry, ceph::real_time timestamp,
38+
const string& section, const string& name, bufferlist& bl)
3939
{
4040
entry.timestamp = timestamp;
4141
entry.section = section;
4242
entry.name = name;
4343
entry.data = bl;
4444
}
4545

46-
void cls_log_add(librados::ObjectWriteOperation& op, const utime_t& timestamp,
46+
void cls_log_add(librados::ObjectWriteOperation& op, ceph::real_time timestamp,
4747
const string& section, const string& name, bufferlist& bl)
4848
{
49-
cls_log_entry entry;
49+
cls::log::entry entry;
5050

5151
cls_log_add_prepare_entry(entry, timestamp, section, name, bl);
5252
cls_log_add(op, entry);
5353
}
5454

55-
void cls_log_trim(librados::ObjectWriteOperation& op, const utime_t& from_time, const utime_t& to_time,
56-
const string& from_marker, const string& to_marker)
55+
void cls_log_trim(librados::ObjectWriteOperation& op, ceph::real_time from_time,
56+
ceph::real_time to_time, const string& from_marker, const string& to_marker)
5757
{
5858
bufferlist in;
59-
cls_log_trim_op call;
59+
cls::log::ops::trim_op call;
6060
call.from_time = from_time;
6161
call.to_time = to_time;
6262
call.from_marker = from_marker;
@@ -65,7 +65,8 @@ void cls_log_trim(librados::ObjectWriteOperation& op, const utime_t& from_time,
6565
op.exec("log", "trim", in);
6666
}
6767

68-
int cls_log_trim(librados::IoCtx& io_ctx, const string& oid, const utime_t& from_time, const utime_t& to_time,
68+
int cls_log_trim(librados::IoCtx& io_ctx, const string& oid,
69+
ceph::real_time from_time, ceph::real_time to_time,
6970
const string& from_marker, const string& to_marker)
7071
{
7172
bool done = false;
@@ -88,15 +89,15 @@ int cls_log_trim(librados::IoCtx& io_ctx, const string& oid, const utime_t& from
8889
}
8990

9091
class LogListCtx : public ObjectOperationCompletion {
91-
list<cls_log_entry> *entries;
92+
vector<cls::log::entry>* entries;
9293
string *marker;
9394
bool *truncated;
9495
public:
95-
LogListCtx(list<cls_log_entry> *_entries, string *_marker, bool *_truncated) :
96-
entries(_entries), marker(_marker), truncated(_truncated) {}
96+
LogListCtx(vector<cls::log::entry> *_entries, string *_marker, bool *_truncated) :
97+
entries(_entries), marker(_marker), truncated(_truncated) {}
9798
void handle_completion(int r, bufferlist& outbl) override {
9899
if (r >= 0) {
99-
cls_log_list_ret ret;
100+
cls::log::ops::list_ret ret;
100101
try {
101102
auto iter = outbl.cbegin();
102103
decode(ret, iter);
@@ -113,13 +114,13 @@ class LogListCtx : public ObjectOperationCompletion {
113114
}
114115
};
115116

116-
void cls_log_list(librados::ObjectReadOperation& op, const utime_t& from,
117-
const utime_t& to, const string& in_marker, int max_entries,
118-
list<cls_log_entry>& entries,
117+
void cls_log_list(librados::ObjectReadOperation& op, ceph::real_time from,
118+
ceph::real_time to, const string& in_marker, int max_entries,
119+
vector<cls::log::entry>& entries,
119120
string *out_marker, bool *truncated)
120121
{
121122
bufferlist inbl;
122-
cls_log_list_op call;
123+
cls::log::ops::list_op call;
123124
call.from_time = from;
124125
call.to_time = to;
125126
call.marker = in_marker;
@@ -131,12 +132,12 @@ void cls_log_list(librados::ObjectReadOperation& op, const utime_t& from,
131132
}
132133

133134
class LogInfoCtx : public ObjectOperationCompletion {
134-
cls_log_header *header;
135+
cls::log::header* header;
135136
public:
136-
explicit LogInfoCtx(cls_log_header *_header) : header(_header) {}
137+
explicit LogInfoCtx(cls::log::header *_header) : header(_header) {}
137138
void handle_completion(int r, bufferlist& outbl) override {
138139
if (r >= 0) {
139-
cls_log_info_ret ret;
140+
cls::log::ops::info_ret ret;
140141
try {
141142
auto iter = outbl.cbegin();
142143
decode(ret, iter);
@@ -149,10 +150,10 @@ class LogInfoCtx : public ObjectOperationCompletion {
149150
}
150151
};
151152

152-
void cls_log_info(librados::ObjectReadOperation& op, cls_log_header *header)
153+
void cls_log_info(librados::ObjectReadOperation& op, cls::log::header *header)
153154
{
154155
bufferlist inbl;
155-
cls_log_info_op call;
156+
cls::log::ops::info_op call;
156157

157158
encode(call, inbl);
158159

0 commit comments

Comments
 (0)