The config observers may want to take locks that are ordered relative
to monc_lock.
We could simply drop monc_lock for this call, but that would implicitly
rely on a single-threaded dispatch to avoid having two incoming MConfig
messages get reordered. Explicitly putting it on a finisher is safer.
Note that we adjust the get_monmap_and_config() to start, drain, and stop
the finisher to ensure we have incoming config processed and applied
before returning.
Fixes: http://tracker.ceph.com/issues/24118
Signed-off-by: Sage Weil <sage@redhat.com>
void MonClient::handle_config(MConfig *m)
{
ldout(cct,10) << __func__ << " " << *m << dendl;
- cct->_conf->set_mon_vals(cct, m->config, config_cb);
- m->put();
+ finisher.queue(new FunctionContext([this, m](int r) {
+ cct->_conf->set_mon_vals(cct, m->config, config_cb);
+ m->put();
+ }));
got_config = true;
map_cond.Signal();
}