]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
mon/OSDMonitor: update creating epoch if target osd changed
authorKefu Chai <kchai@redhat.com>
Fri, 7 Apr 2017 07:28:37 +0000 (15:28 +0800)
committerKefu Chai <kchai@redhat.com>
Fri, 7 Apr 2017 07:28:55 +0000 (15:28 +0800)
there is chance that the acting_primary of a PG being created changes
across osdmap updates, in that case we should update the new creating_pgs
with the mapping's epoch, not the stale one when the PG was originally
created. otherwise the new target OSD won't get the pg-create message.

Fixes: http://tracker.ceph.com/issues/19515
Signed-off-by: Kefu Chai <kchai@redhat.com>
src/mon/OSDMonitor.cc

index 9175f7b0b558f0512595d262796254b46d8c6c09..a9fedbdcc355c74e2efa25c45e5dea01a7e35ce7 100644 (file)
@@ -3233,19 +3233,41 @@ void OSDMonitor::scan_for_creating_pgs(const map<int64_t,pg_pool_t>& pools,
 
 void OSDMonitor::update_creating_pgs()
 {
-  creating_pgs_by_osd_epoch.clear();
+  decltype(creating_pgs_by_osd_epoch) new_pgs_by_osd_epoch;
   std::lock_guard<std::mutex> l(creating_pgs_lock);
-  for (const auto& pg : creating_pgs.pgs) {
+  for (auto& pg : creating_pgs.pgs) {
     int acting_primary = -1;
     auto pgid = pg.first;
-    auto created = pg.second.first;
+    auto& created = pg.second.first;
     mapping.get(pgid, nullptr, nullptr, nullptr, &acting_primary);
-    if (acting_primary >= 0) {
-      dout(10) << __func__ << " will instruct osd." << acting_primary
-              << " to create " << pgid << dendl;
-      creating_pgs_by_osd_epoch[acting_primary][created].insert(pgid);
+    if (acting_primary < 0) {
+      continue;
+    }
+    // check the previous creating_pgs, look for the target to whom the pg was
+    // previously mapped
+    for (const auto& pgs_by_epoch : creating_pgs_by_osd_epoch) {
+      const auto last_acting_primary = pgs_by_epoch.first;
+      for (auto& pgs: pgs_by_epoch.second) {
+       if (pgs.second.count(pgid)) {
+         if (last_acting_primary != acting_primary) {
+           dout(20) << __func__ << " " << pgid << " "
+                    << " acting_primary:" << last_acting_primary
+                    << " -> " << acting_primary << dendl;
+           // note epoch if the target of the create message changed.
+           // creating_pgs is updated here instead of in
+           // scan_for_creating_pgs() because we don't have the updated pg
+           // mapping by then.
+           created = mapping.get_epoch();
+          }
+          break;
+        }
+      }
     }
+    dout(10) << __func__ << " will instruct osd." << acting_primary
+            << " to create " << pgid << dendl;
+    new_pgs_by_osd_epoch[acting_primary][created].insert(pgid);
   }
+  creating_pgs_by_osd_epoch = std::move(new_pgs_by_osd_epoch);
   creating_pgs_epoch = mapping.get_epoch();
 }