std::ostream& PgScrubber::gen_prefix(std::ostream& out) const
{
- const auto fsm_state = m_fsm ? m_fsm->current_states_desc() : "- :";
if (m_pg) {
- return m_pg->gen_prefix(out) << "scrubber " << fsm_state << ": ";
+ return m_pg->gen_prefix(out) << "scrubber<" << m_fsm_state_name << ">: ";
} else {
- return out << " scrubber [~] " << fsm_state << ": ";
+ return out << " scrubber [" << m_pg_id << "]: ";
}
}
return m_pg->recovery_state.is_primary();
}
+ void set_state_name(const char* name) final
+ {
+ m_fsm_state_name = name;
+ }
+
void select_range_n_notify() final;
Scrub::BlockedRangeWarning acquire_blocked_alarm() final;
bool deep);
std::unique_ptr<Scrub::ScrubMachine> m_fsm;
+ /// the FSM state, as a string for logging
+ const char* m_fsm_state_name{nullptr};
const spg_t m_pg_id; ///< a local copy of m_pg->pg_id
OSDService* const m_osds;
const pg_shard_t m_pg_whoami; ///< a local copy of m_pg->pg_whoami;
auto pg_id = context<ScrubMachine>().m_pg_id; \
std::ignore = pg_id;
+NamedSimply::NamedSimply(ScrubMachineListener* scrubber, const char* name)
+{
+ scrubber->set_state_name(name);
+}
+
namespace Scrub {
// --------- trace/debug auxiliaries -------------------------------
dout(20) << " event: --^^^^---- " << nm << dendl;
}
-std::string ScrubMachine::current_states_desc() const
-{
- std::string sts{"<"};
- for (auto si = state_begin(); si != state_end(); ++si) {
- const auto& siw{*si}; // prevents a warning re side-effects
- // the '7' is the size of the 'scrub::'
- sts +=
- boost::core::demangle(typeid(siw).name()).substr(7, std::string::npos) +
- "/";
- }
- return sts + ">";
-}
-
void ScrubMachine::assert_not_active() const
{
ceph_assert(state_cast<const NotActive*>());
// ----------------------- NotActive -----------------------------------------
-NotActive::NotActive(my_context ctx) : my_base(ctx)
+NotActive::NotActive(my_context ctx)
+ : my_base(ctx)
+ , NamedSimply(context<ScrubMachine>().m_scrbr, "NotActive")
{
dout(10) << "-- state -->> NotActive" << dendl;
DECLARE_LOCALS; // 'scrbr' & 'pg_id' aliases
// ----------------------- ReservingReplicas ---------------------------------
-ReservingReplicas::ReservingReplicas(my_context ctx) : my_base(ctx)
+ReservingReplicas::ReservingReplicas(my_context ctx)
+ : my_base(ctx)
+ , NamedSimply(context<ScrubMachine>().m_scrbr, "ReservingReplicas")
{
dout(10) << "-- state -->> ReservingReplicas" << dendl;
DECLARE_LOCALS; // 'scrbr' & 'pg_id' aliases
// ----------------------- ActiveScrubbing -----------------------------------
-ActiveScrubbing::ActiveScrubbing(my_context ctx) : my_base(ctx)
+ActiveScrubbing::ActiveScrubbing(my_context ctx)
+ : my_base(ctx)
+ , NamedSimply(context<ScrubMachine>().m_scrbr, "ActiveScrubbing")
{
dout(10) << "-- state -->> ActiveScrubbing" << dendl;
DECLARE_LOCALS; // 'scrbr' & 'pg_id' aliases
* If that happens, all we can do is to issue a warning message to help
* with the debugging.
*/
-RangeBlocked::RangeBlocked(my_context ctx) : my_base(ctx)
+RangeBlocked::RangeBlocked(my_context ctx)
+ : my_base(ctx)
+ , NamedSimply(context<ScrubMachine>().m_scrbr, "Act/RangeBlocked")
{
dout(10) << "-- state -->> Act/RangeBlocked" << dendl;
DECLARE_LOCALS; // 'scrbr' & 'pg_id' aliases
/**
* Sleeping till timer reactivation - or just requeuing
*/
-PendingTimer::PendingTimer(my_context ctx) : my_base(ctx)
+PendingTimer::PendingTimer(my_context ctx)
+ : my_base(ctx)
+ , NamedSimply(context<ScrubMachine>().m_scrbr, "Act/PendingTimer")
{
dout(10) << "-- state -->> Act/PendingTimer" << dendl;
DECLARE_LOCALS; // 'scrbr' & 'pg_id' aliases
* - preemption data was set
* - epoch start was updated
*/
-NewChunk::NewChunk(my_context ctx) : my_base(ctx)
+NewChunk::NewChunk(my_context ctx)
+ : my_base(ctx)
+ , NamedSimply(context<ScrubMachine>().m_scrbr, "Act/NewChunk")
{
dout(10) << "-- state -->> Act/NewChunk" << dendl;
DECLARE_LOCALS; // 'scrbr' & 'pg_id' aliases
// ----------------------- WaitPushes -----------------------------------
-WaitPushes::WaitPushes(my_context ctx) : my_base(ctx)
+WaitPushes::WaitPushes(my_context ctx)
+ : my_base(ctx)
+ , NamedSimply(context<ScrubMachine>().m_scrbr, "Act/WaitPushes")
{
dout(10) << " -- state -->> Act/WaitPushes" << dendl;
post_event(ActivePushesUpd{});
// ----------------------- WaitLastUpdate -----------------------------------
-WaitLastUpdate::WaitLastUpdate(my_context ctx) : my_base(ctx)
+WaitLastUpdate::WaitLastUpdate(my_context ctx)
+ : my_base(ctx)
+ , NamedSimply(context<ScrubMachine>().m_scrbr, "Act/WaitLastUpdate")
{
dout(10) << " -- state -->> Act/WaitLastUpdate" << dendl;
post_event(UpdatesApplied{});
// ----------------------- BuildMap -----------------------------------
-BuildMap::BuildMap(my_context ctx) : my_base(ctx)
+BuildMap::BuildMap(my_context ctx)
+ : my_base(ctx)
+ , NamedSimply(context<ScrubMachine>().m_scrbr, "Act/BuildMap")
{
dout(10) << " -- state -->> Act/BuildMap" << dendl;
DECLARE_LOCALS; // 'scrbr' & 'pg_id' aliases
// ----------------------- DrainReplMaps -----------------------------------
-DrainReplMaps::DrainReplMaps(my_context ctx) : my_base(ctx)
+DrainReplMaps::DrainReplMaps(my_context ctx)
+ : my_base(ctx)
+ , NamedSimply(context<ScrubMachine>().m_scrbr, "Act/DrainReplMaps")
{
dout(10) << "-- state -->> Act/DrainReplMaps" << dendl;
// we may have got all maps already. Send the event that will make us check.
// ----------------------- WaitReplicas -----------------------------------
-WaitReplicas::WaitReplicas(my_context ctx) : my_base(ctx)
+WaitReplicas::WaitReplicas(my_context ctx)
+ : my_base(ctx)
+ , NamedSimply(context<ScrubMachine>().m_scrbr, "Act/WaitReplicas")
{
dout(10) << "-- state -->> Act/WaitReplicas" << dendl;
post_event(GotReplicas{});
// ----------------------- WaitDigestUpdate -----------------------------------
-WaitDigestUpdate::WaitDigestUpdate(my_context ctx) : my_base(ctx)
+WaitDigestUpdate::WaitDigestUpdate(my_context ctx)
+ : my_base(ctx)
+ , NamedSimply(context<ScrubMachine>().m_scrbr, "Act/WaitDigestUpdate")
{
DECLARE_LOCALS; // 'scrbr' & 'pg_id' aliases
dout(10) << "-- state -->> Act/WaitDigestUpdate" << dendl;
// ----------------------- ReplicaWaitUpdates --------------------------------
-ReplicaWaitUpdates::ReplicaWaitUpdates(my_context ctx) : my_base(ctx)
+ReplicaWaitUpdates::ReplicaWaitUpdates(my_context ctx)
+ : my_base(ctx)
+ , NamedSimply(context<ScrubMachine>().m_scrbr, "ReplicaWaitUpdates")
{
dout(10) << "-- state -->> ReplicaWaitUpdates" << dendl;
DECLARE_LOCALS; // 'scrbr' & 'pg_id' aliases
// ----------------------- ActiveReplica -----------------------------------
-ActiveReplica::ActiveReplica(my_context ctx) : my_base(ctx)
+ActiveReplica::ActiveReplica(my_context ctx)
+ : my_base(ctx)
+ , NamedSimply(context<ScrubMachine>().m_scrbr, "ActiveReplica")
{
DECLARE_LOCALS; // 'scrbr' & 'pg_id' aliases
dout(10) << "-- state -->> ActiveReplica" << dendl;
#include "scrub_machine_lstnr.h"
+/// 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;
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;
* 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 =
sc::result react(const AfterRepairScrub&);
};
-struct ReservingReplicas : sc::state<ReservingReplicas, ScrubMachine> {
+struct ReservingReplicas : sc::state<ReservingReplicas, ScrubMachine>,
+ NamedSimply {
explicit ReservingReplicas(my_context ctx);
~ReservingReplicas();
struct WaitDigestUpdate;
struct ActiveScrubbing
- : sc::state<ActiveScrubbing, ScrubMachine, PendingTimer> {
+ : sc::state<ActiveScrubbing, ScrubMachine, PendingTimer>, NamedSimply {
explicit ActiveScrubbing(my_context ctx);
~ActiveScrubbing();
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);
* (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);
sc::result react(const ActivePushesUpd&);
};
-struct WaitLastUpdate : sc::state<WaitLastUpdate, ActiveScrubbing> {
+struct WaitLastUpdate : sc::state<WaitLastUpdate, ActiveScrubbing>,
+ NamedSimply {
explicit WaitLastUpdate(my_context ctx);
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:
/*
* "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 =
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<
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>,
* - 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>>;
};
-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>,
virtual ~ScrubMachineListener() = default;
+ /// set the string we'd use in logs to convey the current state-machine
+ /// state.
+ virtual void set_state_name(const char* name) = 0;
+
[[nodiscard]] virtual bool is_primary() const = 0;
virtual void select_range_n_notify() = 0;