diff options
Diffstat (limited to '')
-rw-r--r-- | src/osd/PG.h | 1 | ||||
-rw-r--r-- | src/osd/PeeringState.cc | 2 | ||||
-rw-r--r-- | src/osd/PeeringState.h | 1 | ||||
-rw-r--r-- | src/osd/SnapMapper.cc | 44 | ||||
-rw-r--r-- | src/osd/SnapMapper.h | 4 | ||||
-rw-r--r-- | src/osd/scrubber/pg_scrubber.cc | 10 | ||||
-rw-r--r-- | src/osd/scrubber/scrub_job.cc | 31 | ||||
-rw-r--r-- | src/osd/scrubber/scrub_job.h | 6 | ||||
-rw-r--r-- | src/osd/scrubber/scrub_machine.cc | 4 | ||||
-rw-r--r-- | src/osd/scrubber/scrub_machine.h | 4 | ||||
-rw-r--r-- | src/osd/scrubber_common.h | 4 |
11 files changed, 99 insertions, 12 deletions
diff --git a/src/osd/PG.h b/src/osd/PG.h index 6bcb77ee5a9..ef4dd3fc4f0 100644 --- a/src/osd/PG.h +++ b/src/osd/PG.h @@ -612,6 +612,7 @@ public: void on_backfill_reserved() override; void on_backfill_canceled() override; + void on_recovery_cancelled() override {} void on_recovery_reserved() override; bool is_forced_recovery_or_backfill() const { diff --git a/src/osd/PeeringState.cc b/src/osd/PeeringState.cc index 944b77c2812..22222b7f7af 100644 --- a/src/osd/PeeringState.cc +++ b/src/osd/PeeringState.cc @@ -5827,6 +5827,7 @@ PeeringState::Recovering::react(const DeferRecovery &evt) ps->state_set(PG_STATE_RECOVERY_WAIT); pl->cancel_local_background_io_reservation(); release_reservations(true); + pl->on_recovery_cancelled(); pl->schedule_event_after( std::make_shared<PGPeeringEvent>( ps->get_osdmap_epoch(), @@ -5844,6 +5845,7 @@ PeeringState::Recovering::react(const UnfoundRecovery &evt) ps->state_set(PG_STATE_RECOVERY_UNFOUND); pl->cancel_local_background_io_reservation(); release_reservations(true); + pl->on_recovery_cancelled(); return transit<NotRecovering>(); } diff --git a/src/osd/PeeringState.h b/src/osd/PeeringState.h index f036bb44b11..11ac084a054 100644 --- a/src/osd/PeeringState.h +++ b/src/osd/PeeringState.h @@ -419,6 +419,7 @@ public: virtual void on_backfill_reserved() = 0; virtual void on_backfill_canceled() = 0; virtual void on_recovery_reserved() = 0; + virtual void on_recovery_cancelled() = 0; // ================recovery space accounting ================ virtual bool try_reserve_recovery_space( diff --git a/src/osd/SnapMapper.cc b/src/osd/SnapMapper.cc index 414de479dc7..4ece8880411 100644 --- a/src/osd/SnapMapper.cc +++ b/src/osd/SnapMapper.cc @@ -728,6 +728,50 @@ int SnapMapper::get_snaps( return 0; } +void SnapMapper::update_snap_map( + const pg_log_entry_t& i, + MapCacher::Transaction<std::string, ceph::buffer::list> *_t) +{ + ceph_assert(i.soid.snap < CEPH_MAXSNAP); + dout(20) << __func__ << " " << i << dendl; + if (i.is_delete()) { + int r = remove_oid( + i.soid, + _t); + if (r) + dout(20) << __func__ << " remove_oid " << i.soid << " failed with " << r << dendl; + // On removal tolerate missing key corruption + ceph_assert(r == 0 || r == -ENOENT); + } else if (i.is_update()) { + ceph_assert(i.snaps.length() > 0); + std::vector<snapid_t> snaps; + bufferlist snapbl = i.snaps; + auto p = snapbl.cbegin(); + try { + decode(snaps, p); + } catch (...) { + dout(20) << __func__ << " decode snaps failure on " << i << dendl; + snaps.clear(); + } + std::set<snapid_t> _snaps(snaps.begin(), snaps.end()); + + if (i.is_clone() || i.is_promote()) { + add_oid( + i.soid, + _snaps, + _t); + } else if (i.is_modify()) { + int r = update_snaps( + i.soid, + _snaps, + 0, + _t); + ceph_assert(r == 0); + } else { + ceph_assert(i.is_clean()); + } + } +} // -- purged snaps -- diff --git a/src/osd/SnapMapper.h b/src/osd/SnapMapper.h index f9a371932f6..a43bb5d94f0 100644 --- a/src/osd/SnapMapper.h +++ b/src/osd/SnapMapper.h @@ -394,6 +394,10 @@ private: std::set<snapid_t> *snaps ///< [out] snaps ) const; ///< @return error, -ENOENT if oid is not recorded + void update_snap_map( + const pg_log_entry_t& i, + MapCacher::Transaction<std::string, ceph::buffer::list> *t); + /// Get snaps for oid - alternative interface tl::expected<std::set<snapid_t>, SnapMapReaderI::result_t> get_snaps( const hobject_t &hoid) const final; diff --git a/src/osd/scrubber/pg_scrubber.cc b/src/osd/scrubber/pg_scrubber.cc index 0e4253b339a..b0bdc9fcb95 100644 --- a/src/osd/scrubber/pg_scrubber.cc +++ b/src/osd/scrubber/pg_scrubber.cc @@ -2220,7 +2220,7 @@ void PgScrubber::on_mid_scrub_abort(Scrub::delay_cause_t issue) // that made any of the targets into a high-priority one. All that's left: // delay the specific target that was aborted. - auto& trgt = m_scrub_job->delay_on_failure(aborted_target.level(), 5s, issue, + auto& trgt = m_scrub_job->delay_on_failure(aborted_target.level(), issue, scrub_clock_now); /// \todo complete the merging of the deadline & target for non-hp targets @@ -2251,8 +2251,7 @@ void PgScrubber::requeue_penalized( return; } /// \todo fix the 5s' to use a cause-specific delay parameter - auto& trgt = - m_scrub_job->delay_on_failure(s_or_d, 5s, cause, scrub_clock_now); + auto& trgt = m_scrub_job->delay_on_failure(s_or_d, cause, scrub_clock_now); ceph_assert(!trgt.queued); m_osds->get_scrub_services().enqueue_target(trgt); trgt.queued = true; @@ -2274,7 +2273,7 @@ void PgScrubber::requeue_penalized( m_osds->get_scrub_services().dequeue_target(m_pg_id, sister_level); trgt2.queued = false; } - m_scrub_job->delay_on_failure(sister_level, 5s, cause, scrub_clock_now); + m_scrub_job->delay_on_failure(sister_level, cause, scrub_clock_now); m_osds->get_scrub_services().enqueue_target(trgt2); trgt2.queued = true; } @@ -2333,7 +2332,8 @@ Scrub::schedule_result_t PgScrubber::start_scrub_session( // i.e. some time before setting 'snaptrim'. dout(10) << __func__ << ": cannot scrub while snap-trimming" << dendl; requeue_penalized( - s_or_d, delay_both_targets_t::yes, delay_cause_t::pg_state, clock_now); + s_or_d, delay_both_targets_t::yes, delay_cause_t::snap_trimming, + clock_now); return schedule_result_t::target_specific_failure; } diff --git a/src/osd/scrubber/scrub_job.cc b/src/osd/scrubber/scrub_job.cc index ee33ee06706..7b05eea3941 100644 --- a/src/osd/scrubber/scrub_job.cc +++ b/src/osd/scrubber/scrub_job.cc @@ -12,6 +12,7 @@ using sched_conf_t = Scrub::sched_conf_t; using scrub_schedule_t = Scrub::scrub_schedule_t; using ScrubJob = Scrub::ScrubJob; using delay_ready_t = Scrub::delay_ready_t; +using namespace std::chrono; namespace { utime_t add_double(utime_t t, double d) @@ -300,16 +301,42 @@ void ScrubJob::adjust_deep_schedule( SchedTarget& ScrubJob::delay_on_failure( scrub_level_t level, - std::chrono::seconds delay, - Scrub::delay_cause_t delay_cause, + delay_cause_t delay_cause, utime_t scrub_clock_now) { + seconds delay = seconds(cct->_conf.get_val<int64_t>("osd_scrub_retry_delay")); + switch (delay_cause) { + case delay_cause_t::flags: + delay = + seconds(cct->_conf.get_val<int64_t>("osd_scrub_retry_after_noscrub")); + break; + case delay_cause_t::pg_state: + delay = seconds(cct->_conf.get_val<int64_t>("osd_scrub_retry_pg_state")); + break; + case delay_cause_t::snap_trimming: + delay = seconds(cct->_conf.get_val<int64_t>("osd_scrub_retry_trimming")); + break; + case delay_cause_t::interval: + delay = seconds(cct->_conf.get_val<int64_t>("osd_scrub_retry_new_interval")); + break; + case delay_cause_t::local_resources: + case delay_cause_t::aborted: + default: + // for all other possible delay causes: use the default delay + break; + } + auto& delayed_target = (level == scrub_level_t::deep) ? deep_target : shallow_target; delayed_target.sched_info.schedule.not_before = std::max(scrub_clock_now, delayed_target.sched_info.schedule.not_before) + utime_t{delay}; delayed_target.sched_info.last_issue = delay_cause; + dout(20) << fmt::format( + "delayed {}scrub due to {} for {}s. Updated: {}", + (level == scrub_level_t::deep ? "deep " : ""), delay_cause, + delay.count(), delayed_target) + << dendl; return delayed_target; } diff --git a/src/osd/scrubber/scrub_job.h b/src/osd/scrubber/scrub_job.h index 98a3e101f9b..b037084db6b 100644 --- a/src/osd/scrubber/scrub_job.h +++ b/src/osd/scrubber/scrub_job.h @@ -239,14 +239,14 @@ class ScrubJob { /** * For the level specified, set the 'not-before' time to 'now+delay', - * so that this scrub target - * would not be retried before 'delay' seconds have passed. + * so that this scrub target would not be retried before the required + * delay seconds have passed. + * The delay is determined based on the 'cause' parameter. * The 'last_issue' is updated to the cause of the delay. * \returns a reference to the target that was modified. */ [[maybe_unused]] SchedTarget& delay_on_failure( scrub_level_t level, - std::chrono::seconds delay, delay_cause_t delay_cause, utime_t scrub_clock_now); diff --git a/src/osd/scrubber/scrub_machine.cc b/src/osd/scrubber/scrub_machine.cc index 81e9bd7b6d8..da9466758f4 100644 --- a/src/osd/scrubber/scrub_machine.cc +++ b/src/osd/scrubber/scrub_machine.cc @@ -199,6 +199,7 @@ sc::result Session::react(const IntervalChanged&) ceph_assert(m_reservations); m_reservations->discard_remote_reservations(); + m_abort_reason = delay_cause_t::interval; return transit<NotActive>(); } @@ -300,7 +301,8 @@ ActiveScrubbing::~ActiveScrubbing() // completed successfully), we use it now to set the 'failed scrub' duration. if (session.m_session_started_at != ScrubTimePoint{}) { // delay the next invocation of the scrubber on this target - scrbr->on_mid_scrub_abort(Scrub::delay_cause_t::aborted); + scrbr->on_mid_scrub_abort( + session.m_abort_reason.value_or(Scrub::delay_cause_t::aborted)); auto logged_duration = ScrubClock::now() - session.m_session_started_at; session.m_perf_set->tinc(scrbcnt_failed_elapsed, logged_duration); diff --git a/src/osd/scrubber/scrub_machine.h b/src/osd/scrubber/scrub_machine.h index d1edfd37c98..ad0d3bfba38 100644 --- a/src/osd/scrubber/scrub_machine.h +++ b/src/osd/scrubber/scrub_machine.h @@ -551,6 +551,10 @@ struct Session : sc::state<Session, PrimaryActive, ReservingReplicas>, /// the time when the session was initiated ScrubTimePoint m_session_started_at{ScrubClock::now()}; + + /// abort reason - if known. Determines the delay time imposed on the + /// failed scrub target. + std::optional<Scrub::delay_cause_t> m_abort_reason{std::nullopt}; }; struct ReservingReplicas : sc::state<ReservingReplicas, Session>, NamedSimply { diff --git a/src/osd/scrubber_common.h b/src/osd/scrubber_common.h index 60c1a68d2be..5e510a03a82 100644 --- a/src/osd/scrubber_common.h +++ b/src/osd/scrubber_common.h @@ -229,7 +229,8 @@ enum class delay_cause_t { none, ///< scrub attempt was successful replicas, ///< failed to reserve replicas flags, ///< noscrub or nodeep-scrub - pg_state, ///< e.g. snap-trimming + pg_state, ///< not active+clean + snap_trimming, ///< snap-trimming is in progress restricted_time, ///< time restrictions or busy CPU local_resources, ///< too many scrubbing PGs aborted, ///< scrub was aborted w/ unspecified reason @@ -252,6 +253,7 @@ struct formatter<Scrub::delay_cause_t> : ::fmt::formatter<std::string_view> { case replicas: desc = "replicas"; break; case flags: desc = "noscrub"; break; case pg_state: desc = "pg-state"; break; + case snap_trimming: desc = "snap-trim"; break; case restricted_time: desc = "time/load"; break; case local_resources: desc = "local-cnt"; break; case aborted: desc = "aborted"; break; |