]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
OSD: OSDMapRef access by multiple threads is unsafe 27402/head
authorSage Weil <sage@redhat.com>
Fri, 5 Apr 2019 13:59:23 +0000 (08:59 -0500)
committerSage Weil <sage@redhat.com>
Fri, 5 Apr 2019 13:59:23 +0000 (08:59 -0500)
we update OSD::osdmap in OSD::_committed_osd_maps() which is executed
by objectstore's finisher thread. while PG::sched_scrub() is called
by OSD's sharded work queue's worker thread.and we push the osdmap
updates down to PGs OSD::consume_map() which is in turn called by
OSD::_committed_osd_maps() where osdmap is updated. so it does not big
deal if we are checking a stale CEPH_OSDMAP_NODEEP_SCRUB flag.
also this flag will be updated with the latest osdmap very soon.

Signed-off-by: Kefu Chai <kchai@redhat.com>
Signed-off-by: Zengran Zhang <zhangzengran@sangfor.com.cn>
(cherry picked from commit 454c4cbae6b3363b80f52c7db5b6b7a5f3affd1a)

# Conflicts:
# src/osd/OSD.cc
 - trivial conflict from adjacent code in OSDService::shutdown()

src/osd/OSD.cc
src/osd/PG.cc

index 67825ce37e950de40d8f8725d334be4f497db134..960352d4f4cdc7f4209d83cccb24c6bb42f06a83 100644 (file)
@@ -470,7 +470,7 @@ void OSDService::shutdown()
     recovery_request_timer.shutdown();
   }
 
-  osdmap = OSDMapRef();
+  publish_map(OSDMapRef());
   next_osdmap = OSDMapRef();
 }
 
@@ -3959,7 +3959,10 @@ int OSD::shutdown()
   monc->shutdown();
   osd_lock.Unlock();
 
+  map_lock.get_write();
   osdmap = OSDMapRef();
+  map_lock.put_write();
+
   for (auto s : shards) {
     std::lock_guard l(s->osdmap_lock);
     s->shard_osdmap = OSDMapRef();
index dbe86cacb8a595b80021d9dc9e6582ae78ea27b8..f7f536265c433399e09ed9aa3268dc7c802be68e 100644 (file)
@@ -4295,7 +4295,7 @@ bool PG::sched_scrub()
   time_for_deep = (time_for_deep || deep_coin_flip);
 
   //NODEEP_SCRUB so ignore time initiated deep-scrub
-  if (osd->osd->get_osdmap()->test_flag(CEPH_OSDMAP_NODEEP_SCRUB) ||
+  if (get_osdmap()->test_flag(CEPH_OSDMAP_NODEEP_SCRUB) ||
       pool.info.has_flag(pg_pool_t::FLAG_NODEEP_SCRUB)) {
     time_for_deep = false;
     nodeep_scrub = true;
@@ -4305,7 +4305,7 @@ bool PG::sched_scrub()
     ceph_assert(!scrubber.must_deep_scrub);
 
     //NOSCRUB so skip regular scrubs
-    if ((osd->osd->get_osdmap()->test_flag(CEPH_OSDMAP_NOSCRUB) ||
+    if ((get_osdmap()->test_flag(CEPH_OSDMAP_NOSCRUB) ||
         pool.info.has_flag(pg_pool_t::FLAG_NOSCRUB)) && !time_for_deep) {
       if (scrubber.reserved) {
         // cancel scrub if it is still in scheduling,