diff options
author | Samuel Just <samuel.just@dreamhost.com> | 2011-05-25 19:54:27 +0200 |
---|---|---|
committer | Samuel Just <samuel.just@dreamhost.com> | 2011-05-25 19:54:27 +0200 |
commit | d4bfd964fb38249a8514e7bdb681da229570adb2 (patch) | |
tree | 514d584ab53d139fa0a208a47dc9ae781ce5e223 | |
parent | mds: do not shift to EXCL or MIX while rdlocked (diff) | |
download | ceph-d4bfd964fb38249a8514e7bdb681da229570adb2.tar.xz ceph-d4bfd964fb38249a8514e7bdb681da229570adb2.zip |
PG: fix race in _activate_committed
Previously, _activate_committed would access the osdmap epoch racing
with handle_osd_map's osdmap update. This would allow a message to be
sent from a replica to the primary tagged with the same epoch as
last_warm_restart, though the event actually occured before
last_warm_restart. Thus the primary would fail to ignore the event and
transition to crashed.
Signed-off-by: Samuel Just <samuel.just@dreamhost.com>
-rw-r--r-- | src/osd/PG.cc | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/src/osd/PG.cc b/src/osd/PG.cc index 8e58d884dd7..a8c1b39aba8 100644 --- a/src/osd/PG.cc +++ b/src/osd/PG.cc @@ -1705,12 +1705,15 @@ void PG::replay_queued_ops() void PG::_activate_committed(epoch_t e) { - if (e < info.history.same_acting_since) { - dout(10) << "_activate_committed " << e << ", that was an old interval" << dendl; - return; - } + osd->map_lock.get_read(); + lock(); + epoch_t cur_epoch = osd->osdmap->get_epoch(); + entity_inst_t primary = osd->osdmap->get_cluster_inst(acting[0]); + osd->map_lock.put_read(); - if (is_primary()) { + if (e < last_warm_restart) { + dout(10) << "_activate_committed " << e << ", that was an old interval" << dendl; + } else if (is_primary()) { peer_activated.insert(osd->whoami); dout(10) << "_activate_committed " << e << " peer_activated now " << peer_activated << " last_epoch_started " << info.history.last_epoch_started @@ -1719,12 +1722,13 @@ void PG::_activate_committed(epoch_t e) all_activated_and_committed(); } else { dout(10) << "_activate_committed " << e << " telling primary" << dendl; - MOSDPGInfo *m = new MOSDPGInfo(osd->osdmap->get_epoch()); + MOSDPGInfo *m = new MOSDPGInfo(cur_epoch); PG::Info i = info; i.history.last_epoch_started = e; m->pg_info.push_back(i); - osd->cluster_messenger->send_message(m, osd->osdmap->get_cluster_inst(acting[0])); + osd->cluster_messenger->send_message(m, primary); } + unlock(); } /* |