| 736 | } |
| 737 | |
| 738 | void MDSDaemon::handle_command(const cref_t<MCommand> &m) |
| 739 | { |
| 740 | auto priv = m->get_connection()->get_priv(); |
| 741 | auto session = static_cast<Session *>(priv.get()); |
| 742 | ceph_assert(session != NULL); |
| 743 | |
| 744 | int r = 0; |
| 745 | cmdmap_t cmdmap; |
| 746 | CachedStackStringStream css; |
| 747 | auto& ss = *css; |
| 748 | bufferlist outbl; |
| 749 | |
| 750 | // If someone is using a closed session for sending commands (e.g. |
| 751 | // the ceph CLI) then we should feel free to clean up this connection |
| 752 | // as soon as we've sent them a response. |
| 753 | const bool live_session = |
| 754 | session->get_state_seq() > 0 && |
| 755 | mds_rank && |
| 756 | mds_rank->sessionmap.get_session(session->info.inst.name); |
| 757 | |
| 758 | if (!live_session) { |
| 759 | // This session only existed to issue commands, so terminate it |
| 760 | // as soon as we can. |
| 761 | ceph_assert(session->is_closed()); |
| 762 | session->get_connection()->mark_disposable(); |
| 763 | } |
| 764 | priv.reset(); |
| 765 | |
| 766 | if (!session->auth_caps.allow_all()) { |
| 767 | dout(1) << __func__ |
| 768 | << ": received command from client without `tell` capability: " |
| 769 | << *m->get_connection()->peer_addrs << dendl; |
| 770 | |
| 771 | ss << "permission denied"; |
| 772 | r = -EACCES; |
| 773 | } else if (m->cmd.empty()) { |
| 774 | r = -EINVAL; |
| 775 | ss << "no command given"; |
| 776 | } else if (!TOPNSPC::common::cmdmap_from_json(m->cmd, &cmdmap, ss)) { |
| 777 | r = -EINVAL; |
| 778 | } else { |
| 779 | cct->get_admin_socket()->queue_tell_command(m); |
| 780 | return; |
| 781 | } |
| 782 | |
| 783 | auto reply = make_message<MCommandReply>(r, ss.str()); |
| 784 | reply->set_tid(m->get_tid()); |
| 785 | reply->set_data(outbl); |
| 786 | m->get_connection()->send_message2(reply); |
| 787 | } |
| 788 | |
| 789 | void MDSDaemon::handle_mds_map(const cref_t<MMDSMap> &m) |
| 790 | { |
nothing calls this directly
no test coverage detected