]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/osd/scrubber/scrub_machine.h
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / osd / scrubber / scrub_machine.h
index dbdc50d327adb59710b98774f40e2438309aeda1..038668fb264ca3988c1eb7541dae4d83069a4242 100644 (file)
 
 #include "common/version.h"
 #include "include/Context.h"
+#include "osd/scrubber_common.h"
 
 #include "scrub_machine_lstnr.h"
-#include "osd/scrubber_common.h"
 
-using namespace std::string_literals;
+/// a wrapper that sets the FSM state description used by the
+/// PgScrubber
+/// \todo consider using the full NamedState as in Peering
+struct NamedSimply {
+  explicit NamedSimply(ScrubMachineListener* scrubber, const char* name);
+};
 
 class PG;  // holding a pointer to that one - just for testing
 class PgScrubber;
+
 namespace Scrub {
 
 namespace sc = ::boost::statechart;
@@ -53,17 +59,21 @@ void on_event_discard(std::string_view nm);
     std::string_view print() const { return #E; }       \
   };
 
-MEV(RemotesReserved)  ///< all replicas have granted our reserve request
+/// all replicas have granted our reserve request
+MEV(RemotesReserved)
 
-MEV(ReservationFailure)         ///< a reservation request has failed
+/// a reservation request has failed
+MEV(ReservationFailure)
 
-MEV(StartScrub)         ///< initiate a new scrubbing session (relevant if we are a Primary)
+/// initiate a new scrubbing session (relevant if we are a Primary)
+MEV(StartScrub)
 
-MEV(AfterRepairScrub)  ///< initiate a new scrubbing session. Only triggered at Recovery
-                      ///< completion.
+/// initiate a new scrubbing session. Only triggered at Recovery completion
+MEV(AfterRepairScrub)
 
-MEV(Unblocked) ///< triggered when the PG unblocked an object that was marked for
-               ///< scrubbing. Via the PGScrubUnblocked op
+/// triggered when the PG unblocked an object that was marked for scrubbing.
+/// Via the PGScrubUnblocked op
+MEV(Unblocked)
 
 MEV(InternalSchedScrub)
 
@@ -71,48 +81,60 @@ MEV(SelectedChunkFree)
 
 MEV(ChunkIsBusy)
 
-MEV(ActivePushesUpd)  ///< Update to active_pushes. 'active_pushes' represents recovery
-                     ///< that is in-flight to the local ObjectStore
+/// Update to active_pushes. 'active_pushes' represents recovery that
+/// is in-flight to the local ObjectStore
+MEV(ActivePushesUpd)
 
-MEV(UpdatesApplied)  ///< (Primary only) all updates are committed
+/// (Primary only) all updates are committed
+MEV(UpdatesApplied)
 
-MEV(InternalAllUpdates)         ///< the internal counterpart of UpdatesApplied
+/// the internal counterpart of UpdatesApplied
+MEV(InternalAllUpdates)
 
-MEV(GotReplicas)  ///< got a map from a replica
+/// got a map from a replica
+MEV(GotReplicas)
 
-MEV(IntBmPreempted)  ///< internal - BuildMap preempted. Required, as detected within the
-                    ///< ctor
+/// internal - BuildMap preempted. Required, as detected within the ctor
+MEV(IntBmPreempted)
 
 MEV(InternalError)
 
 MEV(IntLocalMapDone)
 
-MEV(DigestUpdate)  ///< external. called upon success of a MODIFY op. See
-                  ///< scrub_snapshot_metadata()
-
-MEV(MapsCompared)  ///< maps_compare_n_cleanup() transactions are done
+/// external. called upon success of a MODIFY op. See
+/// scrub_snapshot_metadata()
+MEV(DigestUpdate)
 
-MEV(StartReplica)  ///< initiating replica scrub.
+/// initiating replica scrub
+MEV(StartReplica)
 
-MEV(StartReplicaNoWait)         ///< 'start replica' when there are no pending updates
+/// 'start replica' when there are no pending updates
+MEV(StartReplicaNoWait)
 
 MEV(SchedReplica)
 
-MEV(ReplicaPushesUpd)  ///< Update to active_pushes. 'active_pushes' represents recovery
-                      ///< that is in-flight to the local ObjectStore
+/// Update to active_pushes. 'active_pushes' represents recovery
+/// that is in-flight to the local ObjectStore
+MEV(ReplicaPushesUpd)
 
-MEV(FullReset) ///< guarantee that the FSM is in the quiescent state (i.e. NotActive)
+/// guarantee that the FSM is in the quiescent state (i.e. NotActive)
+MEV(FullReset)
 
-MEV(NextChunk) ///< finished handling this chunk. Go get the next one
+/// finished handling this chunk. Go get the next one
+MEV(NextChunk)
 
-MEV(ScrubFinished)  ///< all chunks handled
+/// all chunks handled
+MEV(ScrubFinished)
 
+//
+//  STATES
+//
 
 struct NotActive;          ///< the quiescent state. No active scrubbing.
 struct ReservingReplicas;   ///< securing scrub resources from replicas' OSDs
 struct ActiveScrubbing;            ///< the active state for a Primary. A sub-machine.
-struct ReplicaWaitUpdates;  ///< an active state for a replica. Waiting for all active
-                           ///< operations to finish.
+struct ReplicaWaitUpdates;  ///< an active state for a replica. Waiting for all
+                           ///< active operations to finish.
 struct ActiveReplica;      ///< an active state for a replica.
 
 
@@ -128,7 +150,6 @@ class ScrubMachine : public sc::state_machine<ScrubMachine, NotActive> {
   ScrubMachineListener* m_scrbr;
   std::ostream& gen_prefix(std::ostream& out) const;
 
-  std::string current_states_desc() const;
   void assert_not_active() const;
   [[nodiscard]] bool is_reserving() const;
   [[nodiscard]] bool is_accepting_updates() const;
@@ -137,32 +158,36 @@ class ScrubMachine : public sc::state_machine<ScrubMachine, NotActive> {
 /**
  *  The Scrubber's base (quiescent) state.
  *  Scrubbing is triggered by one of the following events:
- *  - (standard scenario for a Primary): 'StartScrub'. Initiates the OSDs resources
- *    reservation process. Will be issued by PG::scrub(), following a
+ *
+ *  - (standard scenario for a Primary): 'StartScrub'. Initiates the OSDs
+ *    resources reservation process. Will be issued by PG::scrub(), following a
  *    queued "PGScrub" op.
- *  - a special end-of-recovery Primary scrub event ('AfterRepairScrub') that is
- *    not required to reserve resources.
- *  - (for a replica) 'StartReplica' or 'StartReplicaNoWait', triggered by an incoming
- *    MOSDRepScrub message.
  *
- *  note (20.8.21): originally, AfterRepairScrub was triggering a scrub without waiting
- *   for replica resources to be acquired. But once replicas started using the
- *   resource-request to identify and tag the scrub session, this bypass cannot be
- *   supported anymore.
+ *  - a special end-of-recovery Primary scrub event ('AfterRepairScrub').
+ *
+ *  - (for a replica) 'StartReplica' or 'StartReplicaNoWait', triggered by
+ *    an incoming MOSDRepScrub message.
+ *
+ *  note (20.8.21): originally, AfterRepairScrub was triggering a scrub without
+ *  waiting for replica resources to be acquired. But once replicas started
+ *  using the resource-request to identify and tag the scrub session, this
+ *  bypass cannot be supported anymore.
  */
-struct NotActive : sc::state<NotActive, ScrubMachine> {
+struct NotActive : sc::state<NotActive, ScrubMachine>, NamedSimply {
   explicit NotActive(my_context ctx);
 
-  using reactions = mpl::list<sc::custom_reaction<StartScrub>,
-                             // a scrubbing that was initiated at recovery completion
-                             sc::custom_reaction<AfterRepairScrub>,
-                             sc::transition<StartReplica, ReplicaWaitUpdates>,
-                             sc::transition<StartReplicaNoWait, ActiveReplica>>;
+  using reactions =
+    mpl::list<sc::custom_reaction<StartScrub>,
+             // a scrubbing that was initiated at recovery completion:
+             sc::custom_reaction<AfterRepairScrub>,
+             sc::transition<StartReplica, ReplicaWaitUpdates>,
+             sc::transition<StartReplicaNoWait, ActiveReplica>>;
   sc::result react(const StartScrub&);
   sc::result react(const AfterRepairScrub&);
 };
 
-struct ReservingReplicas : sc::state<ReservingReplicas, ScrubMachine> {
+struct ReservingReplicas : sc::state<ReservingReplicas, ScrubMachine>,
+                          NamedSimply {
 
   explicit ReservingReplicas(my_context ctx);
   ~ReservingReplicas();
@@ -180,46 +205,55 @@ struct ReservingReplicas : sc::state<ReservingReplicas, ScrubMachine> {
 
 // the "active" sub-states
 
-struct RangeBlocked;  ///< the objects range is blocked
-struct PendingTimer;  ///< either delaying the scrub by some time and requeuing, or just
-                     ///< requeue
-struct NewChunk;      ///< select a chunk to scrub, and verify its availability
+/// the objects range is blocked
+struct RangeBlocked;
+
+/// either delaying the scrub by some time and requeuing, or just requeue
+struct PendingTimer;
+
+/// select a chunk to scrub, and verify its availability
+struct NewChunk;
+
 struct WaitPushes;
 struct WaitLastUpdate;
 struct BuildMap;
-struct DrainReplMaps;  ///< a problem during BuildMap. Wait for all replicas to report,
-                      ///< then restart.
-struct WaitReplicas;   ///< wait for all replicas to report
+
+/// a problem during BuildMap. Wait for all replicas to report, then restart.
+struct DrainReplMaps;
+
+/// wait for all replicas to report
+struct WaitReplicas;
+
 struct WaitDigestUpdate;
 
-struct ActiveScrubbing : sc::state<ActiveScrubbing, ScrubMachine, PendingTimer> {
+struct ActiveScrubbing
+    : sc::state<ActiveScrubbing, ScrubMachine, PendingTimer>, NamedSimply {
 
   explicit ActiveScrubbing(my_context ctx);
   ~ActiveScrubbing();
 
-  using reactions = mpl::list<
-    sc::custom_reaction<InternalError>,
-    sc::custom_reaction<FullReset>>;
+  using reactions = mpl::list<sc::custom_reaction<InternalError>,
+                             sc::custom_reaction<FullReset>>;
 
   sc::result react(const FullReset&);
   sc::result react(const InternalError&);
 };
 
-struct RangeBlocked : sc::state<RangeBlocked, ActiveScrubbing> {
+struct RangeBlocked : sc::state<RangeBlocked, ActiveScrubbing>, NamedSimply {
   explicit RangeBlocked(my_context ctx);
   using reactions = mpl::list<sc::transition<Unblocked, PendingTimer>>;
 
   Scrub::BlockedRangeWarning m_timeout;
 };
 
-struct PendingTimer : sc::state<PendingTimer, ActiveScrubbing> {
+struct PendingTimer : sc::state<PendingTimer, ActiveScrubbing>, NamedSimply {
 
   explicit PendingTimer(my_context ctx);
 
   using reactions = mpl::list<sc::transition<InternalSchedScrub, NewChunk>>;
 };
 
-struct NewChunk : sc::state<NewChunk, ActiveScrubbing> {
+struct NewChunk : sc::state<NewChunk, ActiveScrubbing>, NamedSimply {
 
   explicit NewChunk(my_context ctx);
 
@@ -233,11 +267,12 @@ struct NewChunk : sc::state<NewChunk, ActiveScrubbing> {
  * initiate the update process for this chunk
  *
  * Wait fo 'active_pushes' to clear.
- * 'active_pushes' represents recovery that is in-flight to the local Objectstore, hence
- * scrub waits until the correct data is readable (in-flight data to the Objectstore is
- * not readable until written to disk, termed 'applied' here)
+ * 'active_pushes' represents recovery that is in-flight to the local
+ * Objectstore, hence scrub waits until the correct data is readable
+ * (in-flight data to the Objectstore is not readable until written to
+ * disk, termed 'applied' here)
  */
-struct WaitPushes : sc::state<WaitPushes, ActiveScrubbing> {
+struct WaitPushes : sc::state<WaitPushes, ActiveScrubbing>, NamedSimply {
 
   explicit WaitPushes(my_context ctx);
 
@@ -246,21 +281,23 @@ struct WaitPushes : sc::state<WaitPushes, ActiveScrubbing> {
   sc::result react(const ActivePushesUpd&);
 };
 
-struct WaitLastUpdate : sc::state<WaitLastUpdate, ActiveScrubbing> {
+struct WaitLastUpdate : sc::state<WaitLastUpdate, ActiveScrubbing>,
+                       NamedSimply {
 
   explicit WaitLastUpdate(my_context ctx);
 
   void on_new_updates(const UpdatesApplied&);
 
-  using reactions = mpl::list<sc::custom_reaction<InternalAllUpdates>,
-                             sc::in_state_reaction<UpdatesApplied,
-                                                   WaitLastUpdate,
-                                                   &WaitLastUpdate::on_new_updates>>;
+  using reactions =
+    mpl::list<sc::custom_reaction<InternalAllUpdates>,
+             sc::in_state_reaction<UpdatesApplied,
+                                   WaitLastUpdate,
+                                   &WaitLastUpdate::on_new_updates>>;
 
   sc::result react(const InternalAllUpdates&);
 };
 
-struct BuildMap : sc::state<BuildMap, ActiveScrubbing> {
+struct BuildMap : sc::state<BuildMap, ActiveScrubbing>, NamedSimply {
   explicit BuildMap(my_context ctx);
 
   // possible error scenarios:
@@ -268,14 +305,12 @@ struct BuildMap : sc::state<BuildMap, ActiveScrubbing> {
   //   handled by our parent state;
   // - if preempted, we switch to DrainReplMaps, where we will wait for all
   //   replicas to send their maps before acknowledging the preemption;
-  // - an interval change will be handled by the relevant 'send-event' functions,
-  //   and will translated into a 'FullReset' event.
-  using reactions =
-    mpl::list<sc::transition<IntBmPreempted, DrainReplMaps>,
-             sc::transition<InternalSchedScrub, BuildMap>,  // looping, waiting
-                                                            // for the backend to
-                                                            // finish
-             sc::custom_reaction<IntLocalMapDone>>;
+  // - an interval change will be handled by the relevant 'send-event'
+  //   functions, and will translated into a 'FullReset' event.
+  using reactions = mpl::list<sc::transition<IntBmPreempted, DrainReplMaps>,
+                             // looping, waiting for the backend to finish:
+                             sc::transition<InternalSchedScrub, BuildMap>,
+                             sc::custom_reaction<IntLocalMapDone>>;
 
   sc::result react(const IntLocalMapDone&);
 };
@@ -283,41 +318,41 @@ struct BuildMap : sc::state<BuildMap, ActiveScrubbing> {
 /*
  *  "drain" scrub-maps responses from replicas
  */
-struct DrainReplMaps : sc::state<DrainReplMaps, ActiveScrubbing> {
+struct DrainReplMaps : sc::state<DrainReplMaps, ActiveScrubbing>, NamedSimply {
   explicit DrainReplMaps(my_context ctx);
 
   using reactions =
-    mpl::list<sc::custom_reaction<GotReplicas> // all replicas are accounted for
-             >;
+    // all replicas are accounted for:
+    mpl::list<sc::custom_reaction<GotReplicas>>;
 
   sc::result react(const GotReplicas&);
 };
 
-struct WaitReplicas : sc::state<WaitReplicas, ActiveScrubbing> {
+struct WaitReplicas : sc::state<WaitReplicas, ActiveScrubbing>, NamedSimply {
   explicit WaitReplicas(my_context ctx);
 
-  using reactions =
-    mpl::list<sc::custom_reaction<GotReplicas>,         // all replicas are accounted for
-             sc::transition<MapsCompared, WaitDigestUpdate>,
-             sc::custom_reaction<DigestUpdate>
-             >;
+  using reactions = mpl::list<
+    // all replicas are accounted for:
+    sc::custom_reaction<GotReplicas>,
+    sc::custom_reaction<DigestUpdate>>;
 
   sc::result react(const GotReplicas&);
   sc::result react(const DigestUpdate&);
   bool all_maps_already_called{false}; // see comment in react code
 };
 
-struct WaitDigestUpdate : sc::state<WaitDigestUpdate, ActiveScrubbing> {
+struct WaitDigestUpdate : sc::state<WaitDigestUpdate, ActiveScrubbing>,
+                         NamedSimply {
   explicit WaitDigestUpdate(my_context ctx);
 
   using reactions = mpl::list<sc::custom_reaction<DigestUpdate>,
-                            sc::custom_reaction<ScrubFinished>,
-                            sc::transition<NextChunk, PendingTimer>>;
+                             sc::custom_reaction<ScrubFinished>,
+                             sc::transition<NextChunk, PendingTimer>>;
   sc::result react(const DigestUpdate&);
   sc::result react(const ScrubFinished&);
 };
 
-// ----------------------------- the "replica active" states -----------------------
+// ----------------------------- the "replica active" states
 
 /*
  * Waiting for 'active_pushes' to complete
@@ -326,21 +361,21 @@ struct WaitDigestUpdate : sc::state<WaitDigestUpdate, ActiveScrubbing> {
  * - the details of the Primary's request were internalized by PgScrubber;
  * - 'active' scrubbing is set
  */
-struct ReplicaWaitUpdates : sc::state<ReplicaWaitUpdates, ScrubMachine> {
+struct ReplicaWaitUpdates : sc::state<ReplicaWaitUpdates, ScrubMachine>,
+                           NamedSimply {
   explicit ReplicaWaitUpdates(my_context ctx);
-  using reactions =
-    mpl::list<sc::custom_reaction<ReplicaPushesUpd>, sc::custom_reaction<FullReset>>;
+  using reactions = mpl::list<sc::custom_reaction<ReplicaPushesUpd>,
+                             sc::custom_reaction<FullReset>>;
 
   sc::result react(const ReplicaPushesUpd&);
   sc::result react(const FullReset&);
 };
 
 
-struct ActiveReplica : sc::state<ActiveReplica, ScrubMachine> {
+struct ActiveReplica : sc::state<ActiveReplica, ScrubMachine>, NamedSimply {
   explicit ActiveReplica(my_context ctx);
   using reactions = mpl::list<sc::custom_reaction<SchedReplica>,
-                             sc::custom_reaction<FullReset>,
-                             sc::transition<ScrubFinished, NotActive>>;
+                             sc::custom_reaction<FullReset>>;
 
   sc::result react(const SchedReplica&);
   sc::result react(const FullReset&);