Ceph OSD state machine visualization
The Ceph OSD contains a state machine that encodes different operational aspects of the system such as peering and recovery. The state machine is built using the Boost Statechart library, and using a plugin for Clang that state machine can be programmatically extract and transformed into a graphical state machine representation. I’ve extracted the latest version of the state machine, and posted my notes on reproducing the visualization.
Is something broken with the script https://t.co/yyPooR1TBZ ? Why clang compilation instead?
— Gregory Farnum (@gregsfortytwo) March 5, 2018
Original post #
A similar extraction of the state machine was done at least as far back as 2013, but I cannot find any references online to extractions on newer versions of Ceph. The image below is an SVG of the latest version of Ceph (as of writing this), so for best viewing open it up in its own browser tab (direct link dot source).
Reproducing #
It was a bit of a challenge to get the tool to work. Here are the steps I took.
First build the Clang plugin. I used the version from
https://github.com/Larsjep/boost-statechart-viewer. Below I assume that the
plugin is cloned and built at /tmp/boost-statechart-viewer
. After installing
LLVM and Clang development packages, the plugin built fine by running make
.
Next you’ll need to prepare the Ceph tree:
- Initialize the Ceph source tree by running
cmake .
- I ran
make
just long enough for Boost to get built and setup - Generate the tracing dependencies
cd src/tracing; make
- Apply the small diff (shown below at end of this post)
Next create a file called src/osd/statechart.cc
that contains the following amalgamation of
source files that contain state chart bits (found with git grep -l statechart
):
#include "PG.h"
#include "PrimaryLogPG.h"
#include "PGPeeringEvent.h"
#include "PG.cc"
#include "PrimaryLogPG.cc"
#include "OSD.cc"
Then run the following command in src/osd
:
clang++ -I.. -I../../include -I../dmclock/support/src -std=c++1z \
-Wno-inconsistent-missing-override -Xclang -load -Xclang \
/tmp/boost-statechart-viewer/src/visualizer.so -Xclang -plugin -Xclang \
visualize-statechart -c -o statechart.o statechart.cc
There were a couple warnings and errors, but the tool still produced the graph
source file statechart.dot
which you can now transform into any graphical form
you want (e.g. dot -Tsvg statechart.dot > statechart.svg
).
diff --git a/src/osd/PG.cc b/src/osd/PG.cc
index 649f7177d2..03ae285587 100644
--- a/src/osd/PG.cc
+++ b/src/osd/PG.cc
@@ -87,7 +87,8 @@ const string fastinfo_key("_fastinfo");
template <class T>
static ostream& _prefix(std::ostream *_dout, T *t)
{
- return *_dout << t->gen_prefix();
+ return *_dout;
+ //return *_dout << t->gen_prefix();
}
MEMPOOL_DEFINE_OBJECT_FACTORY(PGPeeringEvent, pg_peering_evt, osd);
diff --git a/src/osd/PrimaryLogPG.cc b/src/osd/PrimaryLogPG.cc
index dc194e0372..bf3e8cfbd3 100644
--- a/src/osd/PrimaryLogPG.cc
+++ b/src/osd/PrimaryLogPG.cc
@@ -63,10 +63,10 @@
#define DOUT_PREFIX_ARGS this, osd->whoami, get_osdmap()
#undef dout_prefix
#define dout_prefix _prefix(_dout, this)
-template <typename T>
-static ostream& _prefix(std::ostream *_dout, T *pg) {
- return *_dout << pg->gen_prefix();
-}
+//template <typename T>
+//static ostream& _prefix(std::ostream *_dout, T *pg) {
+// return *_dout << pg->gen_prefix();
+//}
That’s it. If anyone knows of tools that can be used to produce visualizations that are easier to navigate in the browser, I’d love to hear about them.