}
}
+void DaemonServer::fetch_missing_metadata(const DaemonKey& key,
+ const entity_addr_t& addr)
+{
+ if (!daemon_state.is_updating(key) &&
+ (key.type == "osd" || key.type == "mds" || key.type == "mon")) {
+ std::ostringstream oss;
+ auto c = new MetadataUpdate(daemon_state, key);
+ if (key.type == "osd") {
+ oss << "{\"prefix\": \"osd metadata\", \"id\": "
+ << key.name<< "}";
+ } else if (key.type == "mds") {
+ c->set_default("addr", stringify(addr));
+ oss << "{\"prefix\": \"mds metadata\", \"who\": \""
+ << key.name << "\"}";
+ } else if (key.type == "mon") {
+ oss << "{\"prefix\": \"mon metadata\", \"id\": \""
+ << key.name << "\"}";
+ }
+ monc->start_mon_command({oss.str()}, {}, &c->outbl, &c->outs, c);
+ }
+}
+
bool DaemonServer::handle_open(const ref_t<MMgrOpen>& m)
{
- std::lock_guard l(lock);
+ std::unique_lock l(lock);
DaemonKey key = key_from_service(m->service_name,
m->get_connection()->get_peer_type(),
dout(2) << "ignoring open from " << key << " " << con->get_peer_addr()
<< "; not ready for session (expect reconnect)" << dendl;
con->mark_down();
+ l.unlock();
+ fetch_missing_metadata(key, m->get_source_addr());
return true;
}
}
dout(5) << "rejecting report from " << key << ", since we do not have its metadata now."
<< dendl;
// issue metadata request in background
- if (!daemon_state.is_updating(key) &&
- (key.type == "osd" || key.type == "mds" || key.type == "mon")) {
-
- std::ostringstream oss;
- auto c = new MetadataUpdate(daemon_state, key);
- if (key.type == "osd") {
- oss << "{\"prefix\": \"osd metadata\", \"id\": "
- << key.name<< "}";
-
- } else if (key.type == "mds") {
- c->set_default("addr", stringify(m->get_source_addr()));
- oss << "{\"prefix\": \"mds metadata\", \"who\": \""
- << key.name << "\"}";
-
- } else if (key.type == "mon") {
- oss << "{\"prefix\": \"mon metadata\", \"id\": \""
- << key.name << "\"}";
- } else {
- ceph_abort();
- }
-
- monc->start_mon_command({oss.str()}, {}, &c->outbl, &c->outs, c);
- }
+ fetch_missing_metadata(key, m->get_source_addr());
locker.lock();
bool DaemonServer::handle_command(const ref_t<MCommand>& m)
{
std::lock_guard l(lock);
- // a blank fsid in MCommand signals a legacy client sending a "mon-mgr" CLI
- // command.
- if (m->fsid != uuid_d()) {
- cct->get_admin_socket()->queue_tell_command(m);
+ auto cmdctx = std::make_shared<CommandContext>(m);
+ try {
+ return _handle_command(cmdctx);
+ } catch (const bad_cmd_get& e) {
+ cmdctx->reply(-EINVAL, e.what());
return true;
- } else {
- // legacy client; send to CLI processing
- auto cmdctx = std::make_shared<CommandContext>(m);
- try {
- return _handle_command(cmdctx);
- } catch (const bad_cmd_get& e) {
- cmdctx->reply(-EINVAL, e.what());
- return true;
- }
}
}
std::shared_ptr<CommandContext>& cmdctx)
{
MessageRef m;
+ bool admin_socket_cmd = false;
if (cmdctx->m_tell) {
m = cmdctx->m_tell;
+ // a blank fsid in MCommand signals a legacy client sending a "mon-mgr" CLI
+ // command.
+ admin_socket_cmd = (cmdctx->m_tell->fsid != uuid_d());
} else {
m = cmdctx->m_mgr;
}
dout(10) << "decoded-size=" << cmdctx->cmdmap.size() << " prefix=" << prefix << dendl;
- if (prefix == "get_command_descriptions") {
+ // this is just for mgr commands - admin socket commands will fall
+ // through and use the admin socket version of
+ // get_command_descriptions
+ if (prefix == "get_command_descriptions" && !admin_socket_cmd) {
dout(10) << "reading commands from python modules" << dendl;
const auto py_commands = py_modules.get_commands();
bool is_allowed = false;
ModuleCommand py_command;
- if (!mgr_cmd) {
+ if (admin_socket_cmd) {
+ // admin socket commands require all capabilities
+ is_allowed = session->caps.is_allow_all();
+ } else if (!mgr_cmd) {
// Resolve the command to the name of the module that will
// handle it (if the command exists)
auto py_commands = py_modules.get_py_commands();
<< "entity='" << session->entity_name << "' "
<< "cmd=" << cmdctx->cmd << ": dispatch";
+ if (admin_socket_cmd) {
+ cct->get_admin_socket()->queue_tell_command(cmdctx->m_tell);
+ return true;
+ }
+
// ----------------
// service map commands
if (prefix == "service dump") {
while (q != p->second.daemons.end()) {
DaemonKey key{p->first, q->first};
if (!daemon_state.exists(key)) {
- derr << "missing key " << key << dendl;
- ++q;
- continue;
+ if (ServiceMap::is_normal_ceph_entity(p->first)) {
+ dout(10) << "daemon " << key << " in service map but not in daemon state "
+ << "index -- force pruning" << dendl;
+ q = p->second.daemons.erase(q);
+ pending_service_map_dirty = pending_service_map.epoch;
+ } else {
+ derr << "missing key " << key << dendl;
+ ++q;
+ }
+
+ continue;
}
+
auto daemon = daemon_state.get(key);
std::lock_guard l(daemon->lock);
if (daemon->last_service_beacon == utime_t()) {