/// high/low OP priority
enum class scrub_prio_t : bool { low_priority = false, high_priority = true };
+/// Identifies a specific scrub activation within an interval,
+/// see ScrubPGgIF::m_current_token
+using act_token_t = uint32_t;
+
+/// "environment" preconditions affecting which PGs are eligible for scrubbing
+struct ScrubPreconds {
+ bool allow_requested_repair_only{false};
+ bool load_is_low{true};
+ bool time_permit{true};
+ bool only_deadlined{false};
+};
+
} // namespace Scrub
bool check_repair{false};
};
-ostream& operator<<(ostream& out, const requested_scrub_t& sf);
+std::ostream& operator<<(std::ostream& out, const requested_scrub_t& sf);
/**
* The interface used by the PG when requesting scrub-related info or services
*/
struct ScrubPgIF {
- virtual ~ScrubPgIF(){};
+ virtual ~ScrubPgIF() = default;
- friend ostream& operator<<(ostream& out, const ScrubPgIF& s) { return s.show(out); }
+ friend std::ostream& operator<<(std::ostream& out, const ScrubPgIF& s) { return s.show(out); }
- virtual ostream& show(ostream& out) const = 0;
+ virtual std::ostream& show(std::ostream& out) const = 0;
// --------------- triggering state-machine events:
virtual void send_replica_pushes_upd(epoch_t epoch_queued) = 0;
- virtual void send_start_replica(epoch_t epoch_queued) = 0;
+ virtual void send_start_replica(epoch_t epoch_queued, Scrub::act_token_t token) = 0;
+
+ virtual void send_sched_replica(epoch_t epoch_queued, Scrub::act_token_t token) = 0;
+
+ virtual void send_full_reset(epoch_t epoch_queued) = 0;
+
+ virtual void send_chunk_free(epoch_t epoch_queued) = 0;
+
+ virtual void send_chunk_busy(epoch_t epoch_queued) = 0;
+
+ virtual void send_local_map_done(epoch_t epoch_queued) = 0;
+
+ virtual void send_get_next_chunk(epoch_t epoch_queued) = 0;
- virtual void send_sched_replica(epoch_t epoch_queued) = 0;
+ virtual void send_scrub_is_finished(epoch_t epoch_queued) = 0;
+
+ virtual void send_maps_compared(epoch_t epoch_queued) = 0;
+
+ virtual void on_applied_when_primary(const eversion_t &applied_version) = 0;
// --------------------------------------------------
*/
[[nodiscard]] virtual bool is_scrub_active() const = 0;
+ /**
+ * 'true' until after the FSM processes the 'scrub-finished' event,
+ * and scrubbing is completely cleaned-up.
+ *
+ * In other words - holds longer than is_scrub_active(), thus preventing
+ * a rescrubbing of the same PG while the previous scrub has not fully
+ * terminated.
+ */
+ [[nodiscard]] virtual bool is_queued_or_active() const = 0;
+
+ /**
+ * Manipulate the 'scrubbing request has been queued, or - we are
+ * actually scrubbing' Scrubber's flag
+ */
+ virtual void set_queued_or_active() = 0;
+ virtual void clear_queued_or_active() = 0;
+
/// are we waiting for resource reservation grants form our replicas?
[[nodiscard]] virtual bool is_reserving() const = 0;
virtual void handle_query_state(ceph::Formatter* f) = 0;
- virtual void dump(ceph::Formatter* f) const = 0;
+ virtual pg_scrubbing_status_t get_schedule() const = 0;
+
+ virtual void dump_scrubber(ceph::Formatter* f,
+ const requested_scrub_t& request_flags) const = 0;
/**
* Return true if soid is currently being scrubbed and pending IOs should block.
virtual void add_callback(Context* context) = 0;
- /// should we requeue blocked ops?
- [[nodiscard]] virtual bool should_requeue_blocked_ops(
- eversion_t last_recovery_applied) const = 0;
-
/// add to scrub statistics, but only if the soid is below the scrub start
virtual void stats_of_handled_objects(const object_stat_sum_t& delta_stats,
const hobject_t& soid) = 0;
*/
virtual bool reserve_local() = 0;
+ /**
+ * Register/de-register with the OSD scrub queue
+ *
+ * Following our status as Primary or replica.
+ */
+ virtual void on_primary_change(const requested_scrub_t& request_flags) = 0;
+
+ /**
+ * Recalculate the required scrub time.
+ *
+ * This function assumes that the queue registration status is up-to-date,
+ * i.e. the OSD "knows our name" if-f we are the Primary.
+ */
+ virtual void update_scrub_job(const requested_scrub_t& request_flags) = 0;
+
+ virtual void on_maybe_registration_change(const requested_scrub_t& request_flags) = 0;
+
// on the replica:
virtual void handle_scrub_reserve_request(OpRequestRef op) = 0;
virtual void handle_scrub_reserve_release(OpRequestRef op) = 0;
virtual void handle_scrub_reserve_grant(OpRequestRef op, pg_shard_t from) = 0;
virtual void handle_scrub_reserve_reject(OpRequestRef op, pg_shard_t from) = 0;
- virtual void reg_next_scrub(const requested_scrub_t& request_flags) = 0;
- virtual void unreg_next_scrub() = 0;
+ virtual void rm_from_osd_scrubbing() = 0;
+
virtual void scrub_requested(scrub_level_t scrub_level,
scrub_type_t scrub_type,
requested_scrub_t& req_flags) = 0;
+
+ // --------------- debugging via the asok ------------------------------
+
+ virtual int asok_debug(std::string_view cmd,
+ std::string param,
+ Formatter* f,
+ std::stringstream& ss) = 0;
};