Select the given type for future ``encode`` or ``decode`` operations.
+.. option:: skip <bytes>
+
+ Seek <bytes> into the imported file before reading data structure, use
+ this with objects that have a preamble/header before the object of interest.
+
.. option:: decode
Decode the contents of the in-memory buffer into an instance of the
Example
=======
-Say you want to examine an attribute on an object stored by ``ceph-osd``. You can do::
+Say you want to examine an attribute on an object stored by ``ceph-osd``. You can do this:
+
+::
$ cd /mnt/osd.12/current/2.b_head
$ attr -l foo_bar_head_EFE6384B
"truncate_size": 0,
"watchers": {}}
+Alternatively, perhaps you wish to dump an internal CephFS metadata object, you might
+do that like this:
+
+::
+
+ $ rados -p metadata get mds_snaptable mds_snaptable.bin
+ $ ceph-dencoder type SnapServer skip 8 import mds_snaptable.bin decode dump_json
+ { "snapserver": { "last_snap": 1,
+ "pending_noop": [],
+ "snaps": [],
+ "need_to_purge": {},
+ "pending_create": [],
+ "pending_destroy": []}}
+
+
Availability
============
map<inodeno_t, list<pair<version_t, Context*> > > pending_ops;
void reset_state();
- void encode_server_state(bufferlist& bl) {
+ void encode_server_state(bufferlist& bl) const {
ENCODE_START(2, 2, bl);
::encode(anchor_map, bl);
::encode(pending_create, bl);
// for the dencoder
AnchorServer() : MDSTableServer(NULL, TABLE_ANCHOR) {}
void encode(bufferlist& bl) const {
- AnchorServer *me = const_cast<AnchorServer*>(this);
- me->encode_server_state(bl);
+ encode_server_state(bl);
+ }
+ void decode(bufferlist::iterator& bl) {
+ decode_server_state(bl);
}
- void decode(bufferlist::iterator& bl) { decode_server_state(bl); }
// server bits
void _prepare(bufferlist &bl, uint64_t reqid, int bymds);
projected_version = ++version;
dout(10) << "skip_inos now " << free << dendl;
}
+
+void InoTable::dump(Formatter *f) const
+{
+ f->open_object_section("inotable");
+
+ f->open_array_section("projected_free");
+ for (interval_set<inodeno_t>::const_iterator i = projected_free.begin(); i != projected_free.end(); ++i) {
+ f->open_object_section("range");
+ f->dump_int("start", (*i).first);
+ f->dump_int("len", (*i).second);
+ f->close_section();
+ }
+ f->close_section();
+
+ f->open_array_section("free");
+ for (interval_set<inodeno_t>::const_iterator i = free.begin(); i != free.end(); ++i) {
+ f->open_object_section("range");
+ f->dump_int("start", (*i).first);
+ f->dump_int("len", (*i).second);
+ f->close_section();
+ }
+ f->close_section();
+
+ f->close_section();
+}
+
+
+void InoTable::generate_test_instances(list<InoTable*>& ls)
+{
+ ls.push_back(new InoTable());
+}
void replay_reset();
void reset_state();
- void encode_state(bufferlist& bl) {
+ void encode_state(bufferlist& bl) const {
ENCODE_START(2, 2, bl);
::encode(free, bl);
ENCODE_FINISH(bl);
DECODE_FINISH(bl);
}
+ // To permit enc/decoding in isolation in dencoder
+ InoTable() : MDSTable(NULL, "inotable", true) {}
+ void encode(bufferlist& bl) const {
+ encode_state(bl);
+ }
+ void decode(bufferlist::iterator& bl) {
+ decode_state(bl);
+ }
+ void dump(Formatter *f) const;
+ static void generate_test_instances(list<InoTable*>& ls);
+
void skip_inos(inodeno_t i);
};
#define dout_subsys ceph_subsys_mds
#undef dout_prefix
-#define dout_prefix *_dout << "mds." << mds->get_nodeid() << "." << table_name << ": "
+#define dout_prefix *_dout << "mds." << (mds ? mds->get_nodeid() : -1) << "." << table_name << ": "
class C_MT_Save : public Context {
// child must overload these
virtual void reset_state() = 0;
virtual void decode_state(bufferlist::iterator& p) = 0;
- virtual void encode_state(bufferlist& bl) = 0;
+ virtual void encode_state(bufferlist& bl) const = 0;
};
#endif
void handle_request(MMDSTableRequest *m);
void do_server_update(bufferlist& bl);
- virtual void encode_server_state(bufferlist& bl) = 0;
+ virtual void encode_server_state(bufferlist& bl) const = 0;
virtual void decode_server_state(bufferlist::iterator& bl) = 0;
- void encode_state(bufferlist& bl) {
+ void encode_state(bufferlist& bl) const {
encode_server_state(bl);
::encode(pending_for_mds, bl);
}
last_checked_osdmap = version;
}
+
+
+void SnapServer::dump(Formatter *f) const
+{
+ f->open_object_section("snapserver");
+
+ f->dump_int("last_snap", last_snap.val);
+
+ f->open_array_section("pending_noop");
+ for(set<version_t>::const_iterator i = pending_noop.begin(); i != pending_noop.end(); ++i) {
+ f->dump_unsigned("version", *i);
+ }
+ f->close_section();
+
+ f->open_array_section("snaps");
+ for (map<snapid_t, SnapInfo>::const_iterator i = snaps.begin(); i != snaps.end(); ++i) {
+ f->open_object_section("snap");
+ i->second.dump(f);
+ f->close_section();
+ }
+ f->close_section();
+
+ f->open_object_section("need_to_purge");
+ for (map<int, set<snapid_t> >::const_iterator i = need_to_purge.begin(); i != need_to_purge.end(); ++i) {
+ stringstream pool_id;
+ pool_id << i->first;
+ f->open_array_section(pool_id.str().c_str());
+ for (set<snapid_t>::const_iterator s = i->second.begin(); s != i->second.end(); ++s) {
+ f->dump_unsigned("snapid", s->val);
+ }
+ f->close_section();
+ }
+ f->close_section();
+
+ f->open_array_section("pending_create");
+ for(map<version_t, SnapInfo>::const_iterator i = pending_create.begin(); i != pending_create.end(); ++i) {
+ f->open_object_section("snap");
+ f->dump_unsigned("version", i->first);
+ f->open_object_section("snapinfo");
+ i->second.dump(f);
+ f->close_section();
+ f->close_section();
+ }
+ f->close_section();
+
+ f->open_array_section("pending_destroy");
+ for(map<version_t, pair<snapid_t, snapid_t> >::const_iterator i = pending_destroy.begin(); i != pending_destroy.end(); ++i) {
+ f->open_object_section("snap");
+ f->dump_unsigned("version", i->first);
+ f->dump_unsigned("removed_snap", i->second.first);
+ f->dump_unsigned("seq", i->second.second);
+ f->close_section();
+ }
+ f->close_section();
+
+ f->close_section();
+}
+
+void SnapServer::generate_test_instances(list<SnapServer*>& ls)
+{
+ list<SnapInfo*> snapinfo_instances;
+ SnapInfo::generate_test_instances(snapinfo_instances);
+ SnapInfo populated_snapinfo = *(snapinfo_instances.back());
+ for (list<SnapInfo*>::iterator i = snapinfo_instances.begin(); i != snapinfo_instances.end(); ++i) {
+ delete *i;
+ }
+
+ SnapServer *blank = new SnapServer();
+ ls.push_back(blank);
+ SnapServer *populated = new SnapServer();
+ populated->last_snap = 123;
+ populated->snaps[456] = populated_snapinfo;
+ populated->need_to_purge[2].insert(012);
+ populated->pending_create[234] = populated_snapinfo;
+ populated->pending_destroy[345].first = 567;
+ populated->pending_destroy[345].second = 768;
+ populated->pending_noop.insert(890);
+
+ ls.push_back(populated);
+
+}
last_checked_osdmap(0) { }
void reset_state();
- void encode_server_state(bufferlist& bl) {
+ void encode_server_state(bufferlist& bl) const {
ENCODE_START(3, 3, bl);
::encode(last_snap, bl);
::encode(snaps, bl);
DECODE_FINISH(bl);
}
+ // To permit enc/decoding in isolation in dencoder
+ SnapServer() : MDSTableServer(NULL, TABLE_SNAP), last_checked_osdmap(0) {}
+ void encode(bufferlist& bl) const {
+ encode_server_state(bl);
+ }
+ void decode(bufferlist::iterator& bl) {
+ decode_server_state(bl);
+ }
+ void dump(Formatter *f) const;
+ static void generate_test_instances(list<SnapServer*>& ls);
+
// server bits
void _prepare(bufferlist &bl, uint64_t reqid, int bymds);
bool _is_prepared(version_t tid);
::decode(write_pos, bl);
::decode(layout, bl);
}
+
+ void dump(Formatter *f) const {
+ f->open_object_section("journal_header");
+ {
+ f->dump_string("magic", magic);
+ f->dump_unsigned("write_pos", write_pos);
+ f->dump_unsigned("expire_pos", expire_pos);
+ f->dump_unsigned("trimmed_pos", trimmed_pos);
+ f->open_object_section("layout");
+ {
+ f->dump_unsigned("stripe_unit", layout.fl_stripe_unit);
+ f->dump_unsigned("stripe_count", layout.fl_stripe_unit);
+ f->dump_unsigned("object_size", layout.fl_stripe_unit);
+ f->dump_unsigned("cas_hash", layout.fl_stripe_unit);
+ f->dump_unsigned("object_stripe_unit", layout.fl_stripe_unit);
+ f->dump_unsigned("pg_pool", layout.fl_stripe_unit);
+ }
+ f->close_section(); // layout
+ }
+ f->close_section(); // journal_header
+ }
+
+ static void generate_test_instances(list<Header*> &ls)
+ {
+ ls.push_back(new Header());
+ ls.push_back(new Header());
+ ls.back()->trimmed_pos = 1;
+ ls.back()->expire_pos = 2;
+ ls.back()->unused_field = 3;
+ ls.back()->write_pos = 4;
+ ls.back()->magic = "magique";
+ }
} last_written, last_committed;
WRITE_CLASS_ENCODER(Header)
}
struct Dencoder {
virtual ~Dencoder() {}
- virtual string decode(bufferlist bl) = 0;
+ virtual string decode(bufferlist bl, uint64_t seek) = 0;
virtual void encode(bufferlist& out, uint64_t features) = 0;
virtual void dump(ceph::Formatter *f) = 0;
virtual void copy() {
delete m_object;
}
- string decode(bufferlist bl) {
+ string decode(bufferlist bl, uint64_t seek) {
bufferlist::iterator p = bl.begin();
+ p.seek(seek);
try {
m_object->decode(p);
}
m_object->put();
}
- string decode(bufferlist bl) {
+ string decode(bufferlist bl, uint64_t seek) {
bufferlist::iterator p = bl.begin();
+ p.seek(seek);
try {
Message *n = decode_message(g_ceph_context, p);
if (!n)
Dencoder *den = NULL;
uint64_t features = CEPH_FEATURES_SUPPORTED_DEFAULT;
bufferlist encbl;
+ uint64_t skip = 0;
if (args.empty()) {
usage(cerr);
}
den = dencoders[cname];
den->generate();
+ } else if (*i == string("skip")) {
+ ++i;
+ if (i == args.end()) {
+ usage(cerr);
+ exit(1);
+ }
+ skip = atoi(*i);
} else if (*i == string("get_features")) {
cout << CEPH_FEATURES_SUPPORTED_DEFAULT << std::endl;
exit(0);
usage(cerr);
exit(1);
}
- err = den->decode(encbl);
+ err = den->decode(encbl, skip);
} else if (*i == string("copy_ctor")) {
if (!den) {
cerr << "must first select type with 'type <name>'" << std::endl;
cerr << "error reading " << *i << ": " << err << std::endl;
exit(1);
}
+
} else if (*i == string("export")) {
++i;
if (i == args.end()) {
TYPE(DBObjectMap::_Header)
TYPE(DBObjectMap::State)
+#include "osdc/Journaler.h"
+TYPE(Journaler::Header)
+
#include "mds/Anchor.h"
TYPE(Anchor)
TYPE_NOCOPY(Capability)
#include "mds/AnchorServer.h"
-TYPE(AnchorServer)
+TYPEWITHSTRAYDATA(AnchorServer)
+
+#include "mds/InoTable.h"
+TYPE(InoTable)
+
+#include "mds/SnapServer.h"
+TYPEWITHSTRAYDATA(SnapServer)
#include "mds/SessionMap.h"
TYPE(SessionMap)