osd: add Mutex and flag to cover execution of handle_map_lock.

Fixes a crash when the cluster and client messenger both dispatch an
OSDMap and their handling gets intertwined.
This commit is contained in:
Greg Farnum 2010-07-29 10:24:14 -07:00
parent 28b54973b2
commit cec513ff47
2 changed files with 27 additions and 0 deletions

View File

@ -336,6 +336,7 @@ OSD::OSD(int id, Messenger *internal_messenger, Messenger *external_messenger, M
monc(mc),
logger(NULL), logger_started(false),
store(NULL),
map_in_progress(false),
logclient(cluster_messenger, &mc->monmap, mc),
whoami(id),
dev_path(dev), journal_path(jdev),
@ -378,6 +379,9 @@ OSD::OSD(int id, Messenger *internal_messenger, Messenger *external_messenger, M
remove_wq(this, &disk_tp)
{
monc->set_messenger(client_messenger);
if (client_messenger != cluster_messenger)
handle_map_lock = new Mutex("OSD::handle_map_lock");
else handle_map_lock = NULL;
osdmap = 0;
@ -2157,6 +2161,19 @@ void OSD::handle_osd_map(MOSDMap *m)
if (session)
session->put();
if (handle_map_lock) {
handle_map_lock->Lock();
if (map_in_progress) {
dout(15) << "waiting for prior handle_osd_map to complete" << dendl;
Cond map_cond;
while (map_in_progress)
map_cond.Wait(*handle_map_lock);
}
dout(10) << "locking handle_osd_map permissions" << dendl;
map_in_progress = true;
handle_map_lock->Unlock();
}
if (osdmap) {
dout(3) << "handle_osd_map epochs ["
<< m->get_first() << "," << m->get_last()
@ -2446,6 +2463,13 @@ void OSD::handle_osd_map(MOSDMap *m)
if (is_booting())
send_boot();
if (handle_map_lock) {
handle_map_lock->Lock();
map_in_progress = false;
dout(15) << "unlocking map_in_progress" << dendl;
handle_map_lock->Unlock();
}
}

View File

@ -112,6 +112,9 @@ protected:
bool logger_started;
ObjectStore *store;
Mutex *handle_map_lock; //to cover OSDMap update data when using multiple msgrs
bool map_in_progress;
LogClient logclient;
int whoami;