* * @mds_spec one of ID, rank, GID, "*" * */
| 6746 | * |
| 6747 | */ |
| 6748 | int Client::mds_command( |
| 6749 | const std::string &mds_spec, |
| 6750 | const vector<string>& cmd, |
| 6751 | const bufferlist& inbl, |
| 6752 | bufferlist *outbl, |
| 6753 | string *outs, |
| 6754 | Context *onfinish, |
| 6755 | bool one_shot) |
| 6756 | { |
| 6757 | RWRef_t iref_reader(initialize_state, CLIENT_INITIALIZED); |
| 6758 | if (!iref_reader.is_state_satisfied()) |
| 6759 | return -ENOTCONN; |
| 6760 | |
| 6761 | std::unique_lock cl(client_lock); |
| 6762 | |
| 6763 | int r; |
| 6764 | r = authenticate(); |
| 6765 | if (r < 0) { |
| 6766 | return r; |
| 6767 | } |
| 6768 | |
| 6769 | r = fetch_fsmap(false); |
| 6770 | if (r < 0) { |
| 6771 | return r; |
| 6772 | } |
| 6773 | |
| 6774 | // Look up MDS target(s) of the command |
| 6775 | std::vector<mds_gid_t> targets; |
| 6776 | r = resolve_mds(mds_spec, &targets); |
| 6777 | if (r < 0) { |
| 6778 | return r; |
| 6779 | } |
| 6780 | |
| 6781 | // If daemons are laggy, we won't send them commands. If all |
| 6782 | // are laggy then we fail. |
| 6783 | std::vector<mds_gid_t> non_laggy; |
| 6784 | for (const auto& gid : targets) { |
| 6785 | const auto info = fsmap->get_info_gid(gid); |
| 6786 | if (!info.laggy()) { |
| 6787 | non_laggy.push_back(gid); |
| 6788 | } |
| 6789 | } |
| 6790 | if (non_laggy.size() == 0) { |
| 6791 | *outs = "All targeted MDS daemons are laggy"; |
| 6792 | return -ENOENT; |
| 6793 | } |
| 6794 | |
| 6795 | if (metadata.empty()) { |
| 6796 | // We are called on an unmounted client, so metadata |
| 6797 | // won't be initialized yet. |
| 6798 | populate_metadata(""); |
| 6799 | } |
| 6800 | |
| 6801 | ceph_tid_t multi_target_id = 0; |
| 6802 | if (non_laggy.size() > 1) { |
| 6803 | std::scoped_lock cmd_lock(command_lock); |
| 6804 | multi_target_id = command_table.get_new_multi_target_id(); |
| 6805 | } |