]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
Build might_have_unfound set at activation
authorColin Patrick McCabe <cmccabe@alumni.cmu.edu>
Fri, 19 Nov 2010 23:02:46 +0000 (15:02 -0800)
committerSage Weil <sage@newdream.net>
Tue, 23 Nov 2010 21:52:21 +0000 (13:52 -0800)
The might_have_unfound set is used by the primary OSD during recovery.
This set tracks the OSDs which might have unfound objects that the
primary OSD needs. As we receive Missing from each OSD in
might_have_unfound, we will remove the OSD from the set.

When might_have_unfound is empty, we will mark objects as LOST if the
latest version of the object resided on an OSD marked as lost.

Signed-off-by: Colin McCabe <colinm@hq.newdream.net>
src/osd/PG.cc
src/osd/PG.h

index 7159f1c984b5d681957bdb0b85d0e68345505e69..a82900f57c6a9a7f824b94153ac8a022a3f4d789 100644 (file)
@@ -1192,6 +1192,7 @@ void PG::clear_primary_state()
   peer_last_complete_ondisk.clear();
   min_last_complete_ondisk = eversion_t();
   stray_purged.clear();
+  might_have_unfound.clear();
 
   last_update_ondisk = eversion_t();
 
@@ -1558,6 +1559,55 @@ void PG::do_peer(ObjectStore::Transaction& t, list<Context*>& tfin,
     finish_recovery(t, tfin);
 }
 
+/* Build the might_have_unfound set.
+ *
+ * This is used by the primary OSD during recovery.
+ *
+ * This set tracks the OSDs which might have unfound objects that the primary
+ * OSD needs. As we receive Missing from each OSD in might_have_unfound, we
+ * will remove the OSD from the set.
+ */
+void PG::build_might_have_unfound()
+{
+  assert(might_have_unfound.empty());
+  assert(is_primary());
+
+  dout(10) << __func__ << dendl;
+
+  // Make sure that we have past intervals.
+  if (info.history.same_acting_since > info.history.last_epoch_started &&
+      (past_intervals.empty() ||
+       past_intervals.begin()->first > info.history.last_epoch_started))
+    generate_past_intervals();
+
+  // We need to decide who might have unfound objects that we need
+  std::map<epoch_t,Interval>::const_reverse_iterator p = past_intervals.rbegin();
+  std::map<epoch_t,Interval>::const_reverse_iterator end = past_intervals.rend();
+  for (; p != end; ++p) {
+    const Interval &interval(p->second);
+    // We already have all the objects that exist at last_epoch_clean,
+    // so there's no need to look at earlier intervals.
+    if (interval.last < info.history.last_epoch_clean)
+      break;
+
+    // If nothing changed, we don't care about this interval.
+    if (!interval.maybe_went_rw)
+      continue;
+
+    std::vector<int>::const_iterator a = interval.acting.begin();
+    std::vector<int>::const_iterator a_end = interval.acting.end();
+    for (; a != a_end; ++a) {
+      might_have_unfound.insert(*a);
+    }
+  }
+
+  // The objects which are unfound on the primary can't be found on the
+  // primary itself.
+  might_have_unfound.erase(osd->whoami);
+
+  dout(15) << __func__ << ": built " << might_have_unfound << dendl;
+}
+
 void PG::activate(ObjectStore::Transaction& t, list<Context*>& tfin,
                  map<int, MOSDPGInfo*> *activator_map)
 {
@@ -1579,6 +1629,16 @@ void PG::activate(ObjectStore::Transaction& t, list<Context*>& tfin,
   else
     state_clear(PG_STATE_DEGRADED);
 
+  if (is_primary()) {
+    // If necessary, create might_have_unfound to help us find our unfound objects.
+    // NOTE: It's important that we build might_have_unfound before trimming the
+    // past intervals.
+    might_have_unfound.clear();
+    if (missing.have_missing()) {
+      build_might_have_unfound();
+    }
+  }
+
   info.history.last_epoch_started = osd->osdmap->get_epoch();
   trim_past_intervals();
   
index 2660dbfeaed2b1e80c4cf0ee26ce8f660833a884..7e3e75e62382ab0435029f878c41ac27ea23c1d3 100644 (file)
@@ -746,6 +746,10 @@ public:
   set<int>             peer_summary_requested;
   set<int>             peer_missing_requested;
   set<int>             stray_purged;  // i deleted these strays; ignore racing PGInfo from them
+
+  // primary-only, recovery-only state
+  set<int>             might_have_unfound;  // These osds might have objects on them
+                                           // which are unfound on the primary
   friend class OSD;
 
 
@@ -841,6 +845,7 @@ public:
   void do_peer(ObjectStore::Transaction& t, list<Context*>& tfin,
              map< int, map<pg_t,Query> >& query_map,
              map<int, MOSDPGInfo*> *activator_map=0);
+  void build_might_have_unfound();
   void activate(ObjectStore::Transaction& t, list<Context*>& tfin,
                map<int, MOSDPGInfo*> *activator_map=0);