4 * Copyright (c) Intel Corporation.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 #include <sys/select.h>
38 #include <sys/types.h>
39 #include <sys/socket.h>
41 #include <netinet/in.h>
42 #include <netinet/tcp.h>
43 #include <arpa/inet.h>
49 #include "spdk/queue.h"
52 #include "spdk/conf.h"
54 #include "spdk/string.h"
56 #include "spdk_internal/event.h"
58 #define RPC_SELECT_INTERVAL 4000 /* 4ms */
59 #define RPC_DEFAULT_LISTEN_ADDR "127.0.0.1:5260"
60 #define RPC_DEFAULT_PORT "5260"
62 static struct sockaddr_un g_rpc_listen_addr_unix
= {};
64 static struct spdk_poller
*g_rpc_poller
= NULL
;
66 static struct spdk_jsonrpc_server
*g_jsonrpc_server
= NULL
;
68 struct spdk_rpc_method
{
70 spdk_rpc_method_handler func
;
71 SLIST_ENTRY(spdk_rpc_method
) slist
;
74 static SLIST_HEAD(, spdk_rpc_method
) g_rpc_methods
= SLIST_HEAD_INITIALIZER(g_rpc_methods
);
77 spdk_rpc_server_do_work(void *arg
)
79 spdk_jsonrpc_server_poll(g_jsonrpc_server
);
85 struct spdk_conf_section
*sp
;
87 sp
= spdk_conf_find_section(NULL
, "Rpc");
92 return spdk_conf_section_get_boolval(sp
, "Enable", false);
96 rpc_get_listen_addr(void)
98 struct spdk_conf_section
*sp
;
101 sp
= spdk_conf_find_section(NULL
, "Rpc");
106 val
= spdk_conf_section_get_val(sp
, "Listen");
108 val
= RPC_DEFAULT_LISTEN_ADDR
;
115 spdk_rpc_register_method(const char *method
, spdk_rpc_method_handler func
)
117 struct spdk_rpc_method
*m
;
119 m
= calloc(1, sizeof(struct spdk_rpc_method
));
122 m
->name
= strdup(method
);
123 assert(m
->name
!= NULL
);
127 /* TODO: use a hash table or sorted list */
128 SLIST_INSERT_HEAD(&g_rpc_methods
, m
, slist
);
132 spdk_jsonrpc_handler(
133 struct spdk_jsonrpc_server_conn
*conn
,
134 const struct spdk_json_val
*method
,
135 const struct spdk_json_val
*params
,
136 const struct spdk_json_val
*id
)
138 struct spdk_rpc_method
*m
;
140 assert(method
!= NULL
);
142 SLIST_FOREACH(m
, &g_rpc_methods
, slist
) {
143 if (spdk_json_strequal(method
, m
->name
)) {
144 m
->func(conn
, params
, id
);
149 spdk_jsonrpc_send_error_response(conn
, id
, SPDK_JSONRPC_ERROR_METHOD_NOT_FOUND
, "Method not found");
153 spdk_rpc_setup(void *arg
)
155 struct addrinfo hints
;
156 struct addrinfo
*res
;
157 const char *listen_addr
;
159 memset(&g_rpc_listen_addr_unix
, 0, sizeof(g_rpc_listen_addr_unix
));
161 /* Unregister the one-shot setup poller */
162 spdk_poller_unregister(&g_rpc_poller
, NULL
);
168 listen_addr
= rpc_get_listen_addr();
173 if (listen_addr
[0] == '/') {
176 g_rpc_listen_addr_unix
.sun_family
= AF_UNIX
;
177 rc
= snprintf(g_rpc_listen_addr_unix
.sun_path
,
178 sizeof(g_rpc_listen_addr_unix
.sun_path
),
180 if (rc
< 0 || (size_t)rc
>= sizeof(g_rpc_listen_addr_unix
.sun_path
)) {
181 SPDK_ERRLOG("RPC Listen address Unix socket path too long\n");
182 g_rpc_listen_addr_unix
.sun_path
[0] = '\0';
186 unlink(g_rpc_listen_addr_unix
.sun_path
);
188 g_jsonrpc_server
= spdk_jsonrpc_server_listen(AF_UNIX
, 0,
189 (struct sockaddr
*)&g_rpc_listen_addr_unix
,
190 sizeof(g_rpc_listen_addr_unix
),
191 spdk_jsonrpc_handler
);
196 tmp
= strdup(listen_addr
);
198 SPDK_ERRLOG("Out of memory\n");
202 if (spdk_parse_ip_addr(tmp
, &host
, &port
) < 0) {
204 SPDK_ERRLOG("Invalid listen address '%s'\n", listen_addr
);
209 port
= RPC_DEFAULT_PORT
;
212 memset(&hints
, 0, sizeof(hints
));
213 hints
.ai_family
= AF_UNSPEC
;
214 hints
.ai_socktype
= SOCK_STREAM
;
215 hints
.ai_protocol
= IPPROTO_TCP
;
217 if (getaddrinfo(host
, port
, &hints
, &res
) != 0) {
219 SPDK_ERRLOG("Unable to look up RPC listen address '%s'\n", listen_addr
);
223 g_jsonrpc_server
= spdk_jsonrpc_server_listen(res
->ai_family
, res
->ai_protocol
,
224 res
->ai_addr
, res
->ai_addrlen
,
225 spdk_jsonrpc_handler
);
231 if (g_jsonrpc_server
== NULL
) {
232 SPDK_ERRLOG("spdk_jsonrpc_server_listen() failed\n");
236 /* Register the periodic rpc_server_do_work */
237 spdk_poller_register(&g_rpc_poller
, spdk_rpc_server_do_work
, NULL
, spdk_env_get_current_core(),
238 RPC_SELECT_INTERVAL
);
242 spdk_rpc_initialize(void)
245 * Defer setup of the RPC service until the reactor has started. This
246 * allows us to detect the RPC listen socket as a suitable proxy for determining
247 * when the SPDK application has finished initialization and ready for logins
250 spdk_poller_register(&g_rpc_poller
, spdk_rpc_setup
, NULL
, spdk_env_get_current_core(), 0);
255 spdk_rpc_finish(void)
257 if (g_rpc_listen_addr_unix
.sun_path
[0]) {
258 /* Delete the Unix socket file */
259 unlink(g_rpc_listen_addr_unix
.sun_path
);
262 spdk_poller_unregister(&g_rpc_poller
, NULL
);
264 if (g_jsonrpc_server
) {
265 spdk_jsonrpc_server_shutdown(g_jsonrpc_server
);
272 spdk_rpc_config_text(FILE *fp
)
277 " # Defines whether to enable configuration via RPC.\n"
278 " # Default is disabled. Note that the RPC interface is not\n"
279 " # authenticated, so users should be careful about enabling\n"
280 " # RPC in non-trusted environments.\n"
282 " # Listen address for the RPC service.\n"
283 " # May be an IP address or an absolute path to a Unix socket.\n"
285 enable_rpc() ? "Yes" : "No", rpc_get_listen_addr());
288 SPDK_SUBSYSTEM_REGISTER(spdk_rpc
, spdk_rpc_initialize
, spdk_rpc_finish
, spdk_rpc_config_text
)