Skip to content

Commit 94abd9a

Browse files
authored
Merge pull request ceph#57640 from cbodley/wip-rgw-beast-realm-reload
rgw/beast: realm reload closes connections so requests drain quickly Reviewed-by: Oguzhan Ozmen <[email protected]>
2 parents 8de64f3 + ab30392 commit 94abd9a

File tree

5 files changed

+29
-16
lines changed

5 files changed

+29
-16
lines changed

src/rgw/driver/rados/rgw_period.cc

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,6 @@ int RGWPeriod::commit(const DoutPrefixProvider *dpp,
271271
}
272272
ldpp_dout(dpp, 4) << "Promoted to master zone and committed new period "
273273
<< id << dendl;
274-
realm.notify_new_period(dpp, *this, y);
275274
return 0;
276275
}
277276
// period must be based on current epoch
@@ -295,10 +294,6 @@ int RGWPeriod::commit(const DoutPrefixProvider *dpp,
295294
}
296295
// set as latest epoch
297296
r = update_latest_epoch(dpp, epoch, y);
298-
if (r == -EEXIST) {
299-
// already have this epoch (or a more recent one)
300-
return 0;
301-
}
302297
if (r < 0) {
303298
ldpp_dout(dpp, 0) << "failed to set latest epoch: " << cpp_strerror(-r) << dendl;
304299
return r;
@@ -310,7 +305,6 @@ int RGWPeriod::commit(const DoutPrefixProvider *dpp,
310305
}
311306
ldpp_dout(dpp, 4) << "Committed new epoch " << epoch
312307
<< " for period " << id << dendl;
313-
realm.notify_new_period(dpp, *this, y);
314308
return 0;
315309
}
316310

src/rgw/driver/rados/rgw_rest_realm.cc

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
22
// vim: ts=8 sw=2 smarttab ft=cpp
33

4+
#include <optional>
45
#include "common/errno.h"
56
#include "rgw_rest_realm.h"
67
#include "rgw_rest_s3.h"
@@ -81,14 +82,17 @@ void RGWOp_Period_Get::execute(optional_yield y)
8182

8283
// POST /admin/realm/period
8384
class RGWOp_Period_Post : public RGWOp_Period_Base {
85+
std::optional<RGWRealm> notify_realm;
8486
public:
8587
void execute(optional_yield y) override;
88+
void send_response() override;
8689
int check_caps(const RGWUserCaps& caps) override {
8790
return caps.check_cap("zone", RGW_CAP_WRITE);
8891
}
8992
int verify_permission(optional_yield) override {
9093
return check_caps(s->user->get_caps());
9194
}
95+
9296
const char* name() const override { return "post_period"; }
9397
RGWOpType get_type() override { return RGW_OP_PERIOD_POST; }
9498
};
@@ -139,9 +143,15 @@ void RGWOp_Period_Post::execute(optional_yield y)
139143
// if period id is empty, handle as 'period commit'
140144
if (period.get_id().empty()) {
141145
op_ret = period.commit(this, driver, realm, current_period, error_stream, y);
146+
if (op_ret == -EEXIST) {
147+
op_ret = 0; // succeed on retries so the op is idempotent
148+
return;
149+
}
142150
if (op_ret < 0) {
143151
ldpp_dout(this, -1) << "master zone failed to commit period" << dendl;
152+
return;
144153
}
154+
notify_realm = std::move(realm); // trigger realm reload
145155
return;
146156
}
147157

@@ -221,7 +231,7 @@ void RGWOp_Period_Post::execute(optional_yield y)
221231
ldpp_dout(this, 4) << "period " << period.get_id()
222232
<< " is newer than current period " << current_period.get_id()
223233
<< ", updating realm's current period and notifying zone" << dendl;
224-
realm.notify_new_period(this, period, y);
234+
notify_realm = std::move(realm); // trigger realm reload
225235
return;
226236
}
227237
// reflect the period into our local objects
@@ -234,11 +244,22 @@ void RGWOp_Period_Post::execute(optional_yield y)
234244
ldpp_dout(this, 4) << "period epoch " << period.get_epoch()
235245
<< " is newer than current epoch " << current_period.get_epoch()
236246
<< ", updating period's latest epoch and notifying zone" << dendl;
237-
realm.notify_new_period(this, period, y);
247+
notify_realm = std::move(realm); // trigger realm reload
238248
// update the period history
239249
period_history->insert(RGWPeriod{period});
240250
}
241251

252+
void RGWOp_Period_Post::send_response()
253+
{
254+
RGWOp_Period_Base::send_response();
255+
256+
if (notify_realm) {
257+
// trigger realm reload after sending the response, because reload may
258+
// race to close this connection
259+
notify_realm->notify_new_period(this, period, s->yield);
260+
}
261+
}
262+
242263
class RGWHandler_Period : public RGWHandler_Auth_S3 {
243264
protected:
244265
using RGWHandler_Auth_S3::RGWHandler_Auth_S3;

src/rgw/driver/rados/rgw_zone.cc

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -769,7 +769,6 @@ int commit_period(const DoutPrefixProvider* dpp, optional_yield y,
769769
}
770770
ldpp_dout(dpp, 4) << "Promoted to master zone and committed new period "
771771
<< info.id << dendl;
772-
(void) cfgstore->realm_notify_new_period(dpp, y, info);
773772
return 0;
774773
}
775774
// period must be based on current epoch
@@ -788,10 +787,6 @@ int commit_period(const DoutPrefixProvider* dpp, optional_yield y,
788787
// write the period
789788
constexpr bool exclusive = true;
790789
int r = cfgstore->create_period(dpp, y, exclusive, info);
791-
if (r == -EEXIST) {
792-
// already have this epoch (or a more recent one)
793-
return 0;
794-
}
795790
if (r < 0) {
796791
ldpp_dout(dpp, 0) << "failed to store period: " << cpp_strerror(r) << dendl;
797792
return r;
@@ -803,7 +798,6 @@ int commit_period(const DoutPrefixProvider* dpp, optional_yield y,
803798
}
804799
ldpp_dout(dpp, 4) << "Committed new epoch " << info.epoch
805800
<< " for period " << info.id << dendl;
806-
(void) cfgstore->realm_notify_new_period(dpp, y, info);
807801
return 0;
808802
}
809803

src/rgw/rgw_admin.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1947,6 +1947,7 @@ static int commit_period(rgw::sal::ConfigStore* cfgstore,
19471947
if (ret < 0) {
19481948
cerr << "failed to commit period: " << cpp_strerror(-ret) << std::endl;
19491949
}
1950+
(void) cfgstore->realm_notify_new_period(dpp(), null_yield, period);
19501951
return ret;
19511952
}
19521953

src/rgw/rgw_asio_frontend.cc

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,15 +1101,18 @@ void AsioFrontend::join()
11011101

11021102
void AsioFrontend::pause()
11031103
{
1104-
ldout(ctx(), 4) << "frontend pausing connections..." << dendl;
1104+
ldout(ctx(), 4) << "frontend pausing, closing connections..." << dendl;
11051105

11061106
// cancel pending calls to accept(), but don't close the sockets
11071107
boost::system::error_code ec;
11081108
for (auto& l : listeners) {
11091109
l.acceptor.cancel(ec);
11101110
}
11111111

1112-
// pause and wait for outstanding requests to complete
1112+
// close all connections so outstanding requests fail quickly
1113+
connections.close(ec);
1114+
1115+
// pause and wait until outstanding requests complete
11131116
pause_mutex.lock(ec);
11141117

11151118
if (ec) {

0 commit comments

Comments
 (0)