]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
ceph-objectstore-tool, osd: Fix import handling
authorDavid Zafman <dzafman@redhat.com>
Wed, 20 May 2015 21:09:02 +0000 (14:09 -0700)
committerDavid Zafman <dzafman@redhat.com>
Thu, 3 Mar 2016 23:13:36 +0000 (15:13 -0800)
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 <dzafman@redhat.com>
(cherry picked from commit 70316541bbb115d9a35954bfba373cf1dc084b7e)

Conflicts:
src/osd/PG.cc (trivial)

src/osd/OSD.cc
src/osd/PG.cc
src/tools/ceph_objectstore_tool.cc

index f210821a4ceeb5b1a19a7ada8a04ee35a4b681bd..14097e5837ab63e5df46e1b64f55d1d6809176ae 100644 (file)
@@ -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<PG*,pistate>::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
index fc2f6689d439f3b8621c956dc9cee0fc609546cd..b53c125693e36da420d87e9b7608c04ae4fa457d 100644 (file)
@@ -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<epoch_t,pg_interval_t>::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<IsPGRecoverablePredicate> recoverable(
       get_is_recoverable_predicate());
     bool new_interval = pg_interval_t::check_new_interval(
index a6d885a57062a794ecb3b5887f68b6e91691e3e0..4f301f5fa42b9612a06dd596e21b59e6c0521cc5 100644 (file)
@@ -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;
 }