diff --git a/src/tools/ceph_objectstore_tool.cc b/src/tools/ceph_objectstore_tool.cc index 657fca208367b..8ec8d0b1ce6b2 100644 --- a/src/tools/ceph_objectstore_tool.cc +++ b/src/tools/ceph_objectstore_tool.cc @@ -1482,7 +1482,8 @@ int get_object(ObjectStore *store, coll_t coll, bufferlist &bl, OSDMap &curmap) return 0; } -int get_pg_metadata(ObjectStore *store, bufferlist &bl, metadata_section &ms, const OSDSuperblock& sb) +int get_pg_metadata(ObjectStore *store, bufferlist &bl, metadata_section &ms, + const OSDSuperblock& sb, OSDMap& curmap) { bufferlist::iterator ebliter = bl.begin(); ms.decode(ebliter); @@ -1490,7 +1491,21 @@ int get_pg_metadata(ObjectStore *store, bufferlist &bl, metadata_section &ms, co #if DIAGNOSTIC Formatter *formatter = new JSONFormatter(true); cout << "struct_v " << (int)ms.struct_ver << std::endl; - cout << "epoch " << ms.map_epoch << std::endl; + cout << "map epoch " << ms.map_epoch << std::endl; + + formatter->open_object_section("importing OSDMap"); + ms.osdmap.dump(formatter); + formatter->close_section(); + formatter->flush(cout); + cout << std::endl; + + cout << "osd current epoch " << sb.current_epoch << std::endl; + formatter->open_object_section("current OSDMap"); + curmap.dump(formatter); + formatter->close_section(); + formatter->flush(cout); + cout << std::endl; + formatter->open_object_section("info"); ms.info.dump(formatter); formatter->close_section(); @@ -1504,26 +1519,46 @@ int get_pg_metadata(ObjectStore *store, bufferlist &bl, metadata_section &ms, co cout << std::endl; #endif + if (ms.map_epoch > sb.current_epoch) { + cerr << "ERROR: Export map_epoch " << ms.map_epoch << " > osd epoch " << sb.current_epoch << std::endl; + return 1; + } + // If the osdmap was present in the metadata we can check for splits. // Pool verified to exist for call to get_pg_num(). - if (ms.osdmap.get_epoch() != 0) { - OSDMap curmap; - bufferlist map_bl; - int ret = get_osdmap(store, sb.current_epoch, curmap, map_bl); - if (ret) - return ret; - spg_t parent(ms.info.pgid); - if (parent.is_split( - ms.osdmap.get_pg_num(ms.info.pgid.pgid.m_pool), - curmap.get_pg_num(ms.info.pgid.pgid.m_pool), - NULL)) { - // ms.past_intervals.clear(); - // ms.map_epoch = sb.current_epoch; - cerr << "Import failed due to a split" << std::endl; - return EINVAL; + if (ms.map_epoch < sb.current_epoch) { + bool found_map = false; + OSDMap findmap; + bufferlist findmap_bl; + int ret = get_osdmap(store, ms.map_epoch, findmap, findmap_bl); + if (ret == 0) + found_map = true; + + // Old export didn't include OSDMap + if (ms.osdmap.get_epoch() == 0) { + // If we found the map locally and an older export didn't have it, + // then we'll use the local one. + if (found_map) { + ms.osdmap = findmap; + } else { + cerr << "WARNING: No OSDMap in old export," + " some objects may be ignored due to a split" << std::endl; + } + } + + // If OSDMap is available check for splits + if (ms.osdmap.get_epoch()) { + spg_t parent(ms.info.pgid); + if (parent.is_split(ms.osdmap.get_pg_num(ms.info.pgid.pgid.m_pool), + curmap.get_pg_num(ms.info.pgid.pgid.m_pool), NULL)) { + cerr << "WARNING: Split occurred, some objects may be ignored" << std::endl; + } } } + ms.past_intervals.clear(); + ms.info.history.same_interval_since = ms.map_epoch = sb.current_epoch; + return 0; } @@ -1771,7 +1806,7 @@ int do_import(ObjectStore *store, OSDSuperblock& sb) if (ret) return ret; break; case TYPE_PG_METADATA: - ret = get_pg_metadata(store, ebl, ms, sb); + ret = get_pg_metadata(store, ebl, ms, sb, curmap); if (ret) return ret; found_metadata = true; break;