From aed09380ca314f75d4f01cda2ffb0c7b7c1c1dbc Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 30 Mar 2017 16:25:15 -0400 Subject: [PATCH] ceph-objectstore-tool: handle both new and legacy SnapSet format If we encounter legacy snaps, add to snapmapper then; otherwise, use the clone_snaps field in SnapSet to add all clones to snapmapper when we process the head object. Signed-off-by: Sage Weil --- src/tools/ceph_objectstore_tool.cc | 88 ++++++++++++++++++++++++------ src/tools/ceph_objectstore_tool.h | 9 ++- 2 files changed, 76 insertions(+), 21 deletions(-) diff --git a/src/tools/ceph_objectstore_tool.cc b/src/tools/ceph_objectstore_tool.cc index 5fc117209ec..23e06ecf04e 100644 --- a/src/tools/ceph_objectstore_tool.cc +++ b/src/tools/ceph_objectstore_tool.cc @@ -528,7 +528,7 @@ int ObjectStoreTool::export_file(ObjectStore *store, coll_t cid, ghobject_t &obj cerr << "object_info: " << objb.oi << std::endl; } - // XXX: Should we be checking for WHITEOUT or LOST in objb.oi.flags and skip? + // NOTE: we include whiteouts, lost, etc. ret = write_section(TYPE_OBJECT_BEGIN, objb, file_fd); if (ret < 0) @@ -817,9 +817,12 @@ int get_data(ObjectStore *store, coll_t coll, ghobject_t hoid, return 0; } -int get_attrs(ObjectStore *store, coll_t coll, ghobject_t hoid, - ObjectStore::Transaction *t, bufferlist &bl, - OSDriver &driver, SnapMapper &snap_mapper) +int get_attrs( + ObjectStore *store, coll_t coll, ghobject_t hoid, + ObjectStore::Transaction *t, bufferlist &bl, + OSDriver &driver, SnapMapper &snap_mapper, + const ghobject_t& last_head, + const set& last_clones) { bufferlist::iterator ebliter = bl.begin(); attr_section as; @@ -831,17 +834,47 @@ int get_attrs(ObjectStore *store, coll_t coll, ghobject_t hoid, // This could have been handled in the caller if we didn't need to // support exports that didn't include object_info_t in object_begin. - if (hoid.hobj.snap < CEPH_MAXSNAP && hoid.generation == ghobject_t::NO_GEN) { - map::iterator mi = as.data.find(OI_ATTR); - if (mi != as.data.end()) { - object_info_t oi(mi->second); - - if (debug) - cerr << "object_info " << oi << std::endl; - - OSDriver::OSTransaction _t(driver.get_transaction(t)); - set oi_snaps(oi.legacy_snaps.begin(), oi.legacy_snaps.end()); - snap_mapper.add_oid(hoid.hobj, oi_snaps, &_t); + if (hoid.generation == ghobject_t::NO_GEN) { + if (hoid.hobj.snap < CEPH_MAXSNAP) { + map::iterator mi = as.data.find(OI_ATTR); + if (mi != as.data.end()) { + object_info_t oi(mi->second); + + if (debug) + cerr << "object_info " << oi << std::endl; + + OSDriver::OSTransaction _t(driver.get_transaction(t)); + set oi_snaps(oi.legacy_snaps.begin(), oi.legacy_snaps.end()); + if (!oi_snaps.empty()) { + if (debug) + cerr << "\tsetting legacy snaps " << oi_snaps << std::endl; + snap_mapper.add_oid(hoid.hobj, oi_snaps, &_t); + } + } + } else { + if (hoid == last_head) { + map::iterator mi = as.data.find(SS_ATTR); + if (mi != as.data.end()) { + SnapSet snapset; + auto p = mi->second.begin(); + snapset.decode(p); + cout << "snapset " << snapset << std::endl; + if (!snapset.is_legacy()) { + for (auto& p : snapset.clone_snaps) { + hobject_t clone = hoid.hobj; + clone.snap = p.first; + set snaps(p.second.begin(), p.second.end()); + if (debug) + cerr << "\tsetting " << clone << " snaps " << snaps << std::endl; + OSDriver::OSTransaction _t(driver.get_transaction(t)); + assert(!snaps.empty()); + snap_mapper.add_oid(clone, snaps, &_t); + } + } + } else { + cerr << "missing SS_ATTR on " << hoid << std::endl; + } + } } } @@ -878,7 +911,9 @@ int get_omap(ObjectStore *store, coll_t coll, ghobject_t hoid, int ObjectStoreTool::get_object(ObjectStore *store, coll_t coll, bufferlist &bl, OSDMap &curmap, bool *skipped_objects, - ObjectStore::Sequencer &osr) + ObjectStore::Sequencer &osr, + ghobject_t *last_head, + set *last_clones) { ObjectStore::Transaction tran; ObjectStore::Transaction *t = &tran; @@ -928,6 +963,19 @@ int ObjectStoreTool::get_object(ObjectStore *store, coll_t coll, cout << "Write " << ob.hoid << std::endl; + // manage snap collection + if (ob.hoid.hobj.is_snap()) { + ghobject_t head = ob.hoid; + head.hobj = head.hobj.get_head(); + if (head == *last_head) { + last_clones->insert(ob.hoid); + } else { + *last_head = head; + last_clones->clear(); + } + last_clones->insert(ob.hoid); + } + bufferlist ebl; bool done = false; while(!done) { @@ -950,7 +998,8 @@ int ObjectStoreTool::get_object(ObjectStore *store, coll_t coll, break; case TYPE_ATTRS: if (dry_run) break; - ret = get_attrs(store, coll, ob.hoid, t, ebl, driver, mapper); + ret = get_attrs(store, coll, ob.hoid, t, ebl, driver, mapper, + *last_head, *last_clones); if (ret) return ret; break; case TYPE_OMAP_HDR: @@ -1279,6 +1328,8 @@ int ObjectStoreTool::do_import(ObjectStore *store, OSDSuperblock& sb, bool done = false; bool found_metadata = false; metadata_section ms; + ghobject_t last_head; + set last_clones; while(!done) { ret = read_section(&type, &ebl); if (ret) @@ -1291,7 +1342,8 @@ int ObjectStoreTool::do_import(ObjectStore *store, OSDSuperblock& sb, } switch(type) { case TYPE_OBJECT_BEGIN: - ret = get_object(store, coll, ebl, curmap, &skipped_objects, osr); + ret = get_object(store, coll, ebl, curmap, &skipped_objects, osr, + &last_head, &last_clones); if (ret) return ret; break; case TYPE_PG_METADATA: diff --git a/src/tools/ceph_objectstore_tool.h b/src/tools/ceph_objectstore_tool.h index 9c72483ba42..77fa968879d 100644 --- a/src/tools/ceph_objectstore_tool.h +++ b/src/tools/ceph_objectstore_tool.h @@ -31,9 +31,12 @@ class ObjectStoreTool : public RadosDump pg_info_t &info, epoch_t map_epoch, __u8 struct_ver, const OSDSuperblock& superblock, PastIntervals &past_intervals); - int get_object(ObjectStore *store, coll_t coll, - bufferlist &bl, OSDMap &curmap, bool *skipped_objects, - ObjectStore::Sequencer &osr); + int get_object( + ObjectStore *store, coll_t coll, + bufferlist &bl, OSDMap &curmap, bool *skipped_objects, + ObjectStore::Sequencer &osr, + ghobject_t *last_head, + set *last_clones); int export_file( ObjectStore *store, coll_t cid, ghobject_t &obj); int export_files(ObjectStore *store, coll_t coll); -- 2.39.5