Skip to content

Commit 7455933

Browse files
authored
Merge pull request ceph#54996 from ronen-fr/wip-rf-active-primary
osd/scrub: add a "clean primary" base state Reviewed-by: Samuel Just <[email protected]>
2 parents 6c2c477 + 6d6cc71 commit 7455933

File tree

9 files changed

+240
-92
lines changed

9 files changed

+240
-92
lines changed

src/osd/PG.cc

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1847,7 +1847,6 @@ void PG::on_activate(interval_set<snapid_t> snaps)
18471847
snap_trimq = snaps;
18481848
release_pg_backoffs();
18491849
projected_last_update = info.last_update;
1850-
m_scrubber->on_pg_activate(m_planned_scrub);
18511850
}
18521851

18531852
void PG::on_replica_activate()
@@ -1861,6 +1860,16 @@ void PG::on_active_exit()
18611860
agent_stop();
18621861
}
18631862

1863+
Context* PG::on_clean()
1864+
{
1865+
if (is_active()) {
1866+
kick_snap_trim();
1867+
}
1868+
m_scrubber->on_primary_active_clean();
1869+
requeue_ops(waiting_for_clean_to_primary_repair);
1870+
return finish_recovery();
1871+
}
1872+
18641873
void PG::on_active_advmap(const OSDMapRef &osdmap)
18651874
{
18661875
const auto& new_removed_snaps = osdmap->get_new_removed_snaps();

src/osd/PG.h

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -608,13 +608,7 @@ class PG : public DoutPrefixProvider,
608608

609609
void on_active_exit() override;
610610

611-
Context *on_clean() override {
612-
if (is_active()) {
613-
kick_snap_trim();
614-
}
615-
requeue_ops(waiting_for_clean_to_primary_repair);
616-
return finish_recovery();
617-
}
611+
Context *on_clean() override;
618612

619613
void on_activate(interval_set<snapid_t> snaps) override;
620614

src/osd/PrimaryLogPG.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12879,8 +12879,7 @@ void PrimaryLogPG::on_shutdown()
1287912879
osd->clear_queued_recovery(this);
1288012880
}
1288112881

12882-
m_scrubber->scrub_clear_state();
12883-
m_scrubber->rm_from_osd_scrubbing();
12882+
m_scrubber->on_new_interval();
1288412883

1288512884
vector<ceph_tid_t> tids;
1288612885
cancel_copy_ops(false, &tids);

src/osd/scrubber/pg_scrubber.cc

Lines changed: 37 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ bool PgScrubber::verify_against_abort(epoch_t epoch_to_verify)
152152

153153
// if we were not aware of the abort before - kill the scrub.
154154
if (epoch_to_verify >= m_last_aborted) {
155-
scrub_clear_state();
155+
m_fsm->process_event(FullReset{});
156156
m_last_aborted = std::max(epoch_to_verify, m_epoch_start);
157157
}
158158
return false;
@@ -208,17 +208,18 @@ bool PgScrubber::should_abort() const
208208

209209
void PgScrubber::initiate_regular_scrub(epoch_t epoch_queued)
210210
{
211-
dout(15) << __func__ << " epoch: " << epoch_queued << dendl;
211+
dout(10) << fmt::format(
212+
"{}: epoch:{} is PrimaryIdle:{}", __func__, epoch_queued,
213+
m_fsm->is_primary_idle())
214+
<< dendl;
215+
212216
// we may have lost our Primary status while the message languished in the
213217
// queue
214218
if (check_interval(epoch_queued)) {
215219
dout(10) << "scrubber event -->> StartScrub epoch: " << epoch_queued
216220
<< dendl;
217-
reset_epoch(epoch_queued);
218221
m_fsm->process_event(StartScrub{});
219222
dout(10) << "scrubber event --<< StartScrub" << dendl;
220-
} else {
221-
clear_queued_or_active(); // also restarts snap trimming
222223
}
223224
}
224225

@@ -229,17 +230,17 @@ void PgScrubber::advance_token()
229230

230231
void PgScrubber::initiate_scrub_after_repair(epoch_t epoch_queued)
231232
{
232-
dout(15) << __func__ << " epoch: " << epoch_queued << dendl;
233+
dout(10) << fmt::format(
234+
"{}: epoch:{} is PrimaryIdle:{}", __func__, epoch_queued,
235+
m_fsm->is_primary_idle())
236+
<< dendl;
233237
// we may have lost our Primary status while the message languished in the
234238
// queue
235239
if (check_interval(epoch_queued)) {
236240
dout(10) << "scrubber event -->> AfterRepairScrub epoch: " << epoch_queued
237241
<< dendl;
238-
reset_epoch(epoch_queued);
239242
m_fsm->process_event(AfterRepairScrub{});
240243
dout(10) << "scrubber event --<< AfterRepairScrub" << dendl;
241-
} else {
242-
clear_queued_or_active(); // also restarts snap trimming
243244
}
244245
}
245246

@@ -403,13 +404,13 @@ bool PgScrubber::is_reserving() const
403404
return m_fsm->is_reserving();
404405
}
405406

406-
void PgScrubber::reset_epoch(epoch_t epoch_queued)
407+
void PgScrubber::reset_epoch()
407408
{
408409
dout(10) << __func__ << " state deep? " << state_test(PG_STATE_DEEP_SCRUB)
409410
<< dendl;
410-
m_fsm->assert_not_active();
411+
m_fsm->assert_not_in_session();
411412

412-
m_epoch_start = epoch_queued;
413+
m_epoch_start = m_pg->get_same_interval_since();
413414
ceph_assert(m_is_deep == state_test(PG_STATE_DEEP_SCRUB));
414415
update_op_mode_text();
415416
}
@@ -460,9 +461,12 @@ void PgScrubber::on_new_interval()
460461
(is_primary() ? "Primary" : "Replica/other"),
461462
is_scrub_active(), is_queued_or_active())
462463
<< dendl;
463-
464464
m_fsm->process_event(IntervalChanged{});
465-
rm_from_osd_scrubbing();
465+
// the following asserts were added due to a past bug, where PG flags were
466+
// left set in some scenarios.
467+
ceph_assert(!is_queued_or_active());
468+
ceph_assert(!state_test(PG_STATE_SCRUBBING));
469+
ceph_assert(!state_test(PG_STATE_DEEP_SCRUB));
466470
}
467471

468472
bool PgScrubber::is_scrub_registered() const
@@ -488,35 +492,39 @@ void PgScrubber::rm_from_osd_scrubbing()
488492
}
489493
}
490494

491-
void PgScrubber::on_pg_activate(const requested_scrub_t& request_flags)
495+
/*
496+
* Note: referring to m_planned_scrub here is temporary, as this set of
497+
* scheduling flags will be removed in a followup PR.
498+
*/
499+
void PgScrubber::schedule_scrub_with_osd()
492500
{
493501
ceph_assert(is_primary());
494-
if (!m_scrub_job) {
495-
// we won't have a chance to see more logs from this function, thus:
496-
dout(2) << fmt::format(
497-
"{}: flags:<{}> {}.Reg-state:{:.7}. No scrub-job", __func__,
498-
request_flags, (is_primary() ? "Primary" : "Replica/other"),
499-
registration_state())
500-
<< dendl;
501-
return;
502-
}
502+
ceph_assert(m_scrub_job);
503503

504-
ceph_assert(!is_queued_or_active());
505504
auto pre_state = m_scrub_job->state_desc();
506505
auto pre_reg = registration_state();
507506

508507
auto suggested = m_osds->get_scrub_services().determine_scrub_time(
509-
request_flags, m_pg->info, m_pg->get_pgpool().info.opts);
508+
m_planned_scrub, m_pg->info, m_pg->get_pgpool().info.opts);
510509
m_osds->get_scrub_services().register_with_osd(m_scrub_job, suggested);
511510

512511
dout(10) << fmt::format(
513512
"{}: <flags:{}> {} <{:.5}>&<{:.10}> --> <{:.5}>&<{:.14}>",
514-
__func__, request_flags,
513+
__func__, m_planned_scrub,
515514
(is_primary() ? "Primary" : "Replica/other"), pre_reg,
516515
pre_state, registration_state(), m_scrub_job->state_desc())
517516
<< dendl;
518517
}
519518

519+
520+
void PgScrubber::on_primary_active_clean()
521+
{
522+
dout(10) << fmt::format(
523+
"{}: reg state: {}", __func__, m_scrub_job->state_desc())
524+
<< dendl;
525+
m_fsm->process_event(PrimaryActivate{});
526+
}
527+
520528
/*
521529
* A note re the call to publish_stats_to_osd() below:
522530
* - we are called from either request_rescrubbing() or scrub_requested().
@@ -2164,11 +2172,7 @@ void PgScrubber::handle_query_state(ceph::Formatter* f)
21642172
PgScrubber::~PgScrubber()
21652173
{
21662174
m_fsm->process_event(IntervalChanged{});
2167-
if (m_scrub_job) {
2168-
// make sure the OSD won't try to scrub this one just now
2169-
rm_from_osd_scrubbing();
2170-
m_scrub_job.reset();
2171-
}
2175+
m_scrub_job.reset();
21722176
}
21732177

21742178
PgScrubber::PgScrubber(PG* pg)
@@ -2416,7 +2420,7 @@ void PgScrubber::update_scrub_stats(ceph::coarse_real_clock::time_point now_is)
24162420
/// \todo use the date library (either the one included in Arrow or directly)
24172421
/// to get the formatting of the time_points.
24182422

2419-
if (g_conf()->subsys.should_gather<ceph_subsys_osd, 20>()) {
2423+
if (g_conf()->subsys.should_gather<ceph_subsys_osd, 25>()) {
24202424
// will only create the debug strings if required
24212425
char buf[50];
24222426
auto printable_last = fmt::localtime(clock::to_time_t(m_last_stat_upd));

src/osd/scrubber/pg_scrubber.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ class PgScrubber : public ScrubPgIF,
252252

253253
void rm_from_osd_scrubbing() final;
254254

255-
void on_pg_activate(const requested_scrub_t& request_flags) final;
255+
void schedule_scrub_with_osd() final;
256256

257257
scrub_level_t scrub_requested(
258258
scrub_level_t scrub_level,
@@ -314,6 +314,8 @@ class PgScrubber : public ScrubPgIF,
314314

315315
void on_new_interval() final;
316316

317+
void on_primary_active_clean() final;
318+
317319
void on_replica_activate() final;
318320

319321
void scrub_clear_state() final;
@@ -554,7 +556,7 @@ class PgScrubber : public ScrubPgIF,
554556
* - the epoch when started;
555557
* - the depth of the scrub requested (from the PG_STATE variable)
556558
*/
557-
void reset_epoch(epoch_t epoch_queued);
559+
void reset_epoch() final;
558560

559561
void run_callbacks();
560562

src/osd/scrubber/scrub_machine.cc

Lines changed: 62 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,21 @@ void on_event_discard(std::string_view nm)
4747
dout(20) << " event: --^^^^---- " << nm << dendl;
4848
}
4949

50-
void ScrubMachine::assert_not_active() const
50+
void ScrubMachine::assert_not_in_session() const
5151
{
52-
ceph_assert(state_cast<const NotActive*>());
52+
ceph_assert(!state_cast<const Session*>());
5353
}
5454

5555
bool ScrubMachine::is_reserving() const
5656
{
5757
return state_cast<const ReservingReplicas*>();
5858
}
5959

60+
bool ScrubMachine::is_primary_idle() const
61+
{
62+
return state_cast<const PrimaryIdle*>();
63+
}
64+
6065
bool ScrubMachine::is_accepting_updates() const
6166
{
6267
DECLARE_LOCALS; // 'scrbr' & 'pg_id' aliases
@@ -114,27 +119,68 @@ NotActive::NotActive(my_context ctx)
114119
scrbr->clear_queued_or_active();
115120
}
116121

117-
sc::result NotActive::react(const StartScrub&)
122+
123+
// ----------------------- PrimaryActive --------------------------------
124+
125+
PrimaryActive::PrimaryActive(my_context ctx)
126+
: my_base(ctx)
127+
, NamedSimply(context<ScrubMachine>().m_scrbr, "PrimaryActive")
128+
{
129+
DECLARE_LOCALS; // 'scrbr' & 'pg_id' aliases
130+
dout(10) << "-- state -->> PrimaryActive" << dendl;
131+
// insert this PG into the OSD scrub queue. Calculate initial schedule
132+
scrbr->schedule_scrub_with_osd();
133+
}
134+
135+
PrimaryActive::~PrimaryActive()
118136
{
119-
dout(10) << "NotActive::react(const StartScrub&)" << dendl;
137+
DECLARE_LOCALS; // 'scrbr' & 'pg_id' aliases
138+
// we may have set some PG state flags without reaching Session.
139+
// And we may be holding a 'local resource'.
140+
scrbr->clear_pgscrub_state();
141+
scrbr->rm_from_osd_scrubbing();
142+
}
143+
144+
145+
// ---------------- PrimaryActive/PrimaryIdle ---------------------------
146+
147+
PrimaryIdle::PrimaryIdle(my_context ctx)
148+
: my_base(ctx)
149+
, NamedSimply(context<ScrubMachine>().m_scrbr, "PrimaryActive/PrimaryIdle")
150+
{
151+
dout(10) << "-- state -->> PrimaryActive/PrimaryIdle" << dendl;
152+
}
153+
154+
sc::result PrimaryIdle::react(const StartScrub&)
155+
{
156+
dout(10) << "PrimaryIdle::react(const StartScrub&)" << dendl;
120157
DECLARE_LOCALS;
158+
scrbr->reset_epoch();
121159
return transit<ReservingReplicas>();
122160
}
123161

124-
sc::result NotActive::react(const AfterRepairScrub&)
162+
sc::result PrimaryIdle::react(const AfterRepairScrub&)
125163
{
126-
dout(10) << "NotActive::react(const AfterRepairScrub&)" << dendl;
164+
dout(10) << "PrimaryIdle::react(const AfterRepairScrub&)" << dendl;
127165
DECLARE_LOCALS;
166+
scrbr->reset_epoch();
128167
return transit<ReservingReplicas>();
129168
}
130169

170+
void PrimaryIdle::clear_state(const FullReset&) {
171+
dout(10) << "PrimaryIdle::react(const FullReset&): clearing state flags"
172+
<< dendl;
173+
DECLARE_LOCALS;
174+
scrbr->clear_pgscrub_state();
175+
}
176+
131177
// ----------------------- Session -----------------------------------------
132178

133179
Session::Session(my_context ctx)
134180
: my_base(ctx)
135-
, NamedSimply(context<ScrubMachine>().m_scrbr, "Session")
181+
, NamedSimply(context<ScrubMachine>().m_scrbr, "PrimaryActive/Session")
136182
{
137-
dout(10) << "-- state -->> Session" << dendl;
183+
dout(10) << "-- state -->> PrimaryActive/Session" << dendl;
138184
DECLARE_LOCALS; // 'scrbr' & 'pg_id' aliases
139185

140186
// while we've checked the 'someone is reserving' flag before queueing
@@ -242,7 +288,7 @@ sc::result ReservingReplicas::react(const ReplicaReject& ev)
242288
scrbr->flag_reservations_failure();
243289

244290
// 'Session' state dtor stops the scrubber
245-
return transit<NotActive>();
291+
return transit<PrimaryIdle>();
246292
}
247293

248294
sc::result ReservingReplicas::react(const ReservationTimeout&)
@@ -261,7 +307,7 @@ sc::result ReservingReplicas::react(const ReservationTimeout&)
261307
// cause the scrubber to stop the scrub session, marking 'reservation
262308
// failure' as the cause (affecting future scheduling)
263309
scrbr->flag_reservations_failure();
264-
return transit<NotActive>();
310+
return transit<PrimaryIdle>();
265311
}
266312

267313
// ----------------------- ActiveScrubbing -----------------------------------
@@ -678,7 +724,7 @@ sc::result WaitDigestUpdate::react(const ScrubFinished&)
678724
session.m_session_started_at = ScrubTimePoint{};
679725

680726
scrbr->scrub_finish();
681-
return transit<NotActive>();
727+
return transit<PrimaryIdle>();
682728
}
683729

684730
ScrubMachine::ScrubMachine(PG* pg, ScrubMachineListener* pg_scrub)
@@ -813,6 +859,11 @@ ReplicaIdle::ReplicaIdle(my_context ctx)
813859
dout(10) << "-- state -->> ReplicaActive/ReplicaIdle" << dendl;
814860
}
815861

862+
void ReplicaIdle::reset_ignored(const FullReset&)
863+
{
864+
dout(10) << "ReplicaIdle::react(const FullReset&): FullReset ignored"
865+
<< dendl;
866+
}
816867

817868
// ------------- ReplicaActive/ReplicaActiveOp --------------------------
818869

0 commit comments

Comments
 (0)