summaryrefslogtreecommitdiffstats
path: root/src/osd
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/osd/PG.h1
-rw-r--r--src/osd/PeeringState.cc2
-rw-r--r--src/osd/PeeringState.h1
-rw-r--r--src/osd/SnapMapper.cc44
-rw-r--r--src/osd/SnapMapper.h4
-rw-r--r--src/osd/scrubber/pg_scrubber.cc10
-rw-r--r--src/osd/scrubber/scrub_job.cc31
-rw-r--r--src/osd/scrubber/scrub_job.h6
-rw-r--r--src/osd/scrubber/scrub_machine.cc4
-rw-r--r--src/osd/scrubber/scrub_machine.h4
-rw-r--r--src/osd/scrubber_common.h4
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;