1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
6 A Crimson-wise version of the src/common/admin_socket.h
8 Note: assumed to be running on a single core.
12 #include <string_view>
14 #include <seastar/core/future.hh>
15 #include <seastar/core/gate.hh>
16 #include <seastar/core/iostream.hh>
17 #include <seastar/core/shared_mutex.hh>
18 #include <seastar/core/shared_ptr.hh>
19 #include <seastar/net/api.hh>
21 #include "common/cmdparse.h"
22 #include "include/buffer.h"
23 #include "crimson/net/Fwd.h"
25 using namespace std::literals
;
29 namespace crimson::admin
{
33 struct tell_result_t
{
37 tell_result_t() = default;
38 tell_result_t(int ret
, std::string
&& err
);
39 tell_result_t(int ret
, std::string
&& err
, ceph::bufferlist
&& out
);
41 * create a \c tell_result_t indicating the successful completion
44 * \param formatter the content of formatter will be flushed to the
47 tell_result_t(std::unique_ptr
<Formatter
> formatter
);
51 * An abstract class to be inherited by implementations of asock hooks
53 class AdminSocketHook
{
55 AdminSocketHook(std::string_view prefix
,
56 std::string_view desc
,
57 std::string_view help
) :
58 prefix
{prefix
}, desc
{desc
}, help
{help
}
61 * handle command defined by cmdmap
63 * \param cmdmap dictionary holding the named parameters
64 * \param format the expected format of the output
65 * \param input the binary input of the command
66 * \pre \c cmdmap should be validated with \c desc
67 * \retval an instance of \c tell_result_t
68 * \note a negative \c ret should be set to indicate that the hook fails to
69 * fulfill the command either because of an invalid input or other
70 * failures. in that case, a brief reason of the failure should
71 * noted in \c err in the returned value
73 virtual seastar::future
<tell_result_t
> call(const cmdmap_t
& cmdmap
,
74 std::string_view format
,
75 ceph::bufferlist
&& input
) const = 0;
76 virtual ~AdminSocketHook() {}
77 const std::string_view prefix
;
78 const std::string_view desc
;
79 const std::string_view help
;
82 class AdminSocket
: public seastar::enable_lw_shared_from_this
<AdminSocket
> {
84 AdminSocket() = default;
85 ~AdminSocket() = default;
87 AdminSocket(const AdminSocket
&) = delete;
88 AdminSocket
& operator=(const AdminSocket
&) = delete;
89 AdminSocket(AdminSocket
&&) = delete;
90 AdminSocket
& operator=(AdminSocket
&&) = delete;
93 * create the async Seastar thread that handles asok commands arriving
96 seastar::future
<> start(const std::string
& path
);
98 seastar::future
<> stop();
101 * register an admin socket hook
103 * Commands (APIs) are registered under a command string. Incoming
104 * commands are split by spaces and matched against the longest
105 * registered command. For example, if 'foo' and 'foo bar' are
106 * registered, and an incoming command is 'foo bar baz', it is
107 * matched with 'foo bar', while 'foo fud' will match 'foo'.
109 * \param hook a hook which includes its identifying command string, the
110 * expected call syntax, and some help text.
112 * A note regarding the help text: if empty, command will not be
113 * included in 'help' output.
115 void register_command(std::unique_ptr
<AdminSocketHook
>&& hook
);
118 * Registering the APIs that are served directly by the admin_socket server.
120 void register_admin_commands();
122 * handle a command message by replying an MCommandReply with the same tid
124 * \param conn connection over which the incoming command message is received
125 * \param m message carrying the command vector and optional input buffer
127 seastar::future
<> handle_command(crimson::net::ConnectionRef conn
,
128 boost::intrusive_ptr
<MCommand
> m
);
132 * the result of analyzing an incoming command, and locating it in
133 * the registered APIs collection.
135 struct parsed_command_t
{
138 const AdminSocketHook
& hook
;
140 // and the shorthand:
141 seastar::future
<> handle_client(seastar::input_stream
<char>& inp
,
142 seastar::output_stream
<char>& out
);
144 seastar::future
<> execute_line(std::string cmdline
,
145 seastar::output_stream
<char>& out
);
147 seastar::future
<> finalize_response(seastar::output_stream
<char>& out
,
148 ceph::bufferlist
&& msgs
);
150 seastar::future
<tell_result_t
> execute_command(const std::vector
<std::string
>& cmd
,
151 ceph::bufferlist
&& buf
);
153 std::optional
<seastar::future
<>> task
;
154 std::optional
<seastar::server_socket
> server_sock
;
155 std::optional
<seastar::connected_socket
> connected_sock
;
158 * stopping incoming ASOK requests at shutdown
160 seastar::gate stop_gate
;
163 * parse the incoming command vector, find a registered hook by looking up by
164 * its prefix, perform sanity checks on the parsed parameters with the hook's
165 * command description
167 * \param cmd a vector of string which presents a command
168 * \retval on success, a \c parsed_command_t is returned, tell_result_t with
169 * detailed error messages is returned otherwise
171 std::variant
<parsed_command_t
, tell_result_t
>
172 parse_cmd(const std::vector
<std::string
>& cmd
);
174 using hooks_t
= std::map
<std::string_view
, std::unique_ptr
<AdminSocketHook
>>;
181 hooks_t::const_iterator
begin() const {
182 return hooks
.cbegin();
184 hooks_t::const_iterator
end() const {
189 } // namespace crimson::admin