]>
Commit | Line | Data |
---|---|---|
f67539c2 TL |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | ||
4 | #pragma once | |
5 | /** | |
6 | * \file the PgScrubber interface used by the scrub FSM | |
7 | */ | |
8 | #include "common/version.h" | |
9 | #include "include/Context.h" | |
20effc67 | 10 | #include "osd/osd_types.h" |
f67539c2 | 11 | |
1e59de90 TL |
12 | struct ScrubMachineListener; |
13 | ||
f67539c2 TL |
14 | namespace Scrub { |
15 | ||
f67539c2 TL |
16 | enum class PreemptionNoted { no_preemption, preempted }; |
17 | ||
18 | /// the interface exposed by the PgScrubber into its internal | |
19 | /// preemption_data object | |
20 | struct preemption_t { | |
21 | ||
20effc67 | 22 | virtual ~preemption_t() = default; |
f67539c2 | 23 | |
1e59de90 TL |
24 | preemption_t() = default; |
25 | preemption_t(const preemption_t&) = delete; | |
26 | preemption_t(preemption_t&&) = delete; | |
27 | ||
f67539c2 TL |
28 | [[nodiscard]] virtual bool is_preemptable() const = 0; |
29 | ||
30 | [[nodiscard]] virtual bool was_preempted() const = 0; | |
31 | ||
32 | virtual void adjust_parameters() = 0; | |
33 | ||
34 | /** | |
35 | * Try to preempt the scrub. | |
36 | * 'true' (i.e. - preempted) if: | |
37 | * preemptable && not already preempted | |
38 | */ | |
39 | virtual bool do_preempt() = 0; | |
40 | ||
41 | /** | |
42 | * disables preemptions. | |
43 | * Returns 'true' if we were already preempted | |
44 | */ | |
45 | virtual bool disable_and_test() = 0; | |
46 | }; | |
47 | ||
20effc67 TL |
48 | /// an aux used when blocking on a busy object. |
49 | /// Issues a log warning if still blocked after 'waittime'. | |
50 | struct blocked_range_t { | |
1e59de90 TL |
51 | blocked_range_t(OSDService* osds, |
52 | ceph::timespan waittime, | |
53 | ScrubMachineListener& scrubber, | |
54 | spg_t pg_id); | |
20effc67 TL |
55 | ~blocked_range_t(); |
56 | ||
57 | OSDService* m_osds; | |
1e59de90 TL |
58 | ScrubMachineListener& m_scrubber; |
59 | ||
60 | /// used to identify ourselves to the PG, when no longer blocked | |
61 | spg_t m_pgid; | |
20effc67 | 62 | Context* m_callbk; |
1e59de90 TL |
63 | |
64 | // once timed-out, we flag the OSD's scrub-queue as having | |
65 | // a problem. 'm_warning_issued' signals the need to clear | |
66 | // that OSD-wide flag. | |
67 | bool m_warning_issued{false}; | |
20effc67 TL |
68 | }; |
69 | ||
70 | using BlockedRangeWarning = std::unique_ptr<blocked_range_t>; | |
71 | ||
f67539c2 TL |
72 | } // namespace Scrub |
73 | ||
74 | struct ScrubMachineListener { | |
75 | ||
20effc67 TL |
76 | struct MsgAndEpoch { |
77 | MessageRef m_msg; | |
78 | epoch_t m_epoch; | |
79 | }; | |
80 | ||
81 | virtual ~ScrubMachineListener() = default; | |
82 | ||
1e59de90 TL |
83 | /// set the string we'd use in logs to convey the current state-machine |
84 | /// state. | |
85 | virtual void set_state_name(const char* name) = 0; | |
86 | ||
20effc67 TL |
87 | [[nodiscard]] virtual bool is_primary() const = 0; |
88 | ||
89 | virtual void select_range_n_notify() = 0; | |
f67539c2 | 90 | |
20effc67 | 91 | virtual Scrub::BlockedRangeWarning acquire_blocked_alarm() = 0; |
f67539c2 TL |
92 | |
93 | /// walk the log to find the latest update that affects our chunk | |
94 | virtual eversion_t search_log_for_updates() const = 0; | |
95 | ||
96 | virtual eversion_t get_last_update_applied() const = 0; | |
97 | ||
98 | virtual int pending_active_pushes() const = 0; | |
99 | ||
100 | virtual int build_primary_map_chunk() = 0; | |
101 | ||
102 | virtual int build_replica_map_chunk() = 0; | |
103 | ||
f67539c2 TL |
104 | virtual void on_init() = 0; |
105 | ||
106 | virtual void on_replica_init() = 0; | |
107 | ||
108 | virtual void replica_handling_done() = 0; | |
109 | ||
1e59de90 TL |
110 | /// the version of 'scrub_clear_state()' that does not try to invoke FSM |
111 | /// services (thus can be called from FSM reactions) | |
f67539c2 TL |
112 | virtual void clear_pgscrub_state() = 0; |
113 | ||
20effc67 | 114 | /* |
1e59de90 TL |
115 | * Send an 'InternalSchedScrub' FSM event either immediately, or - if |
116 | * 'm_need_sleep' is asserted - after a configuration-dependent timeout. | |
20effc67 | 117 | */ |
f67539c2 TL |
118 | virtual void add_delayed_scheduling() = 0; |
119 | ||
120 | /** | |
20effc67 TL |
121 | * Ask all replicas for their scrub maps for the current chunk. |
122 | */ | |
123 | virtual void get_replicas_maps(bool replica_can_preempt) = 0; | |
124 | ||
125 | virtual void on_digest_updates() = 0; | |
126 | ||
127 | /// the part that actually finalizes a scrub | |
128 | virtual void scrub_finish() = 0; | |
129 | ||
130 | /** | |
131 | * Prepare a MOSDRepScrubMap message carrying the requested scrub map | |
132 | * @param was_preempted - were we preempted? | |
1e59de90 TL |
133 | * @return the message, and the current value of 'm_replica_min_epoch' (which |
134 | * is used when sending the message, but will be overwritten before that). | |
f67539c2 | 135 | */ |
20effc67 TL |
136 | [[nodiscard]] virtual MsgAndEpoch prep_replica_map_msg( |
137 | Scrub::PreemptionNoted was_preempted) = 0; | |
f67539c2 | 138 | |
20effc67 TL |
139 | /** |
140 | * Send to the primary the pre-prepared message containing the requested map | |
141 | */ | |
142 | virtual void send_replica_map(const MsgAndEpoch& preprepared) = 0; | |
f67539c2 | 143 | |
20effc67 TL |
144 | /** |
145 | * Let the primary know that we were preempted while trying to build the | |
146 | * requested map. | |
147 | */ | |
148 | virtual void send_preempted_replica() = 0; | |
f67539c2 TL |
149 | |
150 | [[nodiscard]] virtual bool has_pg_marked_new_updates() const = 0; | |
151 | ||
152 | virtual void set_subset_last_update(eversion_t e) = 0; | |
153 | ||
154 | [[nodiscard]] virtual bool was_epoch_changed() const = 0; | |
155 | ||
156 | virtual Scrub::preemption_t& get_preemptor() = 0; | |
157 | ||
158 | /** | |
159 | * a "technical" collection of the steps performed once all | |
160 | * rep maps are available: | |
161 | * - the maps are compared | |
162 | * - the scrub region markers (start_ & end_) are advanced | |
20effc67 | 163 | * - callbacks and ops that were pending are allowed to run |
f67539c2 TL |
164 | */ |
165 | virtual void maps_compare_n_cleanup() = 0; | |
166 | ||
167 | /** | |
168 | * order the PgScrubber to initiate the process of reserving replicas' scrub | |
169 | * resources. | |
170 | */ | |
171 | virtual void reserve_replicas() = 0; | |
172 | ||
173 | virtual void unreserve_replicas() = 0; | |
174 | ||
20effc67 TL |
175 | virtual void set_scrub_begin_time() = 0; |
176 | ||
177 | virtual void set_scrub_duration() = 0; | |
178 | ||
179 | /** | |
180 | * No new scrub session will start while a scrub was initiate on a PG, | |
181 | * and that PG is trying to acquire replica resources. | |
182 | * set_reserving_now()/clear_reserving_now() let's the OSD scrub-queue know | |
183 | * we are busy reserving. | |
184 | */ | |
185 | virtual void set_reserving_now() = 0; | |
186 | virtual void clear_reserving_now() = 0; | |
187 | ||
188 | /** | |
189 | * Manipulate the 'I am being scrubbed now' Scrubber's flag | |
190 | */ | |
191 | virtual void set_queued_or_active() = 0; | |
192 | virtual void clear_queued_or_active() = 0; | |
193 | ||
1e59de90 TL |
194 | /** |
195 | * Our scrubbing is blocked, waiting for an excessive length of time for | |
196 | * our target chunk to be unlocked. We will set the corresponding flags, | |
197 | * both in the OSD_wide scrub-queue object, and in our own scrub-job object. | |
198 | * Both flags are used to report the unhealthy state in the log and in | |
199 | * response to scrub-queue queries. | |
200 | */ | |
201 | virtual void set_scrub_blocked(utime_t since) = 0; | |
202 | virtual void clear_scrub_blocked() = 0; | |
203 | ||
f67539c2 TL |
204 | /** |
205 | * the FSM interface into the "are we waiting for maps, either our own or from | |
206 | * replicas" state. | |
207 | * The FSM can only: | |
208 | * - mark the local map as available, and | |
209 | * - query status | |
210 | */ | |
211 | virtual void mark_local_map_ready() = 0; | |
212 | ||
213 | [[nodiscard]] virtual bool are_all_maps_available() const = 0; | |
214 | ||
215 | /// a log/debug interface | |
216 | virtual std::string dump_awaited_maps() const = 0; | |
20effc67 TL |
217 | |
218 | /// exposed to be used by the scrub_machine logger | |
219 | virtual std::ostream& gen_prefix(std::ostream& out) const = 0; | |
33c7a0ef TL |
220 | |
221 | /// sending cluster-log warnings | |
222 | virtual void log_cluster_warning(const std::string& msg) const = 0; | |
f67539c2 | 223 | }; |