]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
ceph-objectstore-tool: bring past_intervals up to date on import
authorSage Weil <sage@redhat.com>
Fri, 6 Oct 2017 19:21:43 +0000 (14:21 -0500)
committerSage Weil <sage@redhat.com>
Fri, 6 Oct 2017 19:26:56 +0000 (14:26 -0500)
We can't blinding fast-forward the pg epoch to the latest map without
also updating the pg history and PastIntervals.  Do that at import time.

Signed-off-by: Sage Weil <sage@redhat.com>
src/tools/ceph_objectstore_tool.cc

index 9e4a557304b5644a55b1a25ac51300fafce53d11..2e4884910c7317b062e1d5a00dbf4cf4e726c716 100644 (file)
@@ -1126,7 +1126,91 @@ int get_pg_metadata(ObjectStore *store, bufferlist &bl, metadata_section &ms,
   if (debug)
     cerr << "Changing pg epoch " << ms.map_epoch << " to " << sb.current_epoch << std::endl;
 
-  ms.map_epoch = sb.current_epoch;
+  // advance map and fill in PastIntervals
+  if (ms.map_epoch < sb.current_epoch) {
+    if (debug)
+      cerr << "Advancing PG from " << ms.map_epoch << " to " << sb.current_epoch
+          << std::endl;
+
+    OSDMap *startmap = new OSDMap;
+    startmap->deepish_copy_from(ms.osdmap);
+    OSDMapRef lastmap(startmap);
+
+    int up_primary, acting_primary;
+    vector<int> up, acting;
+    lastmap->pg_to_up_acting_osds(
+      ms.info.pgid.pgid, &up, &up_primary, &acting, &acting_primary);
+
+    while (ms.map_epoch < sb.current_epoch) {
+      ++ms.map_epoch;
+      if (ms.map_epoch < sb.oldest_map) {
+       // cheat!
+       ms.map_epoch = sb.oldest_map;
+      }
+
+      OSDMap *t = new OSDMap;
+      bufferlist nextmap_bl;
+      int ret = get_osdmap(store, ms.map_epoch, *t, nextmap_bl);
+      OSDMapRef nextmap(t);
+      if (ret < 0) {
+       cerr << "cannot load osdmap " << ms.map_epoch << std::endl;
+       return -EINVAL;
+      }
+      
+      int new_up_primary, new_acting_primary;
+      vector<int> new_up, new_acting;
+      nextmap->pg_to_up_acting_osds(
+       ms.info.pgid.pgid, &new_up, &new_up_primary, &new_acting,
+       &new_acting_primary);
+
+      // this is a bit imprecise, but sufficient?
+      struct min_size_predicate_t : public IsPGRecoverablePredicate {
+       const pg_pool_t *pi;
+       bool operator()(const set<pg_shard_t> &have) const {
+         return have.size() >= pi->min_size;
+       }
+       min_size_predicate_t(const pg_pool_t *i) : pi(i) {}
+      } min_size_predicate(nextmap->get_pg_pool(ms.info.pgid.pgid.pool()));
+
+
+      bool new_interval = PastIntervals::check_new_interval(
+       acting_primary,
+       new_acting_primary,
+       acting, new_acting,
+       up_primary,
+       new_up_primary,
+       up, new_up,
+       ms.info.history.same_interval_since,
+       ms.info.history.last_epoch_clean,
+       nextmap,
+       lastmap,
+       ms.info.pgid.pgid,
+       &min_size_predicate,
+       &ms.past_intervals,
+       &cerr);
+      if (new_interval) {
+       ms.info.history.same_interval_since = nextmap->get_epoch();
+       if (up != new_up) {
+         ms.info.history.same_up_since = nextmap->get_epoch();
+       }
+       if (acting_primary != new_acting_primary) {
+         ms.info.history.same_primary_since = nextmap->get_epoch();
+       }
+       if (pgid.pgid.is_split(lastmap->get_pg_num(ms.info.pgid.pgid.pool()),
+                              nextmap->get_pg_num(ms.info.pgid.pgid.pool()),
+                              nullptr)) {
+         ms.info.history.last_epoch_split = nextmap->get_epoch();
+       }
+       up = new_up;
+       acting = new_acting;
+       up_primary = new_up_primary;
+       acting_primary = new_acting_primary;
+      }
+      lastmap = nextmap;
+    }
+    if (debug)
+      cerr << "new PastIntervals " << ms.past_intervals << std::endl;
+  }
 
   return 0;
 }