From ed6bc9f624d7ae38f1ed52b7135dbc281bd87854 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 5 Apr 2019 08:59:23 -0500 Subject: [PATCH] OSD: OSDMapRef access by multiple threads is unsafe 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 Signed-off-by: Zengran Zhang (cherry picked from commit 454c4cbae6b3363b80f52c7db5b6b7a5f3affd1a) # Conflicts: # src/osd/OSD.cc - trivial conflict from adjacent code in OSDService::shutdown() --- src/osd/OSD.cc | 5 ++++- src/osd/PG.cc | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc index 67825ce37e95..960352d4f4cd 100644 --- a/src/osd/OSD.cc +++ b/src/osd/OSD.cc @@ -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(); diff --git a/src/osd/PG.cc b/src/osd/PG.cc index dbe86cacb8a5..f7f536265c43 100644 --- a/src/osd/PG.cc +++ b/src/osd/PG.cc @@ -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, -- 2.47.3