From: David Zafman Date: Wed, 20 May 2015 21:09:02 +0000 (-0700) Subject: ceph-objectstore-tool, osd: Fix import handling X-Git-Tag: v0.94.7~9^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=c3f031a32df5d434721a2b00f2c8961759b1a916;p=ceph.git ceph-objectstore-tool, osd: Fix import handling Use same_interval_since set to zero to communicate that an import has happened and the correct value needs to be computed. Fixes: #10794 Signed-off-by: David Zafman (cherry picked from commit 70316541bbb115d9a35954bfba373cf1dc084b7e) Conflicts: src/osd/PG.cc (trivial) --- diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc index f210821a4cee..14097e5837ab 100644 --- a/src/osd/OSD.cc +++ b/src/osd/OSD.cc @@ -2973,8 +2973,11 @@ void OSD::build_past_intervals_parallel() PG *pg = i->second; epoch_t start, end; - if (!pg->_calc_past_interval_range(&start, &end, superblock.oldest_map)) + if (!pg->_calc_past_interval_range(&start, &end, superblock.oldest_map)) { + if (pg->info.history.same_interval_since == 0) + pg->info.history.same_interval_since = end; continue; + } dout(10) << pg->info.pgid << " needs " << start << "-" << end << dendl; pistate& p = pis[pg]; @@ -3060,6 +3063,24 @@ void OSD::build_past_intervals_parallel() } } + // Now that past_intervals have been recomputed let's fix the same_interval_since + // if it was cleared by import. + for (map::iterator i = pis.begin(); i != pis.end(); ++i) { + PG *pg = i->first; + pistate& p = i->second; + + // Verify same_interval_since is correct + if (pg->info.history.same_interval_since) { + assert(pg->info.history.same_interval_since == p.same_interval_since); + } else { + assert(p.same_interval_since); + dout(10) << __func__ << " fix same_interval_since " << p.same_interval_since << " pg " << *pg << dendl; + dout(10) << __func__ << " past_intervals " << pg->past_intervals << dendl; + // Fix it + pg->info.history.same_interval_since = p.same_interval_since; + } + } + // write info only at the end. this is necessary because we check // whether the past_intervals go far enough back or forward in time, // but we don't check for holes. we could avoid it by discarding diff --git a/src/osd/PG.cc b/src/osd/PG.cc index fc2f6689d439..b53c125693e3 100644 --- a/src/osd/PG.cc +++ b/src/osd/PG.cc @@ -657,7 +657,12 @@ bool PG::needs_backfill() const bool PG::_calc_past_interval_range(epoch_t *start, epoch_t *end, epoch_t oldest_map) { - *end = info.history.same_interval_since; + if (info.history.same_interval_since) { + *end = info.history.same_interval_since; + } else { + // PG must be imported, so let's calculate the whole range. + *end = osd->get_superblock().newest_map; + } // Do we already have the intervals we want? map::const_iterator pif = past_intervals.begin(); @@ -688,6 +693,8 @@ void PG::generate_past_intervals() epoch_t cur_epoch, end_epoch; if (!_calc_past_interval_range(&cur_epoch, &end_epoch, osd->get_superblock().oldest_map)) { + if (info.history.same_interval_since == 0) + info.history.same_interval_since = end_epoch; return; } @@ -742,6 +749,17 @@ void PG::generate_past_intervals() } } + // Verify same_interval_since is correct + if (info.history.same_interval_since) { + assert(info.history.same_interval_since == same_interval_since); + } else { + assert(same_interval_since); + dout(10) << __func__ << " fix same_interval_since " << same_interval_since << " pg " << *this << dendl; + dout(10) << __func__ << " past_intervals " << past_intervals << dendl; + // Fix it + info.history.same_interval_since = same_interval_since; + } + // record our work. dirty_info = true; dirty_big_info = true; @@ -4788,6 +4806,7 @@ void PG::start_peering_interval( info.history.same_interval_since = osdmap->get_epoch(); } else { std::stringstream debug; + assert(info.history.same_interval_since != 0); boost::scoped_ptr recoverable( get_is_recoverable_predicate()); bool new_interval = pg_interval_t::check_new_interval( diff --git a/src/tools/ceph_objectstore_tool.cc b/src/tools/ceph_objectstore_tool.cc index a6d885a57062..4f301f5fa42b 100644 --- a/src/tools/ceph_objectstore_tool.cc +++ b/src/tools/ceph_objectstore_tool.cc @@ -1824,7 +1824,9 @@ int get_pg_metadata(ObjectStore *store, bufferlist &bl, metadata_section &ms, } if (ms.map_epoch > sb.current_epoch) { - cerr << "ERROR: Export map_epoch " << ms.map_epoch << " > osd epoch " << sb.current_epoch << std::endl; + cerr << "ERROR: Export PG's map_epoch " << ms.map_epoch << " > OSD's epoch " << sb.current_epoch << std::endl; + cerr << "The OSD you are using is older than the exported PG" << std::endl; + cerr << "Either use another OSD or join selected OSD to cluster to update it first" << std::endl; return -EINVAL; } @@ -1878,8 +1880,20 @@ int get_pg_metadata(ObjectStore *store, bufferlist &bl, metadata_section &ms, } } + if (debug) { + cerr << "Import pgid " << ms.info.pgid << std::endl; + cerr << "Clearing past_intervals " << ms.past_intervals << std::endl; + cerr << "Zero same_interval_since " << ms.info.history.same_interval_since << std::endl; + } + + // Let osd recompute past_intervals and same_interval_since ms.past_intervals.clear(); - ms.info.history.same_interval_since = ms.map_epoch = sb.current_epoch; + ms.info.history.same_interval_since = 0; + + if (debug) + cerr << "Changing pg epoch " << ms.map_epoch << " to " << sb.current_epoch << std::endl; + + ms.map_epoch = sb.current_epoch; return 0; }