From 1e4166a049be19975c5bfd3710c1bcd49093843d Mon Sep 17 00:00:00 2001 From: Samuel Just Date: Thu, 21 Mar 2019 12:36:39 -0700 Subject: [PATCH] osd/: pull NamedState and PGStateHistory out into PGStateUtils Signed-off-by: Samuel Just --- src/osd/CMakeLists.txt | 1 + src/osd/PG.cc | 60 ------------------------------- src/osd/PG.h | 61 +------------------------------ src/osd/PGStateUtils.cc | 77 +++++++++++++++++++++++++++++++++++++++ src/osd/PGStateUtils.h | 79 +++++++++++++++++++++++++++++++++++++++++ src/osd/PeeringState.cc | 11 ------ src/osd/PeeringState.h | 10 +----- src/osd/PrimaryLogPG.h | 1 - 8 files changed, 159 insertions(+), 141 deletions(-) create mode 100644 src/osd/PGStateUtils.cc create mode 100644 src/osd/PGStateUtils.h diff --git a/src/osd/CMakeLists.txt b/src/osd/CMakeLists.txt index 74eb6b9b682..0ab2876ad5a 100644 --- a/src/osd/CMakeLists.txt +++ b/src/osd/CMakeLists.txt @@ -34,6 +34,7 @@ set(osd_srcs mClockClientQueue.cc OpQueueItem.cc PeeringState.cc + PGStateUtils.cc ${CMAKE_SOURCE_DIR}/src/common/TrackedOp.cc ${CMAKE_SOURCE_DIR}/src/objclass/class_api.cc ${CMAKE_SOURCE_DIR}/src/mgr/OSDPerfMetricTypes.cc diff --git a/src/osd/PG.cc b/src/osd/PG.cc index 9850c76835e..fd84d6564f6 100644 --- a/src/osd/PG.cc +++ b/src/osd/PG.cc @@ -90,66 +90,6 @@ static ostream& _prefix(std::ostream *_dout, T *t) return t->gen_prefix(*_dout); } -void PGStateHistory::enter(PG* pg, const utime_t entime, const char* state) -{ - // Ignore trimming state machine for now - if (::strstr(state, "Trimming") != NULL) { - return; - } else if (pi != nullptr) { - pi->enter_state(entime, state); - } else { - // Store current state since we can't reliably take the PG lock here - if ( tmppi == nullptr) { - tmppi = std::unique_ptr(new PGStateInstance); - } - - thispg = pg; - tmppi->enter_state(entime, state); - } -} - -void PGStateHistory::exit(const char* state) { - // Ignore trimming state machine for now - // Do nothing if PG is being destroyed! - if (::strstr(state, "Trimming") != NULL || pg_in_destructor) { - return; - } else { - bool ilocked = false; - if(!thispg->is_locked()) { - thispg->lock(); - ilocked = true; - } - if (pi == nullptr) { - buffer.push_back(std::unique_ptr(tmppi.release())); - pi = buffer.back().get(); - pi->setepoch(thispg->get_osdmap_epoch()); - } - - pi->exit_state(ceph_clock_now()); - if (::strcmp(state, "Reset") == 0) { - this->reset(); - } - if(ilocked) { - thispg->unlock(); - } - } -} - -void PGStateHistory::dump(Formatter* f) const { - f->open_array_section("history"); - for (auto pi = buffer.begin(); pi != buffer.end(); ++pi) { - f->open_object_section("states"); - f->dump_stream("epoch") << (*pi)->this_epoch; - for (auto she : (*pi)->state_history) { - f->dump_string("state", std::get<2>(she)); - f->dump_stream("enter") << std::get<0>(she); - f->dump_stream("exit") << std::get<1>(she); - } - f->close_section(); - } - f->close_section(); -} - void PG::get(const char* tag) { int after = ++ref; diff --git a/src/osd/PG.h b/src/osd/PG.h index 8d94f867a7a..52b02012c38 100644 --- a/src/osd/PG.h +++ b/src/osd/PG.h @@ -23,7 +23,6 @@ #include #include #include -#include #include #include "include/mempool.h" @@ -51,7 +50,6 @@ #include #include #include -#include #include #include @@ -78,64 +76,6 @@ namespace Scrub { class Store; } -using state_history_entry = std::tuple; -using embedded_state = std::pair; - -struct PGStateInstance { - // Time spent in pg states - - void setepoch(const epoch_t current_epoch) { - this_epoch = current_epoch; - } - - void enter_state(const utime_t entime, const char* state) { - embedded_states.push(std::make_pair(entime, state)); - } - - void exit_state(const utime_t extime) { - embedded_state this_state = embedded_states.top(); - state_history.push_back(state_history_entry{ - this_state.first, extime, this_state.second}); - embedded_states.pop(); - } - - epoch_t this_epoch; - utime_t enter_time; - std::vector state_history; - std::stack embedded_states; -}; - -class PGStateHistory { - // Member access protected with the PG lock -public: - PGStateHistory() : buffer(10) {} - - void enter(PG* pg, const utime_t entime, const char* state); - - void exit(const char* state); - - void reset() { - pi = nullptr; - } - - void set_pg_in_destructor() { pg_in_destructor = true; } - - void dump(Formatter* f) const; - - string get_current_state() { - if (pi == nullptr) return "unknown"; - return std::get<1>(pi->embedded_states.top()); - } - -private: - bool pg_in_destructor = false; - PG* thispg = nullptr; - std::unique_ptr tmppi; - PGStateInstance* pi = nullptr; - boost::circular_buffer> buffer; - -}; - #ifdef PG_DEBUG_REFS #include "common/tracked_int_ptr.hpp" uint64_t get_with_id(PG *pg); @@ -257,6 +197,7 @@ struct PGPool { */ class PG : public DoutPrefixProvider { + friend class NamedState; friend class PeeringState; public: using PeeringCtx = PeeringState::PeeringCtx; diff --git a/src/osd/PGStateUtils.cc b/src/osd/PGStateUtils.cc new file mode 100644 index 00000000000..e6807a794a8 --- /dev/null +++ b/src/osd/PGStateUtils.cc @@ -0,0 +1,77 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#include "PGStateUtils.h" +#include "PG.h" + +/*------NamedState----*/ +NamedState::NamedState( + PG *pg_, const char *state_name_) + : state_name(state_name_), enter_time(ceph_clock_now()), pg(pg_) { + pg->pgstate_history.enter(pg, enter_time, state_name); +} + +NamedState::~NamedState() { + pg->pgstate_history.exit(state_name); +} + +/*---------PGStateHistory---------*/ +void PGStateHistory::enter(PG* pg, const utime_t entime, const char* state) +{ + // Ignore trimming state machine for now + if (::strstr(state, "Trimming") != NULL) { + return; + } else if (pi != nullptr) { + pi->enter_state(entime, state); + } else { + // Store current state since we can't reliably take the PG lock here + if ( tmppi == nullptr) { + tmppi = std::unique_ptr(new PGStateInstance); + } + + thispg = pg; + tmppi->enter_state(entime, state); + } +} + +void PGStateHistory::exit(const char* state) { + // Ignore trimming state machine for now + // Do nothing if PG is being destroyed! + if (::strstr(state, "Trimming") != NULL || pg_in_destructor) { + return; + } else { + bool ilocked = false; + if(!thispg->is_locked()) { + thispg->lock(); + ilocked = true; + } + if (pi == nullptr) { + buffer.push_back(std::unique_ptr(tmppi.release())); + pi = buffer.back().get(); + pi->setepoch(thispg->get_osdmap_epoch()); + } + + pi->exit_state(ceph_clock_now()); + if (::strcmp(state, "Reset") == 0) { + this->reset(); + } + if(ilocked) { + thispg->unlock(); + } + } +} + +void PGStateHistory::dump(Formatter* f) const { + f->open_array_section("history"); + for (auto pi = buffer.begin(); pi != buffer.end(); ++pi) { + f->open_object_section("states"); + f->dump_stream("epoch") << (*pi)->this_epoch; + for (auto she : (*pi)->state_history) { + f->dump_string("state", std::get<2>(she)); + f->dump_stream("enter") << std::get<0>(she); + f->dump_stream("exit") << std::get<1>(she); + } + f->close_section(); + } + f->close_section(); +} diff --git a/src/osd/PGStateUtils.h b/src/osd/PGStateUtils.h new file mode 100644 index 00000000000..8f38ede90e4 --- /dev/null +++ b/src/osd/PGStateUtils.h @@ -0,0 +1,79 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#pragma once + +#include "include/utime.h" + +#include +#include +#include + +class PG; + +struct NamedState { + const char *state_name; + utime_t enter_time; + PG* pg; + const char *get_state_name() { return state_name; } + NamedState(PG *pg_, const char *state_name_); + virtual ~NamedState(); +}; + +using state_history_entry = std::tuple; +using embedded_state = std::pair; + +struct PGStateInstance { + // Time spent in pg states + + void setepoch(const epoch_t current_epoch) { + this_epoch = current_epoch; + } + + void enter_state(const utime_t entime, const char* state) { + embedded_states.push(std::make_pair(entime, state)); + } + + void exit_state(const utime_t extime) { + embedded_state this_state = embedded_states.top(); + state_history.push_back(state_history_entry{ + this_state.first, extime, this_state.second}); + embedded_states.pop(); + } + + epoch_t this_epoch; + utime_t enter_time; + std::vector state_history; + std::stack embedded_states; +}; + +class PGStateHistory { + // Member access protected with the PG lock +public: + PGStateHistory() : buffer(10) {} + + void enter(PG* pg, const utime_t entime, const char* state); + + void exit(const char* state); + + void reset() { + pi = nullptr; + } + + void set_pg_in_destructor() { pg_in_destructor = true; } + + void dump(Formatter* f) const; + + string get_current_state() { + if (pi == nullptr) return "unknown"; + return std::get<1>(pi->embedded_states.top()); + } + +private: + bool pg_in_destructor = false; + PG* thispg = nullptr; + std::unique_ptr tmppi; + PGStateInstance* pi = nullptr; + boost::circular_buffer> buffer; + +}; diff --git a/src/osd/PeeringState.cc b/src/osd/PeeringState.cc index a580c2fdd43..2631cc3c662 100644 --- a/src/osd/PeeringState.cc +++ b/src/osd/PeeringState.cc @@ -28,17 +28,6 @@ void PeeringState::PeeringMachine::send_query( << "state<" << get_state_name() << ">: ") #define psdout(x) ldout(context< PeeringMachine >().cct, x) -/*------NamedState----*/ -PeeringState::NamedState::NamedState( - PG *pg_, const char *state_name_) - : state_name(state_name_), enter_time(ceph_clock_now()), pg(pg_) { - pg->pgstate_history.enter(pg, enter_time, state_name); -} - -PeeringState::NamedState::~NamedState() { - pg->pgstate_history.exit(state_name); -} - /*------Crashed-------*/ PeeringState::Crashed::Crashed(my_context ctx) : my_base(ctx), diff --git a/src/osd/PeeringState.h b/src/osd/PeeringState.h index 2cfbde01331..b3e054f9d8c 100644 --- a/src/osd/PeeringState.h +++ b/src/osd/PeeringState.h @@ -11,6 +11,7 @@ #include #include +#include "PGStateUtils.h" #include "PGPeeringEvent.h" #include "os/ObjectStore.h" #include "OSDMap.h" @@ -20,15 +21,6 @@ class PG; /* Encapsulates PG recovery process */ class PeeringState { public: - struct NamedState { - const char *state_name; - utime_t enter_time; - PG* pg; - const char *get_state_name() { return state_name; } - NamedState(PG *pg_, const char *state_name_); - virtual ~NamedState(); - }; - // [primary only] content recovery state struct BufferedRecoveryMessages { map > query_map; diff --git a/src/osd/PrimaryLogPG.h b/src/osd/PrimaryLogPG.h index 14d8eb8c702..9aed6243b1e 100644 --- a/src/osd/PrimaryLogPG.h +++ b/src/osd/PrimaryLogPG.h @@ -1589,7 +1589,6 @@ private: } } snap_trimmer_machine; - using NamedState = PeeringState::NamedState; struct WaitReservation; struct Trimming : boost::statechart::state< Trimming, SnapTrimmer, WaitReservation >, NamedState { typedef boost::mpl::list < -- 2.39.5