summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Just <samuel.just@dreamhost.com>2011-05-25 19:54:27 +0200
committerSamuel Just <samuel.just@dreamhost.com>2011-05-25 19:54:27 +0200
commitd4bfd964fb38249a8514e7bdb681da229570adb2 (patch)
tree514d584ab53d139fa0a208a47dc9ae781ce5e223
parentmds: do not shift to EXCL or MIX while rdlocked (diff)
downloadceph-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.cc18
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();
}
/*