From 65d83f4a2a9304f77c78bb34344709e6a3fc33d5 Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Fri, 7 Apr 2017 15:28:37 +0800 Subject: [PATCH] mon/OSDMonitor: update creating epoch if target osd changed 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 --- src/mon/OSDMonitor.cc | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/src/mon/OSDMonitor.cc b/src/mon/OSDMonitor.cc index 9175f7b0b55..a9fedbdcc35 100644 --- a/src/mon/OSDMonitor.cc +++ b/src/mon/OSDMonitor.cc @@ -3233,19 +3233,41 @@ void OSDMonitor::scan_for_creating_pgs(const map& 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 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(); }